diff --git a/_modules/apptools/appscripting/action/start_recording_action.html b/4.5/_modules/apptools/appscripting/action/start_recording_action.html similarity index 100% rename from _modules/apptools/appscripting/action/start_recording_action.html rename to 4.5/_modules/apptools/appscripting/action/start_recording_action.html diff --git a/_modules/apptools/appscripting/action/stop_recording_action.html b/4.5/_modules/apptools/appscripting/action/stop_recording_action.html similarity index 100% rename from _modules/apptools/appscripting/action/stop_recording_action.html rename to 4.5/_modules/apptools/appscripting/action/stop_recording_action.html diff --git a/_modules/apptools/appscripting/bind_event.html b/4.5/_modules/apptools/appscripting/bind_event.html similarity index 100% rename from _modules/apptools/appscripting/bind_event.html rename to 4.5/_modules/apptools/appscripting/bind_event.html diff --git a/_modules/apptools/appscripting/i_bind_event.html b/4.5/_modules/apptools/appscripting/i_bind_event.html similarity index 100% rename from _modules/apptools/appscripting/i_bind_event.html rename to 4.5/_modules/apptools/appscripting/i_bind_event.html diff --git a/_modules/apptools/appscripting/i_script_manager.html b/4.5/_modules/apptools/appscripting/i_script_manager.html similarity index 100% rename from _modules/apptools/appscripting/i_script_manager.html rename to 4.5/_modules/apptools/appscripting/i_script_manager.html diff --git a/_modules/apptools/appscripting/lazy_namespace.html b/4.5/_modules/apptools/appscripting/lazy_namespace.html similarity index 100% rename from _modules/apptools/appscripting/lazy_namespace.html rename to 4.5/_modules/apptools/appscripting/lazy_namespace.html diff --git a/_modules/apptools/appscripting/package_globals.html b/4.5/_modules/apptools/appscripting/package_globals.html similarity index 100% rename from _modules/apptools/appscripting/package_globals.html rename to 4.5/_modules/apptools/appscripting/package_globals.html diff --git a/_modules/apptools/appscripting/script_manager.html b/4.5/_modules/apptools/appscripting/script_manager.html similarity index 100% rename from _modules/apptools/appscripting/script_manager.html rename to 4.5/_modules/apptools/appscripting/script_manager.html diff --git a/_modules/apptools/appscripting/scriptable.html b/4.5/_modules/apptools/appscripting/scriptable.html similarity index 100% rename from _modules/apptools/appscripting/scriptable.html rename to 4.5/_modules/apptools/appscripting/scriptable.html diff --git a/_modules/apptools/appscripting/scriptable_type.html b/4.5/_modules/apptools/appscripting/scriptable_type.html similarity index 100% rename from _modules/apptools/appscripting/scriptable_type.html rename to 4.5/_modules/apptools/appscripting/scriptable_type.html diff --git a/_modules/apptools/help/help_plugin/action/demo_action.html b/4.5/_modules/apptools/help/help_plugin/action/demo_action.html similarity index 100% rename from _modules/apptools/help/help_plugin/action/demo_action.html rename to 4.5/_modules/apptools/help/help_plugin/action/demo_action.html diff --git a/_modules/apptools/help/help_plugin/action/doc_action.html b/4.5/_modules/apptools/help/help_plugin/action/doc_action.html similarity index 100% rename from _modules/apptools/help/help_plugin/action/doc_action.html rename to 4.5/_modules/apptools/help/help_plugin/action/doc_action.html diff --git a/_modules/apptools/help/help_plugin/action/example_action.html b/4.5/_modules/apptools/help/help_plugin/action/example_action.html similarity index 100% rename from _modules/apptools/help/help_plugin/action/example_action.html rename to 4.5/_modules/apptools/help/help_plugin/action/example_action.html diff --git a/_modules/apptools/help/help_plugin/action/load_url_action.html b/4.5/_modules/apptools/help/help_plugin/action/load_url_action.html similarity index 100% rename from _modules/apptools/help/help_plugin/action/load_url_action.html rename to 4.5/_modules/apptools/help/help_plugin/action/load_url_action.html diff --git a/_modules/apptools/help/help_plugin/action/util.html b/4.5/_modules/apptools/help/help_plugin/action/util.html similarity index 100% rename from _modules/apptools/help/help_plugin/action/util.html rename to 4.5/_modules/apptools/help/help_plugin/action/util.html diff --git a/_modules/apptools/help/help_plugin/examples_preferences.html b/4.5/_modules/apptools/help/help_plugin/examples_preferences.html similarity index 100% rename from _modules/apptools/help/help_plugin/examples_preferences.html rename to 4.5/_modules/apptools/help/help_plugin/examples_preferences.html diff --git a/_modules/apptools/help/help_plugin/help_code.html b/4.5/_modules/apptools/help/help_plugin/help_code.html similarity index 100% rename from _modules/apptools/help/help_plugin/help_code.html rename to 4.5/_modules/apptools/help/help_plugin/help_code.html diff --git a/_modules/apptools/help/help_plugin/help_doc.html b/4.5/_modules/apptools/help/help_plugin/help_doc.html similarity index 100% rename from _modules/apptools/help/help_plugin/help_doc.html rename to 4.5/_modules/apptools/help/help_plugin/help_doc.html diff --git a/_modules/apptools/help/help_plugin/help_plugin.html b/4.5/_modules/apptools/help/help_plugin/help_plugin.html similarity index 100% rename from _modules/apptools/help/help_plugin/help_plugin.html rename to 4.5/_modules/apptools/help/help_plugin/help_plugin.html diff --git a/_modules/apptools/help/help_plugin/help_submenu_manager.html b/4.5/_modules/apptools/help/help_plugin/help_submenu_manager.html similarity index 100% rename from _modules/apptools/help/help_plugin/help_submenu_manager.html rename to 4.5/_modules/apptools/help/help_plugin/help_submenu_manager.html diff --git a/_modules/apptools/help/help_plugin/i_help_code.html b/4.5/_modules/apptools/help/help_plugin/i_help_code.html similarity index 100% rename from _modules/apptools/help/help_plugin/i_help_code.html rename to 4.5/_modules/apptools/help/help_plugin/i_help_code.html diff --git a/_modules/apptools/help/help_plugin/i_help_doc.html b/4.5/_modules/apptools/help/help_plugin/i_help_doc.html similarity index 100% rename from _modules/apptools/help/help_plugin/i_help_doc.html rename to 4.5/_modules/apptools/help/help_plugin/i_help_doc.html diff --git a/_modules/apptools/help/help_plugin/preferences_pages.html b/4.5/_modules/apptools/help/help_plugin/preferences_pages.html similarity index 100% rename from _modules/apptools/help/help_plugin/preferences_pages.html rename to 4.5/_modules/apptools/help/help_plugin/preferences_pages.html diff --git a/4.5/_modules/apptools/io/file.html b/4.5/_modules/apptools/io/file.html new file mode 100644 index 000000000..5119052ac --- /dev/null +++ b/4.5/_modules/apptools/io/file.html @@ -0,0 +1,471 @@ + + + + + + + apptools.io.file — Apptools Documentation + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +

Source code for apptools.io.file

+#------------------------------------------------------------------------------
+# Copyright (c) 2005, Enthought, Inc.
+# All rights reserved.
+#
+# This software is provided without warranty under the terms of the BSD
+# license included in enthought/LICENSE.txt and may be redistributed only
+# under the conditions described in the aforementioned license.  The license
+# is also available online at http://www.enthought.com/licenses/BSD.txt
+# Thanks for using Enthought open source!
+#
+# Author: Enthought, Inc.
+# Description: <Enthought IO package component>
+#------------------------------------------------------------------------------
+""" A representation of files and folders in a file system. """
+
+
+# Standard/built-in imports.
+import mimetypes, os, shutil, stat
+
+# Enthought library imports.
+from traits.api import Bool, HasPrivateTraits, Instance, List, Property
+from traits.api import Str
+
+
+
[docs]class File(HasPrivateTraits): + """ A representation of files and folders in a file system. """ + + #### 'File' interface ##################################################### + + # The absolute path name of this file/folder. + absolute_path = Property(Str) + + # The folder's children (for files this is always None). + children = Property(List('File')) + + # The file extension (for folders this is always the empty string). + # + # fixme: Currently the extension includes the '.' (ie. we have '.py' and + # not 'py'). This is because things like 'os.path.splitext' leave the '.' + # on, but I'm not sure that this is a good idea! + ext = Property(Str) + + # Does the file/folder exist? + exists = Property(Bool) + + # Is this an existing file? + is_file = Property(Bool) + + # Is this an existing folder? + is_folder = Property(Bool) + + # Is this a Python package (ie. a folder contaning an '__init__.py' file. + is_package = Property(Bool) + + # Is the file/folder readonly? + is_readonly = Property(Bool) + + # The MIME type of the file (for a folder this will always be + # 'context/unknown' (is that what it should be?)). + mime_type = Property(Str) + + # The last component of the path without the extension. + name = Property(Str) + + # The parent of this file/folder (None if it has no parent). + parent = Property(Instance('File')) + + # The path name of this file/folder. + path = Str + + # A URL reference to the file. + url = Property(Str) + + ########################################################################### + # 'object' interface. + ########################################################################### + + def __init__(self, path, **traits): + """ Creates a new representation of the specified path. """ + + super(File, self).__init__(path=path, **traits) + + return + + def __cmp__(self, other): + """ Comparison operators. """ + if isinstance(other, File): + return cmp(self.path, other.path) + + return 1 + + def __str__(self): + """ Returns an 'informal' string representation of the object. """ + + return 'File(%s)' % self.path + + ########################################################################### + # 'File' interface. + ########################################################################### + + #### Properties ########################################################### + + def _get_absolute_path(self): + """ Returns the absolute path of this file/folder. """ + + return os.path.abspath(self.path) + + def _get_children(self): + """ Returns the folder's children. + + Returns None if the path does not exist or is not a folder. + + """ + + if self.is_folder: + children = [] + for name in os.listdir(self.path): + children.append(File(os.path.join(self.path, name))) + + else: + children = None + + return children + + def _get_exists(self): + """ Returns True if the file exists, otherwise False. """ + + return os.path.exists(self.path) + + def _get_ext(self): + """ Returns the file extension. """ + + name, ext = os.path.splitext(self.path) + + return ext + + def _get_is_file(self): + """ Returns True if the path exists and is a file. """ + + return self.exists and os.path.isfile(self.path) + + def _get_is_folder(self): + """ Returns True if the path exists and is a folder. """ + + return self.exists and os.path.isdir(self.path) + + def _get_is_package(self): + """ Returns True if the path exists and is a Python package. """ + + return self.is_folder and '__init__.py' in os.listdir(self.path) + + def _get_is_readonly(self): + """ Returns True if the file/folder is readonly, otherwise False. """ + + # If the File object is a folder, os.access cannot be used because it + # returns True for both read-only and writable folders on Windows + # systems. + if self.is_folder: + + # Mask for the write-permission bits on the folder. If these bits + # are set to zero, the folder is read-only. + WRITE_MASK = 0x92 + permissions = os.stat(self.path)[0] + + if permissions & WRITE_MASK == 0: + readonly = True + else: + readonly = False + + elif self.is_file: + readonly = not os.access(self.path, os.W_OK) + + else: + readonly = False + + return readonly + + def _get_mime_type(self): + """ Returns the mime-type of this file/folder. """ + + mime_type, encoding = mimetypes.guess_type(self.path) + if mime_type is None: + mime_type = "content/unknown" + + return mime_type + + def _get_name(self): + """ Returns the last component of the path without the extension. """ + + basename = os.path.basename(self.path) + + name, ext = os.path.splitext(basename) + + return name + + def _get_parent(self): + """ Returns the parent of this file/folder. """ + + return File(os.path.dirname(self.path)) + + def _get_url(self): + """ Returns the path as a URL. """ + + # Strip out the leading slash on POSIX systems. + return 'file:///%s' % self.absolute_path.lstrip('/') + + #### Methods ############################################################## + +
[docs] def copy(self, destination): + """ Copies this file/folder. """ + + # Allow the destination to be a string. + if not isinstance(destination, File): + destination = File(destination) + + if self.is_folder: + shutil.copytree(self.path, destination.path) + + elif self.is_file: + shutil.copyfile(self.path, destination.path) + + return
+ +
[docs] def create_file(self, contents=''): + """ Creates a file at this path. """ + + if self.exists: + raise ValueError("file %s already exists" % self.path) + + f = open(self.path, 'w') + f.write(contents) + f.close() + + return
+ +
[docs] def create_folder(self): + """ Creates a folder at this path. + + All intermediate folders MUST already exist. + + """ + + if self.exists: + raise ValueError("folder %s already exists" % self.path) + + os.mkdir(self.path) + + return
+ +
[docs] def create_folders(self): + """ Creates a folder at this path. + + This will attempt to create any missing intermediate folders. + + """ + + if self.exists: + raise ValueError("folder %s already exists" % self.path) + + os.makedirs(self.path) + + return
+ +
[docs] def create_package(self): + """ Creates a package at this path. + + All intermediate folders/packages MUST already exist. + + """ + + if self.exists: + raise ValueError("package %s already exists" % self.path) + + os.mkdir(self.path) + + # Create the '__init__.py' file that actually turns the folder into a + # package! + init = File(os.path.join(self.path, '__init__.py')) + init.create_file() + + return
+ +
[docs] def delete(self): + """ Deletes this file/folder. + + Does nothing if the file/folder does not exist. + + """ + + if self.is_folder: + # Try to make sure that everything in the folder is writeable. + self.make_writeable() + + # Delete it! + shutil.rmtree(self.path) + + elif self.is_file: + # Try to make sure that the file is writeable. + self.make_writeable() + + # Delete it! + os.remove(self.path) + + return
+ +
[docs] def make_writeable(self): + """ Attempt to make the file/folder writeable. """ + + if self.is_folder: + # Try to make sure that everything in the folder is writeable + # (i.e., can be deleted!). This comes in especially handy when + # deleting '.svn' directories. + for path, dirnames, filenames in os.walk(self.path): + for name in dirnames + filenames: + filename = os.path.join(path, name) + if not os.access(filename, os.W_OK): + os.chmod(filename, stat.S_IWUSR) + + elif self.is_file: + # Try to make sure that the file is writeable (i.e., can be + # deleted!). + if not os.access(self.path, os.W_OK): + os.chmod(self.path, stat.S_IWUSR) + + return
+ +
[docs] def move(self, destination): + """ Moves this file/folder. """ + + # Allow the destination to be a string. + if not isinstance(destination, File): + destination = File(destination) + + # Try to make sure that everything in the directory is writeable. + self.make_writeable() + + # Move it! + shutil.move(self.path, destination.path) + + return
+ +#### EOF ###################################################################### +
+ +
+
+
+
+
+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/4.5/_modules/apptools/io/h5/dict_node.html b/4.5/_modules/apptools/io/h5/dict_node.html new file mode 100644 index 000000000..84bf2ec2f --- /dev/null +++ b/4.5/_modules/apptools/io/h5/dict_node.html @@ -0,0 +1,353 @@ + + + + + + + apptools.io.h5.dict_node — Apptools Documentation + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +

Source code for apptools.io.h5.dict_node

+from contextlib import closing
+import json
+
+from numpy import ndarray
+
+from tables import Group as PyTablesGroup
+from tables.nodes import filenode
+
+
+#: The key name which identifies array objects in the JSON dict.
+ARRAY_PROXY_KEY = '__array__'
+NODE_KEY = 'node_name'
+
+
+
[docs]class H5DictNode(object): + """ Dictionary-like node interface. + + Data for the dict is stored as a JSON file in a PyTables FileNode. This + allows easy storage of Python objects, such as dictionaries and lists of + different data types. + + Note that this is implemented using a group-node assuming that arrays are + valid inputs and will be stored as H5 array nodes. + + Parameters + ---------- + h5_group : H5Group instance + Group node which will be used as a dictionary store. + auto_flush : bool + If True, write data to disk whenever the dict data is altered. + Otherwise, call `flush()` explicitly to write data to disk. + """ + + #: Name of filenode where dict data is stored. + _pyobject_data_node = '_pyobject_data' + + def __init__(self, h5_group, auto_flush=True): + assert self.is_dict_node(h5_group) + + h5_group = self._get_pyt_group(h5_group) + self._h5_group = h5_group + self.auto_flush = auto_flush + + # Load dict data from the file node. + dict_node = getattr(h5_group, self._pyobject_data_node) + with closing(filenode.open_node(dict_node)) as f: + self._pyobject_data = json.loads( + f.read().decode('ascii'), object_hook=self._object_hook + ) + + #-------------------------------------------------------------------------- + # Dictionary interface + #-------------------------------------------------------------------------- + + def __getitem__(self, key): + return self.data[key] + + def __setitem__(self, key, value): + self.data[key] = value + if self.auto_flush: + self.flush() + + def __delitem__(self, key): + del self.data[key] + if self.auto_flush: + self.flush() + + def __contains__(self, key): + return key in self.data + +
[docs] def keys(self): + return self.data.keys()
+ + #-------------------------------------------------------------------------- + # Public interface + #-------------------------------------------------------------------------- + + @property + def data(self): + return self._pyobject_data + + @data.setter + def data(self, new_data_dict): + self._pyobject_data = new_data_dict + if self.auto_flush: + self.flush() + +
[docs] def flush(self): + """ Write buffered data to disk. """ + self._remove_pyobject_node() + self._write_pyobject_node()
+ +
[docs] @classmethod + def add_to_h5file(cls, h5, node_path, data=None, **kwargs): + """ Add dict node to an H5 file at the specified path. + + Parameters + ---------- + h5 : H5File + The H5 file where the dictionary data will be stored. + node_path : str + Path to node where data is stored (e.g. '/path/to/my_dict') + data : dict + Data for initialization, if desired. + """ + h5.create_group(node_path) + group = h5[node_path] + + cls._create_pyobject_node(h5._h5, node_path, data=data) + return cls(group, **kwargs)
+ +
[docs] @classmethod + def is_dict_node(cls, pytables_node): + """ Return True if PyTables node looks like an H5DictNode. + + NOTE: That this returns False if the node is an `H5DictNode` instance, + since the input node should be a normal PyTables Group node. + """ + # Import here to prevent circular imports + from .file import H5Group + + if isinstance(pytables_node, H5Group): + pytables_node = cls._get_pyt_group(pytables_node) + + if not isinstance(pytables_node, PyTablesGroup): + return False + + return cls._pyobject_data_node in pytables_node._v_children
+ + #-------------------------------------------------------------------------- + # Private interface + #-------------------------------------------------------------------------- + + def _f_remove(self): + """ This is called by H5File whenever a node is removed. + + All nodes in `_h5_group` will be removed. + """ + for name in self._h5_group._v_children.keys(): + if name != self._pyobject_data_node: + self._h5_group.__getattr__(name)._f_remove() + # Remove the dict node + self._remove_pyobject_node() + # Remove the group node + self._h5_group._f_remove() + + def _object_hook(self, dct): + """ This gets passed object dictionaries by `json.load(s)` and if it + finds `ARRAY_PROXY_KEY` in the object description it returns the + proxied array object. + """ + if ARRAY_PROXY_KEY in dct: + node_name = dct[NODE_KEY] + return getattr(self._h5_group, node_name)[:] + return dct + + def _remove_pyobject_node(self): + node = getattr(self._h5_group, self._pyobject_data_node) + node._f_remove() + + def _write_pyobject_node(self): + pyt_file = self._h5_group._v_file + node_path = self._h5_group._v_pathname + self._create_pyobject_node(pyt_file, node_path, self.data) + + @classmethod + def _create_pyobject_node(cls, pyt_file, node_path, data=None): + if data is None: + data = {} + + # Stash the array values in their own h5 nodes and return a dictionary + # which is appropriate for JSON serialization. + out_data = cls._handle_array_values(pyt_file, node_path, data) + + kwargs = dict(where=node_path, name=cls._pyobject_data_node) + with closing(filenode.new_node(pyt_file, **kwargs)) as f: + f.write(json.dumps(out_data).encode('ascii')) + + @classmethod + def _get_pyt_group(self, group): + if hasattr(group, '_h5_group'): + group = group._h5_group + return group + + @classmethod + def _array_proxy(cls, pyt_file, group, key, array): + """ Stores an array as a normal H5 node and returns the proxy object + which will be serialized to JSON. + + `ARRAY_PROXY_KEY` marks the object dictionary as an array proxy so that + `_object_hook` can recognize it. `NODE_KEY` stores the node name of the + array so that `_object_hook` can load the array data when the dict node + is deserialized. + + """ + if key in group: + pyt_file.remove_node(group, key) + pyt_file.create_array(group, key, array) + return {ARRAY_PROXY_KEY: True, NODE_KEY: key} + + @classmethod + def _handle_array_values(cls, pyt_file, group_path, data): + group = pyt_file.get_node(group_path) + + # Convert numpy array values to H5 array nodes. + out_data = {} + for key in data.keys(): + value = data[key] + if isinstance(value, ndarray): + out_data[key] = cls._array_proxy(pyt_file, group, key, value) + else: + out_data[key] = value + + # Remove stored arrays which are no longer in the data dictionary. + pyt_children = group._v_children + nodes_to_remove = [] + for key in pyt_children.keys(): + if key not in data: + nodes_to_remove.append(key) + + for key in nodes_to_remove: + pyt_file.remove_node(group, key) + + return out_data
+
+ +
+
+
+
+
+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/4.5/_modules/apptools/io/h5/file.html b/4.5/_modules/apptools/io/h5/file.html new file mode 100644 index 000000000..4d4013242 --- /dev/null +++ b/4.5/_modules/apptools/io/h5/file.html @@ -0,0 +1,621 @@ + + + + + + + apptools.io.h5.file — Apptools Documentation + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +

Source code for apptools.io.h5.file

+from collections import Mapping, MutableMapping
+from functools import partial
+
+import numpy as np
+import tables
+
+from .dict_node import H5DictNode
+from .table_node import H5TableNode
+
+
+
[docs]def get_atom(dtype): + """ Return a PyTables Atom for the given dtype or dtype string. + """ + return tables.Atom.from_dtype(np.dtype(dtype))
+ + +
[docs]def iterator_length(iterator): + return sum(1 for _ in iterator)
+ + +def _update_wrapped_docstring(wrapped, original=None): + PREAMBLE = """\ +** H5Group wrapper for H5File.{func_name}: ** +Note that the first argument is a nodepath relative to the group, rather than +an absolute path. Below is the original docstring: + + """.format(func_name=wrapped.__name__) + wrapped.__doc__ = PREAMBLE + original.__doc__ + return wrapped + + +
[docs]def h5_group_wrapper(original): + return partial(_update_wrapped_docstring, original=original)
+ + +
[docs]class H5File(Mapping): + """File object for HDF5 files. + + This class wraps PyTables to provide a cleaner, but only implements an + interface for accessing arrays. + + Parameters + ---------- + filename : str or a `tables.File` instance + Filename for an HDF5 file, or a PyTables `File` object. + mode : str + Mode to open the file: + + 'r' : Read-only + 'w' : Write; create new file (an existing file would be deleted). + 'a' : Read and write to file; create if not existing + 'r+': Read and write to file; must already exist + + delete_existing : bool + If True, an existing node will be deleted when a `create_*` method is + called. Otherwise, a ValueError will be raise. + auto_groups : bool + If True, `create_array` will automatically create parent groups. + auto_open : bool + If True, open the file automatically on initialization. Otherwise, + you can call `H5File.open()` explicitly after initialization. + chunked : bool + If True, the default behavior of `create_array` will be a chunked + array (see PyTables `create_carray`). + + """ + exists_error = ("'{}' exists in '{}'; set `delete_existing` attribute " + "to True to overwrite existing calculations.") + + def __init__(self, filename, mode='r+', delete_existing=False, + auto_groups=True, auto_open=True, h5filters=None): + self.mode = mode + self.delete_existing = delete_existing + self.auto_groups = auto_groups + if h5filters is None: + self.h5filters = tables.Filters(complib='blosc', complevel=5, + shuffle=True) + self._h5 = None + + if isinstance(filename, tables.File): + pyt_file = filename + filename = pyt_file.filename + if pyt_file.isopen: + self._h5 = pyt_file + + self.filename = filename + if auto_open: + self.open() + +
[docs] def open(self): + if not self.is_open: + self._h5 = tables.open_file(self.filename, mode=self.mode)
+ +
[docs] def close(self): + if self.is_open: + self._h5.close() + self._h5 = None
+ + @property + def root(self): + return self['/'] + + @property + def is_open(self): + return self._h5 is not None + + def __str__(self): + return str(self._h5) + + def __repr__(self): + return repr(self._h5) + + def __contains__(self, node_path): + return node_path in self._h5 + + def __getitem__(self, node_path): + try: + node = self._h5.get_node(node_path) + except tables.NoSuchNodeError: + msg = "Node {0!r} not found in {1!r}" + raise NameError(msg.format(node_path, self.filename)) + return _wrap_node(node) + + def __iter__(self): + return (_wrap_node(n) for n in self._h5.iter_nodes(where='/')) + + def __len__(self): + return iterator_length(self) + +
[docs] def iteritems(self, path='/'): + """ Iterate over node paths and nodes of the h5 file. """ + for node in self._h5.walk_nodes(where=path): + node_path = node._v_pathname + yield node_path, _wrap_node(node)
+ +
[docs] def create_array(self, node_path, array_or_shape, dtype=None, + chunked=False, extendable=False, **kwargs): + """Create node to store an array. + + Parameters + ---------- + node_path : str + PyTable node path; e.g. '/path/to/node'. + array_or_shape : array or shape tuple + Array or shape tuple for an array. If given a shape tuple, the + `dtype` parameter must also specified. + dtype : str or numpy.dtype + Data type of array. Only necessary if `array_or_shape` is a shape. + chunked : bool + Controls whether the array is chunked. + extendable : {None | bool} + Controls whether the array is extendable. + kwargs : key/value pairs + Keyword args passed to PyTables `File.create_(c|e)array`. + """ + self._check_node(node_path) + self._assert_valid_path(node_path) + + h5 = self._h5 + + if isinstance(array_or_shape, tuple): + if dtype is None: + msg = "`dtype` must be specified if only given array shape." + raise ValueError(msg) + array = None + dtype = dtype + shape = array_or_shape + else: + array = array_or_shape + dtype = array.dtype.name + shape = array.shape + + path, name = self.split_path(node_path) + if extendable: + shape = (0,) + shape[1:] + atom = get_atom(dtype) + node = h5.create_earray(path, name, atom, shape, + filters=self.h5filters, **kwargs) + if array is not None: + node.append(array) + elif chunked: + atom = get_atom(dtype) + node = h5.create_carray(path, name, atom, shape, + filters=self.h5filters, **kwargs) + if array is not None: + node[:] = array + else: + if array is None: + array = np.zeros(shape, dtype=dtype) + node = h5.create_array(path, name, array, **kwargs) + return node
+ +
[docs] def create_group(self, group_path, **kwargs): + """Create group. + + Parameters + ---------- + group_path : str + PyTable group path; e.g. '/path/to/group'. + kwargs : key/value pairs + Keyword args passed to PyTables `File.create_group`. + """ + self._check_node(group_path) + self._assert_valid_path(group_path) + path, name = self.split_path(group_path) + self._h5.create_group(path, name, **kwargs) + return self[group_path]
+ +
[docs] def create_dict(self, node_path, data=None, **kwargs): + """ Create dict node at the specified path. + + Parameters + ---------- + node_path : str + Path to node where data is stored (e.g. '/path/to/my_dict') + data : dict + Data for initialization, if desired. + """ + self._check_node(node_path) + self._assert_valid_path(node_path) + H5DictNode.add_to_h5file(self, node_path, data=data, **kwargs) + return self[node_path]
+ +
[docs] def create_table(self, node_path, description, **kwargs): + """ Create table node at the specified path. + + Parameters + ---------- + node_path : str + Path to node where data is stored (e.g. '/path/to/my_dict') + description : dict or numpy dtype object + The description of the columns in the table. This is either a dict + of column name -> dtype items or a numpy record array dtype. For + more information, see the documentation for Table in pytables. + """ + self._check_node(node_path) + self._assert_valid_path(node_path) + H5TableNode.add_to_h5file(self, node_path, description, **kwargs) + return self[node_path]
+ + def _check_node(self, node_path): + """Check if node exists and create parent groups if necessary. + + Either raise error or delete depending on `delete_existing` attribute. + """ + if self.auto_groups: + path, name = self.split_path(node_path) + self._create_required_groups(path) + + if node_path in self: + if self.delete_existing: + if isinstance(self[node_path], H5Group): + self.remove_group(node_path, recursive=True) + else: + self.remove_node(node_path) + else: + msg = self.exists_error.format(node_path, self.filename) + raise ValueError(msg) + + def _create_required_groups(self, path): + if path not in self: + parent, missing = self.split_path(path) + # Call recursively to ensure that all parent groups exist. + self._create_required_groups(parent) + self.create_group(path) + +
[docs] def remove_node(self, node_path): + """Remove node + + Parameters + ---------- + node_path : str + PyTable node path; e.g. '/path/to/node'. + """ + node = self[node_path] + if isinstance(node, H5Group): + msg = "{!r} is a group. Use `remove_group` to remove group nodes." + raise ValueError(msg.format(node.pathname)) + node._f_remove()
+ +
[docs] def remove_group(self, group_path, **kwargs): + """Remove group + + Parameters + ---------- + group_path : str + PyTable group path; e.g. '/path/to/group'. + """ + self[group_path]._h5_group._g_remove(**kwargs)
+ + @classmethod + def _assert_valid_path(self, node_path): + if 'attrs' in node_path.split('/'): + raise ValueError("'attrs' is an invalid node name.") + +
[docs] @classmethod + def split_path(cls, node_path): + """Split node path returning the base path and node name. + + For example: '/path/to/node' will return '/path/to' and 'node' + + Parameters + ---------- + node_path : str + PyTable node path; e.g. '/path/to/node'. + """ + i = node_path.rfind('/') + if i == 0: + return '/', node_path[1:] + else: + return node_path[:i], node_path[i + 1:]
+ +
[docs] @classmethod + def join_path(cls, *args): + """Join parts of an h5 path. + + For example, the 3 argmuments 'path', 'to', 'node' will return + '/path/to/node'. + + Parameters + ---------- + args : str + Parts of path to be joined. + """ + path = '/'.join(part.strip('/') for part in args) + if not path.startswith('/'): + path = '/' + path + return path
+ + +
[docs]class H5Attrs(MutableMapping): + """ An attributes dictionary for an h5 node. + + This intercepts `__setitem__` so that python sequences can be converted to + numpy arrays. This helps preserve the readability of our HDF5 files by + other (non-python) programs. + """ + + def __init__(self, node_attrs): + self._node_attrs = node_attrs + + def __delitem__(self, key): + del self._node_attrs[key] + + def __getitem__(self, key): + return self._node_attrs[key] + + def __iter__(self): + return iter(self.keys()) + + def __len__(self): + return len(self._node_attrs._f_list()) + + def __setitem__(self, key, value): + if isinstance(value, tuple) or isinstance(value, list): + value = np.array(value) + self._node_attrs[key] = value + +
[docs] def get(self, key, default=None): + return default if key not in self else self[key]
+ +
[docs] def keys(self): + return self._node_attrs._f_list()
+ +
[docs] def values(self): + return [self[k] for k in self.keys()]
+ +
[docs] def items(self): + return [(k, self[k]) for k in self.keys()]
+ + +
[docs]class H5Group(Mapping): + """ A group node in an H5File. + + This is a thin wrapper around PyTables' Group object to expose attributes + and maintain the dict interface of H5File. + """ + + def __init__(self, pytables_group): + self._h5_group = pytables_group + self.attrs = H5Attrs(self._h5_group._v_attrs) + + def __contains__(self, node_path): + return node_path in self._h5_group + + def __str__(self): + return str(self._h5_group) + + def __repr__(self): + return repr(self._h5_group) + + def __getitem__(self, node_path): + parts = node_path.split('/') + # PyTables stores children as attributes + node = self._h5_group.__getattr__(parts[0]) + node = _wrap_node(node) + if len(parts) == 1: + return node + else: + return node['/'.join(parts[1:])] + + def __iter__(self): + return (_wrap_node(c) for c in self._h5_group) + + def __len__(self): + return iterator_length(self) + + @property + def pathname(self): + return self._h5_group._v_pathname + + @property + def name(self): + return self._h5_group._v_name + + @property + def filename(self): + return self._h5_group._v_file.filename + + @property + def root(self): + return _wrap_node(self._h5_group._v_file.root) + + @property + def children_names(self): + return list(self._h5_group._v_children.keys()) + + @property + def subgroup_names(self): + return list(self._h5_group._v_groups.keys()) + +
[docs] def iter_groups(self): + """ Iterate over `H5Group` nodes that are children of this group. """ + groups = self._h5_group._v_groups + + # not using the groups.values() method here, because groups is a + # `proxydict` object whose .values() method is non-lazy. Related: + # PyTables/PyTables#784. + return (_wrap_node(groups[group_name]) for group_name in groups)
+ +
[docs] @h5_group_wrapper(H5File.create_group) + def create_group(self, group_subpath, delete_existing=False, **kwargs): + return self._delegate_to_h5file('create_group', group_subpath, + delete_existing=delete_existing, + **kwargs)
+ +
[docs] @h5_group_wrapper(H5File.remove_group) + def remove_group(self, group_subpath, **kwargs): + return self._delegate_to_h5file('remove_group', group_subpath, + **kwargs)
+ +
[docs] @h5_group_wrapper(H5File.create_array) + def create_array(self, node_subpath, array_or_shape, dtype=None, + chunked=False, extendable=False, **kwargs): + return self._delegate_to_h5file('create_array', node_subpath, + array_or_shape, dtype=dtype, + chunked=chunked, extendable=extendable, + **kwargs)
+ +
[docs] @h5_group_wrapper(H5File.create_table) + def create_table(self, node_subpath, description, *args, **kwargs): + return self._delegate_to_h5file('create_table', node_subpath, + description, *args, **kwargs)
+ +
[docs] @h5_group_wrapper(H5File.create_dict) + def create_dict(self, node_subpath, data=None, **kwargs): + return self._delegate_to_h5file('create_dict', node_subpath, data=data, + **kwargs)
+ +
[docs] @h5_group_wrapper(H5File.remove_node) + def remove_node(self, node_subpath, **kwargs): + return self._delegate_to_h5file('remove_node', node_subpath, **kwargs)
+ + def _delegate_to_h5file(self, function_name, node_subpath, + *args, **kwargs): + delete_existing = kwargs.pop('delete_existing', False) + h5 = H5File(self._h5_group._v_file, delete_existing=delete_existing) + group_path = h5.join_path(self.pathname, node_subpath) + func = getattr(h5, function_name) + return func(group_path, *args, **kwargs)
+ + +def _wrap_node(node): + """ Wrap PyTables node object, if necessary. """ + if isinstance(node, tables.Group): + if H5DictNode.is_dict_node(node): + node = H5DictNode(node) + else: + node = H5Group(node) + elif H5TableNode.is_table_node(node): + node = H5TableNode(node) + return node +
+ +
+
+
+
+
+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/4.5/_modules/apptools/io/h5/table_node.html b/4.5/_modules/apptools/io/h5/table_node.html new file mode 100644 index 000000000..c8da24049 --- /dev/null +++ b/4.5/_modules/apptools/io/h5/table_node.html @@ -0,0 +1,276 @@ + + + + + + + apptools.io.h5.table_node — Apptools Documentation + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +

Source code for apptools.io.h5.table_node

+import numpy as np
+from pandas import DataFrame
+import six
+from tables.table import Table as PyTablesTable
+
+
+class _TableRowAccessor(object):
+    """ A simple object which provides read access to the rows in a Table.
+    """
+    def __init__(self, h5_table):
+        self._h5_table = h5_table
+
+    def __getitem__(self, key):
+        return self._h5_table[key]
+
+
+
[docs]class H5TableNode(object): + """ A wrapper for PyTables Table nodes. + + Parameters + ---------- + node : tables.Table instance + An H5 node which is a pytables.Table or H5TableNode instance + """ + + def __init__(self, node): + # Avoid a circular import + from .file import H5Attrs + + assert self.is_table_node(node) + self._h5_table = node._h5_table if hasattr(node, '_h5_table') else node + self.attrs = H5Attrs(self._h5_table._v_attrs) + + #-------------------------------------------------------------------------- + # Creation methods + #-------------------------------------------------------------------------- + +
[docs] @classmethod + def add_to_h5file(cls, h5, node_path, description, **kwargs): + """ Add table node to an H5 file at the specified path. + + Parameters + ---------- + h5 : H5File + The H5 file where the table node will be stored. + node_path : str + Path to node where data is stored (e.g. '/path/to/my_table') + description : list of tuples or numpy dtype object + The description of the columns in the table. This is either a list + of (column name, dtype, [, shape or itemsize]) tuples or a numpy + record array dtype. For more information, see the documentation for + `Table` in PyTables. + **kwargs : dict + Additional keyword arguments to pass to pytables.File.create_table + """ + if isinstance(description, (tuple, list)): + description = np.dtype(description) + + cls._create_pytables_node(h5, node_path, description, **kwargs) + node = h5[node_path] + + return cls(node)
+ +
[docs] @classmethod + def is_table_node(cls, pytables_node): + """ Return True if pytables_node is a pytables.Table or a H5TableNode. + """ + return isinstance(pytables_node, (PyTablesTable, H5TableNode))
+ + #-------------------------------------------------------------------------- + # Public interface + #-------------------------------------------------------------------------- + +
[docs] def append(self, data): + """ Add some data to the table. + + Parameters + ---------- + data : dict + A dictionary of column name -> values items + """ + rows = list(zip(*[data[name] for name in self.keys()])) + self._h5_table.append(rows)
+ + def __getitem__(self, col_or_cols): + """ Return one or more columns of data from the table. + + Parameters + ---------- + col_or_cols : str or list of str + A single column name or a list of column names + + Return + ------ + data : ndarray + An array of column data with the column order matching that of + `col_or_cols`. + """ + if isinstance(col_or_cols, six.string_types): + return self._h5_table.col(col_or_cols) + + column_data = [self._h5_table.col(name) for name in col_or_cols] + return np.column_stack(column_data) + + @property + def ix(self): + """ Return an object which provides access to row data. + """ + return _TableRowAccessor(self._h5_table) + +
[docs] def keys(self): + return self._h5_table.colnames
+ +
[docs] def to_dataframe(self): + """ Return table data as a pandas `DataFrame`. + + XXX: This does not work if the table contains a multidimensional column + """ + # Slicing rows gives a numpy struct array, which DataFrame understands. + return DataFrame(self.ix[:])
+ + #-------------------------------------------------------------------------- + # Object interface + #-------------------------------------------------------------------------- + + def __repr__(self): + return repr(self._h5_table) + + def __len__(self): + return self._h5_table.nrows + + #-------------------------------------------------------------------------- + # Private interface + #-------------------------------------------------------------------------- + + def _f_remove(self): + """ Implement the PyTables `Node._f_remove` method so that H5File + doesn't choke when trying to remove our node. + """ + self._h5_table._f_remove() + self._h5_table = None + + @classmethod + def _create_pytables_node(cls, h5, node_path, description, **kwargs): + path, name = h5.split_path(node_path) + pyt_file = h5._h5 + pyt_file.create_table(path, name, description, **kwargs)
+
+ +
+
+
+
+
+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/4.5/_modules/apptools/io/h5/utils.html b/4.5/_modules/apptools/io/h5/utils.html new file mode 100644 index 000000000..b89f2b187 --- /dev/null +++ b/4.5/_modules/apptools/io/h5/utils.html @@ -0,0 +1,157 @@ + + + + + + + apptools.io.h5.utils — Apptools Documentation + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +

Source code for apptools.io.h5.utils

+from contextlib import contextmanager
+
+from .file import H5File
+
+
+
[docs]@contextmanager +def open_h5file(filename, mode='r+', **kwargs): + """Context manager for reading an HDF5 file as an H5File object. + + Parameters + ---------- + filename : str + HDF5 file name. + mode : str + Mode to open the file: + + 'r' : Read-only + 'w' : Write; create new file (an existing file would be deleted). + 'a' : Read and write to file; create if not existing + 'r+': Read and write to file; must already exist + + See `H5File` for additional keyword arguments. + """ + h5 = H5File(filename, mode=mode, **kwargs) + try: + yield h5 + finally: + h5.close()
+
+ +
+
+
+
+
+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/4.5/_modules/apptools/logger/agent/attachments.html b/4.5/_modules/apptools/logger/agent/attachments.html new file mode 100644 index 000000000..7fea4bb9e --- /dev/null +++ b/4.5/_modules/apptools/logger/agent/attachments.html @@ -0,0 +1,227 @@ + + + + + + + apptools.logger.agent.attachments — Apptools Documentation + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +

Source code for apptools.logger.agent.attachments

+""" Attach relevant project files.
+
+FIXME: there are no public project plugins for Envisage 3, yet. In any case,
+this stuff should not be hard-coded, but extensible via extension points. The
+code remains here because we can reuse the zip utility code in that extensible
+rewrite.
+"""
+
+import logging
+import os.path
+from email import encoders
+from email.mime.base import MIMEBase
+
+from traits.api import Any, HasTraits
+
+
+logger = logging.getLogger(__name__)
+
+
+
[docs]class Attachments(HasTraits): + + application = Any() + message = Any() + + def __init__(self, message, **traits): + traits = traits.copy() + traits['message'] = message + super(Attachments, self).__init__(**traits) + + + # FIXME: all of the package_*() methods refer to deprecated project plugins. + +
[docs] def package_workspace(self): + if self.application is None: + pass + + workspace = self.application.get_service('envisage.project.IWorkspace') + if workspace is not None: + dir = workspace.path + self._attach_directory(dir) + return
+ +
[docs] def package_single_project(self): + if self.application is None: + pass + + single_project = self.application.get_service('envisage.single_project.ModelService') + if single_project is not None: + dir = single_project.location + self._attach_directory(dir)
+ +
[docs] def package_any_relevant_files(self): + self.package_workspace() + self.package_single_project() + return
+ + def _attach_directory(self, dir): + relpath = os.path.basename(dir) + + import zipfile + from io import BytesIO + + ctype = 'application/octet-stream' + maintype, subtype = ctype.split('/', 1) + msg = MIMEBase(maintype, subtype) + + file_object = BytesIO() + zip = zipfile.ZipFile(file_object, 'w') + _append_to_zip_archive(zip, dir, relpath) + zip.close() + + msg.set_payload(file_object.getvalue()) + + encoders.encode_base64(msg) # Encode the payload using Base64 + msg.add_header('Content-Disposition', 'attachment', filename='project.zip') + + self.message.attach(msg) + + file_object.close()
+ + + + +def _append_to_zip_archive(zip, dir, relpath): + """ Add all files in and below directory dir into zip archive""" + for filename in os.listdir(dir): + path = os.path.join(dir, filename) + + if os.path.isfile(path): + name = os.path.join(relpath, filename) + zip.write(path, name) + logger.debug('adding %s to error report' % path) + else: + if filename != ".svn": # skip svn files if any + subdir = os.path.join(dir, filename) + _append_to_zip_archive(zip, subdir, os.path.join(relpath, filename)) + return + +
+ +
+
+
+
+
+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/4.5/_modules/apptools/logger/agent/quality_agent_mailer.html b/4.5/_modules/apptools/logger/agent/quality_agent_mailer.html new file mode 100644 index 000000000..adafb08ef --- /dev/null +++ b/4.5/_modules/apptools/logger/agent/quality_agent_mailer.html @@ -0,0 +1,248 @@ + + + + + + + apptools.logger.agent.quality_agent_mailer — Apptools Documentation + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +

Source code for apptools.logger.agent.quality_agent_mailer

+#------------------------------------------------------------------------------
+# Copyright (c) 2005, Enthought, Inc.
+# All rights reserved.
+#
+# This software is provided without warranty under the terms of the BSD
+# license included in enthought/LICENSE.txt and may be redistributed only
+# under the conditions described in the aforementioned license.  The license
+# is also available online at http://www.enthought.com/licenses/BSD.txt
+# Thanks for using Enthought open source!
+#
+# Author: Enthought, Inc.
+# Description: <Enthought logger package component>
+#------------------------------------------------------------------------------
+
+# Standard library imports.
+import logging
+import os
+
+# Enthought library imports.
+from traits.util.home_directory import get_home_directory
+
+
+# Setup a logger for this module.
+logger = logging.getLogger(__name__)
+
+
+
[docs]def create_email_message(fromaddr, toaddrs, ccaddrs, subject, priority, + include_project=False, stack_trace="", comments=""): + # format a message suitable to be sent to the Roundup bug tracker + + from email.MIMEMultipart import MIMEMultipart + from email.MIMEText import MIMEText + from email.MIMEBase import MIMEBase + + message = MIMEMultipart() + message['Subject'] = "%s [priority=%s]" % (subject, priority) + message['To'] = ', '.join(toaddrs) + message['Cc'] = ', '.join(ccaddrs) + message['From'] = fromaddr + message.preamble = 'You will not see this in a MIME-aware mail reader.\n' + message.epilogue = ' ' # To guarantee the message ends with a newline + + # First section is simple ASCII data ... + m = [] + m.append("Bug Report") + m.append("==============================") + m.append("") + + if len(comments) > 0: + m.append("Comments:") + m.append("========") + m.append(comments) + m.append("") + + if len(stack_trace) > 0: + m.append("Stack Trace:") + m.append("===========") + m.append(stack_trace) + m.append("") + + msg = MIMEText('\n'.join(m)) + message.attach(msg) + + # Include the log file ... + if True: + try: + log = os.path.join(get_home_directory(), 'envisage.log') + f = open(log, 'r') + entries = f.readlines() + f.close() + + ctype = 'application/octet-stream' + maintype, subtype = ctype.split('/', 1) + msg = MIMEBase(maintype, subtype) + + msg = MIMEText(''.join(entries)) + msg.add_header('Content-Disposition', 'attachment', filename='logfile.txt') + message.attach(msg) + except: + logger.exception('Failed to include log file with message') + + # Include the environment variables ... + if True: + """ + Transmit the user's environment settings as well. Main purpose is to + work out the user name to help with following up on bug reports and + in future we should probably send less data. + """ + try: + entries = [] + for key, value in os.environ.items(): + entries.append('%30s : %s\n' % (key, value)) + + ctype = 'application/octet-stream' + maintype, subtype = ctype.split('/', 1) + msg = MIMEBase(maintype, subtype) + + msg = MIMEText(''.join(entries)) + msg.add_header('Content-Disposition', 'attachment', filename='environment.txt') + message.attach(msg) + + except: + logger.exception('Failed to include environment variables with message') + + +# FIXME: no project plugins exist for Envisage 3, yet, and this isn't the right +# way to do it, either. See the docstring of attachments.py. +# # Attach the project if requested ... +# if include_project: +# from attachments import Attachments +# try: +# attachments = Attachments(message) +# attachments.package_any_relevant_files() +# except: +# logger.exception('Failed to include workspace files with message') + + return message
+ + +
+ +
+
+
+
+
+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/4.5/_modules/apptools/logger/agent/quality_agent_view.html b/4.5/_modules/apptools/logger/agent/quality_agent_view.html new file mode 100644 index 000000000..b8af52a60 --- /dev/null +++ b/4.5/_modules/apptools/logger/agent/quality_agent_view.html @@ -0,0 +1,488 @@ + + + + + + + apptools.logger.agent.quality_agent_view — Apptools Documentation + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +

Source code for apptools.logger.agent.quality_agent_view

+#------------------------------------------------------------------------------
+# Copyright (c) 2005, Enthought, Inc.
+# All rights reserved.
+#
+# This software is provided without warranty under the terms of the BSD
+# license included in enthought/LICENSE.txt and may be redistributed only
+# under the conditions described in the aforementioned license.  The license
+# is also available online at http://www.enthought.com/licenses/BSD.txt
+# Thanks for using Enthought open source!
+#
+# Author: Enthought, Inc.
+# Description: <Enthought logger package component>
+#------------------------------------------------------------------------------
+
+# Standard library imports.
+import logging
+
+# Enthought library imports.
+from pyface.api import Dialog
+from traits.api import Any, Str, Tuple
+
+
+# Setup a logger for this module.
+logger = logging.getLogger(__name__)
+
+
+priority_levels = ['Low', 'Medium', 'High', 'Critical']
+
+
+
[docs]class QualityAgentView(Dialog): + + size = Tuple((700, 900)) + title = Str('Quality Agent') + + # The associated LoggerService. + service = Any() + + msg = Str('') + subject = Str('Untitled Error Report') + to_address = Str() + cc_address = Str('') + from_address = Str() + smtp_server = Str() + priority = Str(priority_levels[2]) + comments = Str('None') + include_userdata = Any + + ########################################################################### + # Protected 'Dialog' interface. + ########################################################################### + + # fixme: Ideally, this should be passed in; this topic ID belongs to the + # Enlib help project/plug-in. + help_id = 'enlib|HID_Quality_Agent_Dlg' + + def _create_dialog_area(self, parent): + """ Creates the main content of the dialog. """ + import wx + + parent.SetSizeHints(minW=300, minH=575) + + # Add the main panel + sizer = wx.BoxSizer(wx.VERTICAL) + panel = wx.Panel(parent, -1) + panel.SetSizer(sizer) + panel.SetAutoLayout(True) + + + # Add a descriptive label at the top ... + label = wx.StaticText(panel, -1, "Send a comment or bug report ...") + sizer.Add(label, 0, wx.ALL, border=5) + + # Add the stack trace view ... + error_panel = self._create_error_panel(panel) + sizer.Add(error_panel, 1, wx.ALL|wx.EXPAND|wx.CLIP_CHILDREN, border=5) + + # Update the layout: + sizer.Fit(panel) + + # Add the error report view ... + report_panel = self._create_report_panel(panel) + sizer.Add(report_panel, 2, wx.ALL|wx.EXPAND|wx.CLIP_CHILDREN, border=5) + + # Update the layout: + sizer.Fit(panel) + + return panel + + + def _create_buttons(self, parent): + """ Creates the buttons. """ + import wx + + sizer = wx.BoxSizer(wx.HORIZONTAL) + + # 'Send' button. + send = wx.Button(parent, wx.ID_OK, "Send") + wx.EVT_BUTTON(parent, wx.ID_OK, self._on_send) + sizer.Add(send) + send.SetDefault() + + # 'Cancel' button. + cancel = wx.Button(parent, wx.ID_CANCEL, "Cancel") + wx.EVT_BUTTON(parent, wx.ID_CANCEL, self._wx_on_cancel) + sizer.Add(cancel, 0, wx.LEFT, 10) + + # 'Help' button. + if len(self.help_id) > 0: + help = wx.Button(parent, wx.ID_HELP, "Help") + wx.EVT_BUTTON(parent, wx.ID_HELP, self._wx_on_help) + sizer.Add(help, 0, wx.LEFT, 10) + + return sizer + + def _on_help(self, event): + """Called when the 'Help' button is pressed. """ + + hp = self.service.application.get_service('apptools.help.IHelp') + hp.library.show_topic(self.help_id) + + return + + + ### Utility methods ####################################################### + + def _create_error_panel(self, parent): + import wx + + box = wx.StaticBox(parent, -1, "Message:") + sizer = wx.StaticBoxSizer(box, wx.VERTICAL) + + # Print the stack trace + label2 = wx.StaticText(parent, -1,"The following information will be included in the report:") + sizer.Add(label2, 0, wx.LEFT|wx.TOP|wx.BOTTOM|wx.CLIP_CHILDREN, border=5) + + details = wx.TextCtrl(parent, -1, self.msg, size=(-1,75), + style=wx.TE_MULTILINE | + wx.TE_READONLY | + wx.HSCROLL | + wx.VSCROLL | + wx.TE_RICH2 | + wx.CLIP_CHILDREN) + details.SetSizeHints(minW=-1, minH=75) + # Set the font to not be proportional + font = wx.Font(12, wx.MODERN, wx.NORMAL, wx.NORMAL) + details.SetStyle(0, len(self.msg), wx.TextAttr(font=font)) + sizer.Add(details, 1, wx.EXPAND|wx.ALL|wx.CLIP_CHILDREN, 5) + + + return sizer + + + def _create_report_panel(self, parent): + import wx + + box = wx.StaticBox(parent, -1, "Report Information:") + sizer = wx.StaticBoxSizer(box, wx.VERTICAL) + + # Add email info ... + sizer.Add(self._create_email_info(parent), 0, wx.ALL|wx.EXPAND, 5) + + # Add priority combo: + sizer.Add(self._create_priority_combo(parent), 0, wx.ALL|wx.RIGHT, 5) + + # Extra comments from the user: + label3 = wx.StaticText(parent, -1, "Additional Comments:") + sizer.Add(label3, 0, wx.LEFT|wx.TOP|wx.BOTTOM|wx.CLIP_CHILDREN, 5) + + comments_field = wx.TextCtrl(parent, -1, self.comments, size=(-1,75), + style=wx.TE_MULTILINE | + wx.TE_RICH2 | + wx.CLIP_CHILDREN) + comments_field.SetSizeHints(minW=-1, minH=75) + font = wx.Font(12, wx.MODERN, wx.NORMAL, wx.NORMAL) + comments_field.SetStyle(0, len(self.comments), wx.TextAttr(font=font)) + sizer.Add(comments_field, 1, wx.ALL|wx.EXPAND|wx.CLIP_CHILDREN, 5) + wx.EVT_TEXT(parent, comments_field.GetId(), self._on_comments) + + # Include the project combobox? + if len(self.service.mail_files) > 0: + sizer.Add(self._create_project_upload(parent), 0, wx.ALL, border=5) + + return sizer + + + def _create_email_info(self, parent): + import wx + + # Layout setup .. + sizer = wx.FlexGridSizer(5,2,10,10) + sizer.AddGrowableCol(1) + + title_label = wx.StaticText(parent, -1, "Subject:") + sizer.Add(title_label , 0, wx.ALL|wx.ALIGN_RIGHT) + title_field = wx.TextCtrl(parent, -1, self.subject, wx.Point(-1,-1)) + sizer.Add(title_field, 1, wx.EXPAND|wx.ALL|wx.ALIGN_RIGHT|wx.CLIP_CHILDREN) + wx.EVT_TEXT(parent, title_field.GetId(), self._on_subject) + + to_label = wx.StaticText(parent, -1, "To:") + sizer.Add(to_label , 0, wx.ALL|wx.ALIGN_RIGHT) + to_field = wx.TextCtrl(parent, -1, self.to_address) + sizer.Add(to_field, 1, wx.EXPAND|wx.ALL|wx.ALIGN_RIGHT|wx.CLIP_CHILDREN) + wx.EVT_TEXT(parent, to_field.GetId(), self._on_to) + + cc_label = wx.StaticText(parent, -1, "Cc:") + sizer.Add(cc_label, 0, wx.ALL|wx.ALIGN_RIGHT) + cc_field = wx.TextCtrl(parent, -1, "") + sizer.Add(cc_field, 1, wx.EXPAND|wx.ALL|wx.ALIGN_RIGHT|wx.CLIP_CHILDREN) + wx.EVT_TEXT(parent, cc_field.GetId(), self._on_cc) + + from_label = wx.StaticText(parent, -1, "From:") + sizer.Add(from_label, 0, wx.ALL|wx.ALIGN_RIGHT) + from_field = wx.TextCtrl(parent, -1, self.from_address) + sizer.Add(from_field, 1, wx.EXPAND|wx.ALL|wx.ALIGN_RIGHT|wx.CLIP_CHILDREN) + wx.EVT_TEXT(parent, from_field.GetId(), self._on_from) + + smtp_label = wx.StaticText(parent, -1, "SMTP Server:") + sizer.Add(smtp_label, 0, wx.ALL|wx.ALIGN_RIGHT) + smtp_server_field = wx.TextCtrl(parent, -1, self.smtp_server) + sizer.Add(smtp_server_field, 1, wx.EXPAND|wx.ALL|wx.ALIGN_RIGHT|wx.CLIP_CHILDREN) + wx.EVT_TEXT(parent, smtp_server_field.GetId(), self._on_smtp_server) + + return sizer + + + def _create_priority_combo(self, parent): + import wx + + sizer = wx.BoxSizer(wx.HORIZONTAL) + + label = wx.StaticText(parent, -1, "How critical is this issue?") + sizer.Add(label, 0, wx.ALL, border=0) + + cb = wx.ComboBox(parent, -1, self.priority, + wx.Point(90, 50), wx.Size(95, -1), + priority_levels, wx.CB_READONLY) + sizer.Add(cb, 1, wx.EXPAND|wx.LEFT|wx.CLIP_CHILDREN, border=10) + + wx.EVT_COMBOBOX(parent, cb.GetId(), self._on_priority) + + return sizer + + + def _create_project_upload(self, parent): + import wx + + id = wx.NewId() + cb = wx.CheckBox(parent, id, "Include Workspace Files (will increase email size) ", + wx.Point(65, 80), wx.Size(-1, 20), wx.NO_BORDER) + wx.EVT_CHECKBOX(parent, id, self._on_project) + + return cb + + + ## UI Listeners ########################################################### + + def _on_subject(self, event): + self.subject = event.GetEventObject().GetValue() + + + def _on_to(self, event): + self.to_address = event.GetEventObject().GetValue() + + + def _on_cc(self, event): + self.cc_address = event.GetEventObject().GetValue() + + + def _on_from(self, event): + self.from_address = event.GetEventObject().GetValue() + + + def _on_smtp_server(self, event): + self.smtp_server = event.GetEventObject().GetValue() + + + def _on_priority(self, event): + self.priority = event.GetEventObject().GetStringSelection() + + + def _on_comments(self, event): + self.comments = event.GetEventObject().GetValue() + + + def _on_project(self, event): + self.include_userdata = event.Checked() + cb = event.GetEventObject() + + if event.Checked(): + cb.SetLabel("Include Workspace Files (approx. %.2f MBytes)" % self._compute_project_size()) + else: + cb.SetLabel("Include Workspace Files (will increase email size)") + return + + def _on_send(self, event): + import wx + # Disable the Send button while we go through the possibly + # time-consuming email-sending process. + button = event.GetEventObject() + button.Enable(0) + + fromaddr, toaddrs, ccaddrs = self._create_email_addresses() + message = self._create_email(fromaddr, toaddrs, ccaddrs) + + self.service.send_bug_report(self.smtp_server, fromaddr, toaddrs, + ccaddrs, message) + + # save the user's preferences + self.service.preferences.smtp_server = self.smtp_server + self.service.preferences.to_address = self.to_address + self.service.preferences.from_address = self.from_address + + # finally we close the dialog + self._wx_on_ok(event) + + return + + ## Private ################################################################ + + def _create_email_addresses(self): + # utility function map addresses from ui into the standard format + # FIXME: We should use standard To: header parsing instead of this ad + # hoc whitespace-only approach. + fromaddr = self.from_address + if "" == fromaddr.strip(): + fromaddr = "anonymous" + toaddrs = self.to_address.split() + ccaddrs = self.cc_address.split() + + return fromaddr, toaddrs, ccaddrs + + + def _compute_project_size(self): + # determine size of email in MBytes + fromaddr, toaddrs, ccaddrs = self._create_email_addresses() + message = self._create_email(fromaddr, toaddrs, ccaddrs) + return len(message.as_string()) / (2.0**20) + + + def _create_email(self, fromaddr, toaddrs, ccaddrs): + return self.service.create_email_message( + fromaddr, toaddrs, ccaddrs, + self.subject, + self.priority, + self.include_userdata, + self.msg, + self.comments, + ) + + def _to_address_default(self): + return self.service.preferences.to_address + + def _from_address_default(self): + return self.service.preferences.from_address + + def _smtp_server_default(self): + return self.service.preferences.smtp_server
+ +####### EOF ############################################################# +
+ +
+
+
+
+
+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/4.5/_modules/apptools/logger/custom_excepthook.html b/4.5/_modules/apptools/logger/custom_excepthook.html new file mode 100644 index 000000000..79ab1051b --- /dev/null +++ b/4.5/_modules/apptools/logger/custom_excepthook.html @@ -0,0 +1,173 @@ + + + + + + + apptools.logger.custom_excepthook — Apptools Documentation + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +

Source code for apptools.logger.custom_excepthook

+#------------------------------------------------------------------------------
+# Copyright (c) 2005, Enthought, Inc.
+# All rights reserved.
+#
+# This software is provided without warranty under the terms of the BSD
+# license included in enthought/LICENSE.txt and may be redistributed only
+# under the conditions described in the aforementioned license.  The license
+# is also available online at http://www.enthought.com/licenses/BSD.txt
+# Thanks for using Enthought open source!
+#
+# Author: Enthought, Inc.
+# Description: <Enthought logger package component>
+#------------------------------------------------------------------------------
+
+
+# Standard library imports.
+import logging
+from traceback import format_exception
+
+
+
+"""
+    To catch exceptions with our own code this code needs to be added
+    sys.excepthook = custom_excepthook
+"""
+
+
[docs]def custom_excepthook(type, value, traceback): + """ Pass on the exception to the logging system. """ + + msg = 'Custom - Traceback (most recent call last):\n' + list = format_exception(type, value, traceback) + + msg = "".join(list) + + # Try to find the module that the exception actually came from. + name = getattr(traceback.tb_frame, 'f_globals', {}).get('__name__', + __name__) + logger = logging.getLogger(name) + logger.error(msg) + + return
+ + +## EOF ################################################################## +
+ +
+
+
+
+
+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/_modules/apptools/logger/filtering_handler.html b/4.5/_modules/apptools/logger/filtering_handler.html similarity index 100% rename from _modules/apptools/logger/filtering_handler.html rename to 4.5/_modules/apptools/logger/filtering_handler.html diff --git a/4.5/_modules/apptools/logger/log_point.html b/4.5/_modules/apptools/logger/log_point.html new file mode 100644 index 000000000..df3e03d36 --- /dev/null +++ b/4.5/_modules/apptools/logger/log_point.html @@ -0,0 +1,178 @@ + + + + + + + apptools.logger.log_point — Apptools Documentation + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +

Source code for apptools.logger.log_point

+#------------------------------------------------------------------------------
+# Copyright (c) 2005, Enthought, Inc.
+# All rights reserved.
+#
+# This software is provided without warranty under the terms of the BSD
+# license included in enthought/LICENSE.txt and may be redistributed only
+# under the conditions described in the aforementioned license.  The license
+# is also available online at http://www.enthought.com/licenses/BSD.txt
+# Thanks for using Enthought open source!
+#
+# Author: Enthought, Inc.
+# Description: <Enthought logger package component>
+#------------------------------------------------------------------------------
+""" Prints a stack trace every time it is called but does not halt execution
+    of the application.
+
+    Copied from Uche Ogbuji's blog
+"""
+
+# Standard library imports.
+import inspect
+
+# Third-party library imports.
+from six import StringIO
+
+
+
[docs]def log_point(msg='\n'): + stack = inspect.stack() + # get rid of logPoint's part of the stack: + stack = stack[1:] + stack.reverse() + output = StringIO() + if msg: + output.write(str(msg) + '\n') + for stackLine in stack: + frame, filename, line, funcname, lines, unknown = stackLine + if filename.endswith('/unittest.py'): + # unittest.py code is a boring part of the traceback + continue + if filename.startswith('./'): + filename = filename[2:] + output.write('%s:%s in %s:\n' % (filename, line, funcname)) + if lines: + output.write(' %s\n' % ''.join(lines)[:-1]) + s = output.getvalue() + + return s
+ +## EOF ################################################################## +
+ +
+
+
+
+
+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/4.5/_modules/apptools/logger/log_queue_handler.html b/4.5/_modules/apptools/logger/log_queue_handler.html new file mode 100644 index 000000000..c80ea916d --- /dev/null +++ b/4.5/_modules/apptools/logger/log_queue_handler.html @@ -0,0 +1,213 @@ + + + + + + + apptools.logger.log_queue_handler — Apptools Documentation + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +

Source code for apptools.logger.log_queue_handler

+#------------------------------------------------------------------------------
+# Copyright (c) 2005, Enthought, Inc.
+# All rights reserved.
+#
+# This software is provided without warranty under the terms of the BSD
+# license included in enthought/LICENSE.txt and may be redistributed only
+# under the conditions described in the aforementioned license.  The license
+# is also available online at http://www.enthought.com/licenses/BSD.txt
+# Thanks for using Enthought open source!
+#
+# Author: Enthought, Inc.
+# Description: <Enthought logger package component>
+#------------------------------------------------------------------------------
+
+# Standard library imports.
+from logging import Handler
+
+# Local imports.
+from .ring_buffer import RingBuffer
+
+
+
[docs]class LogQueueHandler(Handler): + + """ Buffers up the log messages so that we can display them later. + This is important on startup when log messages are generated before + the ui has started. By putting them in this queue we can display + them once the ui is ready. + """ + + # The view where updates will go + _view = None + + + def __init__(self, size=1000): + Handler.__init__(self) + # only buffer 1000 log records + self.size = size + self.ring = RingBuffer(self.size) + self.dirty = False + return + + +
[docs] def emit(self, record): + """ Actually this is more like an enqueue than an emit().""" + self.ring.append(record) + if self._view is not None: + try: + self._view.update() + except Exception as e: + pass + self.dirty = True + return
+ + +
[docs] def get(self): + self.dirty = False + + try: + result = self.ring.get() + except Exception as msg: + # we did our best and it won't cause too much damage + # to just return a bogus message + result = [] + + return result
+ + +
[docs] def has_new_records(self): + return self.dirty
+ + +
[docs] def reset(self): + # start over with a new empty buffer + self.ring = RingBuffer(self.size) + if self._view is not None: + try: + self._view.update() + except Exception as e: + pass + self.dirty = True + return
+ + +## EOF ################################################################## +
+ +
+
+
+
+
+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/4.5/_modules/apptools/logger/logger.html b/4.5/_modules/apptools/logger/logger.html new file mode 100644 index 000000000..a3e602b76 --- /dev/null +++ b/4.5/_modules/apptools/logger/logger.html @@ -0,0 +1,225 @@ + + + + + + + apptools.logger.logger — Apptools Documentation + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +

Source code for apptools.logger.logger

+#------------------------------------------------------------------------------
+# Copyright (c) 2005, Enthought, Inc.
+# All rights reserved.
+#
+# This software is provided without warranty under the terms of the BSD
+# license included in enthought/LICENSE.txt and may be redistributed only
+# under the conditions described in the aforementioned license.  The license
+# is also available online at http://www.enthought.com/licenses/BSD.txt
+# Thanks for using Enthought open source!
+#
+# Author: Enthought, Inc.
+# Description: <Enthought logger package component>
+#------------------------------------------------------------------------------
+""" Convenience functions for creating logging handlers etc. """
+
+
+# Standard library imports.
+import logging
+from logging.handlers import RotatingFileHandler
+
+# Enthought library imports.
+from traits.util.api import deprecated
+
+# Local imports.
+from .log_queue_handler import LogQueueHandler
+
+
+# The default logging level.
+LEVEL = logging.DEBUG
+
+# The default formatter.
+FORMATTER = logging.Formatter('%(levelname)s|%(asctime)s|%(message)s')
+
+
+
[docs]class LogFileHandler(RotatingFileHandler): + """ The default log file handler. + """ + + def __init__(self, path, maxBytes=1000000, backupCount=3, level=None, + formatter=None): + RotatingFileHandler.__init__( + self, path, maxBytes=maxBytes, backupCount=3 + ) + + if level is None: + level = LEVEL + if formatter is None: + formatter = FORMATTER + # Set our default formatter and log level. + self.setFormatter(formatter) + self.setLevel(level)
+ +
[docs]@deprecated('use "LogFileHandler"') +def create_log_file_handler(path, maxBytes=1000000, backupCount=3, level=None, + formatter=None): + """ Creates a log file handler. + + This is just a convenience function to make it easy to create the same + kind of handlers across applications. + + It sets the handler's formatter to the default formatter, and its logging + level to the default logging level. + + """ + if level is None: + level = LEVEL + if formatter is None: + formatter = FORMATTER + + handler = RotatingFileHandler( + path, maxBytes=maxBytes, backupCount=backupCount + ) + + handler.setFormatter(formatter) + handler.setLevel(level) + + return handler
+ + +
[docs]def add_log_queue_handler(logger, level=None, formatter=None): + """ Adds a queueing log handler to a logger. + """ + if level is None: + level = LEVEL + if formatter is None: + formatter = FORMATTER + + # Add the handler to the root logger. + log_queue_handler = LogQueueHandler() + log_queue_handler.setLevel(level) + log_queue_handler.setFormatter(formatter) + logger.addHandler(log_queue_handler) + return log_queue_handler
+ + +#### EOF ###################################################################### +
+ +
+
+
+
+
+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/_modules/apptools/logger/null_handler.html b/4.5/_modules/apptools/logger/null_handler.html similarity index 100% rename from _modules/apptools/logger/null_handler.html rename to 4.5/_modules/apptools/logger/null_handler.html diff --git a/4.5/_modules/apptools/logger/plugin/logger_plugin.html b/4.5/_modules/apptools/logger/plugin/logger_plugin.html new file mode 100644 index 000000000..f8feb5c37 --- /dev/null +++ b/4.5/_modules/apptools/logger/plugin/logger_plugin.html @@ -0,0 +1,244 @@ + + + + + + + apptools.logger.plugin.logger_plugin — Apptools Documentation + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +

Source code for apptools.logger.plugin.logger_plugin

+#------------------------------------------------------------------------------
+# Copyright (c) 2005, Enthought, Inc.
+# All rights reserved.
+#
+# This software is provided without warranty under the terms of the BSD
+# license included in enthought/LICENSE.txt and may be redistributed only
+# under the conditions described in the aforementioned license.  The license
+# is also available online at http://www.enthought.com/licenses/BSD.txt
+# Thanks for using Enthought open source!
+#
+# Author: Enthought, Inc.
+# Description: <Enthought logger package component>
+#------------------------------------------------------------------------------
+""" Logger plugin.
+"""
+
+# Standard library imports.
+import logging
+
+# Enthought library imports.
+from envisage.api import ExtensionPoint, Plugin
+from apptools.logger.log_queue_handler import LogQueueHandler
+from traits.api import Callable, List
+
+# Local imports.
+from .logger_preferences import LoggerPreferences
+from .logger_service import LoggerService
+
+
+ID = 'apptools.logger'
+ILOGGER = ID + '.plugin.logger_service.LoggerService'
+
+
[docs]class LoggerPlugin(Plugin): + """ Logger plugin. + """ + + id = ID + name = 'Logger plugin' + + #### Extension points for this plugin ###################################### + + MAIL_FILES = 'apptools.logger.plugin.mail_files' + + mail_files = ExtensionPoint( + List(Callable), id=MAIL_FILES, desc=""" + + This extension point allows you to contribute functions which will be + called to add project files to the zip file that the user mails back + with bug reports from the Quality Agent. + + The function will be passed a zipfile.ZipFile object. + + """ + ) + + #### Contributions to extension points made by this plugin ################# + + PREFERENCES = 'envisage.preferences' + PREFERENCES_PAGES = 'envisage.ui.workbench.preferences_pages' + VIEWS = 'envisage.ui.workbench.views' + + preferences = List(contributes_to=PREFERENCES) + preferences_pages = List(contributes_to=PREFERENCES_PAGES) + views = List(contributes_to=VIEWS) + + + def _preferences_default(self): + return ['pkgfile://%s/plugin/preferences.ini' % ID] + + def _preferences_pages_default(self): + from apptools.logger.plugin.view.logger_preferences_page import \ + LoggerPreferencesPage + return [LoggerPreferencesPage] + + def _views_default(self): + return [self._logger_view_factory] + + + #### Plugin interface ###################################################### + +
[docs] def start(self): + """ Starts the plugin. + """ + preferences = LoggerPreferences() + service = LoggerService(application=self.application, + preferences=preferences) + formatter = logging.Formatter('%(levelname)s|%(asctime)s|%(message)s') + handler = LogQueueHandler() + handler.setLevel(preferences.level_) + handler.setFormatter(formatter) + root_logger = logging.getLogger() + root_logger.addHandler(handler) + root_logger.setLevel(preferences.level_) + service.handler = handler + self.application.register_service(ILOGGER, service)
+ +
[docs] def stop(self): + """ Stops the plugin. + """ + service = self.application.get_service(ILOGGER) + service.save_preferences()
+ + + #### LoggerPlugin private interface ######################################## + + def _logger_view_factory(self, **traits): + from apptools.logger.plugin.view.logger_view import LoggerView + service = self.application.get_service(ILOGGER) + view = LoggerView(service=service, **traits) + # Record the created view on the service. + service.plugin_view = view + return view
+ + +#### EOF ###################################################################### +
+ +
+
+
+
+
+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/4.5/_modules/apptools/logger/plugin/logger_preferences.html b/4.5/_modules/apptools/logger/plugin/logger_preferences.html new file mode 100644 index 000000000..899b6ea90 --- /dev/null +++ b/4.5/_modules/apptools/logger/plugin/logger_preferences.html @@ -0,0 +1,159 @@ + + + + + + + apptools.logger.plugin.logger_preferences — Apptools Documentation + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +

Source code for apptools.logger.plugin.logger_preferences

+import logging
+
+from apptools.preferences.api import PreferencesHelper
+from traits.api import Bool, Str, Trait
+
+
+
[docs]class LoggerPreferences(PreferencesHelper): + """ The persistent service exposing the Logger plugin's API. + """ + + #### Preferences ########################################################### + + # The log levels + level = Trait('Info', + {'Debug' : logging.DEBUG, + 'Info' : logging.INFO, + 'Warning' : logging.WARNING, + 'Error' : logging.ERROR, + 'Critical' : logging.CRITICAL, + }, + is_str = True, + ) + + enable_agent = Bool(False) + smtp_server = Str() + to_address = Str() + from_address = Str() + + # The path to the preferences node that contains the preferences. + preferences_path = Str('apptools.logger')
+
+ +
+
+
+
+
+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/4.5/_modules/apptools/logger/plugin/logger_service.html b/4.5/_modules/apptools/logger/plugin/logger_service.html new file mode 100644 index 000000000..a3e4a36da --- /dev/null +++ b/4.5/_modules/apptools/logger/plugin/logger_service.html @@ -0,0 +1,280 @@ + + + + + + + apptools.logger.plugin.logger_service — Apptools Documentation + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +

Source code for apptools.logger.plugin.logger_service

+# Standard library imports
+import logging
+import os
+import zipfile
+
+# Third-party library imports
+from io import BytesIO
+
+# Enthought library imports
+from pyface.workbench.api import View as WorkbenchView
+from traits.api import Any, Callable, HasTraits, Instance, List, \
+    Property, Undefined, on_trait_change
+
+root_logger = logging.getLogger()
+logger = logging.getLogger(__name__)
+
+
+
[docs]class LoggerService(HasTraits): + """ The persistent service exposing the Logger plugin's API. + """ + + # The Envisage application. + application = Any() + + # The logging Handler we use. + handler = Any() + + # Our associated LoggerPreferences. + preferences = Any() + + # The view we use. + plugin_view = Instance(WorkbenchView) + + # Contributions from other plugins. + mail_files = Property(List(Callable)) + +
[docs] def save_preferences(self): + """ Save the preferences. + """ + self.preferences.preferences.save()
+ +
[docs] def whole_log_text(self): + """ Return all of the logged data as formatted text. + """ + lines = [ self.handler.format(rec) for rec in self.handler.get() ] + # Ensure that we end with a newline. + lines.append('') + text = '\n'.join(lines) + return text
+ +
[docs] def create_email_message(self, fromaddr, toaddrs, ccaddrs, subject, + priority, include_userdata=False, stack_trace="", + comments="", include_environment=True): + """ Format a bug report email from the log files. + """ + from email.mime.application import MIMEApplication + from email.mime.multipart import MIMEMultipart + from email.mime.text import MIMEText + + message = MIMEMultipart() + message['Subject'] = "%s [priority=%s]" % (subject, priority) + message['To'] = ', '.join(toaddrs) + message['Cc'] = ', '.join(ccaddrs) + message['From'] = fromaddr + message.preamble = 'You will not see this in a MIME-aware mail ' \ + 'reader.\n' + message.epilogue = ' ' # To guarantee the message ends with a newline + + # First section is simple ASCII data ... + m = [] + m.append("Bug Report") + m.append("==============================") + m.append("") + + if len(comments) > 0: + m.append("Comments:") + m.append("========") + m.append(comments) + m.append("") + + if len(stack_trace) > 0: + m.append("Stack Trace:") + m.append("===========") + m.append(stack_trace) + m.append("") + + msg = MIMEText('\n'.join(m)) + message.attach(msg) + + # Include the log file ... + logtext = self.whole_log_text() + msg = MIMEText(logtext) + msg.add_header('Content-Disposition', 'attachment', + filename='logfile.txt') + message.attach(msg) + + # Include the environment variables ... + # FIXME: ask the user, maybe? + if include_environment: + # Transmit the user's environment settings as well. Main purpose is + # to work out the user name to help with following up on bug reports + # and in future we should probably send less data. + entries = [] + for key, value in sorted(os.environ.items()): + entries.append('%30s : %s\n' % (key, value)) + + msg = MIMEText(''.join(entries)) + msg.add_header('Content-Disposition', 'attachment', + filename='environment.txt') + message.attach(msg) + + if include_userdata and len(self.mail_files) != 0: + f = BytesIO() + zf = zipfile.ZipFile(f, 'w') + for mf in self.mail_files: + mf(zf) + zf.close() + + msg = MIMEApplication(f.getvalue()) + msg.add_header('Content-Disposition', 'attachment', + filename='userdata.zip') + message.attach(msg) + + return message
+ +
[docs] def send_bug_report(self, smtp_server, fromaddr, toaddrs, ccaddrs, message): + """ Send a bug report email. + """ + try: + import smtplib + logger.debug("Connecting to: %s" % smtp_server) + server = smtplib.SMTP(host=smtp_server) + logger.debug("Connected: %s" % server) + #server.set_debuglevel(1) + server.sendmail(fromaddr, toaddrs + ccaddrs, message.as_string()) + server.quit() + except Exception as e: + logger.exception("Problem sending error report")
+ + #### Traits stuff ######################################################### + + def _get_mail_files(self): + return self.application.get_extensions( + 'apptools.logger.plugin.mail_files') + + @on_trait_change('preferences.level_') + def _level_changed(self, new): + if (new is not None and new is not Undefined and + self.handler is not None): + root_logger.setLevel(self.preferences.level_) + self.handler.setLevel(self.preferences.level_)
+
+ +
+
+
+
+
+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/4.5/_modules/apptools/logger/plugin/view/logger_preferences_page.html b/4.5/_modules/apptools/logger/plugin/view/logger_preferences_page.html new file mode 100644 index 000000000..684b0e247 --- /dev/null +++ b/4.5/_modules/apptools/logger/plugin/view/logger_preferences_page.html @@ -0,0 +1,224 @@ + + + + + + + apptools.logger.plugin.view.logger_preferences_page — Apptools Documentation + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +

Source code for apptools.logger.plugin.view.logger_preferences_page

+#------------------------------------------------------------------------------
+# Copyright (c) 2005, Enthought, Inc.
+# All rights reserved.
+#
+# This software is provided without warranty under the terms of the BSD
+# license included in enthought/LICENSE.txt and may be redistributed only
+# under the conditions described in the aforementioned license.  The license
+# is also available online at http://www.enthought.com/licenses/BSD.txt
+# Thanks for using Enthought open source!
+#
+# Author: Enthought, Inc.
+# Description: <Enthought logger package component>
+#------------------------------------------------------------------------------
+
+import logging
+
+from apptools.preferences.ui.api import PreferencesPage
+from traits.api import Bool, Trait, Str
+from traitsui.api import EnumEditor, Group, Item, View
+
+
[docs]class LoggerPreferencesPage(PreferencesPage): + """ A preference page for the logger plugin. + """ + + #### 'PreferencesPage' interface ########################################## + + # The page's category (e.g. 'General/Appearance'). The empty string means + # that this is a top-level page. + category = '' + + # The page's help identifier (optional). If a help Id *is* provided then + # there will be a 'Help' button shown on the preference page. + help_id = '' + + # The page name (this is what is shown in the preferences dialog. + name = 'Logger' + + # The path to the preferences node that contains the preferences. + preferences_path = 'apptools.logger' + + + #### Preferences ########################################################### + + # The log levels + level = Trait('Info', + {'Debug' : logging.DEBUG, + 'Info' : logging.INFO, + 'Warning' : logging.WARNING, + 'Error' : logging.ERROR, + 'Critical' : logging.CRITICAL, + }, + is_str = True, + ) + + enable_agent = Bool(False) + smtp_server = Str + to_address = Str + from_address = Str + + + # The view used to change the plugin preferences + traits_view = View( + Group( + Group( + Item( + name='level', + editor=EnumEditor( + values={ + 'Debug' : '1:Debug', + 'Info' : '2:Info', + 'Warning' : '3:Warning', + 'Error' : '4:Error' , + 'Critical' : '5:Critical', + }, + ), + style='simple', + ), + label='Logger Settings', + show_border=True, + ), + Group(Item(name='10')), + Group( + Group( + Group(Item(name='enable_agent', label='Enable quality agent'), show_left=False), + Group(Item(name='smtp_server', label='SMTP server'), + Item(name='from_address'), + Item(name='to_address'), enabled_when='enable_agent==True')), + label='Quality Agent Settings', + show_border=True, + ), + ), + )
+ + +#### EOF ###################################################################### +
+ +
+
+
+
+
+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/4.5/_modules/apptools/logger/plugin/view/logger_view.html b/4.5/_modules/apptools/logger/plugin/view/logger_view.html new file mode 100644 index 000000000..7535cb118 --- /dev/null +++ b/4.5/_modules/apptools/logger/plugin/view/logger_view.html @@ -0,0 +1,314 @@ + + + + + + + apptools.logger.plugin.view.logger_view — Apptools Documentation + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +

Source code for apptools.logger.plugin.view.logger_view

+#------------------------------------------------------------------------------
+# Copyright (c) 2005, Enthought, Inc.
+# All rights reserved.
+#
+# This software is provided without warranty under the terms of the BSD
+# license included in enthought/LICENSE.txt and may be redistributed only
+# under the conditions described in the aforementioned license.  The license
+# is also available online at http://www.enthought.com/licenses/BSD.txt
+# Thanks for using Enthought open source!
+#
+# Author: Enthought, Inc.
+# Description: <Enthought logger package component>
+#------------------------------------------------------------------------------
+
+# Standard library imports
+from datetime import datetime
+import logging
+
+# Enthought library imports.
+from pyface.api import ImageResource, clipboard
+from pyface.workbench.api import TraitsUIView
+from traits.api import Button, Instance, List, Property, Str, \
+    cached_property, on_trait_change
+from traitsui.api import View, Group, Item, CodeEditor, \
+    TabularEditor, spring
+from traitsui.tabular_adapter import TabularAdapter
+
+# Local imports
+from apptools.logger.agent.quality_agent_view import QualityAgentView
+from apptools.logger.plugin import view
+from apptools.logger.plugin.logger_service import LoggerService
+
+# Constants
+_IMAGE_MAP = { logging.DEBUG: ImageResource('debug'),
+               logging.INFO: ImageResource('info'),
+               logging.WARNING: ImageResource('warning'),
+               logging.ERROR: ImageResource('error'),
+               logging.CRITICAL: ImageResource('crit_error') }
+
+
+
[docs]class LogRecordAdapter(TabularAdapter): + """ A TabularEditor adapter for logging.LogRecord objects. + """ + + columns = [ ('Level', 'level'), ('Date', 'date'), ('Time', 'time'), + ('Message', 'message') ] + column_widths = [ 80, 100, 120, -1 ] + + level_image = Property + level_text = Property(Str) + date_text = Property(Str) + time_text = Property(Str) + message_text = Property(Str) + +
[docs] def get_width(self, object, trait, column): + return self.column_widths[column]
+ + def _get_level_image(self): + return _IMAGE_MAP[self.item.levelno] + + def _get_level_text(self): + return self.item.levelname.capitalize() + + def _get_date_text(self): + dt = datetime.fromtimestamp(self.item.created) + return dt.date().isoformat() + + def _get_time_text(self): + dt = datetime.fromtimestamp(self.item.created) + return dt.time().isoformat() + + def _get_message_text(self): + # Just display the first line of multiline messages, like stacktraces. + msg = self.item.getMessage() + msgs = msg.strip().split('\n') + if len(msgs) > 1: + suffix = '... [double click for details]' + else: + suffix = '' + abbrev_msg = msgs[0] + suffix + return abbrev_msg
+ + +
[docs]class LoggerView(TraitsUIView): + """ The Workbench View showing the list of log items. + """ + + id = Str('apptools.logger.plugin.view.logger_view.LoggerView') + name = Str('Logger') + service = Instance(LoggerService) + + log_records = List(Instance(logging.LogRecord)) + formatted_records = Property(Str, depends_on='log_records') + + activated = Instance(logging.LogRecord) + activated_text = Property(Str, depends_on='activated') + reset_button = Button("Reset Logs") + show_button = Button("Complete Text Log") + copy_button = Button("Copy Log to Clipboard") + + + code_editor = CodeEditor(lexer='null', + show_line_numbers=False) + log_records_editor = TabularEditor(adapter=LogRecordAdapter(), + editable=False, + activated='activated') + trait_view = View(Group(Item('log_records', + editor=log_records_editor), + Group(Item('reset_button'), + spring, + Item('show_button'), + Item('copy_button'), + orientation='horizontal', + show_labels=False), + show_labels=False)) + + ########################################################################### + # LogQueueHandler view interface + ########################################################################### + +
[docs] def update(self, force=False): + """ Update 'log_records' if our handler has new records or 'force' is + set. + """ + service = self.service + if service.handler.has_new_records() or force: + log_records = [ rec for rec in service.handler.get() + if rec.levelno >= service.preferences.level_ ] + log_records.reverse() + self.log_records = log_records
+ + ########################################################################### + # Private interface + ########################################################################### + + @on_trait_change('service.preferences.level_') + def _update_log_records(self): + self.service.handler._view = self + self.update(force=True) + + def _reset_button_fired(self): + self.service.handler.reset() + self.log_records = [] + + def _show_button_fired(self): + self.edit_traits(view=View(Item('formatted_records', + editor=self.code_editor, + style='readonly', + show_label=False), + width=800, height=600, resizable=True, + buttons=[ 'OK' ], + title='Complete Text Log')) + + def _copy_button_fired(self): + clipboard.text_data = self.formatted_records + + @cached_property + def _get_formatted_records(self): + return '\n'.join([ self.service.handler.formatter.format(record) + for record in self.log_records ]) + + def _activated_changed(self): + if self.activated is None: + return + msg = self.activated.getMessage() + if self.service.preferences.enable_agent: + dialog = QualityAgentView(msg=msg, service=self.service) + dialog.open() + else: + self.edit_traits(view=View(Item('activated_text', + editor=self.code_editor, + style='readonly', + show_label=False), + width=800, height=600, resizable=True, + buttons=[ 'OK' ], + title='Log Message Detail')) + + @cached_property + def _get_activated_text(self): + if self.activated is None: + return '' + else: + return self.activated.getMessage()
+ +#### EOF ###################################################################### +
+ +
+
+
+
+
+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/4.5/_modules/apptools/logger/ring_buffer.html b/4.5/_modules/apptools/logger/ring_buffer.html new file mode 100644 index 000000000..e4742d1b5 --- /dev/null +++ b/4.5/_modules/apptools/logger/ring_buffer.html @@ -0,0 +1,182 @@ + + + + + + + apptools.logger.ring_buffer — Apptools Documentation + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +

Source code for apptools.logger.ring_buffer

+#------------------------------------------------------------------------------
+# Copyright (c) 2005, Enthought, Inc.
+# All rights reserved.
+#
+# This software is provided without warranty under the terms of the BSD
+# license included in enthought/LICENSE.txt and may be redistributed only
+# under the conditions described in the aforementioned license.  The license
+# is also available online at http://www.enthought.com/licenses/BSD.txt
+# Thanks for using Enthought open source!
+#
+# Author: Enthought, Inc.
+# Description: <Enthought util package component>
+#------------------------------------------------------------------------------
+"""
+Copied from Python Cookbook.
+
+"""
+
+
[docs]class RingBuffer: + def __init__(self,size_max): + self.max = size_max + self.data = [] +
[docs] def append(self,x): + """append an element at the end of the buffer""" + self.data.append(x) + if len(self.data) == self.max: + self.cur = 0 + self.__class__ = RingBufferFull
+
[docs] def get(self): + """ return a list of elements from the oldest to the newest""" + return self.data
+ + +
[docs]class RingBufferFull: + def __init__(self,n): + raise Exception("you should use RingBuffer") +
[docs] def append(self,x): + self.data[self.cur]=x + self.cur=(self.cur+1) % self.max
+
[docs] def get(self): + return self.data[self.cur:]+self.data[:self.cur]
+ + +# sample of use +"""x=RingBuffer(5) +x.append(1); x.append(2); x.append(3); x.append(4) +print(x.__class__,x.get()) +x.append(5) +print(x.__class__,x.get()) +x.append(6) +print(x.data,x.get()) +x.append(7); x.append(8); x.append(9); x.append(10) +print(x.data,x.get())""" +
+ +
+
+
+
+
+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/_modules/apptools/logger/util.html b/4.5/_modules/apptools/logger/util.html similarity index 100% rename from _modules/apptools/logger/util.html rename to 4.5/_modules/apptools/logger/util.html diff --git a/_modules/apptools/lru_cache/lru_cache.html b/4.5/_modules/apptools/lru_cache/lru_cache.html similarity index 100% rename from _modules/apptools/lru_cache/lru_cache.html rename to 4.5/_modules/apptools/lru_cache/lru_cache.html diff --git a/_modules/apptools/naming/adapter/dict_context_adapter.html b/4.5/_modules/apptools/naming/adapter/dict_context_adapter.html similarity index 100% rename from _modules/apptools/naming/adapter/dict_context_adapter.html rename to 4.5/_modules/apptools/naming/adapter/dict_context_adapter.html diff --git a/_modules/apptools/naming/adapter/dict_context_adapter_factory.html b/4.5/_modules/apptools/naming/adapter/dict_context_adapter_factory.html similarity index 100% rename from _modules/apptools/naming/adapter/dict_context_adapter_factory.html rename to 4.5/_modules/apptools/naming/adapter/dict_context_adapter_factory.html diff --git a/_modules/apptools/naming/adapter/instance_context_adapter.html b/4.5/_modules/apptools/naming/adapter/instance_context_adapter.html similarity index 100% rename from _modules/apptools/naming/adapter/instance_context_adapter.html rename to 4.5/_modules/apptools/naming/adapter/instance_context_adapter.html diff --git a/_modules/apptools/naming/adapter/instance_context_adapter_factory.html b/4.5/_modules/apptools/naming/adapter/instance_context_adapter_factory.html similarity index 100% rename from _modules/apptools/naming/adapter/instance_context_adapter_factory.html rename to 4.5/_modules/apptools/naming/adapter/instance_context_adapter_factory.html diff --git a/_modules/apptools/naming/adapter/list_context_adapter.html b/4.5/_modules/apptools/naming/adapter/list_context_adapter.html similarity index 100% rename from _modules/apptools/naming/adapter/list_context_adapter.html rename to 4.5/_modules/apptools/naming/adapter/list_context_adapter.html diff --git a/_modules/apptools/naming/adapter/list_context_adapter_factory.html b/4.5/_modules/apptools/naming/adapter/list_context_adapter_factory.html similarity index 100% rename from _modules/apptools/naming/adapter/list_context_adapter_factory.html rename to 4.5/_modules/apptools/naming/adapter/list_context_adapter_factory.html diff --git a/_modules/apptools/naming/adapter/trait_dict_context_adapter.html b/4.5/_modules/apptools/naming/adapter/trait_dict_context_adapter.html similarity index 100% rename from _modules/apptools/naming/adapter/trait_dict_context_adapter.html rename to 4.5/_modules/apptools/naming/adapter/trait_dict_context_adapter.html diff --git a/_modules/apptools/naming/adapter/trait_dict_context_adapter_factory.html b/4.5/_modules/apptools/naming/adapter/trait_dict_context_adapter_factory.html similarity index 100% rename from _modules/apptools/naming/adapter/trait_dict_context_adapter_factory.html rename to 4.5/_modules/apptools/naming/adapter/trait_dict_context_adapter_factory.html diff --git a/_modules/apptools/naming/adapter/trait_list_context_adapter.html b/4.5/_modules/apptools/naming/adapter/trait_list_context_adapter.html similarity index 100% rename from _modules/apptools/naming/adapter/trait_list_context_adapter.html rename to 4.5/_modules/apptools/naming/adapter/trait_list_context_adapter.html diff --git a/_modules/apptools/naming/adapter/trait_list_context_adapter_factory.html b/4.5/_modules/apptools/naming/adapter/trait_list_context_adapter_factory.html similarity index 100% rename from _modules/apptools/naming/adapter/trait_list_context_adapter_factory.html rename to 4.5/_modules/apptools/naming/adapter/trait_list_context_adapter_factory.html diff --git a/_modules/apptools/naming/adapter/tuple_context_adapter.html b/4.5/_modules/apptools/naming/adapter/tuple_context_adapter.html similarity index 100% rename from _modules/apptools/naming/adapter/tuple_context_adapter.html rename to 4.5/_modules/apptools/naming/adapter/tuple_context_adapter.html diff --git a/_modules/apptools/naming/adapter/tuple_context_adapter_factory.html b/4.5/_modules/apptools/naming/adapter/tuple_context_adapter_factory.html similarity index 100% rename from _modules/apptools/naming/adapter/tuple_context_adapter_factory.html rename to 4.5/_modules/apptools/naming/adapter/tuple_context_adapter_factory.html diff --git a/4.5/_modules/apptools/naming/address.html b/4.5/_modules/apptools/naming/address.html new file mode 100644 index 000000000..06fe23fc8 --- /dev/null +++ b/4.5/_modules/apptools/naming/address.html @@ -0,0 +1,164 @@ + + + + + + + apptools.naming.address — Apptools Documentation + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +

Source code for apptools.naming.address

+#------------------------------------------------------------------------------
+# Copyright (c) 2005, Enthought, Inc.
+# All rights reserved.
+#
+# This software is provided without warranty under the terms of the BSD
+# license included in enthought/LICENSE.txt and may be redistributed only
+# under the conditions described in the aforementioned license.  The license
+# is also available online at http://www.enthought.com/licenses/BSD.txt
+# Thanks for using Enthought open source!
+#
+# Author: Enthought, Inc.
+# Description: <Enthought naming package component>
+#------------------------------------------------------------------------------
+""" The address of a commuications endpoint. """
+
+
+# Enthought library imports.
+from traits.api import Any, HasTraits, Str
+
+
+
[docs]class Address(HasTraits): + """ The address of a communications end-point. + + It contains a type that describes the communication mechanism, and the + actual address content. + + """ + + # The type of the address. + type = Str + + # The actual content. + content = Any
+ +#### EOF ###################################################################### +
+ +
+
+
+
+
+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/4.5/_modules/apptools/naming/binding.html b/4.5/_modules/apptools/naming/binding.html new file mode 100644 index 000000000..6a72bf86d --- /dev/null +++ b/4.5/_modules/apptools/naming/binding.html @@ -0,0 +1,239 @@ + + + + + + + apptools.naming.binding — Apptools Documentation + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +

Source code for apptools.naming.binding

+#------------------------------------------------------------------------------
+# Copyright (c) 2005, Enthought, Inc.
+# All rights reserved.
+#
+# This software is provided without warranty under the terms of the BSD
+# license included in enthought/LICENSE.txt and may be redistributed only
+# under the conditions described in the aforementioned license.  The license
+# is also available online at http://www.enthought.com/licenses/BSD.txt
+# Thanks for using Enthought open source!
+#
+# Author: Enthought, Inc.
+# Description: <Enthought naming package component>
+#------------------------------------------------------------------------------
+""" The representation of a name-to-object binding in a context. """
+
+
+# Enthought libary imports.
+from traits.api import Any, HasTraits, Property, Str
+
+
+
[docs]class Binding(HasTraits): + """ The representation of a name-to-object binding in a context. """ + + #### 'Binding' interface ################################################## + + # The class name of the object bound to the name in the binding. + class_name = Property(Str) + + # The name. + name = Str + + # The object bound to the name in the binding. + obj = Any + + #### Experimental 'Binding' interface ##################################### + + # fixme: These is not part of the JNDI spec, but they do seem startlingly + # useful! + # + # fixme: And, errr, startlingly broken! If the context that the binding + # is in is required then just look up the name minus the last component! + # + # The context that the binding came from. + context = Any + + # The name of the bound object within the namespace. + namespace_name = Property(Str) + + #### 'Private' interface ################################################## + + # Shadow trait for the 'class_name' property. + _class_name = Str + + ########################################################################### + # 'object' interface. + ########################################################################### + + def __str__(self): + """ Returns an informal string representation of the object. """ + + return super(Binding, self).__str__() + '(name=%s, obj=%s)' % ( + self.name, self.obj) + + ########################################################################### + # 'Binding' interface. + ########################################################################### + + #### Properties ########################################################### + + # class_name + def _get_class_name(self): + """ Returns the class name of the object. """ + + if len(self._class_name) == 0: + if self.obj is None: + class_name = None + + else: + klass = self.obj.__class__ + + class_name = '%s.%s' % (klass.__module__, klass.__name__) + + return class_name + + def _set_class_name(self, class_name): + """ Sets the class name of the object. """ + + self._class_name = class_name + + return + + # namespace_name + def _get_namespace_name(self): + """ Returns the name of the context within its own namespace. """ + + if self.context is not None: + base = self.context.namespace_name + + else: + base = '' + + if len(base) > 0: + namespace_name = base + '/' + self.name + + else: + namespace_name = self.name + + return namespace_name
+ +#### EOF ###################################################################### +
+ +
+
+
+
+
+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/4.5/_modules/apptools/naming/context.html b/4.5/_modules/apptools/naming/context.html new file mode 100644 index 000000000..1fe488f43 --- /dev/null +++ b/4.5/_modules/apptools/naming/context.html @@ -0,0 +1,901 @@ + + + + + + + apptools.naming.context — Apptools Documentation + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +

Source code for apptools.naming.context

+#------------------------------------------------------------------------------
+# Copyright (c) 2005, Enthought, Inc.
+# All rights reserved.
+#
+# This software is provided without warranty under the terms of the BSD
+# license included in enthought/LICENSE.txt and may be redistributed only
+# under the conditions described in the aforementioned license.  The license
+# is also available online at http://www.enthought.com/licenses/BSD.txt
+# Thanks for using Enthought open source!
+#
+# Author: Enthought, Inc.
+# Description: <Enthought naming package component>
+#------------------------------------------------------------------------------
+""" The base class for all naming contexts. """
+
+
+# Enthought library imports.
+from traits.api import Any, Dict, Event, HasTraits, Instance
+from traits.api import Property, Str
+from apptools.type_manager.api import TypeManager
+
+# Local imports.
+from .binding import Binding
+from .exception import InvalidNameError, NameAlreadyBoundError
+from .exception import NameNotFoundError, NotContextError
+from .exception import OperationNotSupportedError
+from .naming_event import NamingEvent
+from .naming_manager import naming_manager
+from .object_factory import ObjectFactory
+from .state_factory import StateFactory
+from .unique_name import make_unique_name
+
+
+# Constants for environment property keys.
+INITIAL_CONTEXT_FACTORY = "apptools.naming.factory.initial"
+OBJECT_FACTORIES = "apptools.naming.factory.object"
+STATE_FACTORIES = "apptools.naming.factory.state"
+
+# Non-JNDI.
+TYPE_MANAGER = "apptools.naming.factory.type.manager"
+
+
+# The default environment.
+ENVIRONMENT = {
+    # 'Context' properties.
+    OBJECT_FACTORIES          : [],
+    STATE_FACTORIES           : [],
+
+    # Non-JNDI.
+    TYPE_MANAGER              : None,
+}
+
+
+
[docs]class Context(HasTraits): + """ The base class for all naming contexts. """ + + # Keys for environment properties. + INITIAL_CONTEXT_FACTORY = INITIAL_CONTEXT_FACTORY + OBJECT_FACTORIES = OBJECT_FACTORIES + STATE_FACTORIES = STATE_FACTORIES + + # Non-JNDI. + TYPE_MANAGER = TYPE_MANAGER + + #### 'Context' interface ################################################## + + # The naming environment in effect for this context. + environment = Dict(ENVIRONMENT) + + # The name of the context within its own namespace. + namespace_name = Property(Str) + + # The type manager in the context's environment (used to create context + # adapters etc.). + # + # fixme: This is an experimental 'convenience' trait, since it is common + # to get hold of the context's type manager to see if some object has a + # context adapter. + type_manager = Property(Instance(TypeManager)) + + #### Events #### + + # Fired when an object has been added to the context (either via 'bind' or + # 'create_subcontext'). + object_added = Event(NamingEvent) + + # Fired when an object has been changed (via 'rebind'). + object_changed = Event(NamingEvent) + + # Fired when an object has been removed from the context (either via + # 'unbind' or 'destroy_subcontext'). + object_removed = Event(NamingEvent) + + # Fired when an object in the context has been renamed (via 'rename'). + object_renamed = Event(NamingEvent) + + # Fired when the contents of the context have changed dramatically. + context_changed = Event(NamingEvent) + + #### Protected 'Context' interface ####################################### + + # The bindings in the context. + _bindings = Dict(Str, Any) + + ########################################################################### + # 'Context' interface. + ########################################################################### + + #### Properties ########################################################### + + def _get_namespace_name(self): + """ + Return the name of the context within its own namespace. + + That is the full-path, through the namespace this context participates + in, to get to this context. For example, if the root context of the + namespace was called 'Foo', and there was a subcontext of that called + 'Bar', and we were within that and called 'Baz', then this should + return 'Foo/Bar/Baz'. + + """ + + # FIXME: We'd like to raise an exception and force implementors to + # decide what to do. However, it appears to be pretty common that + # most Context implementations do not override this method -- possibly + # because the comments aren't clear on what this is supposed to be? + # + # Anyway, if we raise an exception then it is impossible to use any + # evaluations when building a Traits UI for a Context. That is, the + # Traits UI can't include items that have a 'visible_when' or + # 'enabled_when' evaluation. This is because the Traits evaluation + # code calls the 'get()' method on the Context which attempts to + # retrieve the current namespace_name value. + #raise OperationNotSupportedError() + return '' + + def _get_type_manager(self): + """ Returns the type manager in the context's environment. + + This will return None if no type manager was used to create the initial + context. + + """ + + return self.environment.get(self.TYPE_MANAGER) + + #### Methods ############################################################## + +
[docs] def bind(self, name, obj, make_contexts=False): + """ Binds a name to an object. + + If 'make_contexts' is True then any missing intermediate contexts are + created automatically. + + """ + + if len(name) == 0: + raise InvalidNameError('empty name') + + # Parse the name. + components = self._parse_name(name) + + # If there is exactly one component in the name then the operation + # takes place in this context. + if len(components) == 1: + atom = components[0] + + # Is the name already bound? + if self._is_bound(atom): + raise NameAlreadyBoundError(name) + + # Do the actual bind. + self._bind(atom, obj) + + # Trait event notification. + self.object_added = NamingEvent( + new_binding=Binding(name=name, obj=obj, context=self) + ) + + # Otherwise, attempt to continue resolution into the next context. + else: + if not self._is_bound(components[0]): + if make_contexts: + self._create_subcontext(components[0]) + + else: + raise NameNotFoundError(components[0]) + + next_context = self._get_next_context(components[0]) + next_context.bind('/'.join(components[1:]), obj, make_contexts) + + return
+ +
[docs] def rebind(self, name, obj, make_contexts=False): + """ Binds an object to a name that may already be bound. + + If 'make_contexts' is True then any missing intermediate contexts are + created automatically. + + The object may be a different object but may also be the same object + that is already bound to the specified name. The name may or may not be + already used. Think of this as a safer version of 'bind' since this + one will never raise an exception regarding a name being used. + + """ + + if len(name) == 0: + raise InvalidNameError('empty name') + + # Parse the name. + components = self._parse_name(name) + + # If there is exactly one component in the name then the operation + # takes place in this context. + if len(components) == 1: + # Do the actual rebind. + self._rebind(components[0], obj) + + # Trait event notification. + self.object_changed = NamingEvent( + new_binding=Binding(name=name, obj=obj, context=self) + ) + + # Otherwise, attempt to continue resolution into the next context. + else: + if not self._is_bound(components[0]): + if make_contexts: + self._create_subcontext(components[0]) + + else: + raise NameNotFoundError(components[0]) + + next_context = self._get_next_context(components[0]) + next_context.rebind('/'.join(components[1:]), obj, make_contexts) + + return
+ +
[docs] def unbind(self, name): + """ Unbinds a name. """ + + if len(name) == 0: + raise InvalidNameError('empty name') + + # Parse the name. + components = self._parse_name(name) + + # If there is exactly one component in the name then the operation + # takes place in this context. + if len(components) == 1: + atom = components[0] + + if not self._is_bound(atom): + raise NameNotFoundError(name) + + # Lookup the object that we are unbinding to use in the event + # notification. + obj = self._lookup(atom) + + # Do the actual unbind. + self._unbind(atom) + + # Trait event notification. + self.object_removed = NamingEvent( + old_binding=Binding(name=name, obj=obj, context=self) + ) + + # Otherwise, attempt to continue resolution into the next context. + else: + if not self._is_bound(components[0]): + raise NameNotFoundError(components[0]) + + next_context = self._get_next_context(components[0]) + next_context.unbind('/'.join(components[1:])) + + return
+ +
[docs] def rename(self, old_name, new_name): + """ Binds a new name to an object. """ + + if len(old_name) == 0 or len(new_name) == 0: + raise InvalidNameError('empty name') + + # Parse the names. + old_components = self._parse_name(old_name) + new_components = self._parse_name(new_name) + + # If there is axactly one component in BOTH names then the operation + # takes place ENTIRELY in this context. + if len(old_components) == 1 and len(new_components) == 1: + # Is the old name actually bound? + if not self._is_bound(old_name): + raise NameNotFoundError(old_name) + + # Is the new name already bound? + if self._is_bound(new_name): + raise NameAlreadyBoundError(new_name) + + # Do the actual rename. + self._rename(old_name, new_name) + + # Lookup the object that we are renaming to use in the event + # notification. + obj = self._lookup(new_name) + + # Trait event notification. + self.object_renamed = NamingEvent( + old_binding=Binding(name=old_name, obj=obj, context=self), + new_binding=Binding(name=new_name, obj=obj, context=self) + ) + + else: + # fixme: This really needs to be transactional in case the bind + # succeeds but the unbind fails. To be safe should we just not + # support cross-context renaming for now?!?! + # + # Lookup the object. + obj = self.lookup(old_name) + + # Bind the new name. + self.bind(new_name, obj) + + # Unbind the old one. + self.unbind(old_name) + + return
+ +
[docs] def lookup(self, name): + """ Resolves a name relative to this context. """ + + # If the name is empty we return the context itself. + if len(name) == 0: + # fixme: The JNDI spec. says that this should return a COPY of + # the context. + return self + + # Parse the name. + components = self._parse_name(name) + + # If there is exactly one component in the name then the operation + # takes place in this context. + if len(components) == 1: + atom = components[0] + + if not self._is_bound(atom): + raise NameNotFoundError(name) + + # Do the actual lookup. + obj = self._lookup(atom) + + # Otherwise, attempt to continue resolution into the next context. + else: + if not self._is_bound(components[0]): + raise NameNotFoundError(components[0]) + + next_context = self._get_next_context(components[0]) + obj = next_context.lookup('/'.join(components[1:])) + + return obj
+ + + # fixme: Non-JNDI +
[docs] def lookup_binding(self, name): + """ Looks up the binding for a name relative to this context. """ + + if len(name) == 0: + raise InvalidNameError('empty name') + + # Parse the name. + components = self._parse_name(name) + + # If there is exactly one component in the name then the operation + # takes place in this context. + if len(components) == 1: + atom = components[0] + + if not self._is_bound(atom): + raise NameNotFoundError(name) + + # Do the actual lookup. + binding = self._lookup_binding(atom) + + # Otherwise, attempt to continue resolution into the next context. + else: + if not self._is_bound(components[0]): + raise NameNotFoundError(components[0]) + + next_context = self._get_next_context(components[0]) + binding = next_context.lookup_binding('/'.join(components[1:])) + + return binding
+ + # fixme: Non-JNDI +
[docs] def lookup_context(self, name): + """ Resolves a name relative to this context. + + The name MUST resolve to a context. This method is useful to return + context adapters. + + """ + + # If the name is empty we return the context itself. + if len(name) == 0: + # fixme: The JNDI spec. says that this should return a COPY of + # the context. + return self + + # Parse the name. + components = self._parse_name(name) + + # If there is exactly one component in the name then the operation + # takes place in this context. + if len(components) == 1: + atom = components[0] + + if not self._is_bound(atom): + raise NameNotFoundError(name) + + # Do the actual lookup. + obj = self._get_next_context(atom) + + # Otherwise, attempt to continue resolution into the next context. + else: + if not self._is_bound(components[0]): + raise NameNotFoundError(components[0]) + + next_context = self._get_next_context(components[0]) + obj = next_context.lookup('/'.join(components[1:])) + + return obj
+ +
[docs] def create_subcontext(self, name): + """ Creates a sub-context. """ + + if len(name) == 0: + raise InvalidNameError('empty name') + + # Parse the name. + components = self._parse_name(name) + + # If there is exactly one component in the name then the operation + # takes place in this context. + if len(components) == 1: + atom = components[0] + + # Is the name already bound? + if self._is_bound(atom): + raise NameAlreadyBoundError(name) + + # Do the actual creation of the sub-context. + sub = self._create_subcontext(atom) + + # Trait event notification. + self.object_added = NamingEvent( + new_binding=Binding(name=name, obj=sub, context=self) + ) + + # Otherwise, attempt to continue resolution into the next context. + else: + if not self._is_bound(components[0]): + raise NameNotFoundError(components[0]) + + next_context = self._get_next_context(components[0]) + sub = next_context.create_subcontext('/'.join(components[1:])) + + return sub
+ +
[docs] def destroy_subcontext(self, name): + """ Destroys a sub-context. """ + + if len(name) == 0: + raise InvalidNameError('empty name') + + # Parse the name. + components = self._parse_name(name) + + # If there is exactly one component in the name then the operation + # takes place in this context. + if len(components) == 1: + atom = components[0] + + if not self._is_bound(atom): + raise NameNotFoundError(name) + + obj = self._lookup(atom) + if not self._is_context(atom): + raise NotContextError(name) + + # Do the actual destruction of the sub-context. + self._destroy_subcontext(atom) + + # Trait event notification. + self.object_removed = NamingEvent( + old_binding=Binding(name=name, obj=obj, context=self) + ) + + # Otherwise, attempt to continue resolution into the next context. + else: + if not self._is_bound(components[0]): + raise NameNotFoundError(components[0]) + + next_context = self._get_next_context(components[0]) + next_context.destroy_subcontext('/'.join(components[1:])) + + return
+ + # fixme: Non-JNDI +
[docs] def get_unique_name(self, prefix): + """ Returns a name that is unique within the context. + + The name returned will start with the specified prefix. + + """ + + return make_unique_name(prefix, existing=self.list_names(''), + format='%s (%d)')
+ + +
[docs] def list_names(self, name=''): + """ Lists the names bound in a context. """ + + # If the name is empty then the operation takes place in this context. + if len(name) == 0: + names = self._list_names() + + # Otherwise, attempt to continue resolution into the next context. + else: + # Parse the name. + components = self._parse_name(name) + + if not self._is_bound(components[0]): + raise NameNotFoundError(components[0]) + + next_context = self._get_next_context(components[0]) + names = next_context.list_names('/'.join(components[1:])) + + return names
+ +
[docs] def list_bindings(self, name=''): + """ Lists the bindings in a context. """ + + # If the name is empty then the operation takes place in this context. + if len(name) == 0: + bindings = self._list_bindings() + + # Otherwise, attempt to continue resolution into the next context. + else: + # Parse the name. + components = self._parse_name(name) + + if not self._is_bound(components[0]): + raise NameNotFoundError(components[0]) + + next_context = self._get_next_context(components[0]) + bindings = next_context.list_bindings('/'.join(components[1:])) + + return bindings
+ + # fixme: Non-JNDI +
[docs] def is_context(self, name): + """ Returns True if the name is bound to a context. """ + + # If the name is empty then it refers to this context. + if len(name) == 0: + is_context = True + + else: + # Parse the name. + components = self._parse_name(name) + + # If there is exactly one component in the name then the operation + # takes place in this context. + if len(components) == 1: + atom = components[0] + + if not self._is_bound(atom): + raise NameNotFoundError(name) + + # Do the actual check. + is_context = self._is_context(atom) + + # Otherwise, attempt to continue resolution into the next context. + else: + if not self._is_bound(components[0]): + raise NameNotFoundError(components[0]) + + next_context = self._get_next_context(components[0]) + is_context = next_context.is_context('/'.join(components[1:])) + + return is_context
+ + # fixme: Non-JNDI +
[docs] def search(self, obj): + """ Returns a list of namespace names that are bound to obj. """ + + # don't look for None + if obj is None: + return [] + + # Obj is bound to these names relative to this context + names = [] + + # path contain the name components down to the current context + path = [] + + self._search( obj, names, path, {} ) + + return names
+ + ########################################################################### + # Protected 'Context' interface. + ########################################################################### + + def _parse_name(self, name): + """ Parse a name into a list of components. + + e.g. 'foo/bar/baz' -> ['foo', 'bar', 'baz'] + + """ + + return name.split('/') + + def _is_bound(self, name): + """ Is a name bound in this context? """ + + return name in self._bindings + + def _lookup(self, name): + """ Looks up a name in this context. """ + + obj = self._bindings[name] + + return naming_manager.get_object_instance(obj, name, self) + + def _lookup_binding(self, name): + """ Looks up the binding for a name in this context. """ + + return Binding(name=name, obj=self._lookup(name), context=self) + + def _bind(self, name, obj): + """ Binds a name to an object in this context. """ + + state = naming_manager.get_state_to_bind(obj, name, self) + self._bindings[name] = state + + return + + def _rebind(self, name, obj): + """ Rebinds a name to an object in this context. """ + + self._bind(name, obj) + + return + + def _unbind(self, name): + """ Unbinds a name from this context. """ + + del self._bindings[name] + + return + + def _rename(self, old_name, new_name): + """ Renames an object in this context. """ + + # Bind the new name. + self._bindings[new_name] = self._bindings[old_name] + + # Unbind the old one. + del self._bindings[old_name] + + return + + def _create_subcontext(self, name): + """ Creates a sub-context of this context. """ + + sub = self.__class__(environment=self.environment) + self._bindings[name] = sub + + return sub + + def _destroy_subcontext(self, name): + """ Destroys a sub-context of this context. """ + + del self._bindings[name] + + return + + def _list_bindings(self): + """ Lists the bindings in this context. """ + + bindings = [] + for name in self._list_names(): + bindings.append( + Binding(name=name, obj=self._lookup(name), context=self) + ) + + return bindings + + def _list_names(self): + """ Lists the names bound in this context. """ + + return list(self._bindings.keys()) + + def _is_context(self, name): + """ Returns True if a name is bound to a context. """ + + return self._get_next_context(name) is not None + + def _get_next_context(self, name): + """ Returns the next context. """ + + obj = self._lookup(name) + + # If the object is a context then everything is just dandy. + if isinstance(obj, Context): + next_context = obj + + # Otherwise, instead of just giving up, see if the context has a type + # manager that knows how to adapt the object to make it quack like a + # context. + else: + next_context = self._get_context_adapter(obj) + + # If no adapter was found then we cannot continue name resolution. + if next_context is None: + raise NotContextError(name) + + return next_context + + def _search( self, obj, names, path, searched): + """ Append to names any name bound to obj. + Join path and name with '/' to for a complete name from the + top context. + """ + + # Check the bindings recursively. + for binding in self.list_bindings(): + if binding.obj is obj: + path.append( binding.name ) + names.append( '/'.join(path) ) + path.pop() + + if isinstance( binding.obj, Context ) \ + and not binding.obj in searched: + path.append( binding.name ) + searched[binding.obj] = True + binding.obj._search( obj, names, path, searched ) + path.pop() + + return + + ########################################################################### + # Private interface. + ########################################################################### + + def _get_context_adapter(self, obj): + """ Returns a context adapter for an object. + + Returns None if no such adapter is available. + + """ + + if self.type_manager is not None: + adapter = self.type_manager.object_as( + obj, Context, environment=self.environment, context=self + ) + + else: + adapter = None + + return adapter
+ +#### EOF ###################################################################### +
+ +
+
+
+
+
+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/_modules/apptools/naming/context_adapter.html b/4.5/_modules/apptools/naming/context_adapter.html similarity index 100% rename from _modules/apptools/naming/context_adapter.html rename to 4.5/_modules/apptools/naming/context_adapter.html diff --git a/_modules/apptools/naming/context_adapter_factory.html b/4.5/_modules/apptools/naming/context_adapter_factory.html similarity index 100% rename from _modules/apptools/naming/context_adapter_factory.html rename to 4.5/_modules/apptools/naming/context_adapter_factory.html diff --git a/4.5/_modules/apptools/naming/dir_context.html b/4.5/_modules/apptools/naming/dir_context.html new file mode 100644 index 000000000..97f34dee8 --- /dev/null +++ b/4.5/_modules/apptools/naming/dir_context.html @@ -0,0 +1,308 @@ + + + + + + + apptools.naming.dir_context — Apptools Documentation + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +

Source code for apptools.naming.dir_context

+#------------------------------------------------------------------------------
+# Copyright (c) 2005, Enthought, Inc.
+# All rights reserved.
+#
+# This software is provided without warranty under the terms of the BSD
+# license included in enthought/LICENSE.txt and may be redistributed only
+# under the conditions described in the aforementioned license.  The license
+# is also available online at http://www.enthought.com/licenses/BSD.txt
+# Thanks for using Enthought open source!
+#
+# Author: Enthought, Inc.
+# Description: <Enthought naming package component>
+#------------------------------------------------------------------------------
+""" The base class for all directory contexts. """
+
+
+# Enthought library imports.
+from traits.api import Dict
+
+# Local imports.
+from .context import Context
+from .exception import NameNotFoundError, NotContextError
+
+
+
[docs]class DirContext(Context): + """ The base class for all directory contexts. """ + + # The attributes of every object in the context. The attributes for the + # context itself have the empty string as the key. + # + # {str name : dict attributes} + _attributes = Dict + + ########################################################################### + # 'DirContext' interface. + ########################################################################### + +
[docs] def get_attributes(self, name): + """ Returns the attributes associated with a named object. """ + + # If the name is empty then we return the attributes of this context. + if len(name) == 0: + attributes = self._get_attributes(name) + + else: + # Parse the name. + components = self._parse_name(name) + + # If there is exactly one component in the name then the operation + # takes place in this context. + if len(components) == 1: + atom = components[0] + + if not self._is_bound(atom): + raise NameNotFoundError(name) + + # Do the actual get. + attributes = self._get_attributes(atom) + + # Otherwise, attempt to continue resolution into the next context. + else: + if not self._is_bound(components[0]): + raise NameNotFoundError(components[0]) + + next_context = self._get_next_context(components[0]) + attributes = next_context.get_attributes( + '/'.join(components[1:])) + + return attributes
+ +
[docs] def set_attributes(self, name, attributes): + """ Sets the attributes associated with a named object. """ + + # If the name is empty then we set the attributes of this context. + if len(name) == 0: + attributes = self._set_attributes(name, attributes) + + else: + # Parse the name. + components = self._parse_name(name) + + # If there is exactly one component in the name then the operation + # takes place in this context. + if len(components) == 1: + atom = components[0] + + if not self._is_bound(atom): + raise NameNotFoundError(name) + + # Do the actual set. + self._set_attributes(atom, attributes) + + # Otherwise, attempt to continue resolution into the next context. + else: + if not self._is_bound(components[0]): + raise NameNotFoundError(components[0]) + + next_context = self._get_next_context(components[0]) + next_context.set_attributes( + '/'.join(components[1:]), attributes + ) + + return
+ + # fixme: Non-JNDI +
[docs] def find_bindings(self, visitor): + """ Find bindings with attributes matching criteria in visitor. + + Visitor is a function that is passed the bindings for each level of the + heirarchy and the attribute dictionary for those bindings. The visitor + examines the bindings and dictionary and returns the bindings it is + interested in. + + """ + + bindings = visitor(self.list_bindings(), self._attributes) + + # recursively check other sub contexts. + for binding in self.list_bindings(): + obj = binding.obj + if isinstance(obj, DirContext): + bindings.extend(obj.find_bindings(visitor)) + + return bindings
+ + ########################################################################### + # Protected 'DirContext' interface. + ########################################################################### + + def _get_attributes(self, name): + """ Returns the attributes of an object in this context. """ + + attributes = self._attributes.setdefault(name, {}) + + return attributes.copy() + + def _set_attributes(self, name, attributes): + """ Sets the attributes of an object in this context. """ + + self._attributes[name] = attributes + + return + + ########################################################################### + # Protected 'Context' interface. + ########################################################################### + + def _unbind(self, name): + """ Unbinds a name from this context. """ + + super(DirContext, self)._unbind(name) + + if name in self._attributes: + del self._attributes[name] + + return + + def _rename(self, old_name, new_name): + """ Renames an object in this context. """ + + super(DirContext, self)._rename(old_name, new_name) + + if old_name in self._attributes: + self._attributes[new_name] = self._attributes[old_name] + del self._attributes[old_name] + + return + + def _destroy_subcontext(self, name): + """ Destroys a sub-context of this context. """ + + super(DirContext, self)._destroy_subcontext(name) + + if name in self._attributes: + del self._attributes[name] + + return
+ +#### EOF ###################################################################### +
+ +
+
+
+
+
+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/4.5/_modules/apptools/naming/dynamic_context.html b/4.5/_modules/apptools/naming/dynamic_context.html new file mode 100644 index 000000000..58dcd472d --- /dev/null +++ b/4.5/_modules/apptools/naming/dynamic_context.html @@ -0,0 +1,322 @@ + + + + + + + apptools.naming.dynamic_context — Apptools Documentation + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +

Source code for apptools.naming.dynamic_context

+#-----------------------------------------------------------------------------
+#
+#  Copyright (c) 2006 by Enthought, Inc.
+#  All rights reserved.
+#
+#-----------------------------------------------------------------------------
+
+""" Provider of a framework that dynamically determines the contents of a
+    context at the time of interaction with the contents rather than at the
+    time a class is written.
+
+    This capability is particularly useful when the object acting as a context
+    is part of a plug-in application -- such as Envisage.  In general, this
+    capability allows the context to be:
+
+    - Extendable by contributions from somewhere other than the original
+      code writer
+    - Dynamic in that the elements it is composed of can change each time
+      someone interacts with the contents of the context.
+
+    It should be noted that this capability is explicitly different from
+    contexts that look at another container to determine their contents, such
+    as a file system context!
+
+    Users of this framework contribute items to a dynamic context by adding
+    traits to the dynamic context instance.  (This addition can happen
+    statically through the use of a Traits Category.)  The trait value is the
+    context item's value and the trait definition's metadata determines how the
+    item is treated within the context.  The support metadata is:
+
+    context_name: A non-empty string
+        Represents the name of the item within this context.  This must be
+        present for the trait to show up as a context item though the value
+        may change over time as the item gets bound to different names.
+    context_order: A float value
+        Indicates the position for the item within this context.  All
+        dynamically contributed context items are sorted by ascending order
+        of this value using the standard list sort function.
+    is_context: A boolean value
+        True if the item is itself a context.
+"""
+
+# Standardlibrary imports
+import logging
+
+# Local imports
+from .binding import Binding
+from .context import Context
+from .exception import OperationNotSupportedError
+
+
+# Setup a logger for this module.
+logger = logging.getLogger(__name__)
+
+
+
[docs]class DynamicContext(Context): + """ A framework that dynamically determines the contents of a context at + the time of interaction with the contents rather than at the time a + context class is written. + + It should be noted that this capability is explicitly different from + contexts that look at another container to determine their contents, + such as a file system context! + """ + + ########################################################################## + # 'Context' interface. + ########################################################################## + + ### protected interface ################################################## + + def _is_bound(self, name): + """ Is a name bound in this context? + """ + + item = self._get_contributed_context_item(name) + result = item != (None, None) + + return result + + + def _is_context(self, name): + """ Returns True if a name is bound to a context. + """ + item = self._get_contributed_context_item(name) + if item != (None, None): + obj, trait = item + result = True == trait.is_context + else: + result = False + + return result + + + def _list_bindings(self): + """ Lists the bindings in this context. + """ + result = [ Binding(name=n, obj=o, context=self) for n, o, t in \ + self._get_contributed_context_items() ] + + return result + + + def _list_names(self): + """ Lists the names bound in this context. + """ + result = [ n for n, o, t in self._get_contributed_context_items() ] + + return result + + + def _lookup(self, name): + """ Looks up a name in this context. + """ + item = self._get_contributed_context_item(name) + if item != (None, None): + obj, trait = item + result = obj + else: + result = None + + return result + + + def _rename(self, old_name, new_name): + """ Renames an object in this context. + """ + + item = self._get_contributed_context_item(old_name) + if item != (None, None): + obj, trait = item + trait.context_name = new_name + else: + raise ValueError('Name "%s" not in context', old_name) + + + def _unbind(self, name): + """ Unbinds a name from this context. + """ + # It is an error to try to unbind any contributed context items + item = self._get_contributed_context_item(name) + if item != (None, None): + raise OperationNotSupportedError('Unable to unbind ' + \ + 'built-in with name [%s]' % name) + + + ########################################################################## + # 'DynamicContext' interface. + ########################################################################## + + ### protected interface ################################################## + + def _get_contributed_context_item(self, name): + """ If the specified name matches a contributed context item then + returns a tuple of the item's current value and trait definition + (in that order.) Otherwise, returns a tuple of (None, None). + """ + result = (None, None) + + for n, o, t in self._get_contributed_context_items(): + if n == name: + result = (o, t) + + return result + + + def _get_contributed_context_items(self): + """ Returns an ordered list of items to be treated as part of our + context. + + Each item in the list is a tuple of its name, object, and trait + definition (in that order.) + """ + # Our traits that get treated as context items are those that declare + # themselves via metadata on the trait definition. + filter = { + 'context_name': lambda v: v is not None and len(v) > 0 + } + traits = self.traits(**filter) + + # Sort the list of context items according to the name of the item. + traits = [ (t.context_order, n, t) for n, t in traits.items() ] + traits.sort() + + # Convert these trait definitions into a list of name and object tuples. + result = [(t.context_name, getattr(self, n), t) for order, n, t \ + in traits] + + return result
+ + +### EOF ###################################################################### + +
+ +
+
+
+
+
+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/4.5/_modules/apptools/naming/exception.html b/4.5/_modules/apptools/naming/exception.html new file mode 100644 index 000000000..5a6e22135 --- /dev/null +++ b/4.5/_modules/apptools/naming/exception.html @@ -0,0 +1,189 @@ + + + + + + + apptools.naming.exception — Apptools Documentation + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +

Source code for apptools.naming.exception

+#------------------------------------------------------------------------------
+# Copyright (c) 2005, Enthought, Inc.
+# All rights reserved.
+#
+# This software is provided without warranty under the terms of the BSD
+# license included in enthought/LICENSE.txt and may be redistributed only
+# under the conditions described in the aforementioned license.  The license
+# is also available online at http://www.enthought.com/licenses/BSD.txt
+# Thanks for using Enthought open source!
+#
+# Author: Enthought, Inc.
+# Description: <Enthought naming package component>
+#------------------------------------------------------------------------------
+""" Naming exceptions. """
+
+
+
[docs]class NamingError(Exception): + """ Base class for all naming exceptions. + + """
+ +
[docs]class InvalidNameError(NamingError): + """ Invalid name. + + This exception is thrown when the name passed to a naming operation does + not conform to the syntax of the naming system (or is empty etc). + + """
+ +
[docs]class NameAlreadyBoundError(NamingError): + """ Name already bound. + + This exception is thrown when an attempt is made to bind a name that is + already bound in the current context. + + """
+ +
[docs]class NameNotFoundError(NamingError): + """ Name not found. + + This exception is thrown when a component of a name cannot be resolved + because it is not bound in the current context. + + """
+ +
[docs]class NotContextError(NamingError): + """ Not a context. + + This exception is thrown when a naming operation has reached a point where + a context is required to continue the operation, but the resolved object + is not a context. + + """
+ +
[docs]class OperationNotSupportedError(NamingError): + """ The context does support the requested operation. + + """
+ +#### EOF ###################################################################### +
+ +
+
+
+
+
+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/4.5/_modules/apptools/naming/initial_context.html b/4.5/_modules/apptools/naming/initial_context.html new file mode 100644 index 000000000..ffe407dd7 --- /dev/null +++ b/4.5/_modules/apptools/naming/initial_context.html @@ -0,0 +1,191 @@ + + + + + + + apptools.naming.initial_context — Apptools Documentation + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +

Source code for apptools.naming.initial_context

+#------------------------------------------------------------------------------
+# Copyright (c) 2005, Enthought, Inc.
+# All rights reserved.
+#
+# This software is provided without warranty under the terms of the BSD
+# license included in enthought/LICENSE.txt and may be redistributed only
+# under the conditions described in the aforementioned license.  The license
+# is also available online at http://www.enthought.com/licenses/BSD.txt
+# Thanks for using Enthought open source!
+#
+# Author: Enthought, Inc.
+# Description: <Enthought naming package component>
+#------------------------------------------------------------------------------
+""" The starting point for performing naming operations. """
+
+
+# Local imports.
+from .context import Context
+
+
+
[docs]def InitialContext(environment): + """ Creates an initial context for beginning name resolution. """ + + # Get the class name of the factory that will produce the initial context. + klass_name = environment.get(Context.INITIAL_CONTEXT_FACTORY) + if klass_name is None: + raise ValueError("No initial context factory specified") + + # Import the factory class. + klass = _import_symbol(klass_name) + + # Create the factory. + factory = klass() + + # Ask the factory for a context implementation instance. + return factory.get_initial_context(environment)
+ + +# fixme: This is the same code as in the Envisage import manager but we don't +# want naming to be dependent on Envisage, so we need some other package +# for useful 'Python' tools etc. +def _import_symbol(symbol_path): + """ Imports the symbol defined by 'symbol_path'. + + 'symbol_path' is a string in the form 'foo.bar.baz' which is turned + into an import statement 'from foo.bar import baz' (ie. the last + component of the name is the symbol name, the rest is the package/ + module path to load it from). + + """ + + components = symbol_path.split('.') + + module_name = '.'.join(components[:-1]) + symbol_name = components[-1] + + module = __import__(module_name, globals(), locals(), [symbol_name]) + symbol = getattr(module, symbol_name) + + return symbol + +#### EOF ###################################################################### +
+ +
+
+
+
+
+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/4.5/_modules/apptools/naming/initial_context_factory.html b/4.5/_modules/apptools/naming/initial_context_factory.html new file mode 100644 index 000000000..b4d91647b --- /dev/null +++ b/4.5/_modules/apptools/naming/initial_context_factory.html @@ -0,0 +1,165 @@ + + + + + + + apptools.naming.initial_context_factory — Apptools Documentation + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +

Source code for apptools.naming.initial_context_factory

+#------------------------------------------------------------------------------
+# Copyright (c) 2005, Enthought, Inc.
+# All rights reserved.
+#
+# This software is provided without warranty under the terms of the BSD
+# license included in enthought/LICENSE.txt and may be redistributed only
+# under the conditions described in the aforementioned license.  The license
+# is also available online at http://www.enthought.com/licenses/BSD.txt
+# Thanks for using Enthought open source!
+#
+# Author: Enthought, Inc.
+# Description: <Enthought naming package component>
+#------------------------------------------------------------------------------
+""" The base class for all initial context factories. """
+
+
+# Enthought library imports.
+from traits.api import HasTraits
+
+# Local imports.
+from .context import Context
+
+
+
[docs]class InitialContextFactory(HasTraits): + """ The base class for all initial context factories. """ + + ########################################################################### + # 'InitialContextFactory' interface. + ########################################################################### + +
[docs] def get_initial_context(self, environment): + """ Creates an initial context for beginning name resolution. """ + + return Context(environment=environment)
+ +#### EOF ###################################################################### +
+ +
+
+
+
+
+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/4.5/_modules/apptools/naming/naming_event.html b/4.5/_modules/apptools/naming/naming_event.html new file mode 100644 index 000000000..41de0f64d --- /dev/null +++ b/4.5/_modules/apptools/naming/naming_event.html @@ -0,0 +1,163 @@ + + + + + + + apptools.naming.naming_event — Apptools Documentation + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +

Source code for apptools.naming.naming_event

+#------------------------------------------------------------------------------
+# Copyright (c) 2005, Enthought, Inc.
+# All rights reserved.
+#
+# This software is provided without warranty under the terms of the BSD
+# license included in enthought/LICENSE.txt and may be redistributed only
+# under the conditions described in the aforementioned license.  The license
+# is also available online at http://www.enthought.com/licenses/BSD.txt
+# Thanks for using Enthought open source!
+#
+# Author: Enthought, Inc.
+# Description: <Enthought naming package component>
+#------------------------------------------------------------------------------
+""" The event fired by the tree model when it changes. """
+
+
+# Enthought library imports.
+from traits.api import HasTraits, Instance
+
+# Local imports.
+from .binding import Binding
+
+
+# Classes for event traits.
+
[docs]class NamingEvent(HasTraits): + """ Information about tree model changes. """ + + # The old binding. + old_binding = Instance(Binding) + + # The new binding. + new_binding = Instance(Binding)
+ +#### EOF ###################################################################### +
+ +
+
+
+
+
+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/4.5/_modules/apptools/naming/naming_manager.html b/4.5/_modules/apptools/naming/naming_manager.html new file mode 100644 index 000000000..d46a20642 --- /dev/null +++ b/4.5/_modules/apptools/naming/naming_manager.html @@ -0,0 +1,219 @@ + + + + + + + apptools.naming.naming_manager — Apptools Documentation + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +

Source code for apptools.naming.naming_manager

+#------------------------------------------------------------------------------
+# Copyright (c) 2005, Enthought, Inc.
+# All rights reserved.
+#
+# This software is provided without warranty under the terms of the BSD
+# license included in enthought/LICENSE.txt and may be redistributed only
+# under the conditions described in the aforementioned license.  The license
+# is also available online at http://www.enthought.com/licenses/BSD.txt
+# Thanks for using Enthought open source!
+#
+# Author: Enthought, Inc.
+# Description: <Enthought naming package component>
+#------------------------------------------------------------------------------
+""" The naming manager. """
+
+
+# Enthought library imports.
+from traits.api import HasTraits
+
+
+
[docs]class NamingManager(HasTraits): + """ The naming manager. """ + + ########################################################################### + # 'NamingManager' interface. + ########################################################################### + +
[docs] def get_state_to_bind(self, obj, name, context): + """ Returns the state of an object for binding. + + The naming manager asks the context for its list of STATE factories + and then calls them one by one until it gets a non-None result + indicating that the factory recognised the object and created state + information for it. + + If none of the factories recognize the object (or if the context + has no factories) then the object itself is returned. + + """ + + # Local imports. + from .context import Context + + # We get the state factories from the context's environment. + state_factories = context.environment[Context.STATE_FACTORIES] + + for state_factory in state_factories: + state = state_factory.get_state_to_bind(obj, name, context) + if state is not None: + break + + else: + state = obj + + return state
+ +
[docs] def get_object_instance(self, info, name, context): + """ Creates an object using the specified state information. + + The naming manager asks the context for its list of OBJECT factories + and calls them one by one until it gets a non-None result, indicating + that the factory recognised the information and created an object. + + If none of the factories recognize the state information (or if the + context has no factories) then the state information itself is + returned. + + """ + + # Local imports. + from .context import Context + + # We get the object factories from the context's environment. + object_factories = context.environment[Context.OBJECT_FACTORIES] + + for object_factory in object_factories: + obj = object_factory.get_object_instance(info, name, context) + if obj is not None: + break + + else: + obj = info + + return obj
+ + +# Singleton instance. +naming_manager = NamingManager() + +### EOF ####################################################################### +
+ +
+
+
+
+
+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/4.5/_modules/apptools/naming/object_factory.html b/4.5/_modules/apptools/naming/object_factory.html new file mode 100644 index 000000000..e1f681add --- /dev/null +++ b/4.5/_modules/apptools/naming/object_factory.html @@ -0,0 +1,172 @@ + + + + + + + apptools.naming.object_factory — Apptools Documentation + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +

Source code for apptools.naming.object_factory

+#------------------------------------------------------------------------------
+# Copyright (c) 2005, Enthought, Inc.
+# All rights reserved.
+#
+# This software is provided without warranty under the terms of the BSD
+# license included in enthought/LICENSE.txt and may be redistributed only
+# under the conditions described in the aforementioned license.  The license
+# is also available online at http://www.enthought.com/licenses/BSD.txt
+# Thanks for using Enthought open source!
+#
+# Author: Enthought, Inc.
+# Description: <Enthought naming package component>
+#------------------------------------------------------------------------------
+""" The base class for all object factories. """
+
+
+# Enthought library imports.
+from traits.api import HasTraits
+
+
+
[docs]class ObjectFactory(HasTraits): + """ The base class for all object factories. + + An object factory accepts some information about how to create an object + (such as a reference) and returns an instance of that object. + + """ + + ########################################################################### + # 'ObjectFactory' interface. + ########################################################################### + +
[docs] def get_object_instance(self, state, name, context): + """ Creates an object using the specified state information. + + Returns None if the factory cannot create the object (ie. it does not + recognise the state passed to it). + + """ + + raise NotImplementedError
+ +### EOF ####################################################################### +
+ +
+
+
+
+
+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/4.5/_modules/apptools/naming/object_serializer.html b/4.5/_modules/apptools/naming/object_serializer.html new file mode 100644 index 000000000..d42ab950f --- /dev/null +++ b/4.5/_modules/apptools/naming/object_serializer.html @@ -0,0 +1,229 @@ + + + + + + + apptools.naming.object_serializer — Apptools Documentation + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +

Source code for apptools.naming.object_serializer

+#------------------------------------------------------------------------------
+# Copyright (c) 2005, Enthought, Inc.
+# All rights reserved.
+#
+# This software is provided without warranty under the terms of the BSD
+# license included in enthought/LICENSE.txt and may be redistributed only
+# under the conditions described in the aforementioned license.  The license
+# is also available online at http://www.enthought.com/licenses/BSD.txt
+# Thanks for using Enthought open source!
+#
+# Author: Enthought, Inc.
+# Description: <Enthought naming package component>
+#------------------------------------------------------------------------------
+""" The base class for all object serializers. """
+
+
+# Standard library imports.
+import logging
+from traceback import print_exc
+from os.path import splitext
+#import cPickle
+#import pickle
+
+# Enthought library imports.
+import apptools.sweet_pickle as sweet_pickle
+from traits.api import HasTraits, Str
+
+
+# Setup a logger for this module.
+logger = logging.getLogger(__name__)
+
+
+
[docs]class ObjectSerializer(HasTraits): + """ The base class for all object serializers. """ + + #### 'ObjectSerializer' interface ######################################### + + # The file extension recognized by this serializer. + ext = Str('.pickle') + + ########################################################################### + # 'ObjectSerializer' interface. + ########################################################################### + +
[docs] def can_load(self, path): + """ Returns True if the serializer can load a file. """ + + rest, ext = splitext(path) + + return ext == self.ext
+ +
[docs] def load(self, path): + """ Loads an object from a file. """ + + # Unpickle the object. + f = open(path, 'rb') + try: + try: + obj = sweet_pickle.load(f) +# obj = cPickle.load(f) +# obj = pickle.load(f) + except Exception as ex: + print_exc() + logger.exception( "Failed to load pickle file: %s, %s" % (path, ex)) + + raise + finally: + f.close() + + return obj
+ +
[docs] def can_save(self, obj): + """ Returns True if the serializer can save an object. """ + + return True
+ +
[docs] def save(self, path, obj): + """ Saves an object to a file. """ + + if not path.endswith(self.ext): + actual_path = path + self.ext + + else: + actual_path = path + + # Pickle the object. + f = open(actual_path, 'wb') + try: + sweet_pickle.dump(obj, f, 1) +# cPickle.dump(obj, f, 1) +# pickle.dump(obj, f, 1) + except Exception as ex: + logger.exception( "Failed to pickle into file: %s, %s, object:%s" + % (path, ex, obj)) + print_exc() + f.close() + + return actual_path
+ +### EOF ####################################################################### +
+ +
+
+
+
+
+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/4.5/_modules/apptools/naming/py_context.html b/4.5/_modules/apptools/naming/py_context.html new file mode 100644 index 000000000..7e76fa8d1 --- /dev/null +++ b/4.5/_modules/apptools/naming/py_context.html @@ -0,0 +1,335 @@ + + + + + + + apptools.naming.py_context — Apptools Documentation + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +

Source code for apptools.naming.py_context

+#------------------------------------------------------------------------------
+# Copyright (c) 2005, Enthought, Inc.
+# All rights reserved.
+#
+# This software is provided without warranty under the terms of the BSD
+# license included in enthought/LICENSE.txt and may be redistributed only
+# under the conditions described in the aforementioned license.  The license
+# is also available online at http://www.enthought.com/licenses/BSD.txt
+# Thanks for using Enthought open source!
+#
+# Author: Enthought, Inc.
+# Description: <Enthought naming package component>
+#------------------------------------------------------------------------------
+""" A naming context for a Python namespace. """
+
+
+# Enthought library imports.
+from traits.api import Any, Dict, Instance, Property
+
+# Local imports.
+from .address import Address
+from .binding import Binding
+from .context import Context
+from .naming_manager import naming_manager
+from .py_object_factory import PyObjectFactory
+from .reference import Reference
+from .referenceable import Referenceable
+from .referenceable_state_factory import ReferenceableStateFactory
+
+
+# The default environment.
+ENVIRONMENT = {
+    # 'Context' properties.
+    Context.OBJECT_FACTORIES : [PyObjectFactory()],
+    Context.STATE_FACTORIES  : [ReferenceableStateFactory()],
+}
+
+
+
[docs]class PyContext(Context, Referenceable): + """ A naming context for a Python namespace. """ + + #### 'Context' interface ################################################## + + # The naming environment in effect for this context. + environment = Dict(ENVIRONMENT) + + #### 'PyContext' interface ################################################ + + # The Python namespace that we represent. + namespace = Any + + # If the namespace is actual a Python object that has a '__dict__' + # attribute, then this will be that object (the namespace will be the + # object's '__dict__'. + obj = Any + + #### 'Referenceable' interface ############################################ + + # The object's reference suitable for binding in a naming context. + reference = Property(Instance(Reference)) + + ########################################################################### + # 'object' interface. + ########################################################################### + + def __init__(self, **traits): + """ Creates a new context. """ + + # Base class constructor. + super(PyContext, self).__init__(**traits) + + if type(self.namespace) is not dict: + if hasattr(self.namespace, '__dict__'): + self.obj = self.namespace + self.namespace = self.namespace.__dict__ + + else: + raise ValueError('Need a dictionary or a __dict__ attribute') + + return + + ########################################################################### + # 'Referenceable' interface. + ########################################################################### + + #### Properties ########################################################### + + def _get_reference(self): + """ Returns a reference to this object suitable for binding. """ + + reference = Reference( + class_name = self.__class__.__name__, + addresses = [Address(type='py_context', content=self.namespace)] + ) + + return reference + + ########################################################################### + # Protected 'Context' interface. + ########################################################################### + + def _is_bound(self, name): + """ Is a name bound in this context? """ + + return name in self.namespace + + def _lookup(self, name): + """ Looks up a name in this context. """ + + obj = self.namespace[name] + + return naming_manager.get_object_instance(obj, name, self) + + def _bind(self, name, obj): + """ Binds a name to an object in this context. """ + + state = naming_manager.get_state_to_bind(obj, name,self) + self.namespace[name] = state + + # Trait event notification. + # An "added" event is fired by the bind method of the base calss (which calls + # this one), so we don't need to do the changed here (which would be the wrong + # thing anyway) -- LGV + # + # self.trait_property_changed('context_changed', None, None) + + return + + def _rebind(self, name, obj): + """ Rebinds a name to a object in this context. """ + + self._bind(name, obj) + + return + + def _unbind(self, name): + """ Unbinds a name from this context. """ + + del self.namespace[name] + + # Trait event notification. + self.trait_property_changed('context_changed', None, None) + + return + + def _rename(self, old_name, new_name): + """ Renames an object in this context. """ + + state = self.namespace[old_name] + + # Bind the new name. + self.namespace[new_name] = state + + # Unbind the old one. + del self.namespace[old_name] + + # Trait event notification. + self.context_changed = True + + return + + def _create_subcontext(self, name): + """ Creates a sub-context of this context. """ + + sub = self._context_factory(name, {}) + self.namespace[name] = sub + + # Trait event notification. + self.trait_property_changed('context_changed', None, None) + + return sub + + def _destroy_subcontext(self, name): + """ Destroys a sub-context of this context. """ + + del self.namespace[name] + + # Trait event notification. + self.trait_property_changed('context_changed', None, None) + + return + + def _list_bindings(self): + """ Lists the bindings in this context. """ + + bindings = [] + for name, value in self.namespace.items(): + bindings.append(Binding(name=name, obj=self._lookup(name), + context=self)) + return bindings + + def _list_names(self): + """ Lists the names bound in this context. """ + + return list(self.namespace.keys()) + + ########################################################################### + # Private interface. + ########################################################################### + + def _context_factory(self, name, namespace): + """ Create a sub-context. """ + + return self.__class__(namespace=namespace)
+ +#### EOF ###################################################################### +
+ +
+
+
+
+
+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/4.5/_modules/apptools/naming/py_object_factory.html b/4.5/_modules/apptools/naming/py_object_factory.html new file mode 100644 index 000000000..81d0b3fe3 --- /dev/null +++ b/4.5/_modules/apptools/naming/py_object_factory.html @@ -0,0 +1,176 @@ + + + + + + + apptools.naming.py_object_factory — Apptools Documentation + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +

Source code for apptools.naming.py_object_factory

+#------------------------------------------------------------------------------
+# Copyright (c) 2005, Enthought, Inc.
+# All rights reserved.
+#
+# This software is provided without warranty under the terms of the BSD
+# license included in enthought/LICENSE.txt and may be redistributed only
+# under the conditions described in the aforementioned license.  The license
+# is also available online at http://www.enthought.com/licenses/BSD.txt
+# Thanks for using Enthought open source!
+#
+# Author: Enthought, Inc.
+# Description: <Enthought naming package component>
+#------------------------------------------------------------------------------
+""" Object factory for Python namespace contexts. """
+
+
+# Local imports.
+from .object_factory import ObjectFactory
+from .reference import Reference
+
+
+
[docs]class PyObjectFactory(ObjectFactory): + """ Object factory for Python namespace contexts. """ + + ########################################################################### + # 'ObjectFactory' interface. + ########################################################################### + +
[docs] def get_object_instance(self, state, name, context): + """ Creates an object using the specified state information. """ + + obj = None + + if isinstance(state, Reference): + if len(state.addresses) > 0: + if state.addresses[0].type == 'py_context': + namespace = state.addresses[0].content + obj = context._context_factory(name, namespace) + + elif hasattr(state, '__dict__'): + from apptools.naming.py_context import PyContext + if not isinstance(state, PyContext): + obj = context._context_factory(name, state) + + return obj
+ +### EOF ####################################################################### +
+ +
+
+
+
+
+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/4.5/_modules/apptools/naming/pyfs_context.html b/4.5/_modules/apptools/naming/pyfs_context.html new file mode 100644 index 000000000..2f64e4cf0 --- /dev/null +++ b/4.5/_modules/apptools/naming/pyfs_context.html @@ -0,0 +1,709 @@ + + + + + + + apptools.naming.pyfs_context — Apptools Documentation + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +

Source code for apptools.naming.pyfs_context

+#------------------------------------------------------------------------------
+# Copyright (c) 2005, Enthought, Inc.
+# All rights reserved.
+#
+# This software is provided without warranty under the terms of the BSD
+# license included in enthought/LICENSE.txt and may be redistributed only
+# under the conditions described in the aforementioned license.  The license
+# is also available online at http://www.enthought.com/licenses/BSD.txt
+# Thanks for using Enthought open source!
+#
+# Author: Enthought, Inc.
+# Description: <Enthought naming package component>
+#------------------------------------------------------------------------------
+""" A Python File System context. """
+
+
+# Standard library imports.
+import glob
+import logging
+import os
+from os.path import join, splitext
+
+# Third-party library imports.
+import six.moves.cPickle as pickle
+
+# Enthought library imports.
+from apptools.io.api import File
+from traits.api import Any, Dict, Instance, Property, Str
+
+# Local imports.
+from .address import Address
+from .binding import Binding
+from .context import Context
+from .dir_context import DirContext
+from .exception import NameNotFoundError, NotContextError
+from .naming_event import NamingEvent
+from .naming_manager import naming_manager
+from .object_serializer import ObjectSerializer
+from .pyfs_context_factory import PyFSContextFactory
+from .pyfs_object_factory import PyFSObjectFactory
+from .pyfs_state_factory import PyFSStateFactory
+from .reference import Reference
+from .referenceable import Referenceable
+
+
+# Setup a logger for this module.
+logger = logging.getLogger(__name__)
+
+
+# The name of the 'special' file in which we store object attributes.
+ATTRIBUTES_FILE = '__attributes__'
+
+# Constants for environment property keys.
+FILTERS = "apptools.naming.pyfs.filters"
+OBJECT_SERIALIZERS = "apptools.naming.pyfs.object.serializers"
+
+
+# The default environment.
+ENVIRONMENT = {
+    #### 'Context' properties #################################################
+
+    # Object factories.
+    Context.OBJECT_FACTORIES : [PyFSObjectFactory(), PyFSContextFactory()],
+
+    # State factories.
+    Context.STATE_FACTORIES  : [PyFSStateFactory()],
+
+    #### 'PyFSContext' properties #############################################
+
+    # Object serializers.
+    OBJECT_SERIALIZERS : [ObjectSerializer()],
+
+    # List of filename patterns to ignore.  These patterns are passed to
+    # 'glob.glob', so things like '*.pyc' will do what you expect.
+    #
+    # fixme: We should have a generalized filter mechanism here, and '.svn'
+    # should be moved elsewhere!
+    FILTERS : [ATTRIBUTES_FILE, '.svn']
+}
+
+
+
[docs]class PyFSContext(DirContext, Referenceable): + """ A Python File System context. + + This context represents a directory on a local file system. + + """ + + # The name of the 'special' file in which we store object attributes. + ATTRIBUTES_FILE = ATTRIBUTES_FILE + + # Environment property keys. + FILTERS = FILTERS + OBJECT_SERIALIZERS = OBJECT_SERIALIZERS + + #### 'Context' interface ################################################## + + # The naming environment in effect for this context. + environment = Dict(ENVIRONMENT) + + # The name of the context within its own namespace. + namespace_name = Property(Str) + + #### 'PyFSContext' interface ############################################## + + # The name of the context (the last component of the path). + name = Str + + # The path name of the directory on the local file system. + path = Str + + #### 'Referenceable' interface ############################################ + + # The object's reference suitable for binding in a naming context. + reference = Property(Instance(Reference)) + + #### Private interface #################################################### + + # A mapping from bound name to the name of the corresponding file or + # directory on the file system. + _name_to_filename_map = Dict#(Str, Str) + + # The attributes of every object in the context. The attributes for the + # context itself have the empty string as the key. + # + # {str name : dict attributes} + # + # fixme: Don't use 'Dict' here as it causes problems when pickling because + # trait dicts have a reference back to the parent object (hence we end up + # pickling all kinds of things that we don't need or want to!). + _attributes = Any + + ########################################################################### + # 'object' interface. + ########################################################################### + + def __init__(self, **traits): + """ Creates a new context. """ + + # Base class constructor. + super(PyFSContext, self).__init__(**traits) + + # We cache each object as it is looked up so that all accesses to a + # serialized Python object return a reference to exactly the same one. + self._cache = {} + + return + + ########################################################################### + # 'PyFSContext' interface. + ########################################################################### + + #### Properties ########################################################### + + def _get_namespace_name(self): + """ Returns the name of the context within its own namespace. """ + + # fixme: clean this up with an initial context API! + if 'root' in self.environment: + root = self.environment['root'] + + namespace_name = self.path[len(root) + 1:] + + else: + namespace_name = self.path + + # fixme: This is a bit dodgy 'cos we actually return a name that can + # be looked up, and not the file system name... + namespace_name = '/'.join(namespace_name.split(os.path.sep)) + + return namespace_name + + #### methods ############################################################## + +
[docs] def refresh(self): + """ Refresh the context to reflect changes in the file system. """ + + # fixme: This needs more work 'cos if we refresh a context then we + # will load new copies of serialized Python objects! + + # This causes the initializer to run again the next time the trait is + # accessed. + self.reset_traits(['_name_to_filename_map']) + + # Clear out the cache. + self._cache = {} + + # fixme: This is a bit hacky since the context in the binding may + # not be None! + self.context_changed = NamingEvent( + new_binding=Binding(name=self.name, obj=self, context=None) + ) + + return
+ + ########################################################################### + # 'Referenceable' interface. + ########################################################################### + + #### Properties ########################################################### + + def _get_reference(self): + """ Returns a reference to this object suitable for binding. """ + + abspath = os.path.abspath(self.path) + + reference = Reference( + class_name = self.__class__.__name__, + addresses = [Address(type='pyfs_context', content=abspath)] + ) + + return reference + + ########################################################################### + # Protected 'Context' interface. + ########################################################################### + + def _is_bound(self, name): + """ Is a name bound in this context? """ + + return name in self._name_to_filename_map + + def _lookup(self, name): + """ Looks up a name in this context. """ + + if name in self._cache: + obj = self._cache[name] + + else: + # Get the full path to the file. + path = join(self.path, self._name_to_filename_map[name]) + + # If the file contains a serialized Python object then load it. + for serializer in self._get_object_serializers(): + if serializer.can_load(path): + try: + state = serializer.load(path) + + # If the load fails then we create a generic file resource + # (the idea being that it might be useful to have access to + # the file to see what went wrong). + except: + state = File(path) + logger.exception('Error loading resource at %s' % path) + + break + + # Otherwise, it must just be a file or folder. + else: + # Directories are contexts. + if os.path.isdir(path): + state = self._context_factory(name, path) + + # Files are just files! + elif os.path.isfile(path): + state = File(path) + + else: + raise ValueError('unrecognized file for %s' % name) + + # Get the actual object from the naming manager. + obj = naming_manager.get_object_instance(state, name, self) + + # Update the cache. + self._cache[name] = obj + + return obj + + def _bind(self, name, obj): + """ Binds a name to an object in this context. """ + + # Get the actual state to bind from the naming manager. + state = naming_manager.get_state_to_bind(obj, name, self) + + # If the object is actually an abstract file then we don't have to + # do anything. + if isinstance(state, File): + if not state.exists: + state.create_file() + + filename = name + + # Otherwise we are binding an arbitrary Python object, so find a + # serializer for it. + else: + for serializer in self._get_object_serializers(): + if serializer.can_save(obj): + path = serializer.save(join(self.path, name), obj) + filename = os.path.basename(path) + break + + else: + raise ValueError('cannot serialize object %s' % name) + + # Update the name to filename map. + self._name_to_filename_map[name] = filename + + # Update the cache. + self._cache[name] = obj + + return state + + def _rebind(self, name, obj): + """ Rebinds a name to an object in this context. """ + + # We unbind first to make sure that the old file gets removed (this + # is handy if the object that we are rebinding has a different + # serializer than the current one). + #self._unbind(name) + + self._bind(name, obj) + + return + + def _unbind(self, name): + """ Unbinds a name from this context. """ + + # Get the full path to the file. + path = join(self.path, self._name_to_filename_map[name]) + + # Remove it! + f = File(path) + f.delete() + + # Update the name to filename map. + del self._name_to_filename_map[name] + + # Update the cache. + if name in self._cache: + del self._cache[name] + + # Remove any attributes. + if name in self._attributes: + del self._attributes[name] + self._save_attributes() + + return + + def _rename(self, old_name, new_name): + """ Renames an object in this context. """ + + # Get the old filename. + old_filename = self._name_to_filename_map[old_name] + old_file = File(join(self.path, old_filename)) + + # Lookup the object bound to the old name. This has the side effect + # of adding the object to the cache under the name 'old_name'. + obj = self._lookup(old_name) + + # We are renaming a LOCAL context (ie. a folder)... + if old_file.is_folder: + # Create the new filename. + new_filename = new_name + new_file = File(join(self.path, new_filename)) + + # Move the folder. + old_file.move(new_file) + + # Update the 'Context' object. + obj.path = new_file.path + + # Update the cache. + self._cache[new_name] = obj + del self._cache[old_name] + + # Refreshing the context makes sure that all of its contents + # reflect the new name (i.e., sub-folders and files have the + # correct path). + # + # fixme: This currently results in new copies of serialized + # Python objects! We need to be a bit more judicious in the + # refresh. + obj.refresh() + + # We are renaming a file... + elif isinstance(obj, File): + # Create the new filename. + new_filename = new_name + new_file = File(join(self.path, new_filename)) + + # Move the file. + old_file.move(new_file) + + # Update the 'File' object. + obj.path = new_file.path + + # Update the cache. + self._cache[new_name] = obj + del self._cache[old_name] + + # We are renaming a serialized Python object... + else: + # Create the new filename. + new_filename = new_name + old_file.ext + new_file = File(join(self.path, new_filename)) + + old_file.delete() + + # Update the cache. + if old_name in self._cache: + self._cache[new_name] = self._cache[old_name] + del self._cache[old_name] + + # Force the creation of the new file. + # + # fixme: I'm not sure that this is really the place for this. We + # do it because often the 'name' of the object is actually an + # attribute of the object itself, and hence we want the serialized + # state to reflect the new name... Hmmm... + self._rebind(new_name, obj) + + # Update the name to filename map. + del self._name_to_filename_map[old_name] + self._name_to_filename_map[new_name] = new_filename + + # Move any attributes over to the new name. + if old_name in self._attributes: + self._attributes[new_name] = self._attributes[old_name] + del self._attributes[old_name] + self._save_attributes() + + return + + def _create_subcontext(self, name): + """ Creates a sub-context of this context. """ + + path = join(self.path, name) + + # Create a directory. + os.mkdir(path) + + # Create a sub-context that represents the directory. + sub = self._context_factory(name, path) + + # Update the name to filename map. + self._name_to_filename_map[name] = name + + # Update the cache. + self._cache[name] = sub + + return sub + + def _destroy_subcontext(self, name): + """ Destroys a sub-context of this context. """ + + return self._unbind(name) + + def _list_names(self): + """ Lists the names bound in this context. """ + + return list(self._name_to_filename_map.keys()) + + # fixme: YFI this is not part of the protected 'Context' interface so + # what is it doing here? +
[docs] def get_unique_name(self, name): + + ext = splitext(name)[1] + + # specially handle '.py' files + if ext != '.py': + return super(PyFSContext, self).get_unique_name(name) + + body = splitext(name)[0] + names = self.list_names() + i = 2 + unique = name + while unique in names: + unique = body + '_' + str(i) + '.py' + i += 1 + + return unique
+ + ########################################################################### + # Protected 'DirContext' interface. + ########################################################################### + + def _get_attributes(self, name): + """ Returns the attributes of an object in this context. """ + + attributes = self._attributes.setdefault(name, {}) + + return attributes.copy() + + def _set_attributes(self, name, attributes): + """ Sets the attributes of an object in this context. """ + + self._attributes[name] = attributes + self._save_attributes() + + return + + ########################################################################### + # Private interface. + ########################################################################### + + def _get_filters(self): + """ Returns the filters for this context. """ + + return self.environment.get(self.FILTERS, []) + + def _get_object_serializers(self): + """ Returns the object serializers for this context. """ + + return self.environment.get(self.OBJECT_SERIALIZERS, []) + + def _context_factory(self, name, path): + """ Create a sub-context. """ + + return self.__class__(path=path, environment=self.environment) + + def _save_attributes(self): + """ Saves all attributes to the attributes file. """ + + path = join(self.path, self.ATTRIBUTES_FILE) + + f = open(path, 'wb') + pickle.dump(self._attributes, f, 1) + f.close() + + return + + #### Trait initializers ################################################### + + def __name_to_filename_map_default(self): + """ Initializes the '_name_to_filename' trait. """ + + # fixme: We should have a generalized filter mechanism (instead of + # just 'glob' patterns we should have filter objects that can be a bit + # more flexible in how they do the filtering). + patterns = [join(self.path, filter) for filter in self._get_filters()] + + name_to_filename_map = {} + for filename in os.listdir(self.path): + path = join(self.path, filename) + for pattern in patterns: + if path in glob.glob(pattern): + break + + else: + for serializer in self._get_object_serializers(): + if serializer.can_load(filename): + # fixme: We should probably get the name from the + # serializer instead of assuming that we can just + # drop the file exension. + name, ext = os.path.splitext(filename) + break + + else: + name = filename + + name_to_filename_map[name] = filename + + return name_to_filename_map + + def __attributes_default(self): + """ Initializes the '_attributes' trait. """ + + attributes_file = File(join(self.path, self.ATTRIBUTES_FILE)) + if attributes_file.is_file: + f = open(attributes_file.path, 'rb') + attributes = pickle.load(f) + f.close() + + else: + attributes = {} + + return attributes + + #### Trait event handlers ################################################# + + def _path_changed(self): + """ Called when the context's path has changed. """ + + basename = os.path.basename(self.path) + + self.name, ext = os.path.splitext(basename) + + return
+ +#### EOF ###################################################################### +
+ +
+
+
+
+
+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/4.5/_modules/apptools/naming/pyfs_context_factory.html b/4.5/_modules/apptools/naming/pyfs_context_factory.html new file mode 100644 index 000000000..600e5be9e --- /dev/null +++ b/4.5/_modules/apptools/naming/pyfs_context_factory.html @@ -0,0 +1,171 @@ + + + + + + + apptools.naming.pyfs_context_factory — Apptools Documentation + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +

Source code for apptools.naming.pyfs_context_factory

+#------------------------------------------------------------------------------
+# Copyright (c) 2005, Enthought, Inc.
+# All rights reserved.
+#
+# This software is provided without warranty under the terms of the BSD
+# license included in enthought/LICENSE.txt and may be redistributed only
+# under the conditions described in the aforementioned license.  The license
+# is also available online at http://www.enthought.com/licenses/BSD.txt
+# Thanks for using Enthought open source!
+#
+# Author: Enthought, Inc.
+# Description: <Enthought naming package component>
+#------------------------------------------------------------------------------
+""" Object factory for Python File System contexts. """
+
+
+# Local imports.
+from .object_factory import ObjectFactory
+from .reference import Reference
+
+
+
[docs]class PyFSContextFactory(ObjectFactory): + """ Object factory for Python File System contexts. """ + + ########################################################################### + # 'ObjectFactory' interface. + ########################################################################### + +
[docs] def get_object_instance(self, state, name, context): + """ Creates an object using the specified state information. """ + + obj = None + + if isinstance(state, Reference): + if len(state.addresses) > 0: + if state.addresses[0].type == 'pyfs_context': + path = state.addresses[0].content + obj = context._context_factory(name, path) + + return obj
+ +### EOF ####################################################################### +
+ +
+
+
+
+
+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/4.5/_modules/apptools/naming/pyfs_initial_context_factory.html b/4.5/_modules/apptools/naming/pyfs_initial_context_factory.html new file mode 100644 index 000000000..ab20eda97 --- /dev/null +++ b/4.5/_modules/apptools/naming/pyfs_initial_context_factory.html @@ -0,0 +1,180 @@ + + + + + + + apptools.naming.pyfs_initial_context_factory — Apptools Documentation + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +

Source code for apptools.naming.pyfs_initial_context_factory

+#------------------------------------------------------------------------------
+# Copyright (c) 2005, Enthought, Inc.
+# All rights reserved.
+#
+# This software is provided without warranty under the terms of the BSD
+# license included in enthought/LICENSE.txt and may be redistributed only
+# under the conditions described in the aforementioned license.  The license
+# is also available online at http://www.enthought.com/licenses/BSD.txt
+# Thanks for using Enthought open source!
+#
+# Author: Enthought, Inc.
+# Description: <Enthought naming package component>
+#------------------------------------------------------------------------------
+""" The initial context factory for Python file system contexts. """
+
+
+# Local imports.
+from .context import Context
+from .initial_context_factory import InitialContextFactory
+from .object_serializer import ObjectSerializer
+from .pyfs_context import PyFSContext
+from .pyfs_context_factory import PyFSContextFactory
+from .pyfs_object_factory import PyFSObjectFactory
+from .pyfs_state_factory import PyFSStateFactory
+
+
+
[docs]class PyFSInitialContextFactory(InitialContextFactory): + """ The initial context factory for Python file system contexts. """ + + ########################################################################### + # 'InitialContextFactory' interface. + ########################################################################### + +
[docs] def get_initial_context(self, environment): + """ Creates an initial context for beginning name resolution. """ + + # Object factories. + object_factories = [PyFSObjectFactory(), PyFSContextFactory()] + environment[Context.OBJECT_FACTORIES] = object_factories + + # State factories. + state_factories = [PyFSStateFactory()] + environment[Context.STATE_FACTORIES] = state_factories + + # Object serializers. + object_serializers = [ObjectSerializer()] + environment[PyFSContext.OBJECT_SERIALIZERS] = object_serializers + + return PyFSContext(path=r'', environment=environment)
+ +#### EOF ###################################################################### +
+ +
+
+
+
+
+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/4.5/_modules/apptools/naming/pyfs_object_factory.html b/4.5/_modules/apptools/naming/pyfs_object_factory.html new file mode 100644 index 000000000..d40b4ab61 --- /dev/null +++ b/4.5/_modules/apptools/naming/pyfs_object_factory.html @@ -0,0 +1,172 @@ + + + + + + + apptools.naming.pyfs_object_factory — Apptools Documentation + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +

Source code for apptools.naming.pyfs_object_factory

+#------------------------------------------------------------------------------
+# Copyright (c) 2005, Enthought, Inc.
+# All rights reserved.
+#
+# This software is provided without warranty under the terms of the BSD
+# license included in enthought/LICENSE.txt and may be redistributed only
+# under the conditions described in the aforementioned license.  The license
+# is also available online at http://www.enthought.com/licenses/BSD.txt
+# Thanks for using Enthought open source!
+#
+# Author: Enthought, Inc.
+# Description: <Enthought naming package component>
+#------------------------------------------------------------------------------
+""" Object factory for Python File System contexts. """
+
+
+# Enthought library imports.
+from apptools.io.api import File
+
+# Local imports.
+from .object_factory import ObjectFactory
+from .reference import Reference
+
+
+
[docs]class PyFSObjectFactory(ObjectFactory): + """ Object factory for Python File System contexts. """ + + ########################################################################### + # 'ObjectFactory' interface. + ########################################################################### + +
[docs] def get_object_instance(self, state, name, context): + """ Creates an object using the specified state information. """ + + obj = None + + if isinstance(state, Reference): + if state.class_name == 'File' and len(state.addresses) > 0: + obj = File(state.addresses[0].content) + + return obj
+ +### EOF ####################################################################### +
+ +
+
+
+
+
+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/4.5/_modules/apptools/naming/pyfs_state_factory.html b/4.5/_modules/apptools/naming/pyfs_state_factory.html new file mode 100644 index 000000000..582b2491c --- /dev/null +++ b/4.5/_modules/apptools/naming/pyfs_state_factory.html @@ -0,0 +1,178 @@ + + + + + + + apptools.naming.pyfs_state_factory — Apptools Documentation + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +

Source code for apptools.naming.pyfs_state_factory

+#------------------------------------------------------------------------------
+# Copyright (c) 2005, Enthought, Inc.
+# All rights reserved.
+#
+# This software is provided without warranty under the terms of the BSD
+# license included in enthought/LICENSE.txt and may be redistributed only
+# under the conditions described in the aforementioned license.  The license
+# is also available online at http://www.enthought.com/licenses/BSD.txt
+# Thanks for using Enthought open source!
+#
+# Author: Enthought, Inc.
+# Description: <Enthought naming package component>
+#------------------------------------------------------------------------------
+""" State factory for Python File System contexts. """
+
+
+# Enthought library imports.
+from apptools.io.api import File
+
+# Local imports.
+from .address import Address
+from .reference import Reference
+from .state_factory import StateFactory
+
+
+
[docs]class PyFSStateFactory(StateFactory): + """ State factory for Python File System contexts. """ + + ########################################################################### + # 'StateFactory' interface. + ########################################################################### + +
[docs] def get_state_to_bind(self, obj, name, context): + """ Returns the state of an object for binding. """ + + state = None + + if isinstance(obj, File): + # If the file is not actually in the directory represented by the + # context then we create and bind a reference to it. + if obj.parent.path != context.path: + state = Reference( + class_name = obj.__class__.__name__, + addresses = [Address(type='file', content=obj.path)] + ) + + return state
+ +### EOF ####################################################################### +
+ +
+
+
+
+
+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/4.5/_modules/apptools/naming/reference.html b/4.5/_modules/apptools/naming/reference.html new file mode 100644 index 000000000..f57ba249a --- /dev/null +++ b/4.5/_modules/apptools/naming/reference.html @@ -0,0 +1,179 @@ + + + + + + + apptools.naming.reference — Apptools Documentation + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +

Source code for apptools.naming.reference

+#------------------------------------------------------------------------------
+# Copyright (c) 2005, Enthought, Inc.
+# All rights reserved.
+#
+# This software is provided without warranty under the terms of the BSD
+# license included in enthought/LICENSE.txt and may be redistributed only
+# under the conditions described in the aforementioned license.  The license
+# is also available online at http://www.enthought.com/licenses/BSD.txt
+# Thanks for using Enthought open source!
+#
+# Author: Enthought, Inc.
+# Description: <Enthought naming package component>
+#------------------------------------------------------------------------------
+""" A reference to an object that lives outside of the naming system. """
+
+
+# Enthought library imports.
+from traits.api import Any, HasPrivateTraits, List, Str
+
+# Local imports.
+from .address import Address
+
+
+
[docs]class Reference(HasPrivateTraits): + """ A reference to an object that lives outside of the naming system. + + References provide a way to store the address(s) of objects that live + outside of the naming system. A reference consists of a list of + addresses that represent a communications endpoint for the object being + referenced. + + A reference also contains information to assist in the creation of an + instance of the object to which it refers. It contains the name of + the class that will be created and the class name and location of a + factory that will be used to do the actual instance creation. + + """ + + #### 'Reference' interface ################################################ + + # The list of addresses that can be used to 'contact' the object. + addresses = List(Address) + + # The class name of the object that this reference refers to. + class_name = Str + + # The class name of the object factory. + factory_class_name = Str
+ +#### EOF ###################################################################### +
+ +
+
+
+
+
+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/4.5/_modules/apptools/naming/referenceable.html b/4.5/_modules/apptools/naming/referenceable.html new file mode 100644 index 000000000..d0094040a --- /dev/null +++ b/4.5/_modules/apptools/naming/referenceable.html @@ -0,0 +1,161 @@ + + + + + + + apptools.naming.referenceable — Apptools Documentation + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +

Source code for apptools.naming.referenceable

+#------------------------------------------------------------------------------
+# Copyright (c) 2005, Enthought, Inc.
+# All rights reserved.
+#
+# This software is provided without warranty under the terms of the BSD
+# license included in enthought/LICENSE.txt and may be redistributed only
+# under the conditions described in the aforementioned license.  The license
+# is also available online at http://www.enthought.com/licenses/BSD.txt
+# Thanks for using Enthought open source!
+#
+# Author: Enthought, Inc.
+# Description: <Enthought naming package component>
+#------------------------------------------------------------------------------
+""" Base class for classes that can produce a reference to themselves. """
+
+
+# Enthought library imports.
+from traits.api import HasPrivateTraits, Instance
+
+# Local imports.
+from .reference import Reference
+
+
+
[docs]class Referenceable(HasPrivateTraits): + """ Base class for classes that can produce a reference to themselves. """ + + #### 'Referenceable' interface ############################################ + + # The object's reference suitable for binding in a naming context. + reference = Instance(Reference)
+ +#### EOF ###################################################################### +
+ +
+
+
+
+
+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/4.5/_modules/apptools/naming/referenceable_state_factory.html b/4.5/_modules/apptools/naming/referenceable_state_factory.html new file mode 100644 index 000000000..fdeaab2f4 --- /dev/null +++ b/4.5/_modules/apptools/naming/referenceable_state_factory.html @@ -0,0 +1,170 @@ + + + + + + + apptools.naming.referenceable_state_factory — Apptools Documentation + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +

Source code for apptools.naming.referenceable_state_factory

+#------------------------------------------------------------------------------
+# Copyright (c) 2005, Enthought, Inc.
+# All rights reserved.
+#
+# This software is provided without warranty under the terms of the BSD
+# license included in enthought/LICENSE.txt and may be redistributed only
+# under the conditions described in the aforementioned license.  The license
+# is also available online at http://www.enthought.com/licenses/BSD.txt
+# Thanks for using Enthought open source!
+#
+# Author: Enthought, Inc.
+# Description: <Enthought naming package component>
+#------------------------------------------------------------------------------
+""" State factory for referenceable objects. """
+
+
+# Local imports.
+from .referenceable import Referenceable
+from .state_factory import StateFactory
+
+
+
[docs]class ReferenceableStateFactory(StateFactory): + """ State factory for referenceable objects. """ + + ########################################################################### + # 'StateFactory' interface. + ########################################################################### + +
[docs] def get_state_to_bind(self, obj, name, context): + """ Returns the state of an object for binding. """ + + state = None + + # If the object knows how to create a reference to it then let it + # do so. + if isinstance(obj, Referenceable): + state = obj.reference + + return state
+ +### EOF ####################################################################### +
+ +
+
+
+
+
+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/4.5/_modules/apptools/naming/state_factory.html b/4.5/_modules/apptools/naming/state_factory.html new file mode 100644 index 000000000..944e18555 --- /dev/null +++ b/4.5/_modules/apptools/naming/state_factory.html @@ -0,0 +1,172 @@ + + + + + + + apptools.naming.state_factory — Apptools Documentation + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +

Source code for apptools.naming.state_factory

+#------------------------------------------------------------------------------
+# Copyright (c) 2005, Enthought, Inc.
+# All rights reserved.
+#
+# This software is provided without warranty under the terms of the BSD
+# license included in enthought/LICENSE.txt and may be redistributed only
+# under the conditions described in the aforementioned license.  The license
+# is also available online at http://www.enthought.com/licenses/BSD.txt
+# Thanks for using Enthought open source!
+#
+# Author: Enthought, Inc.
+# Description: <Enthought naming package component>
+#------------------------------------------------------------------------------
+""" The base class for all state factories. """
+
+
+# Enthought library imports.
+from traits.api import HasPrivateTraits
+
+
+
[docs]class StateFactory(HasPrivateTraits): + """ The base class for all state factories. + + A state factory accepts an object and returns some data representing the + object that is suitable for storing in a particular context. + + """ + + ########################################################################### + # 'StateFactory' interface. + ########################################################################### + +
[docs] def get_state_to_bind(self, obj, name, context): + """ Returns the state of an object for binding. + + Returns None if the factory cannot create the state (ie. it does not + recognise the object passed to it). + + """ + + raise NotImplementedError
+ +### EOF ####################################################################### +
+ +
+
+
+
+
+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/4.5/_modules/apptools/naming/trait_defs/naming_traits.html b/4.5/_modules/apptools/naming/trait_defs/naming_traits.html new file mode 100644 index 000000000..eee8de7e2 --- /dev/null +++ b/4.5/_modules/apptools/naming/trait_defs/naming_traits.html @@ -0,0 +1,301 @@ + + + + + + + apptools.naming.trait_defs.naming_traits — Apptools Documentation + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +

Source code for apptools.naming.trait_defs.naming_traits

+#-------------------------------------------------------------------------------
+#
+#  Defines the NamingLog and NamingIndex traits
+#
+#  Written by: David C. Morrill
+#
+#  Date: 08/15/2005
+#
+#  (c) Copyright 2005 by Enthought, Inc.
+#
+#-------------------------------------------------------------------------------
+
+#-------------------------------------------------------------------------------
+#  Imports:
+#-------------------------------------------------------------------------------
+
+import sys
+
+import six
+
+from traits.api \
+    import Trait, TraitHandler, TraitFactory
+
+from traits.trait_base \
+    import class_of, get_module_name
+
+from traitsui.api \
+    import DropEditor
+
+from apptools.naming.api \
+    import Binding
+
+
+#-------------------------------------------------------------------------------
+#  'NamingInstance' trait factory:
+#-------------------------------------------------------------------------------
+
+def NamingInstance ( klass = None, value = '', allow_none = False, **metadata ):
+    metadata.setdefault( 'copy', 'deep' )
+    return Trait( value, NamingTraitHandler( klass, or_none = allow_none,
+                  module = get_module_name() ), **metadata )
+
+NamingInstance = TraitFactory( NamingInstance )
+
+#-------------------------------------------------------------------------------
+#  'NamingTraitHandler' class:
+#-------------------------------------------------------------------------------
+
+
[docs]class NamingTraitHandler ( TraitHandler ): + + #--------------------------------------------------------------------------- + # Initializes the object: + #--------------------------------------------------------------------------- + + def __init__ ( self, aClass, or_none, module ): + """ Initializes the object. + """ + self.or_none = (or_none != False) + self.module = module + self.aClass = aClass + if (aClass is not None) \ + and (not isinstance( aClass, ( six.string_types, type ) )): + self.aClass = aClass.__class__ + +
[docs] def validate ( self, object, name, value ): + if isinstance( value, six.string_types ): + if value == '': + if self.or_none: + return '' + else: + self.validate_failed( object, name, value ) + try: + value = self._get_binding_for( value ) + except: + self.validate_failed( object, name, value ) + + if isinstance(self.aClass, six.string_types): + self.resolve_class( object, name, value ) + + if (isinstance( value, Binding ) and + ((self.aClass is None) or isinstance( value.obj, self.aClass ))): + return value.namespace_name + self.validate_failed( object, name, value )
+ +
[docs] def info ( self ): + aClass = self.aClass + if aClass is None: + result = 'path' + else: + if type( aClass ) is not str: + aClass = aClass.__name__ + result = 'path to an instance of ' + class_of( aClass ) + if self.or_none is None: + return result + ' or an empty string' + return result
+ +
[docs] def validate_failed ( self, object, name, value ): + if not isinstance( value, type ): + msg = 'class %s' % value.__class__.__name__ + else: + msg = '%s (i.e. %s)' % ( str( type( value ) )[1:-1], repr( value ) ) + self.error( object, name, msg )
+ +
[docs] def get_editor ( self, trait ): + if self.editor is None: + from traitsui.api import DropEditor + + self.editor = DropEditor( klass = self.aClass, + binding = True, + readonly = False ) + return self.editor
+ +
[docs] def post_setattr ( self, object, name, value ): + other = None + if value != '': + other = self._get_binding_for( value ).obj + object.__dict__[ name + '_' ] = other
+ + def _get_binding_for ( self, value ): + + result = None + + # FIXME: The following code makes this whole component have a dependency + # on envisage, and worse, assumes the use of a particular project + # plugin! This is horrible and should be refactored out, possibly to + # a custom sub-class of whoever needs this behavior. + try: + from envisage import get_application + workspace = get_application().service_registry.get_service( + 'envisage.project.IWorkspace' ) + result = workspace.lookup_binding( value ) + except ImportError: + pass + + return result + + +
[docs] def resolve_class ( self, object, name, value ): + aClass = self.find_class() + if aClass is None: + self.validate_failed( object, name, value ) + self.aClass = aClass + + # fixme: The following is quite ugly, because it wants to try and fix + # the trait referencing this handler to use the 'fast path' now that the + # actual class has been resolved. The problem is finding the trait, + # especially in the case of List(Instance('foo')), where the + # object.base_trait(...) value is the List trait, not the Instance + # trait, so we need to check for this and pull out the List + # 'item_trait'. Obviously this does not extend well to other traits + # containing nested trait references (Dict?)... + trait = object.base_trait( name ) + handler = trait.handler + if (handler is not self) and hasattr( handler, 'item_trait' ): + trait = handler.item_trait + trait.validate( self.fast_validate )
+ +
[docs] def find_class ( self ): + module = self.module + aClass = self.aClass + col = aClass.rfind( '.' ) + if col >= 0: + module = aClass[ : col ] + aClass = aClass[ col + 1: ] + theClass = getattr( sys.modules.get( module ), aClass, None ) + if (theClass is None) and (col >= 0): + try: + theClass = getattr( __import__( module ), aClass, None ) + except: + pass + return theClass
+ +
+ +
+
+
+
+
+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/_modules/apptools/naming/ui/context_monitor.html b/4.5/_modules/apptools/naming/ui/context_monitor.html similarity index 100% rename from _modules/apptools/naming/ui/context_monitor.html rename to 4.5/_modules/apptools/naming/ui/context_monitor.html diff --git a/_modules/apptools/naming/ui/context_node_type.html b/4.5/_modules/apptools/naming/ui/context_node_type.html similarity index 100% rename from _modules/apptools/naming/ui/context_node_type.html rename to 4.5/_modules/apptools/naming/ui/context_node_type.html diff --git a/_modules/apptools/naming/ui/explorer.html b/4.5/_modules/apptools/naming/ui/explorer.html similarity index 100% rename from _modules/apptools/naming/ui/explorer.html rename to 4.5/_modules/apptools/naming/ui/explorer.html diff --git a/_modules/apptools/naming/ui/naming_node_manager.html b/4.5/_modules/apptools/naming/ui/naming_node_manager.html similarity index 100% rename from _modules/apptools/naming/ui/naming_node_manager.html rename to 4.5/_modules/apptools/naming/ui/naming_node_manager.html diff --git a/_modules/apptools/naming/ui/naming_tree.html b/4.5/_modules/apptools/naming/ui/naming_tree.html similarity index 100% rename from _modules/apptools/naming/ui/naming_tree.html rename to 4.5/_modules/apptools/naming/ui/naming_tree.html diff --git a/_modules/apptools/naming/ui/naming_tree_model.html b/4.5/_modules/apptools/naming/ui/naming_tree_model.html similarity index 100% rename from _modules/apptools/naming/ui/naming_tree_model.html rename to 4.5/_modules/apptools/naming/ui/naming_tree_model.html diff --git a/_modules/apptools/naming/ui/object_node_type.html b/4.5/_modules/apptools/naming/ui/object_node_type.html similarity index 100% rename from _modules/apptools/naming/ui/object_node_type.html rename to 4.5/_modules/apptools/naming/ui/object_node_type.html diff --git a/4.5/_modules/apptools/naming/unique_name.html b/4.5/_modules/apptools/naming/unique_name.html new file mode 100644 index 000000000..905803230 --- /dev/null +++ b/4.5/_modules/apptools/naming/unique_name.html @@ -0,0 +1,164 @@ + + + + + + + apptools.naming.unique_name — Apptools Documentation + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +

Source code for apptools.naming.unique_name

+#-----------------------------------------------------------------------------
+#
+#  Copyright (c) 2007 by Enthought, Inc.
+#  All rights reserved.
+#
+#-----------------------------------------------------------------------------
+
+
+"""
+A re-usable method for calculating a unique name given a list of existing
+names.
+
+"""
+
+
[docs]def make_unique_name(base, existing=[], format="%s_%s"): + """ + Return a name, unique within a context, based on the specified name. + + base: the desired base name of the generated unique name. + existing: a sequence of the existing names to avoid returning. + format: a formatting specification for how the name is made unique. + + """ + + count = 2 + name = base + while name in existing: + name = format % (base, count) + count += 1 + + return name
+ + +#### EOF #################################################################### + +
+ +
+
+
+
+
+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/_modules/apptools/permissions/action/login_action.html b/4.5/_modules/apptools/permissions/action/login_action.html similarity index 100% rename from _modules/apptools/permissions/action/login_action.html rename to 4.5/_modules/apptools/permissions/action/login_action.html diff --git a/_modules/apptools/permissions/action/logout_action.html b/4.5/_modules/apptools/permissions/action/logout_action.html similarity index 100% rename from _modules/apptools/permissions/action/logout_action.html rename to 4.5/_modules/apptools/permissions/action/logout_action.html diff --git a/_modules/apptools/permissions/action/user_menu_manager.html b/4.5/_modules/apptools/permissions/action/user_menu_manager.html similarity index 100% rename from _modules/apptools/permissions/action/user_menu_manager.html rename to 4.5/_modules/apptools/permissions/action/user_menu_manager.html diff --git a/_modules/apptools/permissions/adapter_base.html b/4.5/_modules/apptools/permissions/adapter_base.html similarity index 100% rename from _modules/apptools/permissions/adapter_base.html rename to 4.5/_modules/apptools/permissions/adapter_base.html diff --git a/_modules/apptools/permissions/adapters/pyface_action.html b/4.5/_modules/apptools/permissions/adapters/pyface_action.html similarity index 100% rename from _modules/apptools/permissions/adapters/pyface_action.html rename to 4.5/_modules/apptools/permissions/adapters/pyface_action.html diff --git a/_modules/apptools/permissions/default/i_policy_storage.html b/4.5/_modules/apptools/permissions/default/i_policy_storage.html similarity index 100% rename from _modules/apptools/permissions/default/i_policy_storage.html rename to 4.5/_modules/apptools/permissions/default/i_policy_storage.html diff --git a/_modules/apptools/permissions/default/i_user_database.html b/4.5/_modules/apptools/permissions/default/i_user_database.html similarity index 100% rename from _modules/apptools/permissions/default/i_user_database.html rename to 4.5/_modules/apptools/permissions/default/i_user_database.html diff --git a/_modules/apptools/permissions/default/i_user_storage.html b/4.5/_modules/apptools/permissions/default/i_user_storage.html similarity index 100% rename from _modules/apptools/permissions/default/i_user_storage.html rename to 4.5/_modules/apptools/permissions/default/i_user_storage.html diff --git a/_modules/apptools/permissions/default/persistent.html b/4.5/_modules/apptools/permissions/default/persistent.html similarity index 100% rename from _modules/apptools/permissions/default/persistent.html rename to 4.5/_modules/apptools/permissions/default/persistent.html diff --git a/_modules/apptools/permissions/default/policy_data.html b/4.5/_modules/apptools/permissions/default/policy_data.html similarity index 100% rename from _modules/apptools/permissions/default/policy_data.html rename to 4.5/_modules/apptools/permissions/default/policy_data.html diff --git a/_modules/apptools/permissions/default/policy_manager.html b/4.5/_modules/apptools/permissions/default/policy_manager.html similarity index 100% rename from _modules/apptools/permissions/default/policy_manager.html rename to 4.5/_modules/apptools/permissions/default/policy_manager.html diff --git a/_modules/apptools/permissions/default/policy_storage.html b/4.5/_modules/apptools/permissions/default/policy_storage.html similarity index 100% rename from _modules/apptools/permissions/default/policy_storage.html rename to 4.5/_modules/apptools/permissions/default/policy_storage.html diff --git a/_modules/apptools/permissions/default/role_assignment.html b/4.5/_modules/apptools/permissions/default/role_assignment.html similarity index 100% rename from _modules/apptools/permissions/default/role_assignment.html rename to 4.5/_modules/apptools/permissions/default/role_assignment.html diff --git a/_modules/apptools/permissions/default/role_definition.html b/4.5/_modules/apptools/permissions/default/role_definition.html similarity index 100% rename from _modules/apptools/permissions/default/role_definition.html rename to 4.5/_modules/apptools/permissions/default/role_definition.html diff --git a/_modules/apptools/permissions/default/select_role.html b/4.5/_modules/apptools/permissions/default/select_role.html similarity index 100% rename from _modules/apptools/permissions/default/select_role.html rename to 4.5/_modules/apptools/permissions/default/select_role.html diff --git a/_modules/apptools/permissions/default/select_user.html b/4.5/_modules/apptools/permissions/default/select_user.html similarity index 100% rename from _modules/apptools/permissions/default/select_user.html rename to 4.5/_modules/apptools/permissions/default/select_user.html diff --git a/_modules/apptools/permissions/default/user_database.html b/4.5/_modules/apptools/permissions/default/user_database.html similarity index 100% rename from _modules/apptools/permissions/default/user_database.html rename to 4.5/_modules/apptools/permissions/default/user_database.html diff --git a/_modules/apptools/permissions/default/user_manager.html b/4.5/_modules/apptools/permissions/default/user_manager.html similarity index 100% rename from _modules/apptools/permissions/default/user_manager.html rename to 4.5/_modules/apptools/permissions/default/user_manager.html diff --git a/_modules/apptools/permissions/default/user_storage.html b/4.5/_modules/apptools/permissions/default/user_storage.html similarity index 100% rename from _modules/apptools/permissions/default/user_storage.html rename to 4.5/_modules/apptools/permissions/default/user_storage.html diff --git a/_modules/apptools/permissions/i_policy_manager.html b/4.5/_modules/apptools/permissions/i_policy_manager.html similarity index 100% rename from _modules/apptools/permissions/i_policy_manager.html rename to 4.5/_modules/apptools/permissions/i_policy_manager.html diff --git a/_modules/apptools/permissions/i_user.html b/4.5/_modules/apptools/permissions/i_user.html similarity index 100% rename from _modules/apptools/permissions/i_user.html rename to 4.5/_modules/apptools/permissions/i_user.html diff --git a/_modules/apptools/permissions/i_user_manager.html b/4.5/_modules/apptools/permissions/i_user_manager.html similarity index 100% rename from _modules/apptools/permissions/i_user_manager.html rename to 4.5/_modules/apptools/permissions/i_user_manager.html diff --git a/_modules/apptools/permissions/package_globals.html b/4.5/_modules/apptools/permissions/package_globals.html similarity index 100% rename from _modules/apptools/permissions/package_globals.html rename to 4.5/_modules/apptools/permissions/package_globals.html diff --git a/_modules/apptools/permissions/permission.html b/4.5/_modules/apptools/permissions/permission.html similarity index 100% rename from _modules/apptools/permissions/permission.html rename to 4.5/_modules/apptools/permissions/permission.html diff --git a/_modules/apptools/permissions/permissions_manager.html b/4.5/_modules/apptools/permissions/permissions_manager.html similarity index 100% rename from _modules/apptools/permissions/permissions_manager.html rename to 4.5/_modules/apptools/permissions/permissions_manager.html diff --git a/_modules/apptools/permissions/secure_proxy.html b/4.5/_modules/apptools/permissions/secure_proxy.html similarity index 100% rename from _modules/apptools/permissions/secure_proxy.html rename to 4.5/_modules/apptools/permissions/secure_proxy.html diff --git a/4.5/_modules/apptools/persistence/file_path.html b/4.5/_modules/apptools/persistence/file_path.html new file mode 100644 index 000000000..5f54eeb01 --- /dev/null +++ b/4.5/_modules/apptools/persistence/file_path.html @@ -0,0 +1,214 @@ + + + + + + + apptools.persistence.file_path — Apptools Documentation + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +

Source code for apptools.persistence.file_path

+"""Simple class to support file path objects that work well in the
+context of persistent storage with the state_pickler.
+
+"""
+# Author: Prabhu Ramachandran <prabhu_r@users.sf.net>
+# Copyright (c) 2005, Enthought, Inc.
+# License: BSD Style.
+
+# Standard library imports.
+import os
+from os.path import abspath, normpath, dirname, commonprefix, join
+
+
+
[docs]class FilePath(object): + """This class stores two paths to the file. A relative path and + an absolute one. The absolute path is used by the end user. When + this object is pickled the state_pickler sets the relative path + relative to the file that is being generated. When unpickled, the + stored relative path is used to set the absolute path correctly + based on the path of the saved file. + """ + def __init__(self, value=''): + self.set(value) + + def __str__(self): + return self.abs_pth + + def __repr__(self): + return self.abs_pth.__repr__() + +
[docs] def get(self): + """Get the path. + """ + return self.abs_pth
+ +
[docs] def set(self, value): + """Sets the value of the path. + """ + self.rel_pth = value + if value: + self.abs_pth = normpath(abspath(value)) + else: + self.abs_pth = ''
+ +
[docs] def set_relative(self, base_f_name): + """Sets the path relative to `base_f_name`. Note that + `base_f_name` and self.rel_pth should be valid file names + correct on the current os. The set name is a file name that + has a POSIX path. + """ + + # Get normalized paths. + _src = abspath(base_f_name) + _dst = self.abs_pth + + # Now strip out any common prefix between the two paths. + for part in _src.split(os.sep): + if _dst.startswith(part+os.sep): + length = len(part) + 1 + _src = _src[length:] + _dst = _dst[length:] + else: + break + + # For each directory in the source, we need to add a reference to + # the parent directory to the destination. + ret = (_src.count(os.sep) * ('..' + os.sep)) + _dst + + # Make it posix style. + if os.sep != '/': + ret.replace(os.sep, '/') + + # Store it. + self.rel_pth = ret
+ +
[docs] def set_absolute(self, base_f_name): + """Sets the absolute file name for the current relative file + name with respect to the given `base_f_name`. + """ + base_f_name = normpath(abspath(base_f_name)) + rel_file_name = normpath(self.rel_pth) + file_name = join(dirname(base_f_name), rel_file_name) + file_name = os.path.normpath(file_name) + self.abs_pth = file_name
+ +
+ +
+
+
+
+
+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/4.5/_modules/apptools/persistence/project_loader.html b/4.5/_modules/apptools/persistence/project_loader.html new file mode 100644 index 000000000..336220782 --- /dev/null +++ b/4.5/_modules/apptools/persistence/project_loader.html @@ -0,0 +1,245 @@ + + + + + + + apptools.persistence.project_loader — Apptools Documentation + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +

Source code for apptools.persistence.project_loader

+
+# Standard library imports
+import sys
+import pickle
+import logging
+
+# Enthought library imports
+from apptools.persistence.versioned_unpickler import VersionedUnpickler
+
+
+logger = logging.getLogger(__name__)
+
+
+
[docs]def load_project(pickle_filename, updater_path, application_version, protocol, + max_pass=-1): + """ Reads a project from a pickle file and if necessary will update it to + the latest version of the application. + """ + + latest_file = pickle_filename + + # Read the pickled project's metadata. + f = open(latest_file, 'rb') + metadata = VersionedUnpickler(f).load(max_pass) + f.close() + project_version = metadata.get('version', False) + + if not project_version: + raise ValueError("Could not read version number from the project file") + + logger.debug('Project version: %d, Application version: %d' % + (project_version, application_version)) + + # here you can temporarily force an upgrade each time for testing .... + # project_version = 0 + latest_file = upgrade_project(pickle_filename, updater_path, + project_version, application_version, protocol, + max_pass) + + # Finally we can import the project ... + logger.info('loading %s' % latest_file) + i_f = open(latest_file, 'rb') + version = VersionedUnpickler(i_f).load(max_pass) + project = VersionedUnpickler(i_f).load(max_pass) + i_f.close() + + return project
+ + +
[docs]def upgrade_project(pickle_filename, updater_path, project_version, application_version, protocol, max_pass=-1): + """ Repeatedly read and write the project to disk updating it one version + at a time. + + Example the p5.project is at version 0 + The application is at version 3 + + p5.project --- Update1 ---> p5.project.v1 + p5.project.v1 --- Update2 ---> p5.project.v2 + p5.project.v2 --- Update3 ---> p5.project.v3 + p5.project.v3 ---> loaded into app + + The user then has the option to save the updated project as p5.project + """ + first_time = True + latest_file = pickle_filename + + # update the project until it's version matches the application's + while project_version < application_version: + + next_version = project_version + 1 + + if first_time: + i_f = open(pickle_filename, 'rb') + data = i_f.read() + open('%s.bak' % pickle_filename, 'wb').write(data) + i_f.seek(0) # rewind the file to the start + else: + name = '%s.v%d' % (pickle_filename, project_version) + i_f = open(name, 'rb') + latest_file = name + + logger.info('converting %s' % latest_file) + + # find this version's updater ... + updater_name = '%s.update%d' % (updater_path, next_version) + __import__(updater_name) + mod = sys.modules[updater_name] + klass = getattr(mod, 'Update%d' % next_version) + updater = klass() + + # load and update this version of the project + version = VersionedUnpickler(i_f).load(max_pass) + project = VersionedUnpickler(i_f, updater).load(max_pass) + i_f.close() + + # set the project version to be the same as the updater we just + # ran on the unpickled files ... + project.metadata['version'] = next_version + + # Persist the updated project ... + name = '%s.v%d' % (pickle_filename, next_version) + latest_file = name + o_f = open(name, 'wb') + pickle.dump(project.metadata, o_f, protocol=protocol) + pickle.dump(project, o_f, protocol=protocol) + o_f.close() + + # Bump up the version number of the pickled project... + project_version += 1 + first_time = False + + return latest_file
+ + +### EOF ################################################################# + +
+ +
+
+
+
+
+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/4.5/_modules/apptools/persistence/state_pickler.html b/4.5/_modules/apptools/persistence/state_pickler.html new file mode 100644 index 000000000..a1ece00ba --- /dev/null +++ b/4.5/_modules/apptools/persistence/state_pickler.html @@ -0,0 +1,1147 @@ + + + + + + + apptools.persistence.state_pickler — Apptools Documentation + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +

Source code for apptools.persistence.state_pickler

+"""This module provides code that allows one to pickle the state of a
+Python object to a dictionary.
+
+The motivation for this is simple.  The standard Python
+pickler/unpickler is best used to pickle simple objects and does not
+work too well for complex code.  Specifically, there are two major
+problems (1) the pickle file format is not easy to edit with a text
+editor and (2) when a pickle is unpickled, it creates all the
+necessary objects and sets the state of these objects.
+
+Issue (2) might not appear to be a problem.  However, often, the
+determination of the entire 'state' of an application requires the
+knowledge of the state of many objects that are not really in the
+users concern.  The user would ideally like to pickle just what he
+thinks is relevant.  Now, given that the user is not going to save the
+entire state of the application, the use of pickle is insufficient
+since the state is no longer completely known (or worth knowing).  The
+default `Unpickler` recreates the objects and the typical
+implementation of `__setstate__` is usually to simply update the
+object's `__dict__` attribute.  This is inadequate because the pickled
+information is taken out of the real context when it was saved.
+
+The `StatePickler` basically pickles the 'state' of an object into a
+large dictionary.  This pickled data may be easily unpickled and
+modified on the interpreter or edited with a text editor
+(`pprint.saferepr` is a friend).  The second problem is also
+eliminated.  When this state is unpickled using `StateUnpickler`, what
+you get is a special dictionary (a `State` instance).  This allows one
+to navigate the state just like the original object.  Its up to the
+user to create any new objects and set their states using this
+information.  This allows for a lot of flexibility while allowing one
+to save and set the state of (almost) any Python object.
+
+The `StateSetter` class helps set the state of a known instance.  When
+setting the state of an instance it checks to see if there is a
+`__set_pure_state__` method that in turn calls `StateSetter.set`
+appropriately.
+
+Additionally, there is support for versioning.  The class' version is
+obtain from the `__version__` class attribute.  This version along
+with the versions of the bases of a class is embedded into the
+metadata of the state and stored.  By using `version_registry.py` a
+user may register a handler for a particular class and module.  When
+the state of an object is set using `StateSetter.set_state`, then
+these handlers are called in reverse order of their MRO.  This gives
+the handler an opportunity to upgrade the state depending on its
+version.  Builtin classes are not scanned for versions.  If a class
+has no version, then by default it is assumed to be -1.
+
+
+Example::
+
+  >>> class A:
+  ...    def __init__(self):
+  ...        self.a = 'a'
+  ...
+  >>> a = A()
+  >>> a.a = 100
+  >>> import state_pickler
+  >>> s = state_pickler.dumps(a)               # Dump the state of `a`.
+  >>> state = state_pickler.loads_state(s)     # Get the state back.
+  >>> b = state_pickler.create_instance(state) # Create the object.
+  >>> state_pickler.set_state(b, state)        # Set the object's state.
+  >>> assert b.a == 100
+
+
+Features
+--------
+
+ - The output is a plain old dictionary so is easy to parse, edit etc.
+ - Handles references to avoid duplication.
+ - Gzips Numeric arrays when dumping them.
+ - Support for versioning.
+
+
+Caveats
+-------
+
+ - Does not pickle a whole bunch of stuff including code objects and
+   functions.
+ - The output is a pure dictionary and does not contain instances.  So
+   using this *as it is* in `__setstate__` will not work.  Instead
+   define a `__set_pure_state__` and use the `StateSetter` class or
+   the `set_state` function provided by this module.
+
+
+Notes
+-----
+
+  Browsing the code from XMarshaL_ and pickle.py proved useful for
+  ideas.  None of the code is taken from there though.
+
+.. _XMarshaL:  http://www.dezentral.de/soft/XMarshaL
+
+"""
+# Author: Prabhu Ramachandran <prabhu_r@users.sf.net>
+# Copyright (c) 2005-2015, Enthought, Inc.
+# License: BSD Style.
+
+# Standard library imports.
+import base64
+import sys
+import types
+import pickle
+import gzip
+from io import BytesIO, StringIO
+
+import numpy
+
+# Local imports.
+from . import version_registry
+from .file_path import FilePath
+
+PY_VER = sys.version_info[0]
+NumpyArrayType = type(numpy.array([]))
+
+
+
[docs]def gzip_string(data): + """Given a string (`data`) this gzips the string and returns it. + """ + s = BytesIO() + writer = gzip.GzipFile(mode='wb', fileobj=s) + writer.write(data) + writer.close() + s.seek(0) + return s.read()
+ + +
[docs]def gunzip_string(data): + """Given a gzipped string (`data`) this unzips the string and + returns it. + """ + if PY_VER== 2 or (bytes is not str and type(data) is bytes): + s = BytesIO(data) + else: + s = StringIO(data) + writer = gzip.GzipFile(mode='rb', fileobj=s) + data = writer.read() + writer.close() + return data
+ +
[docs]class StatePicklerError(Exception): + pass
+ +
[docs]class StateUnpicklerError(Exception): + pass
+ +
[docs]class StateSetterError(Exception): + pass
+ +###################################################################### +# `State` class +###################################################################### +
[docs]class State(dict): + """Used to encapsulate the state of an instance in a very + convenient form. The '__metadata__' attribute/key is a dictionary + that has class specific details like the class name, module name + etc. + """ + def __init__(self, **kw): + dict.__init__(self, **kw) + self.__dict__ = self
+ +###################################################################### +# `StateDict` class +###################################################################### +
[docs]class StateDict(dict): + """Used to encapsulate a dictionary stored in a `State` instance. + The has_instance attribute specifies if the dict has an instance + embedded in it. + """ + def __init__(self, **kw): + dict.__init__(self, **kw) + self.has_instance = False
+ +###################################################################### +# `StateList` class +###################################################################### +
[docs]class StateList(list): + """Used to encapsulate a list stored in a `State` instance. The + has_instance attribute specifies if the list has an instance + embedded in it. + """ + def __init__(self, seq=None): + if seq: + list.__init__(self, seq) + else: + list.__init__(self) + self.has_instance = False
+ +###################################################################### +# `StateTuple` class +###################################################################### +
[docs]class StateTuple(tuple): + """Used to encapsulate a tuple stored in a `State` instance. The + has_instance attribute specifies if the tuple has an instance + embedded in it. + """ + def __new__(cls, seq=None): + if seq: + obj = super(StateTuple, cls).__new__(cls, tuple(seq)) + else: + obj = super(StateTuple, cls).__new__(cls) + obj.has_instance = False + return obj
+ + +###################################################################### +# `StatePickler` class +###################################################################### +
[docs]class StatePickler: + """Pickles the state of an object into a dictionary. The + dictionary is itself either saved as a pickled file (`dump`) or + pickled string (`dumps`). Alternatively, the `dump_state` method + will return the dictionary that is pickled. + + The format of the state dict is quite strightfoward. Basic types + (bool, int, long, float, complex, None, string and unicode) are + represented as they are. Everything else is stored as a + dictionary containing metadata information on the object's type + etc. and also the actual object in the 'data' key. For example:: + + >>> p = StatePickler() + >>> p.dump_state(1) + 1 + >>> l = [1,2.0, None, [1,2,3]] + >>> p.dump_state(l) + {'data': [1, 2.0, None, {'data': [1, 2, 3], 'type': 'list', 'id': 1}], + 'id': 0, + 'type': 'list'} + + Classes are also represented similarly. The state in this case is + obtained from the `__getstate__` method or from the `__dict__`. + Here is an example:: + + >>> class A: + ... __version__ = 1 # State version + ... def __init__(self): + ... self.attribute = 1 + ... + >>> a = A() + >>> p = StatePickler() + >>> p.dump_state(a) + {'class_name': 'A', + 'data': {'data': {'attribute': 1}, 'type': 'dict', 'id': 2}, + 'id': 0, + 'initargs': {'data': (), 'type': 'tuple', 'id': 1}, + 'module': '__main__', + 'type': 'instance', + 'version': [(('A', '__main__'), 1)]} + + When pickling data, references are taken care of. Numeric arrays + can be pickled and are stored as a gzipped base64 encoded string. + + """ + def __init__(self): + self._clear() + type_map = {bool: self._do_basic_type, + complex: self._do_basic_type, + float: self._do_basic_type, + int: self._do_basic_type, + type(None): self._do_basic_type, + str: self._do_basic_type, + bytes: self._do_basic_type, + tuple: self._do_tuple, + list: self._do_list, + dict: self._do_dict, + NumpyArrayType: self._do_numeric, + State: self._do_state, + } + if PY_VER == 2: + type_map[long] = self._do_basic_type + type_map[unicode] = self._do_basic_type + self.type_map = type_map + +
[docs] def dump(self, value, file): + """Pickles the state of the object (`value`) into the passed + file. + """ + try: + # Store the file name we are writing to so we can munge + # file paths suitably. + self.file_name = file.name + except AttributeError: + pass + pickle.dump(self._do(value), file)
+ +
[docs] def dumps(self, value): + """Pickles the state of the object (`value`) and returns a + string. + """ + return pickle.dumps(self._do(value))
+ +
[docs] def dump_state(self, value): + """Returns a dictionary or a basic type representing the + complete state of the object (`value`). + + This value is pickled by the `dump` and `dumps` methods. + """ + return self._do(value)
+ + ###################################################################### + # Non-public methods + ###################################################################### + def _clear(self): + # Stores the file name of the file being used to dump the + # state. This is used to change any embedded paths relative + # to the saved file. + self.file_name = '' + # Caches id's to handle references. + self.obj_cache = {} + # Misc cache to cache things that are not persistent. For + # example, object.__getstate__()/__getinitargs__() usually + # returns a copy of a dict/tuple that could possibly be reused + # on another object's __getstate__. Caching these prevents + # some wierd problems with the `id` of the object. + self._misc_cache = [] + + def _flush_traits(self, obj): + """Checks if the object has traits and ensures that the traits + are set in the `__dict__` so we can pickle it. + """ + # Not needed with Traits3. + return + + def _do(self, obj): + obj_type = type(obj) + key = self._get_id(obj) + if key in self.obj_cache: + return self._do_reference(obj) + elif obj_type in self.type_map: + return self.type_map[obj_type](obj) + elif isinstance(obj, tuple): + # Takes care of StateTuples. + return self._do_tuple(obj) + elif isinstance(obj, list): + # Takes care of TraitListObjects. + return self._do_list(obj) + elif isinstance(obj, dict): + # Takes care of TraitDictObjects. + return self._do_dict(obj) + elif hasattr(obj, '__dict__'): + return self._do_instance(obj) + + def _get_id(self, value): + try: + key = hash(value) + except TypeError: + key = id(value) + return key + + def _register(self, value): + key = self._get_id(value) + cache = self.obj_cache + idx = len(cache) + cache[key] = idx + return idx + + def _do_basic_type(self, value): + return value + + def _do_reference(self, value): + key = self._get_id(value) + idx = self.obj_cache[key] + return dict(type='reference', id=idx, data=None) + + def _do_instance(self, value): + # Flush out the traits. + self._flush_traits(value) + + # Setup the relative paths of FilePaths before dumping. + if self.file_name and isinstance(value, FilePath): + value.set_relative(self.file_name) + + # Get the initargs. + args = () + if hasattr(value, '__getinitargs__') and value.__getinitargs__: + args = value.__getinitargs__() + + # Get the object state. + if hasattr(value, '__get_pure_state__'): + state = value.__get_pure_state__() + elif hasattr(value, '__getstate__'): + state = value.__getstate__() + else: + state = value.__dict__ + + state.pop('__traits_version__', None) + + # Cache the args and state since they are likely to be gc'd. + self._misc_cache.extend([args, state]) + # Register and process. + idx = self._register(value) + args_data = self._do(args) + data = self._do(state) + + # Get the version of the object. + version = version_registry.get_version(value) + module = value.__class__.__module__ + class_name = value.__class__.__name__ + + return dict(type='instance', + module=module, + class_name=class_name, + version=version, + id=idx, + initargs=args_data, + data=data) + + def _do_state(self, value): + metadata = value.__metadata__ + args = metadata.get('initargs') + state = dict(value) + state.pop('__metadata__') + + self._misc_cache.extend([args, state]) + + idx = self._register(value) + args_data = self._do(args) + data = self._do(state) + + return dict(type='instance', + module=metadata['module'], + class_name=metadata['class_name'], + version=metadata['version'], + id=idx, + initargs=args_data, + data=data) + + def _do_tuple(self, value): + idx = self._register(value) + data = tuple([self._do(x) for x in value]) + return dict(type='tuple', id=idx, data=data) + + def _do_list(self, value): + idx = self._register(value) + data = [self._do(x) for x in value] + return dict(type='list', id=idx, data=data) + + def _do_dict(self, value): + idx = self._register(value) + vals = [self._do(x) for x in value.values()] + data = dict(zip(value.keys(), vals)) + return dict(type='dict', id=idx, data=data) + + def _do_numeric(self, value): + idx = self._register(value) + if PY_VER > 2: + data = base64.encodebytes(gzip_string(numpy.ndarray.dumps(value))) + else: + data = base64.encodestring(gzip_string(numpy.ndarray.dumps(value))) + return dict(type='numeric', id=idx, data=data)
+ + + +###################################################################### +# `StateUnpickler` class +###################################################################### +
[docs]class StateUnpickler: + """Unpickles the state of an object saved using StatePickler. + + Please note that unlike the standard Unpickler, no instances of + any user class are created. The data for the state is obtained + from the file or string, reference objects are setup to refer to + the same state value and this state is returned in the form + usually in the form of a dictionary. For example:: + + >>> class A: + ... def __init__(self): + ... self.attribute = 1 + ... + >>> a = A() + >>> p = StatePickler() + >>> s = p.dumps(a) + >>> up = StateUnpickler() + >>> state = up.loads_state(s) + >>> state.__class__.__name__ + 'State' + >>> state.attribute + 1 + >>> state.__metadata__ + {'class_name': 'A', + 'has_instance': True, + 'id': 0, + 'initargs': (), + 'module': '__main__', + 'type': 'instance', + 'version': [(('A', '__main__'), -1)]} + + Note that the state is actually a `State` instance and is + navigable just like the original object. The details of the + instance are stored in the `__metadata__` attribute. This is + highly convenient since it is possible for someone to view and + modify the state very easily. + """ + + def __init__(self): + self._clear() + self.type_map = {'reference': self._do_reference, + 'instance': self._do_instance, + 'tuple': self._do_tuple, + 'list': self._do_list, + 'dict': self._do_dict, + 'numeric': self._do_numeric, + } + +
[docs] def load_state(self, file): + """Returns the state of an object loaded from the pickled data + in the given file. + """ + try: + self.file_name = file.name + except AttributeError: + pass + data = pickle.load(file) + result = self._process(data) + return result
+ +
[docs] def loads_state(self, string): + """Returns the state of an object loaded from the pickled data + in the given string. + """ + data = pickle.loads(string) + result = self._process(data) + return result
+ + ###################################################################### + # Non-public methods + ###################################################################### + def _clear(self): + # The file from which we are being loaded. + self.file_name = '' + # Cache of the objects. + self._obj_cache = {} + # Paths to the instances. + self._instances = [] + # Caches the references. + self._refs = {} + # Numeric arrays. + self._numeric = {} + + def _set_has_instance(self, obj, value): + if isinstance(obj, State): + obj.__metadata__['has_instance'] = value + elif isinstance(obj, (StateDict, StateList, StateTuple)): + obj.has_instance = value + + def _process(self, data): + result = self._do(data) + + # Setup all the Numeric arrays. Do this first since + # references use this. + for key, (path, val) in self._numeric.items(): + if isinstance(result, StateTuple): + result = list(result) + exec('result%s = val'%path) + result = StateTuple(result) + else: + exec('result%s = val'%path) + + # Setup the references so they really are references. + for key, paths in self._refs.items(): + for path in paths: + x = self._obj_cache[key] + if isinstance(result, StateTuple): + result = list(result) + exec('result%s = x'%path) + result = StateTuple(result) + else: + exec('result%s = x'%path) + # if the reference is to an instance append its path. + if isinstance(x, State): + self._instances.append(path) + + # Now setup the 'has_instance' attribute. If 'has_instance' + # is True then the object contains an instance somewhere + # inside it. + for path in self._instances: + pth = path + while pth: + ns = {'result': result} + exec('val = result%s'%pth, ns, ns) + self._set_has_instance(ns['val'], True) + end = pth.rfind('[') + pth = pth[:end] + # Now make sure that the first element also has_instance. + self._set_has_instance(result, True) + return result + + def _do(self, data, path=''): + if type(data) is dict: + return self.type_map[data['type']](data, path) + else: + return data + + def _do_reference(self, value, path): + id = value['id'] + if id in self._refs: + self._refs[id].append(path) + else: + self._refs[id] = [path] + return State(__metadata__=value) + + def _handle_file_path(self, value): + if (value['class_name'] == 'FilePath') and \ + ('file_path' in value['module']) and \ + self.file_name: + data = value['data']['data'] + fp = FilePath(data['rel_pth']) + fp.set_absolute(self.file_name) + data['abs_pth'] = fp.abs_pth + + def _do_instance(self, value, path): + self._instances.append(path) + initargs = self._do(value['initargs'], + path + '.__metadata__["initargs"]') + # Handle FilePaths. + self._handle_file_path(value) + + d = self._do(value['data'], path) + md = dict(type='instance', + module=value['module'], + class_name=value['class_name'], + version=value['version'], + id=value['id'], + initargs=initargs, + has_instance=True) + result = State(**d) + result.__metadata__ = md + self._obj_cache[value['id']] = result + return result + + def _do_tuple(self, value, path): + res = [] + for i, x in enumerate(value['data']): + res.append(self._do(x, path + '[%d]'%i)) + result = StateTuple(res) + self._obj_cache[value['id']] = result + return result + + def _do_list(self, value, path): + result = StateList() + for i, x in enumerate(value['data']): + result.append(self._do(x, path + '[%d]'%i)) + self._obj_cache[value['id']] = result + return result + + def _do_dict(self, value, path): + result = StateDict() + for key, val in value['data'].items(): + result[key] = self._do(val, path + '["%s"]'%key) + self._obj_cache[value['id']] = result + return result + + def _do_numeric(self, value, path): + if PY_VER > 2: + data = value['data'] + if isinstance(data, str): + data = value['data'].encode('utf-8') + junk = gunzip_string(base64.decodebytes(data)) + result = pickle.loads(junk, encoding='bytes') + else: + junk = gunzip_string(value['data'].decode('base64')) + result = pickle.loads(junk) + self._numeric[value['id']] = (path, result) + self._obj_cache[value['id']] = result + return result
+ + +###################################################################### +# `StateSetter` class +###################################################################### +
[docs]class StateSetter: + """This is a convenience class that helps a user set the + attributes of an object given its saved state. For instances it + checks to see if a `__set_pure_state__` method exists and calls + that when it sets the state. + """ + def __init__(self): + # Stores the ids of instances already done. + self._instance_ids = [] + self.type_map = {State: self._do_instance, + StateTuple: self._do_tuple, + StateList: self._do_list, + StateDict: self._do_dict, + } + +
[docs] def set(self, obj, state, ignore=None, first=None, last=None): + """Sets the state of the object. + + This is to be used as a means to simplify loading the state of + an object from its `__setstate__` method using the dictionary + describing its state. Note that before the state is set, the + registered handlers for the particular class are called in + order to upgrade the version of the state to the latest + version. + + Parameters + ---------- + + - obj : `object` + + The object whose state is to be set. If this is `None` + (default) then the object is created. + + - state : `dict` + + The dictionary representing the state of the object. + + - ignore : `list(str)` + + The list of attributes specified in this list are ignored + and the state of these attributes are not set (this excludes + the ones specified in `first` and `last`). If one specifies + a '*' then all attributes are ignored except the ones + specified in `first` and `last`. + + - first : `list(str)` + + The list of attributes specified in this list are set first (in + order), before any other attributes are set. + + - last : `list(str)` + + The list of attributes specified in this list are set last (in + order), after all other attributes are set. + + """ + if (not isinstance(state, State)) and \ + state.__metadata__['type'] != 'instance': + raise StateSetterError( + 'Can only set the attributes of an instance.' + ) + + # Upgrade the state to the latest using the registry. + self._update_and_check_state(obj, state) + + self._register(obj) + + # This wierdness is needed since the state's own `keys` might + # be set to something else. + state_keys = list(dict.keys(state)) + state_keys.remove('__metadata__') + + if first is None: + first = [] + if last is None: + last = [] + + # Remove all the ignored keys. + if ignore: + if '*' in ignore: + state_keys = first + last + else: + for name in ignore: + try: + state_keys.remove(name) + except KeyError: + pass + + # Do the `first` attributes. + for key in first: + state_keys.remove(key) + self._do(obj, key, state[key]) + + # Remove the `last` attributes. + for key in last: + state_keys.remove(key) + + # Set the remaining attributes. + for key in state_keys: + self._do(obj, key, state[key]) + + # Do the last ones in order. + for key in last: + self._do(obj, key, state[key])
+ + ###################################################################### + # Non-public methods. + ###################################################################### + def _register(self, obj): + idx = id(obj) + if idx not in self._instance_ids: + self._instance_ids.append(idx) + + def _is_registered(self, obj): + return (id(obj) in self._instance_ids) + + def _has_instance(self, value): + """Given something (`value`) that is part of the state this + returns if the value has an instance embedded in it or not. + """ + if isinstance(value, State): + return True + elif isinstance(value, (StateDict, StateList, StateTuple)): + return value.has_instance + return False + + def _get_pure(self, value): + """Returns the Python representation of the object (usually a + list, tuple or dict) that has no instances embedded within it. + """ + result = value + if self._has_instance(value): + raise StateSetterError( + 'Value has an instance: %s'%value + ) + if isinstance(value, (StateList, StateTuple)): + result = [self._get_pure(x) for x in value] + if isinstance(value, StateTuple): + result = tuple(result) + elif isinstance(value, StateDict): + result = {} + for k, v in value.items(): + result[k] = self._get_pure(v) + return result + + def _update_and_check_state(self, obj, state): + """Updates the state from the registry and then checks if the + object and state have same class. + """ + # Upgrade this state object to the latest using the registry. + # This is done before testing because updating may change the + # class name/module. + version_registry.registry.update(state) + + # Make sure object and state have the same class and module names. + metadata = state.__metadata__ + cls = obj.__class__ + if (metadata['class_name'] != cls.__name__): + raise StateSetterError( + 'Instance (%s) and state (%s) do not have the same class'\ + ' name!'%(cls.__name__, metadata['class_name']) + ) + if (metadata['module'] != cls.__module__): + raise StateSetterError( + 'Instance (%s) and state (%s) do not have the same module'\ + ' name!'%(cls.__module__, metadata['module']) + ) + + def _do(self, obj, key, value): + try: + attr = getattr(obj, key) + except AttributeError: + raise StateSetterError( + 'Object %s does not have an attribute called: %s'%(obj, key) + ) + + if isinstance(value, (State, StateDict, StateList, StateTuple)): + # Special handlers are needed. + if not self._has_instance(value): + result = self._get_pure(value) + setattr(obj, key, result) + elif isinstance(value, StateTuple): + setattr(obj, key, self._do_tuple(getattr(obj, key), value)) + else: + self._do_object(getattr(obj, key), value) + else: + setattr(obj, key, value) + + def _do_object(self, obj, state): + self.type_map[state.__class__](obj, state) + + def _do_instance(self, obj, state): + if self._is_registered(obj): + return + else: + self._register(obj) + + metadata = state.__metadata__ + if hasattr(obj, '__set_pure_state__'): + self._update_and_check_state(obj, state) + obj.__set_pure_state__(state) + elif 'tvtk_classes' in metadata['module']: + self._update_and_check_state(obj, state) + tmp = self._get_pure(StateDict(**state)) + del tmp['__metadata__'] + obj.__setstate__(tmp) + else: + # No need to update or check since `set` does it for us. + self.set(obj, state) + + def _do_tuple(self, obj, state): + if not self._has_instance(state): + return self._get_pure(state) + else: + result = list(obj) + self._do_list(result, state) + return tuple(result) + + def _do_list(self, obj, state): + if len(obj) == len(state): + for i in range(len(obj)): + if not self._has_instance(state[i]): + obj[i] = self._get_pure(state[i]) + elif isinstance(state[i], tuple): + obj[i] = self._do_tuple(state[i]) + else: + self._do_object(obj[i], state[i]) + else: + raise StateSetterError( + 'Cannot set state of list of incorrect size.' + ) + + def _do_dict(self, obj, state): + for key, value in state.items(): + if not self._has_instance(value): + obj[key] = self._get_pure(value) + elif isinstance(value, tuple): + obj[key] = self._do_tuple(value) + else: + self._do_object(obj[key], value)
+ + +###################################################################### +# Internal Utility functions. +###################################################################### +def _get_file_read(f): + if hasattr(f, 'read'): + return f + else: + return open(f, 'rb') + +def _get_file_write(f): + if hasattr(f, 'write'): + return f + else: + return open(f, 'wb') + + +###################################################################### +# Utility functions. +###################################################################### +
[docs]def dump(value, file): + """Pickles the state of the object (`value`) into the passed file + (or file name). + """ + f = _get_file_write(file) + try: + StatePickler().dump(value, f) + finally: + f.flush() + if f is not file: + f.close()
+ + +
[docs]def dumps(value): + """Pickles the state of the object (`value`) and returns a string. + """ + return StatePickler().dumps(value)
+ + +
[docs]def load_state(file): + """Returns the state of an object loaded from the pickled data in + the given file (or file name). + """ + f = _get_file_read(file) + try: + state = StateUnpickler().load_state(f) + finally: + if f is not file: + f.close() + return state
+ + +
[docs]def loads_state(string): + """Returns the state of an object loaded from the pickled data + in the given string. + """ + return StateUnpickler().loads_state(string)
+ + +
[docs]def get_state(obj): + """Returns the state of the object (usually as a dictionary). The + returned state may be used directy to set the state of the object + via `set_state`. + """ + s = dumps(obj) + return loads_state(s)
+ + +
[docs]def set_state(obj, state, ignore=None, first=None, last=None): + StateSetter().set(obj, state, ignore, first, last)
+set_state.__doc__ = StateSetter.set.__doc__ + + +
[docs]def update_state(state): + """Given the state of an object, this updates the state to the + latest version using the handlers given in the version registry. + The state is modified in-place. + """ + version_registry.registry.update(state)
+ + +
[docs]def create_instance(state): + """Create an instance from the state if possible. + """ + if (not isinstance(state, State)) and \ + ('class_name' not in state.__metadata__): + raise StateSetterError('No class information in state') + metadata = state.__metadata__ + class_name = metadata.get('class_name') + mod_name = metadata.get('module') + if 'tvtk_classes' in mod_name: + # FIXME: This sort of special-case is probably indicative of something + # that needs more thought, plus it makes it tought to decide whether + # this component depends on tvtk! + from tvtk.api import tvtk + return getattr(tvtk, class_name)() + + initargs = metadata['initargs'] + if initargs.has_instance: + raise StateUnpicklerError('Cannot unpickle non-trivial initargs') + + __import__(mod_name, globals(), locals(), class_name) + mod = sys.modules[mod_name] + cls = getattr(mod, class_name) + return cls(*initargs)
+
+ +
+
+
+
+
+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/4.5/_modules/apptools/persistence/updater.html b/4.5/_modules/apptools/persistence/updater.html new file mode 100644 index 000000000..9d68df9ce --- /dev/null +++ b/4.5/_modules/apptools/persistence/updater.html @@ -0,0 +1,170 @@ + + + + + + + apptools.persistence.updater — Apptools Documentation + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +

Source code for apptools.persistence.updater

+def __replacement_setstate__(self, state):
+    """
+    """
+    state = self.__updater__(state)
+    self.__dict__.update(state)
+
+    return
+
+
+
+
+
[docs]class Updater: + + """ An abstract class to provide functionality common to the updaters. + """ + +
[docs] def get_latest(self, module, name): + """ The refactorings dictionary contains mappings between old and new + module names. Since we only bump the version number one increment + there is only one possible answer. + """ + if hasattr(self, 'refactorings'): + module = self.strip(module) + name = self.strip(name) + # returns the new module and name if it exists otherwise defaults + # to using the original module and name + module, name = self.refactorings.get((module, name), (module, name)) + + return module, name
+ + +
[docs] def strip(self, string): + # Who would have thought that pickle would pass us + # names with \013 on the end? Is this after the files have + # manually edited? + if ord(string[-1:]) == 13: + return string[:-1] + + return string
+ +#### EOF ####################################################################### +
+ +
+
+
+
+
+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/4.5/_modules/apptools/persistence/version_registry.html b/4.5/_modules/apptools/persistence/version_registry.html new file mode 100644 index 000000000..b7a89a612 --- /dev/null +++ b/4.5/_modules/apptools/persistence/version_registry.html @@ -0,0 +1,235 @@ + + + + + + + apptools.persistence.version_registry — Apptools Documentation + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +

Source code for apptools.persistence.version_registry

+"""A version registry that manages handlers for different state
+versions.
+"""
+# Author: Prabhu Ramachandran <prabhu_r@users.sf.net>
+# Copyright (c) 2005, Enthought, Inc.
+# License: BSD Style.
+
+# Standard library imports.
+import sys
+import inspect
+import logging
+
+
+logger = logging.getLogger(__name__)
+
+
+######################################################################
+# Utility functions.
+######################################################################
+
[docs]def get_version(obj): + """Walks the class hierarchy and obtains the versions of the + various classes and returns a list of tuples of the form + ((class_name, module), version) in reverse order of the MRO. + """ + res = [] + for cls in inspect.getmro(obj.__class__): + class_name, module = cls.__name__, cls.__module__ + if module in ['__builtin__']: + # No point in versioning builtins. + continue + try: + version = cls.__version__ + except AttributeError: + version = -1 + res.append( ( (class_name, module), version) ) + res.reverse() + return res
+ + +###################################################################### +# `HandlerRegistry` class. +###################################################################### +
[docs]class HandlerRegistry: + """A simple version conversion handler registry. Classes register + handlers in order to convert the state version to the latest + version. When an object's state is about to be set, the `update` + method of the registy is called. This in turn calls any handlers + registered for the class/module and this handler is then called + with the state and the version of the state. The state is + modified in-place by the handlers. + """ + + def __init__(self): + # The version conversion handlers. + # Key: (class_name, module), value: handler + self.handlers = {} + +
[docs] def register(self, class_name, module, handler): + """Register `handler` that handles versioning for class having + class name (`class_name`) and module name (`module`). The + handler function will be passed the state and its version to fix. + """ + key = (class_name, module) + if key in self.handlers: + msg = 'Overwriting version handler for (%s, %s)'%(key[0], key[1]) + logger.warn(msg) + self.handlers[(class_name, module)] = handler
+ +
[docs] def unregister(self, class_name, module): + """Unregisters any handlers for a class and module. + """ + self.handlers.pop((class_name, module))
+ +
[docs] def update(self, state): + """Updates the given state using the handlers. Note that the + state is modified in-place. + """ + if (not self.handlers) or (not hasattr(state, '__metadata__')): + return + versions = state.__metadata__['version'] + for ver in versions: + key = ver[0] + try: + self.handlers[key](state, ver[1]) + except KeyError: + pass
+ + +def _create_registry(): + """Creates a reload safe, singleton registry. + """ + registry = None + for key in sys.modules.keys(): + if 'version_registry' in key: + mod = sys.modules[key] + if hasattr(mod, 'registry'): + registry = mod.registry + break + if not registry: + registry = HandlerRegistry() + return registry + + +# The singleton registry. +registry = _create_registry() + +
+ +
+
+
+
+
+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/4.5/_modules/apptools/persistence/versioned_unpickler.html b/4.5/_modules/apptools/persistence/versioned_unpickler.html new file mode 100644 index 000000000..4f222a87f --- /dev/null +++ b/4.5/_modules/apptools/persistence/versioned_unpickler.html @@ -0,0 +1,364 @@ + + + + + + + apptools.persistence.versioned_unpickler — Apptools Documentation + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +

Source code for apptools.persistence.versioned_unpickler

+# Standard library imports
+from pickle import *
+import sys
+import logging
+from types import GeneratorType, MethodType
+
+# Enthought library imports
+from apptools.persistence.updater import __replacement_setstate__
+
+
+logger = logging.getLogger(__name__)
+
+
+def _unbound_method(method, klass):
+    """
+    Python-version-agnostic unbound_method generator.
+
+    For Python 2, use MethodType. Python 3 doesn't have a separate
+    type for unbound methods; just return the method itself.
+    """
+    if sys.version_info < (3,):
+        return MethodType(method, None, klass)
+    else:
+        return method
+
+
+##############################################################################
+# class 'NewUnpickler'
+##############################################################################
+
[docs]class NewUnpickler(Unpickler): + """ An unpickler that implements a two-stage pickling process to make it + possible to unpickle complicated Python object hierarchies where the + unserialized state of an object depends on the state of other objects in + the same pickle. + """ + +
[docs] def load(self, max_pass=-1): + """Read a pickled object representation from the open file. + + Return the reconstituted object hierarchy specified in the file. + """ + # List of objects to be unpickled. + self.objects = [] + + # We overload the load_build method. + dispatch = self.dispatch + dispatch[BUILD[0]] = NewUnpickler.load_build + + # call the super class' method. + ret = Unpickler.load(self) + self.initialize(max_pass) + self.objects = [] + + # Reset the Unpickler's dispatch table. + dispatch[BUILD[0]] = Unpickler.load_build + return ret
+ +
[docs] def initialize(self, max_pass): + # List of (object, generator) tuples that initialize objects. + generators = [] + + # Execute object's initialize to setup the generators. + for obj in self.objects: + if hasattr(obj, '__initialize__') and \ + callable(obj.__initialize__): + ret = obj.__initialize__() + if isinstance(ret, GeneratorType): + generators.append((obj, ret)) + elif ret is not None: + raise UnpicklingError('Unexpected return value from ' + '__initialize__. %s returned %s' % (obj, ret)) + + # Ensure a maximum number of passes + if max_pass < 0: + max_pass = len(generators) + + # Now run the generators. + count = 0 + while len(generators) > 0: + count += 1 + if count > max_pass: + not_done = [x[0] for x in generators] + msg = """Reached maximum pass count %s. You may have + a deadlock! The following objects are + uninitialized: %s""" % (max_pass, not_done) + raise UnpicklingError(msg) + for o, g in generators[:]: + try: + next(g) + except StopIteration: + generators.remove((o, g))
+ + # Make this a class method since dispatch is a class variable. + # Otherwise, supposing the initial sweet_pickle.load call (which would + # have overloaded the load_build method) makes a pickle.load call at some + # point, we would have the dispatch still pointing to + # NewPickler.load_build whereas the object being passed in will be an + # Unpickler instance, causing a TypeError. +
[docs] def load_build(cls, obj): + # Just save the instance in the list of objects. + if isinstance(obj, NewUnpickler): + obj.objects.append(obj.stack[-2]) + Unpickler.load_build(obj)
+ load_build = classmethod(load_build)
+ + +
[docs]class VersionedUnpickler(NewUnpickler): + """ This class reads in a pickled file created at revision version 'n' + and then applies the transforms specified in the updater class to + generate a new set of objects which are at revision version 'n+1'. + + I decided to keep the loading of the updater out of this generic class + because we will want updaters to be generated for each plugin's type + of project. + + This ensures that the VersionedUnpickler can remain ignorant about the + actual version numbers - all it needs to do is upgrade one release. + """ + + + def __init__(self, file, updater=None): + Unpickler.__init__(self, file) + self.updater = updater + return + + +
[docs] def find_class(self, module, name): + """ Overridden method from Unpickler. + + NB __setstate__ is not called until later. + """ + + if self.updater: + # check to see if this class needs to be mapped to a new class + # or module name + original_module, original_name = module, name + #logger.debug('omodule:%s oname:%s' % (original_module, original_name)) + module, name = self.updater.get_latest(module, name) + #logger.debug('module:%s name:%s' % (module, name)) + + # load the class... + '''__import__(module) + mod = sys.modules[module] + klass = getattr(mod, name)''' + klass = self.import_name(module, name) + + # add the updater.... TODO - why the old name? + self.add_updater(original_module, original_name, klass) + + else: + # there is no updater so we will be reading in an up to date + # version of the file... + try: + klass = Unpickler.find_class(self, module, name) + except: + logger.error("Looking for [%s] [%s]" % (module, name)) + logger.exception('Problem using default unpickle functionality') + + # restore the original __setstate__ if necessary + fn = getattr(klass, '__setstate_original__', False) + if fn: + m = _unbound_method(fn, klass) + setattr(klass, '__setstate__', m) + + return klass
+ + +
[docs] def add_updater(self, module, name, klass): + """ If there is an updater defined for this class we will add it to the + class as the __setstate__ method. + """ + + fn = self.updater.setstates.get((module, name), False) + + if fn: + # move the existing __setstate__ out of the way + self.backup_setstate(module, klass) + + # add the updater into the class + m = _unbound_method(fn, klass) + setattr(klass, '__updater__', m) + + # hook up our __setstate__ which updates self.__dict__ + m = _unbound_method(__replacement_setstate__, klass) + setattr(klass, '__setstate__', m) + + else: + pass + #print('No updater fn to worry about') + + return
+ + +
[docs] def backup_setstate(self, module, klass): + """ If the class has a user defined __setstate__ we back it up. + """ + if getattr(klass, '__setstate__', False): + + if getattr(klass, '__setstate_original__', False): + # don't overwrite the original __setstate__ + name = '__setstate__%s' % self.updater.__class__ + else: + # backup the original __setstate__ which we will restore + # and run later when we have finished updating the class + name = '__setstate_original__' + + #logger.debug('renaming __setstate__ to %s' % name) + method = getattr(klass, '__setstate__') + m = _unbound_method(method, klass) + setattr(klass, name, m) + + else: + # the class has no __setstate__ method so do nothing + pass + + return
+ + +
[docs] def import_name(self, module, name): + """ + If the class is needed for the latest version of the application then + it should presumably exist. + + If the class no longer exists then we should perhaps return + a proxy of the class. + + If the persisted file is at v1 say and the application is at v3 then + objects that are required for v1 and v2 do not have to exist they only + need to be placeholders for the state during an upgrade. + """ + #print("importing %s %s" % (name, module)) + module = __import__(module, globals(), locals(), [name]) + return vars(module)[name]
+ +### EOF ################################################################# +
+ +
+
+
+
+
+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/4.5/_modules/apptools/preferences/i_preferences.html b/4.5/_modules/apptools/preferences/i_preferences.html new file mode 100644 index 000000000..601fcc5a4 --- /dev/null +++ b/4.5/_modules/apptools/preferences/i_preferences.html @@ -0,0 +1,303 @@ + + + + + + + apptools.preferences.i_preferences — Apptools Documentation + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +

Source code for apptools.preferences.i_preferences

+""" The interface for a node in a preferences hierarchy. """
+
+
+# Enthought library imports.
+from traits.api import Instance, Interface, Str
+
+
+
[docs]class IPreferences(Interface): + """ The interface for a node in a preferences hierarchy. """ + + # The absolute path to this node from the root node (the empty string if + # this node *is* the root node). + path = Str + + # The parent node (None if this node *is* the root node). + parent = Instance('IPreferences') + + # The name of the node relative to its parent (the empty string if this + # node *is* the root node). + name = Str + + #### Methods where 'path' refers to a preference #### + +
[docs] def get(self, path, default=None, inherit=False): + """ Get the value of the preference at the specified path. + + If no value exists for the path (or any part of the path does not + exist) then return the default value. + + Preference values are *always* returned as strings. + + e.g:: + + preferences.set('acme.ui.bgcolor', 'blue') + preferences.get('acme.ui.bgcolor') -> 'blue' + + preferences.set('acme.ui.width', 100) + preferences.get('acme.ui.width') -> '100' + + preferences.set('acme.ui.visible', True) + preferences.get('acme.ui.visible') -> 'True' + + If 'inherit' is True then we allow 'inherited' preference values. + + e.g. If we are looking up:: + + 'acme.ui.widget.bgcolor' + + and it does not exist then we will also try:: + + 'acme.ui.bgcolor' + 'acme.bgcolor' + 'bgcolor' + + Raise a 'ValueError' exception if the path is the empty string. + + """
+ +
[docs] def remove(self, path): + """ Remove the preference at the specified path. + + Does nothing if no value exists for the path (or any part of the path + does not exist. + + Raise a 'ValueError' exception if the path is the empty string. + + e.g.:: + + preferences.remove('acme.ui.bgcolor') + + """
+ +
[docs] def set(self, path, value): + """ Set the value of the preference at the specified path. + + Any missing nodes are created automatically. + + Primitive Python types can be set, but preferences are *always* + stored and returned as strings. + + e.g:: + + preferences.set('acme.ui.bgcolor', 'blue') + preferences.get('acme.ui.bgcolor') -> 'blue' + + preferences.set('acme.ui.width', 100) + preferences.get('acme.ui.width') -> '100' + + preferences.set('acme.ui.visible', True) + preferences.get('acme.ui.visible') -> 'True' + + Raise a 'ValueError' exception if the path is the empty string. + + """
+ + #### Methods where 'path' refers to a node #### + +
[docs] def clear(self, path=''): + """ Remove all preference from the node at the specified path. + + If the path is the empty string (the default) then remove the + preferences in *this* node. + + This does not affect any of the node's children. + + e.g. To clear the preferences out of a node directly:: + + preferences.clear() + + Or to clear the preferences of a node at a given path:: + + preferences.clear('acme.ui') + + """
+ +
[docs] def keys(self, path=''): + """ Return the preference keys of the node at the specified path. + + If the path is the empty string (the default) then return the + preference keys of *this* node. + + e.g:: + + keys = preferences.keys('acme.ui') + + """
+ +
[docs] def node(self, path=''): + """ Return the node at the specified path. + + If the path is the empty string (the default) then return *this* node. + + Any missing nodes are created automatically. + + e.g:: + + node = preferences.node('acme.ui') + bgcolor = node.get('bgcolor') + + """
+ +
[docs] def node_exists(self, path=''): + """ Return True if the node at the specified path exists + + If the path is the empty string (the default) then return True. + + e.g:: + + exists = preferences.exists('acme.ui') + + """
+ +
[docs] def node_names(self, path=''): + """ Return the names of the children of the node at the specified path. + + If the path is the empty string (the default) then return the names of + the children of *this* node. + + e.g:: + + names = preferences.node_names('acme.ui') + + """
+ + #### Persistence methods #### + +
[docs] def flush(self): + """ Force any changes in the node to the backing store. + + This includes any changes to the node's descendants. + + """
+ +#### EOF ###################################################################### +
+ +
+
+
+
+
+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/4.5/_modules/apptools/preferences/package_globals.html b/4.5/_modules/apptools/preferences/package_globals.html new file mode 100644 index 000000000..4936f8634 --- /dev/null +++ b/4.5/_modules/apptools/preferences/package_globals.html @@ -0,0 +1,158 @@ + + + + + + + apptools.preferences.package_globals — Apptools Documentation + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +

Source code for apptools.preferences.package_globals

+""" Package-scope globals.
+
+The default preferences node is currently used by 'PreferencesHelper' and
+'PreferencesBinding' instances if no specific preferences node is set. This
+makes it easy for them to access the root node of an application-wide
+preferences hierarchy.
+
+"""
+
+
+# The default preferences node.
+_default_preferences = None
+
+
[docs]def get_default_preferences(): + """ Get the default preferences node. """ + + return _default_preferences
+ +
[docs]def set_default_preferences(default_preferences): + """ Set the default preferences node. """ + + global _default_preferences + + _default_preferences = default_preferences + + # For convenience. + return _default_preferences
+ +#### EOF ###################################################################### +
+ +
+
+
+
+
+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/4.5/_modules/apptools/preferences/preference_binding.html b/4.5/_modules/apptools/preferences/preference_binding.html new file mode 100644 index 000000000..41b9155cc --- /dev/null +++ b/4.5/_modules/apptools/preferences/preference_binding.html @@ -0,0 +1,306 @@ + + + + + + + apptools.preferences.preference_binding — Apptools Documentation + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +

Source code for apptools.preferences.preference_binding

+""" A binding between a trait on an object and a preference value. """
+
+
+# Enthought library imports.
+from traits.api import Any, HasTraits, Instance, Str, Undefined
+from traits.api import Unicode
+
+# Third-party librart imports.
+import six
+
+# Local imports.
+from .i_preferences import IPreferences
+from .package_globals import get_default_preferences
+
+
+
[docs]class PreferenceBinding(HasTraits): + """ A binding between a trait on an object and a preference value. """ + + #### 'PreferenceBinding' interface ######################################## + + # The object that we are binding the preference to. + obj = Any + + # The preferences node used by the binding. If this trait is not set then + # the package-global default preferences node is used (and if that is not + # set then the binding won't work ;^) + preferences = Instance(IPreferences) + + # The path to the preference value. + preference_path = Str + + # The name of the trait that we are binding the preference to. + trait_name = Str + + ########################################################################### + # 'object' interface. + ########################################################################### + + def __init__(self, **traits): + """ Constructor. """ + + super(PreferenceBinding, self).__init__(**traits) + + # Initialize the object's trait from the preference value. + self._set_trait(notify=False) + + # Wire-up trait change handlers etc. + self._initialize() + + return + + ########################################################################### + # 'PreferenceBinding' interface. + ########################################################################### + + #### Trait initializers ################################################### + + def _preferences_default(self): + """ Trait initializer. """ + + return get_default_preferences() + + ########################################################################### + # Private interface. + ########################################################################### + + #### Trait change handlers ################################################ + + def _on_trait_changed(self, obj, trait_name, old, new): + """ Dynamic trait change handler. """ + + self.preferences.set(self.preference_path, new) + + return + + #### Other observer pattern listeners ##################################### + + def _preferences_listener(self, node, key, old, new): + """ Listener called when a preference value is changed. """ + + components = self.preference_path.split('.') + if key == components[-1]: + self._set_trait() + + return + + #### Methods ############################################################## + + # fixme: This method is mostly duplicated in 'PreferencesHelper' (the only + # difference is the line that gets the handler). + def _get_value(self, trait_name, value): + """ Get the actual value to set. + + This method makes sure that any required work is done to convert the + preference value from a string. + + """ + + handler = self.obj.trait(trait_name).handler + + # If the trait type is 'Str' then we just take the raw value. + if type(handler) is Str: + pass + + # If the trait type is 'Unicode' then we convert the raw value. + elif type(handler) is Unicode: + value = six.text_type(value) + + # Otherwise, we eval it! + else: + try: + value = eval(value) + + # If the eval fails then there is probably a syntax error, but + # we will let the handler validation throw the exception. + except: + pass + + return handler.validate(self, trait_name, value) + + def _initialize(self): + """ Wire-up trait change handlers etc. """ + + # Listen for the object's trait being changed. + self.obj.on_trait_change(self._on_trait_changed, self.trait_name) + + # Listen for the preference value being changed. + components = self.preference_path.split('.') + node = '.'.join(components[:-1]) + + self.preferences.add_preferences_listener( + self._preferences_listener, node + ) + + return + + def _set_trait(self, notify=True): + """ Set the object's trait to the value of the preference. """ + + value = self.preferences.get(self.preference_path, Undefined) + if value is not Undefined: + trait_value = self._get_value(self.trait_name, value) + traits = {self.trait_name : trait_value} + + self.obj.trait_set(trait_change_notify=notify, **traits) + + return
+ + +# Factory function for creating bindings. +
[docs]def bind_preference(obj, trait_name, preference_path, preferences=None): + """ Create a new preference binding. """ + + # This may seem a bit wierd, but we manually build up a dictionary of + # the traits that need to be set at the time the 'PreferenceBinding' + # instance is created. + # + # This is because we only want to set the 'preferences' trait iff one + # is explicitly specified. If we passed it in with the default argument + # value of 'None' then it counts as 'setting' the trait which prevents + # the binding instance from defaulting to the package-global preferences. + # Also, if we try to set the 'preferences' trait *after* construction time + # then it is too late as the binding initialization is done in the + # constructor (we could of course split that out, which may be the 'right' + # way to do it ;^). + traits = { + 'obj' : obj, + 'trait_name' : trait_name, + 'preference_path' : preference_path + } + + if preferences is not None: + traits['preferences'] = preferences + + return PreferenceBinding(**traits)
+ +#### EOF ###################################################################### +
+ +
+
+
+
+
+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/4.5/_modules/apptools/preferences/preferences.html b/4.5/_modules/apptools/preferences/preferences.html new file mode 100644 index 000000000..264942b98 --- /dev/null +++ b/4.5/_modules/apptools/preferences/preferences.html @@ -0,0 +1,718 @@ + + + + + + + apptools.preferences.preferences — Apptools Documentation + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +

Source code for apptools.preferences.preferences

+""" The default implementation of a node in a preferences hierarchy. """
+
+from __future__ import print_function
+
+# Standard library imports.
+import logging, threading
+
+# Third-party library imports.
+import six
+
+# Enthought library imports.
+from traits.api import Any, Callable, Dict, HasTraits, Instance, List
+from traits.api import Property, Str, Undefined, provides
+
+# Local imports.
+from .i_preferences import IPreferences
+
+
+# Logging.
+logger = logging.getLogger(__name__)
+
+
+
[docs]@provides(IPreferences) +class Preferences(HasTraits): + """ The default implementation of a node in a preferences hierarchy. """ + + + #### 'IPreferences' interface ############################################# + + # The absolute path to this node from the root node (the empty string if + # this node *is* the root node). + path = Property(Str) + + # The parent node (None if this node *is* the root node). + parent = Instance(IPreferences) + + # The name of the node relative to its parent (the empty string if this + # node *is* the root node). + name = Str + + #### 'Preferences' interface ############################################## + + # The default name of the file used to persist the preferences (if no + # filename is passed in to the 'load' and 'save' methods, then this is + # used instead). + filename = Str + + #### Protected 'Preferences' interface #################################### + + # A lock to make access to the node thread-safe. + # + # fixme: There *should* be no need to declare this as a trait, but if we + # don't then we have problems using nodes in the preferences manager UI. + # It is something to do with 'cloning' the node for use in a 'modal' traits + # UI... Hmmm... + _lk = Any + + # The node's children. + _children = Dict(Str, IPreferences) + + # The node's preferences. + _preferences = Dict(Str, Any) + + # Listeners for changes to the node's preferences. + # + # The callable must take 4 arguments, e.g:: + # + # listener(node, key, old, new) + _preferences_listeners = List(Callable) + + ########################################################################### + # 'object' interface. + ########################################################################### + + def __init__(self, **traits): + """ Constructor. """ + + # A lock to make access to the '_children', '_preferences' and + # '_preferences_listeners' traits thread-safe. + self._lk = threading.Lock() + + # Base class constructor. + super(Preferences, self).__init__(**traits) + + # If a filename has been specified then load the preferences from it. + if len(self.filename) > 0: + self.load() + + return + + ########################################################################### + # 'IPreferences' interface. + ########################################################################### + + #### Trait properties ##################################################### + + def _get_path(self): + """ Property getter. """ + + names = [] + + node = self + while node.parent is not None: + names.append(node.name) + node = node.parent + + names.reverse() + + return '.'.join(names) + + #### Methods ############################################################## + + #### Methods where 'path' refers to a preference #### + +
[docs] def get(self, path, default=None, inherit=False): + """ Get the value of the preference at the specified path. """ + + if len(path) == 0: + raise ValueError('empty path') + + components = path.split('.') + + # If there is only one component in the path then the operation takes + # place in this node. + if len(components) == 1: + value = self._get(path, Undefined) + + # Otherwise, find the next node and pass the rest of the path to that. + else: + node = self._get_child(components[0]) + if node is not None: + value = node.get('.'.join(components[1:]), Undefined) + + else: + value = Undefined + + # If inherited values are allowed then try those as well. + # + # e.g. 'acme.ui.widget.bgcolor' + # 'acme.ui.bgcolor' + # 'acme.bgcolor' + # 'bgcolor' + while inherit and value is Undefined and len(components) > 1: + # Remove the penultimate component... + # + # e.g. 'acme.ui.widget.bgcolor' -> 'acme.ui.bgcolor' + del components[-2] + + # ... and try that. + value = self.get('.'.join(components), default=Undefined) + + if value is Undefined: + value = default + + return value
+ +
[docs] def remove(self, path): + """ Remove the preference at the specified path. """ + + if len(path) == 0: + raise ValueError('empty path') + + components = path.split('.') + + # If there is only one component in the path then the operation takes + # place in this node. + if len(components) == 1: + self._remove(path) + + # Otherwise, find the next node and pass the rest of the path to that. + else: + node = self._get_child(components[0]) + if node is not None: + node.remove('.'.join(components[1:])) + + return
+ +
[docs] def set(self, path, value): + """ Set the value of the preference at the specified path. """ + + if len(path) == 0: + raise ValueError('empty path') + + components = path.split('.') + + # If there is only one component in the path then the operation takes + # place in this node. + if len(components) == 1: + self._set(path, value) + + # Otherwise, find the next node (creating it if it doesn't exist) + # and pass the rest of the path to that. + else: + node = self._node(components[0]) + node.set('.'.join(components[1:]), value) + + return
+ + #### Methods where 'path' refers to a node #### + +
[docs] def clear(self, path=''): + """ Remove all preferences from the node at the specified path. """ + + # If the path is empty then the operation takes place in this node. + if len(path) == 0: + self._clear() + + # Otherwise, find the next node and pass the rest of the path to that. + else: + components = path.split('.') + + node = self._get_child(components[0]) + if node is not None: + node.clear('.'.join(components[1:])) + + return
+ +
[docs] def keys(self, path=''): + """ Return the preference keys of the node at the specified path. """ + + # If the path is empty then the operation takes place in this node. + if len(path) == 0: + keys = self._keys() + + # Otherwise, find the next node and pass the rest of the path to that. + else: + components = path.split('.') + + node = self._get_child(components[0]) + if node is not None: + keys = node.keys('.'.join(components[1:])) + + else: + keys = [] + + return keys
+ +
[docs] def node(self, path=''): + """ Return the node at the specified path. """ + + # If the path is empty then the operation takes place in this node. + if len(path) == 0: + node = self + + # Otherwise, find the next node and pass the rest of the path to that. + else: + components = path.split('.') + + node = self._node(components[0]) + node = node.node('.'.join(components[1:])) + + return node
+ +
[docs] def node_exists(self, path=''): + """ Return True if the node at the specified path exists. """ + + # If the path is empty then the operation takes place in this node. + if len(path) == 0: + exists = True + + # Otherwise, find the next node and pass the rest of the path to that. + else: + components = path.split('.') + + node = self._get_child(components[0]) + if node is not None: + exists = node.node_exists('.'.join(components[1:])) + + else: + exists = False + + return exists
+ +
[docs] def node_names(self, path=''): + """ Return the names of the children of the node at the specified path. + + """ + + # If the path is empty then the operation takes place in this node. + if len(path) == 0: + names = self._node_names() + + # Otherwise, find the next node and pass the rest of the path to that. + else: + components = path.split('.') + + node = self._get_child(components[0]) + if node is not None: + names = node.node_names('.'.join(components[1:])) + + else: + names = [] + + return names
+ + #### Persistence methods #### + +
[docs] def flush(self): + """ Force any changes in the node to the backing store. + + This includes any changes to the node's descendants. + + """ + + self.save() + + return
+ + ########################################################################### + # 'Preferences' interface. + ########################################################################### + + #### Listener methods #### + +
[docs] def add_preferences_listener(self, listener, path=''): + """ Add a listener for changes to a node's preferences. """ + + # If the path is empty then the operation takes place in this node. + if len(path) == 0: + names = self._add_preferences_listener(listener) + + # Otherwise, find the next node and pass the rest of the path to that. + else: + components = path.split('.') + + node = self._node(components[0]) + node.add_preferences_listener(listener, '.'.join(components[1:])) + + return
+ +
[docs] def remove_preferences_listener(self, listener, path=''): + """ Remove a listener for changes to a node's preferences. """ + + # If the path is empty then the operation takes place in this node. + if len(path) == 0: + names = self._remove_preferences_listener(listener) + + # Otherwise, find the next node and pass the rest of the path to that. + else: + components = path.split('.') + + node = self._node(components[0]) + node.remove_preferences_listener(listener,'.'.join(components[1:])) + + return
+ + #### Persistence methods #### + +
[docs] def load(self, file_or_filename=None): + """ Load preferences from a file. + + This is a *merge* operation i.e. the contents of the file are added to + the node. + + This implementation uses 'ConfigObj' files. + + """ + + if file_or_filename is None: + file_or_filename = self.filename + + logger.debug('loading preferences from <%s>', file_or_filename) + + # Do the import here so that we don't make 'ConfigObj' a requirement + # if preferences aren't ever persisted (or a derived class chooses to + # use a different persistence mechanism). + from configobj import ConfigObj + + config_obj = ConfigObj(file_or_filename, encoding='utf-8') + + # 'name' is the section name, 'value' is a dictionary containing the + # name/value pairs in the section (the actual preferences ;^). + for name, value in config_obj.items(): + # Create/get the node from the section name. + components = name.split('.') + + node = self + for component in components: + node = node._node(component) + + # Add the contents of the section to the node. + self._add_dictionary_to_node(node, value) + + return
+ +
[docs] def save(self, file_or_filename=None): + """ Save the node's preferences to a file. + + This implementation uses 'ConfigObj' files. + + """ + + if file_or_filename is None: + file_or_filename = self.filename + + # If no file or filename is specified then don't save the preferences! + if len(file_or_filename) > 0: + # Do the import here so that we don't make 'ConfigObj' a + # requirement if preferences aren't ever persisted (or a derived + # class chooses to use a different persistence mechanism). + from configobj import ConfigObj + + logger.debug('saving preferences to <%s>', file_or_filename) + + config_obj = ConfigObj(file_or_filename, encoding='utf-8') + self._add_node_to_dictionary(self, config_obj) + config_obj.write() + + return
+ + ########################################################################### + # Protected 'Preferences' interface. + # + # These are the only methods that should access the protected '_children' + # and '_preferences' traits. This helps make it easy to subclass this class + # to create other implementations (all the subclass has to do is to + # implement these protected methods). + # + ########################################################################### + + def _add_dictionary_to_node(self, node, dictionary): + """ Add the contents of a dictionary to a node's preferences. """ + + self._lk.acquire() + node._preferences.update(dictionary) + self._lk.release() + + return + + def _add_node_to_dictionary(self, node, dictionary): + """ Add a node's preferences to a dictionary. """ + + # This method never manipulates the '_preferences' trait directly. + # Instead it does eveything via the other protected methods and hence + # doesn't need to grab the lock. + if len(node._keys()) > 0: + dictionary[node.path] = {} + for key in node._keys(): + dictionary[node.path][key] = node._get(key) + + for name in node._node_names(): + self._add_node_to_dictionary(node._get_child(name), dictionary) + + return + + def _add_preferences_listener(self, listener): + """ Add a listener for changes to thisnode's preferences. """ + + self._lk.acquire() + self._preferences_listeners.append(listener) + self._lk.release() + + return + + def _clear(self): + """ Remove all preferences from this node. """ + + self._lk.acquire() + self._preferences.clear() + self._lk.release() + + return + + def _create_child(self, name): + """ Create a child of this node with the specified name. """ + + self._lk.acquire() + child = self._children[name] = Preferences(name=name, parent=self) + self._lk.release() + + return child + + def _get(self, key, default=None): + """ Get the value of a preference in this node. """ + + self._lk.acquire() + value = self._preferences.get(key, default) + self._lk.release() + + return value + + def _get_child(self, name): + """ Return the child of this node with the specified name. + + Return None if no such child exists. + + """ + + self._lk.acquire() + child = self._children.get(name) + self._lk.release() + + return child + + def _keys(self): + """ Return the preference keys of this node. """ + + self._lk.acquire() + keys = list(self._preferences.keys()) + self._lk.release() + + return keys + + def _node(self, name): + """ Return the child of this node with the specified name. + + Create the child node if it does not exist. + + """ + + node = self._get_child(name) + if node is None: + node = self._create_child(name) + + return node + + def _node_names(self): + """ Return the names of the children of this node. """ + + self._lk.acquire() + node_names = list(self._children.keys()) + self._lk.release() + + return node_names + + def _remove(self, name): + """ Remove a preference value from this node. """ + + self._lk.acquire() + if name in self._preferences: + del self._preferences[name] + self._lk.release() + + return + + def _remove_preferences_listener(self, listener): + """ Remove a listener for changes to the node's preferences. """ + + self._lk.acquire() + if listener in self._preferences_listeners: + self._preferences_listeners.remove(listener) + self._lk.release() + + return + + def _set(self, key, value): + """ Set the value of a preference in this node. """ + + # everything must be unicode encoded so that ConfigObj configuration + # can properly serialize the data. Python str are supposed to be ASCII + # encoded. + value = six.text_type(value) + + self._lk.acquire() + old = self._preferences.get(key) + self._preferences[key] = value + + # If the value is unchanged then don't call the listeners! + if old == value: + listeners = [] + + else: + listeners = self._preferences_listeners[:] + self._lk.release() + + for listener in listeners: + listener(self, key, old, value) + + return + + ########################################################################### + # Debugging interface. + ########################################################################### + +
[docs] def dump(self, indent=''): + """ Dump the preferences hierarchy to stdout. """ + + if indent == '': + print() + + print(indent, 'Node(%s)' % self.name, self._preferences) + indent += ' ' + + for child in self._children.values(): + child.dump(indent) + + return
+ +#### EOF ###################################################################### +
+ +
+
+
+
+
+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/4.5/_modules/apptools/preferences/preferences_helper.html b/4.5/_modules/apptools/preferences/preferences_helper.html new file mode 100644 index 000000000..480b00685 --- /dev/null +++ b/4.5/_modules/apptools/preferences/preferences_helper.html @@ -0,0 +1,315 @@ + + + + + + + apptools.preferences.preferences_helper — Apptools Documentation + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +

Source code for apptools.preferences.preferences_helper

+""" An object that can be initialized from a preferences node. """
+
+
+# Standard library imports.
+import logging
+
+# Enthought library imports.
+from traits.api import HasTraits, Instance, Str, Unicode
+
+# Local imports.
+from .i_preferences import IPreferences
+from .package_globals import get_default_preferences
+
+
+# Logging.
+logger = logging.getLogger(__name__)
+
+
+
[docs]class PreferencesHelper(HasTraits): + """ An object that can be initialized from a preferences node. """ + + #### 'PreferencesHelper' interface ######################################## + + # The preferences node used by the helper. If this trait is not set then + # the package-global default preferences node is used. + # + # fixme: This introduces a 'sneaky' global reference to the preferences + # node! + preferences = Instance(IPreferences) + + # The path to the preference node that contains the preferences that we + # use to initialize instances of this class. + preferences_path = Str + + ########################################################################### + # 'object' interface. + ########################################################################### + + def __init__(self, **traits): + """ Constructor. """ + + super(PreferencesHelper, self).__init__(**traits) + + # Initialize the object's traits from the preferences node. + if self.preferences: + self._initialize(self.preferences) + + return + + ########################################################################### + # Private interface. + ########################################################################### + + #### Trait initializers ################################################### + + def _preferences_default(self): + """ Trait initializer. """ + + # If no specific preferences node is set then we use the package-wide + # global node. + return get_default_preferences() + + #### Trait change handlers ################################################ + + def _anytrait_changed(self, trait_name, old, new): + """ Static trait change handler. """ + + # If we were the one that set the trait (because the underlying + # preferences node changed) then do nothing. + if self.preferences and self._is_preference_trait(trait_name): + self.preferences.set('%s.%s' % (self._get_path(), trait_name), new) + + return + + def _preferences_changed(self, old, new): + """ Static trait change handler. """ + + # Stop listening to the old preferences node. + if old is not None: + old.remove_preferences_listener( + self._preferences_changed_listener, self._get_path() + ) + + if new is not None: + # Initialize with the new preferences node (this also adds a + # listener for preferences being changed in the new node). + self._initialize(new, notify=True) + + return + + #### Other observer pattern listeners ##################################### + + def _preferences_changed_listener(self, node, key, old, new): + """ Listener called when a preference value is changed. """ + + if key in self.trait_names(): + setattr(self, key, self._get_value(key, new)) + + return + + #### Methods ############################################################## + + def _get_path(self): + """ Return the path to our preferences node. """ + + if len(self.preferences_path) > 0: + path = self.preferences_path + + else: + path = getattr(self, 'PREFERENCES_PATH', None) + if path is None: + raise SystemError('no preferences path, %s' % self) + + else: + logger.warn('DEPRECATED: use "preferences_path" %s' % self) + + return path + + def _get_value(self, trait_name, value): + """ Get the actual value to set. + + This method makes sure that any required work is done to convert the + preference value from a string. Str traits or those with the metadata + 'is_str=True' will just be passed the string itself. + + """ + + trait = self.trait(trait_name) + handler = trait.handler + + # If the trait type is 'Str' or Unicode then we just take the raw value. + if isinstance(handler, (Str, Unicode)) or trait.is_str: + pass + + # Otherwise, we eval it! + else: + try: + value = eval(value) + + # If the eval fails then there is probably a syntax error, but + # we will let the handler validation throw the exception. + except: + pass + + if handler.validate is not None: + # Any traits have a validator of None. + validated = handler.validate(self, trait_name, value) + else: + validated = value + + return validated + + def _initialize(self, preferences, notify=False): + """ Initialize the object's traits from the preferences node. """ + + path = self._get_path() + keys = preferences.keys(path) + + traits_to_set = {} + for trait_name in self.trait_names(): + if trait_name in keys: + key = '%s.%s' % (path, trait_name) + value = self._get_value(trait_name, preferences.get(key)) + traits_to_set[trait_name] = value + + self.trait_set(trait_change_notify=notify, **traits_to_set) + + # Listen for changes to the node's preferences. + preferences.add_preferences_listener( + self._preferences_changed_listener, path + ) + + return + + # fixme: Pretty much duplicated in 'PreferencesPage' (except for the + # class name of course!). + def _is_preference_trait(self, trait_name): + """ Return True if a trait represents a preference value. """ + + if trait_name.startswith('_') or trait_name.endswith('_') \ + or trait_name in PreferencesHelper.class_traits(): + return False + + return True
+ +#### EOF ###################################################################### +
+ +
+
+
+
+
+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/4.5/_modules/apptools/preferences/scoped_preferences.html b/4.5/_modules/apptools/preferences/scoped_preferences.html new file mode 100644 index 000000000..c0744338a --- /dev/null +++ b/4.5/_modules/apptools/preferences/scoped_preferences.html @@ -0,0 +1,593 @@ + + + + + + + apptools.preferences.scoped_preferences — Apptools Documentation + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +

Source code for apptools.preferences.scoped_preferences

+""" A preferences node that adds the notion of preferences scopes. """
+
+from __future__ import print_function
+
+# Standard library imports.
+from os.path import join
+
+# Enthought library imports.
+from traits.etsconfig.api import ETSConfig
+from traits.api import List, Str, Undefined
+
+# Local imports.
+from .i_preferences import IPreferences
+from .preferences import Preferences
+
+
+
[docs]class ScopedPreferences(Preferences): + """ A preferences node that adds the notion of preferences scopes. + + Scopes provide a way to access preferences in a precedence order, usually + depending on where they came from, for example from the command-line, + or set by the user in a preferences file, or the defaults (set by the + developer). + + By default, this class provides two scopes - 'application' which is + persistent and 'default' which is not. + + Path names passed to 'ScopedPreferences' nodes can be either:: + + a) a preference path as used in a standard 'Preferences' node, e.g:: + + 'acme.widget.bgcolor'. + + In this case the operation either takes place in the primary scope + (for operations such as 'set' etc), or on all scopes in precedence order + (for operations such as 'get' etc). + + or + + b) a preference path that refers to a specific scope e.g:: + + 'default/acme.widget.bgcolor' + + In this case the operation takes place *only* in the specified scope. + + There is one drawback to this scheme. If you want to access a scope node + itself via the 'clear', 'keys', 'node', 'node_exists' or 'node_names' + methods then you have to append a trailing '/' to the path. Without that, + the node would try to perform the operation in the primary scope. + + e.g. To get the names of the children of the 'application' scope, use:: + + scoped.node_names('application/') + + If you did this:: + + scoped.node_names('application') + + Then the node would get the primary scope and try to find its child node + called 'application'. + + Of course you can just get the scope via:: + + application_scope = scoped.get_scope('application') + + and then call whatever methods you like on it - which is definitely more + intentional and is highly recommended:: + + application_scope.node_names() + + """ + + #### 'ScopedPreferences' interface ######################################## + + # The file that the application scope preferences are stored in. + # + # Defaults to:- + # + # os.path.join(ETSConfig.application_home, 'preferences.ini') + application_preferences_filename = Str + + # The scopes (in the order that they should be searched when looking up + # preferences). + # + # By default, this class provides two scopes - 'application' which is + # persistent and 'default' which is not. + scopes = List(IPreferences) + + # The name of the 'primary' scope. + # + # This is the scope that operations take place in if no scope is specified + # in a given path (for the 'get' operation, if no scope is specified the + # operation takes place in *all* scopes in order of precedence). If this is + # the empty string (the default) then the primary scope is the first scope + # in the 'scopes' list. + primary_scope_name = Str + + ########################################################################### + # 'IPreferences' protocol. + ########################################################################### + + #### Methods where 'path' refers to a preference #### + +
[docs] def get(self, path, default=None, inherit=False): + """ Get the value of the preference at the specified path. """ + + if len(path) == 0: + raise ValueError('empty path') + + # If the path contains a specific scope then lookup the preference in + # just that scope. + if self._path_contains_scope(path): + scope_name, path = self._parse_path(path) + nodes = [self._get_scope(scope_name)] + + # Otherwise, try each scope in turn (i.e. in order of precedence). + else: + nodes = self.scopes + + # Try all nodes first (without inheritance even if specified). + value = self._get(path, Undefined, nodes, inherit=False) + if value is Undefined: + if inherit: + value = self._get(path, default, nodes, inherit=True) + + else: + value = default + + return value
+ +
[docs] def remove(self, path): + """ Remove the preference at the specified path. """ + + if len(path) == 0: + raise ValueError('empty path') + + # If the path contains a specific scope then remove the preference from + # just that scope. + if self._path_contains_scope(path): + scope_name, path = self._parse_path(path) + node = self._get_scope(scope_name) + + # Otherwise, remove the preference from the primary scope. + else: + node = self._get_primary_scope() + + node.remove(path) + + return
+ +
[docs] def set(self, path, value): + """ Set the value of the preference at the specified path. """ + + if len(path) == 0: + raise ValueError('empty path') + + # If the path contains a specific scope then set the value in that + # scope. + if self._path_contains_scope(path): + scope_name, path = self._parse_path(path) + node = self._get_scope(scope_name) + + # Otherwise, set the value in the primary scope. + else: + node = self._get_primary_scope() + + node.set(path, value) + + return
+ + #### Methods where 'path' refers to a node #### + +
[docs] def clear(self, path=''): + """ Remove all preference from the node at the specified path. """ + + # If the path contains a specific scope then remove the preferences + # from a node in that scope. + if self._path_contains_scope(path): + scope_name, path = self._parse_path(path) + node = self._get_scope(scope_name) + + # Otherwise, remove the preferences from a node in the primary scope. + else: + node = self._get_primary_scope() + + return node.clear(path)
+ +
[docs] def keys(self, path=''): + """ Return the preference keys of the node at the specified path. """ + + # If the path contains a specific scope then get the keys of the node + # in that scope. + if self._path_contains_scope(path): + scope_name, path = self._parse_path(path) + nodes = [self._get_scope(scope_name)] + + # Otherwise, merge the keys of the node in all scopes. + else: + nodes = self.scopes + + keys = set() + for node in nodes: + keys.update(node.node(path).keys()) + + return list(keys)
+ +
[docs] def node(self, path=''): + """ Return the node at the specified path. """ + + if len(path) == 0: + node = self + + else: + # If the path contains a specific scope then we get the node that + # scope. + if self._path_contains_scope(path): + scope_name, path = self._parse_path(path) + node = self._get_scope(scope_name) + + # Otherwise, get the node from the primary scope. + else: + node = self._get_primary_scope() + + node = node.node(path) + + return node
+ +
[docs] def node_exists(self, path=''): + """ Return True if the node at the specified path exists. """ + + # If the path contains a specific scope then look for the node in that + # scope. + if self._path_contains_scope(path): + scope_name, path = self._parse_path(path) + node = self._get_scope(scope_name) + + # Otherwise, look for the node in the primary scope. + else: + node = self._get_primary_scope() + + return node.node_exists(path)
+ +
[docs] def node_names(self, path=''): + """ Return the names of the children of the node at the specified path. + + """ + + # If the path contains a specific scope then get the names of the + # children of the node in that scope. + if self._path_contains_scope(path): + scope_name, path = self._parse_path(path) + nodes = [self._get_scope(scope_name)] + + # Otherwise, merge the names of the children of the node in all scopes. + else: + nodes = self.scopes + + names = set() + for node in nodes: + names.update(node.node(path).node_names()) + + return list(names)
+ + ########################################################################### + # 'Preferences' protocol. + ########################################################################### + + #### Listener methods #### + +
[docs] def add_preferences_listener(self, listener, path=''): + """ Add a listener for changes to a node's preferences. """ + + # If the path contains a specific scope then add a preferences listener + # to the node in that scope. + if self._path_contains_scope(path): + scope_name, path = self._parse_path(path) + nodes = [self._get_scope(scope_name)] + + # Otherwise, add a preferences listener to the node in all scopes. + else: + nodes = self.scopes + + for node in nodes: + node.add_preferences_listener(listener, path) + + return
+ +
[docs] def remove_preferences_listener(self, listener, path=''): + """ Remove a listener for changes to a node's preferences. """ + + # If the path contains a specific scope then remove a preferences + # listener from the node in that scope. + if self._path_contains_scope(path): + scope_name, path = self._parse_path(path) + nodes = [self._get_scope(scope_name)] + + # Otherwise, remove a preferences listener from the node in all scopes. + else: + nodes = self.scopes + + for node in nodes: + node.remove_preferences_listener(listener, path) + + return
+ + #### Persistence methods #### + +
[docs] def load(self, file_or_filename=None): + """ Load preferences from a file. + + This loads the preferences into the primary scope. + + fixme: I'm not sure it is worth providing an implentation here. I + think it would be better to encourage people to explicitly reference + a particular scope. + + """ + + if file_or_filename is None and len(self.filename) > 0: + file_or_filename = self.filename + + node = self._get_primary_scope() + node.load(file_or_filename) + + return
+ +
[docs] def save(self, file_or_filename=None): + """ Save the node's preferences to a file. + + This asks each scope in turn to save its preferences. + + If a file or filename is specified then it is only passed to the + primary scope. + + """ + + if file_or_filename is None and len(self.filename) > 0: + file_or_filename = self.filename + + self._get_primary_scope().save(file_or_filename) + for scope in self.scopes: + if scope is not self._get_primary_scope(): + scope.save() + + return
+ + ########################################################################### + # 'ScopedPreferences' protocol. + ########################################################################### + + def _application_preferences_filename_default(self): + """ Trait initializer. """ + + return join(ETSConfig.application_home, 'preferences.ini') + + # fixme: In hindsight, I don't think this class should have provided + # default scopes. This should have been an 'abstract' class that could + # be subclassed by classes providing specific scopes. + def _scopes_default(self): + """ Trait initializer. """ + + scopes = [ + Preferences( + name = 'application', + filename = self.application_preferences_filename + ), + + Preferences(name='default') + ] + + return scopes + +
[docs] def get_scope(self, scope_name): + """ Return the scope with the specified name. + + Return None if no such scope exists. + + """ + + for scope in self.scopes: + if scope_name == scope.name: + break + + else: + scope = None + + return scope
+ + ########################################################################### + # Private protocol. + ########################################################################### + + def _get(self, path, default, nodes, inherit): + """ Get a preference from a list of nodes. """ + + for node in nodes: + value = node.get(path, Undefined, inherit) + if value is not Undefined: + break + + else: + value = default + + return value + + def _get_scope(self, scope_name): + """ Return the scope with the specified name. + + Raise a 'ValueError' is no such scope exists. + + """ + + scope = self.get_scope(scope_name) + if scope is None: + raise ValueError('no such scope %s' % scope_name) + + return scope + + def _get_primary_scope(self): + """ Return the primary scope. + + By default, this is the first scope. + + """ + + if len(self.primary_scope_name) > 0: + scope = self._get_scope(self.primary_scope_name) + + else: + scope = self.scopes[0] + + return scope + + def _path_contains_scope(self, path): + """ Return True if the path contains a scope component. """ + + return '/' in path + + def _parse_path(self, path): + """ 'Parse' the path into two parts, the scope name and the rest! """ + + components = path.split('/') + + return components[0], '/'.join(components[1:]) + + ########################################################################### + # Debugging interface. + ########################################################################### + +
[docs] def dump(self, indent=''): + """ Dump the preferences hierarchy to stdout. """ + + if indent == '': + print() + + print(indent, 'Node(%s)' % self.name, self._preferences) + indent += ' ' + + for child in self.scopes: + child.dump(indent) + + return
+ +#### EOF ###################################################################### +
+ +
+
+
+
+
+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/4.5/_modules/apptools/preferences/ui/i_preferences_page.html b/4.5/_modules/apptools/preferences/ui/i_preferences_page.html new file mode 100644 index 000000000..db3f35d6f --- /dev/null +++ b/4.5/_modules/apptools/preferences/ui/i_preferences_page.html @@ -0,0 +1,163 @@ + + + + + + + apptools.preferences.ui.i_preferences_page — Apptools Documentation + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +

Source code for apptools.preferences.ui.i_preferences_page

+""" The interface for pages in a preferences dialog. """
+
+
+# Enthought library imports.
+from traits.api import Interface, Str
+
+
+
[docs]class IPreferencesPage(Interface): + """ The interface for pages in a preferences dialog. """ + + # The page's category (e.g. 'General/Appearence'). The empty string means + # that this is a top-level page. + category = Str + + # The page's help identifier (optional). If a help Id *is* provided then + # there will be a 'Help' button shown on the preference page. + help_id = Str + + # The page name (this is what is shown in the preferences dialog). + name = Str + +
[docs] def apply(self): + """ Apply the page's preferences. """
+ + # fixme: We would like to be able to have the following API so that + # developers are not forced into using traits UI for their preferences + # pages, but at the moment I can't work out how to do it! +## def create_control(self, parent): +## """ Create the toolkit-specific control that represents the page. """ + +## def destroy_control(self, parent): +## """ Destroy the toolkit-specific control that represents the page. """ + +#### EOF ###################################################################### +
+ +
+
+
+
+
+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/4.5/_modules/apptools/preferences/ui/preferences_manager.html b/4.5/_modules/apptools/preferences/ui/preferences_manager.html new file mode 100644 index 000000000..6a250cd78 --- /dev/null +++ b/4.5/_modules/apptools/preferences/ui/preferences_manager.html @@ -0,0 +1,433 @@ + + + + + + + apptools.preferences.ui.preferences_manager — Apptools Documentation + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +

Source code for apptools.preferences.ui.preferences_manager

+""" The preferences manager. """
+
+
+# Enthought library imports.
+from traits.api import HasTraits, Instance, List, Property, \
+    Any, Bool, Dict
+from traitsui.api import Handler, HSplit, Item, TreeEditor
+from traitsui.api import TreeNode, View, HTMLEditor
+from traitsui.menu import Action
+
+# Local imports.
+from .preferences_node import PreferencesNode
+from .preferences_page import PreferencesPage
+
+# fixme: This is part of the attempt to allow developers to use non-Traits UI
+# preferences pages. It doesn't work yet!
+##from widget_editor import WidgetEditor
+
+
+# A tree editor for preferences nodes.
+tree_editor = TreeEditor(
+    nodes = [
+        TreeNode(
+            node_for  = [PreferencesNode],
+            auto_open = False,
+            children  = 'children',
+            label     = 'name',
+            rename    = False,
+            copy      = False,
+            delete    = False,
+            insert    = False,
+            menu      = None,
+        ),
+    ],
+
+    editable   = False,
+    hide_root  = True,
+    selected   = 'selected_node',
+    show_icons = False
+)
+
+
+
[docs]class PreferencesHelpWindow(HasTraits): + """ Container class to present a view with string info. """ + +
[docs] def traits_view(self): + """ Default view to show for this class. """ + args = [] + kw_args = {'title' : 'Preferences Page Help', + 'buttons' : ['OK'], + 'width' : 800, + 'height' : 800, + 'resizable' : True, + 'id' : 'apptools.preferences.ui.preferences_manager.help'} + to_show = {} + + for name, trait_obj in self.traits().items(): + if name != 'trait_added' and name != 'trait_modified': + to_show[name] = trait_obj.help + for name in to_show: + args.append(Item(name, + style='readonly', + editor=HTMLEditor() + )) + + view = View(*args, **kw_args) + return view
+ + +
[docs]class PreferencesManagerHandler(Handler): + """ The traits UI handler for the preferences manager. """ + + model = Instance(HasTraits) + + ########################################################################### + # 'Handler' interface. + ########################################################################### + +
[docs] def apply(self, info): + """ Handle the **Apply** button being clicked. """ + + info.object.apply() + return
+ +
[docs] def init(self, info): + """ Initialize the controls of a user interface. """ + + # Select the first node in the tree (if there is one). + self._select_first_node(info) + + return super(PreferencesManagerHandler, self).init(info)
+ + +
[docs] def close(self, info, is_ok): + """ Close a dialog-based user interface. """ + + if is_ok: + info.object.apply() + + return super(PreferencesManagerHandler, self).close(info, is_ok)
+ + +
[docs] def preferences_help(self, info): + """ Custom preferences help panel. The Traits help doesn't work.""" + current_page = self.model.selected_page + to_show = {} + for trait_name, trait_obj in current_page.traits().items(): + if hasattr(trait_obj, 'show_help') and trait_obj.show_help: + to_show[trait_name] = trait_obj.help + + help_obj = PreferencesHelpWindow(**to_show) + help_obj.edit_traits(kind='livemodal') + return
+ + + ########################################################################### + # Private interface. + ########################################################################### + + def _select_first_node(self, info): + """ Select the first node in the tree (if there is one). """ + + root = info.object.root + + if len(root.children) > 0: + node = root.children[0] + info.object.selected_page = node.page + + return
+ + +
[docs]class PreferencesManager(HasTraits): + """ The preferences manager. """ + + # All of the preferences pages known to the manager. + pages = List(PreferencesPage) + + # The root of the preferences node tree. + root = Property(Instance(PreferencesNode)) + + # The preferences node currently selected in the tree. + selected_node = Instance(PreferencesNode) + + # The preferences associated with the currently selected preferences node. + selected_page = Instance(PreferencesPage) + + # Should the custom Info button be shown? If this is True, then an + # Info button is shown that pops up a trait view with an HTML entry + # for each trait of the *selected_page* with the metadata 'show_help' + # set to True. + show_help = Bool(False) + + # Should the Apply button be shown? + show_apply = Bool(False) + + #### Traits UI views ###################################################### + +
[docs] def traits_view(self): + """ Default traits view for this class. """ + + help_action = Action(name = 'Info', action = 'preferences_help') + + buttons = ['OK', 'Cancel'] + + if self.show_apply: + buttons = ['Apply'] + buttons + if self.show_help: + buttons = [help_action] + buttons + + + # A tree editor for preferences nodes. + tree_editor = TreeEditor( + nodes = [ + TreeNode( + node_for = [PreferencesNode], + auto_open = False, + children = 'children', + label = 'name', + rename = False, + copy = False, + delete = False, + insert = False, + menu = None, + ), + ], + on_select = self._selection_changed, + editable = False, + hide_root = True, + selected = 'selected_node', + show_icons = False + ) + + view = View( + HSplit( + Item( + name = 'root', + editor = tree_editor, + show_label = False, + width = 250, + ), + + Item( + name = 'selected_page', + #editor = WidgetEditor(), + show_label = False, + width = 450, + style = 'custom', + ), + ), + + buttons = buttons, + handler = PreferencesManagerHandler(model=self), + resizable = True, + title = 'Preferences', + width = .3, + height = .3, + kind = 'modal' + ) + self.selected_page = self.pages[0] + return view
+ + ########################################################################### + # 'PreferencesManager' interface. + ########################################################################### + + #### Trait properties ##################################################### + + def _get_root(self): + """ Property getter. """ + + # Sort the pages by the length of their category path. This makes it + # easy for us to create the preference hierarchy as we know that all of + # a node's ancestors will have already been created. + def sort_key(a): + # We have the guard because if the category is the empty string + # then split will still return a list containing one item (and not + # the empty list). + if len(a.category) == 0: + len_a = 0 + + else: + len_a = len(a.category.split('/')) + + return len_a + + self.pages.sort(key=sort_key) + + # Create a corresponding preference node hierarchy (the root of the + # hierachy is NOT displayed in the preference dialog). + # + # fixme: Currently we have to create a dummy page for the root node + # event though the root does not get shown in the tree! + root_page = PreferencesPage(name='Root', preferences_path='root') + root = PreferencesNode(page=root_page) + + for page in self.pages: + # Get the page's parent node. + parent = self._get_parent(root, page) + + # Add a child node representing the page. + parent.append(PreferencesNode(page=page)) + + return root + + #### Trait change handlers ################################################ + + def _selection_changed(self, new_selection): + self.selected_node = new_selection + + + def _selected_node_changed(self, new): + """ Static trait change handler. """ + if self.selected_node: + self.selected_page = self.selected_node.page + + return + + #### Methods ############################################################## + +
[docs] def apply(self): + """ Apply all changes made in the manager. """ + + for page in self.pages: + page.apply() + + return
+ + ########################################################################### + # Private interface. + ########################################################################### + + def _get_parent(self, root, page): + """ Return the page's parent preference node. """ + + parent = root + + if len(page.category) > 0: + components = page.category.split('/') + for component in components: + parent = parent.lookup(component) + + return parent
+ +#### EOF ###################################################################### +
+ +
+
+
+
+
+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/4.5/_modules/apptools/preferences/ui/preferences_node.html b/4.5/_modules/apptools/preferences/ui/preferences_node.html new file mode 100644 index 000000000..d2d514482 --- /dev/null +++ b/4.5/_modules/apptools/preferences/ui/preferences_node.html @@ -0,0 +1,231 @@ + + + + + + + apptools.preferences.ui.preferences_node — Apptools Documentation + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +

Source code for apptools.preferences.ui.preferences_node

+#------------------------------------------------------------------------------
+# Copyright (c) 2005, Enthought, Inc.
+# All rights reserved.
+#
+# This software is provided without warranty under the terms of the BSD
+# license included in enthought/LICENSE.txt and may be redistributed only
+# under the conditions described in the aforementioned license.  The license
+# is also available online at http://www.enthought.com/licenses/BSD.txt
+# Thanks for using Enthought open source!
+#
+# Author: Enthought, Inc.
+# Description: <Enthought pyface package component>
+#------------------------------------------------------------------------------
+""" Abstract base class for a node in a preferences dialog. """
+
+from __future__ import print_function
+
+# Enthought library imports.
+from traits.api import Delegate, Instance, Str
+
+# Local imports.
+from .i_preferences_page import IPreferencesPage
+from .tree_item import TreeItem
+
+
+
[docs]class PreferencesNode(TreeItem): + """ Abstract base class for a node in a preferences dialog. + + A preferences node has a name and an image which are used to represent the + node in a preferences dialog (usually in the form of a tree). + + """ + + #### 'PreferenceNode' interface ########################################### + + # The page's help identifier (optional). If a help Id *is* provided then + # there will be a 'Help' button shown on the preference page. + help_id = Delegate('page') + + # The page name (this is what is shown in the preferences dialog. + name = Delegate('page') + + # The page that we are a node for. + page = Instance(IPreferencesPage) + + ########################################################################### + # 'object' interface. + ########################################################################### + + def __str__(self): + """ Returns the string representation of the item. """ + + if self.page is None: + s = 'root' + + else: + s = self.page.name + + return s + + __repr__ = __str__ + + ########################################################################### + # 'PreferencesNode' interface. + ########################################################################### + +
[docs] def create_page(self, parent): + """ Creates the preference page for this node. """ + + return self.page.create_control(parent)
+ +
[docs] def lookup(self, name): + """ Returns the child of this node with the specified Id. + + Returns None if no such child exists. + + """ + + for node in self.children: + if node.name == name: + break + + else: + node = None + + return node
+ + ########################################################################### + # Debugging interface. + ########################################################################### + +
[docs] def dump(self, indent=''): + """ Pretty-print the node to stdout. """ + + print(indent, 'Node', str(self)) + + for child in self.children: + child.dump(indent+' ') + + return
+ +#### EOF ###################################################################### +
+ +
+
+
+
+
+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/4.5/_modules/apptools/preferences/ui/preferences_page.html b/4.5/_modules/apptools/preferences/ui/preferences_page.html new file mode 100644 index 000000000..0b8d1e09f --- /dev/null +++ b/4.5/_modules/apptools/preferences/ui/preferences_page.html @@ -0,0 +1,250 @@ + + + + + + + apptools.preferences.ui.preferences_page — Apptools Documentation + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +

Source code for apptools.preferences.ui.preferences_page

+""" A page in a preferences dialog. """
+
+
+# Enthought library imports.
+from apptools.preferences.api import PreferencesHelper
+from traits.api import Any, Dict, Str, provides
+
+# Local imports.
+from .i_preferences_page import IPreferencesPage
+
+
+
[docs]@provides(IPreferencesPage) +class PreferencesPage(PreferencesHelper): + """ A page in a preferences dialog. """ + + + + #### 'IPreferencesPage' interface ######################################### + + # The page's category (e.g. 'General/Appearance'). The empty string means + # that this is a top-level page. + category = Str + + # DEPRECATED: The help_id was never fully implemented, and it's been + # over two years (now 4/2009). The original goal was for the the Help + # button to automatically appear and connect to a help page with a + # help_id. Not removing the trait right now to avoid breaking code + # that may be checking for this. + # + # Use PreferencesManager.show_help and trait show_help metadata instead. + help_id = Str + + # The page name (this is what is shown in the preferences dialog. + name = Str + + #### Private interface #################################################### + + # The traits UI that represents the page. + _ui = Any + + # A dictionary containing the traits that have been changed since the + # last call to 'apply'. + _changed = Dict + + ########################################################################### + # 'IPreferencesPage' interface. + ########################################################################### + +
[docs] def apply(self): + """ Apply the page's preferences. """ + + path = self._get_path() + + for trait_name, value in self._changed.items(): + if self._is_preference_trait(trait_name): + self.preferences.set('%s.%s' % (path, trait_name), value) + + self._changed.clear() + + return
+ + # fixme: We would like to be able to have the following API so that + # developers are not forced into using traits UI for their preferences + # pages, but at the moment I can't work out how to do it! +## def create_control(self, parent): +## """ Create the toolkit-specific control that represents the page. """ + +## if self._ui is None: +## self._ui = self.edit_traits(parent=parent, kind='subpanel') + +## return self._ui.control + +## def destroy_control(self): +## """ Destroy the toolkit-specific control that represents the page. """ + +## if self._ui is not None: +## self._ui.dispose() +## self._ui = None + +## return + + ########################################################################### + # Private interface. + ########################################################################### + + #### Trait change handlers ################################################ + + def _anytrait_changed(self, trait_name, old, new): + """ Static trait change handler. + + This is an important override! In the base-class when a trait is + changed the preferences node is updated too. Here, we stop that from + happening and just make a note of what changes have been made. The + preferences node gets updated when the 'apply' method is called. + + """ + + # If the trait was a list or dict '_items' trait then just treat it as + # if the entire list or dict was changed. + if trait_name.endswith('_items'): + trait_name = trait_name[:-6] + if self._is_preference_trait(trait_name): + self._changed[trait_name] = getattr(self, trait_name) + + elif self._is_preference_trait(trait_name): + self._changed[trait_name] = new + + return + + # fixme: Pretty much duplicated in 'PreferencesHelper' (except for the + # class name of course!). + def _is_preference_trait(self, trait_name): + """ Return True if a trait represents a preference value. """ + + if trait_name.startswith('_') or trait_name.endswith('_') \ + or trait_name in PreferencesPage.class_traits(): + return False + + return True
+ +#### EOF ###################################################################### +
+ +
+
+
+
+
+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/4.5/_modules/apptools/preferences/ui/tree_item.html b/4.5/_modules/apptools/preferences/ui/tree_item.html new file mode 100644 index 000000000..a8965549a --- /dev/null +++ b/4.5/_modules/apptools/preferences/ui/tree_item.html @@ -0,0 +1,275 @@ + + + + + + + apptools.preferences.ui.tree_item — Apptools Documentation + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +

Source code for apptools.preferences.ui.tree_item

+#------------------------------------------------------------------------------
+# Copyright (c) 2005, Enthought, Inc.
+# All rights reserved.
+#
+# This software is provided without warranty under the terms of the BSD
+# license included in enthought/LICENSE.txt and may be redistributed only
+# under the conditions described in the aforementioned license.  The license
+# is also available online at http://www.enthought.com/licenses/BSD.txt
+# Thanks for using Enthought open source!
+#
+# Author: Enthought, Inc.
+# Description: <Enthought pyface package component>
+#------------------------------------------------------------------------------
+""" A generic base-class for items in a tree data structure.
+
+An example:-
+
+root = TreeItem(data='Root')
+
+fruit = TreeItem(data='Fruit')
+fruit.append(TreeItem(data='Apple', allows_children=False))
+fruit.append(TreeItem(data='Orange', allows_children=False))
+fruit.append(TreeItem(data='Pear', allows_children=False))
+root.append(fruit)
+
+veg = TreeItem(data='Veg')
+veg.append(TreeItem(data='Carrot', allows_children=False))
+veg.append(TreeItem(data='Cauliflower', allows_children=False))
+veg.append(TreeItem(data='Sprout', allows_children=False))
+root.append(veg)
+
+"""
+
+
+# Enthought library imports.
+from traits.api import Any, Bool, HasTraits, Instance, List, Property
+
+
+
[docs]class TreeItem(HasTraits): + """ A generic base-class for items in a tree data structure. """ + + #### 'TreeItem' interface ################################################# + + # Does this item allow children? + allows_children = Bool(True) + + # The item's children. + children = List(Instance('TreeItem')) + + # Arbitrary data associated with the item. + data = Any + + # Does the item have any children? + has_children = Property(Bool) + + # The item's parent. + parent = Instance('TreeItem') + + ########################################################################### + # 'object' interface. + ########################################################################### + + def __str__(self): + """ Returns the informal string representation of the object. """ + + if self.data is None: + s = '' + + else: + s = str(self.data) + + return s + + ########################################################################### + # 'TreeItem' interface. + ########################################################################### + + #### Properties ########################################################### + + # has_children + def _get_has_children(self): + """ True iff the item has children. """ + + return len(self.children) != 0 + + #### Methods ############################################################## + +
[docs] def append(self, child): + """ Appends a child to this item. + + This removes the child from its current parent (if it has one). + + """ + + return self.insert(len(self.children), child)
+ +
[docs] def insert(self, index, child): + """ Inserts a child into this item at the specified index. + + This removes the child from its current parent (if it has one). + + """ + + if child.parent is not None: + child.parent.remove(child) + + child.parent = self + self.children.insert(index, child) + + return child
+ +
[docs] def remove(self, child): + """ Removes a child from this item. """ + + child.parent = None + self.children.remove(child) + + return child
+ +
[docs] def insert_before(self, before, child): + """ Inserts a child into this item before the specified item. + + This removes the child from its current parent (if it has one). + + """ + + index = self.children.index(before) + + self.insert(index, child) + + return (index, child)
+ +
[docs] def insert_after(self, after, child): + """ Inserts a child into this item after the specified item. + + This removes the child from its current parent (if it has one). + + """ + + index = self.children.index(after) + + self.insert(index + 1, child) + + return (index, child)
+ +#### EOF ###################################################################### +
+ +
+
+
+
+
+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/4.5/_modules/apptools/scripting/package_globals.html b/4.5/_modules/apptools/scripting/package_globals.html new file mode 100644 index 000000000..fd0119b6b --- /dev/null +++ b/4.5/_modules/apptools/scripting/package_globals.html @@ -0,0 +1,154 @@ + + + + + + + apptools.scripting.package_globals — Apptools Documentation + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +

Source code for apptools.scripting.package_globals

+"""
+Globals for the scripting package.
+"""
+# Author: Prabhu Ramachandran <prabhu@aero.iitb.ac.in>
+# Copyright (c) 2008, Prabhu Ramachandran and Enthought, Inc.
+# License: BSD Style.
+
+
+# The global recorder.
+_recorder = None
+
+
[docs]def get_recorder(): + """Return the global recorder. Does not create a new one if none + exists. + """ + global _recorder + return _recorder
+ +
[docs]def set_recorder(rec): + """Set the global recorder instance. + """ + global _recorder + _recorder = rec
+ + +
+ +
+
+
+
+
+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/4.5/_modules/apptools/scripting/recordable.html b/4.5/_modules/apptools/scripting/recordable.html new file mode 100644 index 000000000..1958670ae --- /dev/null +++ b/4.5/_modules/apptools/scripting/recordable.html @@ -0,0 +1,183 @@ + + + + + + + apptools.scripting.recordable — Apptools Documentation + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +

Source code for apptools.scripting.recordable

+"""
+Decorator to mark functions and methods as recordable.
+"""
+# Author: Prabhu Ramachandran <prabhu@aero.iitb.ac.in>
+# Copyright (c) 2008, Prabhu Ramachandran and Enthought, Inc.
+# License: BSD Style.
+
+from .package_globals import get_recorder
+
+
+# Guard to ensure that only the outermost recordable call is recorded
+# and nested calls ignored.
+_outermost_call = True
+
+
+
[docs]def recordable(func): + """A decorator that wraps a function into one that is recordable. + + This will record the function only if the global recorder has been + set via a `set_recorder` function call. + + This is almost entirely copied from the + apptools.appscripting.scriptable.scriptable decorator. + """ + + def _wrapper(*args, **kw): + """A wrapper returned to replace the decorated function.""" + global _outermost_call + + # Boolean to specify if the method was recorded or not. + record = False + if _outermost_call: + # Get the recorder. + rec = get_recorder() + if rec is not None: + _outermost_call = False + # Record the method if recorder is available. + record = True + try: + result = rec.record_function(func, args, kw) + finally: + _outermost_call = True + if not record: + # If the method was not recorded, just call it. + result = func(*args, **kw) + + return result + + # Mimic the actual function. + _wrapper.__name__ = func.__name__ + _wrapper.__doc__ = func.__doc__ + _wrapper.__dict__.update(func.__dict__) + + return _wrapper
+
+ +
+
+
+
+
+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/4.5/_modules/apptools/scripting/recorder.html b/4.5/_modules/apptools/scripting/recorder.html new file mode 100644 index 000000000..b3ae49a23 --- /dev/null +++ b/4.5/_modules/apptools/scripting/recorder.html @@ -0,0 +1,848 @@ + + + + + + + apptools.scripting.recorder — Apptools Documentation + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +

Source code for apptools.scripting.recorder

+"""
+Code to support recording to a readable and executable Python script.
+
+TODO:
+    - Support for dictionaries?
+
+"""
+# Author: Prabhu Ramachandran <prabhu@aero.iitb.ac.in>
+# Copyright (c) 2008-2015, Enthought, Inc.
+# License: BSD Style.
+
+import warnings
+
+import six
+import six.moves.builtins
+
+from traits.api import (HasTraits, List, Str, Dict, Bool,
+        Unicode, Property, Int, Instance)
+from traits.util.camel_case import camel_case_to_python
+
+
+################################################################################
+# `_RegistryData` class.
+################################################################################
+class _RegistryData(HasTraits):
+    # Object's script ID
+    script_id = Property(Str)
+
+    # Path to object in object hierarchy.
+    path = Property(Str)
+
+    # Parent data for this object if any.
+    parent_data = Instance('_RegistryData', allow_none=True)
+
+    # The name of the trait on the parent which is this object.
+    trait_name_on_parent = Str('')
+
+    # List of traits we are listening for on this object.
+    names = List(Str)
+
+    # Nested recordable instances on the object.
+    sub_recordables = List(Str)
+
+    # List of traits that are lists.
+    list_names = List(Str)
+
+    _script_id = Str('')
+
+    ######################################################################
+    # Non-public interface.
+    ######################################################################
+    def _get_path(self):
+        pdata = self.parent_data
+        path = ''
+        if pdata is not None:
+            pid = pdata.script_id
+            ppath = pdata.path
+            tnop = self.trait_name_on_parent
+            if '[' in tnop:
+                # If the object is a nested object through an iterator,
+                # we instantiate it and don't refer to it through the
+                # path, this makes scripting convenient.
+                if len(ppath) == 0:
+                    path = pid + '.' + tnop
+                else:
+                    path = ppath + '.' + tnop
+            else:
+                path = ppath + '.' + tnop
+
+        return path
+
+    def _get_script_id(self):
+        sid = self._script_id
+        if len(sid) == 0:
+            pdata = self.parent_data
+            sid = pdata.script_id + '.' + self.trait_name_on_parent
+        return sid
+
+    def _set_script_id(self, id):
+        self._script_id = id
+
+
+
+################################################################################
+# `RecorderError` class.
+################################################################################
+
[docs]class RecorderError(Exception): + pass
+ + +################################################################################ +# `Recorder` class. +################################################################################ +
[docs]class Recorder(HasTraits): + + # The lines of code recorded. + lines = List(Str) + + # Are we recording or not? + recording = Bool(False, desc='if script recording is enabled or not') + + # The Python script we have recorded so far. This is just a + # convenience trait for the `get_code()` method. + script = Property(Unicode) + + ######################################## + # Private traits. + + # Dict used to store information on objects registered. It stores a + # unique name for the object and its path in the object hierarchy + # traversed. + _registry = Dict + + # Reverse registry with keys as script_id and object as value. + _reverse_registry = Dict + + # A mapping to generate unique names for objects. The key is the + # name used (which is something derived from the class name of the + # object) and the value is an integer describing the number of times + # that variable name has been used earlier. + _name_map = Dict(Str, Int) + + # A list of special reserved script IDs. This is handy when you + # want a particular object to have an easy to read script ID and not + # the default one based on its class name. This leads to slightly + # easier to read scripts. + _special_ids = List + + # What are the known names in the script? By known names we mean + # names which are actually bound to objects. + _known_ids = List(Str) + + # The known types in the namespace. + _known_types = List(Str) + + # A guard to check if we are currently in a recorded function call, + # in which case we don't want to do any recording. + _in_function = Bool(False) + + ###################################################################### + # `Recorder` interface. + ###################################################################### +
[docs] def record(self, code): + """Record a string to be stored to the output file. + + Parameters: + ----------- + + code - A string of text. + """ + if self.recording and not self._in_function: + lines = self.lines + # Analyze the code and add extra code if needed. + self._analyze_code(code) + # Add the code. + lines.append(code)
+ +
[docs] def register(self, object, parent=None, trait_name_on_parent='', + ignore=None, known=False, script_id=None): + """Register an object with the recorder. This sets up the + object for recording. + + By default all traits (except those starting and ending with + '_') are recorded. For attributes that are themselves + recordable, one may mark traits with a 'record' metadata as + follows: + + - If metadata `record=False` is set, the nested object will not be + recorded. + + - If `record=True`, then that object is also recorded if it is + not `None`. + + If the object is a list or dict that is marked with + `record=True`, the list is itself not listened to for changes + but all its contents are registered. + + If the `object` has a trait named `recorder` then this recorder + instance will be set to it if possible. + + Parameters: + ----------- + + object : Instance(HasTraits) + The object to register in the registry. + + parent : Instance(HasTraits) + An optional parent object in which `object` is contained + + trait_name_on_parent : str + An optional trait name of the `object` in the `parent`. + + ignore : list(str) + An optional list of trait names on the `object` to be + ignored. + + known : bool + Optional specification if the `object` id is known on the + interpreter. This is needed if you are manually injecting + code to define/create an object. + + script_id : str + Optionally specify a script_id to use for this object. It + is not guaranteed that this ID will be used since it may + already be in use. + """ + registry = self._registry + + # Do nothing if the object is already registered. + if object in registry: + return + + # When parent is specified the trait_name_on_parent must also be. + if parent is not None: + assert len(trait_name_on_parent) > 0 + + if ignore is None: + ignore = [] + + if isinstance(object, HasTraits): + # Always ignore these. + ignore.extend(['trait_added', 'trait_modified']) + + sub_recordables = list(object.traits(record=True).keys()) + # Find all the trait names we must ignore. + ignore.extend(object.traits(record=False).keys()) + # The traits to listen for. + tnames = [t for t in object.trait_names() + if not t.startswith('_') and not t.endswith('_') \ + and t not in ignore] + # Find all list traits. + trts = object.traits() + list_names = [] + for t in tnames: + tt = trts[t].trait_type + if hasattr(tt, 'default_value_type') and \ + tt.default_value_type == 5: + list_names.append(t) + else: + # No traits, so we can't do much. + sub_recordables = [] + tnames = [] + list_names = [] + + # Setup the registry data. + + # If a script id is supplied try and use it. + sid = '' + if script_id is not None: + r_registry = self._reverse_registry + while script_id in r_registry: + script_id = '%s1'%script_id + sid = script_id + # Add the chosen id to special_id list. + self._special_ids.append(sid) + + if parent is None: + pdata = None + if len(sid) == 0: + sid = self._get_unique_name(object) + else: + pdata = self._get_registry_data(parent) + tnop = trait_name_on_parent + if '[' in tnop: + # If the object is a nested object through an iterator, + # we instantiate it and don't refer to it through the + # path, this makes scripting convenient. + sid = self._get_unique_name(object) + + # Register the object with the data. + data = _RegistryData(script_id=sid, + parent_data=pdata, + trait_name_on_parent=trait_name_on_parent, + names=tnames, + sub_recordables=sub_recordables, + list_names=list_names) + registry[object] = data + + # Now get the script id of the object -- note that if sid is '' + # above then the script_id is computed from that of the parent. + sid = data.script_id + # Setup reverse registry so we can get the object from the + # script_id. + self._reverse_registry[sid] = object + + # Record the script_id if the known argument is explicitly set to + # True. + if known: + self._known_ids.append(sid) + + # Try and set the recorder attribute if necessary. + if hasattr(object, 'recorder'): + try: + object.recorder = self + except Exception as e: + msg = "Cannot set 'recorder' trait of object %r: "\ + "%s"%(object, e) + warnings.warn(msg, warnings.RuntimeWarning) + + if isinstance(object, HasTraits): + # Add handler for lists. + for name in list_names: + object.on_trait_change(self._list_items_listner, + '%s_items'%name) + + # Register all sub-recordables. + for name in sub_recordables: + obj = getattr(object, name) + if isinstance(obj, list): + # Don't register the object itself but register its + # children. + for i, child in enumerate(obj): + attr = '%s[%d]'%(name, i) + self.register(child, parent=object, + trait_name_on_parent=attr) + elif obj is not None: + self.register(obj, parent=object, + trait_name_on_parent=name) + # Listen for changes to the trait itself so the newly + # assigned object can also be listened to. + object.on_trait_change(self._object_changed_handler, name) + # Now add listner for the object itself. + object.on_trait_change(self._listner, tnames)
+ +
[docs] def unregister(self, object): + """Unregister the given object from the recorder. This inverts + the logic of the `register(...)` method. + """ + registry = self._registry + # Do nothing if the object isn't registered. + if object not in registry: + return + + data = registry[object] + + # Try and unset the recorder attribute if necessary. + if hasattr(object, 'recorder'): + try: + object.recorder = None + except Exception as e: + msg = "Cannot unset 'recorder' trait of object %r:"\ + "%s"%(object, e) + warnings.warn(msg, warnings.RuntimeWarning) + + if isinstance(object, HasTraits): + # Remove all list_items handlers. + for name in data.list_names: + object.on_trait_change(self._list_items_listner, + '%s_items'%name, remove=True) + + # Unregister all sub-recordables. + for name in data.sub_recordables: + obj = getattr(object, name) + if isinstance(obj, list): + # Unregister the children. + for i, child in enumerate(obj): + self.unregister(child) + elif obj is not None: + self.unregister(obj) + # Remove the trait handler for trait assignments. + object.on_trait_change(self._object_changed_handler, + name, remove=True) + # Now remove listner for the object itself. + object.on_trait_change(self._listner, data.names, remove=True) + + # Remove the object data from the registry etc. + if data.script_id in self._known_ids: + self._known_ids.remove(data.script_id) + del self._reverse_registry[data.script_id] + del registry[object]
+ +
[docs] def save(self, file): + """Save the recorded lines to the given file. It does not close + the file. + """ + if six.PY3: + file.write(self.get_code()) + else: + file.write(six.text_type(self.get_code(), encoding='utf-8')) + file.flush()
+ +
[docs] def record_function(self, func, args, kw): + """Record a function call given the function and its + arguments.""" + if self.recording and not self._in_function: + # Record the function name and arguments. + call_str = self._function_as_string(func, args, kw) + # Call the function. + try: + self._in_function = True + result = func(*args, **kw) + finally: + self._in_function = False + + # Register the result if it is not None. + if func.__name__ == '__init__': + f_self = args[0] + code = self._import_class_string(f_self.__class__) + self.lines.append(code) + return_str = self._registry.get(f_self).script_id + else: + return_str = self._return_as_string(result) + if len(return_str) > 0: + self.lines.append('%s = %s'%(return_str, call_str)) + else: + self.lines.append('%s'%(call_str)) + else: + result = func(*args, **kw) + return result
+ +
[docs] def ui_save(self): + """Save recording to file, pop up a UI dialog to find out where + and close the file when done. + """ + from pyface.api import FileDialog, OK + wildcard = 'Python files (*.py)|*.py|' + FileDialog.WILDCARD_ALL + dialog = FileDialog(title='Save Script', + action='save as', wildcard=wildcard + ) + if dialog.open() == OK: + fname = dialog.path + f = open(fname, 'w') + self.save(f) + f.close()
+ +
[docs] def clear(self): + """Clears all previous recorded state and unregisters all + registered objects.""" + # First unregister any registered objects. + registry = self._registry + while len(registry) > 0: + self.unregister(list(registry.keys())[0]) + # Clear the various lists. + self.lines[:] = [] + self._registry.clear() + self._known_ids[:] = [] + self._name_map.clear() + self._reverse_registry.clear() + self._known_types[:] = [] + self._special_ids[:] = []
+ +
[docs] def get_code(self): + """Returns the recorded lines as a string of printable code.""" + return '\n'.join(self.lines) + '\n'
+ +
[docs] def is_registered(self, object): + """Returns True if the given object is registered with the + recorder.""" + return object in self._registry
+ +
[docs] def get_script_id(self, object): + """Returns the script_id of a registered object. Useful when + you want to manually add a record statement.""" + return self._get_registry_data(object).script_id
+ +
[docs] def get_object_path(self, object): + """Returns the path in the object hierarchy of a registered + object. Useful for debugging.""" + return self._get_registry_data(object).path
+ +
[docs] def write_script_id_in_namespace(self, script_id): + """If a script_id is not known in the current script's namespace, + this sets it using the path of the object or actually + instantiating it. If this is not possible (since the script_id + matches no existing object), nothing is recorded but the + framework is notified that the particular script_id is available + in the namespace. This is useful when you want to inject code + in the namespace to create a particular object. + """ + if not self.recording: + return + known_ids = self._known_ids + if script_id not in known_ids: + obj = self._reverse_registry.get(script_id) + # Add the ID to the known_ids. + known_ids.append(script_id) + if obj is not None: + data = self._registry.get(obj) + result = '' + if len(data.path) > 0: + # Record code for instantiation of object. + result = '%s = %s'%(script_id, data.path) + else: + # This is not the best thing to do but better than + # nothing. + result = self._import_class_string(obj.__class__) + cls = obj.__class__.__name__ + mod = obj.__module__ + result += '\n%s = %s()'%(script_id, cls) + + if len(result) > 0: + self.lines.extend(result.split('\n'))
+ + ###################################################################### + # Non-public interface. + ###################################################################### + def _get_unique_name(self, obj): + """Return a unique object name (a string). Note that this does + not cache the object, so if called with the same object 3 times + you'll get three different names. + """ + cname = obj.__class__.__name__ + nm = self._name_map + result = '' + builtin = False + if cname in six.moves.builtins.__dict__: + builtin = True + if hasattr(obj, '__name__'): + cname = obj.__name__ + else: + cname = camel_case_to_python(cname) + + special_ids = self._special_ids + while len(result) == 0 or result in special_ids: + if cname in nm: + id = nm[cname] + 1 + nm[cname] = id + result = '%s%d'%(cname, id) + else: + nm[cname] = 0 + # The first id doesn't need a number if it isn't builtin. + if builtin: + result = '%s0'%(cname) + else: + result = cname + return result + + def _get_registry_data(self, object): + """Get the data for an object from registry.""" + data = self._registry.get(object) + if data is None: + msg = "Recorder: Can't get script_id since object %s not registered" + raise RecorderError(msg%(object)) + return data + + def _listner(self, object, name, old, new): + """The listner for trait changes on an object. + + This is called by child listners or when any of the recordable + object's traits change when recording to a script is enabled. + + Parameters: + ----------- + + object : Object which has changed. + + name : extended name of attribute that changed. + + old : Old value. + + new : New value. + + """ + if self.recording and not self._in_function: + new_repr = repr(new) + sid = self._get_registry_data(object).script_id + if len(sid) == 0: + msg = '%s = %r'%(name, new) + else: + msg = '%s.%s = %r'%(sid, name, new) + if new_repr.startswith('<') and new_repr.endswith('>'): + self.record('# ' + msg) + else: + self.record(msg) + + def _list_items_listner(self, object, name, old, event): + """The listner for *_items on list traits of the object. + """ + # Set the path of registered objects in the modified list and + # all their children. This is done by unregistering the object + # and re-registering them. This is slow but. + registry = self._registry + sid = registry.get(object).script_id + trait_name = name[:-6] + items = getattr(object, trait_name) + for (i, item) in enumerate(items): + if item in registry: + data = registry.get(item) + tnop = data.trait_name_on_parent + if len(tnop) > 0: + data.trait_name_on_parent = '%s[%d]'%(trait_name, i) + + # Record the change. + if self.recording and not self._in_function: + index = event.index + removed = event.removed + added = event.added + nr = len(removed) + slice = '[%d:%d]'%(index, index + nr) + na = len(added) + rhs = [self._object_as_string(item) for item in added] + rhs = ', '.join(rhs) + obj = '%s.%s'%(sid, name[:-6]) + msg = '%s%s = [%s]'%(obj, slice, rhs) + self.record(msg) + + def _object_changed_handler(self, object, name, old, new): + """Called when a child recordable object has been reassigned.""" + registry = self._registry + if old is not None: + if old in registry: + self.unregister(old) + if new is not None: + if new not in registry: + self.register(new, parent=object, + trait_name_on_parent=name) + + def _get_script(self): + return self.get_code() + + def _analyze_code(self, code): + """Analyze the code and return extra code if needed. + """ + known_ids = self._known_ids + lhs = '' + try: + lhs = code.split()[0] + except IndexError: + pass + + if '.' in lhs: + ob_name = lhs.split('.')[0] + self.write_script_id_in_namespace(ob_name) + + def _function_as_string(self, func, args, kw): + """Return a string representing the function call.""" + func_name = func.__name__ + func_code = func.__code__ + # Even if func is really a decorated method it never shows up as + # a bound or unbound method here, so we have to inspect the + # argument names to figure out if this is a method or function. + if func_code.co_argcount > 0 and \ + func_code.co_varnames[0] == 'self': + # This is a method, the first argument is bound to self. + f_self = args[0] + # Convert the remaining arguments to strings. + argl = [self._object_as_string(arg) for arg in args[1:]] + + # If this is __init__ we special case it. + if func_name == '__init__': + # Register the object. + self.register(f_self, known=True) + func_name = f_self.__class__.__name__ + else: + sid = self._object_as_string(f_self) + func_name = '%s.%s'%(sid, func_name) + else: + argl = [self._object_as_string(arg) for arg in args] + + # Convert the keyword args. + kwl = ['%s=%s'%(key, self._object_as_string(value)) + for key, value in kw.items()] + argl.extend(kwl) + + # Make a string representation of the args, kw. + argstr = ', '.join(argl) + return '%s(%s)'%(func_name, argstr) + + def _is_arbitrary_object(self, object): + """Return True if the object is an arbitrary non-primitive object. + + As done in appscripting, we assume that if the hex id of the object is + in its string representation then it is an arbitrary object. + """ + ob_id = id(object) + orepr = repr(object) + hex_id = "%x"%ob_id + return hex_id.upper() in orepr.upper() + + def _object_as_string(self, object): + """Return a string representing the object. + """ + registry = self._registry + if object in registry: + # Return script id if the object is known; create the script + # id on the namespace if needed before that. + sid = registry.get(object).script_id + base_id = sid.split('.')[0] + self.write_script_id_in_namespace(base_id) + return sid + else: + if not self._is_arbitrary_object(object): + return repr(object) + + # If we get here, we just register the object and call ourselves + # again to do the needful. + self.register(object) + return self._object_as_string(object) + + def _return_as_string(self, object): + """Return a string given a returned object from a function. + """ + result = '' + long_type = long if six.PY2 else int + ignore = (float, complex, bool, int, long_type, str) + if object is not None and type(object) not in ignore: + # If object is not know, register it. + registry = self._registry + if object not in registry: + self.register(object) + result = registry.get(object).script_id + # Since this is returned it is known on the namespace. + known_ids = self._known_ids + if result not in known_ids: + known_ids.append(result) + return result + + def _import_class_string(self, cls): + """Import a class if needed. + """ + cname = cls.__name__ + result = '' + if cname not in six.moves.builtins.__dict__: + mod = cls.__module__ + typename = '%s.%s'%(mod, cname) + if typename not in self._known_types: + result = 'from %s import %s'%(mod, cname) + self._known_types.append(typename) + return result
+
+ +
+
+
+
+
+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/4.5/_modules/apptools/scripting/recorder_with_ui.html b/4.5/_modules/apptools/scripting/recorder_with_ui.html new file mode 100644 index 000000000..4947321e7 --- /dev/null +++ b/4.5/_modules/apptools/scripting/recorder_with_ui.html @@ -0,0 +1,219 @@ + + + + + + + apptools.scripting.recorder_with_ui — Apptools Documentation + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +

Source code for apptools.scripting.recorder_with_ui

+"""
+A Recorder subclass that presents a simple user interface.
+"""
+# Author: Prabhu Ramachandran <prabhu@aero.iitb.ac.in>
+# Copyright (c) 2008, Prabhu Ramachandran.
+# License: BSD Style.
+
+from traits.api import Code, Button, Int, on_trait_change, Any
+from traitsui.api import (View, Item, Group, HGroup, CodeEditor,
+                                     spring, Handler)
+
+from .recorder import Recorder
+
+######################################################################
+# `CloseHandler` class.
+######################################################################
+
[docs]class CloseHandler(Handler): + """This class cleans up after the UI for the recorder is closed.""" + +
[docs] def close(self, info, is_ok): + """This method is invoked when the user closes the UI.""" + recorder = info.object + recorder.on_ui_close() + return True
+ + +################################################################################ +# `RecorderWithUI` class. +################################################################################ +
[docs]class RecorderWithUI(Recorder): + """ + This class represents a Recorder but with a simple user interface. + """ + + # The code to display + code = Code(editor=CodeEditor(line='current_line')) + + # Button to save script to file. + save_script = Button('Save Script') + + # The current line to show, used by the editor. + current_line = Int + + # The root object which is being recorded. + root = Any + + ######################################## + # Traits View. + view = View( + Group( + HGroup(Item('recording', show_label=True), + spring, + Item('save_script', show_label=False), + ), + Group(Item('code', show_label=False)), + ), + width=600, + height=360, + id='apptools.scripting.recorder_with_ui', + buttons=['Cancel'], + resizable=True, + handler=CloseHandler() + ) + + ###################################################################### + # RecorderWithUI interface. + ###################################################################### +
[docs] def on_ui_close(self): + """Called from the CloseHandler when the UI is closed. This + method basically stops the recording. + """ + from .util import stop_recording + from .package_globals import get_recorder + + if get_recorder() is self: + stop_recording(self.root, save=False) + else: + self.recording = False + self.unregister(self.root)
+ + ###################################################################### + # Non-public interface. + ###################################################################### + @on_trait_change('lines[]') + def _update_code(self): + self.code = self.get_code() + self.current_line = len(self.lines) + 1 + + def _save_script_fired(self): + self.ui_save()
+
+ +
+
+
+
+
+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/4.5/_modules/apptools/scripting/util.html b/4.5/_modules/apptools/scripting/util.html new file mode 100644 index 000000000..d9f142517 --- /dev/null +++ b/4.5/_modules/apptools/scripting/util.html @@ -0,0 +1,179 @@ + + + + + + + apptools.scripting.util — Apptools Documentation + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +

Source code for apptools.scripting.util

+"""Simple utility functions provided by the scripting API.
+"""
+# Author: Prabhu Ramachandran <prabhu [at] aero . iitb . ac . in>
+# Copyright (c) 2008,  Prabhu Ramachandran
+# License: BSD Style.
+
+from .recorder import Recorder
+from .recorder_with_ui import RecorderWithUI
+from .package_globals import get_recorder, set_recorder
+
+
+################################################################################
+# Utility functions.
+################################################################################
+
[docs]def start_recording(object, ui=True, **kw): + """Convenience function to start recording. Returns the recorder. + + Parameters: + ----------- + + object : object to record. + + ui : bool specifying if a UI is to be shown or not + + kw : Keyword arguments to pass to the register function of the + recorder. + """ + if ui: + r = RecorderWithUI(root=object) + r.edit_traits(kind='live') + else: + r = Recorder() + # Set the global recorder. + set_recorder(r) + r.recording = True + r.register(object, **kw) + return r
+ +
[docs]def stop_recording(object, save=True): + """Stop recording the object. If `save` is `True`, this will pop up + a UI to ask where to save the script. + """ + recorder = get_recorder() + recorder.unregister(object) + recorder.recording = False + # Set the global recorder back to None + set_recorder(None) + # Save the script. + if save: + recorder.ui_save()
+
+ +
+
+
+
+
+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/4.5/_modules/apptools/selection/errors.html b/4.5/_modules/apptools/selection/errors.html new file mode 100644 index 000000000..d440c8edd --- /dev/null +++ b/4.5/_modules/apptools/selection/errors.html @@ -0,0 +1,161 @@ + + + + + + + apptools.selection.errors — Apptools Documentation + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +

Source code for apptools.selection.errors

+
[docs]class ProviderNotRegisteredError(Exception): + """ Raised when a provider is requested by ID and not found. """ + + def __init__(self, provider_id): + self.provider_id = provider_id + + def __str__(self): + msg = "Selection provider with ID '{id}' not found." + return msg.format(id=self.provider_id)
+ + +
[docs]class IDConflictError(Exception): + """ Raised when a provider is added and its ID is already registered. """ + + def __init__(self, provider_id): + self.provider_id = provider_id + + def __str__(self): + msg = "A selection provider with ID '{id}' is already registered." + return msg.format(id=self.provider_id)
+ + +
[docs]class ListenerNotConnectedError(Exception): + """ Raised when a listener that was never connected is disconnected. """ + + def __init__(self, provider_id, listener): + self.provider_id = provider_id + self.listener = listener + + def __str__(self): + msg = "Selection listener {l} is not connected to provider '{id}'." + return msg.format(l=self.listener, id=self.provider_id)
+
+ +
+
+
+
+
+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/4.5/_modules/apptools/selection/i_selection.html b/4.5/_modules/apptools/selection/i_selection.html new file mode 100644 index 000000000..b570483d5 --- /dev/null +++ b/4.5/_modules/apptools/selection/i_selection.html @@ -0,0 +1,150 @@ + + + + + + + apptools.selection.i_selection — Apptools Documentation + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +

Source code for apptools.selection.i_selection

+from traits.api import Interface, List, Str
+
+
+
[docs]class ISelection(Interface): + """ Collection of selected items. """ + + #: ID of the selection provider that created this selection object. + provider_id = Str + +
[docs] def is_empty(self): + """ Is the selection empty? """
+ + +
[docs]class IListSelection(ISelection): + """ Selection for ordered sequences of items. """ + + #: Selected objects. + items = List + + #: Indices of the selected objects in the selection provider. + indices = List
+
+ +
+
+
+
+
+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/4.5/_modules/apptools/selection/i_selection_provider.html b/4.5/_modules/apptools/selection/i_selection_provider.html new file mode 100644 index 000000000..24061c8da --- /dev/null +++ b/4.5/_modules/apptools/selection/i_selection_provider.html @@ -0,0 +1,167 @@ + + + + + + + apptools.selection.i_selection_provider — Apptools Documentation + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +

Source code for apptools.selection.i_selection_provider

+from traits.api import Event, Interface, Str
+
+
+
[docs]class ISelectionProvider(Interface): + """ Source of selections. """ + + #: Unique ID identifying the provider. + provider_id = Str() + + #: Event triggered when the selection changes. + #: The content of the event is an :class:`~.ISelection` instance. + selection = Event + +
[docs] def get_selection(self): + """ Return the current selection. + + Returns: + selection -- ISelection + Object representing the current selection. + """
+ +
[docs] def set_selection(self, items, ignore_missing=False): + """ Set the current selection to the given items. + + If ``ignore_missing`` is ``True``, items that are not available in the + selection provider are silently ignored. If it is ``False`` (default), + an :class:`~.ValueError` should be raised. + + Arguments: + items -- list + List of items to be selected. + + ignore_missing -- bool + If ``False`` (default), the provider raises an exception if any + of the items in ``items`` is not available to be selected. + Otherwise, missing elements are silently ignored, and the rest + is selected. + """
+
+ +
+
+
+
+
+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/4.5/_modules/apptools/selection/list_selection.html b/4.5/_modules/apptools/selection/list_selection.html new file mode 100644 index 000000000..741413d8b --- /dev/null +++ b/4.5/_modules/apptools/selection/list_selection.html @@ -0,0 +1,187 @@ + + + + + + + apptools.selection.list_selection — Apptools Documentation + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +

Source code for apptools.selection.list_selection

+from traits.api import HasTraits, List, provides, Str
+
+from apptools.selection.i_selection import IListSelection
+
+
+
[docs]@provides(IListSelection) +class ListSelection(HasTraits): + """ Selection for ordered sequences of items. + + This is the default implementation of the :class:`~.IListSelection` + interface. + """ + + #### 'ISelection' protocol ################################################ + + #: ID of the selection provider that created this selection object. + provider_id = Str + +
[docs] def is_empty(self): + """ Is the selection empty? """ + return len(self.items) == 0
+ + #### 'IListSelection' protocol ############################################ + + #: Selected objects. + items = List + + #: Indices of the selected objects in the selection provider. + indices = List + + #### 'ListSelection' class protocol ####################################### + +
[docs] @classmethod + def from_available_items(cls, provider_id, selected, all_items): + """ Create a list selection given a list of all available items. + + Fills in the required information (in particular, the indices) based + on a list of selected items and a list of all available items. + + .. note:: + - The list of available items must not contain any duplicate items. + - It is expected that ``selected`` is populated by items in + ``all_items``. + + """ + number_of_items = len(all_items) + indices = [] + + for item in selected: + for index in range(number_of_items): + if all_items[index] is item: + indices.append(index) + break + else: + msg = 'Selected item: {!r}, could not be found' + raise ValueError(msg.format(item)) + + return cls(provider_id=provider_id, items=selected, indices=indices)
+
+ +
+
+
+
+
+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/4.5/_modules/apptools/selection/selection_service.html b/4.5/_modules/apptools/selection/selection_service.html new file mode 100644 index 000000000..275b7b320 --- /dev/null +++ b/4.5/_modules/apptools/selection/selection_service.html @@ -0,0 +1,313 @@ + + + + + + + apptools.selection.selection_service — Apptools Documentation + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +

Source code for apptools.selection.selection_service

+from traits.api import Dict, HasTraits
+
+from apptools.selection.errors import (
+    ProviderNotRegisteredError, IDConflictError, ListenerNotConnectedError
+)
+
+
+
[docs]class SelectionService(HasTraits): + """ The selection service connects selection providers and listeners. + + The selection service is a register of selection providers, i.e., objects + that publish their current selection. + + Selections can be requested actively, by explicitly requesting the current + selection in a provider (:meth:`get_selection(id)`), or passively by + connecting selection listeners. + """ + + #### 'SelectionService' protocol ########################################## + +
[docs] def add_selection_provider(self, provider): + """ Add a selection provider. + + The provider is identified by its ID. If a provider with the same + ID has been already registered, an :class:`~.IDConflictError` + is raised. + + Arguments: + provider -- ISelectionProvider + The selection provider added to the internal registry. + + """ + provider_id = provider.provider_id + if self.has_selection_provider(provider_id): + raise IDConflictError(provider_id=provider_id) + + self._providers[provider_id] = provider + + if provider_id in self._listeners: + self._connect_all_listeners(provider_id)
+ +
[docs] def has_selection_provider(self, provider_id): + """ Has a provider with the given ID been registered? """ + return provider_id in self._providers
+ +
[docs] def remove_selection_provider(self, provider): + """ Remove a selection provider. + + If the provider has not been registered, a + :class:`~.ProviderNotRegisteredError` is raised. + + Arguments: + provider -- ISelectionProvider + The selection provider added to the internal registry. + """ + provider_id = provider.provider_id + self._raise_if_not_registered(provider_id) + + if provider_id in self._listeners: + self._disconnect_all_listeners(provider_id) + + del self._providers[provider_id]
+ +
[docs] def get_selection(self, provider_id): + """ Return the current selection of the provider with the given ID. + + If a provider with that ID has not been registered, a + :class:`~.ProviderNotRegisteredError` is raised. + + Arguments: + provider_id -- str + The selection provider ID. + + Returns: + selection -- ISelection + The current selection of the provider. + """ + self._raise_if_not_registered(provider_id) + provider = self._providers[provider_id] + return provider.get_selection()
+ +
[docs] def set_selection(self, provider_id, items, ignore_missing=False): + """ Set the current selection in a provider to the given items. + + If a provider with the given ID has not been registered, a + :class:`~.ProviderNotRegisteredError` is raised. + + If ``ignore_missing`` is ``True``, items that are not available in the + selection provider are silently ignored. If it is ``False`` (default), + a :class:`ValueError` should be raised. + + Arguments: + provider_id -- str + The selection provider ID. + + items -- list + List of items to be selected. + + ignore_missing -- bool + If ``False`` (default), the provider raises an exception if any + of the items in ``items`` is not available to be selected. + Otherwise, missing elements are silently ignored, and the rest + is selected. + """ + self._raise_if_not_registered(provider_id) + provider = self._providers[provider_id] + return provider.set_selection(items, ignore_missing=ignore_missing)
+ +
[docs] def connect_selection_listener(self, provider_id, func): + """ Connect a listener to selection events from a specific provider. + + The signature if the listener callback is ``func(i_selection)``. + The listener is called: + + 1) When a provider with the given ID is registered, with its initial + selection as argument, or + + 2) whenever the provider fires a selection event. + + It is perfectly valid to connect a listener before a provider with the + given ID is registered. The listener will remain connected even if + the provider is repeatedly connected and disconnected. + + Arguments: + provider_id -- str + The selection provider ID. + func -- callable(i_selection) + A callable object that is notified when the selection changes. + """ + self._listeners.setdefault(provider_id, []) + self._listeners[provider_id].append(func) + + if self.has_selection_provider(provider_id): + self._toggle_listener(provider_id, func, remove=False)
+ +
[docs] def disconnect_selection_listener(self, provider_id, func): + """ Disconnect a listener from a specific provider. + + Arguments: + provider_id -- str + The selection provider ID. + func -- callable(provider_id, i_selection) + A callable object that is notified when the selection changes. + """ + + if self.has_selection_provider(provider_id): + self._toggle_listener(provider_id, func, remove=True) + + try: + self._listeners[provider_id].remove(func) + except (ValueError, KeyError): + raise ListenerNotConnectedError(provider_id=provider_id, + listener=func)
+ + #### Private protocol ##################################################### + + _listeners = Dict() + + _providers = Dict() + + def _toggle_listener(self, provider_id, func, remove): + provider = self._providers[provider_id] + provider.on_trait_change(func, 'selection', remove=remove) + + def _connect_all_listeners(self, provider_id): + """ Connect all listeners connected to a provider. + + As soon as they are connected, they receive the initial selection. + """ + provider = self._providers[provider_id] + selection = provider.get_selection() + for func in self._listeners[provider_id]: + self._toggle_listener(provider_id, func, remove=False) + # FIXME: make this robust to notifications that raise exceptions. + # Can we send the error to the traits exception hook? + func(selection) + + def _disconnect_all_listeners(self, provider_id): + for func in self._listeners[provider_id]: + self._toggle_listener(provider_id, func, remove=True) + + def _raise_if_not_registered(self, provider_id): + if not self.has_selection_provider(provider_id): + raise ProviderNotRegisteredError(provider_id=provider_id)
+
+ +
+
+
+
+
+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/_modules/apptools/sweet_pickle.html b/4.5/_modules/apptools/sweet_pickle.html similarity index 100% rename from _modules/apptools/sweet_pickle.html rename to 4.5/_modules/apptools/sweet_pickle.html diff --git a/_modules/apptools/sweet_pickle/global_registry.html b/4.5/_modules/apptools/sweet_pickle/global_registry.html similarity index 100% rename from _modules/apptools/sweet_pickle/global_registry.html rename to 4.5/_modules/apptools/sweet_pickle/global_registry.html diff --git a/_modules/apptools/sweet_pickle/placeholder.html b/4.5/_modules/apptools/sweet_pickle/placeholder.html similarity index 100% rename from _modules/apptools/sweet_pickle/placeholder.html rename to 4.5/_modules/apptools/sweet_pickle/placeholder.html diff --git a/_modules/apptools/sweet_pickle/updater.html b/4.5/_modules/apptools/sweet_pickle/updater.html similarity index 100% rename from _modules/apptools/sweet_pickle/updater.html rename to 4.5/_modules/apptools/sweet_pickle/updater.html diff --git a/_modules/apptools/sweet_pickle/versioned_unpickler.html b/4.5/_modules/apptools/sweet_pickle/versioned_unpickler.html similarity index 100% rename from _modules/apptools/sweet_pickle/versioned_unpickler.html rename to 4.5/_modules/apptools/sweet_pickle/versioned_unpickler.html diff --git a/_modules/apptools/template/impl/any_context_data_name_item.html b/4.5/_modules/apptools/template/impl/any_context_data_name_item.html similarity index 100% rename from _modules/apptools/template/impl/any_context_data_name_item.html rename to 4.5/_modules/apptools/template/impl/any_context_data_name_item.html diff --git a/_modules/apptools/template/impl/any_data_name_item.html b/4.5/_modules/apptools/template/impl/any_data_name_item.html similarity index 100% rename from _modules/apptools/template/impl/any_data_name_item.html rename to 4.5/_modules/apptools/template/impl/any_data_name_item.html diff --git a/_modules/apptools/template/impl/context_data_name_item.html b/4.5/_modules/apptools/template/impl/context_data_name_item.html similarity index 100% rename from _modules/apptools/template/impl/context_data_name_item.html rename to 4.5/_modules/apptools/template/impl/context_data_name_item.html diff --git a/_modules/apptools/template/impl/helper.html b/4.5/_modules/apptools/template/impl/helper.html similarity index 100% rename from _modules/apptools/template/impl/helper.html rename to 4.5/_modules/apptools/template/impl/helper.html diff --git a/_modules/apptools/template/impl/template_data_context.html b/4.5/_modules/apptools/template/impl/template_data_context.html similarity index 100% rename from _modules/apptools/template/impl/template_data_context.html rename to 4.5/_modules/apptools/template/impl/template_data_context.html diff --git a/_modules/apptools/template/impl/template_data_source.html b/4.5/_modules/apptools/template/impl/template_data_source.html similarity index 100% rename from _modules/apptools/template/impl/template_data_source.html rename to 4.5/_modules/apptools/template/impl/template_data_source.html diff --git a/_modules/apptools/template/impl/value_data_name_item.html b/4.5/_modules/apptools/template/impl/value_data_name_item.html similarity index 100% rename from _modules/apptools/template/impl/value_data_name_item.html rename to 4.5/_modules/apptools/template/impl/value_data_name_item.html diff --git a/_modules/apptools/template/impl/value_nd_data_name_item.html b/4.5/_modules/apptools/template/impl/value_nd_data_name_item.html similarity index 100% rename from _modules/apptools/template/impl/value_nd_data_name_item.html rename to 4.5/_modules/apptools/template/impl/value_nd_data_name_item.html diff --git a/_modules/apptools/template/imutable_template.html b/4.5/_modules/apptools/template/imutable_template.html similarity index 100% rename from _modules/apptools/template/imutable_template.html rename to 4.5/_modules/apptools/template/imutable_template.html diff --git a/_modules/apptools/template/itemplate.html b/4.5/_modules/apptools/template/itemplate.html similarity index 100% rename from _modules/apptools/template/itemplate.html rename to 4.5/_modules/apptools/template/itemplate.html diff --git a/_modules/apptools/template/itemplate_choice.html b/4.5/_modules/apptools/template/itemplate_choice.html similarity index 100% rename from _modules/apptools/template/itemplate_choice.html rename to 4.5/_modules/apptools/template/itemplate_choice.html diff --git a/_modules/apptools/template/itemplate_data_context.html b/4.5/_modules/apptools/template/itemplate_data_context.html similarity index 100% rename from _modules/apptools/template/itemplate_data_context.html rename to 4.5/_modules/apptools/template/itemplate_data_context.html diff --git a/_modules/apptools/template/itemplate_data_name_item.html b/4.5/_modules/apptools/template/itemplate_data_name_item.html similarity index 100% rename from _modules/apptools/template/itemplate_data_name_item.html rename to 4.5/_modules/apptools/template/itemplate_data_name_item.html diff --git a/_modules/apptools/template/itemplate_data_source.html b/4.5/_modules/apptools/template/itemplate_data_source.html similarity index 100% rename from _modules/apptools/template/itemplate_data_source.html rename to 4.5/_modules/apptools/template/itemplate_data_source.html diff --git a/_modules/apptools/template/mutable_template.html b/4.5/_modules/apptools/template/mutable_template.html similarity index 100% rename from _modules/apptools/template/mutable_template.html rename to 4.5/_modules/apptools/template/mutable_template.html diff --git a/_modules/apptools/template/template_choice.html b/4.5/_modules/apptools/template/template_choice.html similarity index 100% rename from _modules/apptools/template/template_choice.html rename to 4.5/_modules/apptools/template/template_choice.html diff --git a/_modules/apptools/template/template_data_name.html b/4.5/_modules/apptools/template/template_data_name.html similarity index 100% rename from _modules/apptools/template/template_data_name.html rename to 4.5/_modules/apptools/template/template_data_name.html diff --git a/_modules/apptools/template/template_impl.html b/4.5/_modules/apptools/template/template_impl.html similarity index 100% rename from _modules/apptools/template/template_impl.html rename to 4.5/_modules/apptools/template/template_impl.html diff --git a/_modules/apptools/template/template_traits.html b/4.5/_modules/apptools/template/template_traits.html similarity index 100% rename from _modules/apptools/template/template_traits.html rename to 4.5/_modules/apptools/template/template_traits.html diff --git a/_modules/apptools/type_manager/abstract_adapter_factory.html b/4.5/_modules/apptools/type_manager/abstract_adapter_factory.html similarity index 100% rename from _modules/apptools/type_manager/abstract_adapter_factory.html rename to 4.5/_modules/apptools/type_manager/abstract_adapter_factory.html diff --git a/_modules/apptools/type_manager/abstract_factory.html b/4.5/_modules/apptools/type_manager/abstract_factory.html similarity index 100% rename from _modules/apptools/type_manager/abstract_factory.html rename to 4.5/_modules/apptools/type_manager/abstract_factory.html diff --git a/_modules/apptools/type_manager/abstract_type_system.html b/4.5/_modules/apptools/type_manager/abstract_type_system.html similarity index 100% rename from _modules/apptools/type_manager/abstract_type_system.html rename to 4.5/_modules/apptools/type_manager/abstract_type_system.html diff --git a/_modules/apptools/type_manager/adaptable.html b/4.5/_modules/apptools/type_manager/adaptable.html similarity index 100% rename from _modules/apptools/type_manager/adaptable.html rename to 4.5/_modules/apptools/type_manager/adaptable.html diff --git a/_modules/apptools/type_manager/adapter.html b/4.5/_modules/apptools/type_manager/adapter.html similarity index 100% rename from _modules/apptools/type_manager/adapter.html rename to 4.5/_modules/apptools/type_manager/adapter.html diff --git a/_modules/apptools/type_manager/adapter_factory.html b/4.5/_modules/apptools/type_manager/adapter_factory.html similarity index 100% rename from _modules/apptools/type_manager/adapter_factory.html rename to 4.5/_modules/apptools/type_manager/adapter_factory.html diff --git a/_modules/apptools/type_manager/adapter_manager.html b/4.5/_modules/apptools/type_manager/adapter_manager.html similarity index 100% rename from _modules/apptools/type_manager/adapter_manager.html rename to 4.5/_modules/apptools/type_manager/adapter_manager.html diff --git a/_modules/apptools/type_manager/factory.html b/4.5/_modules/apptools/type_manager/factory.html similarity index 100% rename from _modules/apptools/type_manager/factory.html rename to 4.5/_modules/apptools/type_manager/factory.html diff --git a/_modules/apptools/type_manager/hook.html b/4.5/_modules/apptools/type_manager/hook.html similarity index 100% rename from _modules/apptools/type_manager/hook.html rename to 4.5/_modules/apptools/type_manager/hook.html diff --git a/_modules/apptools/type_manager/python_type_system.html b/4.5/_modules/apptools/type_manager/python_type_system.html similarity index 100% rename from _modules/apptools/type_manager/python_type_system.html rename to 4.5/_modules/apptools/type_manager/python_type_system.html diff --git a/_modules/apptools/type_manager/type_manager.html b/4.5/_modules/apptools/type_manager/type_manager.html similarity index 100% rename from _modules/apptools/type_manager/type_manager.html rename to 4.5/_modules/apptools/type_manager/type_manager.html diff --git a/_modules/apptools/type_manager/util.html b/4.5/_modules/apptools/type_manager/util.html similarity index 100% rename from _modules/apptools/type_manager/util.html rename to 4.5/_modules/apptools/type_manager/util.html diff --git a/4.5/_modules/apptools/type_registry/type_registry.html b/4.5/_modules/apptools/type_registry/type_registry.html new file mode 100644 index 000000000..7abb81d2e --- /dev/null +++ b/4.5/_modules/apptools/type_registry/type_registry.html @@ -0,0 +1,397 @@ + + + + + + + apptools.type_registry.type_registry — Apptools Documentation + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +

Source code for apptools.type_registry.type_registry

+import six
+
+
+
[docs]def get_mro(obj_class): + """ Get a reasonable method resolution order of a class and its + superclasses for both old-style and new-style classes. + """ + if not hasattr(obj_class, '__mro__'): + # Old-style class. Mix in object to make a fake new-style class. + try: + obj_class = type(obj_class.__name__, (obj_class, object), {}) + except TypeError: + # Old-style extension type that does not descend from object. + mro = [obj_class] + else: + mro = obj_class.__mro__[1:-1] + else: + mro = obj_class.__mro__ + return mro
+ + +def _mod_name_key(typ): + """ Return a '__module__:__name__' key for a type. + """ + module = getattr(typ, '__module__', None) + name = getattr(typ, '__name__', None) + key = '{0}:{1}'.format(module, name) + return key + + +
[docs]class TypeRegistry(object): + """ Register objects for types. + + Each type maintains a stack of registered objects that can be pushed and + popped. + """ + + def __init__(self): + # Map types to lists of registered objects. The last is the most + # current and will be the one that is returned on lookup. + self.type_map = {} + + # Map '__module__:__name__' strings to lists of registered objects. + self.name_map = {} + + # Map abstract base classes to lists of registered objects. + self.abc_map = {} + + #### TypeRegistry public interface ######################################## + +
[docs] def push(self, typ, obj): + """ Push an object onto the stack for the given type. + + Parameters + ---------- + typ : type or '__module__:__name__' string for a type + obj : object + The object to register. + """ + if isinstance(typ, six.string_types): + # Check the cached types. + for cls in self.type_map: + if _mod_name_key(cls) == typ: + self.type_map[cls].append(obj) + break + else: + if typ not in self.name_map: + self.name_map[typ] = [] + self.name_map[typ].append(obj) + else: + if typ not in self.type_map: + self.type_map[typ] = [] + self.type_map[typ].append(obj)
+ +
[docs] def push_abc(self, typ, obj): + """ Push an object onto the stack for the given ABC. + + Parameters + ---------- + typ : abc.ABCMeta + obj : object + """ + if typ not in self.abc_map: + self.abc_map[typ] = [] + self.abc_map[typ].append(obj)
+ +
[docs] def pop(self, typ): + """ Pop a registered object for the given type. + + Parameters + ---------- + typ : type or '__module__:__name__' string for a type + + Returns + ------- + obj : object + The last registered object for the type. + + Raises + ------ + KeyError if the type is not registered. + """ + if isinstance(typ, six.string_types): + if typ not in self.name_map: + # We may have it cached in the type map. We will have to + # iterate over all of the types to check. + for cls in self.type_map: + if _mod_name_key(cls) == typ: + old = self._pop_value(self.type_map, cls) + break + else: + raise KeyError("No registered value for {0!r}".format(typ)) + else: + old = self._pop_value(self.name_map, typ) + else: + if typ in self.type_map: + old = self._pop_value(self.type_map, typ) + elif typ in self.abc_map: + old = self._pop_value(self.abc_map, typ) + else: + old = self._pop_value(self.name_map, _mod_name_key(typ)) + return old
+ +
[docs] def lookup(self, instance): + """ Look up the registered object for the given instance. + + Parameters + ---------- + instance : object + An instance of a possibly registered type. + + Returns + ------- + obj : object + The registered object for the type of the instance, one of the + type's superclasses, or else one of the ABCs the type implements. + + Raises + ------ + KeyError if the instance's type has not been registered. + """ + return self.lookup_by_type(type(instance))
+ +
[docs] def lookup_by_type(self, typ): + """ Look up the registered object for a type. + + Parameters + ---------- + typ : type + + Returns + ------- + obj : object + The registered object for the type, one of its superclasses, or + else one of the ABCs it implements. + + Raises + ------ + KeyError if the type has not been registered. + """ + return self.lookup_all_by_type(typ)[-1]
+ +
[docs] def lookup_all(self, instance): + """ Look up all the registered objects for the given instance. + + Parameters + ---------- + instance : object + An instance of a possibly registered type. + + Returns + ------- + objs : list of objects + The list of registered objects for the instance. If the given + instance is not registered, its superclasses are searched. If none + of the superclasses are registered, search the possible ABCs. + + Raises + ------ + KeyError if the instance's type has not been registered. + """ + return self.lookup_all_by_type(type(instance))
+ +
[docs] def lookup_all_by_type(self, typ): + """ Look up all the registered objects for a type. + + Parameters + ---------- + typ : type + + Returns + ------- + objs : list of objects + The list of registered objects for the type. If the given type is + not registered, its superclasses are searched. If none of the + superclasses are registered, search the possible ABCs. + + Raises + ------ + KeyError if the type has not been registered. + """ + # If a concrete superclass is registered use it. + for cls in get_mro(typ): + if cls in self.type_map or self._in_name_map(cls): + objs = self.type_map[cls] + if objs: + return objs + + # None of the concrete superclasses. Check the ABCs. + for abstract, objs in self.abc_map.items(): + if issubclass(typ, abstract) and objs: + return objs + + # If we have reached here, the lookup failed. + raise KeyError("No registered value for {0!r}".format(typ))
+ + #### Private implementation ############################################### + + def _pop_value(self, mapping, key): + """ Pop a value from a keyed stack in a mapping, taking care to remove + the key if the stack is depleted. + """ + objs = mapping[key] + old = objs.pop() + if not objs: + del mapping[key] + return old + + def _in_name_map(self, typ): + """ Check if the given type is specified in the name map. + + Parameters + ---------- + typ : type + + Returns + ------- + is_in_name_map : bool + If True, the registered value will be moved over to the type map + for future lookups. + """ + key = _mod_name_key(typ) + if key in self.name_map: + self.type_map[typ] = self.name_map.pop(key) + return True + else: + return False
+ + +
[docs]class LazyRegistry(TypeRegistry): + """ A type registry that will lazily import the registered objects. + + Register '__module__:__name__' strings for the lazily imported objects. + These will only be imported when the matching type is looked up. The module + name must be a fully-qualified absolute name with all of the parent + packages specified. + """ + +
[docs] def lookup_by_type(self, typ): + """ Look up the registered object for a type. + """ + mod_name = TypeRegistry.lookup_by_type(self, typ) + return self._import_object(mod_name)
+ + def _import_object(self, mod_object): + module, name = mod_object.split(':') + mod = __import__(module, {}, {}, [name], 0) + return getattr(mod, name)
+
+ +
+
+
+
+
+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/4.5/_modules/apptools/undo/abstract_command.html b/4.5/_modules/apptools/undo/abstract_command.html new file mode 100644 index 000000000..d408525a2 --- /dev/null +++ b/4.5/_modules/apptools/undo/abstract_command.html @@ -0,0 +1,205 @@ + + + + + + + apptools.undo.abstract_command — Apptools Documentation + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +

Source code for apptools.undo.abstract_command

+#------------------------------------------------------------------------------
+# Copyright (c) 2007, Riverbank Computing Limited
+# All rights reserved.
+#
+# This software is provided without warranty under the terms of the BSD
+# license included in enthought/LICENSE.txt and may be redistributed only
+# under the conditions described in the aforementioned license.  The license
+# is also available online at http://www.enthought.com/licenses/BSD.txt
+# Thanks for using Enthought open source!
+#
+# Author: Riverbank Computing Limited
+# Description: <Enthought undo package component>
+#------------------------------------------------------------------------------
+
+# Enthought library imports.
+from traits.api import Any, HasTraits, Unicode, provides
+
+# Local imports.
+from .i_command import ICommand
+
+
+
[docs]@provides(ICommand) +class AbstractCommand(HasTraits): + """ The AbstractCommand class is an abstract base class that implements the + ICommand interface. + """ + + #### 'ICommand' interface ################################################# + + # This is the data on which the command operates. + data = Any + + # This is the name of the command as it will appear in any GUI element. It + # may include '&' which will be automatically removed whenever it is + # inappropriate. + name = Unicode + + ########################################################################### + # 'ICommand' interface. + ########################################################################### + +
[docs] def do(self): + """ This is called by the command stack to do the command and to return + any value. The command must save any state necessary for the 'redo()' + and 'undo()' methods to work. The class's __init__() must also ensure + that deep copies of any arguments are made if appropriate. It is + guaranteed that this will only ever be called once and that it will be + called before any call to 'redo()' or 'undo()'. + """ + + raise NotImplementedError
+ +
[docs] def merge(self, other): + """ This is called by the command stack to try and merge another + command with this one. True is returned if the commands were merged. + 'other' is the command that is about to be executed. If the commands + are merged then 'other' will discarded and not placed on the command + stack. A subsequent undo or redo of this modified command must have + the same effect as the two original commands. + """ + + # By default merges never happen. + return False
+ +
[docs] def redo(self): + """ This is called by the command stack to redo the command. Any + returned value will replace the value that the command stack references + from the original call to 'do()' or previous call to 'redo()'. + """ + + raise NotImplementedError
+ +
[docs] def undo(self): + """ This is called by the command stack to undo the command. """ + + raise NotImplementedError
+
+ +
+
+
+
+
+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/4.5/_modules/apptools/undo/action/abstract_command_stack_action.html b/4.5/_modules/apptools/undo/action/abstract_command_stack_action.html new file mode 100644 index 000000000..3ea7b67d9 --- /dev/null +++ b/4.5/_modules/apptools/undo/action/abstract_command_stack_action.html @@ -0,0 +1,209 @@ + + + + + + + apptools.undo.action.abstract_command_stack_action — Apptools Documentation + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +

Source code for apptools.undo.action.abstract_command_stack_action

+#------------------------------------------------------------------------------
+# Copyright (c) 2008, Riverbank Computing Limited
+# All rights reserved.
+#
+# This software is provided without warranty under the terms of the BSD
+# license included in enthought/LICENSE.txt and may be redistributed only
+# under the conditions described in the aforementioned license.  The license
+# is also available online at http://www.enthought.com/licenses/BSD.txt
+# Thanks for using Enthought open source!
+#
+# Author: Riverbank Computing Limited
+# Description: <Enthought undo package component>
+#------------------------------------------------------------------------------
+
+# Enthought library imports.
+from pyface.action.api import Action
+from traits.api import Instance
+
+# Local library imports
+from ..i_undo_manager import IUndoManager
+
+
+
[docs]class AbstractCommandStackAction(Action): + """ The abstract base class for all actions that operate on a command + stack. + """ + + #### 'AbstractCommandStackAction' interface ############################### + + # The undo manager. + undo_manager = Instance(IUndoManager) + + ########################################################################### + # 'object' interface. + ########################################################################### + + def __init__(self, **traits): + """ Initialise the instance. """ + + super(AbstractCommandStackAction, self).__init__(**traits) + + self.undo_manager.on_trait_event(self._on_stack_updated, 'stack_updated') + + # Update the action to initialise it. + self._update_action() + + ########################################################################### + # 'Action' interface. + ########################################################################### + +
[docs] def destroy(self): + """ Called when the action is no longer required. + + By default this method does nothing, but this would be a great place to + unhook trait listeners etc. + + """ + + self.undo_manager.on_trait_event(self._on_stack_updated, + 'stack_updated', remove=True)
+ + ########################################################################### + # Protected interface. + ########################################################################### + + def _update_action(self): + """ Update the state of the action. """ + + raise NotImplementedError + + ########################################################################### + # Private interface. + ########################################################################### + + def _on_stack_updated(self, stack): + """ Handle changes to the state of a command stack. """ + + # Ignore unless it is the active stack. + if stack is self.undo_manager.active_stack: + self._update_action()
+
+ +
+
+
+
+
+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/4.5/_modules/apptools/undo/action/command_action.html b/4.5/_modules/apptools/undo/action/command_action.html new file mode 100644 index 000000000..270a9fc5b --- /dev/null +++ b/4.5/_modules/apptools/undo/action/command_action.html @@ -0,0 +1,187 @@ + + + + + + + apptools.undo.action.command_action — Apptools Documentation + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +

Source code for apptools.undo.action.command_action

+#------------------------------------------------------------------------------
+# Copyright (c) 2007, Riverbank Computing Limited
+# All rights reserved.
+#
+# This software is provided without warranty under the terms of the BSD
+# license included in enthought/LICENSE.txt and may be redistributed only
+# under the conditions described in the aforementioned license.  The license
+# is also available online at http://www.enthought.com/licenses/BSD.txt
+# Thanks for using Enthought open source!
+#
+# Author: Riverbank Computing Limited
+# Description: <Enthought undo package component>
+#------------------------------------------------------------------------------
+
+# Enthought library imports.
+from pyface.action.api import Action
+from traits.api import Any, Callable, Instance
+from ..i_command_stack import ICommandStack
+
+
+
[docs]class CommandAction(Action): + """ The CommandAction class is an Action class that wraps undo/redo + commands. It is only useful for commands that do not take any arguments or + return any result. + """ + + #### 'CommandAction' interface ############################################ + + # The command to create when the action is performed. + command = Callable + + # The command stack onto which the command will be pushed when the action + # is performed. + command_stack = Instance(ICommandStack) + + # This is the data on which the command operates. + data = Any + + ########################################################################### + # 'Action' interface. + ########################################################################### + +
[docs] def perform(self, event): + """ This is reimplemented to push a new command instance onto the + command stack. + """ + + self.command_stack.push(self.command(data=self.data))
+ + def _name_default(self): + """ This gets the action name from the command. """ + + if self.command: + name = self.command().name + else: + name = "" + + return name
+
+ +
+
+
+
+
+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/4.5/_modules/apptools/undo/action/redo_action.html b/4.5/_modules/apptools/undo/action/redo_action.html new file mode 100644 index 000000000..670291670 --- /dev/null +++ b/4.5/_modules/apptools/undo/action/redo_action.html @@ -0,0 +1,178 @@ + + + + + + + apptools.undo.action.redo_action — Apptools Documentation + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +

Source code for apptools.undo.action.redo_action

+#------------------------------------------------------------------------------
+# Copyright (c) 2007, Riverbank Computing Limited
+# All rights reserved.
+#
+# This software is provided without warranty under the terms of the BSD
+# license included in enthought/LICENSE.txt and may be redistributed only
+# under the conditions described in the aforementioned license.  The license
+# is also available online at http://www.enthought.com/licenses/BSD.txt
+# Thanks for using Enthought open source!
+#
+# Author: Riverbank Computing Limited
+# Description: <Enthought undo package component>
+#------------------------------------------------------------------------------
+
+# Local imports.
+from .abstract_command_stack_action import AbstractCommandStackAction
+
+
+
[docs]class RedoAction(AbstractCommandStackAction): + """ An action that redos the last command undone of the active command + stack. + """ + + ########################################################################### + # 'Action' interface. + ########################################################################### + +
[docs] def perform(self, event): + """ Perform the action. """ + + self.undo_manager.redo()
+ + ########################################################################### + # 'AbstractUndoAction' interface. + ########################################################################### + + def _update_action(self): + """ Update the state of the action. """ + + name = self.undo_manager.redo_name + + if name: + name = "&Redo " + name + self.enabled = True + else: + name = "&Redo" + self.enabled = False + + self.name = name
+
+ +
+
+
+
+
+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/4.5/_modules/apptools/undo/action/undo_action.html b/4.5/_modules/apptools/undo/action/undo_action.html new file mode 100644 index 000000000..04038b756 --- /dev/null +++ b/4.5/_modules/apptools/undo/action/undo_action.html @@ -0,0 +1,176 @@ + + + + + + + apptools.undo.action.undo_action — Apptools Documentation + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +

Source code for apptools.undo.action.undo_action

+#------------------------------------------------------------------------------
+# Copyright (c) 2007, Riverbank Computing Limited
+# All rights reserved.
+#
+# This software is provided without warranty under the terms of the BSD
+# license included in enthought/LICENSE.txt and may be redistributed only
+# under the conditions described in the aforementioned license.  The license
+# is also available online at http://www.enthought.com/licenses/BSD.txt
+# Thanks for using Enthought open source!
+#
+# Author: Riverbank Computing Limited
+# Description: <Enthought undo package component>
+#------------------------------------------------------------------------------
+
+# Local imports.
+from .abstract_command_stack_action import AbstractCommandStackAction
+
+
+
[docs]class UndoAction(AbstractCommandStackAction): + """ An action that undos the last command of the active command stack. """ + + ########################################################################### + # 'Action' interface. + ########################################################################### + +
[docs] def perform(self, event): + """ Perform the action. """ + + self.undo_manager.undo()
+ + ########################################################################### + # 'AbstractUndoAction' interface. + ########################################################################### + + def _update_action(self): + """ Update the state of the action. """ + + name = self.undo_manager.undo_name + + if name: + name = "&Undo " + name + self.enabled = True + else: + name = "&Undo" + self.enabled = False + + self.name = name
+
+ +
+
+
+
+
+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/4.5/_modules/apptools/undo/command_stack.html b/4.5/_modules/apptools/undo/command_stack.html new file mode 100644 index 000000000..f4b5aa7c2 --- /dev/null +++ b/4.5/_modules/apptools/undo/command_stack.html @@ -0,0 +1,437 @@ + + + + + + + apptools.undo.command_stack — Apptools Documentation + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +

Source code for apptools.undo.command_stack

+#------------------------------------------------------------------------------
+# Copyright (c) 2008, Riverbank Computing Limited
+# All rights reserved.
+#
+# This software is provided without warranty under the terms of the BSD
+# license included in enthought/LICENSE.txt and may be redistributed only
+# under the conditions described in the aforementioned license.  The license
+# is also available online at http://www.enthought.com/licenses/BSD.txt
+# Thanks for using Enthought open source!
+#
+# Author: Riverbank Computing Limited
+# Description: <Enthought undo package component>
+#------------------------------------------------------------------------------
+
+# Enthought library imports.
+from traits.api import Bool, HasTraits, Instance, Int, List, Property, \
+    Unicode, provides
+
+# Local imports.
+from .abstract_command import AbstractCommand
+from .i_command import ICommand
+from .i_command_stack import ICommandStack
+from .i_undo_manager import IUndoManager
+
+
+class _StackEntry(HasTraits):
+    """ The _StackEntry class is a single entry on a command stack. """
+
+    #### '_StackEntry' interface ##############################################
+
+    # Set if the entry corresponds to a clean point on the stack.
+    clean = Bool(False)
+
+    # The command instance.
+    command = Instance(ICommand)
+
+    # The sequence number of the entry.
+    sequence_nr = Int
+
+
+class _MacroCommand(AbstractCommand):
+    """ The _MacroCommand class is an internal command that handles macros. """
+
+    #### '_MacroCommand' interface ############################################
+
+    # The commands that make up this macro.
+    macro_commands = List(Instance(ICommand))
+
+    ###########################################################################
+    # 'ICommand' interface.
+    ###########################################################################
+
+    def do(self):
+        """ Invoke the command. """
+
+        # This is a dummy.
+        return None
+
+    def merge(self, other):
+        """ Try and merge a command. """
+
+        if len(self.macro_commands) == 0:
+            merged = False
+        else:
+            merged = self.macro_commands[-1].merge(other)
+
+        return merged
+
+    def redo(self):
+        """ Redo the sub-commands. """
+
+        for cmd in self.macro_commands:
+            cmd.redo()
+
+        # Macros cannot return values.
+        return None
+
+    def undo(self):
+        """ Undo the sub-commands. """
+
+        for cmd in self.macro_commands:
+            cmd.undo()
+
+
+
[docs]@provides(ICommandStack) +class CommandStack(HasTraits): + """ The CommandStack class is the default implementation of the + ICommandStack interface. + """ + + #### 'ICommandStack' interface ############################################ + + # This is the clean state of the stack. Its value changes as commands are + # undone and redone. It can also be explicity set to mark the current + # stack position as being clean (when the data is saved to disk for + # example). + clean = Property(Bool) + + # This is the name of the command that can be redone. It will be empty if + # there is no command that can be redone. It is maintained by the undo + # stack. + redo_name = Property(Unicode) + + # This is the undo manager that manages this stack. + undo_manager = Instance(IUndoManager) + + # This is the name of the command that can be undone. It will be empty if + # there is no command that can be undone. It is maintained by the undo + # stack. + undo_name = Property(Unicode) + + #### Private interface #################################################### + + # The current index into the stack (ie. the last command that was done). + _index = Int(-1) + + # The current macro stack. + _macro_stack = List(Instance(_MacroCommand)) + + # The stack itself. + _stack = List(Instance(_StackEntry)) + + ########################################################################### + # 'ICommandStack' interface. + ########################################################################### + +
[docs] def begin_macro(self, name): + """ This begins a macro by creating an empty command with the given + 'name'. All subsequent calls to 'push()' create commands that will be + children of the empty command until the next call to 'end_macro()'. + Macros may be nested. The stack is disabled (ie. nothing can be undone + or redone) while a macro is being created (ie. while there is an + outstanding 'end_macro()' call). + """ + + command = _MacroCommand(name=name) + self.push(command) + self._macro_stack.append(command)
+ +
[docs] def clear(self): + """ This clears the stack, without undoing or redoing any commands, and + leaves the stack in a clean state. It is typically used when all + changes to the data have been abandoned. + """ + + self._index = -1 + self._stack = [] + self._macro_stack = [] + + self.undo_manager.stack_updated = self
+ +
[docs] def end_macro(self): + """ This ends a macro. """ + + try: + self._macro_stack.pop() + except IndexError: + pass
+ +
[docs] def push(self, command): + """ This executes a command and saves it on the command stack so that + it can be subsequently undone and redone. 'command' is an instance + that implements the ICommand interface. Its 'do()' method is called + to execute the command. If any value is returned by 'do()' then it is + returned by 'push()'. + """ + + # See if the command can be merged with the previous one. + if len(self._macro_stack) == 0: + if self._index >= 0: + merged = self._stack[self._index].command.merge(command) + else: + merged = False + else: + merged = self._macro_stack[-1].merge(command) + + # Increment the global sequence number. + if not merged: + self.undo_manager.sequence_nr += 1 + + # Execute the command. + result = command.do() + + # Do nothing more if the command was merged. + if merged: + return result + + # Only update the command stack if there is no current macro. + if len(self._macro_stack) == 0: + # Remove everything on the stack after the last command that was + # done. + self._index += 1 + del self._stack[self._index:] + + # Create a new stack entry and add it to the stack. + entry = _StackEntry(command=command, + sequence_nr=self.undo_manager.sequence_nr) + + self._stack.append(entry) + self.undo_manager.stack_updated = self + else: + # Add the command to the parent macro command. + self._macro_stack[-1].macro_commands.append(command) + + return result
+ +
[docs] def redo(self, sequence_nr=0): + """ If 'sequence_nr' is 0 then the last command that was undone is + redone and any result returned. Otherwise commands are redone up to + and including the given 'sequence_nr' and any result of the last of + these is returned. + """ + + # Make sure a redo is valid in the current context. + if self.redo_name == "": + return None + + if sequence_nr == 0: + result = self._redo_one() + else: + result = None + + while self._index + 1 < len(self._stack): + if self._stack[self._index + 1].sequence_nr > sequence_nr: + break + + result = self._redo_one() + + self.undo_manager.stack_updated = self + + return result
+ +
[docs] def undo(self, sequence_nr=0): + """ If 'sequence_nr' is 0 then the last command is undone. Otherwise + commands are undone up to and including the given 'sequence_nr'. + """ + + # Make sure an undo is valid in the current context. + if self.undo_name == "": + return + + if sequence_nr == 0: + self._undo_one() + else: + while self._index >= 0: + if self._stack[self._index].sequence_nr <= sequence_nr: + break + + self._undo_one() + + self.undo_manager.stack_updated = self
+ + ########################################################################### + # Private interface. + ########################################################################### + + def _redo_one(self): + """ Redo the command at the current index and return the result. """ + + self._index += 1 + entry = self._stack[self._index] + + return entry.command.redo() + + def _undo_one(self): + """ Undo the command at the current index. """ + + entry = self._stack[self._index] + self._index -= 1 + + entry.command.undo() + + def _get_clean(self): + """ Get the clean state of the stack. """ + + if self._index >= 0: + clean = self._stack[self._index].clean + else: + clean = True + + return clean + + def _set_clean(self, clean): + """ Set the clean state of the stack. """ + + if self._index >= 0: + self._stack[self._index].clean = clean + + def _get_redo_name(self): + """ Get the name of the redo command, if any. """ + + redo_name = "" + + if len(self._macro_stack) == 0 and self._index + 1 < len(self._stack): + redo_name = self._stack[self._index + 1].command.name.replace('&', '') + + return redo_name + + def _get_undo_name(self): + """ Get the name of the undo command, if any. """ + + undo_name = "" + + if len(self._macro_stack) == 0 and self._index >= 0: + command = self._stack[self._index].command + undo_name = command.name.replace('&', '') + + return undo_name
+
+ +
+
+
+
+
+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/4.5/_modules/apptools/undo/i_command.html b/4.5/_modules/apptools/undo/i_command.html new file mode 100644 index 000000000..8c0d2596d --- /dev/null +++ b/4.5/_modules/apptools/undo/i_command.html @@ -0,0 +1,194 @@ + + + + + + + apptools.undo.i_command — Apptools Documentation + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +

Source code for apptools.undo.i_command

+#------------------------------------------------------------------------------
+# Copyright (c) 2007, Riverbank Computing Limited
+# All rights reserved.
+#
+# This software is provided without warranty under the terms of the BSD
+# license included in enthought/LICENSE.txt and may be redistributed only
+# under the conditions described in the aforementioned license.  The license
+# is also available online at http://www.enthought.com/licenses/BSD.txt
+# Thanks for using Enthought open source!
+#
+# Author: Riverbank Computing Limited
+# Description: <Enthought undo package component>
+#------------------------------------------------------------------------------
+
+
+# Enthought library imports.
+from traits.api import Any, Interface, Unicode
+
+
+
[docs]class ICommand(Interface): + """ The command interface. The state of the data can be changed by passing + an instance that implements this interface to the 'push()' method of a + command stack along with any arguments. + """ + + #### 'ICommand' interface ################################################# + + # This is the data on which the command operates. + data = Any + + # This is the name of the command as it will appear in any GUI element. It + # may include '&' which will be automatically removed whenever it is + # inappropriate. + name = Unicode + + ########################################################################### + # 'ICommand' interface. + ########################################################################### + +
[docs] def do(self): + """ This is called by the command stack to do the command and to return + any value. The command must save any state necessary for the 'redo()' + and 'undo()' methods to work. The class's __init__() must also ensure + that deep copies of any arguments are made if appropriate. It is + guaranteed that this will only ever be called once and that it will be + called before any call to 'redo()' or 'undo()'. + """
+ +
[docs] def merge(self, other): + """ This is called by the command stack to try and merge another + command with this one. True is returned if the commands were merged. + 'other' is the command that is about to be executed. If the commands + are merged then 'other' will discarded and not placed on the command + stack. A subsequent undo or redo of this modified command must have + the same effect as the two original commands. + """
+ +
[docs] def redo(self): + """ This is called by the command stack to redo the command. Any + returned value will replace the value that the command stack references + from the original call to 'do()' or previous call to 'redo()'. + """
+ +
[docs] def undo(self): + """ This is called by the command stack to undo the command. """
+
+ +
+
+
+
+
+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/4.5/_modules/apptools/undo/i_command_stack.html b/4.5/_modules/apptools/undo/i_command_stack.html new file mode 100644 index 000000000..392086ebf --- /dev/null +++ b/4.5/_modules/apptools/undo/i_command_stack.html @@ -0,0 +1,220 @@ + + + + + + + apptools.undo.i_command_stack — Apptools Documentation + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +

Source code for apptools.undo.i_command_stack

+#------------------------------------------------------------------------------
+# Copyright (c) 2007, Riverbank Computing Limited
+# All rights reserved.
+#
+# This software is provided without warranty under the terms of the BSD
+# license included in enthought/LICENSE.txt and may be redistributed only
+# under the conditions described in the aforementioned license.  The license
+# is also available online at http://www.enthought.com/licenses/BSD.txt
+# Thanks for using Enthought open source!
+#
+# Author: Riverbank Computing Limited
+# Description: <Enthought undo package component>
+#------------------------------------------------------------------------------
+
+# Enthought library imports.
+from traits.api import Bool, Instance, Interface, Unicode
+
+# Local imports.
+from .i_undo_manager import IUndoManager
+
+
+
[docs]class ICommandStack(Interface): + """ The command stack interface. A command stack is responsible for + managing the changes to a data model and recording those changes so that + they can be undone or redone. + """ + + #### 'ICommandStack' interface ############################################ + + # This is the clean state of the stack. Its value changes as commands are + # undone and redone. It can also be explicity set to mark the current + # stack position as being clean (when the data is saved to disk for + # example). + clean = Bool + + # This is the name of the command that can be redone. It will be empty if + # there is no command that can be redone. It is maintained by the undo + # stack. + redo_name = Unicode + + # This is the undo manager that manages this stack. + undo_manager = Instance(IUndoManager) + + # This is the name of the command that can be undone. It will be empty if + # there is no command that can be undone. It is maintained by the undo + # stack. + undo_name = Unicode + + ########################################################################### + # 'ICommandStack' interface. + ########################################################################### + +
[docs] def begin_macro(self, name): + """ This begins a macro by creating an empty command with the given + 'name'. The commands passed to all subsequent calls to 'push()' will + be contained in the macro until the next call to 'end_macro()'. Macros + may be nested. The stack is disabled (ie. nothing can be undone or + redone) while a macro is being created (ie. while there is an + outstanding 'end_macro()' call). + """
+ +
[docs] def clear(self): + """ This clears the stack, without undoing or redoing any commands, and + leaves the stack in a clean state. It is typically used when all + changes to the data have been abandoned. + """
+ +
[docs] def end_macro(self): + """ This ends a macro. """
+ +
[docs] def push(self, command): + """ This executes a command and saves it on the command stack so that + it can be subsequently undone and redone. 'command' is an instance + that implements the ICommand interface. Its 'do()' method is called + to execute the command. If any value is returned by 'do()' then it is + returned by 'push()'. The command stack will keep a reference to the + result so that it can recognise it as an argument to a subsequent + command (which allows a script to properly save a result needed later). + """
+ +
[docs] def redo(self, sequence_nr=0): + """ If 'sequence_nr' is 0 then the last command that was undone is + redone and any result returned. Otherwise commands are redone up to + and including the given 'sequence_nr' and any result of the last of + these is returned. + """
+ +
[docs] def undo(self, sequence_nr=0): + """ If 'sequence_nr' is 0 then the last command is undone. Otherwise + commands are undone up to and including the given 'sequence_nr'. + """
+
+ +
+
+
+
+
+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/4.5/_modules/apptools/undo/i_undo_manager.html b/4.5/_modules/apptools/undo/i_undo_manager.html new file mode 100644 index 000000000..9ae732e95 --- /dev/null +++ b/4.5/_modules/apptools/undo/i_undo_manager.html @@ -0,0 +1,192 @@ + + + + + + + apptools.undo.i_undo_manager — Apptools Documentation + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +

Source code for apptools.undo.i_undo_manager

+#------------------------------------------------------------------------------
+# Copyright (c) 2008, Riverbank Computing Limited
+# All rights reserved.
+#
+# This software is provided without warranty under the terms of the BSD
+# license included in enthought/LICENSE.txt and may be redistributed only
+# under the conditions described in the aforementioned license.  The license
+# is also available online at http://www.enthought.com/licenses/BSD.txt
+# Thanks for using Enthought open source!
+#
+# Author: Riverbank Computing Limited
+# Description: <Enthought undo package component>
+#------------------------------------------------------------------------------
+
+# Enthought library imports.
+from traits.api import Bool, Event, Instance, Int, Interface, Unicode
+
+
+
[docs]class IUndoManager(Interface): + """ The undo manager interface. An undo manager is responsible for one or + more command stacks. Typically an application would have a single undo + manager. + """ + + #### 'IUndoManager' interface ############################################# + + # This is the currently active command stack and may be None. Typically it + # is set when some sort of editor becomes active. + active_stack = Instance('apptools.undo.api.ICommandStack') + + # This reflects the clean state of the currently active command stack. It + # is intended to support a "document modified" indicator in the GUI. It is + # maintained by the undo manager. + active_stack_clean = Bool + + # This is the name of the command that can be redone. It will be empty if + # there is no command that can be redone. It is maintained by the undo + # manager. + redo_name = Unicode + + # This is the sequence number of the next command to be performed. It is + # incremented immediately before a command is invoked (by its 'do()' + # method). + sequence_nr = Int + + # This event is fired when the index of a command stack changes. Note that + # it may not be the active stack. + stack_updated = Event(Instance('apptools.undo.api.ICommandStack')) + + # This is the name of the command that can be undone. It will be empty if + # there is no command that can be undone. It is maintained by the undo + # manager. + undo_name = Unicode + + ########################################################################### + # 'IUndoManager' interface. + ########################################################################### + +
[docs] def redo(self): + """ Redo the last undone command of the active command stack. """
+ +
[docs] def undo(self): + """ Undo the last command of the active command stack. """
+
+ +
+
+
+
+
+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/4.5/_modules/apptools/undo/undo_manager.html b/4.5/_modules/apptools/undo/undo_manager.html new file mode 100644 index 000000000..1d20792fa --- /dev/null +++ b/4.5/_modules/apptools/undo/undo_manager.html @@ -0,0 +1,243 @@ + + + + + + + apptools.undo.undo_manager — Apptools Documentation + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +

Source code for apptools.undo.undo_manager

+#------------------------------------------------------------------------------
+# Copyright (c) 2008, Riverbank Computing Limited
+# All rights reserved.
+#
+# This software is provided without warranty under the terms of the BSD
+# license included in enthought/LICENSE.txt and may be redistributed only
+# under the conditions described in the aforementioned license.  The license
+# is also available online at http://www.enthought.com/licenses/BSD.txt
+# Thanks for using Enthought open source!
+#
+# Author: Riverbank Computing Limited
+# Description: <Enthought undo package component>
+#------------------------------------------------------------------------------
+
+# Enthought library imports.
+from traits.api import Bool, Event, HasTraits, Instance, Int, Property, \
+    Unicode, provides
+
+# Local imports.
+from .i_undo_manager import IUndoManager
+
+
+
[docs]@provides(IUndoManager) +class UndoManager(HasTraits): + """ The UndoManager class is the default implementation of the + IUndoManager interface. + """ + + #### 'IUndoManager' interface ############################################# + + # This is the currently active command stack and may be None. Typically it + # is set when some sort of editor becomes active. + active_stack = Instance('apptools.undo.api.ICommandStack') + + # This reflects the clean state of the currently active command stack. It + # is intended to support a "document modified" indicator in the GUI. It is + # maintained by the undo manager. + active_stack_clean = Property(Bool) + + # This is the name of the command that can be redone. It will be empty if + # there is no command that can be redone. It is maintained by the undo + # manager. + redo_name = Property(Unicode) + + # This is the sequence number of the next command to be performed. It is + # incremented immediately before a command is invoked (by its 'do()' + # method). + sequence_nr = Int + + # This event is fired when the index of a command stack changes. The value + # of the event is the stack that has changed. Note that it may not be the + # active stack. + stack_updated = Event + + # This is the name of the command that can be undone. It will be empty if + # there is no command that can be undone. It is maintained by the undo + # manager. + undo_name = Property(Unicode) + + ########################################################################### + # 'IUndoManager' interface. + ########################################################################### + +
[docs] def redo(self): + """ Redo the last undone command of the active command stack. """ + + if self.active_stack is not None: + self.active_stack.redo()
+ +
[docs] def undo(self): + """ Undo the last command of the active command stack. """ + + if self.active_stack is not None: + self.active_stack.undo()
+ + ########################################################################### + # Private interface. + ########################################################################### + + def _active_stack_changed(self, new): + """ Handle a different stack becoming active. """ + + # Pretend that the stack contents have changed. + self.stack_updated = new + + def _get_active_stack_clean(self): + """ Get the current clean state. """ + + if self.active_stack is None: + active_stack_clean = True + else: + active_stack_clean = self.active_stack.clean + + return active_stack_clean + + def _get_redo_name(self): + """ Get the current redo name. """ + + if self.active_stack is None: + redo_name = "" + else: + redo_name = self.active_stack.redo_name + + return redo_name + + def _get_undo_name(self): + """ Get the current undo name. """ + + if self.active_stack is None: + undo_name = "" + else: + undo_name = self.active_stack.undo_name + + return undo_name
+
+ +
+
+
+
+
+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/4.5/_modules/index.html b/4.5/_modules/index.html new file mode 100644 index 000000000..478b3a6bc --- /dev/null +++ b/4.5/_modules/index.html @@ -0,0 +1,323 @@ + + + + + + + Overview: module code — Apptools Documentation + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +

All modules for which code is available

+ + +
+
+
+
+
+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/4.5/_modules/traits/trait_types.html b/4.5/_modules/traits/trait_types.html new file mode 100644 index 000000000..784122855 --- /dev/null +++ b/4.5/_modules/traits/trait_types.html @@ -0,0 +1,4029 @@ + + + + + + + traits.trait_types — Apptools Documentation + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +

Source code for traits.trait_types

+# ------------------------------------------------------------------------------
+#
+#  Copyright (c) 2007, Enthought, Inc.
+#  All rights reserved.
+#
+#  This software is provided without warranty under the terms of the BSD
+#  license included in enthought/LICENSE.txt and may be redistributed only
+#  under the conditions described in the aforementioned license.  The license
+#  is also available online at http://www.enthought.com/licenses/BSD.txt
+#
+#  Thanks for using Enthought open source!
+#
+#  Author: David C. Morrill
+#  Date:   03/22/2007
+#
+# ------------------------------------------------------------------------------
+
+""" Core Trait definitions.
+"""
+
+# -------------------------------------------------------------------------------
+#  Imports:
+# -------------------------------------------------------------------------------
+
+from __future__ import absolute_import
+
+import datetime
+import operator
+import re
+import sys
+from os.path import isfile, isdir
+from types import FunctionType, MethodType, ModuleType
+import uuid
+
+import six
+
+from . import trait_handlers
+
+from .trait_base import (
+    strx,
+    get_module_name,
+    class_of,
+    SequenceTypes,
+    TypeTypes,
+    ClassTypes,
+    Undefined,
+    TraitsCache,
+)
+
+from .trait_handlers import (
+    TraitType,
+    TraitInstance,
+    TraitListObject,
+    TraitSetObject,
+    TraitSetEvent,
+    TraitDictObject,
+    TraitDictEvent,
+    ThisClass,
+    items_event,
+    RangeTypes,
+    HandleWeakRef,
+    OBJECT_DEFAULT_VALUE,
+    TRAIT_LIST_OBJECT_DEFAULT_VALUE,
+    TRAIT_DICT_OBJECT_DEFAULT_VALUE,
+    CALLABLE_AND_ARGS_DEFAULT_VALUE,
+    CALLABLE_DEFAULT_VALUE,
+    TRAIT_SET_OBJECT_DEFAULT_VALUE,
+)
+
+from .traits import (
+    Trait,
+    trait_from,
+    _TraitMaker,
+    _InstanceArgs,
+    code_editor,
+    html_editor,
+    password_editor,
+    shell_editor,
+    date_editor,
+    time_editor,
+    list_editor,
+)
+
+from .trait_errors import TraitError
+
+from . import _py2to3
+from ._py2to3 import LONG_TYPE
+
+# -------------------------------------------------------------------------------
+#  Constants:
+# -------------------------------------------------------------------------------
+
+MutableTypes = (list, dict)
+SetTypes = SequenceTypes + (set,)
+
+# -------------------------------------------------------------------------------
+#  Numeric type fast validator definitions:
+# -------------------------------------------------------------------------------
+
+# A few words about the next block of code:
+
+# Validator #11 is a generic validator for possibly coercible types
+# (see validate_trait_coerce_type in ctraits.c).
+#
+# The tuples below are of the form
+# (11, type1, [type2, type3, ...], [None, ctype1, [ctype2, ...]])
+#
+# 'type1' corresponds to the main type for the trait
+# 'None' acts as the separator between 'types' and 'ctypes' (coercible types)
+#
+# The validation passes if:
+# 1) The trait value type is (a subtype of) one of 'type1', 'type2',  ...
+#    in which case the value is returned as-is
+# or
+# 2) The trait value type is (a subtype of) one of 'ctype1', 'ctype2', ...
+#    in which case the value is returned coerced to trait type using
+#    'return type1(value')
+
+try:
+    # The numpy enhanced definitions:
+    from numpy import integer, floating, complexfloating, bool_
+
+    int_fast_validate = (11, int, integer)
+    long_fast_validate = (11, LONG_TYPE, None, int, integer)
+    float_fast_validate = (11, float, floating, None, int, LONG_TYPE, integer)
+    complex_fast_validate = (
+        11,
+        complex,
+        complexfloating,
+        None,
+        float,
+        floating,
+        int,
+        integer,
+    )
+    bool_fast_validate = (11, bool, None, bool_)
+    # Tuple or single type suitable for an isinstance check.
+    _BOOL_TYPES = (bool, bool_)
+except ImportError:
+    # The standard python definitions (without numpy):
+    int_fast_validate = (11, int)
+    long_fast_validate = (11, LONG_TYPE, None, int)
+    float_fast_validate = (11, float, None, int, LONG_TYPE)
+    complex_fast_validate = (11, complex, None, float, int)
+    bool_fast_validate = (11, bool)
+    # Tuple or single type suitable for an isinstance check.
+    _BOOL_TYPES = bool
+
+# -------------------------------------------------------------------------------
+#  Returns a default text editor:
+# -------------------------------------------------------------------------------
+
+
+def default_text_editor(trait, type=None):
+    auto_set = trait.auto_set
+    if auto_set is None:
+        auto_set = True
+
+    enter_set = trait.enter_set or False
+
+    from traitsui.api import TextEditor
+
+    if type is None:
+        return TextEditor(auto_set=auto_set, enter_set=enter_set)
+
+    return TextEditor(auto_set=auto_set, enter_set=enter_set, evaluate=type)
+
+
+# Generic validators
+
+
+def _validate_float(value):
+    """
+    Convert an arbitrary Python object to a float, or raise TypeError.
+    """
+    if type(value) == float:  # fast path for common case
+        return value
+    try:
+        nb_float = type(value).__float__
+    except AttributeError:
+        raise TypeError(
+            "Object of type {!r} not convertible to float".format(type(value))
+        )
+    return nb_float(value)
+
+
+# -------------------------------------------------------------------------------
+#  'Any' trait:
+# -------------------------------------------------------------------------------
+
+
+class Any(TraitType):
+    """ Defines a trait whose value can be anything.
+    """
+
+    #: The default value for the trait:
+    default_value = None
+
+    #: A description of the type of value this trait accepts:
+    info_text = "any value"
+
+
+# -------------------------------------------------------------------------------
+#  'Generic' trait:
+# -------------------------------------------------------------------------------
+
+
+class Generic(Any):
+    """ Defines a trait whose value can be anything and whose definition can
+        be redefined via assignment using a TraitValue object.
+    """
+
+    #: The standard metadata for the trait:
+    metadata = {"trait_value": True}
+
+
+# -------------------------------------------------------------------------------
+#  'BaseInt' and 'Int' traits:
+# -------------------------------------------------------------------------------
+
+
+class BaseInt(TraitType):
+    """ Defines a trait whose type must be an int or long.
+    """
+
+    #: The function to use for evaluating strings to this type:
+    evaluate = int
+
+    #: The default value for the trait:
+    default_value = 0
+
+    #: A description of the type of value this trait accepts:
+    info_text = "an integer (int or long)"
+
+    def validate(self, object, name, value):
+        """ Validates that a specified value is valid for this trait.
+        """
+        if type(value) is int:
+            return value
+        elif type(value) is LONG_TYPE:
+            return int(value)
+
+        try:
+            int_value = operator.index(value)
+        except TypeError:
+            pass
+        else:
+            return int(int_value)
+
+        self.error(object, name, value)
+
+    def create_editor(self):
+        """ Returns the default traits UI editor for this type of trait.
+        """
+        return default_text_editor(self, int)
+
+
+class Int(BaseInt):
+    """ Defines a trait whose type must be an int or long using a C-level fast
+        validator.
+    """
+
+    #: The C-level fast validator to use:
+    fast_validate = (20,)
+
+
+# -------------------------------------------------------------------------------
+#  'BaseLong' and 'Long' traits:
+# -------------------------------------------------------------------------------
+
+
+class BaseLong(TraitType):
+    """ Defines a trait whose value must be a Python long.
+    """
+
+    #: The function to use for evaluating strings to this type:
+    evaluate = LONG_TYPE
+
+    #: The default value for the trait:
+    default_value = LONG_TYPE(0)
+
+    #: A description of the type of value this trait accepts:
+    info_text = "a long"
+
+    def validate(self, object, name, value):
+        """ Validates that a specified value is valid for this trait.
+
+            Note: The 'fast validator' version performs this check in C.
+        """
+        if isinstance(value, int):
+            return LONG_TYPE(value)
+
+        if isinstance(value, six.integer_types):
+            return value
+
+        self.error(object, name, value)
+
+    def create_editor(self):
+        """ Returns the default traits UI editor for this type of trait.
+        """
+        return default_text_editor(self, LONG_TYPE)
+
+
+class Long(BaseLong):
+    """ Defines a trait whose value must be a Python long using a C-level fast
+        validator.
+    """
+
+    #: The C-level fast validator to use:
+    fast_validate = long_fast_validate
+
+
+# -------------------------------------------------------------------------------
+#  'BaseFloat' and 'Float' traits:
+# -------------------------------------------------------------------------------
+
+
+class BaseFloat(TraitType):
+    """ Defines a trait whose value must be a Python float.
+    """
+
+    #: The function to use for evaluating strings to this type:
+    evaluate = float
+
+    #: The default value for the trait:
+    default_value = 0.0
+
+    #: A description of the type of value this trait accepts:
+    info_text = "a float"
+
+    def validate(self, object, name, value):
+        """ Validates that a specified value is valid for this trait.
+
+            Note: The 'fast validator' version performs this check in C.
+        """
+        try:
+            return _validate_float(value)
+        except TypeError:
+            self.error(object, name, value)
+
+    def create_editor(self):
+        """ Returns the default traits UI editor for this type of trait.
+        """
+        return default_text_editor(self, float)
+
+
+class Float(BaseFloat):
+    """ Defines a trait whose value must be a Python float using a C-level fast
+        validator.
+    """
+
+    #: The C-level fast validator to use:
+    fast_validate = (21,)
+
+
+# -------------------------------------------------------------------------------
+#  'BaseComplex' and 'Complex' traits:
+# -------------------------------------------------------------------------------
+
+
+class BaseComplex(TraitType):
+    """ Defines a trait whose value must be a Python complex.
+    """
+
+    #: The function to use for evaluating strings to this type:
+    evaluate = complex
+
+    #: The default value for the trait:
+    default_value = 0.0 + 0.0j
+
+    #: A description of the type of value this trait accepts:
+    info_text = "a complex number"
+
+    def validate(self, object, name, value):
+        """ Validates that a specified value is valid for this trait.
+
+            Note: The 'fast validator' version performs this check in C.
+        """
+        if isinstance(value, complex):
+            return value
+
+        if isinstance(value, (float, int)):
+            return complex(value)
+
+        self.error(object, name, value)
+
+    def create_editor(self):
+        """ Returns the default traits UI editor for this type of trait.
+        """
+        return default_text_editor(self, complex)
+
+
+class Complex(BaseComplex):
+    """ Defines a trait whose value must be a Python complex using a C-level
+        fast validator.
+    """
+
+    #: The C-level fast validator to use:
+    fast_validate = complex_fast_validate
+
+
+# -------------------------------------------------------------------------------
+#  'BaseStr' and 'Str' traits:
+# -------------------------------------------------------------------------------
+
+
+class BaseStr(TraitType):
+    """ Defines a trait whose value must be a Python string.
+    """
+
+    #: The default value for the trait:
+    default_value = ""
+
+    #: A description of the type of value this trait accepts:
+    info_text = "a string"
+
+    def validate(self, object, name, value):
+        """ Validates that a specified value is valid for this trait.
+
+            Note: The 'fast validator' version performs this check in C.
+        """
+        if isinstance(value, six.string_types):
+            return value
+
+        self.error(object, name, value)
+
+    def create_editor(self):
+        """ Returns the default traits UI editor for this type of trait.
+        """
+        from .traits import multi_line_text_editor
+
+        auto_set = self.auto_set
+        if auto_set is None:
+            auto_set = True
+        enter_set = self.enter_set or False
+
+        return multi_line_text_editor(auto_set, enter_set)
+
+
+class Str(BaseStr):
+    """ Defines a trait whose value must be a Python string using a C-level
+        fast validator.
+    """
+
+    #: The C-level fast validator to use:
+    fast_validate = (11,) + six.string_types
+
+
+class Title(Str):
+    """ Defines a string type which by default uses the traits ui TitleEditor
+        when used in a View.
+    """
+
+    def create_editor(self):
+        """ Returns the default traits UI editor to use for a trait.
+        """
+        from traitsui.api import TitleEditor
+
+        if hasattr(self, "allow_selection"):
+            return TitleEditor(allow_selection=self.allow_selection)
+        else:
+            return TitleEditor()
+
+
+# -------------------------------------------------------------------------------
+#  'BaseUnicode' and 'Unicode' traits:
+# -------------------------------------------------------------------------------
+
+
+class BaseUnicode(TraitType):
+    """ Defines a trait whose value must be a Python unicode string.
+    """
+
+    #: The default value for the trait:
+    default_value = u""
+
+    #: A description of the type of value this trait accepts:
+    info_text = "a unicode string"
+
+    def validate(self, object, name, value):
+        """ Validates that a specified value is valid for this trait.
+
+            Note: The 'fast validator' version performs this check in C.
+        """
+        if isinstance(value, six.text_type):
+            return value
+
+        if isinstance(value, str):
+            return six.text_type(value)
+
+        self.error(object, name, value)
+
+    def create_editor(self):
+        """ Returns the default traits UI editor for this type of trait.
+        """
+        from .traits import multi_line_text_editor
+
+        auto_set = self.auto_set
+        if auto_set is None:
+            auto_set = True
+        enter_set = self.enter_set or False
+
+        return multi_line_text_editor(auto_set, enter_set)
+
+
+class Unicode(BaseUnicode):
+    """ Defines a trait whose value must be a Python unicode string using a
+        C-level fast validator.
+    """
+
+    #: The C-level fast validator to use:
+    fast_validate = (11, six.text_type, None, str)
+
+
+# -------------------------------------------------------------------------------
+#  'BaseBytes' and 'Bytes' traits:
+# -------------------------------------------------------------------------------
+
+
+class BaseBytes(TraitType):
+    """ Defines a trait whose value must be a Python bytes string.
+    """
+
+    #: The default value for the trait:
+    default_value = b""
+
+    #: A description of the type of value this trait accepts:
+    info_text = "a bytes string"
+
+    #: An encoding to use with TraitsUI editors
+    encoding = None
+
+    def validate(self, object, name, value):
+        """ Validates that a specified value is valid for this trait.
+
+            Note: The 'fast validator' version performs this check in C.
+        """
+        if isinstance(value, bytes):
+            return value
+
+        self.error(object, name, value)
+
+    def create_editor(self):
+        """ Returns the default traits UI editor for this type of trait.
+        """
+        from .traits import bytes_editor
+
+        auto_set = self.auto_set
+        if auto_set is None:
+            auto_set = True
+        enter_set = self.enter_set or False
+
+        return bytes_editor(auto_set, enter_set, self.encoding)
+
+
+class Bytes(BaseBytes):
+    """ Defines a trait whose value must be a Python bytes string using a
+        C-level fast validator.
+    """
+
+    #: The C-level fast validator to use:
+    fast_validate = (11, bytes)
+
+
+# -------------------------------------------------------------------------------
+#  'BaseBool' and 'Bool' traits:
+# -------------------------------------------------------------------------------
+
+
+class BaseBool(TraitType):
+    """ Defines a trait whose value must be a Python boolean.
+    """
+
+    #: The function to use for evaluating strings to this type:
+    evaluate = bool
+
+    #: The default value for the trait:
+    default_value = False
+
+    #: A description of the type of value this trait accepts:
+    info_text = "a boolean"
+
+    def validate(self, object, name, value):
+        """ Validates that a specified value is valid for this trait.
+
+            Note: The 'fast validator' version performs this check in C.
+        """
+        if isinstance(value, _BOOL_TYPES):
+            return bool(value)
+
+        self.error(object, name, value)
+
+    def create_editor(self):
+        """ Returns the default traits UI editor for this type of trait.
+        """
+        from traitsui.api import BooleanEditor
+
+        return BooleanEditor()
+
+
+class Bool(BaseBool):
+    """ Defines a trait whose value must be a Python boolean using a C-level
+        fast validator.
+    """
+
+    #: The C-level fast validator to use:
+    fast_validate = bool_fast_validate
+
+
+# -------------------------------------------------------------------------------
+#  'BaseCInt' and 'CInt' traits:
+# -------------------------------------------------------------------------------
+
+
+class BaseCInt(BaseInt):
+    """ Defines a trait whose value must be a Python int and which supports
+        coercions of non-int values to int.
+    """
+
+    #: The function to use for evaluating strings to this type:
+    evaluate = int
+
+    def validate(self, object, name, value):
+        """ Validates that a specified value is valid for this trait.
+
+            Note: The 'fast validator' version performs this check in C.
+        """
+        try:
+            return int(value)
+        except:
+            self.error(object, name, value)
+
+
+class CInt(BaseCInt):
+    """ Defines a trait whose value must be a Python int and which supports
+        coercions of non-int values to int using a C-level fast validator.
+    """
+
+    #: The C-level fast validator to use:
+    fast_validate = (12, int)
+
+
+# -------------------------------------------------------------------------------
+#  'BaseCLong' and 'CLong' traits:
+# -------------------------------------------------------------------------------
+
+
+class BaseCLong(BaseLong):
+    """ Defines a trait whose value must be a Python long and which supports
+        coercions of non-long values to long.
+    """
+
+    #: The function to use for evaluating strings to this type:
+    evaluate = LONG_TYPE
+
+    def validate(self, object, name, value):
+        """ Validates that a specified value is valid for this trait.
+
+            Note: The 'fast validator' version performs this check in C.
+        """
+        try:
+            return LONG_TYPE(value)
+        except:
+            self.error(object, name, value)
+
+
+class CLong(BaseCLong):
+    """ Defines a trait whose value must be a Python long and which supports
+        coercions of non-long values to long using a C-level fast validator.
+    """
+
+    #: The C-level fast validator to use:
+    fast_validate = (12, LONG_TYPE)
+
+
+# -------------------------------------------------------------------------------
+#  'BaseCFloat' and 'CFloat' traits:
+# -------------------------------------------------------------------------------
+
+
+class BaseCFloat(BaseFloat):
+    """ Defines a trait whose value must be a Python float and which supports
+        coercions of non-float values to float.
+    """
+
+    #: The function to use for evaluating strings to this type:
+    evaluate = float
+
+    def validate(self, object, name, value):
+        """ Validates that a specified value is valid for this trait.
+
+            Note: The 'fast validator' version performs this check in C.
+        """
+        try:
+            return float(value)
+        except:
+            self.error(object, name, value)
+
+
+class CFloat(BaseCFloat):
+    """ Defines a trait whose value must be a Python float and which supports
+        coercions of non-float values to float using a C-level fast validator.
+    """
+
+    #: The C-level fast validator to use:
+    fast_validate = (12, float)
+
+
+# -------------------------------------------------------------------------------
+#  'BaseCComplex' and 'CComplex' traits:
+# -------------------------------------------------------------------------------
+
+
+class BaseCComplex(BaseComplex):
+    """ Defines a trait whose value must be a Python complex and which supports
+        coercions of non-complex values to complex.
+    """
+
+    #: The function to use for evaluating strings to this type:
+    evaluate = complex
+
+    def validate(self, object, name, value):
+        """ Validates that a specified value is valid for this trait.
+
+            Note: The 'fast validator' version performs this check in C.
+        """
+        try:
+            return complex(value)
+        except:
+            self.error(object, name, value)
+
+
+class CComplex(BaseCComplex):
+    """ Defines a trait whose value must be a Python complex and which supports
+        coercions of non-complex values to complex using a C-level fast
+        validator.
+    """
+
+    #: The C-level fast validator to use:
+    fast_validate = (12, complex)
+
+
+# -------------------------------------------------------------------------------
+#  'BaseCStr' and 'CStr' traits:
+# -------------------------------------------------------------------------------
+
+
+class BaseCStr(BaseStr):
+    """ Defines a trait whose value must be a Python string and which supports
+        coercions of non-string values to string.
+    """
+
+    def validate(self, object, name, value):
+        """ Validates that a specified value is valid for this trait.
+
+            Note: The 'fast validator' version performs this check in C.
+        """
+        try:
+            return str(value)
+        except:
+            try:
+                return six.text_type(value)
+            except:
+                self.error(object, name, value)
+
+
+class CStr(BaseCStr):
+    """ Defines a trait whose value must be a Python string and which supports
+        coercions of non-string values to string using a C-level fast
+        validator.
+    """
+
+    #: The C-level fast validator to use:
+    fast_validate = (7, ((12, str), (12, six.text_type)))
+
+
+# -------------------------------------------------------------------------------
+#  'BaseCUnicode' and 'CUnicode' traits:
+# -------------------------------------------------------------------------------
+
+
+class BaseCUnicode(BaseUnicode):
+    """ Defines a trait whose value must be a Python unicode string and which
+        supports coercions of non-unicode values to unicode.
+    """
+
+    def validate(self, object, name, value):
+        """ Validates that a specified value is valid for this trait.
+
+            Note: The 'fast validator' version performs this check in C.
+        """
+        try:
+            return six.text_type(value)
+        except:
+            self.error(object, name, value)
+
+
+class CUnicode(BaseCUnicode):
+    """ Defines a trait whose value must be a Python unicode string and which
+        supports coercions of non-unicode values to unicode using a C-level
+        fast validator.
+    """
+
+    #: The C-level fast validator to use:
+    fast_validate = (12, six.text_type)
+
+
+# -------------------------------------------------------------------------------
+#  'BaseCBytes' and 'CBytes' traits:
+# -------------------------------------------------------------------------------
+
+
+class BaseCBytes(BaseBytes):
+    """ Defines a trait whose value must be a Python bytes object and which
+        supports coercions of non-bytes values to bytes.
+    """
+
+    def validate(self, object, name, value):
+        """ Validates that a specified value is valid for this trait.
+
+            Note: The 'fast validator' version performs this check in C.
+        """
+        try:
+            return bytes(value)
+        except:
+            self.error(object, name, value)
+
+
+class CBytes(BaseCBytes):
+    """ Defines a trait whose value must be a Python bytes and which
+        supports coercions of non-bytes values bytes using a C-level
+        fast validator.
+    """
+
+    #: The C-level fast validator to use:
+    fast_validate = (12, bytes)
+
+
+# -------------------------------------------------------------------------------
+#  'BaseCBool' and 'CBool' traits:
+# -------------------------------------------------------------------------------
+
+
+class BaseCBool(BaseBool):
+    """ Defines a trait whose value must be a Python boolean and which supports
+        coercions of non-boolean values to boolean.
+    """
+
+    #: The function to use for evaluating strings to this type:
+    evaluate = bool
+
+    def validate(self, object, name, value):
+        """ Validates that a specified value is valid for this trait.
+
+            Note: The 'fast validator' version performs this check in C.
+        """
+        try:
+            return bool(value)
+        except:
+            self.error(object, name, value)
+
+
+class CBool(BaseCBool):
+    """ Defines a trait whose value must be a Python boolean and which supports
+        coercions of non-boolean values to boolean using a C-level fast
+        validator.
+    """
+
+    #: The C-level fast validator to use:
+    fast_validate = (12, bool)
+
+
+# -------------------------------------------------------------------------------
+#  'String' trait:
+# -------------------------------------------------------------------------------
+
+
+class String(TraitType):
+    """ Defines a trait whose value must be a Python string whose length is
+        optionally in a specified range, and which optionally matches a
+        specified regular expression.
+    """
+
+    def __init__(
+        self, value="", minlen=0, maxlen=six.MAXSIZE, regex="", **metadata
+    ):
+        """ Creates a String trait.
+
+        Parameters
+        ----------
+        value : str
+            The default value for the string.
+        minlen : integer
+            The minimum length allowed for the string.
+        maxlen : integer
+            The maximum length allowed for the string.
+        regex : str
+            A Python regular expression that the string must match.
+
+        """
+        super(String, self).__init__(value, **metadata)
+        self.minlen = max(0, minlen)
+        self.maxlen = max(self.minlen, maxlen)
+        self.regex = regex
+        self._init()
+
+    def _init(self):
+        """ Completes initialization of the trait at construction or unpickling
+            time.
+        """
+        self._validate = "validate_all"
+        if self.regex != "":
+            self.match = re.compile(self.regex).match
+            if (self.minlen == 0) and (self.maxlen == six.MAXSIZE):
+                self._validate = "validate_regex"
+        elif (self.minlen == 0) and (self.maxlen == six.MAXSIZE):
+            self._validate = "validate_str"
+        else:
+            self._validate = "validate_len"
+
+    def validate(self, object, name, value):
+        """ Validates that the value is a valid string.
+        """
+        return getattr(self, self._validate)(object, name, value)
+
+    def validate_all(self, object, name, value):
+        """ Validates that the value is a valid string in the specified length
+            range which matches the specified regular expression.
+        """
+        try:
+            value = strx(value)
+            if (self.minlen <= len(value) <= self.maxlen) and (
+                self.match(value) is not None
+            ):
+                return value
+        except:
+            pass
+
+        self.error(object, name, value)
+
+    def validate_str(self, object, name, value):
+        """ Validates that the value is a valid string.
+        """
+        try:
+            return strx(value)
+        except:
+            pass
+
+        self.error(object, name, value)
+
+    def validate_len(self, object, name, value):
+        """ Validates that the value is a valid string in the specified length
+            range.
+        """
+        try:
+            value = strx(value)
+            if self.minlen <= len(value) <= self.maxlen:
+                return value
+        except:
+            pass
+
+        self.error(object, name, value)
+
+    def validate_regex(self, object, name, value):
+        """ Validates that the value is a valid string which matches the
+            specified regular expression.
+        """
+        try:
+            value = strx(value)
+            if self.match(value) is not None:
+                return value
+        except:
+            pass
+
+        self.error(object, name, value)
+
+    def info(self):
+        """ Returns a description of the trait.
+        """
+        msg = ""
+        if (self.minlen != 0) and (self.maxlen != six.MAXSIZE):
+            msg = " between %d and %d characters long" % (
+                self.minlen,
+                self.maxlen,
+            )
+        elif self.maxlen != six.MAXSIZE:
+            msg = " <= %d characters long" % self.maxlen
+        elif self.minlen != 0:
+            msg = " >= %d characters long" % self.minlen
+        if self.regex != "":
+            if msg != "":
+                msg += " and"
+            msg += " matching the pattern '%s'" % self.regex
+        return "a string" + msg
+
+    def create_editor(self):
+        """ Returns the default traits UI editor for this type of trait.
+        """
+        return default_text_editor(self)
+
+    def __getstate__(self):
+        """ Returns the current state of the trait.
+        """
+        result = self.__dict__.copy()
+        for name in ["validate", "match"]:
+            if name in result:
+                del result[name]
+
+        return result
+
+    def __setstate__(self, state):
+        """ Sets the current state of the trait.
+        """
+        self.__dict__.update(state)
+        self._init()
+
+
+# -------------------------------------------------------------------------------
+#  'Regex' trait:
+# -------------------------------------------------------------------------------
+
+
+class Regex(String):
+    """ Defines a trait whose value is a Python string that matches a specified
+        regular expression.
+    """
+
+    def __init__(self, value="", regex=".*", **metadata):
+        """ Creates a Regex trait.
+
+        Parameters
+        ----------
+        value : str
+            The default value of the trait.
+        regex : str
+            The regular expression that the trait value must match.
+
+        Default Value
+        -------------
+        *value* or ''
+        """
+        super(Regex, self).__init__(value=value, regex=regex, **metadata)
+
+
+# -------------------------------------------------------------------------------
+#  'Code' trait:
+# -------------------------------------------------------------------------------
+
+
+class Code(String):
+    """ Defines a trait whose value is a Python string that represents source
+        code in some language.
+    """
+
+    #: The standard metadata for the trait:
+    metadata = {"editor": code_editor}
+
+
+# -------------------------------------------------------------------------------
+#  'HTML' trait:
+# -------------------------------------------------------------------------------
+
+
+class HTML(String):
+    """ Defines a trait whose value must be a string that is interpreted as
+    being HTML. By default the value is parsed and displayed as HTML in
+    TraitsUI views. The validation of the value does not enforce HTML syntax.
+    """
+
+    #: The standard metadata for the trait:
+    metadata = {"editor": html_editor}
+
+
+# -------------------------------------------------------------------------------
+#  'Password' trait:
+# -------------------------------------------------------------------------------
+
+
+class Password(String):
+    """ Defines a trait whose value must be a string, optionally of constrained
+    length or matching a regular expression.
+
+    The trait is identical to a String trait except that by default it uses a
+    PasswordEditor in TraitsUI views, which obscures text entered by the user.
+    """
+
+    #: The standard metadata for the trait:
+    metadata = {"editor": password_editor}
+
+
+# -------------------------------------------------------------------------------
+#  'Callable' trait:
+# -------------------------------------------------------------------------------
+
+
+class Callable(TraitType):
+    """ Defines a trait whose value must be a Python callable.
+    """
+
+    #: The standard metadata for the trait:
+    metadata = {"copy": "ref"}
+
+    #: The default value for the trait:
+    default_value = None
+
+    #: A description of the type of value this trait accepts:
+    info_text = "a callable value"
+
+    def validate(self, object, name, value):
+        """ Validates that the value is a Python callable.
+        """
+        if (value is None) or callable(value):
+            return value
+
+        self.error(object, name, value)
+
+
+# -------------------------------------------------------------------------------
+#  'BaseType' base class:
+# -------------------------------------------------------------------------------
+
+
+class BaseType(TraitType):
+    """ Defines a trait whose value must be an instance of a simple Python type.
+    """
+
+    def validate(self, object, name, value):
+        """ Validates that the value is a Python callable.
+        """
+        if isinstance(value, self.fast_validate[1:]):
+            return value
+
+        self.error(object, name, value)
+
+
+class This(BaseType):
+    """ Defines a trait whose value must be an instance of the defining class.
+    """
+
+    #: The C-level fast validator to use:
+    fast_validate = (2,)
+
+    #: A description of the type of value this trait accepts:
+    info_text = "an instance of the same type as the receiver"
+
+    def __init__(self, value=None, allow_none=True, **metadata):
+        super(This, self).__init__(value, **metadata)
+
+        if allow_none:
+            self.fast_validate = (2, None)
+            self.validate = self.validate_none
+            self.info = self.info_none
+
+    def validate(self, object, name, value):
+        if isinstance(value, object.__class__):
+            return value
+
+        self.validate_failed(object, name, value)
+
+    def validate_none(self, object, name, value):
+        if isinstance(value, object.__class__) or (value is None):
+            return value
+
+        self.validate_failed(object, name, value)
+
+    def info(self):
+        return "an instance of the same type as the receiver"
+
+    def info_none(self):
+        return "an instance of the same type as the receiver or None"
+
+    def validate_failed(self, object, name, value):
+        kind = type(value)
+        if _py2to3.is_InstanceType(kind):
+            msg = "class %s" % value.__class__.__name__
+        else:
+            msg = "%s (i.e. %s)" % (str(kind)[1:-1], repr(value))
+
+        self.error(object, name, msg)
+
+
+class self(This):
+    """ Defines a trait whose value must be an instance of the defining class
+        and whose default value is the object containing the trait.
+    """
+
+    #: The default value type to use (i.e. 'self'):
+    default_value_type = OBJECT_DEFAULT_VALUE
+
+
+class Function(TraitType):
+    """ Defines a trait whose value must be a Python function.
+    """
+
+    #: The C-level fast validator to use:
+    fast_validate = (11, FunctionType)
+
+    #: A description of the type of value this trait accepts:
+    info_text = "a function"
+
+
+class Method(TraitType):
+    """ Defines a trait whose value must be a Python method.
+    """
+
+    #: The C-level fast validator to use:
+    fast_validate = (11, MethodType)
+
+    #: A description of the type of value this trait accepts:
+    info_text = "a method"
+
+
+if six.PY2:
+    from types import ClassType
+
+    class Class(TraitType):
+        """ Defines a trait whose value must be an old-style Python class.
+        """
+
+        #: The C-level fast validator to use:
+        fast_validate = (11, ClassType)
+
+        #: A description of the type of value this trait accepts:
+        info_text = "an old-style class"
+
+
+class Module(TraitType):
+    """ Defines a trait whose value must be a Python module.
+    """
+
+    #: The C-level fast validator to use:
+    fast_validate = (11, ModuleType)
+
+    #: A description of the type of value this trait accepts:
+    info_text = "a module"
+
+
+# -------------------------------------------------------------------------------
+#  'Python' trait:
+# -------------------------------------------------------------------------------
+
+
+class Python(TraitType):
+    """ Defines a trait that provides behavior identical to a standard Python
+        attribute. That is, it allows any value to be assigned, and raises an
+        ValueError if an attempt is made to get the value before one has been
+        assigned. It has no default value. This trait is most often used in
+        conjunction with wildcard naming. See the *Traits User Manual* for
+        details on wildcards.
+    """
+
+    #: The standard metadata for the trait:
+    metadata = {"type": "python"}
+
+    #: The default value for the trait:
+    default_value = Undefined
+
+
+# -------------------------------------------------------------------------------
+#  'ReadOnly' trait:
+# -------------------------------------------------------------------------------
+
+
+class ReadOnly(TraitType):
+    """ Defines a trait that is write-once, and then read-only.
+        The initial value of the attribute is the special, singleton object
+        Undefined. The trait allows any value to be assigned to the attribute
+        if the current value is the Undefined object. Once any other value is
+        assigned, no further assignment is allowed. Normally, the initial
+        assignment to the attribute is performed in the class constructor,
+        based on information passed to the constructor. If the read-only value
+        is known in advance of run time, use the Constant() function instead of
+        ReadOnly to define the trait.
+    """
+
+    # Defines the CTrait type to use for this trait:
+    ctrait_type = 6
+
+    #: The default value for the trait:
+    default_value = Undefined
+
+
+# Create a singleton instance as the trait:
+ReadOnly = ReadOnly()
+
+# -------------------------------------------------------------------------------
+#  'Disallow' trait:
+# -------------------------------------------------------------------------------
+
+
+class Disallow(TraitType):
+    """ Defines a trait that prevents any value from being assigned or read.
+        That is, any attempt to get or set the value of the trait attribute
+        raises an exception. This trait is most often used in conjunction with
+        wildcard naming, for example, to catch spelling mistakes in attribute
+        names. See the *Traits User Manual* for details on wildcards.
+    """
+
+    #: Defines the CTrait type to use for this trait:
+    ctrait_type = 5
+
+
+# Create a singleton instance as the trait:
+Disallow = Disallow()
+
+# -------------------------------------------------------------------------------
+#  'Constant' trait:
+# -------------------------------------------------------------------------------
+
+
+class Constant(TraitType):
+    """  Defines a trait whose value is a constant.
+    """
+
+    #: Defines the CTrait type to use for this trait:
+    ctrait_type = 7
+
+    #: The standard metadata for the trait:
+    metadata = {"type": "constant", "transient": True}
+
+    def __init__(self, value, **metadata):
+        """ Returns a constant, read-only trait whose value is *value*.
+
+            Parameters
+            ----------
+            value : any type except a list or dictionary
+                The default value for the trait.
+
+            Default Value
+            -------------
+            *value*
+
+            Description
+            -----------
+            Traits of this type are very space efficient (and fast) because
+            *value* is not stored in each instance using the trait, but only in
+            the trait object itself. The *value* cannot be a list or dictionary,
+            because those types have mutable values.
+        """
+        if type(value) in MutableTypes:
+            raise TraitError(
+                "Cannot define a constant using a mutable list or dictionary"
+            )
+
+        super(Constant, self).__init__(value, **metadata)
+
+
+# -------------------------------------------------------------------------------
+#  'Delegate' trait:
+# -------------------------------------------------------------------------------
+
+
+class Delegate(TraitType):
+    """ Defines a trait whose value is delegated to a trait on another object.
+    """
+
+    #: Defines the CTrait type to use for this trait:
+    ctrait_type = 3
+
+    #: The standard metadata for the trait:
+    metadata = {"type": "delegate", "transient": False}
+
+    def __init__(
+        self, delegate, prefix="", modify=False, listenable=True, **metadata
+    ):
+        """ Creates a Delegate trait.
+        """
+        if prefix == "":
+            prefix_type = 0
+        elif prefix[-1:] != "*":
+            prefix_type = 1
+        else:
+            prefix = prefix[:-1]
+            if prefix != "":
+                prefix_type = 2
+            else:
+                prefix_type = 3
+
+        metadata["_delegate"] = delegate
+        metadata["_prefix"] = prefix
+        metadata["_listenable"] = listenable
+
+        super(Delegate, self).__init__(**metadata)
+
+        self.delegate = delegate
+        self.prefix = prefix
+        self.prefix_type = prefix_type
+        self.modify = modify
+
+    def as_ctrait(self):
+        """ Returns a CTrait corresponding to the trait defined by this class.
+        """
+        trait = super(Delegate, self).as_ctrait()
+        trait.delegate(
+            self.delegate, self.prefix, self.prefix_type, self.modify
+        )
+
+        return trait
+
+
+# -------------------------------------------------------------------------------
+#  'DelegatesTo' trait:
+# -------------------------------------------------------------------------------
+
+
+class DelegatesTo(Delegate):
+    """ Defines a trait delegate that matches the standard 'delegate' design
+        pattern.
+    """
+
+    def __init__(self, delegate, prefix="", listenable=True, **metadata):
+        """ Creates a "delegator" trait, whose definition and default value are
+            delegated to a *delegate* trait attribute on another object.
+
+            Parameters
+            ----------
+            delegate : str
+                Name of the attribute on the current object which references
+                the object that is the trait's delegate.
+            prefix : str
+                A prefix or substitution applied to the original attribute when
+                looking up the delegated attribute.
+            listenable : bool
+                Indicates whether a listener can be attached to this attribute
+                such that changes to the delagate attribute will trigger it.
+
+            Description
+            -----------
+            An object containing a delegator trait attribute must contain a
+            second attribute that references the object containing the delegate
+            trait attribute. The name of this second attribute is passed as the
+            *delegate* argument to the DelegatesTo() function.
+
+            The following rules govern the application of the prefix parameter:
+
+            * If *prefix* is empty or omitted, the delegation is to an attribute
+              of the delegate object with the same name as the delegator
+              attribute.
+            * If *prefix* is a valid Python attribute name, then the delegation
+              is to an attribute whose name is the value of *prefix*.
+            * If *prefix* ends with an asterisk ('*') and is longer than one
+              character, then the delegation is to an attribute whose name is
+              the value of *prefix*, minus the trailing asterisk, prepended to
+              the delegator attribute name.
+            * If *prefix* is equal to a single asterisk, the delegation is to an
+              attribute whose name is the value of the delegator object's
+              __prefix__ attribute prepended to delegator attribute name.
+
+            Note that any changes to the delegator attribute are actually
+            applied to the corresponding attribute on the delegate object. The
+            original object containing the delegator trait is not modified.
+        """
+        super(DelegatesTo, self).__init__(
+            delegate,
+            prefix=prefix,
+            modify=True,
+            listenable=listenable,
+            **metadata
+        )
+
+
+# -------------------------------------------------------------------------------
+#  'PrototypedFrom' trait:
+# -------------------------------------------------------------------------------
+
+
+class PrototypedFrom(Delegate):
+    """ Defines a trait delegate that matches the standard 'prototype' design
+        pattern.
+    """
+
+    def __init__(self, prototype, prefix="", listenable=True, **metadata):
+        """ Creates a "prototyped" trait, whose definition and default value are
+            obtained from a trait attribute on another object.
+
+            Parameters
+            ----------
+            prototype : str
+                Name of the attribute on the current object which references the
+                object that is the trait's prototype.
+            prefix : str
+                A prefix or substitution applied to the original attribute when
+                looking up the prototyped attribute.
+            listenable : bool
+                Indicates whether a listener can be attached to this attribute
+                such that changes to the corresponding attribute on the
+                prototype object will trigger it.
+
+            Description
+            -----------
+            An object containing a prototyped trait attribute must contain a
+            second attribute that references the object containing the prototype
+            trait attribute. The name of this second attribute is passed as the
+            *prototype* argument to the PrototypedFrom() function.
+
+            The following rules govern the application of the prefix parameter:
+
+            * If *prefix* is empty or omitted, the prototype delegation is to an
+              attribute of the prototype object with the same name as the
+              prototyped attribute.
+            * If *prefix* is a valid Python attribute name, then the prototype
+              delegation is to an attribute whose name is the value of *prefix*.
+            * If *prefix* ends with an asterisk ('*') and is longer than one
+              character, then the prototype delegation is to an attribute whose
+              name is the value of *prefix*, minus the trailing asterisk,
+              prepended to the prototyped attribute name.
+            * If *prefix* is equal to a single asterisk, the prototype
+              delegation is to an attribute whose name is the value of the
+              prototype object's __prefix__ attribute prepended to the
+              prototyped attribute name.
+
+            Note that any changes to the prototyped attribute are made to the
+            original object, not the prototype object. The prototype object is
+            only used to define to trait type and default value.
+
+        """
+        super(PrototypedFrom, self).__init__(
+            prototype,
+            prefix=prefix,
+            modify=False,
+            listenable=listenable,
+            **metadata
+        )
+
+
+# -------------------------------------------------------------------------------
+#  'Expression' class:
+# -------------------------------------------------------------------------------
+
+
+class Expression(TraitType):
+    """ Defines a trait whose value must be a valid Python expression. The
+        compiled form of a valid expression is stored as the mapped value of
+        the trait.
+    """
+
+    #: The default value for the trait:
+    default_value = "0"
+
+    #: A description of the type of value this trait accepts:
+    info_text = "a valid Python expression"
+
+    #: Indicate that this is a mapped trait:
+    is_mapped = True
+
+    def validate(self, object, name, value):
+        """ Validates that a specified value is valid for this trait.
+        """
+        try:
+            return compile(value, "<string>", "eval")
+        except:
+            self.error(object, name, value)
+
+    def post_setattr(self, object, name, value):
+        """ Performs additional post-assignment processing.
+        """
+        object.__dict__[name + "_"] = value
+
+    def mapped_value(self, value):
+        """ Returns the 'mapped' value for the specified **value**.
+        """
+        return compile(value, "<string>", "eval")
+
+    def as_ctrait(self):
+        """ Returns a CTrait corresponding to the trait defined by this class.
+        """
+        # Tell the C code that 'setattr' should store the original, unadapted
+        # value passed to it:
+        return super(Expression, self).as_ctrait().setattr_original_value(True)
+
+
+# -------------------------------------------------------------------------------
+#  'PythonValue' trait:
+# -------------------------------------------------------------------------------
+
+
+class PythonValue(Any):
+    """ Defines a trait whose value can be of any type, and whose default
+    editor is a Python shell.
+    """
+
+    #: The standard metadata for the trait:
+    metadata = {"editor": shell_editor}
+
+
+# -------------------------------------------------------------------------------
+#  'BaseFile' and 'File' traits:
+# -------------------------------------------------------------------------------
+
+
+class BaseFile(BaseStr):
+    """ Defines a trait whose value must be the name of a file.
+    """
+
+    #: A description of the type of value this trait accepts:
+    info_text = "a file name"
+
+    def __init__(
+        self,
+        value="",
+        filter=None,
+        auto_set=False,
+        entries=0,
+        exists=False,
+        **metadata
+    ):
+        """ Creates a File trait.
+
+        Parameters
+        ----------
+        value : str
+            The default value for the trait.
+        filter : str
+            A wildcard string to filter filenames in the file dialog box used by
+            the attribute trait editor.
+        auto_set : bool
+            Indicates whether the file editor updates the trait value after
+            every key stroke.
+        exists : bool
+            Indicates whether the trait value must be an existing file or
+            not.
+
+        Default Value
+        -------------
+        *value* or ''
+        """
+        self.filter = filter
+        self.auto_set = auto_set
+        self.entries = entries
+        self.exists = exists
+
+        super(BaseFile, self).__init__(value, **metadata)
+
+    def validate(self, object, name, value):
+        """ Validates that a specified value is valid for this trait.
+
+            Note: The 'fast validator' version performs this check in C.
+        """
+        validated_value = super(BaseFile, self).validate(object, name, value)
+        if not self.exists:
+            return validated_value
+        elif isfile(value):
+            return validated_value
+
+        self.error(object, name, value)
+
+    def create_editor(self):
+        from traitsui.editors.file_editor import FileEditor
+
+        editor = FileEditor(
+            filter=self.filter or [],
+            auto_set=self.auto_set,
+            entries=self.entries,
+            dialog_style="open" if self.exists else "save",
+        )
+        return editor
+
+
+class File(BaseFile):
+    """ Defines a trait whose value must be the name of a file using a C-level
+        fast validator.
+    """
+
+    def __init__(
+        self,
+        value="",
+        filter=None,
+        auto_set=False,
+        entries=0,
+        exists=False,
+        **metadata
+    ):
+        """ Creates a File trait.
+
+        Parameters
+        ----------
+        value : str
+            The default value for the trait.
+        filter : str
+            A wildcard string to filter filenames in the file dialog box used
+            by the attribute trait editor.
+        auto_set : bool
+            Indicates whether the file editor updates the trait value after
+            every key stroke.
+        exists : bool
+            Indicates whether the trait value must be an existing file or
+            not.
+
+        Default Value
+        -------------
+        *value* or ''
+        """
+        if not exists:
+            # Define the C-level fast validator to use:
+            self.fast_validate = (11,) + six.string_types
+
+        super(File, self).__init__(
+            value, filter, auto_set, entries, exists, **metadata
+        )
+
+
+# -------------------------------------------------------------------------------
+#  'BaseDirectory' and 'Directory' traits:
+# -------------------------------------------------------------------------------
+
+
+class BaseDirectory(BaseStr):
+    """ Defines a trait whose value must be the name of a directory.
+    """
+
+    #: A description of the type of value this trait accepts:
+    info_text = "a directory name"
+
+    def __init__(
+        self, value="", auto_set=False, entries=0, exists=False, **metadata
+    ):
+        """ Creates a BaseDirectory trait.
+
+        Parameters
+        ----------
+        value : str
+            The default value for the trait.
+        auto_set : bool
+            Indicates whether the directory editor updates the trait value
+            after every key stroke.
+        exists : bool
+            Indicates whether the trait value must be an existing directory or
+            not.
+
+        Default Value
+        -------------
+        *value* or ''
+        """
+        self.entries = entries
+        self.auto_set = auto_set
+        self.exists = exists
+
+        super(BaseDirectory, self).__init__(value, **metadata)
+
+    def validate(self, object, name, value):
+        """ Validates that a specified value is valid for this trait.
+
+            Note: The 'fast validator' version performs this check in C.
+        """
+        validated_value = super(BaseDirectory, self).validate(
+            object, name, value
+        )
+        if not self.exists:
+            return validated_value
+        elif isdir(value):
+            return validated_value
+
+        self.error(object, name, value)
+
+    def create_editor(self):
+        from traitsui.editors.directory_editor import DirectoryEditor
+
+        editor = DirectoryEditor(auto_set=self.auto_set, entries=self.entries)
+        return editor
+
+
+class Directory(BaseDirectory):
+    """ Defines a trait whose value must be the name of a directory using a
+        C-level fast validator.
+    """
+
+    def __init__(
+        self, value="", auto_set=False, entries=0, exists=False, **metadata
+    ):
+        """ Creates a Directory trait.
+
+        Parameters
+        ----------
+        value : str
+            The default value for the trait.
+        auto_set : bool
+            Indicates whether the directory editor updates the trait value
+            after every key stroke.
+        exists : bool
+            Indicates whether the trait value must be an existing directory or
+            not.
+
+        Default Value
+        -------------
+        *value* or ''
+        """
+        # Define the C-level fast validator to use if the directory existence
+        #: test is not required:
+        if not exists:
+            self.fast_validate = (11,) + six.string_types
+        super(Directory, self).__init__(
+            value, auto_set, entries, exists, **metadata
+        )
+
+
+# -------------------------------------------------------------------------------
+#  'BaseRange' and 'Range' traits:
+# -------------------------------------------------------------------------------
+
+
+class BaseRange(TraitType):
+    """ Defines a trait whose numeric value must be in a specified range.
+    """
+
+    def __init__(
+        self,
+        low=None,
+        high=None,
+        value=None,
+        exclude_low=False,
+        exclude_high=False,
+        **metadata
+    ):
+        """ Creates a Range trait.
+
+        Parameters
+        ----------
+        low : integer, float or string (i.e. extended trait name)
+            The low end of the range.
+        high : integer, float or string (i.e. extended trait name)
+            The high end of the range.
+        value : integer, float or string (i.e. extended trait name)
+            The default value of the trait.
+        exclude_low : bool
+            Indicates whether the low end of the range is exclusive.
+        exclude_high : bool
+            Indicates whether the high end of the range is exclusive.
+
+        The *low*, *high*, and *value* arguments must be of the same type
+        (integer or float), except in the case where either *low* or *high* is
+        a string (i.e. extended trait name).
+
+        Default Value
+        -------------
+        *value*; if *value* is None or omitted, the default value is *low*,
+        unless *low* is None or omitted, in which case the default value is
+        *high*.
+        """
+        if value is None:
+            if low is not None:
+                value = low
+            else:
+                value = high
+
+        super(BaseRange, self).__init__(value, **metadata)
+
+        vtype = type(high)
+        if (low is not None) and (
+            not issubclass(vtype, (float,) + six.string_types)
+        ):
+            vtype = type(low)
+
+        is_static = not issubclass(vtype, six.string_types)
+        if is_static and (vtype not in RangeTypes):
+            raise TraitError(
+                "Range can only be use for int, long or float "
+                "values, but a value of type %s was specified." % vtype
+            )
+
+        self._low_name = self._high_name = ""
+        self._vtype = Undefined
+
+        if vtype is float:
+            self._validate = "float_validate"
+            kind = 4
+            self._type_desc = "a floating point number"
+            if low is not None:
+                low = float(low)
+
+            if high is not None:
+                high = float(high)
+
+        elif vtype is LONG_TYPE:
+            self._validate = "long_validate"
+            self._type_desc = "a long integer"
+            if low is not None:
+                low = LONG_TYPE(low)
+
+            if high is not None:
+                high = LONG_TYPE(high)
+
+        elif vtype is int:
+            self._validate = "int_validate"
+            kind = 3
+            self._type_desc = "an integer"
+            if low is not None:
+                low = int(low)
+
+            if high is not None:
+                high = int(high)
+        else:
+            self.get, self.set, self.validate = self._get, self._set, None
+            self._vtype = None
+            self._type_desc = "a number"
+
+            if isinstance(high, six.string_types):
+                self._high_name = high = "object." + high
+            else:
+                self._vtype = type(high)
+            high = compile(str(high), "<string>", "eval")
+
+            if isinstance(low, six.string_types):
+                self._low_name = low = "object." + low
+            else:
+                self._vtype = type(low)
+            low = compile(str(low), "<string>", "eval")
+
+            if isinstance(value, six.string_types):
+                value = "object." + value
+            self._value = compile(str(value), "<string>", "eval")
+
+            self.default_value_type = CALLABLE_DEFAULT_VALUE
+            self.default_value = self._get_default_value
+
+        exclude_mask = 0
+        if exclude_low:
+            exclude_mask |= 1
+
+        if exclude_high:
+            exclude_mask |= 2
+
+        if is_static and (vtype is not LONG_TYPE):
+            self.init_fast_validator(kind, low, high, exclude_mask)
+
+        #: Assign type-corrected arguments to handler attributes:
+        self._low = low
+        self._high = high
+        self._exclude_low = exclude_low
+        self._exclude_high = exclude_high
+
+    def init_fast_validator(self, *args):
+        """ Does nothing for the BaseRange class. Used in the Range class to
+            set up the fast validator.
+        """
+        pass
+
+    def validate(self, object, name, value):
+        """ Validate that the value is in the specified range.
+        """
+        return getattr(self, self._validate)(object, name, value)
+
+    def float_validate(self, object, name, value):
+        """ Validate that the value is a float value in the specified range.
+        """
+        try:
+            if (
+                isinstance(value, RangeTypes)
+                and (
+                    (self._low is None)
+                    or (self._exclude_low and (self._low < value))
+                    or ((not self._exclude_low) and (self._low <= value))
+                )
+                and (
+                    (self._high is None)
+                    or (self._exclude_high and (self._high > value))
+                    or ((not self._exclude_high) and (self._high >= value))
+                )
+            ):
+                return float(value)
+        except:
+            pass
+
+        self.error(object, name, value)
+
+    def int_validate(self, object, name, value):
+        """ Validate that the value is an int value in the specified range.
+        """
+        try:
+            if (
+                isinstance(value, int_fast_validate[1:])
+                and (
+                    (self._low is None)
+                    or (self._exclude_low and (self._low < value))
+                    or ((not self._exclude_low) and (self._low <= value))
+                )
+                and (
+                    (self._high is None)
+                    or (self._exclude_high and (self._high > value))
+                    or ((not self._exclude_high) and (self._high >= value))
+                )
+            ):
+                return value
+        except:
+            pass
+
+        self.error(object, name, value)
+
+    def long_validate(self, object, name, value):
+        """ Validate that the value is a long value in the specified range.
+        """
+        try:
+            valid_types = list(long_fast_validate[1:])
+            valid_types.remove(None)
+            if (
+                isinstance(value, tuple(valid_types))
+                and (
+                    (self._low is None)
+                    or (self._exclude_low and (self._low < value))
+                    or ((not self._exclude_low) and (self._low <= value))
+                )
+                and (
+                    (self._high is None)
+                    or (self._exclude_high and (self._high > value))
+                    or ((not self._exclude_high) and (self._high >= value))
+                )
+            ):
+                return value
+        except:
+            pass
+
+        self.error(object, name, value)
+
+    def _get_default_value(self, object):
+        """ Returns the default value of the range.
+        """
+        return eval(self._value)
+
+    def _get(self, object, name, trait):
+        """ Returns the current value of a dynamic range trait.
+        """
+        cname = "_traits_cache_" + name
+        value = object.__dict__.get(cname, Undefined)
+        if value is Undefined:
+            object.__dict__[cname] = value = eval(self._value)
+
+        low = eval(self._low)
+        high = eval(self._high)
+        if (low is not None) and (value < low):
+            value = low
+        elif (high is not None) and (value > high):
+            value = high
+
+        return self._typed_value(value, low, high)
+
+    def _set(self, object, name, value):
+        """ Sets the current value of a dynamic range trait.
+        """
+        if not isinstance(value, six.string_types):
+            try:
+                low = eval(self._low)
+                high = eval(self._high)
+                if (low is None) and (high is None):
+                    if isinstance(value, RangeTypes):
+                        self._set_value(object, name, value)
+                        return
+                else:
+                    new_value = self._typed_value(value, low, high)
+                    if (
+                        (low is None)
+                        or (self._exclude_low and (low < new_value))
+                        or ((not self._exclude_low) and (low <= new_value))
+                    ) and (
+                        (high is None)
+                        or (self._exclude_high and (high > new_value))
+                        or ((not self._exclude_high) and (high >= new_value))
+                    ):
+                        self._set_value(object, name, new_value)
+                        return
+            except:
+                pass
+
+        self.error(object, name, value)
+
+    def _typed_value(self, value, low, high):
+        """ Returns the specified value with the correct type for the current
+            dynamic range.
+        """
+        vtype = self._vtype
+        if vtype is None:
+            if low is not None:
+                vtype = type(low)
+            elif high is not None:
+                vtype = type(high)
+            else:
+                vtype = lambda x: x
+
+        return vtype(value)
+
+    def _set_value(self, object, name, value):
+        """ Sets the specified value as the value of the dynamic range.
+        """
+        cname = "_traits_cache_" + name
+        old = object.__dict__.get(cname, Undefined)
+        if old is Undefined:
+            old = eval(self._value)
+        object.__dict__[cname] = value
+        if value != old:
+            object.trait_property_changed(name, old, value)
+
+    def full_info(self, object, name, value):
+        """ Returns a description of the trait.
+        """
+        if self._vtype is not Undefined:
+            low = eval(self._low)
+            high = eval(self._high)
+            low, high = (
+                self._typed_value(low, low, high),
+                self._typed_value(high, low, high),
+            )
+        else:
+            low = self._low
+            high = self._high
+
+        if low is None:
+            if high is None:
+                return self._type_desc
+
+            return "%s <%s %s" % (
+                self._type_desc,
+                "="[self._exclude_high :],
+                high,
+            )
+
+        elif high is None:
+            return "%s >%s %s" % (
+                self._type_desc,
+                "="[self._exclude_low :],
+                low,
+            )
+
+        return "%s <%s %s <%s %s" % (
+            low,
+            "="[self._exclude_low :],
+            self._type_desc,
+            "="[self._exclude_high :],
+            high,
+        )
+
+    def create_editor(self):
+        """ Returns the default UI editor for the trait.
+        """
+        # fixme: Needs to support a dynamic range editor.
+
+        auto_set = self.auto_set
+        if auto_set is None:
+            auto_set = True
+
+        from traitsui.api import RangeEditor
+
+        return RangeEditor(
+            self,
+            mode=self.mode or "auto",
+            cols=self.cols or 3,
+            auto_set=auto_set,
+            enter_set=self.enter_set or False,
+            low_label=self.low or "",
+            high_label=self.high or "",
+            low_name=self._low_name,
+            high_name=self._high_name,
+        )
+
+
+class Range(BaseRange):
+    """ Defines a trait whose numeric value must be in a specified range using
+        a C-level fast validator.
+    """
+
+    def init_fast_validator(self, *args):
+        """ Set up the C-level fast validator.
+        """
+        self.fast_validate = args
+
+
+# -------------------------------------------------------------------------------
+#  'BaseEnum' and 'Enum' traits:
+# -------------------------------------------------------------------------------
+
+
+class BaseEnum(TraitType):
+    """ Defines a trait whose value must be one of a specified set of values.
+    """
+
+    def __init__(self, *args, **metadata):
+        """ Returns an Enum trait.
+
+        Parameters
+        ----------
+        values : list or tuple
+            The enumeration of all legal values for the trait
+
+        Default Value
+        -------------
+        values[0]
+        """
+        values = metadata.pop("values", None)
+        if isinstance(values, six.string_types):
+            n = len(args)
+            if n == 0:
+                default_value = None
+            elif n == 1:
+                default_value = args[0]
+            else:
+                raise TraitError(
+                    "Incorrect number of arguments specified "
+                    "when using the 'values' keyword"
+                )
+            self.name = values
+            self.values = compile("object." + values, "<string>", "eval")
+            self.get, self.set, self.validate = self._get, self._set, None
+        else:
+            default_value = args[0]
+            if (len(args) == 1) and isinstance(default_value, SequenceTypes):
+                args = default_value
+                default_value = args[0]
+            elif (len(args) == 2) and isinstance(args[1], SequenceTypes):
+                args = args[1]
+
+            self.name = ""
+            self.values = tuple(args)
+            self.init_fast_validator(5, self.values)
+
+        super(BaseEnum, self).__init__(default_value, **metadata)
+
+    def init_fast_validator(self, *args):
+        """ Does nothing for the BaseEnum class. Used in the Enum class to set
+            up the fast validator.
+        """
+        pass
+
+    def validate(self, object, name, value):
+        """ Validates that the value is one of the enumerated set of valid
+            values.
+        """
+        if value in self.values:
+            return value
+
+        self.error(object, name, value)
+
+    def full_info(self, object, name, value):
+        """ Returns a description of the trait.
+        """
+        if self.name == "":
+            values = self.values
+        else:
+            values = eval(self.values)
+
+        return " or ".join([repr(x) for x in values])
+
+    def create_editor(self):
+        """ Returns the default UI editor for the trait.
+        """
+        from traitsui.api import EnumEditor
+
+        values = self
+        if self.name != "":
+            values = None
+
+        return EnumEditor(
+            values=values,
+            name=self.name,
+            cols=self.cols or 3,
+            evaluate=self.evaluate,
+            mode=self.mode or "radio",
+        )
+
+    def _get(self, object, name, trait):
+        """ Returns the current value of a dynamic enum trait.
+        """
+        value = self.get_value(object, name, trait)
+        values = eval(self.values)
+        if value not in values:
+            value = None
+            if len(values) > 0:
+                value = values[0]
+
+        return value
+
+    def _set(self, object, name, value):
+        """ Sets the current value of a dynamic range trait.
+        """
+        if value in eval(self.values):
+            self.set_value(object, name, value)
+        else:
+            self.error(object, name, value)
+
+
+class Enum(BaseEnum):
+    """ Defines a trait whose value must be one of a specified set of values
+        using a C-level fast validator.
+    """
+
+    def init_fast_validator(self, *args):
+        """ Set up the C-level fast validator.
+        """
+        self.fast_validate = args
+
+
+# -------------------------------------------------------------------------------
+#  'BaseTuple' and 'Tuple' and 'ValidatedTuple' traits:
+# -------------------------------------------------------------------------------
+
+
+class BaseTuple(TraitType):
+    """ Defines a trait whose value must be a tuple of specified trait types.
+    """
+
+    def __init__(self, *types, **metadata):
+        """ Returns a Tuple trait.
+
+        Parameters
+        ----------
+        types : zero or more arguments
+            Definition of the default and allowed tuples. If the first item of
+            *types* is a tuple, it is used as the default value.
+            The remaining argument list is used to form a tuple that constrains
+            the  values assigned to the returned trait. The trait's value must
+            be a tuple of the same length as the remaining argument list, whose
+            elements must match the types specified by the corresponding items
+            of the remaining argument list.
+
+        Default Value
+        -------------
+        1. If no arguments are specified, the default value is ().
+        2. If a tuple is specified as the first argument, it is the default
+           value.
+        3. If a tuple is not specified as the first argument, the default
+           value is a tuple whose length is the length of the argument list,
+           and whose values are the default values for the corresponding trait
+           types.
+
+        Example for case #2::
+
+            mytuple = Tuple(('Fred', 'Betty', 5))
+
+        The trait's value must be a 3-element tuple whose first and second
+        elements are strings, and whose third element is an integer. The
+        default value is ``('Fred', 'Betty', 5)``.
+
+        Example for case #3::
+
+            mytuple = Tuple('Fred', 'Betty', 5)
+
+        The trait's value must be a 3-element tuple whose first and second
+        elements are strings, and whose third element is an integer. The
+        default value is ``('','',0)``.
+        """
+        if len(types) == 0:
+            self.init_fast_validator(11, tuple, None, list)
+
+            super(BaseTuple, self).__init__((), **metadata)
+
+            return
+
+        default_value = None
+
+        if isinstance(types[0], tuple):
+            default_value, types = types[0], types[1:]
+            if len(types) == 0:
+                types = [Trait(element) for element in default_value]
+
+        self.types = tuple([trait_from(type) for type in types])
+        self.init_fast_validator(9, self.types)
+
+        if default_value is None:
+            default_value = tuple(
+                [type.default_value()[1] for type in self.types]
+            )
+
+        super(BaseTuple, self).__init__(default_value, **metadata)
+
+    def init_fast_validator(self, *args):
+        """ Saves the validation parameters.
+        """
+        self.no_type_check = args[0] == 11
+
+    def validate(self, object, name, value):
+        """ Validates that the value is a valid tuple.
+        """
+        if self.no_type_check:
+            if isinstance(value, tuple):
+                return value
+
+            if isinstance(value, list):
+                return tuple(value)
+
+            self.error(object, name, value)
+
+        try:
+            if isinstance(value, list):
+                value = tuple(value)
+
+            if isinstance(value, tuple):
+                types = self.types
+                if len(value) == len(types):
+                    values = []
+                    for i, type in enumerate(types):
+                        values.append(type.validate(object, name, value[i]))
+
+                    return tuple(values)
+        except:
+            pass
+
+        self.error(object, name, value)
+
+    def full_info(self, object, name, value):
+        """ Returns a description of the trait.
+        """
+        if self.no_type_check:
+            return "a tuple"
+
+        return "a tuple of the form: (%s)" % (
+            ", ".join(
+                [type.full_info(object, name, value) for type in self.types]
+            )
+        )
+
+    def create_editor(self):
+        """ Returns the default UI editor for the trait.
+        """
+        from traitsui.api import TupleEditor
+
+        auto_set = self.auto_set
+        if auto_set is None:
+            auto_set = True
+        enter_set = self.enter_set or False
+
+        return TupleEditor(
+            types=self.types,
+            labels=self.labels or [],
+            cols=self.cols or 1,
+            auto_set=auto_set,
+            enter_set=enter_set,
+        )
+
+
+class Tuple(BaseTuple):
+    """ Defines a trait whose value must be a tuple of specified trait types
+        using a C-level fast validator.
+    """
+
+    def init_fast_validator(self, *args):
+        """ Set up the C-level fast validator.
+        """
+        super(Tuple, self).init_fast_validator(*args)
+
+        self.fast_validate = args
+
+
+class ValidatedTuple(BaseTuple):
+    """ A Tuple trait that supports custom validation.
+    """
+
+    def __init__(self, *types, **metadata):
+        """ Returns a ValidatedTuple trait
+
+        Parameters
+        ----------
+        types : zero or more arguments
+            Definition of the default and allowed tuples. (see
+            :class:`~.BaseTuple` for more details)
+        fvalidate : callable, optional
+            A callable to provide the additional custom validation for the
+            tuple. The callable will be passed the tuple value and should
+            return True or False.
+        fvalidate_info : string, optional
+            A string describing the custom validation to use for the error
+            messages.
+
+        For example::
+
+          value_range = ValidatedTuple(Int(0), Int(1), fvalidate=lambda x: x[0] < x[1])
+
+        This definition will accept only tuples ``(a, b)`` containing two integers
+        that satisfy ``a < b``.
+        """
+        metadata.setdefault("fvalidate", None)
+        metadata.setdefault("fvalidate_info", "")
+        super(ValidatedTuple, self).__init__(*types, **metadata)
+
+    def validate(self, object, name, value):
+        """ Validates that the value is a valid tuple.
+        """
+        values = super(ValidatedTuple, self).validate(object, name, value)
+        # Exceptions in the fvalidate function will not result in a TraitError
+        # but will be allowed to propagate up the frame stacks.
+        if self.fvalidate is None or self.fvalidate(values):
+            return values
+        else:
+            self.error(object, name, value)
+
+    def full_info(self, object, name, value):
+        """ Returns a description of the trait.
+        """
+        message = "a tuple of the form: ({0}) that passes custom validation{1}"
+        types_info = ", ".join(
+            [type_.full_info(object, name, value) for type_ in self.types]
+        )
+        if self.fvalidate_info is not None:
+            fvalidate_info = ": {0}".format(self.fvalidate_info)
+        else:
+            fvalidate_info = ""
+        return message.format(types_info, fvalidate_info)
+
+
+# -------------------------------------------------------------------------------
+#  'List' trait:
+# -------------------------------------------------------------------------------
+
+
+class List(TraitType):
+    """ Defines a trait whose value must be a list whose items are of the
+        specified trait type.
+    """
+
+    info_trait = None
+    default_value_type = TRAIT_LIST_OBJECT_DEFAULT_VALUE
+    _items_event = None
+
+    def __init__(
+        self,
+        trait=None,
+        value=None,
+        minlen=0,
+        maxlen=six.MAXSIZE,
+        items=True,
+        **metadata
+    ):
+        """ Returns a List trait.
+
+        Parameters
+        ----------
+        trait : a trait or value that can be converted to a trait using Trait()
+            The type of item that the list contains. If not specified, the list
+            can contain items of any type.
+        value : list
+            Default value for the list.
+        minlen : integer
+            The minimum length of a list that can be assigned to the trait.
+        maxlen : integer
+            The maximum length of a list that can be assigned to the trait.
+
+        The length of the list assigned to the trait must be such that::
+
+            minlen <= len(list) <= maxlen
+
+        Default Value
+        -------------
+        *value* or None
+        """
+        metadata.setdefault("copy", "deep")
+
+        if isinstance(trait, SequenceTypes):
+            trait, value = value, list(trait)
+
+        if value is None:
+            value = []
+
+        self.item_trait = trait_from(trait)
+        self.minlen = max(0, minlen)
+        self.maxlen = max(minlen, maxlen)
+        self.has_items = items
+
+        if self.item_trait.instance_handler == "_instance_changed_handler":
+            metadata.setdefault("instance_handler", "_list_changed_handler")
+
+        super(List, self).__init__(value, **metadata)
+
+    def validate(self, object, name, value):
+        """ Validates that the values is a valid list.
+
+        .. note::
+
+            `object` can be None when validating a default value (see e.g.
+            :meth:`~traits.trait_handlers.TraitType.clone`)
+
+        """
+        if isinstance(value, list) and (
+            self.minlen <= len(value) <= self.maxlen
+        ):
+            if object is None:
+                return value
+
+            return TraitListObject(self, object, name, value)
+
+        self.error(object, name, value)
+
+    def full_info(self, object, name, value):
+        """ Returns a description of the trait.
+        """
+        if self.minlen == 0:
+            if self.maxlen == six.MAXSIZE:
+                size = "items"
+            else:
+                size = "at most %d items" % self.maxlen
+        else:
+            if self.maxlen == six.MAXSIZE:
+                size = "at least %d items" % self.minlen
+            else:
+                size = "from %s to %s items" % (self.minlen, self.maxlen)
+
+        return "a list of %s which are %s" % (
+            size,
+            self.item_trait.full_info(object, name, value),
+        )
+
+    def create_editor(self):
+        """ Returns the default UI editor for the trait.
+        """
+        return list_editor(self, self)
+
+    def inner_traits(self):
+        """ Returns the *inner trait* (or traits) for this trait.
+        """
+        return (self.item_trait,)
+
+    # -- Private Methods --------------------------------------------------------
+
+    def items_event(self):
+        return items_event()
+
+
+# -------------------------------------------------------------------------------
+#  'CList' trait:
+# -------------------------------------------------------------------------------
+
+
+class CList(List):
+    """ Defines a trait whose values must be a list whose items are of the
+        specified trait type or which can be coerced to a list whose values are
+        of the specified trait type.
+    """
+
+    def validate(self, object, name, value):
+        """ Validates that the values is a valid list.
+        """
+        if not isinstance(value, list):
+            try:
+                # Should work for all iterables as well as strings (which do
+                # not define an __iter__ method)
+                value = list(value)
+            except (ValueError, TypeError):
+                value = [value]
+
+        return super(CList, self).validate(object, name, value)
+
+    def full_info(self, object, name, value):
+        """ Returns a description of the trait.
+        """
+        return "%s or %s" % (
+            self.item_trait.full_info(object, name, value),
+            super(CList, self).full_info(object, name, value),
+        )
+
+
+# -------------------------------------------------------------------------------
+#  'Set' trait:
+# -------------------------------------------------------------------------------
+
+
+class Set(TraitType):
+    """ Defines a trait whose value must be a set whose items are of the
+        specified trait type.
+    """
+
+    info_trait = None
+    default_value_type = TRAIT_SET_OBJECT_DEFAULT_VALUE
+    _items_event = None
+
+    def __init__(self, trait=None, value=None, items=True, **metadata):
+        """ Returns a Set trait.
+
+        Parameters
+        ----------
+        trait : a trait or value that can be converted to a trait using Trait()
+            The type of item that the list contains. If not specified, the list
+            can contain items of any type.
+        value : set
+            Default value for the set.
+
+        Default Value
+        -------------
+        *value* or None
+        """
+        metadata.setdefault("copy", "deep")
+
+        if isinstance(trait, SetTypes):
+            trait, value = value, set(trait)
+
+        if value is None:
+            value = set()
+
+        self.item_trait = trait_from(trait)
+        self.has_items = items
+
+        super(Set, self).__init__(value, **metadata)
+
+    def validate(self, object, name, value):
+        """ Validates that the values is a valid set.
+
+        .. note::
+
+            `object` can be None when validating a default value (see e.g.
+            :meth:`~traits.trait_handlers.TraitType.clone`)
+
+        """
+        if isinstance(value, set):
+            if object is None:
+                return value
+
+            return TraitSetObject(self, object, name, value)
+
+        self.error(object, name, value)
+
+    def full_info(self, object, name, value):
+        """ Returns a description of the trait.
+        """
+        return "a set of %s" % self.item_trait.full_info(object, name, value)
+
+    def create_editor(self):
+        """ Returns the default UI editor for the trait.
+        """
+        from traitsui.api import TextEditor
+
+        return TextEditor(evaluate=eval)
+
+    def inner_traits(self):
+        """ Returns the *inner trait* (or traits) for this trait.
+        """
+        return (self.item_trait,)
+
+    # -- Private Methods --------------------------------------------------------
+
+    def items_event(self):
+        if self.__class__._items_event is None:
+            self.__class__._items_event = Event(
+                TraitSetEvent, is_base=False
+            ).as_ctrait()
+
+        return self.__class__._items_event
+
+
+# -------------------------------------------------------------------------------
+#  'CSet' trait:
+# -------------------------------------------------------------------------------
+
+
+class CSet(Set):
+    """ Defines a trait whose values must be a set whose items are of the
+        specified trait type or which can be coerced to a set whose values are
+        of the specified trait type.
+    """
+
+    def validate(self, object, name, value):
+        """ Validates that the values is a valid list.
+        """
+        if not isinstance(value, set):
+            try:
+                # Should work for all iterables as well as strings (which do
+                # not define an __iter__ method)
+                value = set(value)
+            except (ValueError, TypeError):
+                value = set([value])
+
+        return super(CSet, self).validate(object, name, value)
+
+    def full_info(self, object, name, value):
+        """ Returns a description of the trait.
+        """
+        return "%s or %s" % (
+            self.item_trait.full_info(object, name, value),
+            super(CSet, self).full_info(object, name, value),
+        )
+
+
+# -------------------------------------------------------------------------------
+#  'Dict' trait:
+# -------------------------------------------------------------------------------
+
+
+class Dict(TraitType):
+    """ Defines a trait whose value must be a dictionary, optionally with
+        specified types for keys and values.
+    """
+
+    info_trait = None
+    default_value_type = TRAIT_DICT_OBJECT_DEFAULT_VALUE
+    _items_event = None
+
+    def __init__(
+        self,
+        key_trait=None,
+        value_trait=None,
+        value=None,
+        items=True,
+        **metadata
+    ):
+        """ Returns a Dict trait.
+
+        Parameters
+        ----------
+        key_trait : a trait or value that can convert to a trait using Trait()
+            The trait type for keys in the dictionary; if not specified, any
+            values can be used as keys.
+        value_trait : a trait or value that can convert to a trait using Trait()
+            The trait type for values in the dictionary; if not specified, any
+            values can be used as dictionary values.
+        value : dict
+            The default value for the returned trait.
+        items : bool
+            Indicates whether the value contains items.
+
+        Default Value
+        -------------
+        *value* or {}
+        """
+        if isinstance(key_trait, dict):
+            key_trait, value_trait, value = value_trait, value, key_trait
+
+        if value is None:
+            value = {}
+
+        self.key_trait = trait_from(key_trait)
+        self.value_trait = trait_from(value_trait)
+        self.has_items = items
+
+        handler = self.value_trait.handler
+        if (handler is not None) and handler.has_items:
+            handler = handler.clone()
+            handler.has_items = False
+        self.value_handler = handler
+
+        super(Dict, self).__init__(value, **metadata)
+
+    def validate(self, object, name, value):
+        """ Validates that the value is a valid dictionary.
+
+        .. note::
+
+            `object` can be None when validating a default value (see e.g.
+            :meth:`~traits.trait_handlers.TraitType.clone`)
+
+        """
+        if isinstance(value, dict):
+            if object is None:
+                return value
+            return TraitDictObject(self, object, name, value)
+
+        self.error(object, name, value)
+
+    def full_info(self, object, name, value):
+        """ Returns a description of the trait.
+        """
+        return (
+            "a dictionary with keys which are %s and with values which "
+            "are %s"
+        ) % (
+            self.key_trait.full_info(object, name, value),
+            self.value_trait.full_info(object, name, value),
+        )
+
+    def create_editor(self):
+        """ Returns the default UI editor for the trait.
+        """
+        from traitsui.api import TextEditor
+
+        return TextEditor(evaluate=eval)
+
+    def inner_traits(self):
+        """ Returns the *inner trait* (or traits) for this trait.
+        """
+        return (self.key_trait, self.value_trait)
+
+    # -- Private Methods --------------------------------------------------------
+
+    def items_event(self):
+        cls = self.__class__
+        if cls._items_event is None:
+            cls._items_event = Event(TraitDictEvent, is_base=False).as_ctrait()
+
+        return cls._items_event
+
+
+# -------------------------------------------------------------------------------
+#  'BaseInstance' and 'Instance' traits:
+# -------------------------------------------------------------------------------
+
+# Allowed values and mappings for the 'adapt' keyword:
+AdaptMap = {"no": 0, "yes": 1, "default": 2}
+
+
+class BaseClass(TraitType):
+    """ Base class for types which have an associated class which can be
+        determined dynamically by specifying a string name for the class (e.g.
+        'package1.package2.module.class'.
+
+        Any subclass must define instances with 'klass' and 'module' attributes
+        that contain the string name of the class (or actual class object) and
+        the module name that contained the original trait definition (used for
+        resolving local class names (e.g. 'LocalClass')).
+
+        This is an abstract class that only provides helper methods used to
+        resolve the class name into an actual class object.
+    """
+
+    def resolve_class(self, object, name, value):
+        klass = self.validate_class(self.find_class(self.klass))
+        if klass is None:
+            self.validate_failed(object, name, value)
+
+        self.klass = klass
+
+    def validate_class(self, klass):
+        return klass
+
+    def find_class(self, klass):
+        module = self.module
+        col = klass.rfind(".")
+        if col >= 0:
+            module = klass[:col]
+            klass = klass[col + 1 :]
+
+        theClass = getattr(sys.modules.get(module), klass, None)
+        if (theClass is None) and (col >= 0):
+            try:
+                mod = __import__(module)
+                for component in module.split(".")[1:]:
+                    mod = getattr(mod, component)
+
+                theClass = getattr(mod, klass, None)
+            except:
+                pass
+
+        return theClass
+
+    def validate_failed(self, object, name, value):
+
+        self.error(object, name, value)
+
+
+def validate_implements(value, klass, unused=None):
+    """ Checks to see if a specified value implements the instance class
+        interface (if it is an interface).
+    """
+
+    from .has_traits import isinterface
+    from .interface_checker import check_implements
+
+    return isinterface(klass) and check_implements(value.__class__, klass)
+
+
+#: Tell the C-base code about the 'validate_implements' function (used by the
+#: 'fast_validate' code for Instance types):
+from . import ctraits
+
+ctraits._validate_implements(validate_implements)
+
+
+class BaseInstance(BaseClass):
+    """ Defines a trait whose value must be an instance of a specified class,
+        or one of its subclasses.
+    """
+
+    adapt_default = "no"
+
+    def __init__(
+        self,
+        klass=None,
+        factory=None,
+        args=None,
+        kw=None,
+        allow_none=True,
+        adapt=None,
+        module=None,
+        **metadata
+    ):
+        """ Returns an Instance trait.
+
+        Parameters
+        ----------
+        klass : class or instance
+            The object that forms the basis for the trait; if it is an
+            instance, then trait values must be instances of the same class or
+            a subclass. This object is not the default value, even if it is an
+            instance.
+        factory : callable
+            A callable, typically a class, that when called with *args* and
+            *kw*, returns the default value for the trait. If not specified,
+            or *None*, *klass* is used as the factory.
+        args : tuple
+            Positional arguments for generating the default value.
+        kw : dictionary
+            Keyword arguments for generating the default value.
+        allow_none : bool
+            Indicates whether None is allowed as a value.
+        adapt : str
+            A string specifying how adaptation should be applied. The possible
+            values are:
+
+                - 'no': Adaptation is not allowed.
+                - 'yes': Adaptation is allowed. If adaptation fails, an
+                    exception should be raised.
+                - 'default': Adaptation is allowed. If adaptation fails, the
+                    default value for the trait should be used.
+
+        Default Value
+        -------------
+        **None** if *klass* is an instance or if it is a class and *args* and
+        *kw* are not specified. Otherwise, the default value is the instance
+        obtained by calling ``klass(*args, **kw)``. Note that the constructor
+        call is performed each time a default value is assigned, so each
+        default value assigned is a unique instance.
+        """
+        if klass is None:
+            raise TraitError(
+                "A %s trait must have a class specified."
+                % self.__class__.__name__
+            )
+
+        metadata.setdefault("copy", "deep")
+        metadata.setdefault("instance_handler", "_instance_changed_handler")
+
+        adapt = adapt or self.adapt_default
+        if adapt not in AdaptMap:
+            raise TraitError("'adapt' must be 'yes', 'no' or 'default'.")
+
+        if isinstance(factory, tuple):
+            if args is None:
+                args, factory = factory, klass
+            elif isinstance(args, dict):
+                factory, args, kw = klass, factory, args
+
+        elif (kw is None) and isinstance(factory, dict):
+            kw, factory = factory, klass
+
+        elif ((args is not None) or (kw is not None)) and (factory is None):
+            factory = klass
+
+        self._allow_none = allow_none
+        self.adapt = AdaptMap[adapt]
+        self.module = module or get_module_name()
+
+        if isinstance(klass, six.string_types):
+            self.klass = klass
+        else:
+            if not isinstance(klass, ClassTypes):
+                klass = klass.__class__
+
+            self.klass = klass
+            self.init_fast_validate()
+
+        value = factory
+        if factory is not None:
+            if args is None:
+                args = ()
+
+            if kw is None:
+                if isinstance(args, dict):
+                    kw = args
+                    args = ()
+                else:
+                    kw = {}
+            elif not isinstance(kw, dict):
+                raise TraitError("The 'kw' argument must be a dictionary.")
+
+            if (not callable(factory)) and (
+                not isinstance(factory, six.string_types)
+            ):
+                if (len(args) > 0) or (len(kw) > 0):
+                    raise TraitError("'factory' must be callable")
+            else:
+                value = _InstanceArgs(factory, args, kw)
+
+        self.default_value = value
+
+        super(BaseInstance, self).__init__(value, **metadata)
+
+    def validate(self, object, name, value):
+        """ Validates that the value is a valid object instance.
+        """
+        from traits.adaptation.api import adapt
+
+        if value is None:
+            if self._allow_none:
+                return value
+
+            self.validate_failed(object, name, value)
+
+        if isinstance(self.klass, six.string_types):
+            self.resolve_class(object, name, value)
+
+        if self.adapt == 0:
+            try:
+                if value is adapt(value, self.klass):
+                    return value
+            except:
+                if validate_implements(value, self.klass):
+                    return value
+
+        elif self.adapt == 1:
+            try:
+                return adapt(value, self.klass)
+            except:
+                if validate_implements(value, self.klass):
+                    return value
+
+        else:
+            result = adapt(value, self.klass, None)
+            if result is None:
+                if validate_implements(value, self.klass):
+                    return value
+
+                result = self.default_value
+                if isinstance(result, _InstanceArgs):
+                    result = result[0](*result[1], **result[2])
+
+            return result
+
+        self.validate_failed(object, name, value)
+
+    def info(self):
+        """ Returns a description of the trait.
+        """
+        klass = self.klass
+        if not isinstance(klass, six.string_types):
+            klass = klass.__name__
+
+        if self.adapt == 0:
+            result = class_of(klass)
+        else:
+            result = (
+                "an implementor of, or can be adapted to implement, %s" % klass
+            )
+
+        if self._allow_none:
+            return result + " or None"
+
+        return result
+
+    def get_default_value(self):
+        """ Returns a tuple of the form: ( default_value_type, default_value )
+            which describes the default value for this trait.
+        """
+        dv = self.default_value
+        dvt = self.default_value_type
+        if dvt < 0:
+            if not isinstance(dv, _InstanceArgs):
+                return super(BaseInstance, self).get_default_value()
+
+            self.default_value_type = dvt = CALLABLE_AND_ARGS_DEFAULT_VALUE
+            self.default_value = dv = (
+                self.create_default_value,
+                dv.args,
+                dv.kw,
+            )
+
+        return (dvt, dv)
+
+    def create_editor(self):
+        """ Returns the default traits UI editor for this type of trait.
+        """
+        from traitsui.api import InstanceEditor
+
+        return InstanceEditor(
+            label=self.label or "",
+            view=self.view or "",
+            kind=self.kind or "live",
+        )
+
+    # -- Private Methods --------------------------------------------------------
+
+    def create_default_value(self, *args, **kw):
+        klass = args[0]
+        if isinstance(klass, six.string_types):
+            klass = self.validate_class(self.find_class(klass))
+            if klass is None:
+                raise TraitError("Unable to locate class: " + args[0])
+
+        return klass(*args[1:], **kw)
+
+    #: fixme: Do we still need this method using the new style?...
+    def allow_none(self):
+        self._allow_none = True
+        self.init_fast_validate()
+
+    def init_fast_validate(self):
+        """ Does nothing for the BaseInstance' class. Used by the 'Instance',
+            'AdaptedTo' and 'AdaptsTo' classes to set up the C-level fast
+            validator.
+        """
+        pass
+
+    def resolve_class(self, object, name, value):
+        super(BaseInstance, self).resolve_class(object, name, value)
+
+        #: fixme: The following is quite ugly, because it wants to try and fix
+        #: the trait referencing this handler to use the 'fast path' now that the
+        #: actual class has been resolved. The problem is finding the trait,
+        # especially in the case of List(Instance('foo')), where the
+        # object.base_trait(...) value is the List trait, not the Instance
+        # trait, so we need to check for this and pull out the List
+        # 'item_trait'. Obviously this does not extend well to other traits
+        # containing nested trait references (Dict?)...
+        self.init_fast_validate()
+        trait = object.base_trait(name)
+        handler = trait.handler
+        if handler is not self:
+            set_validate = getattr(handler, "set_validate", None)
+            if set_validate is not None:
+                # The outer trait is a TraitCompound. Recompute its
+                # fast_validate table now that we have updated ours.
+                # FIXME: there are probably still issues if the TraitCompound is
+                # further nested.
+                set_validate()
+            else:
+                item_trait = getattr(handler, "item_trait", None)
+                if item_trait is not None and item_trait.handler is self:
+                    # The outer trait is a List trait.
+                    trait = item_trait
+                    handler = self
+                else:
+                    return
+        if handler.fast_validate is not None:
+            trait.set_validate(handler.fast_validate)
+
+
+class Instance(BaseInstance):
+    """ Defines a trait whose value must be an instance of a specified class,
+        or one of its subclasses using a C-level fast validator.
+    """
+
+    def init_fast_validate(self):
+        """ Sets up the C-level fast validator. """
+
+        from .has_traits import isinterface
+
+        if (self.adapt == 0) and (not isinterface(self.klass)):
+            fast_validate = [1, self.klass]
+            if self._allow_none:
+                fast_validate = [1, None, self.klass]
+
+            if self.klass in TypeTypes:
+                fast_validate[0] = 0
+
+            self.fast_validate = tuple(fast_validate)
+        else:
+            self.fast_validate = (19, self.klass, self.adapt, self._allow_none)
+
+
+class Supports(Instance):
+    """ A traits whose value must support a specified protocol.
+
+    In other words, the value of the trait directly provide, or can be adapted
+    to, the given protocol (Interface or type).
+
+    The value of the trait after assignment is the possibly adapted value
+    (i.e., it is the original assigned value if that provides the protocol,
+    or is an adapter otherwise).
+
+    The original, unadapted value is stored in a "shadow" attribute with
+    the same name followed by an underscore (e.g., ``foo`` and ``foo_``).
+    """
+
+    adapt_default = "yes"
+
+    def post_setattr(self, object, name, value):
+        """ Performs additional post-assignment processing.
+        """
+        # Save the original, unadapted value in the mapped trait:
+        object.__dict__[name + "_"] = value
+
+    def as_ctrait(self):
+        """ Returns a CTrait corresponding to the trait defined by this class.
+        """
+        return self.modify_ctrait(super(AdaptedTo, self).as_ctrait())
+
+    def modify_ctrait(self, ctrait):
+
+        # Tell the C code that the 'post_setattr' method wants the original,
+        # unadapted value passed to 'setattr':
+        return ctrait.post_setattr_original_value(True)
+
+
+# Alias defined for backward compatibility with Traits 4.3.0
+AdaptedTo = Supports
+
+
+class AdaptsTo(Supports):
+    """ A traits whose value must support a specified protocol.
+
+    In other words, the value of the trait directly provide, or can be adapted
+    to, the given protocol (Interface or type).
+
+    The value of the trait after assignment is the original, unadapted value.
+
+    A possibly adapted value is stored in a "shadow" attribute with
+    the same name followed by an underscore (e.g., ``foo`` and ``foo_``).
+    """
+
+    def modify_ctrait(self, ctrait):
+        # Tell the C code that 'setattr' should store the original, unadapted
+        # value passed to it:
+        return ctrait.setattr_original_value(True)
+
+
+# -------------------------------------------------------------------------------
+#  'Type' trait:
+# -------------------------------------------------------------------------------
+
+
+class Type(BaseClass):
+    """ Defines a trait whose value must be a subclass of a specified class.
+    """
+
+    def __init__(self, value=None, klass=None, allow_none=True, **metadata):
+        """ Returns an Type trait.
+
+        Parameters
+        ----------
+        value : class or None
+
+        klass : class or None
+
+        allow_none : bool
+            Indicates whether None is allowed as an assignable value. Even if
+            **False**, the default *value* may be **None**.
+
+        Default Value
+        -------------
+        **None** if *klass* is an instance or if it is a class and *args* and
+        *kw* are not specified. Otherwise, the default value is the instance
+        obtained by calling ``klass(*args, **kw)``. Note that the constructor
+        call is performed each time a default value is assigned, so each
+        default value assigned is a unique instance.
+        """
+        if value is None:
+            if klass is None:
+                klass = object
+
+        elif klass is None:
+            klass = value
+
+        if isinstance(klass, six.string_types):
+            self.validate = self.resolve
+
+        elif not isinstance(klass, ClassTypes):
+            raise TraitError("A Type trait must specify a class.")
+
+        self.klass = klass
+        self._allow_none = allow_none
+        self.module = get_module_name()
+
+        super(Type, self).__init__(value, **metadata)
+
+    def validate(self, object, name, value):
+        """ Validates that the value is a valid object instance.
+        """
+        try:
+            if issubclass(value, self.klass):
+                return value
+        except:
+            if (value is None) and (self._allow_none):
+                return value
+
+        self.error(object, name, value)
+
+    def resolve(self, object, name, value):
+        """ Resolves a class originally specified as a string into an actual
+            class, then resets the trait so that future calls will be handled by
+            the normal validate method.
+        """
+        if isinstance(self.klass, six.string_types):
+            self.resolve_class(object, name, value)
+            del self.validate
+
+        return self.validate(object, name, value)
+
+    def info(self):
+        """ Returns a description of the trait.
+        """
+        klass = self.klass
+        if not isinstance(klass, six.string_types):
+            klass = klass.__name__
+
+        result = "a subclass of " + klass
+
+        if self._allow_none:
+            return result + " or None"
+
+        return result
+
+    def get_default_value(self):
+        """ Returns a tuple of the form: ( default_value_type, default_value )
+            which describes the default value for this trait.
+        """
+        if not isinstance(self.default_value, six.string_types):
+            return super(Type, self).get_default_value()
+
+        return (
+            CALLABLE_AND_ARGS_DEFAULT_VALUE,
+            (self.resolve_default_value, (), None),
+        )
+
+    def resolve_default_value(self):
+        """ Resolves a class name into a class so that it can be used to
+            return the class as the default value of the trait.
+        """
+        if isinstance(self.klass, six.string_types):
+            try:
+                self.resolve_class(None, None, None)
+                del self.validate
+            except:
+                raise TraitError(
+                    "Could not resolve %s into a valid class" % self.klass
+                )
+
+        return self.klass
+
+
+# -------------------------------------------------------------------------------
+#  'Event' trait:
+# -------------------------------------------------------------------------------
+
+
+class Event(TraitType):
+    def __init__(self, trait=None, **metadata):
+        metadata["type"] = "event"
+        metadata["transient"] = True
+
+        super(Event, self).__init__(**metadata)
+
+        self.trait = None
+        if trait is not None:
+            self.trait = trait_from(trait)
+            validate = self.trait.get_validate()
+            if validate is not None:
+                self.fast_validate = validate
+
+    def full_info(self, object, name, value):
+        """ Returns a description of the trait.
+        """
+        trait = self.trait
+        if trait is None:
+            return "any value"
+
+        return trait.full_info(object, name, value)
+
+
+#  Handle circular module dependencies:
+trait_handlers.Event = Event
+
+# -------------------------------------------------------------------------------
+#  'Button' trait:
+# -------------------------------------------------------------------------------
+
+
+class Button(Event):
+    """ Defines a trait whose UI editor is a button.
+    """
+
+    def __init__(
+        self,
+        label="",
+        image=None,
+        values_trait=None,
+        style="button",
+        orientation="vertical",
+        width_padding=7,
+        height_padding=5,
+        view=None,
+        **metadata
+    ):
+        """ Returns a trait event whose editor is a button.
+
+            Parameters
+            ----------
+            label : str
+                The label for the button.
+            image : pyface.ImageResource
+                An image to display on the button.
+            style : one of: 'button', 'radio', 'toolbar', 'checkbox'
+                The style of button to display.
+            values_trait : str
+                For a "button" or "toolbar" style, the name of an enum
+                trait whose values will populate a drop-down menu on the button.
+                The selected value will replace the label on the button.
+            orientation : one of: 'horizontal', 'vertical'
+                The orientation of the label relative to the image.
+            width_padding : integer between 0 and 31
+                Extra padding (in pixels) added to the left and right sides of
+                the button.
+            height_padding : integer between 0 and 31
+                Extra padding (in pixels) added to the top and bottom of the
+                button.
+
+            Default Value
+            -------------
+            No default value because events do not store values.
+        """
+        self.label = label
+        self.values_trait = values_trait
+        self.image = image
+        self.style = style
+        self.orientation = orientation
+        self.width_padding = width_padding
+        self.height_padding = height_padding
+        self.view = view
+        super(Button, self).__init__(**metadata)
+
+    def create_editor(self):
+        from traitsui.api import ButtonEditor
+
+        editor = ButtonEditor(
+            label=self.label,
+            values_trait=self.values_trait,
+            image=self.image,
+            style=self.style,
+            orientation=self.orientation,
+            width_padding=self.width_padding,
+            height_padding=self.height_padding,
+            view=self.view,
+        )
+        return editor
+
+
+# -------------------------------------------------------------------------------
+#  'ToolbarButton' trait:
+# -------------------------------------------------------------------------------
+
+
+class ToolbarButton(Button):
+    """ Defines a trait whose UI editor is a button that can be used on a
+        toolbar.
+    """
+
+    def __init__(
+        self,
+        label="",
+        image=None,
+        style="toolbar",
+        orientation="vertical",
+        width_padding=2,
+        height_padding=2,
+        **metadata
+    ):
+        """ Returns a trait event whose editor is a toolbar button.
+
+            Parameters
+            ----------
+            label : str
+                The label for the button
+            image : pyface.ImageResource
+                An image to display on the button
+            style : one of: 'button', 'radio', 'toolbar', 'checkbox'
+                The style of button to display
+            orientation : one of ['horizontal', 'vertical']
+                The orientation of the label relative to the image
+            width_padding : integer between 0 and 31
+                Extra padding (in pixels) added to the left and right sides of
+                the button
+            height_padding : integer between 0 and 31
+                Extra padding (in pixels) added to the top and bottom of the
+                button
+
+            Default Value
+            -------------
+            No default value because events do not store values.
+
+        """
+        super(ToolbarButton, self).__init__(
+            label,
+            image=image,
+            style=style,
+            orientation=orientation,
+            width_padding=width_padding,
+            height_padding=height_padding,
+            **metadata
+        )
+
+
+# -------------------------------------------------------------------------------
+#  'Either' trait:
+# -------------------------------------------------------------------------------
+
+
+class Either(TraitType):
+    """ Defines a trait whose value can be any of of a specified list of traits.
+    """
+
+    def __init__(self, *traits, **metadata):
+        """ Creates a trait whose value can be any of of a specified list of
+            traits.
+        """
+        self.trait_maker = _TraitMaker(
+            metadata.pop("default", None), *traits, **metadata
+        )
+
+    def as_ctrait(self):
+        """ Returns a CTrait corresponding to the trait defined by this class.
+        """
+        return self.trait_maker.as_ctrait()
+
+
+# -------------------------------------------------------------------------------
+#  'Symbol' trait:
+# -------------------------------------------------------------------------------
+
+
+class Symbol(TraitType):
+
+    #: A description of the type of value this trait accepts:
+    info_text = (
+        "an object or a string of the form "
+        "'[package.package...package.]module[:symbol[([arg1,...,argn])]]' "
+        "specifying where to locate the object"
+    )
+
+    def get(self, object, name):
+        value = object.__dict__.get(name, Undefined)
+        if value is Undefined:
+            cache = TraitsCache + name
+            ref = object.__dict__.get(cache)
+            if ref is None:
+                object.__dict__[cache] = ref = object.trait(
+                    name
+                ).default_value_for(object, name)
+
+            if isinstance(ref, six.string_types):
+                object.__dict__[name] = value = self._resolve(ref)
+
+        return value
+
+    def set(self, object, name, value):
+        dict = object.__dict__
+        old = dict.get(name, Undefined)
+        if isinstance(value, six.string_types):
+            dict.pop(name, None)
+            dict[TraitsCache + name] = value
+            object.trait_property_changed(name, old)
+        else:
+            dict[name] = value
+            object.trait_property_changed(name, old, value)
+
+    def _resolve(self, ref):
+        try:
+            path = ref.split(":", 1)
+            module = __import__(path[0])
+            for component in path[0].split(".")[1:]:
+                module = getattr(module, component)
+
+            if len(path) == 1:
+                return module
+
+            elements = path[1].split("(", 1)
+            symbol = getattr(module, elements[0])
+            if len(elements) == 1:
+                return symbol
+
+            args = eval("(" + elements[1])
+            if not isinstance(args, tuple):
+                args = (args,)
+
+            return symbol(*args)
+        except:
+            raise TraitError(
+                "Could not resolve '%s' into a valid symbol." % ref
+            )
+
+
+# ---------------------------------------------------------------------------
+#  'UUID' trait:
+# ---------------------------------------------------------------------------
+
+class UUID(TraitType):
+    """ Defines a trait whose value is a globally unique UUID (type 4).
+
+    Passing `can_init=True` allows the UUID value to be set during
+    object instantiation, e.g.::
+
+        class A(HasTraits):
+            id = UUID
+
+        class B(HasTraits):
+            id = UUID(can_init=True)
+
+        # TraitError!
+        A(id=uuid.uuid4())
+
+        # Okay!
+        B(id=uuid.uuid4())
+
+    Note however that in both cases, the UUID trait is set automatically
+    to a `uuid.UUID` instance (assuming none is provided during initialization
+    in the latter case).
+    """
+
+    #: A description of the type of value this trait accepts:
+    info_text = "a read-only UUID"
+
+    def __init__(self, can_init=False, **metadata):
+        """ Returns a UUID trait.
+        """
+        super(UUID, self).__init__(None, **metadata)
+        self.can_init = can_init
+
+    def validate(self, object, name, value):
+        """ Raises an error, since no values can be assigned to the trait.
+        """
+        if not self.can_init:
+            raise TraitError(
+                "The '%s' trait of %s instance is a read-only "
+                "UUID." % (name, class_of(object))
+            )
+
+        if object.traits_inited():
+            msg = ("Initializable UUID trait is read-only "
+                   "after initialization")
+            raise TraitError(msg)
+
+        if isinstance(value, uuid.UUID):
+            return value
+
+        try:
+            # Construct the UUID from a string
+            return uuid.UUID(value)
+        except ValueError:
+            msg = ("The '{}' trait of '{}' expects an RFC 4122-compatible "
+                   "UUID value, but '{}' was given")
+            raise TraitError(msg.format(name, type(object).__name__, value))
+
+    def get_default_value(self):
+        return (
+            CALLABLE_AND_ARGS_DEFAULT_VALUE,
+            (self._create_uuid, (), None),
+        )
+
+    # -- Private Methods ---------------------------------------------------
+
+    def _create_uuid(self):
+        return uuid.uuid4()
+
+
+# -------------------------------------------------------------------------------
+#  'WeakRef' trait:
+# -------------------------------------------------------------------------------
+
+
+class WeakRef(Instance):
+    """ Returns a trait whose value must be an instance of the same type
+    (or a subclass) of the specified *klass*, which can be a class or an
+    instance. Note that the trait only maintains a weak reference to the
+    assigned value.
+    """
+
+    def __init__(
+        self,
+        klass="traits.has_traits.HasTraits",
+        allow_none=False,
+        adapt="yes",
+        **metadata
+    ):
+        """ Returns a WeakRef trait.
+
+        Only a weak reference is maintained to any object assigned to a WeakRef
+        trait. If no other references exist to the assigned value, the value
+        may be garbage collected, in which case the value of the trait becomes
+        None. In all other cases, the value returned by the trait is the
+        original object.
+
+        Parameters
+        ----------
+        klass : class or instance
+            The object that forms the basis for the trait. If *klass* is
+            omitted, then values must be an instance of HasTraits.
+        allow_none : boolean
+            Indicates whether None can be assigned.
+
+        Default Value
+        -------------
+        **None** (even if allow_none==False)
+        """
+
+        metadata.setdefault("copy", "ref")
+
+        super(WeakRef, self).__init__(
+            klass,
+            allow_none=allow_none,
+            adapt=adapt,
+            module=get_module_name(),
+            **metadata
+        )
+
+    def get(self, object, name):
+        value = getattr(object, name + "_", None)
+        if value is not None:
+            return value.value()
+
+        return None
+
+    def set(self, object, name, value):
+        old = self.get(object, name)
+
+        if value is None:
+            object.__dict__[name + "_"] = None
+        else:
+            object.__dict__[name + "_"] = HandleWeakRef(object, name, value)
+
+        if value is not old:
+            object.trait_property_changed(name, old, value)
+
+    def resolve_class(self, object, name, value):
+        # fixme: We have to override this method to prevent the 'fast validate'
+        # from being set up, since the trait using this is a 'property' style
+        # trait which is not currently compatible with the 'fast_validate'
+        # style (causes internal Python SystemError messages).
+        klass = self.find_class(self.klass)
+        if klass is None:
+            self.validate_failed(object, name, value)
+
+        self.klass = klass
+
+
+# -- Date Trait definition ----------------------------------------------------
+Date = BaseInstance(datetime.date, editor=date_editor)
+
+
+# -- Time Trait definition ----------------------------------------------------
+Time = BaseInstance(datetime.time, editor=time_editor)
+
+
+# -------------------------------------------------------------------------------
+#  Create predefined, reusable trait instances:
+# -------------------------------------------------------------------------------
+
+# Synonym for Bool; default value is False.
+false = Bool
+
+# Boolean values only; default value is True.
+true = Bool(True)
+
+# Allows any value to be assigned; no type-checking is performed.
+# Default value is Undefined.
+undefined = Any(Undefined)
+
+# -- List Traits ----------------------------------------------------------------
+
+#: List of integer values; default value is [].
+ListInt = List(int)
+
+#: List of float values; default value is [].
+ListFloat = List(float)
+
+#: List of string values; default value is [].
+ListStr = List(str)
+
+#: List of Unicode string values; default value is [].
+ListUnicode = List(six.text_type)
+
+#: List of complex values; default value is [].
+ListComplex = List(complex)
+
+#: List of Boolean values; default value is [].
+ListBool = List(bool)
+
+#: List of function values; default value is [].
+ListFunction = List(FunctionType)
+
+#: List of method values; default value is [].
+ListMethod = List(MethodType)
+
+if six.PY2:
+    from types import ClassType, InstanceType
+
+    #: List of class values; default value is [].
+    ListClass = List(ClassType)
+
+    #: List of instance values; default value is [].
+    ListInstance = List(InstanceType)
+
+#: List of container type values; default value is [].
+ListThis = List(ThisClass)
+
+# -- Dictionary Traits ----------------------------------------------------------
+
+#: Only a dictionary of string:Any values can be assigned; only string keys can
+#: be inserted. The default value is {}.
+DictStrAny = Dict(str, Any)
+
+#: Only a dictionary of string:string values can be assigned; only string keys
+#: with string values can be inserted. The default value is {}.
+DictStrStr = Dict(str, str)
+
+#: Only a dictionary of string:integer values can be assigned; only string keys
+#: with integer values can be inserted. The default value is {}.
+DictStrInt = Dict(str, int)
+
+#: Only a dictionary of string:long-integer values can be assigned; only string
+#: keys with long-integer values can be inserted. The default value is {}.
+DictStrLong = Dict(str, LONG_TYPE)
+
+#: Only a dictionary of string:float values can be assigned; only string keys
+#: with float values can be inserted. The default value is {}.
+DictStrFloat = Dict(str, float)
+
+#: Only a dictionary of string:bool values can be assigned; only string keys
+#: with boolean values can be inserted. The default value is {}.
+DictStrBool = Dict(str, bool)
+
+#: Only a dictionary of string:list values can be assigned; only string keys
+#: with list values can be assigned. The default value is {}.
+DictStrList = Dict(str, list)
+
+ +
+
+
+
+
+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/4.5/_modules/traits/traits.html b/4.5/_modules/traits/traits.html new file mode 100644 index 000000000..344be21b4 --- /dev/null +++ b/4.5/_modules/traits/traits.html @@ -0,0 +1,1596 @@ + + + + + + + traits.traits — Apptools Documentation + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +

Source code for traits.traits

+# ------------------------------------------------------------------------------
+#
+#  Copyright (c) 2005, Enthought, Inc.
+#  All rights reserved.
+#
+#  This software is provided without warranty under the terms of the BSD
+#  license included in enthought/LICENSE.txt and may be redistributed only
+#  under the conditions described in the aforementioned license.  The license
+#  is also available online at http://www.enthought.com/licenses/BSD.txt
+#
+#  Thanks for using Enthought open source!
+#
+#  Author:        David C. Morrill
+#  Original Date: 06/21/2002
+#
+#  Rewritten as a C-based type extension: 06/21/2004
+#
+# ------------------------------------------------------------------------------
+
+"""
+Defines the 'core' traits for the Traits package. A trait is a type definition
+that can be used for normal Python object attributes, giving the attributes
+some additional characteristics:
+
+Initialization:
+    Traits have predefined values that do not need to be explicitly
+    initialized in the class constructor or elsewhere.
+Validation:
+    Trait attributes have flexible, type-checked values.
+Delegation:
+    Trait attributes' values can be delegated to other objects.
+Notification:
+    Trait attributes can automatically notify interested parties when
+    their values change.
+Visualization:
+    Trait attributes can automatically construct (automatic or
+    programmer-defined) user interfaces that allow their values to be
+    edited or displayed)
+
+.. note:: 'trait' is a synonym for 'property', but is used instead of the
+    word 'property' to differentiate it from the Python language 'property'
+    feature.
+"""
+
+# -------------------------------------------------------------------------------
+#  Imports:
+# -------------------------------------------------------------------------------
+
+from __future__ import absolute_import
+
+import sys
+from types import FunctionType, MethodType
+
+import six
+
+NoneType = type(None)  # Python 3's types does not include NoneType
+
+from . import trait_handlers
+from .ctraits import cTrait
+from .trait_errors import TraitError
+from .trait_base import (
+    SequenceTypes,
+    Self,
+    Undefined,
+    Missing,
+    TypeTypes,
+    add_article,
+)
+
+from .trait_handlers import (
+    TraitHandler,
+    TraitInstance,
+    TraitFunction,
+    TraitCoerceType,
+    TraitCastType,
+    TraitEnum,
+    TraitCompound,
+    TraitMap,
+    TraitString,
+    ThisClass,
+    TraitType,
+    _arg_count,
+    _read_only,
+    _write_only,
+    _undefined_get,
+    _undefined_set,
+    UNSPECIFIED_DEFAULT_VALUE,
+    CALLABLE_AND_ARGS_DEFAULT_VALUE,
+)
+
+
+from ._py2to3 import LONG_TYPE
+
+# -------------------------------------------------------------------------------
+#  Constants:
+# -------------------------------------------------------------------------------
+
+# Mapping from 'ctrait' default value types to a string representation:
+KindMap = {
+    0: "value",
+    1: "value",
+    2: "self",
+    3: "list",
+    4: "dict",
+    5: "list",
+    6: "dict",
+    7: "factory",
+    8: "method",
+}
+
+# -------------------------------------------------------------------------------
+#  Editor factory functions:
+# -------------------------------------------------------------------------------
+
+PasswordEditor = None
+MultilineTextEditors = {}
+BytesEditors = {}
+SourceCodeEditor = None
+HTMLTextEditor = None
+PythonShellEditor = None
+DateEditor = None
+TimeEditor = None
+
+
+def password_editor(auto_set=True, enter_set=False):
+    """ Factory function that returns an editor for passwords.
+    """
+    global PasswordEditor
+
+    if PasswordEditor is None:
+        from traitsui.api import TextEditor
+
+        PasswordEditor = TextEditor(
+            password=True, auto_set=auto_set, enter_set=enter_set
+        )
+
+    return PasswordEditor
+
+
+def multi_line_text_editor(auto_set=True, enter_set=False):
+    """ Factory function that returns a text editor for multi-line strings.
+    """
+    if (auto_set, enter_set) not in MultilineTextEditors:
+        from traitsui.api import TextEditor
+
+        MultilineTextEditors[auto_set, enter_set] = TextEditor(
+            multi_line=True, auto_set=auto_set, enter_set=enter_set
+        )
+
+    return MultilineTextEditors[auto_set, enter_set]
+
+
+def bytes_editor(auto_set=True, enter_set=False, encoding=None):
+    """ Factory function that returns a text editor for bytes.
+    """
+    if encoding is not None:
+        if isinstance(encoding, str):
+            import codecs
+
+            encoding = codecs.lookup(encoding)
+
+    if (auto_set, enter_set, encoding) not in BytesEditors:
+        from traitsui.api import TextEditor
+
+        if encoding is None:
+            # py3-compatible bytes <-> hex unicode string
+            format = lambda b: b.encode("hex").decode("ascii")
+            evaluate = lambda s: s.encode("ascii").decode("hex")
+        else:
+            format = encoding.decode
+            evaluate = encoding.encode
+
+        BytesEditors[(auto_set, enter_set, encoding)] = TextEditor(
+            multi_line=True,
+            format_func=format,
+            evaluate=evaluate,
+            auto_set=auto_set,
+            enter_set=enter_set,
+        )
+
+    return BytesEditors[(auto_set, enter_set, encoding)]
+
+
+def code_editor():
+    """ Factory function that returns an editor that treats a multi-line string
+    as source code.
+    """
+    global SourceCodeEditor
+
+    if SourceCodeEditor is None:
+        from traitsui.api import CodeEditor
+
+        SourceCodeEditor = CodeEditor()
+
+    return SourceCodeEditor
+
+
+def html_editor():
+    """ Factory function for an "editor" that displays a multi-line string as
+    interpreted HTML.
+    """
+    global HTMLTextEditor
+
+    if HTMLTextEditor is None:
+        from traitsui.api import HTMLEditor
+
+        HTMLTextEditor = HTMLEditor()
+
+    return HTMLTextEditor
+
+
+def shell_editor():
+    """ Factory function that returns a Python shell for editing Python values.
+    """
+    global PythonShellEditor
+
+    if PythonShellEditor is None:
+        from traitsui.api import ShellEditor
+
+        PythonShellEditor = ShellEditor()
+
+    return PythonShellEditor
+
+
+def time_editor():
+    """ Factory function that returns a Time editor for editing Time values.
+    """
+    global TimeEditor
+
+    if TimeEditor is None:
+        from traitsui.api import TimeEditor
+
+        TimeEditor = TimeEditor()
+
+    return TimeEditor
+
+
+def date_editor():
+    """ Factory function that returns a Date editor for editing Date values.
+    """
+    global DateEditor
+
+    if DateEditor is None:
+        from traitsui.api import DateEditor
+
+        DateEditor = DateEditor()
+
+    return DateEditor
+
+
+def _expects_hastraits_instance(handler):
+    """ Does a trait handler or type expect a HasTraits subclass instance?
+    """
+    from traits.api import HasTraits, BaseInstance, TraitInstance
+
+    if isinstance(handler, TraitInstance):
+        cls = handler.aClass
+    elif isinstance(handler, BaseInstance):
+        cls = handler.klass
+    else:
+        return False
+    return issubclass(cls, HasTraits)
+
+
+def _instance_handler_factory(handler):
+    """ Get the instance factory of an Instance or TraitInstance
+    """
+    from traits.api import BaseInstance, TraitInstance
+
+    if isinstance(handler, TraitInstance):
+        return handler.aClass
+    elif isinstance(handler, BaseInstance):
+        return handler.default_value
+    else:
+        msg = "handler should be TraitInstance or BaseInstance, but got {}"
+        raise ValueError(msg.format(repr(handler)))
+
+
+def list_editor(trait, handler):
+    """ Factory that constructs an appropriate editor for a list.
+    """
+    item_handler = handler.item_trait.handler
+    if _expects_hastraits_instance(item_handler):
+        from traitsui.table_column import ObjectColumn
+        from traitsui.table_filter import (
+            EvalFilterTemplate,
+            RuleFilterTemplate,
+            MenuFilterTemplate,
+            EvalTableFilter,
+        )
+        from traitsui.api import TableEditor
+
+        return TableEditor(
+            filters=[
+                RuleFilterTemplate,
+                MenuFilterTemplate,
+                EvalFilterTemplate,
+            ],
+            edit_view="",
+            orientation="vertical",
+            search=EvalTableFilter(),
+            deletable=True,
+            show_toolbar=True,
+            reorderable=True,
+            row_factory=_instance_handler_factory(item_handler),
+        )
+    else:
+        from traitsui.api import ListEditor
+
+        return ListEditor(
+            trait_handler=handler,
+            rows=trait.rows if trait.rows else 5,
+            use_notebook=bool(trait.use_notebook),
+            page_name=trait.page_name if trait.page_name else "",
+        )
+
+
+# -------------------------------------------------------------------------------
+#  'CTrait' class (extends the underlying cTrait c-based type):
+# -------------------------------------------------------------------------------
+
+
+class CTrait(cTrait):
+    """ Extends the underlying C-based cTrait type.
+    """
+
+    # ---------------------------------------------------------------------------
+    #  Allows a derivative trait to be defined from this one:
+    # ---------------------------------------------------------------------------
+
+    def __call__(self, *args, **metadata):
+        handler = self.handler
+        if isinstance(handler, TraitType):
+            dict = (self.__dict__ or {}).copy()
+            dict.update(metadata)
+
+            return handler(*args, **dict)
+
+        metadata.setdefault("parent", self)
+        return Trait(*(args + (self,)), **metadata)
+
+    # ---------------------------------------------------------------------------
+    #  (Python) property definitions:
+    # ---------------------------------------------------------------------------
+
+    def __get_default(self):
+        kind, value = self.default_value()
+        if kind in (2, 7, 8):
+            return Undefined
+
+        if kind in (4, 6):
+            return value.copy()
+
+        if kind in (3, 5):
+            return value[:]
+
+        return value
+
+    default = property(__get_default)
+
+    def __get_default_kind(self):
+        return KindMap[self.default_value()[0]]
+
+    default_kind = property(__get_default_kind)
+
+    def __get_trait_type(self):
+        handler = self.handler
+        if handler is not None:
+            return handler
+        else:
+            from .trait_types import Any
+
+            return Any
+
+    trait_type = property(__get_trait_type)
+
+    def __get_inner_traits(self):
+        handler = self.handler
+        if handler is not None:
+            return handler.inner_traits()
+
+        return ()
+
+    inner_traits = property(__get_inner_traits)
+
+    # ---------------------------------------------------------------------------
+    #  Returns whether or not this trait is of a specified trait type:
+    # ---------------------------------------------------------------------------
+
+    def is_trait_type(self, trait_type):
+        """ Returns whether or not this trait is of a specified trait type.
+        """
+        return isinstance(self.trait_type, trait_type)
+
+    # ---------------------------------------------------------------------------
+    #  Returns the user interface editor associated with the trait:
+    # ---------------------------------------------------------------------------
+
+    def get_editor(self):
+        """ Returns the user interface editor associated with the trait.
+        """
+        from traitsui.api import EditorFactory
+
+        # See if we have an editor:
+        editor = self.editor
+        if editor is None:
+
+            # Else see if the trait handler has an editor:
+            handler = self.handler
+            if handler is not None:
+                editor = handler.get_editor(self)
+
+            # If not, give up and use a default text editor:
+            if editor is None:
+                from traitsui.api import TextEditor
+
+                editor = TextEditor
+
+        # If the result is not an EditorFactory:
+        if not isinstance(editor, EditorFactory):
+            # Then it should be a factory for creating them:
+            args = ()
+            traits = {}
+            if type(editor) in SequenceTypes:
+                for item in editor[:]:
+                    if type(item) in SequenceTypes:
+                        args = tuple(item)
+                    elif isinstance(item, dict):
+                        traits = item
+                        if traits.get("trait", 0) is None:
+                            traits = traits.copy()
+                            traits["trait"] = self
+                    else:
+                        editor = item
+            editor = editor(*args, **traits)
+
+        # Cache the result:
+        self.editor = editor
+
+        # Return the resulting EditorFactory object:
+        return editor
+
+    # ---------------------------------------------------------------------------
+    #  Returns the help text for a trait:
+    # ---------------------------------------------------------------------------
+
+    def get_help(self, full=True):
+        """ Returns the help text for a trait.
+
+        Parameters
+        ----------
+        full : bool
+            Indicates whether to return the value of the *help* attribute of
+            the trait itself.
+
+        Description
+        -----------
+        If *full* is False or the trait does not have a **help** string,
+        the returned string is constructed from the **desc** attribute on the
+        trait and the **info** string on the trait's handler.
+        """
+        if full:
+            help = self.help
+            if help is not None:
+                return help
+
+        handler = self.handler
+        if handler is not None:
+            info = "must be %s." % handler.info()
+        else:
+            info = "may be any value."
+
+        desc = self.desc
+        if self.desc is None:
+            return info.capitalize()
+
+        return "Specifies %s and %s" % (desc, info)
+
+    # ---------------------------------------------------------------------------
+    #  Returns a description of the trait:
+    # ---------------------------------------------------------------------------
+
+    def full_info(self, object, name, value):
+        """ Returns a description of the trait.
+        """
+        handler = self.handler
+        if handler is not None:
+            return handler.full_info(object, name, value)
+
+        return "any value"
+
+    # ---------------------------------------------------------------------------
+    #  Returns a description of the trait:
+    # ---------------------------------------------------------------------------
+
+    def info(self):
+        """ Returns a description of the trait.
+        """
+        handler = self.handler
+        if handler is not None:
+            return handler.info()
+
+        return "any value"
+
+    # ---------------------------------------------------------------------------
+    #  Returns the pickleable form of a CTrait object:
+    # ---------------------------------------------------------------------------
+
+    def __reduce_ex__(self, protocol):
+        return (__newobj__, (self.__class__, 0), self.__getstate__())
+
+    # ---------------------------------------------------------------------------
+    #  Registers listeners on an assigned 'TraitValue' object's 'value'
+    #  property:
+    # ---------------------------------------------------------------------------
+
+    def _register(self, object, name):
+        """ Registers listeners on an assigned 'TraitValue' object's 'value'
+            property.
+        """
+
+        def handler():
+            object.trait_property_changed(name, None)
+
+        tv = self._trait_value
+        handlers = tv._handlers
+        if handlers is None:
+            tv._handlers = handlers = {}
+        handlers[(id(object), name)] = handler
+
+        tv.on_trait_change(handler, "value")
+
+    # ---------------------------------------------------------------------------
+    #  Unregisters listeners on an assigned 'TraitValue' object's 'value'
+    #  property:
+    # ---------------------------------------------------------------------------
+
+    def _unregister(self, object, name):
+        """ Unregisters listeners on an assigned 'TraitValue' object's 'value'
+            property.
+        """
+        tv = self._trait_value
+        handlers = tv._handlers
+        key = (id(object), name)
+        handler = handlers.get(key)
+        if handler is not None:
+            del handlers[key]
+            tv.on_trait_change(handler, "value", remove=True)
+
+
+# Make sure the Python-level version of the trait class is known to all
+# interested parties:
+from . import ctraits
+
+ctraits._ctrait(CTrait)
+
+# -------------------------------------------------------------------------------
+#  Constants:
+# -------------------------------------------------------------------------------
+
+ConstantTypes = (NoneType, int, LONG_TYPE, float, complex, str, six.text_type)
+
+PythonTypes = (
+    str,
+    six.text_type,
+    int,
+    LONG_TYPE,
+    float,
+    complex,
+    list,
+    tuple,
+    dict,
+    FunctionType,
+    MethodType,
+    type,
+    NoneType,
+)
+
+if six.PY2:
+    from types import InstanceType, ClassType
+
+    PythonTypes = (
+        PythonTypes[:-2] + (InstanceType, ClassType) + PythonTypes[2:]
+    )
+
+
+CallableTypes = (FunctionType, MethodType)
+
+TraitTypes = (TraitHandler, CTrait)
+
+DefaultValues = {
+    str: "",
+    six.text_type: "",
+    int: 0,
+    LONG_TYPE: LONG_TYPE(0),
+    float: 0.0,
+    complex: 0j,
+    list: [],
+    tuple: (),
+    dict: {},
+    bool: False,
+}
+
+DefaultValueSpecial = [Missing, Self]
+DefaultValueTypes = [list, dict]
+
+# -------------------------------------------------------------------------------
+#  Function used to unpickle new-style objects:
+# -------------------------------------------------------------------------------
+
+
+def __newobj__(cls, *args):
+    """ Unpickles new-style objects.
+    """
+    return cls.__new__(cls, *args)
+
+
+# -------------------------------------------------------------------------------
+#  Returns the type of default value specified:
+# -------------------------------------------------------------------------------
+
+
+def _default_value_type(default_value):
+    try:
+        return DefaultValueSpecial.index(default_value) + 1
+    except:
+        try:
+            return DefaultValueTypes.index(type(default_value)) + 3
+        except:
+            return 0
+
+
+# -------------------------------------------------------------------------------
+#  'TraitFactory' class:
+# -------------------------------------------------------------------------------
+
+
+class TraitFactory(object):
+    ### Need a docstring here.
+
+    # ---------------------------------------------------------------------------
+    #  Initializes the object:
+    # ---------------------------------------------------------------------------
+
+    def __init__(self, maker_function=None):
+        if maker_function is not None:
+            self.maker_function = maker_function
+            self.__doc__ = maker_function.__doc__
+
+    # ---------------------------------------------------------------------------
+    #  Creates a CTrait instance:
+    # ---------------------------------------------------------------------------
+
+    def __call__(self, *args, **metadata):
+        return self.maker_function(*args, **metadata)
+
+
+class TraitImportError(TraitFactory):
+    """ Defines a factory class for deferring import problems until encountering
+        code that actually tries to use the unimportable trait.
+    """
+
+    # ---------------------------------------------------------------------------
+    #  Initializes the object:
+    # ---------------------------------------------------------------------------
+
+    def __init__(self, message):
+        self.message = message
+
+    # ---------------------------------------------------------------------------
+    #  Creates a CTrait instance:
+    # ---------------------------------------------------------------------------
+
+    def __call__(self, *args, **metadata):
+        raise TraitError(self.message)
+
+
+# -------------------------------------------------------------------------------
+#  Returns a trait created from a TraitFactory instance:
+# -------------------------------------------------------------------------------
+
+_trait_factory_instances = {}
+
+
+def trait_factory(trait):
+    global _trait_factory_instances
+
+    tid = id(trait)
+    if tid not in _trait_factory_instances:
+        _trait_factory_instances[tid] = trait()
+
+    return _trait_factory_instances[tid]
+
+
+# -------------------------------------------------------------------------------
+#  Casts a CTrait or TraitFactory to a CTrait but returns None if it is neither:
+# -------------------------------------------------------------------------------
+
+
+def trait_cast(something):
+    """ Casts a CTrait, TraitFactory or TraitType to a CTrait but returns None
+        if it is none of those.
+    """
+    if isinstance(something, CTrait):
+        return something
+
+    if isinstance(something, TraitFactory):
+        return trait_factory(something)
+
+    if isinstance(something, type) and issubclass(something, TraitType):
+        return something().as_ctrait()
+
+    if isinstance(something, TraitType):
+        return something.as_ctrait()
+
+    return None
+
+
+# -------------------------------------------------------------------------------
+#  Attempts to cast a value to a trait. Returns either a trait or the original
+#  value:
+# -------------------------------------------------------------------------------
+
+
+def try_trait_cast(something):
+    """ Attempts to cast a value to a trait. Returns either a trait or the
+        original value.
+    """
+    return trait_cast(something) or something
+
+
+# -------------------------------------------------------------------------------
+#  Returns a trait derived from its input:
+# -------------------------------------------------------------------------------
+
+
+def trait_from(something):
+    """ Returns a trait derived from its input.
+    """
+    from .trait_types import Any
+
+    if isinstance(something, CTrait):
+        return something
+
+    if something is None:
+        something = Any
+
+    if isinstance(something, TraitFactory):
+        return trait_factory(something)
+
+    if isinstance(something, type) and issubclass(something, TraitType):
+        return something().as_ctrait()
+
+    if isinstance(something, TraitType):
+        return something.as_ctrait()
+
+    return Trait(something)
+
+
+# Patch the reference to 'trait_from' in 'trait_handlers.py':
+trait_handlers.trait_from = trait_from
+
+# --- 'instance' traits ---------------------------------------------------------
+
+
+class _InstanceArgs(object):
+    def __init__(self, factory, args, kw):
+        self.args = (factory,) + args
+        self.kw = kw
+
+
+# --- 'creates a run-time default value' ----------------------------------------
+
+
+class Default(object):
+    """ Generates a value the first time it is accessed.
+
+    A Default object can be used anywhere a default trait value would normally
+    be specified, to generate a default value dynamically.
+    """
+
+    def __init__(self, func=None, args=(), kw=None):
+        self.default_value = (func, args, kw)
+
+
+# -------------------------------------------------------------------------------
+#  Factory function for creating C-based traits:
+# -------------------------------------------------------------------------------
+
+
+def Trait(*value_type, **metadata):
+    """ Creates a trait definition.
+
+    Parameters
+    ----------
+    This function accepts a variety of forms of parameter lists:
+
+    +-------------------+---------------+-------------------------------------+
+    | Format            | Example       | Description                         |
+    +===================+===============+=====================================+
+    | Trait(*default*)  | Trait(150.0)  | The type of the trait is inferred   |
+    |                   |               | from the type of the default value, |
+    |                   |               | which must be in *ConstantTypes*.   |
+    +-------------------+---------------+-------------------------------------+
+    | Trait(*default*,  | Trait(None,   | The trait accepts any of the        |
+    | *other1*,         | 0, 1, 2,      | enumerated values, with the first   |
+    | *other2*, ...)    | 'many')       | value being the default value. The  |
+    |                   |               | values must be of types in          |
+    |                   |               | *ConstantTypes*, but they need not  |
+    |                   |               | be of the same type. The *default*  |
+    |                   |               | value is not valid for assignment   |
+    |                   |               | unless it is repeated later in the  |
+    |                   |               | list.                               |
+    +-------------------+---------------+-------------------------------------+
+    | Trait([*default*, | Trait([None,  | Similar to the previous format, but |
+    | *other1*,         | 0, 1, 2,      | takes an explicit list or a list    |
+    | *other2*, ...])   | 'many'])      | variable.                           |
+    +-------------------+---------------+-------------------------------------+
+    | Trait(*type*)     | Trait(Int)    | The *type* parameter must be a name |
+    |                   |               | of a Python type (see               |
+    |                   |               | *PythonTypes*). Assigned values     |
+    |                   |               | must be of exactly the specified    |
+    |                   |               | type; no casting or coercion is     |
+    |                   |               | performed. The default value is the |
+    |                   |               | appropriate form of zero, False,    |
+    |                   |               | or emtpy string, set or sequence.   |
+    +-------------------+---------------+-------------------------------------+
+    | Trait(*class*)    |::             | Values must be instances of *class* |
+    |                   |               | or of a subclass of *class*. The    |
+    |                   | class MyClass:| default value is None, but None     |
+    |                   |    pass       | cannot be assigned as a value.      |
+    |                   | foo = Trait(  |                                     |
+    |                   | MyClass)      |                                     |
+    +-------------------+---------------+-------------------------------------+
+    | Trait(None,       |::             | Similar to the previous format, but |
+    | *class*)          |               | None *can* be assigned as a value.  |
+    |                   | class MyClass:|                                     |
+    |                   |   pass        |                                     |
+    |                   | foo = Trait(  |                                     |
+    |                   | None, MyClass)|                                     |
+    +-------------------+---------------+-------------------------------------+
+    | Trait(*instance*) |::             | Values must be instances of the     |
+    |                   |               | same class as *instance*, or of a   |
+    |                   | class MyClass:| subclass of that class. The         |
+    |                   |    pass       | specified instance is the default   |
+    |                   | i = MyClass() | value.                              |
+    |                   | foo =         |                                     |
+    |                   |   Trait(i)    |                                     |
+    +-------------------+---------------+-------------------------------------+
+    | Trait(*handler*)  | Trait(        | Assignment to this trait is         |
+    |                   | TraitEnum )   | validated by an object derived from |
+    |                   |               | **traits.TraitHandler**.            |
+    +-------------------+---------------+-------------------------------------+
+    | Trait(*default*,  | Trait(0.0, 0.0| This is the most general form of    |
+    | { *type* |        | 'stuff',      | the function. The notation:         |
+    | *constant* |      | TupleType)    | ``{...|...|...}+`` means a list of  |
+    | *dict* | *class* ||               | one or more of any of the items     |
+    | *function* |      |               | listed between the braces. Thus, the|
+    | *handler* |       |               | most general form of the function   |
+    | *trait* }+ )      |               | consists of a default value,        |
+    |                   |               | followed by one or more of several  |
+    |                   |               | possible items. A trait defined by  |
+    |                   |               | multiple items is called a          |
+    |                   |               | "compound" trait.                   |
+    +-------------------+---------------+-------------------------------------+
+
+    All forms of the Trait function accept both predefined and arbitrary
+    keyword arguments. The value of each keyword argument becomes bound to the
+    resulting trait object as the value of an attribute having the same name
+    as the keyword. This feature lets you associate metadata with a trait.
+
+    The following predefined keywords are accepted:
+
+    Keywords
+    --------
+    desc : str
+        Describes the intended meaning of the trait. It is used in
+        exception messages and fly-over help in user interfaces.
+    label : str
+        Provides a human-readable name for the trait. It is used to label user
+        interface editors for traits.
+    editor : traits.api.Editor
+        Instance of a subclass Editor object to use when creating a user
+        interface editor for the trait. See the "Traits UI User Guide" for
+        more information on trait editors.
+    comparison_mode : int
+        Indicates when trait change notifications should be generated based upon
+        the result of comparing the old and new values of a trait assignment:
+
+        * 0 (NO_COMPARE): The values are not compared and a trait change
+          notification is generated on each assignment.
+        * 1 (OBJECT_IDENTITY_COMPARE): A trait change notification is
+          generated if the old and new values are not the same object.
+        * 2 (RICH_COMPARE): A trait change notification is generated if the
+          old and new values are not equal using Python's
+          'rich comparison' operator. This is the default.
+
+    rich_compare : bool
+        Indicates whether the basis for considering a trait attribute value to
+        have changed is a "rich" comparison (True, the default), or simple
+        object identity (False). This attribute can be useful in cases
+        where a detailed comparison of two objects is very expensive, or where
+        you do not care whether the details of an object change, as long as the
+        same object is used.
+
+            .. deprecated:: 3.0.3
+                Use ``comparison_mode`` instead
+
+
+    """
+    return _TraitMaker(*value_type, **metadata).as_ctrait()
+
+
+#  Handle circular module dependencies:
+trait_handlers.Trait = Trait
+
+# -------------------------------------------------------------------------------
+#  '_TraitMaker' class:
+# -------------------------------------------------------------------------------
+
+
+class _TraitMaker(object):
+
+    # Ctrait type map for special trait types:
+    type_map = {"event": 2, "constant": 7}
+
+    # ---------------------------------------------------------------------------
+    #  Initialize the object:
+    # ---------------------------------------------------------------------------
+
+    def __init__(self, *value_type, **metadata):
+        metadata.setdefault("type", "trait")
+        self.define(*value_type, **metadata)
+
+    # ---------------------------------------------------------------------------
+    #  Define the trait:
+    # ---------------------------------------------------------------------------
+
+    def define(self, *value_type, **metadata):
+        default_value_type = UNSPECIFIED_DEFAULT_VALUE
+        default_value = handler = clone = None
+
+        if len(value_type) > 0:
+            default_value = value_type[0]
+            value_type = value_type[1:]
+
+            if (len(value_type) == 0) and (
+                type(default_value) in SequenceTypes
+            ):
+                default_value, value_type = default_value[0], default_value
+
+            if len(value_type) == 0:
+                default_value = try_trait_cast(default_value)
+
+                if default_value in PythonTypes:
+                    handler = TraitCoerceType(default_value)
+                    default_value = DefaultValues.get(default_value)
+
+                elif isinstance(default_value, CTrait):
+                    clone = default_value
+                    default_value_type, default_value = clone.default_value()
+                    metadata["type"] = clone.type
+
+                elif isinstance(default_value, TraitHandler):
+                    handler = default_value
+                    default_value = None
+
+                elif default_value is ThisClass:
+                    handler = ThisClass()
+                    default_value = None
+
+                else:
+                    typeValue = type(default_value)
+
+                    if isinstance(default_value, six.string_types):
+                        string_options = self.extract(
+                            metadata, "min_len", "max_len", "regex"
+                        )
+                        if len(string_options) == 0:
+                            handler = TraitCastType(typeValue)
+                        else:
+                            handler = TraitString(**string_options)
+
+                    elif typeValue in TypeTypes:
+                        handler = TraitCastType(typeValue)
+
+                    else:
+                        metadata.setdefault(
+                            "instance_handler", "_instance_changed_handler"
+                        )
+                        handler = TraitInstance(default_value)
+                        if default_value is handler.aClass:
+                            default_value = DefaultValues.get(default_value)
+            else:
+                enum = []
+                other = []
+                map = {}
+                self.do_list(value_type, enum, map, other)
+
+                if ((len(enum) == 1) and (enum[0] is None)) and (
+                    (len(other) == 1) and isinstance(other[0], TraitInstance)
+                ):
+                    enum = []
+                    other[0].allow_none()
+                    metadata.setdefault(
+                        "instance_handler", "_instance_changed_handler"
+                    )
+                if len(enum) > 0:
+                    if ((len(map) + len(other)) == 0) and (
+                        default_value not in enum
+                    ):
+                        enum.insert(0, default_value)
+
+                    other.append(TraitEnum(enum))
+
+                if len(map) > 0:
+                    other.append(TraitMap(map))
+
+                if len(other) == 0:
+                    handler = TraitHandler()
+
+                elif len(other) == 1:
+                    handler = other[0]
+                    if isinstance(handler, CTrait):
+                        clone, handler = handler, None
+                        metadata["type"] = clone.type
+
+                    elif isinstance(handler, TraitInstance):
+                        metadata.setdefault(
+                            "instance_handler", "_instance_changed_handler"
+                        )
+
+                        if default_value is None:
+                            handler.allow_none()
+
+                        elif isinstance(default_value, _InstanceArgs):
+                            default_value_type = (
+                                CALLABLE_AND_ARGS_DEFAULT_VALUE
+                            )
+                            default_value = (
+                                handler.create_default_value,
+                                default_value.args,
+                                default_value.kw,
+                            )
+
+                        elif (len(enum) == 0) and (len(map) == 0):
+                            aClass = handler.aClass
+                            typeValue = type(default_value)
+
+                            if typeValue is dict:
+                                default_value_type = (
+                                    CALLABLE_AND_ARGS_DEFAULT_VALUE
+                                )
+                                default_value = (aClass, (), default_value)
+                            elif not isinstance(default_value, aClass):
+                                if typeValue is not tuple:
+                                    default_value = (default_value,)
+                                default_value_type = (
+                                    CALLABLE_AND_ARGS_DEFAULT_VALUE
+                                )
+                                default_value = (aClass, default_value, None)
+                else:
+                    for i, item in enumerate(other):
+                        if isinstance(item, CTrait):
+                            if item.type != "trait":
+                                raise TraitError(
+                                    "Cannot create a complex "
+                                    "trait containing %s trait."
+                                    % add_article(item.type)
+                                )
+                            handler = item.handler
+                            if handler is None:
+                                break
+                            other[i] = handler
+                    else:
+                        handler = TraitCompound(other)
+
+        # Save the results:
+        self.handler = handler
+        self.clone = clone
+
+        if default_value_type < 0:
+            if isinstance(default_value, Default):
+                default_value_type = CALLABLE_AND_ARGS_DEFAULT_VALUE
+                default_value = default_value.default_value
+            else:
+                if (handler is None) and (clone is not None):
+                    handler = clone.handler
+
+                if handler is not None:
+                    default_value_type = handler.default_value_type
+                    if default_value_type < 0:
+                        try:
+                            default_value = handler.validate(
+                                None, "", default_value
+                            )
+                        except:
+                            pass
+
+                if default_value_type < 0:
+                    default_value_type = _default_value_type(default_value)
+
+        self.default_value_type = default_value_type
+        self.default_value = default_value
+        self.metadata = metadata.copy()
+
+    # ---------------------------------------------------------------------------
+    #  Determine the correct TraitHandler for each item in a list:
+    # ---------------------------------------------------------------------------
+
+    def do_list(self, list, enum, map, other):
+        for item in list:
+            if item in PythonTypes:
+                other.append(TraitCoerceType(item))
+            else:
+                item = try_trait_cast(item)
+                typeItem = type(item)
+
+                if typeItem in ConstantTypes:
+                    enum.append(item)
+
+                elif typeItem in SequenceTypes:
+                    self.do_list(item, enum, map, other)
+
+                elif typeItem is dict:
+                    map.update(item)
+
+                elif typeItem in CallableTypes:
+                    other.append(TraitFunction(item))
+
+                elif item is ThisClass:
+                    other.append(ThisClass())
+
+                elif isinstance(item, TraitTypes):
+                    other.append(item)
+
+                else:
+                    other.append(TraitInstance(item))
+
+    # ---------------------------------------------------------------------------
+    #  Returns a properly initialized 'CTrait' instance:
+    # ---------------------------------------------------------------------------
+
+    def as_ctrait(self):
+        metadata = self.metadata
+        trait = CTrait(self.type_map.get(metadata.get("type"), 0))
+        clone = self.clone
+        if clone is not None:
+            trait.clone(clone)
+            if clone.__dict__ is not None:
+                trait.__dict__ = clone.__dict__.copy()
+
+        trait.default_value(self.default_value_type, self.default_value)
+
+        handler = self.handler
+        if handler is not None:
+            trait.handler = handler
+            validate = getattr(handler, "fast_validate", None)
+            if validate is None:
+                validate = handler.validate
+            trait.set_validate(validate)
+
+            post_setattr = getattr(handler, "post_setattr", None)
+            if post_setattr is not None:
+                trait.post_setattr = post_setattr
+                trait.is_mapped(handler.is_mapped)
+
+        # Note: The use of 'rich_compare' metadata is deprecated; use
+        # 'comparison_mode' metadata instead:
+        rich_compare = metadata.get("rich_compare")
+        if rich_compare is not None:
+            trait.rich_comparison(rich_compare is True)
+
+        comparison_mode = metadata.get("comparison_mode")
+        if comparison_mode is not None:
+            trait.comparison_mode(comparison_mode)
+
+        trait.value_allowed(metadata.get("trait_value", False) is True)
+
+        if len(metadata) > 0:
+            if trait.__dict__ is None:
+                trait.__dict__ = metadata
+            else:
+                trait.__dict__.update(metadata)
+
+        return trait
+
+    # ---------------------------------------------------------------------------
+    #  Extract a set of keywords from a dictionary:
+    # ---------------------------------------------------------------------------
+
+    def extract(self, from_dict, *keys):
+        to_dict = {}
+        for key in keys:
+            if key in from_dict:
+                to_dict[key] = from_dict[key]
+                del from_dict[key]
+        return to_dict
+
+
+# -------------------------------------------------------------------------------
+#  Factory function for creating C-based trait properties:
+# -------------------------------------------------------------------------------
+
+
+def Property(
+    fget=None,
+    fset=None,
+    fvalidate=None,
+    force=False,
+    handler=None,
+    trait=None,
+    **metadata
+):
+    """ Returns a trait whose value is a Python property.
+
+    Parameters
+    ----------
+    fget : function
+        The "getter" function for the property.
+    fset : function
+        The "setter" function for the property.
+    fvalidate : function
+        The validation function for the property. The method should return the
+        value to set or raise TraitError if the new value is not valid.
+    force : bool
+        Indicates whether to use only the function definitions specified by
+        **fget** and **fset**, and not look elsewhere on the class.
+    handler : function
+        A trait handler function for the trait.
+    trait : Trait or value
+        A trait definition or a value that can be converted to a trait that
+        constrains the values of the property trait.
+
+    Description
+    -----------
+    If no getter, setter or validate functions are specified (and **force** is
+    not True), it is assumed that they are defined elsewhere on the class whose
+    attribute this trait is assigned to. For example::
+
+        class Bar(HasTraits):
+
+            # A float traits Property that should be always positive.
+            foo = Property(Float)
+
+            # Shadow trait attribute
+            _foo = Float
+
+            def _set_foo(self,x):
+                self._foo = x
+
+            def _validate_foo(self, x):
+                if x <= 0:
+                    raise TraitError(
+                        'foo property should be a positive number')
+                return x
+
+            def _get_foo(self):
+                return self._foo
+
+    You can use the **depends_on** metadata attribute to indicate that the
+    property depends on the value of another trait. The value of **depends_on**
+    is an extended name specifier for traits that the property depends on. The
+    property will a trait change notification if any of the traits specified
+    by **depends_on** change. For example::
+
+        class Wheel ( Part ):
+            axle     = Instanced( Axle )
+            position = Property( depends_on = 'axle.chassis.position' )
+
+    For details of the extended trait name syntax, refer to the on_trait_change()
+    method of the HasTraits class.
+    """
+    metadata["type"] = "property"
+
+    # If no parameters specified, must be a forward reference (if not forced):
+    if (not force) and (fset is None):
+        sum = (
+            (fget is not None) + (fvalidate is not None) + (trait is not None)
+        )
+        if sum <= 1:
+            if sum == 0:
+                return ForwardProperty(metadata)
+
+            handler = None
+            if fget is not None:
+                trait = fget
+
+            if trait is not None:
+                trait = trait_cast(trait)
+                if trait is not None:
+                    fvalidate = handler = trait.handler
+                    if fvalidate is not None:
+                        fvalidate = handler.validate
+
+            if (fvalidate is not None) or (trait is not None):
+                if "editor" not in metadata:
+                    if (trait is not None) and (trait.editor is not None):
+                        metadata["editor"] = trait.editor
+
+                return ForwardProperty(metadata, fvalidate, handler)
+
+    if fget is None:
+        metadata["transient"] = True
+        if fset is None:
+            fget = _undefined_get
+            fset = _undefined_set
+        else:
+            fget = _write_only
+
+    elif fset is None:
+        fset = _read_only
+        metadata["transient"] = True
+
+    if trait is not None:
+        trait = trait_cast(trait)
+        handler = trait.handler
+        if (fvalidate is None) and (handler is not None):
+            fvalidate = handler.validate
+
+        if ("editor" not in metadata) and (trait.editor is not None):
+            metadata["editor"] = trait.editor
+
+    metadata.setdefault("depends_on", getattr(fget, "depends_on", None))
+    if (metadata.get("depends_on") is not None) and getattr(
+        fget, "cached_property", False
+    ):
+        metadata.setdefault("cached", True)
+
+    n = 0
+    trait = CTrait(4)
+    trait.__dict__ = metadata.copy()
+    if fvalidate is not None:
+        n = _arg_count(fvalidate)
+
+    trait.property(
+        fget, _arg_count(fget), fset, _arg_count(fset), fvalidate, n
+    )
+    trait.handler = handler
+
+    return trait
+
+
+Property = TraitFactory(Property)
+
+
+class ForwardProperty(object):
+    """ Used to implement Property traits where accessor functions are defined
+    implicitly on the class.
+    """
+
+    def __init__(self, metadata, validate=None, handler=None):
+        self.metadata = metadata.copy()
+        self.validate = validate
+        self.handler = handler
+
+
+# -------------------------------------------------------------------------------
+#  Dictionary used to handle return type mapping special cases:
+# -------------------------------------------------------------------------------
+
+SpecialNames = {
+    ###   'int':     trait_factory( Int ),
+    ###   'long':    trait_factory( Long ),
+    ###   'float':   trait_factory( Float ),
+    ###   'complex': trait_factory( Complex ),
+    ###   'str':     trait_factory( Str ),
+    ###   'unicode': trait_factory( Unicode ),
+    ###   'bool':    trait_factory( Bool ),
+    ###   'list':    trait_factory( List ),
+    ###   'tuple':   trait_factory( Tuple ),
+    ###   'dict':    trait_factory( Dict )
+}
+
+
+# -- Date Trait definition ----------------------------------------------------
+# Date = Instance(datetime.date, metadata = { 'editor': date_editor })
+
+
+# -- Time Trait definition ----------------------------------------------------
+# Time = Instance(datetime.time, metadata = { 'editor': time_editor })
+
+
+# -------------------------------------------------------------------------------
+#  Create predefined, reusable trait instances:
+# -------------------------------------------------------------------------------
+
+# Generic trait with 'object' behavior:
+generic_trait = CTrait(8)
+
+# -------------------------------------------------------------------------------
+#  User interface related color and font traits:
+# -------------------------------------------------------------------------------
+
+
+def Color(*args, **metadata):
+    """ Returns a trait whose value must be a GUI toolkit-specific color.
+
+    Description
+    -----------
+    For wxPython, the returned trait accepts any of the following values:
+
+    * A wx.Colour instance
+    * A wx.ColourPtr instance
+    * an integer whose hexadecimal form is 0x*RRGGBB*, where *RR* is the red
+      value, *GG* is the green value, and *BB* is the blue value
+
+    Default Value
+    -------------
+    For wxPython, 0xffffff (that is, white)
+    """
+    from traitsui.toolkit_traits import ColorTrait
+
+    return ColorTrait(*args, **metadata)
+
+
+Color = TraitFactory(Color)
+
+
+def RGBColor(*args, **metadata):
+    """ Returns a trait whose value must be a GUI toolkit-specific RGB-based
+        color.
+
+    Description
+    -----------
+    For wxPython, the returned trait accepts any of the following values:
+
+    * A tuple of the form (*r*, *g*, *b*), in which *r*, *g*, and *b* represent
+      red, green, and blue values, respectively, and are floats in the range
+      from 0.0 to 1.0
+    * An integer whose hexadecimal form is 0x*RRGGBB*, where *RR* is the red
+      value, *GG* is the green value, and *BB* is the blue value
+
+    Default Value
+    -------------
+    For wxPython, (1.0, 1.0, 1.0) (that is, white)
+    """
+    from traitsui.toolkit_traits import RGBColorTrait
+
+    return RGBColorTrait(*args, **metadata)
+
+
+RGBColor = TraitFactory(RGBColor)
+
+
+def Font(*args, **metadata):
+    """ Returns a trait whose value must be a GUI toolkit-specific font.
+
+    Description
+    -----------
+    For wxPython, the returned trait accepts any of the following:
+
+    * a wx.Font instance
+    * a wx.FontPtr instance
+    * a string describing the font, including one or more of the font family,
+      size, weight, style, and typeface name.
+
+    Default Value
+    -------------
+    For wxPython, 'Arial 10'
+    """
+    from traitsui.toolkit_traits import FontTrait
+
+    return FontTrait(*args, **metadata)
+
+
+Font = TraitFactory(Font)
+
+ +
+
+
+
+
+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/4.5/_modules/traitsui/editors/code_editor.html b/4.5/_modules/traitsui/editors/code_editor.html new file mode 100644 index 000000000..8761b3bb4 --- /dev/null +++ b/4.5/_modules/traitsui/editors/code_editor.html @@ -0,0 +1,248 @@ + + + + + + + traitsui.editors.code_editor — Apptools Documentation + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +

Source code for traitsui.editors.code_editor

+#------------------------------------------------------------------------------
+#
+#  Copyright (c) 2008, Enthought, Inc.
+#  All rights reserved.
+#
+#  This software is provided without warranty under the terms of the BSD
+#  license included in enthought/LICENSE.txt and may be redistributed only
+#  under the conditions described in the aforementioned license.  The license
+#  is also available online at http://www.enthought.com/licenses/BSD.txt
+#
+#  Thanks for using Enthought open source!
+#
+#  Author: David C. Morrill
+#  Date:   01/27/2006
+#
+#------------------------------------------------------------------------------
+
+""" Defines the code editor factory for all traits toolkit backends,
+useful for tools such as debuggers.
+"""
+
+#-------------------------------------------------------------------------
+#  Imports:
+#-------------------------------------------------------------------------
+
+from __future__ import absolute_import
+
+from traits.api import Instance, Str, Color, Enum, Bool
+
+from ..editor_factory import EditorFactory
+
+#-------------------------------------------------------------------------
+#  'ToolkitEditorFactory' class:
+#-------------------------------------------------------------------------
+
+
+class ToolkitEditorFactory(EditorFactory):
+    """ Editor factory for code editors.
+    """
+
+    #-------------------------------------------------------------------------
+    #  Trait definitions:
+    #-------------------------------------------------------------------------
+
+    # Object trait containing list of line numbers to mark (optional)
+    mark_lines = Str
+
+    # Background color for marking lines
+    mark_color = Color(0xECE9D8)
+
+    # Object trait containing the currently selected line (optional)
+    selected_line = Str
+
+    # Object trait containing the currently selected text (optional)
+    selected_text = Str
+
+    # Object trait containing the currently selected text start position
+    # (optional)
+    selected_start_pos = Str
+
+    # Object trait containing the currently selected text end position
+    # (optional)
+    selected_end_pos = Str
+
+    # Background color for selected lines
+    selected_color = Color(0xA4FFFF)
+
+    # Where should the search toolbar be placed?
+    search = Enum('top', 'bottom', 'none')
+
+    # Background color for lines that match the current search
+    search_color = Color(0xFFFF94)
+
+    # Current line
+    line = Str
+
+    # Current column
+    column = Str
+
+    # Should code folding be enabled?
+    foldable = Bool(True)
+
+    # Should line numbers be displayed in the margin?
+    show_line_numbers = Bool(True)
+
+    # Is user input set on every change?
+    auto_set = Bool(True)
+
+    # Should the editor auto-scroll when a new **selected_line** value is set?
+    auto_scroll = Bool(True)
+
+    # Optional key bindings associated with the editor
+    key_bindings = Instance('traitsui.key_bindings.KeyBindings')
+
+    # Calltip clicked event
+    calltip_clicked = Str
+
+    # The lexer to use. Default is 'python'; 'null' indicates no lexing.
+    lexer = Str('python')
+
+    # Object trait containing the list of line numbers to dim (optional)
+    dim_lines = Str
+
+    # Object trait to dim lines to. Can be of form #rrggbb or a color spec. If
+    # not specified, dark grey is used.
+    dim_color = Str
+
+    # Object trait containing the list of line numbers to put squiggles under
+    # (optional)
+    squiggle_lines = Str
+
+    # Object trait for the color of squiggles. If not specified, red is used.
+    squiggle_color = Str
+
+
+# Define the Code Editor class.
+CodeEditor = ToolkitEditorFactory
+
+### EOF #######################################################################
+
+ +
+
+
+
+
+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/4.5/_modules/traitsui/editors/tabular_editor.html b/4.5/_modules/traitsui/editors/tabular_editor.html new file mode 100644 index 000000000..f58e43228 --- /dev/null +++ b/4.5/_modules/traitsui/editors/tabular_editor.html @@ -0,0 +1,298 @@ + + + + + + + traitsui.editors.tabular_editor — Apptools Documentation + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +

Source code for traitsui.editors.tabular_editor

+#-------------------------------------------------------------------------
+#
+#  Copyright (c) 2007, Enthought, Inc.
+#  All rights reserved.
+#
+#  This software is provided without warranty under the terms of the BSD
+#  license included in enthought/LICENSE.txt and may be redistributed only
+#  under the conditions described in the aforementioned license.  The license
+#  is also available online at http://www.enthought.com/licenses/BSD.txt
+#
+#  Thanks for using Enthought open source!
+#
+#  Author: David C. Morrill
+#  Date:   05/20/2007
+#
+#-------------------------------------------------------------------------
+
+""" A traits UI editor for editing tabular data (arrays, list of tuples, lists
+    of objects, etc).
+"""
+
+#-------------------------------------------------------------------------
+#  Imports:
+#-------------------------------------------------------------------------
+
+from __future__ import absolute_import
+
+from pyface.ui_traits import Image
+from traits.api import Str, Bool, Property, List, Enum, Instance
+
+from ..basic_editor_factory import BasicEditorFactory
+
+from ..toolkit import toolkit_object
+
+#-------------------------------------------------------------------------
+#  'TabularEditor' editor factory class:
+#-------------------------------------------------------------------------
+
+
+class TabularEditor(BasicEditorFactory):
+    """ Editor factory for tabular editors.
+    """
+
+    #-- Trait Definitions ----------------------------------------------------
+
+    # The editor class to be created:
+    klass = Property
+
+    # Should column headers (i.e. titles) be displayed?
+    show_titles = Bool(True)
+
+    # Should row headers be displated (Qt4 only)?
+    show_row_titles = Bool(False)
+
+    # The optional extended name of the trait used to indicate that a complete
+    # table update is needed:
+    update = Str
+
+    # The optional extended name of the trait used to indicate that the table
+    # just needs to be repainted.
+    refresh = Str
+
+    # Should the table update automatically when the table item's contents
+    # change? Note that in order for this feature to work correctly, the editor
+    # trait should be a list of objects derived from HasTraits. Also,
+    # performance can be affected when very long lists are used, since enabling
+    # this feature adds and removed Traits listeners to each item in the list.
+    auto_update = Bool(False)
+
+    # The optional extended name of the trait to synchronize the selection
+    # values with:
+    selected = Str
+
+    # The optional extended name of the trait to synchronize the selection rows
+    # with:
+    selected_row = Str
+
+    # Whether or not to allow selection.
+    selectable = Bool(True)
+
+    # The optional extended name of the trait to synchronize the activated value
+    # with:
+    activated = Str
+
+    # The optional extended name of the trait to synchronize the activated
+    # value's row with:
+    activated_row = Str
+
+    # The optional extended name of the trait to synchronize left click data
+    # with. The data is a TabularEditorEvent:
+    clicked = Str
+
+    # The optional extended name of the trait to synchronize left double click
+    # data with. The data is a TabularEditorEvent:
+    dclicked = Str
+
+    # The optional extended name of the trait to synchronize right click data
+    # with. The data is a TabularEditorEvent:
+    right_clicked = Str
+
+    # The optional extended name of the trait to synchronize right double
+    # clicked data with. The data is a TabularEditorEvent:
+    right_dclicked = Str
+
+    # The optional extended name of the trait to synchronize column
+    # clicked data with. The data is a TabularEditorEvent:
+    column_clicked = Str
+
+    # The optional extended name of the trait to synchronize column
+    # right clicked data with. The data is a TabularEditorEvent:
+    column_right_clicked = Str
+
+    # The optional extended name of the Event trait that should be used to
+    # trigger a scroll-to command. The data is an integer giving the row.
+    scroll_to_row = Str
+
+    # The optional extended name of the Event trait that should be used to
+    # trigger a scroll-to command. The data is an integer giving the column.
+    scroll_to_column = Str
+
+    # Controls behavior of scroll to row
+    scroll_to_row_hint = Enum("center", "top", "bottom", "visible")
+
+    # Can the user edit the values?
+    editable = Bool(True)
+
+    # Can the user edit the labels (i.e. the first column)
+    editable_labels = Bool(False)
+
+    # Are multiple selected items allowed?
+    multi_select = Bool(False)
+
+    # Should horizontal lines be drawn between items?
+    horizontal_lines = Bool(True)
+
+    # Should vertical lines be drawn between items?
+    vertical_lines = Bool(True)
+
+    # Should the columns automatically resize? Don't allow this when the amount
+    # of data is large.
+    auto_resize = Bool(False)
+
+    # Should the rows automatically resize (Qt4 only)? Don't allow
+    # this when the amount of data is large.
+    auto_resize_rows = Bool(False)
+
+    # Whether to stretch the last column to fit the available space.
+    stretch_last_section = Bool(True)
+
+    # The adapter from trait values to editor values:
+    adapter = Instance('traitsui.tabular_adapter.TabularAdapter', ())
+
+    # What type of operations are allowed on the list:
+    operations = List(Enum('delete', 'insert', 'append', 'edit', 'move'),
+                      ['delete', 'insert', 'append', 'edit', 'move'])
+
+    # Are 'drag_move' operations allowed (i.e. True), or should they always be
+    # treated as 'drag_copy' operations (i.e. False):
+    drag_move = Bool(True)
+
+    # The set of images that can be used:
+    images = List(Image)
+
+    def _get_klass(self):
+        """ Returns the toolkit-specific editor class to be instantiated.
+        """
+        return toolkit_object('tabular_editor:TabularEditor')
+
+### EOF #######################################################################
+
+ +
+
+
+
+
+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/4.5/_modules/traitsui/view.html b/4.5/_modules/traitsui/view.html new file mode 100644 index 000000000..dfb0afec9 --- /dev/null +++ b/4.5/_modules/traitsui/view.html @@ -0,0 +1,603 @@ + + + + + + + traitsui.view — Apptools Documentation + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +

Source code for traitsui.view

+#------------------------------------------------------------------------------
+#
+#  Copyright (c) 2005, Enthought, Inc.
+#  All rights reserved.
+#
+#  This software is provided without warranty under the terms of the BSD
+#  license included in enthought/LICENSE.txt and may be redistributed only
+#  under the conditions described in the aforementioned license.  The license
+#  is also available online at http://www.enthought.com/licenses/BSD.txt
+#
+#  Thanks for using Enthought open source!
+#
+#  Author: David C. Morrill
+#  Date:   10/07/2004
+#
+#------------------------------------------------------------------------------
+
+""" Defines the View class used to represent the structural content of a
+    Traits-based user interface.
+"""
+
+#-------------------------------------------------------------------------
+#  Imports:
+#-------------------------------------------------------------------------
+
+from __future__ import absolute_import
+
+from pyface.ui_traits import Image
+from traits.api import (
+    Any,
+    Bool,
+    Callable,
+    Enum,
+    Event,
+    Float,
+    Instance,
+    List,
+    Str,
+    Trait,
+    TraitPrefixList)
+
+from .view_element import ViewElement, ViewSubElement
+
+from .ui import UI
+
+from .ui_traits import (
+    AButton,
+    AnObject,
+    Buttons,
+    DockStyle,
+    EditorStyle,
+    ExportType,
+    HelpId,
+    Image,
+    SequenceTypes,
+    ViewStatus)
+
+from .handler import Handler, default_handler
+
+from .group import Group
+
+from .item import Item
+
+from .include import Include
+import six
+
+#-------------------------------------------------------------------------
+#  Trait definitions:
+#-------------------------------------------------------------------------
+
+# Name of the view trait:
+AnId = Str(desc='the name of the view')
+
+# Contents of the view trait (i.e., a single Group object):
+Content = Instance(Group, desc='the content of the view')
+
+# An optional model/view factory for converting the model into a viewable
+# 'model_view' object
+AModelView = Callable(desc='the factory function for converting a model '
+                      'into a model/view object')
+
+# Reference to a Handler object trait:
+AHandler = Any(desc='the handler for the view')
+
+# Dialog window title trait:
+ATitle = Str(desc='the window title for the view')
+
+# User interface 'kind' trait. The values have the following meanings:
+#
+# * 'panel': An embeddable panel. This type of window is intended to be used as
+#   part of a larger interface.
+# * 'subpanel': An embeddable panel that does not display command buttons,
+#   even if the View specifies them.
+# * 'modal': A modal dialog box that operates on a clone of the object until
+#   the user commits the change.
+# * 'nonmodal':  A nonmodal dialog box that operates on a clone of the object
+#   until the user commits the change
+# * 'live': A nonmodal dialog box that immediately updates the object.
+# * 'livemodal': A modal dialog box that immediately updates the object.
+# * 'popup': A temporary, frameless popup dialog that immediately updates the
+#   object and is active only while the mouse pointer is in the dialog.
+# * 'info': A temporary, frameless popup dialog that immediately updates the
+#   object and is active only while the dialog is still over the invoking
+#   control.
+# * 'wizard': A wizard modal dialog box. A wizard contains a sequence of
+#   pages, which can be accessed by clicking **Next** and **Back** buttons.
+#   Changes to attribute values are applied only when the user clicks the
+#   **Finish** button on the last page.
+AKind = Trait('live', TraitPrefixList(
+    'panel', 'subpanel', 'modal', 'nonmodal', 'livemodal',
+    'live', 'popup', 'popover', 'info', 'wizard'),
+    desc='the kind of view window to create',
+    cols=4)
+
+# Apply changes handler:
+OnApply = Callable(desc='the routine to call when modal changes are applied '
+                   'or reverted')
+
+# Is the dialog window resizable?
+IsResizable = Bool(False, desc='whether dialog can be resized or not')
+
+# Is the view scrollable?
+IsScrollable = Bool(False, desc='whether view should be scrollable or not')
+
+# The valid categories of imported elements that can be dragged into the view:
+ImportTypes = List(Str, desc='the categories of elements that can be '
+                   'dragged into the view')
+
+# The view position and size traits:
+Width = Float(-1E6, desc='the width of the view window')
+Height = Float(-1E6, desc='the height of the view window')
+XCoordinate = Float(-1E6, desc='the x coordinate of the view window')
+YCoordinate = Float(-1E6, desc='the y coordinate of the view window')
+
+# The result that should be returned if the user clicks the window or dialog
+# close button or icon
+CloseResult = Enum(None, True, False,
+                   desc='the result to return when the user clicks the '
+                   'window or dialog close button or icon')
+
+# The KeyBindings trait:
+AKeyBindings = Instance('traitsui.key_bindings.KeyBindings',
+                        desc='the global key bindings for the view')
+
+#-------------------------------------------------------------------------
+#  'View' class:
+#-------------------------------------------------------------------------
+
+
+class View(ViewElement):
+    """ A Traits-based user interface for one or more objects.
+
+        The attributes of the View object determine the contents and layout of
+        an attribute-editing window. A View object contains a set of Group,
+        Item, and Include objects. A View object can be an attribute of an
+        object derived from HasTraits, or it can be a standalone object.
+    """
+
+    #-------------------------------------------------------------------------
+    #  Trait definitions:
+    #-------------------------------------------------------------------------
+
+    # A unique identifier for the view:
+    id = AnId
+
+    # The top-level Group object for the view:
+    content = Content
+
+    # The menu bar for the view. Usually requires a custom **handler**:
+    menubar = Any  # Instance( pyface.action.MenuBarManager )
+
+    # The toolbar for the view. Usually requires a custom **handler**:
+    toolbar = Any  # Instance( pyface.action.ToolBarManager )
+
+    # Status bar items to add to the view's status bar. The value can be:
+    #
+    #   - **None**: No status bar for the view (the default).
+    #   - string: Same as [ StatusItem( name = string ) ].
+    #   - StatusItem: Same as [ StatusItem ].
+    #   - [ [StatusItem|string], ... ]: Create a status bar with one field for
+    #     each StatusItem in the list (or tuple). The status bar fields are
+    #     defined from left to right in the order specified. A string value is
+    #     converted to: StatusItem( name = string ):
+    statusbar = ViewStatus
+
+    # List of button actions to add to the view. The **traitsui.menu**
+    # module defines standard buttons, such as **OKButton**, and standard sets
+    # of buttons, such as **ModalButtons**, which can be used to define a value
+    # for this attribute. This value can also be a list of button name strings,
+    # such as ``['OK', 'Cancel', 'Help']``. If set to the empty list, the
+    # view contains a default set of buttons (equivalent to **LiveButtons**:
+    # Undo/Redo, Revert, OK, Cancel, Help). To suppress buttons in the view,
+    # use the **NoButtons** variable, defined in **traitsui.menu**.
+    buttons = Buttons
+
+    # The default button to activate when Enter is pressed. If not specified,
+    # pressing Enter will not activate any button.
+    default_button = AButton
+
+    # The set of global key bindings for the view. Each time a key is pressed
+    # while the view has keyboard focus, the key is checked to see if it is one
+    # of the keys recognized by the KeyBindings object. If it is, the matching
+    # KeyBinding's method name is checked to see if it is defined on any of the
+    # object's in the view's context. If it is, the method is invoked. If the
+    # result of the method is **False**, then the search continues with the
+    # next object in the context. If any invoked method returns a non-False
+    # value, processing stops and the key is marked as having been handled. If
+    # all invoked methods return **False**, or no matching KeyBinding object is
+    # found, the key is processed normally. If the view has a non-empty *id*
+    # trait, the contents of the **KeyBindings** object will be saved as part
+    # of the view's persistent data:
+    key_bindings = AKeyBindings
+
+    # The Handler object that provides GUI logic for handling events in the
+    # window. Set this attribute only if you are using a custom Handler. If
+    # not set, the default Traits UI Handler is used.
+    handler = AHandler
+
+    # The factory function for converting a model into a model/view object:
+    model_view = AModelView
+
+    # Title for the view, displayed in the title bar when the view appears as a
+    # secondary window (i.e., dialog or wizard). If not specified, "Edit
+    # properties" is used as the title.
+    title = ATitle
+
+    # The name of the icon to display in the dialog window title bar:
+    icon = Image
+
+    # The kind of user interface to create:
+    kind = AKind
+
+    # The default object being edited:
+    object = AnObject
+
+    # The default editor style of elements in the view:
+    style = EditorStyle
+
+    # The default docking style to use for sub-groups of the view. The following
+    # values are possible:
+    #
+    # * 'fixed': No rearrangement of sub-groups is allowed.
+    # * 'horizontal': Moveable elements have a visual "handle" to the left by
+    #   which the element can be dragged.
+    # * 'vertical': Moveable elements have a visual "handle" above them by
+    #   which the element can be dragged.
+    # * 'tabbed': Moveable elements appear as tabbed pages, which can be
+    #   arranged within the window or "stacked" so that only one appears at
+    #   at a time.
+    dock = DockStyle
+
+    # The image to display on notebook tabs:
+    image = Image
+
+    # Called when modal changes are applied or reverted:
+    on_apply = OnApply
+
+    # Can the user resize the window?
+    resizable = IsResizable
+
+    # Can the user scroll the view? If set to True, window-level scroll bars
+    # appear whenever the window is too small to show all of its contents at
+    # one time. If set to False, the window does not scroll, but individual
+    # widgets might still contain scroll bars.
+    scrollable = IsScrollable
+
+    # The category of exported elements:
+    export = ExportType
+
+    # The valid categories of imported elements:
+    imports = ImportTypes
+
+    # External help context identifier, which can be used by a custom help
+    # handler. This attribute is ignored by the default help handler.
+    help_id = HelpId
+
+    # Requested x-coordinate (horizontal position) for the view window. This
+    # attribute can be specified in the following ways:
+    #
+    # * A positive integer: indicates the number of pixels from the left edge
+    #   of the screen to the left edge of the window.
+    # * A negative integer: indicates the number of pixels from the right edge
+    #   of the screen to the right edge of the window.
+    # * A floating point value between 0 and 1: indicates the fraction of the
+    #   total screen width between the left edge of the screen and the left edge
+    #   of the window.
+    # * A floating point value between -1 and 0: indicates the fraction of the
+    #   total screen width between the right edge of the screen and the right
+    #   edge of the window.
+    x = XCoordinate
+
+    # Requested y-coordinate (vertical position) for the view window. This
+    # attribute behaves exactly like the **x** attribute, except that its value
+    # indicates the position of the top or bottom of the view window relative
+    # to the top or bottom of the screen.
+    y = YCoordinate
+
+    # Requested width for the view window, as an (integer) number of pixels, or
+    # as a (floating point) fraction of the screen width.
+    width = Width
+
+    # Requested height for the view window, as an (integer) number of pixels, or
+    # as a (floating point) fraction of the screen height.
+    height = Height
+
+    # Class of dropped objects that can be added:
+    drop_class = Any
+
+    # Event when the view has been updated:
+    updated = Event
+
+    # What result should be returned if the user clicks the window or dialog
+    # close button or icon?
+    close_result = CloseResult
+
+    # Note: Group objects delegate their 'object' and 'style' traits to the
+    # View
+
+    #-- Deprecated Traits (DO NOT USE) ---------------------------------------
+
+    ok = Bool(False)
+    cancel = Bool(False)
+    undo = Bool(False)
+    redo = Bool(False)
+    apply = Bool(False)
+    revert = Bool(False)
+    help = Bool(False)
+
+    #-------------------------------------------------------------------------
+    #  Initializes the object:
+    #-------------------------------------------------------------------------
+
+    def __init__(self, *values, **traits):
+        """ Initializes the object.
+        """
+        ViewElement.__init__(self, **traits)
+        self.set_content(*values)
+
+    #-------------------------------------------------------------------------
+    #  Sets the content of a view:
+    #-------------------------------------------------------------------------
+
+    def set_content(self, *values):
+        """ Sets the content of a view.
+        """
+        content = []
+        accum = []
+        for value in values:
+            if isinstance(value, ViewSubElement):
+                content.append(value)
+            elif type(value) in SequenceTypes:
+                content.append(Group(*value))
+            elif (isinstance(value, six.string_types) and
+                  (value[:1] == '<') and (value[-1:] == '>')):
+                # Convert string to an Include value:
+                content.append(Include(value[1:-1].strip()))
+            else:
+                content.append(Item(value))
+
+        # If there are any 'Item' objects in the content, wrap the content in a
+        # Group:
+        for item in content:
+            if isinstance(item, Item):
+                content = [Group(*content)]
+                break
+
+        # Wrap all of the content up into a Group and save it as our content:
+        self.content = Group(container=self, *content)
+
+    #-------------------------------------------------------------------------
+    #  Creates a UI user interface object:
+    #-------------------------------------------------------------------------
+
+    def ui(self, context, parent=None, kind=None,
+            view_elements=None, handler=None,
+            id='', scrollable=None,
+            args=None):
+        """ Creates a **UI** object, which generates the actual GUI window or
+        panel from a set of view elements.
+
+        Parameters
+        ----------
+        context : object or dictionary
+            A single object or a dictionary of string/object pairs, whose trait
+            attributes are to be edited. If not specified, the current object is
+            used.
+        parent : window component
+            The window parent of the View object's window
+        kind : string
+            The kind of window to create. See the **AKind** trait for details.
+            If *kind* is unspecified or None, the **kind** attribute of the
+            View object is used.
+        view_elements : ViewElements object
+            The set of Group, Item, and Include objects contained in the view.
+            Do not use this parameter when calling this method directly.
+        handler : Handler object
+            A handler object used for event handling in the dialog box. If
+            None, the default handler for Traits UI is used.
+        id : string
+            A unique ID for persisting preferences about this user interface,
+            such as size and position. If not specified, no user preferences
+            are saved.
+        scrollable : Boolean
+            Indicates whether the dialog box should be scrollable. When set to
+            True, scroll bars appear on the dialog box if it is not large enough
+            to display all of the items in the view at one time.
+
+        """
+        handler = handler or self.handler or default_handler()
+        if not isinstance(handler, Handler):
+            handler = handler()
+
+        if args is not None:
+            handler.trait_set(**args)
+
+        if not isinstance(context, dict):
+            context = context.trait_context()
+
+        context.setdefault('handler', handler)
+        handler = context['handler']
+
+        if self.model_view is not None:
+            context['object'] = self.model_view(context['object'])
+
+        self_id = self.id
+        if self_id != '':
+            if id != '':
+                id = '%s:%s' % (self_id, id)
+            else:
+                id = self_id
+
+        if scrollable is None:
+            scrollable = self.scrollable
+
+        ui = UI(view=self,
+                context=context,
+                handler=handler,
+                view_elements=view_elements,
+                title=self.title,
+                id=id,
+                scrollable=scrollable)
+
+        if kind is None:
+            kind = self.kind
+
+        ui.ui(parent, kind)
+
+        return ui
+
+    #-------------------------------------------------------------------------
+    #  Replaces any items which have an 'id' with an Include object with the
+    #  same 'id', and puts the object with the 'id' into the specified
+    #  ViewElements object:
+    #-------------------------------------------------------------------------
+
+    def replace_include(self, view_elements):
+        """ Replaces any items that have an ID with an Include object with
+            the same ID, and puts the object with the ID into the specified
+            ViewElements object.
+        """
+        if self.content is not None:
+            self.content.replace_include(view_elements)
+
+    #-------------------------------------------------------------------------
+    #  Returns a 'pretty print' version of the View:
+    #-------------------------------------------------------------------------
+
+    def __repr__(self):
+        """ Returns a "pretty print" version of the View.
+        """
+        if self.content is None:
+            return '()'
+        return "( %s )" % ', '.join(
+               [item.__repr__() for item in self.content.content])
+
+ +
+
+
+
+
+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/4.5/_sources/api.rst.txt b/4.5/_sources/api.rst.txt new file mode 100644 index 000000000..7972821bf --- /dev/null +++ b/4.5/_sources/api.rst.txt @@ -0,0 +1,9 @@ +API documentation +================= + +This section contains auto-generated API documentation for AppTools. + +.. toctree:: + :maxdepth: 2 + + api/modules diff --git a/_sources/api/apptools.appscripting.action.rst.txt b/4.5/_sources/api/apptools.appscripting.action.rst.txt similarity index 100% rename from _sources/api/apptools.appscripting.action.rst.txt rename to 4.5/_sources/api/apptools.appscripting.action.rst.txt diff --git a/_sources/api/apptools.appscripting.rst.txt b/4.5/_sources/api/apptools.appscripting.rst.txt similarity index 100% rename from _sources/api/apptools.appscripting.rst.txt rename to 4.5/_sources/api/apptools.appscripting.rst.txt diff --git a/_sources/api/apptools.help.help_plugin.action.rst.txt b/4.5/_sources/api/apptools.help.help_plugin.action.rst.txt similarity index 100% rename from _sources/api/apptools.help.help_plugin.action.rst.txt rename to 4.5/_sources/api/apptools.help.help_plugin.action.rst.txt diff --git a/_sources/api/apptools.help.help_plugin.rst.txt b/4.5/_sources/api/apptools.help.help_plugin.rst.txt similarity index 100% rename from _sources/api/apptools.help.help_plugin.rst.txt rename to 4.5/_sources/api/apptools.help.help_plugin.rst.txt diff --git a/_sources/api/apptools.help.rst.txt b/4.5/_sources/api/apptools.help.rst.txt similarity index 100% rename from _sources/api/apptools.help.rst.txt rename to 4.5/_sources/api/apptools.help.rst.txt diff --git a/4.5/_sources/api/apptools.io.h5.rst.txt b/4.5/_sources/api/apptools.io.h5.rst.txt new file mode 100644 index 000000000..656910ff4 --- /dev/null +++ b/4.5/_sources/api/apptools.io.h5.rst.txt @@ -0,0 +1,46 @@ +apptools.io.h5 package +====================== + +Submodules +---------- + +apptools.io.h5.dict\_node module +-------------------------------- + +.. automodule:: apptools.io.h5.dict_node + :members: + :undoc-members: + :show-inheritance: + +apptools.io.h5.file module +-------------------------- + +.. automodule:: apptools.io.h5.file + :members: + :undoc-members: + :show-inheritance: + +apptools.io.h5.table\_node module +--------------------------------- + +.. automodule:: apptools.io.h5.table_node + :members: + :undoc-members: + :show-inheritance: + +apptools.io.h5.utils module +--------------------------- + +.. automodule:: apptools.io.h5.utils + :members: + :undoc-members: + :show-inheritance: + + +Module contents +--------------- + +.. automodule:: apptools.io.h5 + :members: + :undoc-members: + :show-inheritance: diff --git a/4.5/_sources/api/apptools.io.rst.txt b/4.5/_sources/api/apptools.io.rst.txt new file mode 100644 index 000000000..ba5232adb --- /dev/null +++ b/4.5/_sources/api/apptools.io.rst.txt @@ -0,0 +1,37 @@ +apptools.io package +=================== + +Subpackages +----------- + +.. toctree:: + + apptools.io.h5 + +Submodules +---------- + +apptools.io.api module +---------------------- + +.. automodule:: apptools.io.api + :members: + :undoc-members: + :show-inheritance: + +apptools.io.file module +----------------------- + +.. automodule:: apptools.io.file + :members: + :undoc-members: + :show-inheritance: + + +Module contents +--------------- + +.. automodule:: apptools.io + :members: + :undoc-members: + :show-inheritance: diff --git a/4.5/_sources/api/apptools.logger.agent.rst.txt b/4.5/_sources/api/apptools.logger.agent.rst.txt new file mode 100644 index 000000000..263c0440d --- /dev/null +++ b/4.5/_sources/api/apptools.logger.agent.rst.txt @@ -0,0 +1,38 @@ +apptools.logger.agent package +============================= + +Submodules +---------- + +apptools.logger.agent.attachments module +---------------------------------------- + +.. automodule:: apptools.logger.agent.attachments + :members: + :undoc-members: + :show-inheritance: + +apptools.logger.agent.quality\_agent\_mailer module +--------------------------------------------------- + +.. automodule:: apptools.logger.agent.quality_agent_mailer + :members: + :undoc-members: + :show-inheritance: + +apptools.logger.agent.quality\_agent\_view module +------------------------------------------------- + +.. automodule:: apptools.logger.agent.quality_agent_view + :members: + :undoc-members: + :show-inheritance: + + +Module contents +--------------- + +.. automodule:: apptools.logger.agent + :members: + :undoc-members: + :show-inheritance: diff --git a/4.5/_sources/api/apptools.logger.plugin.rst.txt b/4.5/_sources/api/apptools.logger.plugin.rst.txt new file mode 100644 index 000000000..a33510ddd --- /dev/null +++ b/4.5/_sources/api/apptools.logger.plugin.rst.txt @@ -0,0 +1,45 @@ +apptools.logger.plugin package +============================== + +Subpackages +----------- + +.. toctree:: + + apptools.logger.plugin.view + +Submodules +---------- + +apptools.logger.plugin.logger\_plugin module +-------------------------------------------- + +.. automodule:: apptools.logger.plugin.logger_plugin + :members: + :undoc-members: + :show-inheritance: + +apptools.logger.plugin.logger\_preferences module +------------------------------------------------- + +.. automodule:: apptools.logger.plugin.logger_preferences + :members: + :undoc-members: + :show-inheritance: + +apptools.logger.plugin.logger\_service module +--------------------------------------------- + +.. automodule:: apptools.logger.plugin.logger_service + :members: + :undoc-members: + :show-inheritance: + + +Module contents +--------------- + +.. automodule:: apptools.logger.plugin + :members: + :undoc-members: + :show-inheritance: diff --git a/4.5/_sources/api/apptools.logger.plugin.view.rst.txt b/4.5/_sources/api/apptools.logger.plugin.view.rst.txt new file mode 100644 index 000000000..888ed7c6c --- /dev/null +++ b/4.5/_sources/api/apptools.logger.plugin.view.rst.txt @@ -0,0 +1,30 @@ +apptools.logger.plugin.view package +=================================== + +Submodules +---------- + +apptools.logger.plugin.view.logger\_preferences\_page module +------------------------------------------------------------ + +.. automodule:: apptools.logger.plugin.view.logger_preferences_page + :members: + :undoc-members: + :show-inheritance: + +apptools.logger.plugin.view.logger\_view module +----------------------------------------------- + +.. automodule:: apptools.logger.plugin.view.logger_view + :members: + :undoc-members: + :show-inheritance: + + +Module contents +--------------- + +.. automodule:: apptools.logger.plugin.view + :members: + :undoc-members: + :show-inheritance: diff --git a/4.5/_sources/api/apptools.logger.rst.txt b/4.5/_sources/api/apptools.logger.rst.txt new file mode 100644 index 000000000..e8444d74f --- /dev/null +++ b/4.5/_sources/api/apptools.logger.rst.txt @@ -0,0 +1,94 @@ +apptools.logger package +======================= + +Subpackages +----------- + +.. toctree:: + + apptools.logger.agent + apptools.logger.plugin + +Submodules +---------- + +apptools.logger.api module +-------------------------- + +.. automodule:: apptools.logger.api + :members: + :undoc-members: + :show-inheritance: + +apptools.logger.custom\_excepthook module +----------------------------------------- + +.. automodule:: apptools.logger.custom_excepthook + :members: + :undoc-members: + :show-inheritance: + +apptools.logger.filtering\_handler module +----------------------------------------- + +.. automodule:: apptools.logger.filtering_handler + :members: + :undoc-members: + :show-inheritance: + +apptools.logger.log\_point module +--------------------------------- + +.. automodule:: apptools.logger.log_point + :members: + :undoc-members: + :show-inheritance: + +apptools.logger.log\_queue\_handler module +------------------------------------------ + +.. automodule:: apptools.logger.log_queue_handler + :members: + :undoc-members: + :show-inheritance: + +apptools.logger.logger module +----------------------------- + +.. automodule:: apptools.logger.logger + :members: + :undoc-members: + :show-inheritance: + +apptools.logger.null\_handler module +------------------------------------ + +.. automodule:: apptools.logger.null_handler + :members: + :undoc-members: + :show-inheritance: + +apptools.logger.ring\_buffer module +----------------------------------- + +.. automodule:: apptools.logger.ring_buffer + :members: + :undoc-members: + :show-inheritance: + +apptools.logger.util module +--------------------------- + +.. automodule:: apptools.logger.util + :members: + :undoc-members: + :show-inheritance: + + +Module contents +--------------- + +.. automodule:: apptools.logger + :members: + :undoc-members: + :show-inheritance: diff --git a/_sources/api/apptools.lru_cache.rst.txt b/4.5/_sources/api/apptools.lru_cache.rst.txt similarity index 100% rename from _sources/api/apptools.lru_cache.rst.txt rename to 4.5/_sources/api/apptools.lru_cache.rst.txt diff --git a/_sources/api/apptools.naming.adapter.rst.txt b/4.5/_sources/api/apptools.naming.adapter.rst.txt similarity index 100% rename from _sources/api/apptools.naming.adapter.rst.txt rename to 4.5/_sources/api/apptools.naming.adapter.rst.txt diff --git a/4.5/_sources/api/apptools.naming.rst.txt b/4.5/_sources/api/apptools.naming.rst.txt new file mode 100644 index 000000000..e3f233454 --- /dev/null +++ b/4.5/_sources/api/apptools.naming.rst.txt @@ -0,0 +1,239 @@ +apptools.naming package +======================= + +Subpackages +----------- + +.. toctree:: + + apptools.naming.adapter + apptools.naming.trait_defs + apptools.naming.ui + +Submodules +---------- + +apptools.naming.address module +------------------------------ + +.. automodule:: apptools.naming.address + :members: + :undoc-members: + :show-inheritance: + +apptools.naming.api module +-------------------------- + +.. automodule:: apptools.naming.api + :members: + :undoc-members: + :show-inheritance: + +apptools.naming.binding module +------------------------------ + +.. automodule:: apptools.naming.binding + :members: + :undoc-members: + :show-inheritance: + +apptools.naming.context module +------------------------------ + +.. automodule:: apptools.naming.context + :members: + :undoc-members: + :show-inheritance: + +apptools.naming.context\_adapter module +--------------------------------------- + +.. automodule:: apptools.naming.context_adapter + :members: + :undoc-members: + :show-inheritance: + +apptools.naming.context\_adapter\_factory module +------------------------------------------------ + +.. automodule:: apptools.naming.context_adapter_factory + :members: + :undoc-members: + :show-inheritance: + +apptools.naming.dir\_context module +----------------------------------- + +.. automodule:: apptools.naming.dir_context + :members: + :undoc-members: + :show-inheritance: + +apptools.naming.dynamic\_context module +--------------------------------------- + +.. automodule:: apptools.naming.dynamic_context + :members: + :undoc-members: + :show-inheritance: + +apptools.naming.exception module +-------------------------------- + +.. automodule:: apptools.naming.exception + :members: + :undoc-members: + :show-inheritance: + +apptools.naming.initial\_context module +--------------------------------------- + +.. automodule:: apptools.naming.initial_context + :members: + :undoc-members: + :show-inheritance: + +apptools.naming.initial\_context\_factory module +------------------------------------------------ + +.. automodule:: apptools.naming.initial_context_factory + :members: + :undoc-members: + :show-inheritance: + +apptools.naming.naming\_event module +------------------------------------ + +.. automodule:: apptools.naming.naming_event + :members: + :undoc-members: + :show-inheritance: + +apptools.naming.naming\_manager module +-------------------------------------- + +.. automodule:: apptools.naming.naming_manager + :members: + :undoc-members: + :show-inheritance: + +apptools.naming.object\_factory module +-------------------------------------- + +.. automodule:: apptools.naming.object_factory + :members: + :undoc-members: + :show-inheritance: + +apptools.naming.object\_serializer module +----------------------------------------- + +.. automodule:: apptools.naming.object_serializer + :members: + :undoc-members: + :show-inheritance: + +apptools.naming.py\_context module +---------------------------------- + +.. automodule:: apptools.naming.py_context + :members: + :undoc-members: + :show-inheritance: + +apptools.naming.py\_object\_factory module +------------------------------------------ + +.. automodule:: apptools.naming.py_object_factory + :members: + :undoc-members: + :show-inheritance: + +apptools.naming.pyfs\_context module +------------------------------------ + +.. automodule:: apptools.naming.pyfs_context + :members: + :undoc-members: + :show-inheritance: + +apptools.naming.pyfs\_context\_factory module +--------------------------------------------- + +.. automodule:: apptools.naming.pyfs_context_factory + :members: + :undoc-members: + :show-inheritance: + +apptools.naming.pyfs\_initial\_context\_factory module +------------------------------------------------------ + +.. automodule:: apptools.naming.pyfs_initial_context_factory + :members: + :undoc-members: + :show-inheritance: + +apptools.naming.pyfs\_object\_factory module +-------------------------------------------- + +.. automodule:: apptools.naming.pyfs_object_factory + :members: + :undoc-members: + :show-inheritance: + +apptools.naming.pyfs\_state\_factory module +------------------------------------------- + +.. automodule:: apptools.naming.pyfs_state_factory + :members: + :undoc-members: + :show-inheritance: + +apptools.naming.reference module +-------------------------------- + +.. automodule:: apptools.naming.reference + :members: + :undoc-members: + :show-inheritance: + +apptools.naming.referenceable module +------------------------------------ + +.. automodule:: apptools.naming.referenceable + :members: + :undoc-members: + :show-inheritance: + +apptools.naming.referenceable\_state\_factory module +---------------------------------------------------- + +.. automodule:: apptools.naming.referenceable_state_factory + :members: + :undoc-members: + :show-inheritance: + +apptools.naming.state\_factory module +------------------------------------- + +.. automodule:: apptools.naming.state_factory + :members: + :undoc-members: + :show-inheritance: + +apptools.naming.unique\_name module +----------------------------------- + +.. automodule:: apptools.naming.unique_name + :members: + :undoc-members: + :show-inheritance: + + +Module contents +--------------- + +.. automodule:: apptools.naming + :members: + :undoc-members: + :show-inheritance: diff --git a/4.5/_sources/api/apptools.naming.trait_defs.rst.txt b/4.5/_sources/api/apptools.naming.trait_defs.rst.txt new file mode 100644 index 000000000..b75680e73 --- /dev/null +++ b/4.5/_sources/api/apptools.naming.trait_defs.rst.txt @@ -0,0 +1,30 @@ +apptools.naming.trait\_defs package +=================================== + +Submodules +---------- + +apptools.naming.trait\_defs.api module +-------------------------------------- + +.. automodule:: apptools.naming.trait_defs.api + :members: + :undoc-members: + :show-inheritance: + +apptools.naming.trait\_defs.naming\_traits module +------------------------------------------------- + +.. automodule:: apptools.naming.trait_defs.naming_traits + :members: + :undoc-members: + :show-inheritance: + + +Module contents +--------------- + +.. automodule:: apptools.naming.trait_defs + :members: + :undoc-members: + :show-inheritance: diff --git a/_sources/api/apptools.naming.ui.rst.txt b/4.5/_sources/api/apptools.naming.ui.rst.txt similarity index 100% rename from _sources/api/apptools.naming.ui.rst.txt rename to 4.5/_sources/api/apptools.naming.ui.rst.txt diff --git a/_sources/api/apptools.permissions.action.rst.txt b/4.5/_sources/api/apptools.permissions.action.rst.txt similarity index 100% rename from _sources/api/apptools.permissions.action.rst.txt rename to 4.5/_sources/api/apptools.permissions.action.rst.txt diff --git a/_sources/api/apptools.permissions.adapters.rst.txt b/4.5/_sources/api/apptools.permissions.adapters.rst.txt similarity index 100% rename from _sources/api/apptools.permissions.adapters.rst.txt rename to 4.5/_sources/api/apptools.permissions.adapters.rst.txt diff --git a/_sources/api/apptools.permissions.default.rst.txt b/4.5/_sources/api/apptools.permissions.default.rst.txt similarity index 100% rename from _sources/api/apptools.permissions.default.rst.txt rename to 4.5/_sources/api/apptools.permissions.default.rst.txt diff --git a/_sources/api/apptools.permissions.rst.txt b/4.5/_sources/api/apptools.permissions.rst.txt similarity index 100% rename from _sources/api/apptools.permissions.rst.txt rename to 4.5/_sources/api/apptools.permissions.rst.txt diff --git a/4.5/_sources/api/apptools.persistence.rst.txt b/4.5/_sources/api/apptools.persistence.rst.txt new file mode 100644 index 000000000..ce06acc08 --- /dev/null +++ b/4.5/_sources/api/apptools.persistence.rst.txt @@ -0,0 +1,70 @@ +apptools.persistence package +============================ + +Submodules +---------- + +apptools.persistence.file\_path module +-------------------------------------- + +.. automodule:: apptools.persistence.file_path + :members: + :undoc-members: + :show-inheritance: + +apptools.persistence.project\_loader module +------------------------------------------- + +.. automodule:: apptools.persistence.project_loader + :members: + :undoc-members: + :show-inheritance: + +apptools.persistence.spickle module +----------------------------------- + +.. automodule:: apptools.persistence.spickle + :members: + :undoc-members: + :show-inheritance: + +apptools.persistence.state\_pickler module +------------------------------------------ + +.. automodule:: apptools.persistence.state_pickler + :members: + :undoc-members: + :show-inheritance: + +apptools.persistence.updater module +----------------------------------- + +.. automodule:: apptools.persistence.updater + :members: + :undoc-members: + :show-inheritance: + +apptools.persistence.version\_registry module +--------------------------------------------- + +.. automodule:: apptools.persistence.version_registry + :members: + :undoc-members: + :show-inheritance: + +apptools.persistence.versioned\_unpickler module +------------------------------------------------ + +.. automodule:: apptools.persistence.versioned_unpickler + :members: + :undoc-members: + :show-inheritance: + + +Module contents +--------------- + +.. automodule:: apptools.persistence + :members: + :undoc-members: + :show-inheritance: diff --git a/4.5/_sources/api/apptools.preferences.rst.txt b/4.5/_sources/api/apptools.preferences.rst.txt new file mode 100644 index 000000000..69d06e7c9 --- /dev/null +++ b/4.5/_sources/api/apptools.preferences.rst.txt @@ -0,0 +1,77 @@ +apptools.preferences package +============================ + +Subpackages +----------- + +.. toctree:: + + apptools.preferences.ui + +Submodules +---------- + +apptools.preferences.api module +------------------------------- + +.. automodule:: apptools.preferences.api + :members: + :undoc-members: + :show-inheritance: + +apptools.preferences.i\_preferences module +------------------------------------------ + +.. automodule:: apptools.preferences.i_preferences + :members: + :undoc-members: + :show-inheritance: + +apptools.preferences.package\_globals module +-------------------------------------------- + +.. automodule:: apptools.preferences.package_globals + :members: + :undoc-members: + :show-inheritance: + +apptools.preferences.preference\_binding module +----------------------------------------------- + +.. automodule:: apptools.preferences.preference_binding + :members: + :undoc-members: + :show-inheritance: + +apptools.preferences.preferences module +--------------------------------------- + +.. automodule:: apptools.preferences.preferences + :members: + :undoc-members: + :show-inheritance: + +apptools.preferences.preferences\_helper module +----------------------------------------------- + +.. automodule:: apptools.preferences.preferences_helper + :members: + :undoc-members: + :show-inheritance: + +apptools.preferences.scoped\_preferences module +----------------------------------------------- + +.. automodule:: apptools.preferences.scoped_preferences + :members: + :undoc-members: + :show-inheritance: + + +Module contents +--------------- + +.. automodule:: apptools.preferences + :members: + :undoc-members: + :show-inheritance: diff --git a/4.5/_sources/api/apptools.preferences.ui.rst.txt b/4.5/_sources/api/apptools.preferences.ui.rst.txt new file mode 100644 index 000000000..75986c10a --- /dev/null +++ b/4.5/_sources/api/apptools.preferences.ui.rst.txt @@ -0,0 +1,70 @@ +apptools.preferences.ui package +=============================== + +Submodules +---------- + +apptools.preferences.ui.api module +---------------------------------- + +.. automodule:: apptools.preferences.ui.api + :members: + :undoc-members: + :show-inheritance: + +apptools.preferences.ui.i\_preferences\_page module +--------------------------------------------------- + +.. automodule:: apptools.preferences.ui.i_preferences_page + :members: + :undoc-members: + :show-inheritance: + +apptools.preferences.ui.preferences\_manager module +--------------------------------------------------- + +.. automodule:: apptools.preferences.ui.preferences_manager + :members: + :undoc-members: + :show-inheritance: + +apptools.preferences.ui.preferences\_node module +------------------------------------------------ + +.. automodule:: apptools.preferences.ui.preferences_node + :members: + :undoc-members: + :show-inheritance: + +apptools.preferences.ui.preferences\_page module +------------------------------------------------ + +.. automodule:: apptools.preferences.ui.preferences_page + :members: + :undoc-members: + :show-inheritance: + +apptools.preferences.ui.tree\_item module +----------------------------------------- + +.. automodule:: apptools.preferences.ui.tree_item + :members: + :undoc-members: + :show-inheritance: + +apptools.preferences.ui.widget\_editor module +--------------------------------------------- + +.. automodule:: apptools.preferences.ui.widget_editor + :members: + :undoc-members: + :show-inheritance: + + +Module contents +--------------- + +.. automodule:: apptools.preferences.ui + :members: + :undoc-members: + :show-inheritance: diff --git a/4.5/_sources/api/apptools.rst.txt b/4.5/_sources/api/apptools.rst.txt new file mode 100644 index 000000000..7dbaaeb30 --- /dev/null +++ b/4.5/_sources/api/apptools.rst.txt @@ -0,0 +1,32 @@ +apptools package +================ + +Subpackages +----------- + +.. toctree:: + + apptools.appscripting + apptools.help + apptools.io + apptools.logger + apptools.lru_cache + apptools.naming + apptools.permissions + apptools.persistence + apptools.preferences + apptools.scripting + apptools.selection + apptools.sweet_pickle + apptools.template + apptools.type_manager + apptools.type_registry + apptools.undo + +Module contents +--------------- + +.. automodule:: apptools + :members: + :undoc-members: + :show-inheritance: diff --git a/4.5/_sources/api/apptools.scripting.rst.txt b/4.5/_sources/api/apptools.scripting.rst.txt new file mode 100644 index 000000000..7c2e0f04b --- /dev/null +++ b/4.5/_sources/api/apptools.scripting.rst.txt @@ -0,0 +1,62 @@ +apptools.scripting package +========================== + +Submodules +---------- + +apptools.scripting.api module +----------------------------- + +.. automodule:: apptools.scripting.api + :members: + :undoc-members: + :show-inheritance: + +apptools.scripting.package\_globals module +------------------------------------------ + +.. automodule:: apptools.scripting.package_globals + :members: + :undoc-members: + :show-inheritance: + +apptools.scripting.recordable module +------------------------------------ + +.. automodule:: apptools.scripting.recordable + :members: + :undoc-members: + :show-inheritance: + +apptools.scripting.recorder module +---------------------------------- + +.. automodule:: apptools.scripting.recorder + :members: + :undoc-members: + :show-inheritance: + +apptools.scripting.recorder\_with\_ui module +-------------------------------------------- + +.. automodule:: apptools.scripting.recorder_with_ui + :members: + :undoc-members: + :show-inheritance: + +apptools.scripting.util module +------------------------------ + +.. automodule:: apptools.scripting.util + :members: + :undoc-members: + :show-inheritance: + + +Module contents +--------------- + +.. automodule:: apptools.scripting + :members: + :undoc-members: + :show-inheritance: diff --git a/4.5/_sources/api/apptools.selection.rst.txt b/4.5/_sources/api/apptools.selection.rst.txt new file mode 100644 index 000000000..c96838354 --- /dev/null +++ b/4.5/_sources/api/apptools.selection.rst.txt @@ -0,0 +1,62 @@ +apptools.selection package +========================== + +Submodules +---------- + +apptools.selection.api module +----------------------------- + +.. automodule:: apptools.selection.api + :members: + :undoc-members: + :show-inheritance: + +apptools.selection.errors module +-------------------------------- + +.. automodule:: apptools.selection.errors + :members: + :undoc-members: + :show-inheritance: + +apptools.selection.i\_selection module +-------------------------------------- + +.. automodule:: apptools.selection.i_selection + :members: + :undoc-members: + :show-inheritance: + +apptools.selection.i\_selection\_provider module +------------------------------------------------ + +.. automodule:: apptools.selection.i_selection_provider + :members: + :undoc-members: + :show-inheritance: + +apptools.selection.list\_selection module +----------------------------------------- + +.. automodule:: apptools.selection.list_selection + :members: + :undoc-members: + :show-inheritance: + +apptools.selection.selection\_service module +-------------------------------------------- + +.. automodule:: apptools.selection.selection_service + :members: + :undoc-members: + :show-inheritance: + + +Module contents +--------------- + +.. automodule:: apptools.selection + :members: + :undoc-members: + :show-inheritance: diff --git a/_sources/api/apptools.sweet_pickle.rst.txt b/4.5/_sources/api/apptools.sweet_pickle.rst.txt similarity index 100% rename from _sources/api/apptools.sweet_pickle.rst.txt rename to 4.5/_sources/api/apptools.sweet_pickle.rst.txt diff --git a/_sources/api/apptools.template.impl.rst.txt b/4.5/_sources/api/apptools.template.impl.rst.txt similarity index 100% rename from _sources/api/apptools.template.impl.rst.txt rename to 4.5/_sources/api/apptools.template.impl.rst.txt diff --git a/_sources/api/apptools.template.rst.txt b/4.5/_sources/api/apptools.template.rst.txt similarity index 100% rename from _sources/api/apptools.template.rst.txt rename to 4.5/_sources/api/apptools.template.rst.txt diff --git a/_sources/api/apptools.template.test.rst.txt b/4.5/_sources/api/apptools.template.test.rst.txt similarity index 100% rename from _sources/api/apptools.template.test.rst.txt rename to 4.5/_sources/api/apptools.template.test.rst.txt diff --git a/_sources/api/apptools.type_manager.rst.txt b/4.5/_sources/api/apptools.type_manager.rst.txt similarity index 100% rename from _sources/api/apptools.type_manager.rst.txt rename to 4.5/_sources/api/apptools.type_manager.rst.txt diff --git a/4.5/_sources/api/apptools.type_registry.rst.txt b/4.5/_sources/api/apptools.type_registry.rst.txt new file mode 100644 index 000000000..ec2f8182a --- /dev/null +++ b/4.5/_sources/api/apptools.type_registry.rst.txt @@ -0,0 +1,30 @@ +apptools.type\_registry package +=============================== + +Submodules +---------- + +apptools.type\_registry.api module +---------------------------------- + +.. automodule:: apptools.type_registry.api + :members: + :undoc-members: + :show-inheritance: + +apptools.type\_registry.type\_registry module +--------------------------------------------- + +.. automodule:: apptools.type_registry.type_registry + :members: + :undoc-members: + :show-inheritance: + + +Module contents +--------------- + +.. automodule:: apptools.type_registry + :members: + :undoc-members: + :show-inheritance: diff --git a/4.5/_sources/api/apptools.undo.action.rst.txt b/4.5/_sources/api/apptools.undo.action.rst.txt new file mode 100644 index 000000000..b2e8fea8d --- /dev/null +++ b/4.5/_sources/api/apptools.undo.action.rst.txt @@ -0,0 +1,54 @@ +apptools.undo.action package +============================ + +Submodules +---------- + +apptools.undo.action.abstract\_command\_stack\_action module +------------------------------------------------------------ + +.. automodule:: apptools.undo.action.abstract_command_stack_action + :members: + :undoc-members: + :show-inheritance: + +apptools.undo.action.api module +------------------------------- + +.. automodule:: apptools.undo.action.api + :members: + :undoc-members: + :show-inheritance: + +apptools.undo.action.command\_action module +------------------------------------------- + +.. automodule:: apptools.undo.action.command_action + :members: + :undoc-members: + :show-inheritance: + +apptools.undo.action.redo\_action module +---------------------------------------- + +.. automodule:: apptools.undo.action.redo_action + :members: + :undoc-members: + :show-inheritance: + +apptools.undo.action.undo\_action module +---------------------------------------- + +.. automodule:: apptools.undo.action.undo_action + :members: + :undoc-members: + :show-inheritance: + + +Module contents +--------------- + +.. automodule:: apptools.undo.action + :members: + :undoc-members: + :show-inheritance: diff --git a/4.5/_sources/api/apptools.undo.rst.txt b/4.5/_sources/api/apptools.undo.rst.txt new file mode 100644 index 000000000..62fabb592 --- /dev/null +++ b/4.5/_sources/api/apptools.undo.rst.txt @@ -0,0 +1,77 @@ +apptools.undo package +===================== + +Subpackages +----------- + +.. toctree:: + + apptools.undo.action + +Submodules +---------- + +apptools.undo.abstract\_command module +-------------------------------------- + +.. automodule:: apptools.undo.abstract_command + :members: + :undoc-members: + :show-inheritance: + +apptools.undo.api module +------------------------ + +.. automodule:: apptools.undo.api + :members: + :undoc-members: + :show-inheritance: + +apptools.undo.command\_stack module +----------------------------------- + +.. automodule:: apptools.undo.command_stack + :members: + :undoc-members: + :show-inheritance: + +apptools.undo.i\_command module +------------------------------- + +.. automodule:: apptools.undo.i_command + :members: + :undoc-members: + :show-inheritance: + +apptools.undo.i\_command\_stack module +-------------------------------------- + +.. automodule:: apptools.undo.i_command_stack + :members: + :undoc-members: + :show-inheritance: + +apptools.undo.i\_undo\_manager module +------------------------------------- + +.. automodule:: apptools.undo.i_undo_manager + :members: + :undoc-members: + :show-inheritance: + +apptools.undo.undo\_manager module +---------------------------------- + +.. automodule:: apptools.undo.undo_manager + :members: + :undoc-members: + :show-inheritance: + + +Module contents +--------------- + +.. automodule:: apptools.undo + :members: + :undoc-members: + :show-inheritance: diff --git a/4.5/_sources/api/modules.rst.txt b/4.5/_sources/api/modules.rst.txt new file mode 100644 index 000000000..f51f30d15 --- /dev/null +++ b/4.5/_sources/api/modules.rst.txt @@ -0,0 +1,7 @@ +apptools +======== + +.. toctree:: + :maxdepth: 4 + + apptools diff --git a/_sources/appscripting/Introduction.rst.txt b/4.5/_sources/appscripting/Introduction.rst.txt similarity index 100% rename from _sources/appscripting/Introduction.rst.txt rename to 4.5/_sources/appscripting/Introduction.rst.txt diff --git a/4.5/_sources/index.rst.txt b/4.5/_sources/index.rst.txt new file mode 100644 index 000000000..9f69ab94c --- /dev/null +++ b/4.5/_sources/index.rst.txt @@ -0,0 +1,19 @@ +AppTools Documentation +============================================== + +.. toctree:: + :maxdepth: 2 + :glob: + + appscripting/* + permissions/Introduction + permissions/ApplicationAPI + permissions/DefaultPolicyManagerDataAPI + permissions/DefaultUserManagerDataAPI + preferences/* + scripting/* + undo/* + selection/* + api + +* :ref:`search` diff --git a/_sources/permissions/ApplicationAPI.rst.txt b/4.5/_sources/permissions/ApplicationAPI.rst.txt similarity index 100% rename from _sources/permissions/ApplicationAPI.rst.txt rename to 4.5/_sources/permissions/ApplicationAPI.rst.txt diff --git a/_sources/permissions/DefaultPolicyManagerDataAPI.rst.txt b/4.5/_sources/permissions/DefaultPolicyManagerDataAPI.rst.txt similarity index 100% rename from _sources/permissions/DefaultPolicyManagerDataAPI.rst.txt rename to 4.5/_sources/permissions/DefaultPolicyManagerDataAPI.rst.txt diff --git a/_sources/permissions/DefaultUserManagerDataAPI.rst.txt b/4.5/_sources/permissions/DefaultUserManagerDataAPI.rst.txt similarity index 100% rename from _sources/permissions/DefaultUserManagerDataAPI.rst.txt rename to 4.5/_sources/permissions/DefaultUserManagerDataAPI.rst.txt diff --git a/_sources/permissions/Introduction.rst.txt b/4.5/_sources/permissions/Introduction.rst.txt similarity index 100% rename from _sources/permissions/Introduction.rst.txt rename to 4.5/_sources/permissions/Introduction.rst.txt diff --git a/4.5/_sources/preferences/Preferences.rst.txt b/4.5/_sources/preferences/Preferences.rst.txt new file mode 100644 index 000000000..54148f110 --- /dev/null +++ b/4.5/_sources/preferences/Preferences.rst.txt @@ -0,0 +1,340 @@ +Preferences +=========== + +The preferences package provides a simple API for managing application +preferences. The classes in the package are implemented using a layered +approach where the lowest layer provides access to the raw preferences +mechanism and each layer on top providing more convenient ways to get and set +preference values. + +The Basic Preferences Mechanism +=============================== + +Lets start by taking a look at the lowest layer which consists of the +IPreferences_ interface and its default implementation in the Preferences_ +class. This layer implements the basic preferences system which is a +hierarchical arrangement of preferences 'nodes' (where each node is simply an +object that implements the IPreferences_ interface). Nodes in the hierarchy can +contain preference settings and/or child nodes. This layer also provides a +default way to read and write preferences from the filesystem using the +excellent ConfigObj_ package. + +This all sounds a bit complicated but, believe me, it isn't! To prove it +(hopefully) lets look at an example. Say I have the following preferences in +a file 'example.ini':: + + [acme.ui] + bgcolor = blue + width = 50 + ratio = 1.0 + visible = True + + [acme.ui.splash_screen] + image = splash + fgcolor = red + +I can create a preferences hierarchy from this file by:: + + >>> from apptools.preferences.api import Preferences + >>> preferences = Preferences(filename='example.ini') + >>> preferences.dump() + + Node() {} + Node(acme) {} + Node(ui) {'bgcolor': 'blue', 'ratio': '1.0', 'width': '50', 'visible': 'True'} + Node(splash_screen) {'image': 'splash', 'fgcolor': 'red'} + +The 'dump' method (useful for debugging etc) simply 'pretty prints' a +preferences hierarchy. The dictionary next to each node contains the node's +actual preferences. In this case, the root node (the node with no name) is the +preferences object that we created. This node now has one child node 'acme', +which contains no preferences. The 'acme' node has one child, 'ui', which +contains some preferences (e.g. 'bgcolor') and also a child node +'splash_screen' which also contains preferences (e.g. 'image'). + +To look up a preference we use:: + + >>> preferences.get('acme.ui.bgcolor') + 'blue' + +If no such preferences exists then, by default, None is returned:: + + >>> preferences.get('acme.ui.bogus') is None + True + +You can also specify an explicit default value:: + + >>> preferences.get('acme.ui.bogus', 'fred') + 'fred' + +To set a preference we use:: + + >>> preferences.set('acme.ui.bgcolor', 'red') + >>> preferences.get('acme.ui.bgcolor') + 'red' + +And to make sure the preferences are saved back to disk:: + + >>> preferences.flush() + +To add a new preference value we simply set it:: + + >>> preferences.set('acme.ui.fgcolor', 'black') + >>> preferences.get('acme.ui.fgcolor') + 'black' + +Any missing nodes in a call to 'set' are created automatically, hence:: + + >>> preferences.set('acme.ui.button.fgcolor', 'white') + >>> preferences.get('acme.ui.button.fgcolor') + 'white' + +Preferences can also be 'inherited'. e.g. Notice that the 'splash_screen' +node does not contain a 'bgcolor' preference, and hence:: + + >>> preferences.get('acme.ui.splash_screen.bgcolor') is None + True + +But if we allow the 'inheritance' of preference values then:: + + >>> preferences.get('acme.ui.splash_screen.bgcolor', inherit=True) + 'red' + +By using 'inheritance' here the preferences system will try the following +preferences:: + + 'acme.ui.splash_screen.bgcolor' + 'acme.ui.bgcolor' + 'acme.bgcolor' + 'bgcolor' + +Strings, Glorious Strings +------------------------- + +At this point it is worth mentioning that preferences are *always* stored and +returned as strings. This is because of the limitations of the traditional +'.ini' file format i.e. they don't contain any type information! Now before you +start panicking, this doesn't mean that all of your preferences have to be +strings! Currently the preferences system allows, strings(!), booleans, ints, +longs, floats and complex numbers. When you store a non-string value it gets +converted to a string for you, but you *always* get a string back:: + + >>> preferences.get('acme.ui.width') + '50' + >>> preferences.set('acme.ui.width', 100) + >>> preferences.get('acme.ui.width') + '100' + + >>> preferences.get('acme.ui.visible') + 'True' + >>> preferences.set('acme.ui.visible', False) + >>> preferences.get('acme.ui.visible') + 'False' + +This is obviously not terribly convenient, and so the following section +discusses how we associate type information with our preferences to make +getting and setting them more natural. + +Preferences and Types +===================== + +As mentioned previously, we would like to be able to get and set non-string +preferences in a more convenient way. This is where the PreferencesHelper_ +class comes in. + +Let's take another look at 'example.ini':: + + [acme.ui] + bgcolor = blue + width = 50 + ratio = 1.0 + visible = True + + [acme.ui.splash_screen] + image = splash + fgcolor = red + +Say, I am interested in the preferences in the 'acme.ui' section. I can use a +preferences helper as follows:: + + from apptools.preferences.api import PreferencesHelper + + class SplashScreenPreferences(PreferencesHelper): + """ A preferences helper for the splash screen. """ + + PREFERENCES_PATH = 'acme.ui' + + bgcolor = Str + width = Int + ratio = Float + visible = Bool + + >>> preferences = Preferences(filename='example.ini') + >>> helper = SplashScreenPreferences(preferences=preferences) + >>> helper.bgcolor + 'blue' + >>> helper.width + 100 + >>> helper.ratio + 1.0 + >>> helper.visible + True + +And, obviously, I can set the value of the preferences via the helper too:: + + >>> helper.ratio = 0.5 + +And if you want to prove to yourself it really did set the preference:: + + >>> preferences.get('acme.ui.ratio') + '0.5' + +Using a preferences helper you also get notified via the usual trait +mechanism when the preferences are changed (either via the helper or via the +preferences node directly:: + + def listener(obj, trait_name, old, new): + print(trait_name, old, new) + + >>> helper.on_trait_change(listener) + >>> helper.ratio = 0.75 + ratio 0.5 0.75 + >>> preferences.set('acme.ui.ratio', 0.33) + ratio 0.75 0.33 + +If you always use the same preference node as the root of your preferences you +can also set the class attribute 'PreferencesHelper.preferences' to be that +node and from then on in, you don't have to pass a preferences collection in +each time you create a helper:: + + >>> PreferencesHelper.preferences = Preferences(filename='example.ini') + >>> helper = SplashScreenPreferences() + >>> helper.bgcolor + 'blue' + >>> helper.width + 100 + >>> helper.ratio + 1.0 + >>> helper.visible + True + +Scoped Preferences +================== + +In many applications the idea of preferences scopes is useful. In a scoped +system, an actual preference value can be stored in any scope and when a call +is made to the 'get' method the scopes are searched in order of precedence. + +The default implementation (in the ScopedPreferences_ class) provides two +scopes by default: + +1) The application scope + +This scope stores itself in the 'ETSConfig.application_home' directory. This +scope is generally used when *setting* any user preferences. + +2) The default scope + +This scope is transient (i.e. it does not store itself anywhere). This scope +is generally used to load any predefined default values into the preferences +system. + +If you are happy with the default arrangement, then using the scoped +preferences is just like using the plain old non-scoped version:: + + >>> from apptools.preferences.api import ScopedPreferences + >>> preferences = ScopedPreferences(filename='example.ini') + >>> preferences.load('example.ini') + >>> p.dump() + + Node() {} + Node(application) {} + Node(acme) {} + Node(ui) {'bgcolor': 'blue', 'ratio': '1.0', 'width': '50', 'visible': 'True'} + Node(splash_screen) {'image': 'splash', 'fgcolor': 'red'} + Node(default) {} + +Here you can see that the root node now has a child node representing each +scope. + +When we are getting and setting preferences using scopes we generally want the +following behaviour: + +a) When we get a preference we want to look it up in each scope in order. The +first scope that contains a value 'wins'. + +b) When we set a preference, we want to set it in the first scope. By default +this means that when we set a preference it will be set in the application +scope. This is exactly what we want as the application scope is the scope that +is persistent. + +So usually, we just use the scoped preferences as before:: + + >>> preferences.get('acme.ui.bgcolor') + 'blue' + >>> preferences.set('acme.ui.bgcolor', 'red') + >>> preferences.dump() + + Node() {} + Node(application) {} + Node(acme) {} + Node(ui) {'bgcolor': 'red', 'ratio': '1.0', 'width': '50', 'visible': 'True'} + Node(splash_screen) {'image': 'splash', 'fgcolor': 'red'} + Node(default) {} + +And, conveniently, preference helpers work just the same with scoped +preferences too:: + + >>> PreferencesHelper.preferences = ScopedPreferences(filename='example.ini') + >>> helper = SplashScreenPreferences() + >>> helper.bgcolor + 'blue' + >>> helper.width + 100 + >>> helper.ratio + 1.0 + >>> helper.visible + True + +Accessing a particular scope +---------------------------- + +Should you care about getting or setting a preference in a particular scope +then you use the following syntax:: + + >>> preferences.set('default/acme.ui.bgcolor', 'red') + >>> preferences.get('default/acme.ui.bgcolor') + 'red' + >>> preferences.dump() + + Node() {} + Node(application) {} + Node(acme) {} + Node(ui) {'bgcolor': 'red', 'ratio': '1.0', 'width': '50', 'visible': 'True'} + Node(splash_screen) {'image': 'splash', 'fgcolor': 'red'} + Node(default) {} + Node(acme) {} + Node(ui) {'bgcolor': 'red'} + +You can also get hold of a scope via:: + + >>> default = preferences.get_scope('default') + +And then perform any of the usual operations on it. + +Further Reading +=============== + +So that's a quick tour around the basic useage of the preferences API. For more +imformation about what is provided take a look at the API_ documentation. + +If you are using Envisage to build your applications then you might also be +interested in the `Preferences in Envisage`_ section. + +.. _API: api/index.html +.. _ConfigObj: http://www.voidspace.org.uk/python/configobj.html +.. _IPreferences: ../../enthought/preferences/i_preferences.py +.. _Preferences: ../../enthought/preferences/preferences.py +.. _PreferencesHelper: ../../enthought/preferences/preferences_helper.py +.. _ScopedPreferences: ../../enthought/preferences/scoped_preferences.py +.. _`Preferences in Envisage`: PreferencesInEnvisage.html diff --git a/4.5/_sources/preferences/PreferencesInEnvisage.rst.txt b/4.5/_sources/preferences/PreferencesInEnvisage.rst.txt new file mode 100644 index 000000000..f317477d1 --- /dev/null +++ b/4.5/_sources/preferences/PreferencesInEnvisage.rst.txt @@ -0,0 +1,47 @@ +Preferences in Envisage +======================= + +This section discusses how an Envisage application uses the preferences +mechanism. Envisage tries not to dictate too much, and so this describes the +default behaviour, but you are free to override it as desired. + +Envisage uses the default implementation of the ScopedPreferences_ class which +is made available via the application's 'preferences' trait:: + + >>> application = Application(id='myapplication') + >>> application.preferences.set('acme.ui.bgcolor', 'yellow') + >>> application.preferences.get('acme.ui.bgcolor') + 'yellow' + +Hence, you use the Envisage preferences just like you would any other scoped +preferences. + +It also registers itself as the default preferences node used by the +PreferencesHelper_ class. Hence you don't need to provide a preferences node +explicitly to your helper:: + + >>> helper = SplashScreenPreferences() + >>> helper.bgcolor + 'blue' + >>> helper.width + 100 + >>> helper.ratio + 1.0 + >>> helper.visible + True + +The only extra thing that Envisage does for you is to provide an extension +point that allows you to contribute any number of '.ini' files that are +loaded into the default scope when the application is started. + +e.g. To contribute a preference file for my plugin I might use:: + + class MyPlugin(Plugin): + ... + + @contributes_to('envisage.preferences') + def get_preferences(self, application): + return ['pkgfile://mypackage:preferences.ini'] + +.. _PreferencesHelper: ../../enthought/preferences/preferences_helper.py +.. _ScopedPreferences: ../../enthought/preferences/scoped_preferences.py diff --git a/4.5/_sources/scripting/introduction.rst.txt b/4.5/_sources/scripting/introduction.rst.txt new file mode 100644 index 000000000..6772b764f --- /dev/null +++ b/4.5/_sources/scripting/introduction.rst.txt @@ -0,0 +1,197 @@ +.. _automatic-script-recording: + +Automatic script recording +=========================== + +This package provides a very handy and powerful Python script recording +facility. This can be used to: + + - record all actions performed on a traits based UI into a *human + readable*, Python script that should be able to recreate your UI + actions. + + - easily learn the scripting API of an application. + +This package is not just a toy framework and is powerful enough to +provide full script recording to the Mayavi_ application. Mayavi is a +powerful 3D visualization tool that is part of ETS_. + +.. _Mayavi: http://code.enthought.com/projects/mayavi +.. _ETS: http://code.enthought.com/projects/tool-suite.php + +.. _scripting-api: + + +The scripting API +------------------ + +The scripting API primarily allows you to record UI actions for objects +that have Traits. Technically the framework listens to all trait +changes so will work outside a UI. We do not document the full API +here, the best place to look for that is the +``apptools.scripting.recorder`` module which is reasonably well +documented. We provide a high level overview of the library. + +The quickest way to get started is to look at a small example. + + +.. _scripting-api-example: + +A tour by example +~~~~~~~~~~~~~~~~~~~ + +The following example is taken from the test suite. Consider a set of +simple objects organized in a hierarchy:: + + from traits.api import (HasTraits, Float, Instance, + Str, List, Bool, HasStrictTraits, Tuple, Range, TraitPrefixMap, + Trait) + from apptools.scripting.api import (Recorder, recordable, + set_recorder) + + class Property(HasStrictTraits): + color = Tuple(Range(0.0, 1.0), Range(0.0, 1.0), Range(0.0, 1.0)) + opacity = Range(0.0, 1.0, 1.0) + representation = Trait('surface', + TraitPrefixMap({'surface':2, + 'wireframe': 1, + 'points': 0})) + class Toy(HasTraits): + color = Str + type = Str + # Note the use of the trait metadata to ignore this trait. + ignore = Bool(False, record=False) + + class Child(HasTraits): + name = Str('child') + age = Float(10.0) + # The recorder walks through sub-instances if they are marked + # with record=True + property = Instance(Property, (), record=True) + toy = Instance(Toy, record=True) + friends = List(Str) + + # The decorator records the method. + @recordable + def grow(self, x): + """Increase age by x years.""" + self.age += x + + class Parent(HasTraits): + children = List(Child, record=True) + recorder = Instance(Recorder, record=False) + +Using these simple classes we first create a simple object hierarchy as +follows:: + + p = Parent() + c = Child() + t = Toy() + c.toy = t + p.children.append(c) + +Given this hierarchy, we'd like to be able to record a script. To do +this we setup the recording infrastructure:: + + from mayavi.core.recorder import Recorder, set_recorder + # Create a recorder. + r = Recorder() + # Set the global recorder so the decorator works. + set_recorder(r) + r.register(p) + r.recording = True + +The key method here is the ``r.register(p)`` call above. It looks at +the traits of ``p`` and finds all traits and nested objects that specify +a ``record=True`` in their trait metadata (all methods starting and +ending with ``_`` are ignored). All sub-objects are in turn registered +with the recorder and so on. Callbacks are attached to traits changes +and these are wired up to produce readable and executable code. The +``set_recorder(r)`` call is also very important and sets the global +recorder so the framework listens to any functions that are decorated +with the ``recordable`` decorator. + +Now lets test this out like so:: + + # The following will be recorded. + c.name = 'Shiva' + c.property.representation = 'w' + c.property.opacity = 0.4 + c.grow(1) + +To see what's been recorded do this:: + + print(r.script) + +This prints:: + + child = parent.children[0] + child.name = 'Shiva' + child.property.representation = 'wireframe' + child.property.opacity = 0.40000000000000002 + child.grow(1) + +The recorder internally maintains a mapping between objects and unique +names for each object. It also stores the information about the +location of a particular object in the object hierarchy. For example, +the path to the ``Toy`` instance in the hierarchy above is +``parent.children[0].toy``. Since scripting with lists this way can be +tedious, the recorder first instantiates the ``child``:: + + child = parent.children[0] + +Subsequent lines use the ``child`` attribute. The recorder always tries +to instantiate the object referred to using its path information in this +manner. + +To record a function or method call one must simply decorate the +function/method with the ``recordable`` decorator. Nested recordable +functions are not recorded and trait changes are also not recorded if +done inside a recordable function. + +.. note:: + + 1. It is very important to note that the global recorder must be set + via the ``set_recorder`` method. The ``recordable`` decorator + relies on this being set to work. + + 2. The ``recordable`` decorator will work with plain Python classes + and with functions too. + +To stop recording do this:: + + r.unregister(p) + r.recording = False + +The ``r.unregister(p)`` reverses the ``r.register(p)`` call and +unregisters all nested objects as well. + + +.. _recorder-advanced-uses: + +Advanced use cases +~~~~~~~~~~~~~~~~~~~~ + +Here are a few advanced use cases. + + - The API also provides a ``RecorderWithUI`` class that provides a + simple user interface that prints the recorded script and allows the + user to save the script. + + - Sometimes it is not enough to just record trait changes, one may want + to pass an arbitrary string or command when recording is occurring. + To allow for this, if one defines a ``recorder`` trait on the object, + it is set to the current recorder. One can then use this recorder to + do whatever one wants. This is very convenient. + + - To ignore specific traits one must specify either a ``record=False`` + metadata to the trait definition or specify a list of strings to the + ``register`` method in the ``ignore`` keyword argument. + + - If you want to use a specific name for an object on the script you + can pass the ``script_id`` parameter to the register function. + + +For more details on the recorder itself we suggest reading the module +source code. It is fairly well documented and with the above background +should be enough to get you going. diff --git a/4.5/_sources/selection/selection.rst.txt b/4.5/_sources/selection/selection.rst.txt new file mode 100644 index 000000000..975ed2f9c --- /dev/null +++ b/4.5/_sources/selection/selection.rst.txt @@ -0,0 +1,195 @@ +.. _selection_service: + +The selection service +===================== + +It is quite common in GUI applications to have a UI element displaying a +collection of items that a user can select ("selection providers"), while +other parts of the application must react to changes in the selection +("selection listeners"). + +Ideally, the listeners would not have a direct dependency on the UI object. +This is especially important in extensible `envisage`_ applications, where +a plugin might need to react to a selection change, but we do not want to +expose the internal organization of the application to external developers. + +This package defines a selection service that manages the communication +between providers and listener. + + +The :class:`~.SelectionService` object +-------------------------------------- + +The :class:`~.SelectionService` object is the central manager that handles +the communication between selection providers and listener. + +:ref:`Selection providers ` are components that wish to +publish information about their current selection for public consumption. +They register to a selection +service instance when they first have a selection available (e.g., when the +UI showing a list of selectable items is initialized), and un-register as soon +as the selection is not available anymore (e.g., the UI is destroyed when the +windows is closed). + +:ref:`Selection listeners ` can query the selection +service to get the current selection published by a provider, using the +provider unique ID. + +The service acts as a broker between providers and listeners, making sure that +they are notified when the +:attr:`~apptools.selection.i_selection_provider.ISelectionProvider.selection` +event is fired. + +.. _selection_providers: + +Selection providers +------------------- + +Any object can become a selection provider by implementing the +:class:`~apptools.selection.i_selection_provider.ISelectionProvider` +interface, and registering to the selection service. + +Selection providers must provide a unique ID +:attr:`~apptools.selection.i_selection_provider.ISelectionProvider.provider_id`, +which is used by listeners to request its current selection. + +Whenever its selection changes, providers fire a +:attr:`~apptools.selection.i_selection_provider.ISelectionProvider.selection` +event. The content of the event is an instance implementing +:class:`~.ISelection` that contains information about the selected items. +For example, a :class:`~.ListSelection` object contains a list of selected +items, and their indices. + +Selection providers can also be queried directly about their current selection +using the +:attr:`~apptools.selection.i_selection_provider.ISelectionProvider.get_selection` +method, and can be requested to change their selection to a new one with the +:attr:`~apptools.selection.i_selection_provider.ISelectionProvider.set_selection` +method. + +Registration +~~~~~~~~~~~~ + +Selection providers publish their selection by registering to the selection +service using the +:attr:`~apptools.selection.selection_service.SelectionService.add_selection_provider` +method. When the selection is no longer available, selection providers +should un-register through +:attr:`~apptools.selection.selection_service.SelectionService.remove_selection_provider`. + +Typically, selection providers are UI objects showing a list or tree of items, +they register as soon as the UI component is initialized, and un-register +when the UI component disappears (e.g., because their window has been closed). +In more complex applications, the registration could be done by a controller +object instead. + +.. _selection_listeners: + +Selection listeners +------------------- + +Selection listeners request information regarding the current selection +of a selection provider given their provider ID. The :class:`~.SelectionService` +supports two distinct use cases: + + 1) Passively listening to selection changes: listener connect to a specific + provider and are notified when the provider's selection changes. + + 2) Actively querying a provider for its current selection: the selection + service can be used to query a provider using its unique ID. + +Passive listening +~~~~~~~~~~~~~~~~~ + +Listeners connect to the selection events for a given provider using the +:attr:`~apptools.selection.selection_service.SelectionService.connect_selection_listener` +method. They need to provide the unique ID of the provider, and a function +(or callable) that is called to send the event. This callback function takes +one argument, an implementation of the :class:`~.ISelection` that represents +the selection. + +It is possible for a listener to connect to a provider ID before it is +registered. As soon as the provider is registered, the listener will receive +a notification containing the provider's initial selection. + +To disconnect a listener use the methods +:attr:`~apptools.selection.selection_service.SelectionService.disconnect_selection_listener`. + +Active querying +~~~~~~~~~~~~~~~ + +In other instances, an element of the application only needs the current +selection at a specific time. For example, a toolbar button could open dialog +representing a user action based on what is currently selected in the active +editor. + +The +:attr:`~apptools.selection.selection_service.SelectionService.get_selection` +method calls the corresponding method on the provider with the given ID and +returns an :class:`~.ISelection` instance. + +Setting a selection +~~~~~~~~~~~~~~~~~~~ + +Finally, it is possible to request a provider to set its selection to a given +set of objects with +:attr:`~apptools.selection.selection_service.SelectionService.set_selection`. +The main use case for this method is multiple views of the same list of +objects, which need to keep their selection synchronized. + +If the items specified in the arguments are not available in the provider, +a :class:`~apptools.selection.errors.ProviderNotRegisteredError` is raised, +unless the optional keyword argument :attr:`ignore_missing` is set to ``True``. + + +API Reference +------------- + +:mod:`apptools.selection` Package +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Users of the :mod:`apptools.selection` package can access the objects that are +part of the public API through the convenience :mod:`apptools.selection.api`. + +:mod:`~apptools.selection.selection_service` Module +''''''''''''''''''''''''''''''''''''''''''''''''''' + +.. automodule:: apptools.selection.selection_service + :members: + :undoc-members: + :show-inheritance: + +:mod:`~apptools.selection.i_selection_provider` Module +'''''''''''''''''''''''''''''''''''''''''''''''''''''' + +.. automodule:: apptools.selection.i_selection_provider + :members: + :undoc-members: + :show-inheritance: + +:mod:`~apptools.selection.is_selection` Module +'''''''''''''''''''''''''''''''''''''''''''''' + +.. automodule:: apptools.selection.i_selection + :members: + :undoc-members: + :show-inheritance: + +:mod:`~apptools.selection.list_selection` Module +'''''''''''''''''''''''''''''''''''''''''''''''' + +.. automodule:: apptools.selection.list_selection + :members: + :undoc-members: + :show-inheritance: + +:mod:`~apptools.selection.errors` Module +'''''''''''''''''''''''''''''''''''''''''''''''' + +.. automodule:: apptools.selection.errors + :members: + :undoc-members: + :show-inheritance: + + +.. _envisage: http://docs.enthought.com/envisage/ diff --git a/4.5/_sources/undo/Introduction.rst.txt b/4.5/_sources/undo/Introduction.rst.txt new file mode 100644 index 000000000..d182f862d --- /dev/null +++ b/4.5/_sources/undo/Introduction.rst.txt @@ -0,0 +1,275 @@ +Undo Framework +============== + +The Undo Framework is a component of the Enthought Tool Suite that provides +developers with an API that implements the standard pattern for do/undo/redo +commands. + +The framework is completely configurable. Alternate implementations of all +major components can be provided if necessary. + + +Framework Concepts +------------------ + +The following are the concepts supported by the framework. + +- Command + + A command is an application defined operation that can be done (i.e. + executed), undone (i.e. reverted) and redone (i.e. repeated). + + A command operates on some data and maintains sufficient state to allow it to + revert or repeat a change to the data. + + Commands may be merged so that potentially long sequences of similar + commands (e.g. to add a character to some text) can be collapsed into a + single command (e.g. to add a word to some text). + +- Macro + + A macro is a sequence of commands that is treated as a single command when + being undone or redone. + +- Command Stack + + A command is done by pushing it onto a command stack. The last command can + be undone and redone by calling appropriate command stack methods. It is + also possible to move the stack's position to any point and the command stack + will ensure that commands are undone or redone as required. + + A command stack maintains a *clean* state which is updated as commands are + done and undone. It may be explicitly set, for example when the data being + manipulated by the commands is saved to disk. + + Canned PyFace actions are provided as wrappers around command stack methods + to implement common menu items. + +- Undo Manager + + An undo manager is responsible for one or more command stacks and maintains + a reference to the currently active stack. It provides convenience undo and + redo methods that operate on the currently active stack. + + An undo manager ensures that each command execution is allocated a unique + sequence number, irrespective of which command stack it is pushed to. Using + this it is possible to synchronise multiple command stacks and restore them + to a particular point in time. + + An undo manager will generate an event whenever the clean state of the active + stack changes. This can be used to maintain some sort of GUI status + indicator to tell the user that their data has been modified since it was + last saved. + +Typically an application will have one undo manager and one undo stack for +each data type that can be edited. However this is not a requirement: how the +command stack's in particular are organised and linked (with the user +manager's sequence number) can need careful thought so as not to confuse the +user - particularly in a plugin based application that may have many editors. + +To support this typical usage the PyFace ``Workbench`` class has an +``undo_manager`` trait and the PyFace ``Editor`` class has a ``command_stack`` +trait. Both are lazy loaded so can be completely ignored if they are not used. + + +API Overview +------------ + +This section gives a brief overview of the various classes implemented in the +framework. The complete API_ documentation is available as endo generated +HTML. + +The example_ application demonstrates all the major features of the framework. + + +UndoManager +........... + +The ``UndoManager`` class is the default implementation of the ``IUndoManager`` +interface. + +``active_stack`` + This trait is a reference to the currently active command stack and may be + None. Typically it is set when some sort of editor becomes active. + +``active_stack_clean`` + This boolean trait reflects the clean state of the currently active + command stack. It is intended to support a "document modified" indicator + in the GUI. It is maintained by the undo manager. + +``stack_updated`` + This event is fired when the index of a command stack is changed. A + reference to the stack is passed as an argument to the event and may not + be the currently active stack. + +``undo_name`` + This Unicode trait is the name of the command that can be undone, and will + be empty if there is no such command. It is maintained by the undo + manager. + +``redo_name`` + This Unicode trait is the name of the command that can be redone, and will + be empty if there is no such command. It is maintained by the undo + manager. + +``sequence_nr`` + This integer trait is the sequence number of the next command to be + executed. It is incremented immediately before a command's ``do()`` + method is called. A particular sequence number identifies the state of + all command stacks handled by the undo manager and allows those stacks to + be set to the point they were at at a particular point in time. In other + words, the sequence number allows otherwise independent command stacks to + be synchronised. + +``undo()`` + This method calls the ``undo()`` method of the last command on the active + command stack. + +``redo()`` + This method calls the ``redo()`` method of the last undone command on the + active command stack. + + +CommandStack +............ + +The ``CommandStack`` class is the default implementation of the +``ICommandStack`` interface. + +``clean`` + This boolean traits reflects the clean state of the command stack. Its + value changes as commands are executed, undone and redone. It may also be + explicitly set to mark the current stack position as being clean (when + data is saved to disk for example). + +``undo_name`` + This Unicode trait is the name of the command that can be undone, and will + be empty if there is no such command. It is maintained by the command + stack. + +``redo_name`` + This Unicode trait is the name of the command that can be redone, and will + be empty if there is no such command. It is maintained by the command + stack. + +``undo_manager`` + This trait is a reference to the undo manager that manages the command + stack. + +``push(command)`` + This method executes the given command by calling its ``do()`` method. + Any value returned by ``do()`` is returned by ``push()``. If the command + couldn't be merged with the previous one then it is saved on the command + stack. + +``undo(sequence_nr=0)`` + This method undoes the last command. If a sequence number is given then + all commands are undone up to an including the sequence number. + +``redo(sequence_nr=0)`` + This method redoes the last command and returns any result. If a sequence + number is given then all commands are redone up to an including the + sequence number and any result of the last of these is returned. + +``clear()`` + This method clears the command stack, without undoing or redoing any + commands, and leaves the stack in a clean state. It is typically used + when all changes to the data have been abandoned. + +``begin_macro(name)`` + This method begins a macro by creating an empty command with the given + name. The commands passed to all subsequent calls to ``push()`` will be + contained in the macro until the next call to ``end_macro()``. Macros may + be nested. The command stack is disabled (ie. nothing can be undone or + redone) while a macro is being created (ie. while there is an outstanding + ``end_macro()`` call). + +``end_macro()`` + This method ends the current macro. + + +ICommand +........ + +The ``ICommand`` interface defines the interface that must be implemented by +any undoable/redoable command. + +``data`` + This optional trait is a reference to the data object that the command + operates on. It is not used by the framework itself. + +``name`` + This Unicode trait is the name of the command as it will appear in any GUI + element (e.g. in the text of an undo and redo menu entry). It may include + ``&`` to indicate a keyboard shortcut which will be automatically removed + whenever it is inappropriate. + +``__init__(*args)`` + If the command takes arguments then the command must ensure that deep + copies should be made if appropriate. + +``do()`` + This method is called by a command stack to execute the command and to + return any result. The command must save any state necessary for the + ``undo()`` and ``redo()`` methods to work. It is guaranteed that this + will only ever be called once and that it will be called before any call + to ``undo()`` or ``redo()``. + +``undo()`` + This method is called by a command stack to undo the command. + +``redo()`` + This method is called by a command stack to redo the command and to return + any result. + +``merge(other)`` + This method is called by the command stack to try and merge the ``other`` + command with this one. True should be returned if the commands were + merged. If the commands are merged then ``other`` will not be placed on + the command stack. A subsequent undo or redo of this modified command + must have the same effect as the two original commands. + + +AbstractCommand +............... + +``AbstractCommand`` is an abstract base class that implements the ``ICommand`` +interface. It provides a default implementation of the ``merge()`` method. + + +CommandAction +............. + +The ``CommandAction`` class is a sub-class of the PyFace ``Action`` class that +is used to wrap commands. + +``command`` + This callable trait must be set to a factory that will return an object + that implements ``ICommand``. It will be called when the action is invoked + and the object created pushed onto the command stack. + +``command_stack`` + This instance trait must be set to the command stack that commands invoked + by the action are pushed to. + +``data`` + This optional trait is a reference to the data object that will be passed + to the ``command`` factory when it is called. + + +UndoAction +.......... + +The ``UndoAction`` class is a canned PyFace action that undoes the last +command of the active command stack. + + +RedoAction +.......... + +The ``RedoAction`` class is a canned PyFace action that redoes the last +command undone of the active command stack. + + +.. _API: api/index.html +.. _example: https://svn.enthought.com/enthought/browser/AppTools/trunk/examples/undo/ diff --git a/_static/ajax-loader.gif b/4.5/_static/ajax-loader.gif similarity index 100% rename from _static/ajax-loader.gif rename to 4.5/_static/ajax-loader.gif diff --git a/4.5/_static/basic.css b/4.5/_static/basic.css new file mode 100644 index 000000000..0807176ec --- /dev/null +++ b/4.5/_static/basic.css @@ -0,0 +1,676 @@ +/* + * basic.css + * ~~~~~~~~~ + * + * Sphinx stylesheet -- basic theme. + * + * :copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ + +/* -- main layout ----------------------------------------------------------- */ + +div.clearer { + clear: both; +} + +/* -- relbar ---------------------------------------------------------------- */ + +div.related { + width: 100%; + font-size: 90%; +} + +div.related h3 { + display: none; +} + +div.related ul { + margin: 0; + padding: 0 0 0 10px; + list-style: none; +} + +div.related li { + display: inline; +} + +div.related li.right { + float: right; + margin-right: 5px; +} + +/* -- sidebar --------------------------------------------------------------- */ + +div.sphinxsidebarwrapper { + padding: 10px 5px 0 10px; +} + +div.sphinxsidebar { + float: left; + width: 230px; + margin-left: -100%; + font-size: 90%; + word-wrap: break-word; + overflow-wrap : break-word; +} + +div.sphinxsidebar ul { + list-style: none; +} + +div.sphinxsidebar ul ul, +div.sphinxsidebar ul.want-points { + margin-left: 20px; + list-style: square; +} + +div.sphinxsidebar ul ul { + margin-top: 0; + margin-bottom: 0; +} + +div.sphinxsidebar form { + margin-top: 10px; +} + +div.sphinxsidebar input { + border: 1px solid #98dbcc; + font-family: sans-serif; + font-size: 1em; +} + +div.sphinxsidebar #searchbox form.search { + overflow: hidden; +} + +div.sphinxsidebar #searchbox input[type="text"] { + float: left; + width: 80%; + padding: 0.25em; + box-sizing: border-box; +} + +div.sphinxsidebar #searchbox input[type="submit"] { + float: left; + width: 20%; + border-left: none; + padding: 0.25em; + box-sizing: border-box; +} + + +img { + border: 0; + max-width: 100%; +} + +/* -- search page ----------------------------------------------------------- */ + +ul.search { + margin: 10px 0 0 20px; + padding: 0; +} + +ul.search li { + padding: 5px 0 5px 20px; + background-image: url(file.png); + background-repeat: no-repeat; + background-position: 0 7px; +} + +ul.search li a { + font-weight: bold; +} + +ul.search li div.context { + color: #888; + margin: 2px 0 0 30px; + text-align: left; +} + +ul.keywordmatches li.goodmatch a { + font-weight: bold; +} + +/* -- index page ------------------------------------------------------------ */ + +table.contentstable { + width: 90%; + margin-left: auto; + margin-right: auto; +} + +table.contentstable p.biglink { + line-height: 150%; +} + +a.biglink { + font-size: 1.3em; +} + +span.linkdescr { + font-style: italic; + padding-top: 5px; + font-size: 90%; +} + +/* -- general index --------------------------------------------------------- */ + +table.indextable { + width: 100%; +} + +table.indextable td { + text-align: left; + vertical-align: top; +} + +table.indextable ul { + margin-top: 0; + margin-bottom: 0; + list-style-type: none; +} + +table.indextable > tbody > tr > td > ul { + padding-left: 0em; +} + +table.indextable tr.pcap { + height: 10px; +} + +table.indextable tr.cap { + margin-top: 10px; + background-color: #f2f2f2; +} + +img.toggler { + margin-right: 3px; + margin-top: 3px; + cursor: pointer; +} + +div.modindex-jumpbox { + border-top: 1px solid #ddd; + border-bottom: 1px solid #ddd; + margin: 1em 0 1em 0; + padding: 0.4em; +} + +div.genindex-jumpbox { + border-top: 1px solid #ddd; + border-bottom: 1px solid #ddd; + margin: 1em 0 1em 0; + padding: 0.4em; +} + +/* -- domain module index --------------------------------------------------- */ + +table.modindextable td { + padding: 2px; + border-collapse: collapse; +} + +/* -- general body styles --------------------------------------------------- */ + +div.body { + min-width: 450px; + max-width: 800px; +} + +div.body p, div.body dd, div.body li, div.body blockquote { + -moz-hyphens: auto; + -ms-hyphens: auto; + -webkit-hyphens: auto; + hyphens: auto; +} + +a.headerlink { + visibility: hidden; +} + +h1:hover > a.headerlink, +h2:hover > a.headerlink, +h3:hover > a.headerlink, +h4:hover > a.headerlink, +h5:hover > a.headerlink, +h6:hover > a.headerlink, +dt:hover > a.headerlink, +caption:hover > a.headerlink, +p.caption:hover > a.headerlink, +div.code-block-caption:hover > a.headerlink { + visibility: visible; +} + +div.body p.caption { + text-align: inherit; +} + +div.body td { + text-align: left; +} + +.first { + margin-top: 0 !important; +} + +p.rubric { + margin-top: 30px; + font-weight: bold; +} + +img.align-left, .figure.align-left, object.align-left { + clear: left; + float: left; + margin-right: 1em; +} + +img.align-right, .figure.align-right, object.align-right { + clear: right; + float: right; + margin-left: 1em; +} + +img.align-center, .figure.align-center, object.align-center { + display: block; + margin-left: auto; + margin-right: auto; +} + +.align-left { + text-align: left; +} + +.align-center { + text-align: center; +} + +.align-right { + text-align: right; +} + +/* -- sidebars -------------------------------------------------------------- */ + +div.sidebar { + margin: 0 0 0.5em 1em; + border: 1px solid #ddb; + padding: 7px 7px 0 7px; + background-color: #ffe; + width: 40%; + float: right; +} + +p.sidebar-title { + font-weight: bold; +} + +/* -- topics ---------------------------------------------------------------- */ + +div.topic { + border: 1px solid #ccc; + padding: 7px 7px 0 7px; + margin: 10px 0 10px 0; +} + +p.topic-title { + font-size: 1.1em; + font-weight: bold; + margin-top: 10px; +} + +/* -- admonitions ----------------------------------------------------------- */ + +div.admonition { + margin-top: 10px; + margin-bottom: 10px; + padding: 7px; +} + +div.admonition dt { + font-weight: bold; +} + +div.admonition dl { + margin-bottom: 0; +} + +p.admonition-title { + margin: 0px 10px 5px 0px; + font-weight: bold; +} + +div.body p.centered { + text-align: center; + margin-top: 25px; +} + +/* -- tables ---------------------------------------------------------------- */ + +table.docutils { + border: 0; + border-collapse: collapse; +} + +table.align-center { + margin-left: auto; + margin-right: auto; +} + +table caption span.caption-number { + font-style: italic; +} + +table caption span.caption-text { +} + +table.docutils td, table.docutils th { + padding: 1px 8px 1px 5px; + border-top: 0; + border-left: 0; + border-right: 0; + border-bottom: 1px solid #aaa; +} + +table.footnote td, table.footnote th { + border: 0 !important; +} + +th { + text-align: left; + padding-right: 5px; +} + +table.citation { + border-left: solid 1px gray; + margin-left: 1px; +} + +table.citation td { + border-bottom: none; +} + +/* -- figures --------------------------------------------------------------- */ + +div.figure { + margin: 0.5em; + padding: 0.5em; +} + +div.figure p.caption { + padding: 0.3em; +} + +div.figure p.caption span.caption-number { + font-style: italic; +} + +div.figure p.caption span.caption-text { +} + +/* -- field list styles ----------------------------------------------------- */ + +table.field-list td, table.field-list th { + border: 0 !important; +} + +.field-list ul { + margin: 0; + padding-left: 1em; +} + +.field-list p { + margin: 0; +} + +.field-name { + -moz-hyphens: manual; + -ms-hyphens: manual; + -webkit-hyphens: manual; + hyphens: manual; +} + +/* -- hlist styles ---------------------------------------------------------- */ + +table.hlist td { + vertical-align: top; +} + + +/* -- other body styles ----------------------------------------------------- */ + +ol.arabic { + list-style: decimal; +} + +ol.loweralpha { + list-style: lower-alpha; +} + +ol.upperalpha { + list-style: upper-alpha; +} + +ol.lowerroman { + list-style: lower-roman; +} + +ol.upperroman { + list-style: upper-roman; +} + +dl { + margin-bottom: 15px; +} + +dd p { + margin-top: 0px; +} + +dd ul, dd table { + margin-bottom: 10px; +} + +dd { + margin-top: 3px; + margin-bottom: 10px; + margin-left: 30px; +} + +dt:target, span.highlighted { + background-color: #fbe54e; +} + +rect.highlighted { + fill: #fbe54e; +} + +dl.glossary dt { + font-weight: bold; + font-size: 1.1em; +} + +.optional { + font-size: 1.3em; +} + +.sig-paren { + font-size: larger; +} + +.versionmodified { + font-style: italic; +} + +.system-message { + background-color: #fda; + padding: 5px; + border: 3px solid red; +} + +.footnote:target { + background-color: #ffa; +} + +.line-block { + display: block; + margin-top: 1em; + margin-bottom: 1em; +} + +.line-block .line-block { + margin-top: 0; + margin-bottom: 0; + margin-left: 1.5em; +} + +.guilabel, .menuselection { + font-family: sans-serif; +} + +.accelerator { + text-decoration: underline; +} + +.classifier { + font-style: oblique; +} + +abbr, acronym { + border-bottom: dotted 1px; + cursor: help; +} + +/* -- code displays --------------------------------------------------------- */ + +pre { + overflow: auto; + overflow-y: hidden; /* fixes display issues on Chrome browsers */ +} + +span.pre { + -moz-hyphens: none; + -ms-hyphens: none; + -webkit-hyphens: none; + hyphens: none; +} + +td.linenos pre { + padding: 5px 0px; + border: 0; + background-color: transparent; + color: #aaa; +} + +table.highlighttable { + margin-left: 0.5em; +} + +table.highlighttable td { + padding: 0 0.5em 0 0.5em; +} + +div.code-block-caption { + padding: 2px 5px; + font-size: small; +} + +div.code-block-caption code { + background-color: transparent; +} + +div.code-block-caption + div > div.highlight > pre { + margin-top: 0; +} + +div.code-block-caption span.caption-number { + padding: 0.1em 0.3em; + font-style: italic; +} + +div.code-block-caption span.caption-text { +} + +div.literal-block-wrapper { + padding: 1em 1em 0; +} + +div.literal-block-wrapper div.highlight { + margin: 0; +} + +code.descname { + background-color: transparent; + font-weight: bold; + font-size: 1.2em; +} + +code.descclassname { + background-color: transparent; +} + +code.xref, a code { + background-color: transparent; + font-weight: bold; +} + +h1 code, h2 code, h3 code, h4 code, h5 code, h6 code { + background-color: transparent; +} + +.viewcode-link { + float: right; +} + +.viewcode-back { + float: right; + font-family: sans-serif; +} + +div.viewcode-block:target { + margin: -1px -10px; + padding: 0 10px; +} + +/* -- math display ---------------------------------------------------------- */ + +img.math { + vertical-align: middle; +} + +div.body div.math p { + text-align: center; +} + +span.eqno { + float: right; +} + +span.eqno a.headerlink { + position: relative; + left: 0px; + z-index: 1; +} + +div.math:hover a.headerlink { + visibility: visible; +} + +/* -- printout stylesheet --------------------------------------------------- */ + +@media print { + div.document, + div.documentwrapper, + div.bodywrapper { + margin: 0 !important; + width: 100%; + } + + div.sphinxsidebar, + div.related, + div.footer, + #top-link { + display: none; + } +} \ No newline at end of file diff --git a/_static/comment-bright.png b/4.5/_static/comment-bright.png similarity index 100% rename from _static/comment-bright.png rename to 4.5/_static/comment-bright.png diff --git a/_static/comment-close.png b/4.5/_static/comment-close.png similarity index 100% rename from _static/comment-close.png rename to 4.5/_static/comment-close.png diff --git a/_static/comment.png b/4.5/_static/comment.png similarity index 100% rename from _static/comment.png rename to 4.5/_static/comment.png diff --git a/4.5/_static/css/pygments.css b/4.5/_static/css/pygments.css new file mode 100644 index 000000000..1c9c56a51 --- /dev/null +++ b/4.5/_static/css/pygments.css @@ -0,0 +1,87 @@ +/* Styling for the source code listings: (mostly from pygments)*/ + +.highlight pre{ + overflow: auto; + padding: 5px; + background-color: #ffffff; + color: #333333; + border: 1px solid #ac9; + border-left: none; + border-right: none; +} + +/* Styling for pre elements: from http://perishablepress.com/press/2009/11/09/perfect-pre-tags/ */ +/* no vertical scrollbars for IE 6 */ +* html pre { + padding-bottom:25px; + overflow-y:hidden; + overflow:visible; + overflow-x:auto +} +/* no vertical scrollbars for IE 7 */ +*:first-child+html pre { + padding-bottom:25px; + overflow-y:hidden; + overflow:visible; + overflow-x:auto +} + +div#spc-section-body td.linenos pre { + padding: 5px 0px; + border: 0; + background-color: transparent; + color: #aaa; +} +.highlight .hll { background-color: #ffffcc } +.highlight { background: #ffffff; } +.highlight .c { color: #008000 } /* Comment */ +.highlight .k { color: #000080; font-weight: bold } /* Keyword */ +.highlight .n { color: #000000 } /* Name */ +.highlight .o { color: #000000 } /* Operator */ +.highlight .cm { color: #008000 } /* Comment.Multiline */ +.highlight .cp { color: #008000 } /* Comment.Preproc */ +.highlight .c1 { color: #008000 } /* Comment.Single */ +.highlight .cs { color: #008000 } /* Comment.Special */ +.highlight .kc { color: #000080; font-weight: bold } /* Keyword.Constant */ +.highlight .kd { color: #000080; font-weight: bold } /* Keyword.Declaration */ +.highlight .kn { color: #000080; font-weight: bold } /* Keyword.Namespace */ +.highlight .kp { color: #000080; font-weight: bold } /* Keyword.Pseudo */ +.highlight .kr { color: #000080; font-weight: bold } /* Keyword.Reserved */ +.highlight .kt { color: #000080; font-weight: bold } /* Keyword.Type */ +.highlight .m { color: #008080 } /* Literal.Number */ +.highlight .s { color: #800080 } /* Literal.String */ +.highlight .na { color: #000000 } /* Name.Attribute */ +.highlight .nb { color: #407090 } /* Name.Builtin */ +.highlight .nc { color: #0000F0; font-weight: bold } /* Name.Class */ +.highlight .no { color: #000000 } /* Name.Constant */ +.highlight .nd { color: #000000 } /* Name.Decorator */ +.highlight .ni { color: #000000 } /* Name.Entity */ +.highlight .ne { color: #000000 } /* Name.Exception */ +.highlight .nf { color: #008080; font-weight: bold } /* Name.Function */ +.highlight .nl { color: #000000 } /* Name.Label */ +.highlight .nn { color: #000000 } /* Name.Namespace */ +.highlight .nx { color: #000000 } /* Name.Other */ +.highlight .py { color: #000000 } /* Name.Property */ +.highlight .nt { color: #000000 } /* Name.Tag */ +.highlight .nv { color: #000000 } /* Name.Variable */ +.highlight .ow { color: #AA22FF; font-weight: bold } /* Operator.Word */ +.highlight .mf { color: #008080 } /* Literal.Number.Float */ +.highlight .mh { color: #008080 } /* Literal.Number.Hex */ +.highlight .mi { color: #008080 } /* Literal.Number.Integer */ +.highlight .mo { color: #008080 } /* Literal.Number.Oct */ +.highlight .sb { color: #800080 } /* Literal.String.Backtick */ +.highlight .sc { color: #800080 } /* Literal.String.Char */ +.highlight .sd { color: #800000 } /* Literal.String.Doc */ +.highlight .s2 { color: #800080 } /* Literal.String.Double */ +.highlight .se { color: #800080 } /* Literal.String.Escape */ +.highlight .sh { color: #800080 } /* Literal.String.Heredoc */ +.highlight .si { color: #800080 } /* Literal.String.Interpol */ +.highlight .sx { color: #800080 } /* Literal.String.Other */ +.highlight .sr { color: #800080 } /* Literal.String.Regex */ +.highlight .s1 { color: #800080 } /* Literal.String.Single */ +.highlight .ss { color: #800080 } /* Literal.String.Symbol */ +.highlight .bp { color: #407090 } /* Name.Builtin.Pseudo */ +.highlight .vc { color: #000000 } /* Name.Variable.Class */ +.highlight .vg { color: #000000 } /* Name.Variable.Global */ +.highlight .vi { color: #000000 } /* Name.Variable.Instance */ +.highlight .il { color: #008080 } /* Literal.Number.Integer.Long */ diff --git a/4.5/_static/css/spc-bootstrap.css b/4.5/_static/css/spc-bootstrap.css new file mode 100644 index 000000000..9895e61fe --- /dev/null +++ b/4.5/_static/css/spc-bootstrap.css @@ -0,0 +1,6288 @@ +/*! + * Bootstrap v2.3.1 + * + * Copyright 2012 Twitter, Inc + * Licensed under the Apache License v2.0 + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Designed and built with all the love in the world @twitter by @mdo and @fat. + */ +.clearfix { + *zoom: 1; +} +.clearfix:before, +.clearfix:after { + display: table; + content: ""; + line-height: 0; +} +.clearfix:after { + clear: both; +} +.hide-text { + font: 0/0 a; + color: transparent; + text-shadow: none; + background-color: transparent; + border: 0; +} +.input-block-level { + display: block; + width: 100%; + min-height: 31px; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} +article, +aside, +details, +figcaption, +figure, +footer, +header, +hgroup, +nav, +section { + display: block; +} +audio, +canvas, +video { + display: inline-block; + *display: inline; + *zoom: 1; +} +audio:not([controls]) { + display: none; +} +html { + font-size: 100%; + -webkit-text-size-adjust: 100%; + -ms-text-size-adjust: 100%; +} +a:focus { + outline: thin dotted #333; + outline: 5px auto -webkit-focus-ring-color; + outline-offset: -2px; +} +a:hover, +a:active { + outline: 0; +} +sub, +sup { + position: relative; + font-size: 75%; + line-height: 0; + vertical-align: baseline; +} +sup { + top: -0.5em; +} +sub { + bottom: -0.25em; +} +img { + /* Responsive images (ensure images don't scale beyond their parents) */ + max-width: 100%; + /* Part 1: Set a maxium relative to the parent */ + width: auto\9; + /* IE7-8 need help adjusting responsive images */ + height: auto; + /* Part 2: Scale the height according to the width, otherwise you get stretching */ + vertical-align: middle; + border: 0; + -ms-interpolation-mode: bicubic; +} +#map_canvas img, +.google-maps img { + max-width: none; +} +button, +input, +select, +textarea { + margin: 0; + font-size: 100%; + vertical-align: middle; +} +button, +input { + *overflow: visible; + line-height: normal; +} +button::-moz-focus-inner, +input::-moz-focus-inner { + padding: 0; + border: 0; +} +button, +html input[type="button"], +input[type="reset"], +input[type="submit"] { + -webkit-appearance: button; + cursor: pointer; +} +label, +select, +button, +input[type="button"], +input[type="reset"], +input[type="submit"], +input[type="radio"], +input[type="checkbox"] { + cursor: pointer; +} +input[type="search"] { + -webkit-box-sizing: content-box; + -moz-box-sizing: content-box; + box-sizing: content-box; + -webkit-appearance: textfield; +} +input[type="search"]::-webkit-search-decoration, +input[type="search"]::-webkit-search-cancel-button { + -webkit-appearance: none; +} +textarea { + overflow: auto; + vertical-align: top; +} +@media print { + * { + text-shadow: none !important; + color: #000 !important; + background: transparent !important; + box-shadow: none !important; + } + a, + a:visited { + text-decoration: underline; + } + a[href]:after { + content: " (" attr(href) ")"; + } + abbr[title]:after { + content: " (" attr(title) ")"; + } + .ir a:after, + a[href^="javascript:"]:after, + a[href^="#"]:after { + content: ""; + } + pre, + blockquote { + border: 1px solid #999; + page-break-inside: avoid; + } + thead { + display: table-header-group; + } + tr, + img { + page-break-inside: avoid; + } + img { + max-width: 100% !important; + } + @page { + margin: 0.5cm; + } + p, + h2, + h3 { + orphans: 3; + widows: 3; + } + h2, + h3 { + page-break-after: avoid; + } +} +body { + margin: 0; + font-family: 'Source Sans Pro', sans-serif; + font-size: 16px; + line-height: 21px; + color: #333333; + background-color: #ffffff; +} +a { + color: #0088cc; + text-decoration: none; +} +a:hover, +a:focus { + color: #005580; + text-decoration: underline; +} +.img-rounded { + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; +} +.img-polaroid { + padding: 4px; + background-color: #fff; + border: 1px solid #ccc; + border: 1px solid rgba(0, 0, 0, 0.2); + -webkit-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); + -moz-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); + box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); +} +.img-circle { + -webkit-border-radius: 500px; + -moz-border-radius: 500px; + border-radius: 500px; +} +.row { + margin-left: -20px; + *zoom: 1; +} +.row:before, +.row:after { + display: table; + content: ""; + line-height: 0; +} +.row:after { + clear: both; +} +[class*="span"] { + float: left; + min-height: 1px; + margin-left: 20px; +} +.container, +.navbar-static-top .container, +.navbar-fixed-top .container, +.navbar-fixed-bottom .container { + width: 940px; +} +.span12 { + width: 940px; +} +.span11 { + width: 860px; +} +.span10 { + width: 780px; +} +.span9 { + width: 700px; +} +.span8 { + width: 620px; +} +.span7 { + width: 540px; +} +.span6 { + width: 460px; +} +.span5 { + width: 380px; +} +.span4 { + width: 300px; +} +.span3 { + width: 220px; +} +.span2 { + width: 140px; +} +.span1 { + width: 60px; +} +.offset12 { + margin-left: 980px; +} +.offset11 { + margin-left: 900px; +} +.offset10 { + margin-left: 820px; +} +.offset9 { + margin-left: 740px; +} +.offset8 { + margin-left: 660px; +} +.offset7 { + margin-left: 580px; +} +.offset6 { + margin-left: 500px; +} +.offset5 { + margin-left: 420px; +} +.offset4 { + margin-left: 340px; +} +.offset3 { + margin-left: 260px; +} +.offset2 { + margin-left: 180px; +} +.offset1 { + margin-left: 100px; +} +.row-fluid { + width: 100%; + *zoom: 1; +} +.row-fluid:before, +.row-fluid:after { + display: table; + content: ""; + line-height: 0; +} +.row-fluid:after { + clear: both; +} +.row-fluid [class*="span"] { + display: block; + width: 100%; + min-height: 31px; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + float: left; + margin-left: 2.12765957%; + *margin-left: 2.07446809%; +} +.row-fluid [class*="span"]:first-child { + margin-left: 0; +} +.row-fluid .controls-row [class*="span"] + [class*="span"] { + margin-left: 2.12765957%; +} +.row-fluid .span12 { + width: 100%; + *width: 99.94680851%; +} +.row-fluid .span11 { + width: 91.4893617%; + *width: 91.43617021%; +} +.row-fluid .span10 { + width: 82.9787234%; + *width: 82.92553191%; +} +.row-fluid .span9 { + width: 74.46808511%; + *width: 74.41489362%; +} +.row-fluid .span8 { + width: 65.95744681%; + *width: 65.90425532%; +} +.row-fluid .span7 { + width: 57.44680851%; + *width: 57.39361702%; +} +.row-fluid .span6 { + width: 48.93617021%; + *width: 48.88297872%; +} +.row-fluid .span5 { + width: 40.42553191%; + *width: 40.37234043%; +} +.row-fluid .span4 { + width: 31.91489362%; + *width: 31.86170213%; +} +.row-fluid .span3 { + width: 23.40425532%; + *width: 23.35106383%; +} +.row-fluid .span2 { + width: 14.89361702%; + *width: 14.84042553%; +} +.row-fluid .span1 { + width: 6.38297872%; + *width: 6.32978723%; +} +.row-fluid .offset12 { + margin-left: 104.25531915%; + *margin-left: 104.14893617%; +} +.row-fluid .offset12:first-child { + margin-left: 102.12765957%; + *margin-left: 102.0212766%; +} +.row-fluid .offset11 { + margin-left: 95.74468085%; + *margin-left: 95.63829787%; +} +.row-fluid .offset11:first-child { + margin-left: 93.61702128%; + *margin-left: 93.5106383%; +} +.row-fluid .offset10 { + margin-left: 87.23404255%; + *margin-left: 87.12765957%; +} +.row-fluid .offset10:first-child { + margin-left: 85.10638298%; + *margin-left: 85%; +} +.row-fluid .offset9 { + margin-left: 78.72340426%; + *margin-left: 78.61702128%; +} +.row-fluid .offset9:first-child { + margin-left: 76.59574468%; + *margin-left: 76.4893617%; +} +.row-fluid .offset8 { + margin-left: 70.21276596%; + *margin-left: 70.10638298%; +} +.row-fluid .offset8:first-child { + margin-left: 68.08510638%; + *margin-left: 67.9787234%; +} +.row-fluid .offset7 { + margin-left: 61.70212766%; + *margin-left: 61.59574468%; +} +.row-fluid .offset7:first-child { + margin-left: 59.57446809%; + *margin-left: 59.46808511%; +} +.row-fluid .offset6 { + margin-left: 53.19148936%; + *margin-left: 53.08510638%; +} +.row-fluid .offset6:first-child { + margin-left: 51.06382979%; + *margin-left: 50.95744681%; +} +.row-fluid .offset5 { + margin-left: 44.68085106%; + *margin-left: 44.57446809%; +} +.row-fluid .offset5:first-child { + margin-left: 42.55319149%; + *margin-left: 42.44680851%; +} +.row-fluid .offset4 { + margin-left: 36.17021277%; + *margin-left: 36.06382979%; +} +.row-fluid .offset4:first-child { + margin-left: 34.04255319%; + *margin-left: 33.93617021%; +} +.row-fluid .offset3 { + margin-left: 27.65957447%; + *margin-left: 27.55319149%; +} +.row-fluid .offset3:first-child { + margin-left: 25.53191489%; + *margin-left: 25.42553191%; +} +.row-fluid .offset2 { + margin-left: 19.14893617%; + *margin-left: 19.04255319%; +} +.row-fluid .offset2:first-child { + margin-left: 17.0212766%; + *margin-left: 16.91489362%; +} +.row-fluid .offset1 { + margin-left: 10.63829787%; + *margin-left: 10.53191489%; +} +.row-fluid .offset1:first-child { + margin-left: 8.5106383%; + *margin-left: 8.40425532%; +} +[class*="span"].hide, +.row-fluid [class*="span"].hide { + display: none; +} +[class*="span"].pull-right, +.row-fluid [class*="span"].pull-right { + float: right; +} +.container { + margin-right: auto; + margin-left: auto; + *zoom: 1; +} +.container:before, +.container:after { + display: table; + content: ""; + line-height: 0; +} +.container:after { + clear: both; +} +.container-fluid { + padding-right: 20px; + padding-left: 20px; + *zoom: 1; +} +.container-fluid:before, +.container-fluid:after { + display: table; + content: ""; + line-height: 0; +} +.container-fluid:after { + clear: both; +} +p { + margin: 0 0 10.5px; +} +.lead { + margin-bottom: 21px; + font-size: 24px; + font-weight: 200; + line-height: 31.5px; +} +small { + font-size: 85%; +} +strong { + font-weight: bold; +} +em { + font-style: italic; +} +cite { + font-style: normal; +} +.muted { + color: #999999; +} +a.muted:hover, +a.muted:focus { + color: #808080; +} +.text-warning { + color: #c09853; +} +a.text-warning:hover, +a.text-warning:focus { + color: #a47e3c; +} +.text-error { + color: #b94a48; +} +a.text-error:hover, +a.text-error:focus { + color: #953b39; +} +.text-info { + color: #3a87ad; +} +a.text-info:hover, +a.text-info:focus { + color: #2d6987; +} +.text-success { + color: #468847; +} +a.text-success:hover, +a.text-success:focus { + color: #356635; +} +.text-left { + text-align: left; +} +.text-right { + text-align: right; +} +.text-center { + text-align: center; +} +h1, +h2, +h3, +h4, +h5, +h6 { + margin: 10.5px 0; + font-family: inherit; + font-weight: bold; + line-height: 21px; + color: inherit; + text-rendering: optimizelegibility; +} +h1 small, +h2 small, +h3 small, +h4 small, +h5 small, +h6 small { + font-weight: normal; + line-height: 1; + color: #999999; +} +h1, +h2, +h3 { + line-height: 42px; +} +h1 { + font-size: 44px; +} +h2 { + font-size: 36px; +} +h3 { + font-size: 28px; +} +h4 { + font-size: 20px; +} +h5 { + font-size: 16px; +} +h6 { + font-size: 13.6px; +} +h1 small { + font-size: 28px; +} +h2 small { + font-size: 20px; +} +h3 small { + font-size: 16px; +} +h4 small { + font-size: 16px; +} +.page-header { + padding-bottom: 9.5px; + margin: 21px 0 31.5px; + border-bottom: 1px solid #eeeeee; +} +ul, +ol { + padding: 0; + margin: 0 0 10.5px 25px; +} +ul ul, +ul ol, +ol ol, +ol ul { + margin-bottom: 0; +} +li { + line-height: 21px; +} +ul.unstyled, +ol.unstyled { + margin-left: 0; + list-style: none; +} +ul.inline, +ol.inline { + margin-left: 0; + list-style: none; +} +ul.inline > li, +ol.inline > li { + display: inline-block; + *display: inline; + /* IE7 inline-block hack */ + *zoom: 1; + padding-left: 5px; + padding-right: 5px; +} +dl { + margin-bottom: 21px; +} +dt, +dd { + line-height: 21px; +} +dt { + font-weight: bold; +} +dd { + margin-left: 10.5px; +} +.dl-horizontal { + *zoom: 1; +} +.dl-horizontal:before, +.dl-horizontal:after { + display: table; + content: ""; + line-height: 0; +} +.dl-horizontal:after { + clear: both; +} +.dl-horizontal dt { + float: left; + width: 160px; + clear: left; + text-align: right; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} +.dl-horizontal dd { + margin-left: 180px; +} +hr { + margin: 21px 0; + border: 0; + border-top: 1px solid #eeeeee; + border-bottom: 1px solid #ffffff; +} +abbr[title], +abbr[data-original-title] { + cursor: help; + border-bottom: 1px dotted #999999; +} +abbr.initialism { + font-size: 90%; + text-transform: uppercase; +} +blockquote { + padding: 0 0 0 15px; + margin: 0 0 21px; + border-left: 5px solid #eeeeee; +} +blockquote p { + margin-bottom: 0; + font-size: 20px; + font-weight: 300; + line-height: 1.25; +} +blockquote small { + display: block; + line-height: 21px; + color: #999999; +} +blockquote small:before { + content: '\2014 \00A0'; +} +blockquote.pull-right { + float: right; + padding-right: 15px; + padding-left: 0; + border-right: 5px solid #eeeeee; + border-left: 0; +} +blockquote.pull-right p, +blockquote.pull-right small { + text-align: right; +} +blockquote.pull-right small:before { + content: ''; +} +blockquote.pull-right small:after { + content: '\00A0 \2014'; +} +q:before, +q:after, +blockquote:before, +blockquote:after { + content: ""; +} +address { + display: block; + margin-bottom: 21px; + font-style: normal; + line-height: 21px; +} +code, +pre { + padding: 0 3px 2px; + font-family: 'Source Code Pro', monospace; + font-size: 14px; + color: #333333; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; +} +code { + padding: 2px 4px; + color: #d14; + background-color: #f7f7f9; + border: 1px solid #e1e1e8; + white-space: nowrap; +} +pre { + display: block; + padding: 10px; + margin: 0 0 10.5px; + font-size: 15px; + line-height: 21px; + word-break: break-all; + word-wrap: break-word; + white-space: pre; + white-space: pre-wrap; + background-color: #f5f5f5; + border: 1px solid #ccc; + border: 1px solid rgba(0, 0, 0, 0.15); + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; +} +pre.prettyprint { + margin-bottom: 21px; +} +pre code { + padding: 0; + color: inherit; + white-space: pre; + white-space: pre-wrap; + background-color: transparent; + border: 0; +} +.pre-scrollable { + max-height: 340px; + overflow-y: scroll; +} +form { + margin: 0 0 21px; +} +fieldset { + padding: 0; + margin: 0; + border: 0; +} +legend { + display: block; + width: 100%; + padding: 0; + margin-bottom: 21px; + font-size: 24px; + line-height: 42px; + color: #333333; + border: 0; + border-bottom: 1px solid #e5e5e5; +} +legend small { + font-size: 15.75px; + color: #999999; +} +label, +input, +button, +select, +textarea { + font-size: 16px; + font-weight: normal; + line-height: 21px; +} +input, +button, +select, +textarea { + font-family: 'Source Sans Pro', sans-serif; +} +label { + display: block; + margin-bottom: 5px; +} +select, +textarea, +input[type="text"], +input[type="password"], +input[type="datetime"], +input[type="datetime-local"], +input[type="date"], +input[type="month"], +input[type="time"], +input[type="week"], +input[type="number"], +input[type="email"], +input[type="url"], +input[type="search"], +input[type="tel"], +input[type="color"], +.uneditable-input { + display: inline-block; + height: 21px; + padding: 4px 6px; + margin-bottom: 10.5px; + font-size: 16px; + line-height: 21px; + color: #555555; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; + vertical-align: middle; +} +input, +textarea, +.uneditable-input { + width: 206px; +} +textarea { + height: auto; +} +textarea, +input[type="text"], +input[type="password"], +input[type="datetime"], +input[type="datetime-local"], +input[type="date"], +input[type="month"], +input[type="time"], +input[type="week"], +input[type="number"], +input[type="email"], +input[type="url"], +input[type="search"], +input[type="tel"], +input[type="color"], +.uneditable-input { + background-color: #ffffff; + border: 1px solid #cccccc; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + -webkit-transition: border linear .2s, box-shadow linear .2s; + -moz-transition: border linear .2s, box-shadow linear .2s; + -o-transition: border linear .2s, box-shadow linear .2s; + transition: border linear .2s, box-shadow linear .2s; +} +textarea:focus, +input[type="text"]:focus, +input[type="password"]:focus, +input[type="datetime"]:focus, +input[type="datetime-local"]:focus, +input[type="date"]:focus, +input[type="month"]:focus, +input[type="time"]:focus, +input[type="week"]:focus, +input[type="number"]:focus, +input[type="email"]:focus, +input[type="url"]:focus, +input[type="search"]:focus, +input[type="tel"]:focus, +input[type="color"]:focus, +.uneditable-input:focus { + border-color: rgba(82, 168, 236, 0.8); + outline: 0; + outline: thin dotted \9; + /* IE6-9 */ + -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(82,168,236,.6); + -moz-box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(82,168,236,.6); + box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(82,168,236,.6); +} +input[type="radio"], +input[type="checkbox"] { + margin: 4px 0 0; + *margin-top: 0; + /* IE7 */ + margin-top: 1px \9; + /* IE8-9 */ + line-height: normal; +} +input[type="file"], +input[type="image"], +input[type="submit"], +input[type="reset"], +input[type="button"], +input[type="radio"], +input[type="checkbox"] { + width: auto; +} +select, +input[type="file"] { + height: 31px; + /* In IE7, the height of the select element cannot be changed by height, only font-size */ + *margin-top: 4px; + /* For IE7, add top margin to align select with labels */ + line-height: 31px; +} +select { + width: 220px; + border: 1px solid #cccccc; + background-color: #ffffff; +} +select[multiple], +select[size] { + height: auto; +} +select:focus, +input[type="file"]:focus, +input[type="radio"]:focus, +input[type="checkbox"]:focus { + outline: thin dotted #333; + outline: 5px auto -webkit-focus-ring-color; + outline-offset: -2px; +} +.uneditable-input, +.uneditable-textarea { + color: #999999; + background-color: #fcfcfc; + border-color: #cccccc; + -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.025); + -moz-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.025); + box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.025); + cursor: not-allowed; +} +.uneditable-input { + overflow: hidden; + white-space: nowrap; +} +.uneditable-textarea { + width: auto; + height: auto; +} +input:-moz-placeholder, +textarea:-moz-placeholder { + color: #999999; +} +input:-ms-input-placeholder, +textarea:-ms-input-placeholder { + color: #999999; +} +input::-webkit-input-placeholder, +textarea::-webkit-input-placeholder { + color: #999999; +} +.radio, +.checkbox { + min-height: 21px; + padding-left: 20px; +} +.radio input[type="radio"], +.checkbox input[type="checkbox"] { + float: left; + margin-left: -20px; +} +.controls > .radio:first-child, +.controls > .checkbox:first-child { + padding-top: 5px; +} +.radio.inline, +.checkbox.inline { + display: inline-block; + padding-top: 5px; + margin-bottom: 0; + vertical-align: middle; +} +.radio.inline + .radio.inline, +.checkbox.inline + .checkbox.inline { + margin-left: 10px; +} +.input-mini { + width: 60px; +} +.input-small { + width: 90px; +} +.input-medium { + width: 150px; +} +.input-large { + width: 210px; +} +.input-xlarge { + width: 270px; +} +.input-xxlarge { + width: 530px; +} +input[class*="span"], +select[class*="span"], +textarea[class*="span"], +.uneditable-input[class*="span"], +.row-fluid input[class*="span"], +.row-fluid select[class*="span"], +.row-fluid textarea[class*="span"], +.row-fluid .uneditable-input[class*="span"] { + float: none; + margin-left: 0; +} +.input-append input[class*="span"], +.input-append .uneditable-input[class*="span"], +.input-prepend input[class*="span"], +.input-prepend .uneditable-input[class*="span"], +.row-fluid input[class*="span"], +.row-fluid select[class*="span"], +.row-fluid textarea[class*="span"], +.row-fluid .uneditable-input[class*="span"], +.row-fluid .input-prepend [class*="span"], +.row-fluid .input-append [class*="span"] { + display: inline-block; +} +input, +textarea, +.uneditable-input { + margin-left: 0; +} +.controls-row [class*="span"] + [class*="span"] { + margin-left: 20px; +} +input.span12, +textarea.span12, +.uneditable-input.span12 { + width: 926px; +} +input.span11, +textarea.span11, +.uneditable-input.span11 { + width: 846px; +} +input.span10, +textarea.span10, +.uneditable-input.span10 { + width: 766px; +} +input.span9, +textarea.span9, +.uneditable-input.span9 { + width: 686px; +} +input.span8, +textarea.span8, +.uneditable-input.span8 { + width: 606px; +} +input.span7, +textarea.span7, +.uneditable-input.span7 { + width: 526px; +} +input.span6, +textarea.span6, +.uneditable-input.span6 { + width: 446px; +} +input.span5, +textarea.span5, +.uneditable-input.span5 { + width: 366px; +} +input.span4, +textarea.span4, +.uneditable-input.span4 { + width: 286px; +} +input.span3, +textarea.span3, +.uneditable-input.span3 { + width: 206px; +} +input.span2, +textarea.span2, +.uneditable-input.span2 { + width: 126px; +} +input.span1, +textarea.span1, +.uneditable-input.span1 { + width: 46px; +} +.controls-row { + *zoom: 1; +} +.controls-row:before, +.controls-row:after { + display: table; + content: ""; + line-height: 0; +} +.controls-row:after { + clear: both; +} +.controls-row [class*="span"], +.row-fluid .controls-row [class*="span"] { + float: left; +} +.controls-row .checkbox[class*="span"], +.controls-row .radio[class*="span"] { + padding-top: 5px; +} +input[disabled], +select[disabled], +textarea[disabled], +input[readonly], +select[readonly], +textarea[readonly] { + cursor: not-allowed; + background-color: #eeeeee; +} +input[type="radio"][disabled], +input[type="checkbox"][disabled], +input[type="radio"][readonly], +input[type="checkbox"][readonly] { + background-color: transparent; +} +.control-group.warning .control-label, +.control-group.warning .help-block, +.control-group.warning .help-inline { + color: #c09853; +} +.control-group.warning .checkbox, +.control-group.warning .radio, +.control-group.warning input, +.control-group.warning select, +.control-group.warning textarea { + color: #c09853; +} +.control-group.warning input, +.control-group.warning select, +.control-group.warning textarea { + border-color: #c09853; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); +} +.control-group.warning input:focus, +.control-group.warning select:focus, +.control-group.warning textarea:focus { + border-color: #a47e3c; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #dbc59e; + -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #dbc59e; + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #dbc59e; +} +.control-group.warning .input-prepend .add-on, +.control-group.warning .input-append .add-on { + color: #c09853; + background-color: #fcf8e3; + border-color: #c09853; +} +.control-group.error .control-label, +.control-group.error .help-block, +.control-group.error .help-inline { + color: #b94a48; +} +.control-group.error .checkbox, +.control-group.error .radio, +.control-group.error input, +.control-group.error select, +.control-group.error textarea { + color: #b94a48; +} +.control-group.error input, +.control-group.error select, +.control-group.error textarea { + border-color: #b94a48; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); +} +.control-group.error input:focus, +.control-group.error select:focus, +.control-group.error textarea:focus { + border-color: #953b39; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #d59392; + -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #d59392; + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #d59392; +} +.control-group.error .input-prepend .add-on, +.control-group.error .input-append .add-on { + color: #b94a48; + background-color: #f2dede; + border-color: #b94a48; +} +.control-group.success .control-label, +.control-group.success .help-block, +.control-group.success .help-inline { + color: #468847; +} +.control-group.success .checkbox, +.control-group.success .radio, +.control-group.success input, +.control-group.success select, +.control-group.success textarea { + color: #468847; +} +.control-group.success input, +.control-group.success select, +.control-group.success textarea { + border-color: #468847; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); +} +.control-group.success input:focus, +.control-group.success select:focus, +.control-group.success textarea:focus { + border-color: #356635; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #7aba7b; + -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #7aba7b; + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #7aba7b; +} +.control-group.success .input-prepend .add-on, +.control-group.success .input-append .add-on { + color: #468847; + background-color: #dff0d8; + border-color: #468847; +} +.control-group.info .control-label, +.control-group.info .help-block, +.control-group.info .help-inline { + color: #3a87ad; +} +.control-group.info .checkbox, +.control-group.info .radio, +.control-group.info input, +.control-group.info select, +.control-group.info textarea { + color: #3a87ad; +} +.control-group.info input, +.control-group.info select, +.control-group.info textarea { + border-color: #3a87ad; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); +} +.control-group.info input:focus, +.control-group.info select:focus, +.control-group.info textarea:focus { + border-color: #2d6987; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #7ab5d3; + -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #7ab5d3; + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #7ab5d3; +} +.control-group.info .input-prepend .add-on, +.control-group.info .input-append .add-on { + color: #3a87ad; + background-color: #d9edf7; + border-color: #3a87ad; +} +input:focus:invalid, +textarea:focus:invalid, +select:focus:invalid { + color: #b94a48; + border-color: #ee5f5b; +} +input:focus:invalid:focus, +textarea:focus:invalid:focus, +select:focus:invalid:focus { + border-color: #e9322d; + -webkit-box-shadow: 0 0 6px #f8b9b7; + -moz-box-shadow: 0 0 6px #f8b9b7; + box-shadow: 0 0 6px #f8b9b7; +} +.form-actions { + padding: 20px 20px 21px; + margin-top: 21px; + margin-bottom: 21px; + background-color: #f5f5f5; + border-top: 1px solid #e5e5e5; + *zoom: 1; +} +.form-actions:before, +.form-actions:after { + display: table; + content: ""; + line-height: 0; +} +.form-actions:after { + clear: both; +} +.help-block, +.help-inline { + color: #595959; +} +.help-block { + display: block; + margin-bottom: 10.5px; +} +.help-inline { + display: inline-block; + *display: inline; + /* IE7 inline-block hack */ + *zoom: 1; + vertical-align: middle; + padding-left: 5px; +} +.input-append, +.input-prepend { + display: inline-block; + margin-bottom: 10.5px; + vertical-align: middle; + font-size: 0; + white-space: nowrap; +} +.input-append input, +.input-prepend input, +.input-append select, +.input-prepend select, +.input-append .uneditable-input, +.input-prepend .uneditable-input, +.input-append .dropdown-menu, +.input-prepend .dropdown-menu, +.input-append .popover, +.input-prepend .popover { + font-size: 16px; +} +.input-append input, +.input-prepend input, +.input-append select, +.input-prepend select, +.input-append .uneditable-input, +.input-prepend .uneditable-input { + position: relative; + margin-bottom: 0; + *margin-left: 0; + vertical-align: top; + -webkit-border-radius: 0 4px 4px 0; + -moz-border-radius: 0 4px 4px 0; + border-radius: 0 4px 4px 0; +} +.input-append input:focus, +.input-prepend input:focus, +.input-append select:focus, +.input-prepend select:focus, +.input-append .uneditable-input:focus, +.input-prepend .uneditable-input:focus { + z-index: 2; +} +.input-append .add-on, +.input-prepend .add-on { + display: inline-block; + width: auto; + height: 21px; + min-width: 16px; + padding: 4px 5px; + font-size: 16px; + font-weight: normal; + line-height: 21px; + text-align: center; + text-shadow: 0 1px 0 #ffffff; + background-color: #eeeeee; + border: 1px solid #ccc; +} +.input-append .add-on, +.input-prepend .add-on, +.input-append .btn, +.input-prepend .btn, +.input-append .btn-group > .dropdown-toggle, +.input-prepend .btn-group > .dropdown-toggle { + vertical-align: top; + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; +} +.input-append .active, +.input-prepend .active { + background-color: #a9dba9; + border-color: #46a546; +} +.input-prepend .add-on, +.input-prepend .btn { + margin-right: -1px; +} +.input-prepend .add-on:first-child, +.input-prepend .btn:first-child { + -webkit-border-radius: 4px 0 0 4px; + -moz-border-radius: 4px 0 0 4px; + border-radius: 4px 0 0 4px; +} +.input-append input, +.input-append select, +.input-append .uneditable-input { + -webkit-border-radius: 4px 0 0 4px; + -moz-border-radius: 4px 0 0 4px; + border-radius: 4px 0 0 4px; +} +.input-append input + .btn-group .btn:last-child, +.input-append select + .btn-group .btn:last-child, +.input-append .uneditable-input + .btn-group .btn:last-child { + -webkit-border-radius: 0 4px 4px 0; + -moz-border-radius: 0 4px 4px 0; + border-radius: 0 4px 4px 0; +} +.input-append .add-on, +.input-append .btn, +.input-append .btn-group { + margin-left: -1px; +} +.input-append .add-on:last-child, +.input-append .btn:last-child, +.input-append .btn-group:last-child > .dropdown-toggle { + -webkit-border-radius: 0 4px 4px 0; + -moz-border-radius: 0 4px 4px 0; + border-radius: 0 4px 4px 0; +} +.input-prepend.input-append input, +.input-prepend.input-append select, +.input-prepend.input-append .uneditable-input { + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; +} +.input-prepend.input-append input + .btn-group .btn, +.input-prepend.input-append select + .btn-group .btn, +.input-prepend.input-append .uneditable-input + .btn-group .btn { + -webkit-border-radius: 0 4px 4px 0; + -moz-border-radius: 0 4px 4px 0; + border-radius: 0 4px 4px 0; +} +.input-prepend.input-append .add-on:first-child, +.input-prepend.input-append .btn:first-child { + margin-right: -1px; + -webkit-border-radius: 4px 0 0 4px; + -moz-border-radius: 4px 0 0 4px; + border-radius: 4px 0 0 4px; +} +.input-prepend.input-append .add-on:last-child, +.input-prepend.input-append .btn:last-child { + margin-left: -1px; + -webkit-border-radius: 0 4px 4px 0; + -moz-border-radius: 0 4px 4px 0; + border-radius: 0 4px 4px 0; +} +.input-prepend.input-append .btn-group:first-child { + margin-left: 0; +} +input.search-query { + padding-right: 14px; + padding-right: 4px \9; + padding-left: 14px; + padding-left: 4px \9; + /* IE7-8 doesn't have border-radius, so don't indent the padding */ + margin-bottom: 0; + -webkit-border-radius: 15px; + -moz-border-radius: 15px; + border-radius: 15px; +} +/* Allow for input prepend/append in search forms */ +.form-search .input-append .search-query, +.form-search .input-prepend .search-query { + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; +} +.form-search .input-append .search-query { + -webkit-border-radius: 14px 0 0 14px; + -moz-border-radius: 14px 0 0 14px; + border-radius: 14px 0 0 14px; +} +.form-search .input-append .btn { + -webkit-border-radius: 0 14px 14px 0; + -moz-border-radius: 0 14px 14px 0; + border-radius: 0 14px 14px 0; +} +.form-search .input-prepend .search-query { + -webkit-border-radius: 0 14px 14px 0; + -moz-border-radius: 0 14px 14px 0; + border-radius: 0 14px 14px 0; +} +.form-search .input-prepend .btn { + -webkit-border-radius: 14px 0 0 14px; + -moz-border-radius: 14px 0 0 14px; + border-radius: 14px 0 0 14px; +} +.form-search input, +.form-inline input, +.form-horizontal input, +.form-search textarea, +.form-inline textarea, +.form-horizontal textarea, +.form-search select, +.form-inline select, +.form-horizontal select, +.form-search .help-inline, +.form-inline .help-inline, +.form-horizontal .help-inline, +.form-search .uneditable-input, +.form-inline .uneditable-input, +.form-horizontal .uneditable-input, +.form-search .input-prepend, +.form-inline .input-prepend, +.form-horizontal .input-prepend, +.form-search .input-append, +.form-inline .input-append, +.form-horizontal .input-append { + display: inline-block; + *display: inline; + /* IE7 inline-block hack */ + *zoom: 1; + margin-bottom: 0; + vertical-align: middle; +} +.form-search .hide, +.form-inline .hide, +.form-horizontal .hide { + display: none; +} +.form-search label, +.form-inline label, +.form-search .btn-group, +.form-inline .btn-group { + display: inline-block; +} +.form-search .input-append, +.form-inline .input-append, +.form-search .input-prepend, +.form-inline .input-prepend { + margin-bottom: 0; +} +.form-search .radio, +.form-search .checkbox, +.form-inline .radio, +.form-inline .checkbox { + padding-left: 0; + margin-bottom: 0; + vertical-align: middle; +} +.form-search .radio input[type="radio"], +.form-search .checkbox input[type="checkbox"], +.form-inline .radio input[type="radio"], +.form-inline .checkbox input[type="checkbox"] { + float: left; + margin-right: 3px; + margin-left: 0; +} +.control-group { + margin-bottom: 10.5px; +} +legend + .control-group { + margin-top: 21px; + -webkit-margin-top-collapse: separate; +} +.form-horizontal .control-group { + margin-bottom: 21px; + *zoom: 1; +} +.form-horizontal .control-group:before, +.form-horizontal .control-group:after { + display: table; + content: ""; + line-height: 0; +} +.form-horizontal .control-group:after { + clear: both; +} +.form-horizontal .control-label { + float: left; + width: 160px; + padding-top: 5px; + text-align: right; +} +.form-horizontal .controls { + *display: inline-block; + *padding-left: 20px; + margin-left: 180px; + *margin-left: 0; +} +.form-horizontal .controls:first-child { + *padding-left: 180px; +} +.form-horizontal .help-block { + margin-bottom: 0; +} +.form-horizontal input + .help-block, +.form-horizontal select + .help-block, +.form-horizontal textarea + .help-block, +.form-horizontal .uneditable-input + .help-block, +.form-horizontal .input-prepend + .help-block, +.form-horizontal .input-append + .help-block { + margin-top: 10.5px; +} +.form-horizontal .form-actions { + padding-left: 180px; +} +table { + max-width: 100%; + background-color: transparent; + border-collapse: collapse; + border-spacing: 0; +} +.table { + width: 100%; + margin-bottom: 21px; +} +.table th, +.table td { + padding: 8px; + line-height: 21px; + text-align: left; + vertical-align: top; + border-top: 1px solid #dddddd; +} +.table th { + font-weight: bold; +} +.table thead th { + vertical-align: bottom; +} +.table caption + thead tr:first-child th, +.table caption + thead tr:first-child td, +.table colgroup + thead tr:first-child th, +.table colgroup + thead tr:first-child td, +.table thead:first-child tr:first-child th, +.table thead:first-child tr:first-child td { + border-top: 0; +} +.table tbody + tbody { + border-top: 2px solid #dddddd; +} +.table .table { + background-color: #ffffff; +} +.table-condensed th, +.table-condensed td { + padding: 4px 5px; +} +.table-bordered { + border: 1px solid #dddddd; + border-collapse: separate; + *border-collapse: collapse; + border-left: 0; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; +} +.table-bordered th, +.table-bordered td { + border-left: 1px solid #dddddd; +} +.table-bordered caption + thead tr:first-child th, +.table-bordered caption + tbody tr:first-child th, +.table-bordered caption + tbody tr:first-child td, +.table-bordered colgroup + thead tr:first-child th, +.table-bordered colgroup + tbody tr:first-child th, +.table-bordered colgroup + tbody tr:first-child td, +.table-bordered thead:first-child tr:first-child th, +.table-bordered tbody:first-child tr:first-child th, +.table-bordered tbody:first-child tr:first-child td { + border-top: 0; +} +.table-bordered thead:first-child tr:first-child > th:first-child, +.table-bordered tbody:first-child tr:first-child > td:first-child, +.table-bordered tbody:first-child tr:first-child > th:first-child { + -webkit-border-top-left-radius: 4px; + -moz-border-radius-topleft: 4px; + border-top-left-radius: 4px; +} +.table-bordered thead:first-child tr:first-child > th:last-child, +.table-bordered tbody:first-child tr:first-child > td:last-child, +.table-bordered tbody:first-child tr:first-child > th:last-child { + -webkit-border-top-right-radius: 4px; + -moz-border-radius-topright: 4px; + border-top-right-radius: 4px; +} +.table-bordered thead:last-child tr:last-child > th:first-child, +.table-bordered tbody:last-child tr:last-child > td:first-child, +.table-bordered tbody:last-child tr:last-child > th:first-child, +.table-bordered tfoot:last-child tr:last-child > td:first-child, +.table-bordered tfoot:last-child tr:last-child > th:first-child { + -webkit-border-bottom-left-radius: 4px; + -moz-border-radius-bottomleft: 4px; + border-bottom-left-radius: 4px; +} +.table-bordered thead:last-child tr:last-child > th:last-child, +.table-bordered tbody:last-child tr:last-child > td:last-child, +.table-bordered tbody:last-child tr:last-child > th:last-child, +.table-bordered tfoot:last-child tr:last-child > td:last-child, +.table-bordered tfoot:last-child tr:last-child > th:last-child { + -webkit-border-bottom-right-radius: 4px; + -moz-border-radius-bottomright: 4px; + border-bottom-right-radius: 4px; +} +.table-bordered tfoot + tbody:last-child tr:last-child td:first-child { + -webkit-border-bottom-left-radius: 0; + -moz-border-radius-bottomleft: 0; + border-bottom-left-radius: 0; +} +.table-bordered tfoot + tbody:last-child tr:last-child td:last-child { + -webkit-border-bottom-right-radius: 0; + -moz-border-radius-bottomright: 0; + border-bottom-right-radius: 0; +} +.table-bordered caption + thead tr:first-child th:first-child, +.table-bordered caption + tbody tr:first-child td:first-child, +.table-bordered colgroup + thead tr:first-child th:first-child, +.table-bordered colgroup + tbody tr:first-child td:first-child { + -webkit-border-top-left-radius: 4px; + -moz-border-radius-topleft: 4px; + border-top-left-radius: 4px; +} +.table-bordered caption + thead tr:first-child th:last-child, +.table-bordered caption + tbody tr:first-child td:last-child, +.table-bordered colgroup + thead tr:first-child th:last-child, +.table-bordered colgroup + tbody tr:first-child td:last-child { + -webkit-border-top-right-radius: 4px; + -moz-border-radius-topright: 4px; + border-top-right-radius: 4px; +} +.table-striped tbody > tr:nth-child(odd) > td, +.table-striped tbody > tr:nth-child(odd) > th { + background-color: #f9f9f9; +} +.table-hover tbody tr:hover > td, +.table-hover tbody tr:hover > th { + background-color: #f5f5f5; +} +table td[class*="span"], +table th[class*="span"], +.row-fluid table td[class*="span"], +.row-fluid table th[class*="span"] { + display: table-cell; + float: none; + margin-left: 0; +} +.table td.span1, +.table th.span1 { + float: none; + width: 44px; + margin-left: 0; +} +.table td.span2, +.table th.span2 { + float: none; + width: 124px; + margin-left: 0; +} +.table td.span3, +.table th.span3 { + float: none; + width: 204px; + margin-left: 0; +} +.table td.span4, +.table th.span4 { + float: none; + width: 284px; + margin-left: 0; +} +.table td.span5, +.table th.span5 { + float: none; + width: 364px; + margin-left: 0; +} +.table td.span6, +.table th.span6 { + float: none; + width: 444px; + margin-left: 0; +} +.table td.span7, +.table th.span7 { + float: none; + width: 524px; + margin-left: 0; +} +.table td.span8, +.table th.span8 { + float: none; + width: 604px; + margin-left: 0; +} +.table td.span9, +.table th.span9 { + float: none; + width: 684px; + margin-left: 0; +} +.table td.span10, +.table th.span10 { + float: none; + width: 764px; + margin-left: 0; +} +.table td.span11, +.table th.span11 { + float: none; + width: 844px; + margin-left: 0; +} +.table td.span12, +.table th.span12 { + float: none; + width: 924px; + margin-left: 0; +} +.table tbody tr.success > td { + background-color: #dff0d8; +} +.table tbody tr.error > td { + background-color: #f2dede; +} +.table tbody tr.warning > td { + background-color: #fcf8e3; +} +.table tbody tr.info > td { + background-color: #d9edf7; +} +.table-hover tbody tr.success:hover > td { + background-color: #d0e9c6; +} +.table-hover tbody tr.error:hover > td { + background-color: #ebcccc; +} +.table-hover tbody tr.warning:hover > td { + background-color: #faf2cc; +} +.table-hover tbody tr.info:hover > td { + background-color: #c4e3f3; +} +[class^="icon-"], +[class*=" icon-"] { + display: inline-block; + width: 14px; + height: 14px; + *margin-right: .3em; + line-height: 14px; + vertical-align: text-top; + background-image: url("../../img/glyphicons-halflings.png"); + background-position: 14px 14px; + background-repeat: no-repeat; + margin-top: 1px; +} +/* White icons with optional class, or on hover/focus/active states of certain elements */ +.icon-white, +.nav-pills > .active > a > [class^="icon-"], +.nav-pills > .active > a > [class*=" icon-"], +.nav-list > .active > a > [class^="icon-"], +.nav-list > .active > a > [class*=" icon-"], +.navbar-inverse .nav > .active > a > [class^="icon-"], +.navbar-inverse .nav > .active > a > [class*=" icon-"], +.dropdown-menu > li > a:hover > [class^="icon-"], +.dropdown-menu > li > a:focus > [class^="icon-"], +.dropdown-menu > li > a:hover > [class*=" icon-"], +.dropdown-menu > li > a:focus > [class*=" icon-"], +.dropdown-menu > .active > a > [class^="icon-"], +.dropdown-menu > .active > a > [class*=" icon-"], +.dropdown-submenu:hover > a > [class^="icon-"], +.dropdown-submenu:focus > a > [class^="icon-"], +.dropdown-submenu:hover > a > [class*=" icon-"], +.dropdown-submenu:focus > a > [class*=" icon-"] { + background-image: url("../../img/glyphicons-halflings-white.png"); +} +.icon-glass { + background-position: 0 0; +} +.icon-music { + background-position: -24px 0; +} +.icon-search { + background-position: -48px 0; +} +.icon-envelope { + background-position: -72px 0; +} +.icon-heart { + background-position: -96px 0; +} +.icon-star { + background-position: -120px 0; +} +.icon-star-empty { + background-position: -144px 0; +} +.icon-user { + background-position: -168px 0; +} +.icon-film { + background-position: -192px 0; +} +.icon-th-large { + background-position: -216px 0; +} +.icon-th { + background-position: -240px 0; +} +.icon-th-list { + background-position: -264px 0; +} +.icon-ok { + background-position: -288px 0; +} +.icon-remove { + background-position: -312px 0; +} +.icon-zoom-in { + background-position: -336px 0; +} +.icon-zoom-out { + background-position: -360px 0; +} +.icon-off { + background-position: -384px 0; +} +.icon-signal { + background-position: -408px 0; +} +.icon-cog { + background-position: -432px 0; +} +.icon-trash { + background-position: -456px 0; +} +.icon-home { + background-position: 0 -24px; +} +.icon-file { + background-position: -24px -24px; +} +.icon-time { + background-position: -48px -24px; +} +.icon-road { + background-position: -72px -24px; +} +.icon-download-alt { + background-position: -96px -24px; +} +.icon-download { + background-position: -120px -24px; +} +.icon-upload { + background-position: -144px -24px; +} +.icon-inbox { + background-position: -168px -24px; +} +.icon-play-circle { + background-position: -192px -24px; +} +.icon-repeat { + background-position: -216px -24px; +} +.icon-refresh { + background-position: -240px -24px; +} +.icon-list-alt { + background-position: -264px -24px; +} +.icon-lock { + background-position: -287px -24px; +} +.icon-flag { + background-position: -312px -24px; +} +.icon-headphones { + background-position: -336px -24px; +} +.icon-volume-off { + background-position: -360px -24px; +} +.icon-volume-down { + background-position: -384px -24px; +} +.icon-volume-up { + background-position: -408px -24px; +} +.icon-qrcode { + background-position: -432px -24px; +} +.icon-barcode { + background-position: -456px -24px; +} +.icon-tag { + background-position: 0 -48px; +} +.icon-tags { + background-position: -25px -48px; +} +.icon-book { + background-position: -48px -48px; +} +.icon-bookmark { + background-position: -72px -48px; +} +.icon-print { + background-position: -96px -48px; +} +.icon-camera { + background-position: -120px -48px; +} +.icon-font { + background-position: -144px -48px; +} +.icon-bold { + background-position: -167px -48px; +} +.icon-italic { + background-position: -192px -48px; +} +.icon-text-height { + background-position: -216px -48px; +} +.icon-text-width { + background-position: -240px -48px; +} +.icon-align-left { + background-position: -264px -48px; +} +.icon-align-center { + background-position: -288px -48px; +} +.icon-align-right { + background-position: -312px -48px; +} +.icon-align-justify { + background-position: -336px -48px; +} +.icon-list { + background-position: -360px -48px; +} +.icon-indent-left { + background-position: -384px -48px; +} +.icon-indent-right { + background-position: -408px -48px; +} +.icon-facetime-video { + background-position: -432px -48px; +} +.icon-picture { + background-position: -456px -48px; +} +.icon-pencil { + background-position: 0 -72px; +} +.icon-map-marker { + background-position: -24px -72px; +} +.icon-adjust { + background-position: -48px -72px; +} +.icon-tint { + background-position: -72px -72px; +} +.icon-edit { + background-position: -96px -72px; +} +.icon-share { + background-position: -120px -72px; +} +.icon-check { + background-position: -144px -72px; +} +.icon-move { + background-position: -168px -72px; +} +.icon-step-backward { + background-position: -192px -72px; +} +.icon-fast-backward { + background-position: -216px -72px; +} +.icon-backward { + background-position: -240px -72px; +} +.icon-play { + background-position: -264px -72px; +} +.icon-pause { + background-position: -288px -72px; +} +.icon-stop { + background-position: -312px -72px; +} +.icon-forward { + background-position: -336px -72px; +} +.icon-fast-forward { + background-position: -360px -72px; +} +.icon-step-forward { + background-position: -384px -72px; +} +.icon-eject { + background-position: -408px -72px; +} +.icon-chevron-left { + background-position: -432px -72px; +} +.icon-chevron-right { + background-position: -456px -72px; +} +.icon-plus-sign { + background-position: 0 -96px; +} +.icon-minus-sign { + background-position: -24px -96px; +} +.icon-remove-sign { + background-position: -48px -96px; +} +.icon-ok-sign { + background-position: -72px -96px; +} +.icon-question-sign { + background-position: -96px -96px; +} +.icon-info-sign { + background-position: -120px -96px; +} +.icon-screenshot { + background-position: -144px -96px; +} +.icon-remove-circle { + background-position: -168px -96px; +} +.icon-ok-circle { + background-position: -192px -96px; +} +.icon-ban-circle { + background-position: -216px -96px; +} +.icon-arrow-left { + background-position: -240px -96px; +} +.icon-arrow-right { + background-position: -264px -96px; +} +.icon-arrow-up { + background-position: -289px -96px; +} +.icon-arrow-down { + background-position: -312px -96px; +} +.icon-share-alt { + background-position: -336px -96px; +} +.icon-resize-full { + background-position: -360px -96px; +} +.icon-resize-small { + background-position: -384px -96px; +} +.icon-plus { + background-position: -408px -96px; +} +.icon-minus { + background-position: -433px -96px; +} +.icon-asterisk { + background-position: -456px -96px; +} +.icon-exclamation-sign { + background-position: 0 -120px; +} +.icon-gift { + background-position: -24px -120px; +} +.icon-leaf { + background-position: -48px -120px; +} +.icon-fire { + background-position: -72px -120px; +} +.icon-eye-open { + background-position: -96px -120px; +} +.icon-eye-close { + background-position: -120px -120px; +} +.icon-warning-sign { + background-position: -144px -120px; +} +.icon-plane { + background-position: -168px -120px; +} +.icon-calendar { + background-position: -192px -120px; +} +.icon-random { + background-position: -216px -120px; + width: 16px; +} +.icon-comment { + background-position: -240px -120px; +} +.icon-magnet { + background-position: -264px -120px; +} +.icon-chevron-up { + background-position: -288px -120px; +} +.icon-chevron-down { + background-position: -313px -119px; +} +.icon-retweet { + background-position: -336px -120px; +} +.icon-shopping-cart { + background-position: -360px -120px; +} +.icon-folder-close { + background-position: -384px -120px; + width: 16px; +} +.icon-folder-open { + background-position: -408px -120px; + width: 16px; +} +.icon-resize-vertical { + background-position: -432px -119px; +} +.icon-resize-horizontal { + background-position: -456px -118px; +} +.icon-hdd { + background-position: 0 -144px; +} +.icon-bullhorn { + background-position: -24px -144px; +} +.icon-bell { + background-position: -48px -144px; +} +.icon-certificate { + background-position: -72px -144px; +} +.icon-thumbs-up { + background-position: -96px -144px; +} +.icon-thumbs-down { + background-position: -120px -144px; +} +.icon-hand-right { + background-position: -144px -144px; +} +.icon-hand-left { + background-position: -168px -144px; +} +.icon-hand-up { + background-position: -192px -144px; +} +.icon-hand-down { + background-position: -216px -144px; +} +.icon-circle-arrow-right { + background-position: -240px -144px; +} +.icon-circle-arrow-left { + background-position: -264px -144px; +} +.icon-circle-arrow-up { + background-position: -288px -144px; +} +.icon-circle-arrow-down { + background-position: -312px -144px; +} +.icon-globe { + background-position: -336px -144px; +} +.icon-wrench { + background-position: -360px -144px; +} +.icon-tasks { + background-position: -384px -144px; +} +.icon-filter { + background-position: -408px -144px; +} +.icon-briefcase { + background-position: -432px -144px; +} +.icon-fullscreen { + background-position: -456px -144px; +} +.dropup, +.dropdown { + position: relative; +} +.dropdown-toggle { + *margin-bottom: -3px; +} +.dropdown-toggle:active, +.open .dropdown-toggle { + outline: 0; +} +.caret { + display: inline-block; + width: 0; + height: 0; + vertical-align: top; + border-top: 4px solid #000000; + border-right: 4px solid transparent; + border-left: 4px solid transparent; + content: ""; +} +.dropdown .caret { + margin-top: 8px; + margin-left: 2px; +} +.dropdown-menu { + position: absolute; + top: 100%; + left: 0; + z-index: 1000; + display: none; + float: left; + min-width: 160px; + padding: 5px 0; + margin: 2px 0 0; + list-style: none; + background-color: #ffffff; + border: 1px solid #ccc; + border: 1px solid rgba(0, 0, 0, 0.2); + *border-right-width: 2px; + *border-bottom-width: 2px; + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; + -webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); + -moz-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); + box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); + -webkit-background-clip: padding-box; + -moz-background-clip: padding; + background-clip: padding-box; +} +.dropdown-menu.pull-right { + right: 0; + left: auto; +} +.dropdown-menu .divider { + *width: 100%; + height: 1px; + margin: 9.5px 1px; + *margin: -5px 0 5px; + overflow: hidden; + background-color: #e5e5e5; + border-bottom: 1px solid #ffffff; +} +.dropdown-menu > li > a { + display: block; + padding: 3px 20px; + clear: both; + font-weight: normal; + line-height: 21px; + color: #333333; + white-space: nowrap; +} +.dropdown-menu > li > a:hover, +.dropdown-menu > li > a:focus, +.dropdown-submenu:hover > a, +.dropdown-submenu:focus > a { + text-decoration: none; + color: #ffffff; + background-color: #0081c2; + background-image: -moz-linear-gradient(top, #0088cc, #0077b3); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#0088cc), to(#0077b3)); + background-image: -webkit-linear-gradient(top, #0088cc, #0077b3); + background-image: -o-linear-gradient(top, #0088cc, #0077b3); + background-image: linear-gradient(to bottom, #0088cc, #0077b3); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc', endColorstr='#ff0077b3', GradientType=0); +} +.dropdown-menu > .active > a, +.dropdown-menu > .active > a:hover, +.dropdown-menu > .active > a:focus { + color: #ffffff; + text-decoration: none; + outline: 0; + background-color: #0081c2; + background-image: -moz-linear-gradient(top, #0088cc, #0077b3); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#0088cc), to(#0077b3)); + background-image: -webkit-linear-gradient(top, #0088cc, #0077b3); + background-image: -o-linear-gradient(top, #0088cc, #0077b3); + background-image: linear-gradient(to bottom, #0088cc, #0077b3); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc', endColorstr='#ff0077b3', GradientType=0); +} +.dropdown-menu > .disabled > a, +.dropdown-menu > .disabled > a:hover, +.dropdown-menu > .disabled > a:focus { + color: #999999; +} +.dropdown-menu > .disabled > a:hover, +.dropdown-menu > .disabled > a:focus { + text-decoration: none; + background-color: transparent; + background-image: none; + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); + cursor: default; +} +.open { + *z-index: 1000; +} +.open > .dropdown-menu { + display: block; +} +.pull-right > .dropdown-menu { + right: 0; + left: auto; +} +.dropup .caret, +.navbar-fixed-bottom .dropdown .caret { + border-top: 0; + border-bottom: 4px solid #000000; + content: ""; +} +.dropup .dropdown-menu, +.navbar-fixed-bottom .dropdown .dropdown-menu { + top: auto; + bottom: 100%; + margin-bottom: 1px; +} +.dropdown-submenu { + position: relative; +} +.dropdown-submenu > .dropdown-menu { + top: 0; + left: 100%; + margin-top: -6px; + margin-left: -1px; + -webkit-border-radius: 0 6px 6px 6px; + -moz-border-radius: 0 6px 6px 6px; + border-radius: 0 6px 6px 6px; +} +.dropdown-submenu:hover > .dropdown-menu { + display: block; +} +.dropup .dropdown-submenu > .dropdown-menu { + top: auto; + bottom: 0; + margin-top: 0; + margin-bottom: -2px; + -webkit-border-radius: 5px 5px 5px 0; + -moz-border-radius: 5px 5px 5px 0; + border-radius: 5px 5px 5px 0; +} +.dropdown-submenu > a:after { + display: block; + content: " "; + float: right; + width: 0; + height: 0; + border-color: transparent; + border-style: solid; + border-width: 5px 0 5px 5px; + border-left-color: #cccccc; + margin-top: 5px; + margin-right: -10px; +} +.dropdown-submenu:hover > a:after { + border-left-color: #ffffff; +} +.dropdown-submenu.pull-left { + float: none; +} +.dropdown-submenu.pull-left > .dropdown-menu { + left: -100%; + margin-left: 10px; + -webkit-border-radius: 6px 0 6px 6px; + -moz-border-radius: 6px 0 6px 6px; + border-radius: 6px 0 6px 6px; +} +.dropdown .dropdown-menu .nav-header { + padding-left: 20px; + padding-right: 20px; +} +.typeahead { + z-index: 1051; + margin-top: 2px; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; +} +.well { + min-height: 20px; + padding: 19px; + margin-bottom: 20px; + background-color: #f5f5f5; + border: 1px solid #e3e3e3; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05); + -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05); +} +.well blockquote { + border-color: #ddd; + border-color: rgba(0, 0, 0, 0.15); +} +.well-large { + padding: 24px; + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; +} +.well-small { + padding: 9px; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; +} +.fade { + opacity: 0; + -webkit-transition: opacity 0.15s linear; + -moz-transition: opacity 0.15s linear; + -o-transition: opacity 0.15s linear; + transition: opacity 0.15s linear; +} +.fade.in { + opacity: 1; +} +.collapse { + position: relative; + height: 0; + overflow: hidden; + -webkit-transition: height 0.35s ease; + -moz-transition: height 0.35s ease; + -o-transition: height 0.35s ease; + transition: height 0.35s ease; +} +.collapse.in { + height: auto; +} +.close { + float: right; + font-size: 20px; + font-weight: bold; + line-height: 21px; + color: #000000; + text-shadow: 0 1px 0 #ffffff; + opacity: 0.2; + filter: alpha(opacity=20); +} +.close:hover, +.close:focus { + color: #000000; + text-decoration: none; + cursor: pointer; + opacity: 0.4; + filter: alpha(opacity=40); +} +button.close { + padding: 0; + cursor: pointer; + background: transparent; + border: 0; + -webkit-appearance: none; +} +.btn { + display: inline-block; + *display: inline; + /* IE7 inline-block hack */ + *zoom: 1; + padding: 4px 12px; + margin-bottom: 0; + font-size: 16px; + line-height: 21px; + text-align: center; + vertical-align: middle; + cursor: pointer; + color: #333333; + text-shadow: 0 1px 1px rgba(255, 255, 255, 0.75); + background-color: #f5f5f5; + background-image: -moz-linear-gradient(top, #ffffff, #e6e6e6); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#ffffff), to(#e6e6e6)); + background-image: -webkit-linear-gradient(top, #ffffff, #e6e6e6); + background-image: -o-linear-gradient(top, #ffffff, #e6e6e6); + background-image: linear-gradient(to bottom, #ffffff, #e6e6e6); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffe6e6e6', GradientType=0); + border-color: #e6e6e6 #e6e6e6 #bfbfbf; + border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); + *background-color: #e6e6e6; + /* Darken IE7 buttons by default so they stand out more given they won't have borders */ + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); + border: 1px solid #cccccc; + *border: 0; + border-bottom-color: #b3b3b3; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; + *margin-left: .3em; + -webkit-box-shadow: inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05); + -moz-box-shadow: inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05); + box-shadow: inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05); +} +.btn:hover, +.btn:focus, +.btn:active, +.btn.active, +.btn.disabled, +.btn[disabled] { + color: #333333; + background-color: #e6e6e6; + *background-color: #d9d9d9; +} +.btn:active, +.btn.active { + background-color: #cccccc \9; +} +.btn:first-child { + *margin-left: 0; +} +.btn:hover, +.btn:focus { + color: #333333; + text-decoration: none; + background-position: 0 -15px; + -webkit-transition: background-position 0.1s linear; + -moz-transition: background-position 0.1s linear; + -o-transition: background-position 0.1s linear; + transition: background-position 0.1s linear; +} +.btn:focus { + outline: thin dotted #333; + outline: 5px auto -webkit-focus-ring-color; + outline-offset: -2px; +} +.btn.active, +.btn:active { + background-image: none; + outline: 0; + -webkit-box-shadow: inset 0 2px 4px rgba(0,0,0,.15), 0 1px 2px rgba(0,0,0,.05); + -moz-box-shadow: inset 0 2px 4px rgba(0,0,0,.15), 0 1px 2px rgba(0,0,0,.05); + box-shadow: inset 0 2px 4px rgba(0,0,0,.15), 0 1px 2px rgba(0,0,0,.05); +} +.btn.disabled, +.btn[disabled] { + cursor: default; + background-image: none; + opacity: 0.65; + filter: alpha(opacity=65); + -webkit-box-shadow: none; + -moz-box-shadow: none; + box-shadow: none; +} +.btn-large { + padding: 11px 19px; + font-size: 20px; + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; +} +.btn-large [class^="icon-"], +.btn-large [class*=" icon-"] { + margin-top: 4px; +} +.btn-small { + padding: 2px 10px; + font-size: 13.6px; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; +} +.btn-small [class^="icon-"], +.btn-small [class*=" icon-"] { + margin-top: 0; +} +.btn-mini [class^="icon-"], +.btn-mini [class*=" icon-"] { + margin-top: -1px; +} +.btn-mini { + padding: 0 6px; + font-size: 12px; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; +} +.btn-block { + display: block; + width: 100%; + padding-left: 0; + padding-right: 0; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} +.btn-block + .btn-block { + margin-top: 5px; +} +input[type="submit"].btn-block, +input[type="reset"].btn-block, +input[type="button"].btn-block { + width: 100%; +} +.btn-primary.active, +.btn-warning.active, +.btn-danger.active, +.btn-success.active, +.btn-info.active, +.btn-inverse.active { + color: rgba(255, 255, 255, 0.75); +} +.btn-primary { + color: #ffffff; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); + background-color: #006dcc; + background-image: -moz-linear-gradient(top, #0088cc, #0044cc); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#0088cc), to(#0044cc)); + background-image: -webkit-linear-gradient(top, #0088cc, #0044cc); + background-image: -o-linear-gradient(top, #0088cc, #0044cc); + background-image: linear-gradient(to bottom, #0088cc, #0044cc); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc', endColorstr='#ff0044cc', GradientType=0); + border-color: #0044cc #0044cc #002a80; + border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); + *background-color: #0044cc; + /* Darken IE7 buttons by default so they stand out more given they won't have borders */ + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); +} +.btn-primary:hover, +.btn-primary:focus, +.btn-primary:active, +.btn-primary.active, +.btn-primary.disabled, +.btn-primary[disabled] { + color: #ffffff; + background-color: #0044cc; + *background-color: #003bb3; +} +.btn-primary:active, +.btn-primary.active { + background-color: #003399 \9; +} +.btn-warning { + color: #ffffff; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); + background-color: #faa732; + background-image: -moz-linear-gradient(top, #fbb450, #f89406); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#fbb450), to(#f89406)); + background-image: -webkit-linear-gradient(top, #fbb450, #f89406); + background-image: -o-linear-gradient(top, #fbb450, #f89406); + background-image: linear-gradient(to bottom, #fbb450, #f89406); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffbb450', endColorstr='#fff89406', GradientType=0); + border-color: #f89406 #f89406 #ad6704; + border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); + *background-color: #f89406; + /* Darken IE7 buttons by default so they stand out more given they won't have borders */ + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); +} +.btn-warning:hover, +.btn-warning:focus, +.btn-warning:active, +.btn-warning.active, +.btn-warning.disabled, +.btn-warning[disabled] { + color: #ffffff; + background-color: #f89406; + *background-color: #df8505; +} +.btn-warning:active, +.btn-warning.active { + background-color: #c67605 \9; +} +.btn-danger { + color: #ffffff; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); + background-color: #da4f49; + background-image: -moz-linear-gradient(top, #ee5f5b, #bd362f); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#ee5f5b), to(#bd362f)); + background-image: -webkit-linear-gradient(top, #ee5f5b, #bd362f); + background-image: -o-linear-gradient(top, #ee5f5b, #bd362f); + background-image: linear-gradient(to bottom, #ee5f5b, #bd362f); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffee5f5b', endColorstr='#ffbd362f', GradientType=0); + border-color: #bd362f #bd362f #802420; + border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); + *background-color: #bd362f; + /* Darken IE7 buttons by default so they stand out more given they won't have borders */ + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); +} +.btn-danger:hover, +.btn-danger:focus, +.btn-danger:active, +.btn-danger.active, +.btn-danger.disabled, +.btn-danger[disabled] { + color: #ffffff; + background-color: #bd362f; + *background-color: #a9302a; +} +.btn-danger:active, +.btn-danger.active { + background-color: #942a25 \9; +} +.btn-success { + color: #ffffff; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); + background-color: #5bb75b; + background-image: -moz-linear-gradient(top, #62c462, #51a351); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#62c462), to(#51a351)); + background-image: -webkit-linear-gradient(top, #62c462, #51a351); + background-image: -o-linear-gradient(top, #62c462, #51a351); + background-image: linear-gradient(to bottom, #62c462, #51a351); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff62c462', endColorstr='#ff51a351', GradientType=0); + border-color: #51a351 #51a351 #387038; + border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); + *background-color: #51a351; + /* Darken IE7 buttons by default so they stand out more given they won't have borders */ + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); +} +.btn-success:hover, +.btn-success:focus, +.btn-success:active, +.btn-success.active, +.btn-success.disabled, +.btn-success[disabled] { + color: #ffffff; + background-color: #51a351; + *background-color: #499249; +} +.btn-success:active, +.btn-success.active { + background-color: #408140 \9; +} +.btn-info { + color: #ffffff; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); + background-color: #49afcd; + background-image: -moz-linear-gradient(top, #5bc0de, #2f96b4); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#5bc0de), to(#2f96b4)); + background-image: -webkit-linear-gradient(top, #5bc0de, #2f96b4); + background-image: -o-linear-gradient(top, #5bc0de, #2f96b4); + background-image: linear-gradient(to bottom, #5bc0de, #2f96b4); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff2f96b4', GradientType=0); + border-color: #2f96b4 #2f96b4 #1f6377; + border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); + *background-color: #2f96b4; + /* Darken IE7 buttons by default so they stand out more given they won't have borders */ + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); +} +.btn-info:hover, +.btn-info:focus, +.btn-info:active, +.btn-info.active, +.btn-info.disabled, +.btn-info[disabled] { + color: #ffffff; + background-color: #2f96b4; + *background-color: #2a85a0; +} +.btn-info:active, +.btn-info.active { + background-color: #24748c \9; +} +.btn-inverse { + color: #ffffff; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); + background-color: #363636; + background-image: -moz-linear-gradient(top, #444444, #222222); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#444444), to(#222222)); + background-image: -webkit-linear-gradient(top, #444444, #222222); + background-image: -o-linear-gradient(top, #444444, #222222); + background-image: linear-gradient(to bottom, #444444, #222222); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff444444', endColorstr='#ff222222', GradientType=0); + border-color: #222222 #222222 #000000; + border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); + *background-color: #222222; + /* Darken IE7 buttons by default so they stand out more given they won't have borders */ + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); +} +.btn-inverse:hover, +.btn-inverse:focus, +.btn-inverse:active, +.btn-inverse.active, +.btn-inverse.disabled, +.btn-inverse[disabled] { + color: #ffffff; + background-color: #222222; + *background-color: #151515; +} +.btn-inverse:active, +.btn-inverse.active { + background-color: #080808 \9; +} +button.btn, +input[type="submit"].btn { + *padding-top: 3px; + *padding-bottom: 3px; +} +button.btn::-moz-focus-inner, +input[type="submit"].btn::-moz-focus-inner { + padding: 0; + border: 0; +} +button.btn.btn-large, +input[type="submit"].btn.btn-large { + *padding-top: 7px; + *padding-bottom: 7px; +} +button.btn.btn-small, +input[type="submit"].btn.btn-small { + *padding-top: 3px; + *padding-bottom: 3px; +} +button.btn.btn-mini, +input[type="submit"].btn.btn-mini { + *padding-top: 1px; + *padding-bottom: 1px; +} +.btn-link, +.btn-link:active, +.btn-link[disabled] { + background-color: transparent; + background-image: none; + -webkit-box-shadow: none; + -moz-box-shadow: none; + box-shadow: none; +} +.btn-link { + border-color: transparent; + cursor: pointer; + color: #0088cc; + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; +} +.btn-link:hover, +.btn-link:focus { + color: #005580; + text-decoration: underline; + background-color: transparent; +} +.btn-link[disabled]:hover, +.btn-link[disabled]:focus { + color: #333333; + text-decoration: none; +} +.btn-group { + position: relative; + display: inline-block; + *display: inline; + /* IE7 inline-block hack */ + *zoom: 1; + font-size: 0; + vertical-align: middle; + white-space: nowrap; + *margin-left: .3em; +} +.btn-group:first-child { + *margin-left: 0; +} +.btn-group + .btn-group { + margin-left: 5px; +} +.btn-toolbar { + font-size: 0; + margin-top: 10.5px; + margin-bottom: 10.5px; +} +.btn-toolbar > .btn + .btn, +.btn-toolbar > .btn-group + .btn, +.btn-toolbar > .btn + .btn-group { + margin-left: 5px; +} +.btn-group > .btn { + position: relative; + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; +} +.btn-group > .btn + .btn { + margin-left: -1px; +} +.btn-group > .btn, +.btn-group > .dropdown-menu, +.btn-group > .popover { + font-size: 16px; +} +.btn-group > .btn-mini { + font-size: 12px; +} +.btn-group > .btn-small { + font-size: 13.6px; +} +.btn-group > .btn-large { + font-size: 20px; +} +.btn-group > .btn:first-child { + margin-left: 0; + -webkit-border-top-left-radius: 4px; + -moz-border-radius-topleft: 4px; + border-top-left-radius: 4px; + -webkit-border-bottom-left-radius: 4px; + -moz-border-radius-bottomleft: 4px; + border-bottom-left-radius: 4px; +} +.btn-group > .btn:last-child, +.btn-group > .dropdown-toggle { + -webkit-border-top-right-radius: 4px; + -moz-border-radius-topright: 4px; + border-top-right-radius: 4px; + -webkit-border-bottom-right-radius: 4px; + -moz-border-radius-bottomright: 4px; + border-bottom-right-radius: 4px; +} +.btn-group > .btn.large:first-child { + margin-left: 0; + -webkit-border-top-left-radius: 6px; + -moz-border-radius-topleft: 6px; + border-top-left-radius: 6px; + -webkit-border-bottom-left-radius: 6px; + -moz-border-radius-bottomleft: 6px; + border-bottom-left-radius: 6px; +} +.btn-group > .btn.large:last-child, +.btn-group > .large.dropdown-toggle { + -webkit-border-top-right-radius: 6px; + -moz-border-radius-topright: 6px; + border-top-right-radius: 6px; + -webkit-border-bottom-right-radius: 6px; + -moz-border-radius-bottomright: 6px; + border-bottom-right-radius: 6px; +} +.btn-group > .btn:hover, +.btn-group > .btn:focus, +.btn-group > .btn:active, +.btn-group > .btn.active { + z-index: 2; +} +.btn-group .dropdown-toggle:active, +.btn-group.open .dropdown-toggle { + outline: 0; +} +.btn-group > .btn + .dropdown-toggle { + padding-left: 8px; + padding-right: 8px; + -webkit-box-shadow: inset 1px 0 0 rgba(255,255,255,.125), inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05); + -moz-box-shadow: inset 1px 0 0 rgba(255,255,255,.125), inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05); + box-shadow: inset 1px 0 0 rgba(255,255,255,.125), inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05); + *padding-top: 5px; + *padding-bottom: 5px; +} +.btn-group > .btn-mini + .dropdown-toggle { + padding-left: 5px; + padding-right: 5px; + *padding-top: 2px; + *padding-bottom: 2px; +} +.btn-group > .btn-small + .dropdown-toggle { + *padding-top: 5px; + *padding-bottom: 4px; +} +.btn-group > .btn-large + .dropdown-toggle { + padding-left: 12px; + padding-right: 12px; + *padding-top: 7px; + *padding-bottom: 7px; +} +.btn-group.open .dropdown-toggle { + background-image: none; + -webkit-box-shadow: inset 0 2px 4px rgba(0,0,0,.15), 0 1px 2px rgba(0,0,0,.05); + -moz-box-shadow: inset 0 2px 4px rgba(0,0,0,.15), 0 1px 2px rgba(0,0,0,.05); + box-shadow: inset 0 2px 4px rgba(0,0,0,.15), 0 1px 2px rgba(0,0,0,.05); +} +.btn-group.open .btn.dropdown-toggle { + background-color: #e6e6e6; +} +.btn-group.open .btn-primary.dropdown-toggle { + background-color: #0044cc; +} +.btn-group.open .btn-warning.dropdown-toggle { + background-color: #f89406; +} +.btn-group.open .btn-danger.dropdown-toggle { + background-color: #bd362f; +} +.btn-group.open .btn-success.dropdown-toggle { + background-color: #51a351; +} +.btn-group.open .btn-info.dropdown-toggle { + background-color: #2f96b4; +} +.btn-group.open .btn-inverse.dropdown-toggle { + background-color: #222222; +} +.btn .caret { + margin-top: 8px; + margin-left: 0; +} +.btn-large .caret { + margin-top: 6px; +} +.btn-large .caret { + border-left-width: 5px; + border-right-width: 5px; + border-top-width: 5px; +} +.btn-mini .caret, +.btn-small .caret { + margin-top: 8px; +} +.dropup .btn-large .caret { + border-bottom-width: 5px; +} +.btn-primary .caret, +.btn-warning .caret, +.btn-danger .caret, +.btn-info .caret, +.btn-success .caret, +.btn-inverse .caret { + border-top-color: #ffffff; + border-bottom-color: #ffffff; +} +.btn-group-vertical { + display: inline-block; + *display: inline; + /* IE7 inline-block hack */ + *zoom: 1; +} +.btn-group-vertical > .btn { + display: block; + float: none; + max-width: 100%; + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; +} +.btn-group-vertical > .btn + .btn { + margin-left: 0; + margin-top: -1px; +} +.btn-group-vertical > .btn:first-child { + -webkit-border-radius: 4px 4px 0 0; + -moz-border-radius: 4px 4px 0 0; + border-radius: 4px 4px 0 0; +} +.btn-group-vertical > .btn:last-child { + -webkit-border-radius: 0 0 4px 4px; + -moz-border-radius: 0 0 4px 4px; + border-radius: 0 0 4px 4px; +} +.btn-group-vertical > .btn-large:first-child { + -webkit-border-radius: 6px 6px 0 0; + -moz-border-radius: 6px 6px 0 0; + border-radius: 6px 6px 0 0; +} +.btn-group-vertical > .btn-large:last-child { + -webkit-border-radius: 0 0 6px 6px; + -moz-border-radius: 0 0 6px 6px; + border-radius: 0 0 6px 6px; +} +.alert { + padding: 8px 35px 8px 14px; + margin-bottom: 21px; + text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5); + background-color: #fcf8e3; + border: 1px solid #fbeed5; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; +} +.alert, +.alert h4 { + color: #c09853; +} +.alert h4 { + margin: 0; +} +.alert .close { + position: relative; + top: -2px; + right: -21px; + line-height: 21px; +} +.alert-success { + background-color: #dff0d8; + border-color: #d6e9c6; + color: #468847; +} +.alert-success h4 { + color: #468847; +} +.alert-danger, +.alert-error { + background-color: #f2dede; + border-color: #eed3d7; + color: #b94a48; +} +.alert-danger h4, +.alert-error h4 { + color: #b94a48; +} +.alert-info { + background-color: #d9edf7; + border-color: #bce8f1; + color: #3a87ad; +} +.alert-info h4 { + color: #3a87ad; +} +.alert-block { + padding-top: 14px; + padding-bottom: 14px; +} +.alert-block > p, +.alert-block > ul { + margin-bottom: 0; +} +.alert-block p + p { + margin-top: 5px; +} +.nav { + margin-left: 0; + margin-bottom: 21px; + list-style: none; +} +.nav > li > a { + display: block; +} +.nav > li > a:hover, +.nav > li > a:focus { + text-decoration: none; + background-color: #eeeeee; +} +.nav > li > a > img { + max-width: none; +} +.nav > .pull-right { + float: right; +} +.nav-header { + display: block; + padding: 3px 15px; + font-size: 11px; + font-weight: bold; + line-height: 21px; + color: #999999; + text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5); + text-transform: uppercase; +} +.nav li + .nav-header { + margin-top: 9px; +} +.nav-list { + padding-left: 15px; + padding-right: 15px; + margin-bottom: 0; +} +.nav-list > li > a, +.nav-list .nav-header { + margin-left: -15px; + margin-right: -15px; + text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5); +} +.nav-list > li > a { + padding: 3px 15px; +} +.nav-list > .active > a, +.nav-list > .active > a:hover, +.nav-list > .active > a:focus { + color: #ffffff; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.2); + background-color: #0088cc; +} +.nav-list [class^="icon-"], +.nav-list [class*=" icon-"] { + margin-right: 2px; +} +.nav-list .divider { + *width: 100%; + height: 1px; + margin: 9.5px 1px; + *margin: -5px 0 5px; + overflow: hidden; + background-color: #e5e5e5; + border-bottom: 1px solid #ffffff; +} +.nav-tabs, +.nav-pills { + *zoom: 1; +} +.nav-tabs:before, +.nav-pills:before, +.nav-tabs:after, +.nav-pills:after { + display: table; + content: ""; + line-height: 0; +} +.nav-tabs:after, +.nav-pills:after { + clear: both; +} +.nav-tabs > li, +.nav-pills > li { + float: left; +} +.nav-tabs > li > a, +.nav-pills > li > a { + padding-right: 12px; + padding-left: 12px; + margin-right: 2px; + line-height: 14px; +} +.nav-tabs { + border-bottom: 1px solid #ddd; +} +.nav-tabs > li { + margin-bottom: -1px; +} +.nav-tabs > li > a { + padding-top: 8px; + padding-bottom: 8px; + line-height: 21px; + border: 1px solid transparent; + -webkit-border-radius: 4px 4px 0 0; + -moz-border-radius: 4px 4px 0 0; + border-radius: 4px 4px 0 0; +} +.nav-tabs > li > a:hover, +.nav-tabs > li > a:focus { + border-color: #eeeeee #eeeeee #dddddd; +} +.nav-tabs > .active > a, +.nav-tabs > .active > a:hover, +.nav-tabs > .active > a:focus { + color: #555555; + background-color: #ffffff; + border: 1px solid #ddd; + border-bottom-color: transparent; + cursor: default; +} +.nav-pills > li > a { + padding-top: 8px; + padding-bottom: 8px; + margin-top: 2px; + margin-bottom: 2px; + -webkit-border-radius: 5px; + -moz-border-radius: 5px; + border-radius: 5px; +} +.nav-pills > .active > a, +.nav-pills > .active > a:hover, +.nav-pills > .active > a:focus { + color: #ffffff; + background-color: #0088cc; +} +.nav-stacked > li { + float: none; +} +.nav-stacked > li > a { + margin-right: 0; +} +.nav-tabs.nav-stacked { + border-bottom: 0; +} +.nav-tabs.nav-stacked > li > a { + border: 1px solid #ddd; + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; +} +.nav-tabs.nav-stacked > li:first-child > a { + -webkit-border-top-right-radius: 4px; + -moz-border-radius-topright: 4px; + border-top-right-radius: 4px; + -webkit-border-top-left-radius: 4px; + -moz-border-radius-topleft: 4px; + border-top-left-radius: 4px; +} +.nav-tabs.nav-stacked > li:last-child > a { + -webkit-border-bottom-right-radius: 4px; + -moz-border-radius-bottomright: 4px; + border-bottom-right-radius: 4px; + -webkit-border-bottom-left-radius: 4px; + -moz-border-radius-bottomleft: 4px; + border-bottom-left-radius: 4px; +} +.nav-tabs.nav-stacked > li > a:hover, +.nav-tabs.nav-stacked > li > a:focus { + border-color: #ddd; + z-index: 2; +} +.nav-pills.nav-stacked > li > a { + margin-bottom: 3px; +} +.nav-pills.nav-stacked > li:last-child > a { + margin-bottom: 1px; +} +.nav-tabs .dropdown-menu { + -webkit-border-radius: 0 0 6px 6px; + -moz-border-radius: 0 0 6px 6px; + border-radius: 0 0 6px 6px; +} +.nav-pills .dropdown-menu { + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; +} +.nav .dropdown-toggle .caret { + border-top-color: #0088cc; + border-bottom-color: #0088cc; + margin-top: 6px; +} +.nav .dropdown-toggle:hover .caret, +.nav .dropdown-toggle:focus .caret { + border-top-color: #005580; + border-bottom-color: #005580; +} +/* move down carets for tabs */ +.nav-tabs .dropdown-toggle .caret { + margin-top: 8px; +} +.nav .active .dropdown-toggle .caret { + border-top-color: #fff; + border-bottom-color: #fff; +} +.nav-tabs .active .dropdown-toggle .caret { + border-top-color: #555555; + border-bottom-color: #555555; +} +.nav > .dropdown.active > a:hover, +.nav > .dropdown.active > a:focus { + cursor: pointer; +} +.nav-tabs .open .dropdown-toggle, +.nav-pills .open .dropdown-toggle, +.nav > li.dropdown.open.active > a:hover, +.nav > li.dropdown.open.active > a:focus { + color: #ffffff; + background-color: #999999; + border-color: #999999; +} +.nav li.dropdown.open .caret, +.nav li.dropdown.open.active .caret, +.nav li.dropdown.open a:hover .caret, +.nav li.dropdown.open a:focus .caret { + border-top-color: #ffffff; + border-bottom-color: #ffffff; + opacity: 1; + filter: alpha(opacity=100); +} +.tabs-stacked .open > a:hover, +.tabs-stacked .open > a:focus { + border-color: #999999; +} +.tabbable { + *zoom: 1; +} +.tabbable:before, +.tabbable:after { + display: table; + content: ""; + line-height: 0; +} +.tabbable:after { + clear: both; +} +.tab-content { + overflow: auto; +} +.tabs-below > .nav-tabs, +.tabs-right > .nav-tabs, +.tabs-left > .nav-tabs { + border-bottom: 0; +} +.tab-content > .tab-pane, +.pill-content > .pill-pane { + display: none; +} +.tab-content > .active, +.pill-content > .active { + display: block; +} +.tabs-below > .nav-tabs { + border-top: 1px solid #ddd; +} +.tabs-below > .nav-tabs > li { + margin-top: -1px; + margin-bottom: 0; +} +.tabs-below > .nav-tabs > li > a { + -webkit-border-radius: 0 0 4px 4px; + -moz-border-radius: 0 0 4px 4px; + border-radius: 0 0 4px 4px; +} +.tabs-below > .nav-tabs > li > a:hover, +.tabs-below > .nav-tabs > li > a:focus { + border-bottom-color: transparent; + border-top-color: #ddd; +} +.tabs-below > .nav-tabs > .active > a, +.tabs-below > .nav-tabs > .active > a:hover, +.tabs-below > .nav-tabs > .active > a:focus { + border-color: transparent #ddd #ddd #ddd; +} +.tabs-left > .nav-tabs > li, +.tabs-right > .nav-tabs > li { + float: none; +} +.tabs-left > .nav-tabs > li > a, +.tabs-right > .nav-tabs > li > a { + min-width: 74px; + margin-right: 0; + margin-bottom: 3px; +} +.tabs-left > .nav-tabs { + float: left; + margin-right: 19px; + border-right: 1px solid #ddd; +} +.tabs-left > .nav-tabs > li > a { + margin-right: -1px; + -webkit-border-radius: 4px 0 0 4px; + -moz-border-radius: 4px 0 0 4px; + border-radius: 4px 0 0 4px; +} +.tabs-left > .nav-tabs > li > a:hover, +.tabs-left > .nav-tabs > li > a:focus { + border-color: #eeeeee #dddddd #eeeeee #eeeeee; +} +.tabs-left > .nav-tabs .active > a, +.tabs-left > .nav-tabs .active > a:hover, +.tabs-left > .nav-tabs .active > a:focus { + border-color: #ddd transparent #ddd #ddd; + *border-right-color: #ffffff; +} +.tabs-right > .nav-tabs { + float: right; + margin-left: 19px; + border-left: 1px solid #ddd; +} +.tabs-right > .nav-tabs > li > a { + margin-left: -1px; + -webkit-border-radius: 0 4px 4px 0; + -moz-border-radius: 0 4px 4px 0; + border-radius: 0 4px 4px 0; +} +.tabs-right > .nav-tabs > li > a:hover, +.tabs-right > .nav-tabs > li > a:focus { + border-color: #eeeeee #eeeeee #eeeeee #dddddd; +} +.tabs-right > .nav-tabs .active > a, +.tabs-right > .nav-tabs .active > a:hover, +.tabs-right > .nav-tabs .active > a:focus { + border-color: #ddd #ddd #ddd transparent; + *border-left-color: #ffffff; +} +.nav > .disabled > a { + color: #999999; +} +.nav > .disabled > a:hover, +.nav > .disabled > a:focus { + text-decoration: none; + background-color: transparent; + cursor: default; +} +.navbar { + overflow: visible; + margin-bottom: 21px; + *position: relative; + *z-index: 2; +} +.navbar-inner { + min-height: 40px; + padding-left: 20px; + padding-right: 20px; + background-color: #fafafa; + background-image: -moz-linear-gradient(top, #ffffff, #f2f2f2); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#ffffff), to(#f2f2f2)); + background-image: -webkit-linear-gradient(top, #ffffff, #f2f2f2); + background-image: -o-linear-gradient(top, #ffffff, #f2f2f2); + background-image: linear-gradient(to bottom, #ffffff, #f2f2f2); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#fff2f2f2', GradientType=0); + border: 1px solid #d4d4d4; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; + -webkit-box-shadow: 0 1px 4px rgba(0, 0, 0, 0.065); + -moz-box-shadow: 0 1px 4px rgba(0, 0, 0, 0.065); + box-shadow: 0 1px 4px rgba(0, 0, 0, 0.065); + *zoom: 1; +} +.navbar-inner:before, +.navbar-inner:after { + display: table; + content: ""; + line-height: 0; +} +.navbar-inner:after { + clear: both; +} +.navbar .container { + width: auto; +} +.nav-collapse.collapse { + height: auto; + overflow: visible; +} +.navbar .brand { + float: left; + display: block; + padding: 9.5px 20px 9.5px; + margin-left: -20px; + font-size: 20px; + font-weight: 200; + color: #777777; + text-shadow: 0 1px 0 #ffffff; +} +.navbar .brand:hover, +.navbar .brand:focus { + text-decoration: none; +} +.navbar-text { + margin-bottom: 0; + line-height: 40px; + color: #777777; +} +.navbar-link { + color: #777777; +} +.navbar-link:hover, +.navbar-link:focus { + color: #333333; +} +.navbar .divider-vertical { + height: 40px; + margin: 0 9px; + border-left: 1px solid #f2f2f2; + border-right: 1px solid #ffffff; +} +.navbar .btn, +.navbar .btn-group { + margin-top: 5px; +} +.navbar .btn-group .btn, +.navbar .input-prepend .btn, +.navbar .input-append .btn, +.navbar .input-prepend .btn-group, +.navbar .input-append .btn-group { + margin-top: 0; +} +.navbar-form { + margin-bottom: 0; + *zoom: 1; +} +.navbar-form:before, +.navbar-form:after { + display: table; + content: ""; + line-height: 0; +} +.navbar-form:after { + clear: both; +} +.navbar-form input, +.navbar-form select, +.navbar-form .radio, +.navbar-form .checkbox { + margin-top: 5px; +} +.navbar-form input, +.navbar-form select, +.navbar-form .btn { + display: inline-block; + margin-bottom: 0; +} +.navbar-form input[type="image"], +.navbar-form input[type="checkbox"], +.navbar-form input[type="radio"] { + margin-top: 3px; +} +.navbar-form .input-append, +.navbar-form .input-prepend { + margin-top: 5px; + white-space: nowrap; +} +.navbar-form .input-append input, +.navbar-form .input-prepend input { + margin-top: 0; +} +.navbar-search { + position: relative; + float: left; + margin-top: 5px; + margin-bottom: 0; +} +.navbar-search .search-query { + margin-bottom: 0; + padding: 4px 14px; + font-family: 'Source Sans Pro', sans-serif; + font-size: 13px; + font-weight: normal; + line-height: 1; + -webkit-border-radius: 15px; + -moz-border-radius: 15px; + border-radius: 15px; +} +.navbar-static-top { + position: static; + margin-bottom: 0; +} +.navbar-static-top .navbar-inner { + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; +} +.navbar-fixed-top, +.navbar-fixed-bottom { + position: fixed; + right: 0; + left: 0; + z-index: 1030; + margin-bottom: 0; +} +.navbar-fixed-top .navbar-inner, +.navbar-static-top .navbar-inner { + border-width: 0 0 1px; +} +.navbar-fixed-bottom .navbar-inner { + border-width: 1px 0 0; +} +.navbar-fixed-top .navbar-inner, +.navbar-fixed-bottom .navbar-inner { + padding-left: 0; + padding-right: 0; + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; +} +.navbar-static-top .container, +.navbar-fixed-top .container, +.navbar-fixed-bottom .container { + width: 940px; +} +.navbar-fixed-top { + top: 0; +} +.navbar-fixed-top .navbar-inner, +.navbar-static-top .navbar-inner { + -webkit-box-shadow: 0 1px 10px rgba(0,0,0,.1); + -moz-box-shadow: 0 1px 10px rgba(0,0,0,.1); + box-shadow: 0 1px 10px rgba(0,0,0,.1); +} +.navbar-fixed-bottom { + bottom: 0; +} +.navbar-fixed-bottom .navbar-inner { + -webkit-box-shadow: 0 -1px 10px rgba(0,0,0,.1); + -moz-box-shadow: 0 -1px 10px rgba(0,0,0,.1); + box-shadow: 0 -1px 10px rgba(0,0,0,.1); +} +.navbar .nav { + position: relative; + left: 0; + display: block; + float: left; + margin: 0 10px 0 0; +} +.navbar .nav.pull-right { + float: right; + margin-right: 0; +} +.navbar .nav > li { + float: left; +} +.navbar .nav > li > a { + float: none; + padding: 9.5px 15px 9.5px; + color: #777777; + text-decoration: none; + text-shadow: 0 1px 0 #ffffff; +} +.navbar .nav .dropdown-toggle .caret { + margin-top: 8px; +} +.navbar .nav > li > a:focus, +.navbar .nav > li > a:hover { + background-color: transparent; + color: #333333; + text-decoration: none; +} +.navbar .nav > .active > a, +.navbar .nav > .active > a:hover, +.navbar .nav > .active > a:focus { + color: #555555; + text-decoration: none; + background-color: #e5e5e5; + -webkit-box-shadow: inset 0 3px 8px rgba(0, 0, 0, 0.125); + -moz-box-shadow: inset 0 3px 8px rgba(0, 0, 0, 0.125); + box-shadow: inset 0 3px 8px rgba(0, 0, 0, 0.125); +} +.navbar .btn-navbar { + display: none; + float: right; + padding: 7px 10px; + margin-left: 5px; + margin-right: 5px; + color: #ffffff; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); + background-color: #ededed; + background-image: -moz-linear-gradient(top, #f2f2f2, #e5e5e5); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#f2f2f2), to(#e5e5e5)); + background-image: -webkit-linear-gradient(top, #f2f2f2, #e5e5e5); + background-image: -o-linear-gradient(top, #f2f2f2, #e5e5e5); + background-image: linear-gradient(to bottom, #f2f2f2, #e5e5e5); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2f2f2', endColorstr='#ffe5e5e5', GradientType=0); + border-color: #e5e5e5 #e5e5e5 #bfbfbf; + border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); + *background-color: #e5e5e5; + /* Darken IE7 buttons by default so they stand out more given they won't have borders */ + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); + -webkit-box-shadow: inset 0 1px 0 rgba(255,255,255,.1), 0 1px 0 rgba(255,255,255,.075); + -moz-box-shadow: inset 0 1px 0 rgba(255,255,255,.1), 0 1px 0 rgba(255,255,255,.075); + box-shadow: inset 0 1px 0 rgba(255,255,255,.1), 0 1px 0 rgba(255,255,255,.075); +} +.navbar .btn-navbar:hover, +.navbar .btn-navbar:focus, +.navbar .btn-navbar:active, +.navbar .btn-navbar.active, +.navbar .btn-navbar.disabled, +.navbar .btn-navbar[disabled] { + color: #ffffff; + background-color: #e5e5e5; + *background-color: #d9d9d9; +} +.navbar .btn-navbar:active, +.navbar .btn-navbar.active { + background-color: #cccccc \9; +} +.navbar .btn-navbar .icon-bar { + display: block; + width: 18px; + height: 2px; + background-color: #f5f5f5; + -webkit-border-radius: 1px; + -moz-border-radius: 1px; + border-radius: 1px; + -webkit-box-shadow: 0 1px 0 rgba(0, 0, 0, 0.25); + -moz-box-shadow: 0 1px 0 rgba(0, 0, 0, 0.25); + box-shadow: 0 1px 0 rgba(0, 0, 0, 0.25); +} +.btn-navbar .icon-bar + .icon-bar { + margin-top: 3px; +} +.navbar .nav > li > .dropdown-menu:before { + content: ''; + display: inline-block; + border-left: 7px solid transparent; + border-right: 7px solid transparent; + border-bottom: 7px solid #ccc; + border-bottom-color: rgba(0, 0, 0, 0.2); + position: absolute; + top: -7px; + left: 9px; +} +.navbar .nav > li > .dropdown-menu:after { + content: ''; + display: inline-block; + border-left: 6px solid transparent; + border-right: 6px solid transparent; + border-bottom: 6px solid #ffffff; + position: absolute; + top: -6px; + left: 10px; +} +.navbar-fixed-bottom .nav > li > .dropdown-menu:before { + border-top: 7px solid #ccc; + border-top-color: rgba(0, 0, 0, 0.2); + border-bottom: 0; + bottom: -7px; + top: auto; +} +.navbar-fixed-bottom .nav > li > .dropdown-menu:after { + border-top: 6px solid #ffffff; + border-bottom: 0; + bottom: -6px; + top: auto; +} +.navbar .nav li.dropdown > a:hover .caret, +.navbar .nav li.dropdown > a:focus .caret { + border-top-color: #333333; + border-bottom-color: #333333; +} +.navbar .nav li.dropdown.open > .dropdown-toggle, +.navbar .nav li.dropdown.active > .dropdown-toggle, +.navbar .nav li.dropdown.open.active > .dropdown-toggle { + background-color: #e5e5e5; + color: #555555; +} +.navbar .nav li.dropdown > .dropdown-toggle .caret { + border-top-color: #777777; + border-bottom-color: #777777; +} +.navbar .nav li.dropdown.open > .dropdown-toggle .caret, +.navbar .nav li.dropdown.active > .dropdown-toggle .caret, +.navbar .nav li.dropdown.open.active > .dropdown-toggle .caret { + border-top-color: #555555; + border-bottom-color: #555555; +} +.navbar .pull-right > li > .dropdown-menu, +.navbar .nav > li > .dropdown-menu.pull-right { + left: auto; + right: 0; +} +.navbar .pull-right > li > .dropdown-menu:before, +.navbar .nav > li > .dropdown-menu.pull-right:before { + left: auto; + right: 12px; +} +.navbar .pull-right > li > .dropdown-menu:after, +.navbar .nav > li > .dropdown-menu.pull-right:after { + left: auto; + right: 13px; +} +.navbar .pull-right > li > .dropdown-menu .dropdown-menu, +.navbar .nav > li > .dropdown-menu.pull-right .dropdown-menu { + left: auto; + right: 100%; + margin-left: 0; + margin-right: -1px; + -webkit-border-radius: 6px 0 6px 6px; + -moz-border-radius: 6px 0 6px 6px; + border-radius: 6px 0 6px 6px; +} +.navbar-inverse .navbar-inner { + background-color: #1b1b1b; + background-image: -moz-linear-gradient(top, #222222, #111111); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#222222), to(#111111)); + background-image: -webkit-linear-gradient(top, #222222, #111111); + background-image: -o-linear-gradient(top, #222222, #111111); + background-image: linear-gradient(to bottom, #222222, #111111); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff222222', endColorstr='#ff111111', GradientType=0); + border-color: #252525; +} +.navbar-inverse .brand, +.navbar-inverse .nav > li > a { + color: #999999; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); +} +.navbar-inverse .brand:hover, +.navbar-inverse .nav > li > a:hover, +.navbar-inverse .brand:focus, +.navbar-inverse .nav > li > a:focus { + color: #ffffff; +} +.navbar-inverse .brand { + color: #999999; +} +.navbar-inverse .navbar-text { + color: #999999; +} +.navbar-inverse .nav > li > a:focus, +.navbar-inverse .nav > li > a:hover { + background-color: transparent; + color: #ffffff; +} +.navbar-inverse .nav .active > a, +.navbar-inverse .nav .active > a:hover, +.navbar-inverse .nav .active > a:focus { + color: #ffffff; + background-color: #111111; +} +.navbar-inverse .navbar-link { + color: #999999; +} +.navbar-inverse .navbar-link:hover, +.navbar-inverse .navbar-link:focus { + color: #ffffff; +} +.navbar-inverse .divider-vertical { + border-left-color: #111111; + border-right-color: #222222; +} +.navbar-inverse .nav li.dropdown.open > .dropdown-toggle, +.navbar-inverse .nav li.dropdown.active > .dropdown-toggle, +.navbar-inverse .nav li.dropdown.open.active > .dropdown-toggle { + background-color: #111111; + color: #ffffff; +} +.navbar-inverse .nav li.dropdown > a:hover .caret, +.navbar-inverse .nav li.dropdown > a:focus .caret { + border-top-color: #ffffff; + border-bottom-color: #ffffff; +} +.navbar-inverse .nav li.dropdown > .dropdown-toggle .caret { + border-top-color: #999999; + border-bottom-color: #999999; +} +.navbar-inverse .nav li.dropdown.open > .dropdown-toggle .caret, +.navbar-inverse .nav li.dropdown.active > .dropdown-toggle .caret, +.navbar-inverse .nav li.dropdown.open.active > .dropdown-toggle .caret { + border-top-color: #ffffff; + border-bottom-color: #ffffff; +} +.navbar-inverse .navbar-search .search-query { + color: #ffffff; + background-color: #515151; + border-color: #111111; + -webkit-box-shadow: inset 0 1px 2px rgba(0,0,0,.1), 0 1px 0 rgba(255,255,255,.15); + -moz-box-shadow: inset 0 1px 2px rgba(0,0,0,.1), 0 1px 0 rgba(255,255,255,.15); + box-shadow: inset 0 1px 2px rgba(0,0,0,.1), 0 1px 0 rgba(255,255,255,.15); + -webkit-transition: none; + -moz-transition: none; + -o-transition: none; + transition: none; +} +.navbar-inverse .navbar-search .search-query:-moz-placeholder { + color: #cccccc; +} +.navbar-inverse .navbar-search .search-query:-ms-input-placeholder { + color: #cccccc; +} +.navbar-inverse .navbar-search .search-query::-webkit-input-placeholder { + color: #cccccc; +} +.navbar-inverse .navbar-search .search-query:focus, +.navbar-inverse .navbar-search .search-query.focused { + padding: 5px 15px; + color: #333333; + text-shadow: 0 1px 0 #ffffff; + background-color: #ffffff; + border: 0; + -webkit-box-shadow: 0 0 3px rgba(0, 0, 0, 0.15); + -moz-box-shadow: 0 0 3px rgba(0, 0, 0, 0.15); + box-shadow: 0 0 3px rgba(0, 0, 0, 0.15); + outline: 0; +} +.navbar-inverse .btn-navbar { + color: #ffffff; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); + background-color: #0e0e0e; + background-image: -moz-linear-gradient(top, #151515, #040404); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#151515), to(#040404)); + background-image: -webkit-linear-gradient(top, #151515, #040404); + background-image: -o-linear-gradient(top, #151515, #040404); + background-image: linear-gradient(to bottom, #151515, #040404); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff151515', endColorstr='#ff040404', GradientType=0); + border-color: #040404 #040404 #000000; + border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); + *background-color: #040404; + /* Darken IE7 buttons by default so they stand out more given they won't have borders */ + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); +} +.navbar-inverse .btn-navbar:hover, +.navbar-inverse .btn-navbar:focus, +.navbar-inverse .btn-navbar:active, +.navbar-inverse .btn-navbar.active, +.navbar-inverse .btn-navbar.disabled, +.navbar-inverse .btn-navbar[disabled] { + color: #ffffff; + background-color: #040404; + *background-color: #000000; +} +.navbar-inverse .btn-navbar:active, +.navbar-inverse .btn-navbar.active { + background-color: #000000 \9; +} +.breadcrumb { + padding: 8px 15px; + margin: 0 0 21px; + list-style: none; + background-color: #f5f5f5; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; +} +.breadcrumb > li { + display: inline-block; + *display: inline; + /* IE7 inline-block hack */ + *zoom: 1; + text-shadow: 0 1px 0 #ffffff; +} +.breadcrumb > li > .divider { + padding: 0 5px; + color: #ccc; +} +.breadcrumb > .active { + color: #999999; +} +.pagination { + margin: 21px 0; +} +.pagination ul { + display: inline-block; + *display: inline; + /* IE7 inline-block hack */ + *zoom: 1; + margin-left: 0; + margin-bottom: 0; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; + -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05); + -moz-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05); + box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05); +} +.pagination ul > li { + display: inline; +} +.pagination ul > li > a, +.pagination ul > li > span { + float: left; + padding: 4px 12px; + line-height: 21px; + text-decoration: none; + background-color: #ffffff; + border: 1px solid #dddddd; + border-left-width: 0; +} +.pagination ul > li > a:hover, +.pagination ul > li > a:focus, +.pagination ul > .active > a, +.pagination ul > .active > span { + background-color: #f5f5f5; +} +.pagination ul > .active > a, +.pagination ul > .active > span { + color: #999999; + cursor: default; +} +.pagination ul > .disabled > span, +.pagination ul > .disabled > a, +.pagination ul > .disabled > a:hover, +.pagination ul > .disabled > a:focus { + color: #999999; + background-color: transparent; + cursor: default; +} +.pagination ul > li:first-child > a, +.pagination ul > li:first-child > span { + border-left-width: 1px; + -webkit-border-top-left-radius: 4px; + -moz-border-radius-topleft: 4px; + border-top-left-radius: 4px; + -webkit-border-bottom-left-radius: 4px; + -moz-border-radius-bottomleft: 4px; + border-bottom-left-radius: 4px; +} +.pagination ul > li:last-child > a, +.pagination ul > li:last-child > span { + -webkit-border-top-right-radius: 4px; + -moz-border-radius-topright: 4px; + border-top-right-radius: 4px; + -webkit-border-bottom-right-radius: 4px; + -moz-border-radius-bottomright: 4px; + border-bottom-right-radius: 4px; +} +.pagination-centered { + text-align: center; +} +.pagination-right { + text-align: right; +} +.pagination-large ul > li > a, +.pagination-large ul > li > span { + padding: 11px 19px; + font-size: 20px; +} +.pagination-large ul > li:first-child > a, +.pagination-large ul > li:first-child > span { + -webkit-border-top-left-radius: 6px; + -moz-border-radius-topleft: 6px; + border-top-left-radius: 6px; + -webkit-border-bottom-left-radius: 6px; + -moz-border-radius-bottomleft: 6px; + border-bottom-left-radius: 6px; +} +.pagination-large ul > li:last-child > a, +.pagination-large ul > li:last-child > span { + -webkit-border-top-right-radius: 6px; + -moz-border-radius-topright: 6px; + border-top-right-radius: 6px; + -webkit-border-bottom-right-radius: 6px; + -moz-border-radius-bottomright: 6px; + border-bottom-right-radius: 6px; +} +.pagination-mini ul > li:first-child > a, +.pagination-small ul > li:first-child > a, +.pagination-mini ul > li:first-child > span, +.pagination-small ul > li:first-child > span { + -webkit-border-top-left-radius: 3px; + -moz-border-radius-topleft: 3px; + border-top-left-radius: 3px; + -webkit-border-bottom-left-radius: 3px; + -moz-border-radius-bottomleft: 3px; + border-bottom-left-radius: 3px; +} +.pagination-mini ul > li:last-child > a, +.pagination-small ul > li:last-child > a, +.pagination-mini ul > li:last-child > span, +.pagination-small ul > li:last-child > span { + -webkit-border-top-right-radius: 3px; + -moz-border-radius-topright: 3px; + border-top-right-radius: 3px; + -webkit-border-bottom-right-radius: 3px; + -moz-border-radius-bottomright: 3px; + border-bottom-right-radius: 3px; +} +.pagination-small ul > li > a, +.pagination-small ul > li > span { + padding: 2px 10px; + font-size: 13.6px; +} +.pagination-mini ul > li > a, +.pagination-mini ul > li > span { + padding: 0 6px; + font-size: 12px; +} +.pager { + margin: 21px 0; + list-style: none; + text-align: center; + *zoom: 1; +} +.pager:before, +.pager:after { + display: table; + content: ""; + line-height: 0; +} +.pager:after { + clear: both; +} +.pager li { + display: inline; +} +.pager li > a, +.pager li > span { + display: inline-block; + padding: 5px 14px; + background-color: #fff; + border: 1px solid #ddd; + -webkit-border-radius: 15px; + -moz-border-radius: 15px; + border-radius: 15px; +} +.pager li > a:hover, +.pager li > a:focus { + text-decoration: none; + background-color: #f5f5f5; +} +.pager .next > a, +.pager .next > span { + float: right; +} +.pager .previous > a, +.pager .previous > span { + float: left; +} +.pager .disabled > a, +.pager .disabled > a:hover, +.pager .disabled > a:focus, +.pager .disabled > span { + color: #999999; + background-color: #fff; + cursor: default; +} +.modal-backdrop { + position: fixed; + top: 0; + right: 0; + bottom: 0; + left: 0; + z-index: 1040; + background-color: #000000; +} +.modal-backdrop.fade { + opacity: 0; +} +.modal-backdrop, +.modal-backdrop.fade.in { + opacity: 0.8; + filter: alpha(opacity=80); +} +.modal { + position: fixed; + top: 10%; + left: 50%; + z-index: 1050; + width: 560px; + margin-left: -280px; + background-color: #ffffff; + border: 1px solid #999; + border: 1px solid rgba(0, 0, 0, 0.3); + *border: 1px solid #999; + /* IE6-7 */ + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; + -webkit-box-shadow: 0 3px 7px rgba(0, 0, 0, 0.3); + -moz-box-shadow: 0 3px 7px rgba(0, 0, 0, 0.3); + box-shadow: 0 3px 7px rgba(0, 0, 0, 0.3); + -webkit-background-clip: padding-box; + -moz-background-clip: padding-box; + background-clip: padding-box; + outline: none; +} +.modal.fade { + -webkit-transition: opacity .3s linear, top .3s ease-out; + -moz-transition: opacity .3s linear, top .3s ease-out; + -o-transition: opacity .3s linear, top .3s ease-out; + transition: opacity .3s linear, top .3s ease-out; + top: -25%; +} +.modal.fade.in { + top: 10%; +} +.modal-header { + padding: 9px 15px; + border-bottom: 1px solid #eee; +} +.modal-header .close { + margin-top: 2px; +} +.modal-header h3 { + margin: 0; + line-height: 30px; +} +.modal-body { + position: relative; + overflow-y: auto; + max-height: 400px; + padding: 15px; +} +.modal-form { + margin-bottom: 0; +} +.modal-footer { + padding: 14px 15px 15px; + margin-bottom: 0; + text-align: right; + background-color: #f5f5f5; + border-top: 1px solid #ddd; + -webkit-border-radius: 0 0 6px 6px; + -moz-border-radius: 0 0 6px 6px; + border-radius: 0 0 6px 6px; + -webkit-box-shadow: inset 0 1px 0 #ffffff; + -moz-box-shadow: inset 0 1px 0 #ffffff; + box-shadow: inset 0 1px 0 #ffffff; + *zoom: 1; +} +.modal-footer:before, +.modal-footer:after { + display: table; + content: ""; + line-height: 0; +} +.modal-footer:after { + clear: both; +} +.modal-footer .btn + .btn { + margin-left: 5px; + margin-bottom: 0; +} +.modal-footer .btn-group .btn + .btn { + margin-left: -1px; +} +.modal-footer .btn-block + .btn-block { + margin-left: 0; +} +.tooltip { + position: absolute; + z-index: 1030; + display: block; + visibility: visible; + font-size: 11px; + line-height: 1.4; + opacity: 0; + filter: alpha(opacity=0); +} +.tooltip.in { + opacity: 0.8; + filter: alpha(opacity=80); +} +.tooltip.top { + margin-top: -3px; + padding: 5px 0; +} +.tooltip.right { + margin-left: 3px; + padding: 0 5px; +} +.tooltip.bottom { + margin-top: 3px; + padding: 5px 0; +} +.tooltip.left { + margin-left: -3px; + padding: 0 5px; +} +.tooltip-inner { + max-width: 200px; + padding: 8px; + color: #ffffff; + text-align: center; + text-decoration: none; + background-color: #000000; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; +} +.tooltip-arrow { + position: absolute; + width: 0; + height: 0; + border-color: transparent; + border-style: solid; +} +.tooltip.top .tooltip-arrow { + bottom: 0; + left: 50%; + margin-left: -5px; + border-width: 5px 5px 0; + border-top-color: #000000; +} +.tooltip.right .tooltip-arrow { + top: 50%; + left: 0; + margin-top: -5px; + border-width: 5px 5px 5px 0; + border-right-color: #000000; +} +.tooltip.left .tooltip-arrow { + top: 50%; + right: 0; + margin-top: -5px; + border-width: 5px 0 5px 5px; + border-left-color: #000000; +} +.tooltip.bottom .tooltip-arrow { + top: 0; + left: 50%; + margin-left: -5px; + border-width: 0 5px 5px; + border-bottom-color: #000000; +} +.popover { + position: absolute; + top: 0; + left: 0; + z-index: 1010; + display: none; + max-width: 276px; + padding: 1px; + text-align: left; + background-color: #ffffff; + -webkit-background-clip: padding-box; + -moz-background-clip: padding; + background-clip: padding-box; + border: 1px solid #ccc; + border: 1px solid rgba(0, 0, 0, 0.2); + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; + -webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); + -moz-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); + box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); + white-space: normal; +} +.popover.top { + margin-top: -10px; +} +.popover.right { + margin-left: 10px; +} +.popover.bottom { + margin-top: 10px; +} +.popover.left { + margin-left: -10px; +} +.popover-title { + margin: 0; + padding: 8px 14px; + font-size: 14px; + font-weight: normal; + line-height: 18px; + background-color: #f7f7f7; + border-bottom: 1px solid #ebebeb; + -webkit-border-radius: 5px 5px 0 0; + -moz-border-radius: 5px 5px 0 0; + border-radius: 5px 5px 0 0; +} +.popover-title:empty { + display: none; +} +.popover-content { + padding: 9px 14px; +} +.popover .arrow, +.popover .arrow:after { + position: absolute; + display: block; + width: 0; + height: 0; + border-color: transparent; + border-style: solid; +} +.popover .arrow { + border-width: 11px; +} +.popover .arrow:after { + border-width: 10px; + content: ""; +} +.popover.top .arrow { + left: 50%; + margin-left: -11px; + border-bottom-width: 0; + border-top-color: #999; + border-top-color: rgba(0, 0, 0, 0.25); + bottom: -11px; +} +.popover.top .arrow:after { + bottom: 1px; + margin-left: -10px; + border-bottom-width: 0; + border-top-color: #ffffff; +} +.popover.right .arrow { + top: 50%; + left: -11px; + margin-top: -11px; + border-left-width: 0; + border-right-color: #999; + border-right-color: rgba(0, 0, 0, 0.25); +} +.popover.right .arrow:after { + left: 1px; + bottom: -10px; + border-left-width: 0; + border-right-color: #ffffff; +} +.popover.bottom .arrow { + left: 50%; + margin-left: -11px; + border-top-width: 0; + border-bottom-color: #999; + border-bottom-color: rgba(0, 0, 0, 0.25); + top: -11px; +} +.popover.bottom .arrow:after { + top: 1px; + margin-left: -10px; + border-top-width: 0; + border-bottom-color: #ffffff; +} +.popover.left .arrow { + top: 50%; + right: -11px; + margin-top: -11px; + border-right-width: 0; + border-left-color: #999; + border-left-color: rgba(0, 0, 0, 0.25); +} +.popover.left .arrow:after { + right: 1px; + border-right-width: 0; + border-left-color: #ffffff; + bottom: -10px; +} +.thumbnails { + margin-left: -20px; + list-style: none; + *zoom: 1; +} +.thumbnails:before, +.thumbnails:after { + display: table; + content: ""; + line-height: 0; +} +.thumbnails:after { + clear: both; +} +.row-fluid .thumbnails { + margin-left: 0; +} +.thumbnails > li { + float: left; + margin-bottom: 21px; + margin-left: 20px; +} +.thumbnail { + display: block; + padding: 4px; + line-height: 21px; + border: 1px solid #ddd; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; + -webkit-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.055); + -moz-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.055); + box-shadow: 0 1px 3px rgba(0, 0, 0, 0.055); + -webkit-transition: all 0.2s ease-in-out; + -moz-transition: all 0.2s ease-in-out; + -o-transition: all 0.2s ease-in-out; + transition: all 0.2s ease-in-out; +} +a.thumbnail:hover, +a.thumbnail:focus { + border-color: #0088cc; + -webkit-box-shadow: 0 1px 4px rgba(0, 105, 214, 0.25); + -moz-box-shadow: 0 1px 4px rgba(0, 105, 214, 0.25); + box-shadow: 0 1px 4px rgba(0, 105, 214, 0.25); +} +.thumbnail > img { + display: block; + max-width: 100%; + margin-left: auto; + margin-right: auto; +} +.thumbnail .caption { + padding: 9px; + color: #555555; +} +.media, +.media-body { + overflow: hidden; + *overflow: visible; + zoom: 1; +} +.media, +.media .media { + margin-top: 15px; +} +.media:first-child { + margin-top: 0; +} +.media-object { + display: block; +} +.media-heading { + margin: 0 0 5px; +} +.media > .pull-left { + margin-right: 10px; +} +.media > .pull-right { + margin-left: 10px; +} +.media-list { + margin-left: 0; + list-style: none; +} +.label, +.badge { + display: inline-block; + padding: 2px 4px; + font-size: 13.536px; + font-weight: bold; + line-height: 14px; + color: #ffffff; + vertical-align: baseline; + white-space: nowrap; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); + background-color: #999999; +} +.label { + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; +} +.badge { + padding-left: 9px; + padding-right: 9px; + -webkit-border-radius: 9px; + -moz-border-radius: 9px; + border-radius: 9px; +} +.label:empty, +.badge:empty { + display: none; +} +a.label:hover, +a.label:focus, +a.badge:hover, +a.badge:focus { + color: #ffffff; + text-decoration: none; + cursor: pointer; +} +.label-important, +.badge-important { + background-color: #b94a48; +} +.label-important[href], +.badge-important[href] { + background-color: #953b39; +} +.label-warning, +.badge-warning { + background-color: #f89406; +} +.label-warning[href], +.badge-warning[href] { + background-color: #c67605; +} +.label-success, +.badge-success { + background-color: #468847; +} +.label-success[href], +.badge-success[href] { + background-color: #356635; +} +.label-info, +.badge-info { + background-color: #3a87ad; +} +.label-info[href], +.badge-info[href] { + background-color: #2d6987; +} +.label-inverse, +.badge-inverse { + background-color: #333333; +} +.label-inverse[href], +.badge-inverse[href] { + background-color: #1a1a1a; +} +.btn .label, +.btn .badge { + position: relative; + top: -1px; +} +.btn-mini .label, +.btn-mini .badge { + top: 0; +} +@-webkit-keyframes progress-bar-stripes { + from { + background-position: 40px 0; + } + to { + background-position: 0 0; + } +} +@-moz-keyframes progress-bar-stripes { + from { + background-position: 40px 0; + } + to { + background-position: 0 0; + } +} +@-ms-keyframes progress-bar-stripes { + from { + background-position: 40px 0; + } + to { + background-position: 0 0; + } +} +@-o-keyframes progress-bar-stripes { + from { + background-position: 0 0; + } + to { + background-position: 40px 0; + } +} +@keyframes progress-bar-stripes { + from { + background-position: 40px 0; + } + to { + background-position: 0 0; + } +} +.progress { + overflow: hidden; + height: 21px; + margin-bottom: 21px; + background-color: #f7f7f7; + background-image: -moz-linear-gradient(top, #f5f5f5, #f9f9f9); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#f5f5f5), to(#f9f9f9)); + background-image: -webkit-linear-gradient(top, #f5f5f5, #f9f9f9); + background-image: -o-linear-gradient(top, #f5f5f5, #f9f9f9); + background-image: linear-gradient(to bottom, #f5f5f5, #f9f9f9); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#fff9f9f9', GradientType=0); + -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1); + -moz-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1); + box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1); + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; +} +.progress .bar { + width: 0%; + height: 100%; + color: #ffffff; + float: left; + font-size: 12px; + text-align: center; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); + background-color: #0e90d2; + background-image: -moz-linear-gradient(top, #149bdf, #0480be); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#149bdf), to(#0480be)); + background-image: -webkit-linear-gradient(top, #149bdf, #0480be); + background-image: -o-linear-gradient(top, #149bdf, #0480be); + background-image: linear-gradient(to bottom, #149bdf, #0480be); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff149bdf', endColorstr='#ff0480be', GradientType=0); + -webkit-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15); + -moz-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15); + box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15); + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + -webkit-transition: width 0.6s ease; + -moz-transition: width 0.6s ease; + -o-transition: width 0.6s ease; + transition: width 0.6s ease; +} +.progress .bar + .bar { + -webkit-box-shadow: inset 1px 0 0 rgba(0,0,0,.15), inset 0 -1px 0 rgba(0,0,0,.15); + -moz-box-shadow: inset 1px 0 0 rgba(0,0,0,.15), inset 0 -1px 0 rgba(0,0,0,.15); + box-shadow: inset 1px 0 0 rgba(0,0,0,.15), inset 0 -1px 0 rgba(0,0,0,.15); +} +.progress-striped .bar { + background-color: #149bdf; + background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent)); + background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -moz-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + -webkit-background-size: 40px 40px; + -moz-background-size: 40px 40px; + -o-background-size: 40px 40px; + background-size: 40px 40px; +} +.progress.active .bar { + -webkit-animation: progress-bar-stripes 2s linear infinite; + -moz-animation: progress-bar-stripes 2s linear infinite; + -ms-animation: progress-bar-stripes 2s linear infinite; + -o-animation: progress-bar-stripes 2s linear infinite; + animation: progress-bar-stripes 2s linear infinite; +} +.progress-danger .bar, +.progress .bar-danger { + background-color: #dd514c; + background-image: -moz-linear-gradient(top, #ee5f5b, #c43c35); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#ee5f5b), to(#c43c35)); + background-image: -webkit-linear-gradient(top, #ee5f5b, #c43c35); + background-image: -o-linear-gradient(top, #ee5f5b, #c43c35); + background-image: linear-gradient(to bottom, #ee5f5b, #c43c35); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffee5f5b', endColorstr='#ffc43c35', GradientType=0); +} +.progress-danger.progress-striped .bar, +.progress-striped .bar-danger { + background-color: #ee5f5b; + background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent)); + background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -moz-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); +} +.progress-success .bar, +.progress .bar-success { + background-color: #5eb95e; + background-image: -moz-linear-gradient(top, #62c462, #57a957); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#62c462), to(#57a957)); + background-image: -webkit-linear-gradient(top, #62c462, #57a957); + background-image: -o-linear-gradient(top, #62c462, #57a957); + background-image: linear-gradient(to bottom, #62c462, #57a957); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff62c462', endColorstr='#ff57a957', GradientType=0); +} +.progress-success.progress-striped .bar, +.progress-striped .bar-success { + background-color: #62c462; + background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent)); + background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -moz-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); +} +.progress-info .bar, +.progress .bar-info { + background-color: #4bb1cf; + background-image: -moz-linear-gradient(top, #5bc0de, #339bb9); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#5bc0de), to(#339bb9)); + background-image: -webkit-linear-gradient(top, #5bc0de, #339bb9); + background-image: -o-linear-gradient(top, #5bc0de, #339bb9); + background-image: linear-gradient(to bottom, #5bc0de, #339bb9); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff339bb9', GradientType=0); +} +.progress-info.progress-striped .bar, +.progress-striped .bar-info { + background-color: #5bc0de; + background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent)); + background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -moz-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); +} +.progress-warning .bar, +.progress .bar-warning { + background-color: #faa732; + background-image: -moz-linear-gradient(top, #fbb450, #f89406); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#fbb450), to(#f89406)); + background-image: -webkit-linear-gradient(top, #fbb450, #f89406); + background-image: -o-linear-gradient(top, #fbb450, #f89406); + background-image: linear-gradient(to bottom, #fbb450, #f89406); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffbb450', endColorstr='#fff89406', GradientType=0); +} +.progress-warning.progress-striped .bar, +.progress-striped .bar-warning { + background-color: #fbb450; + background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent)); + background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -moz-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); +} +.accordion { + margin-bottom: 21px; +} +.accordion-group { + margin-bottom: 2px; + border: 1px solid #e5e5e5; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; +} +.accordion-heading { + border-bottom: 0; +} +.accordion-heading .accordion-toggle { + display: block; + padding: 8px 15px; +} +.accordion-toggle { + cursor: pointer; +} +.accordion-inner { + padding: 9px 15px; + border-top: 1px solid #e5e5e5; +} +.carousel { + position: relative; + margin-bottom: 21px; + line-height: 1; +} +.carousel-inner { + overflow: hidden; + width: 100%; + position: relative; +} +.carousel-inner > .item { + display: none; + position: relative; + -webkit-transition: 0.6s ease-in-out left; + -moz-transition: 0.6s ease-in-out left; + -o-transition: 0.6s ease-in-out left; + transition: 0.6s ease-in-out left; +} +.carousel-inner > .item > img, +.carousel-inner > .item > a > img { + display: block; + line-height: 1; +} +.carousel-inner > .active, +.carousel-inner > .next, +.carousel-inner > .prev { + display: block; +} +.carousel-inner > .active { + left: 0; +} +.carousel-inner > .next, +.carousel-inner > .prev { + position: absolute; + top: 0; + width: 100%; +} +.carousel-inner > .next { + left: 100%; +} +.carousel-inner > .prev { + left: -100%; +} +.carousel-inner > .next.left, +.carousel-inner > .prev.right { + left: 0; +} +.carousel-inner > .active.left { + left: -100%; +} +.carousel-inner > .active.right { + left: 100%; +} +.carousel-control { + position: absolute; + top: 40%; + left: 15px; + width: 40px; + height: 40px; + margin-top: -20px; + font-size: 60px; + font-weight: 100; + line-height: 30px; + color: #ffffff; + text-align: center; + background: #222222; + border: 3px solid #ffffff; + -webkit-border-radius: 23px; + -moz-border-radius: 23px; + border-radius: 23px; + opacity: 0.5; + filter: alpha(opacity=50); +} +.carousel-control.right { + left: auto; + right: 15px; +} +.carousel-control:hover, +.carousel-control:focus { + color: #ffffff; + text-decoration: none; + opacity: 0.9; + filter: alpha(opacity=90); +} +.carousel-indicators { + position: absolute; + top: 15px; + right: 15px; + z-index: 5; + margin: 0; + list-style: none; +} +.carousel-indicators li { + display: block; + float: left; + width: 10px; + height: 10px; + margin-left: 5px; + text-indent: -999px; + background-color: #ccc; + background-color: rgba(255, 255, 255, 0.25); + border-radius: 5px; +} +.carousel-indicators .active { + background-color: #fff; +} +.carousel-caption { + position: absolute; + left: 0; + right: 0; + bottom: 0; + padding: 15px; + background: #333333; + background: rgba(0, 0, 0, 0.75); +} +.carousel-caption h4, +.carousel-caption p { + color: #ffffff; + line-height: 21px; +} +.carousel-caption h4 { + margin: 0 0 5px; +} +.carousel-caption p { + margin-bottom: 0; +} +.hero-unit { + padding: 60px; + margin-bottom: 30px; + font-size: 18px; + font-weight: 200; + line-height: 31.5px; + color: inherit; + background-color: #eeeeee; + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; +} +.hero-unit h1 { + margin-bottom: 0; + font-size: 60px; + line-height: 1; + color: inherit; + letter-spacing: -1px; +} +.hero-unit li { + line-height: 31.5px; +} +.pull-right { + float: right; +} +.pull-left { + float: left; +} +.hide { + display: none; +} +.show { + display: block; +} +.invisible { + visibility: hidden; +} +.affix { + position: fixed; +} +/*! + * Bootstrap Responsive v2.3.1 + * + * Copyright 2012 Twitter, Inc + * Licensed under the Apache License v2.0 + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Designed and built with all the love in the world @twitter by @mdo and @fat. + */ +@-ms-viewport { + width: device-width; +} +.hidden { + display: none; + visibility: hidden; +} +.visible-phone { + display: none !important; +} +.visible-tablet { + display: none !important; +} +.hidden-desktop { + display: none !important; +} +.visible-desktop { + display: inherit !important; +} +@media (min-width: 768px) and (max-width: 979px) { + .hidden-desktop { + display: inherit !important; + } + .visible-desktop { + display: none !important ; + } + .visible-tablet { + display: inherit !important; + } + .hidden-tablet { + display: none !important; + } +} +@media (max-width: 767px) { + .hidden-desktop { + display: inherit !important; + } + .visible-desktop { + display: none !important; + } + .visible-phone { + display: inherit !important; + } + .hidden-phone { + display: none !important; + } +} +.visible-print { + display: none !important; +} +@media print { + .visible-print { + display: inherit !important; + } + .hidden-print { + display: none !important; + } +} +@media (min-width: 1200px) { + .row { + margin-left: -30px; + *zoom: 1; + } + .row:before, + .row:after { + display: table; + content: ""; + line-height: 0; + } + .row:after { + clear: both; + } + [class*="span"] { + float: left; + min-height: 1px; + margin-left: 30px; + } + .container, + .navbar-static-top .container, + .navbar-fixed-top .container, + .navbar-fixed-bottom .container { + width: 1170px; + } + .span12 { + width: 1170px; + } + .span11 { + width: 1070px; + } + .span10 { + width: 970px; + } + .span9 { + width: 870px; + } + .span8 { + width: 770px; + } + .span7 { + width: 670px; + } + .span6 { + width: 570px; + } + .span5 { + width: 470px; + } + .span4 { + width: 370px; + } + .span3 { + width: 270px; + } + .span2 { + width: 170px; + } + .span1 { + width: 70px; + } + .offset12 { + margin-left: 1230px; + } + .offset11 { + margin-left: 1130px; + } + .offset10 { + margin-left: 1030px; + } + .offset9 { + margin-left: 930px; + } + .offset8 { + margin-left: 830px; + } + .offset7 { + margin-left: 730px; + } + .offset6 { + margin-left: 630px; + } + .offset5 { + margin-left: 530px; + } + .offset4 { + margin-left: 430px; + } + .offset3 { + margin-left: 330px; + } + .offset2 { + margin-left: 230px; + } + .offset1 { + margin-left: 130px; + } + .row-fluid { + width: 100%; + *zoom: 1; + } + .row-fluid:before, + .row-fluid:after { + display: table; + content: ""; + line-height: 0; + } + .row-fluid:after { + clear: both; + } + .row-fluid [class*="span"] { + display: block; + width: 100%; + min-height: 31px; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + float: left; + margin-left: 2.56410256%; + *margin-left: 2.51091107%; + } + .row-fluid [class*="span"]:first-child { + margin-left: 0; + } + .row-fluid .controls-row [class*="span"] + [class*="span"] { + margin-left: 2.56410256%; + } + .row-fluid .span12 { + width: 100%; + *width: 99.94680851%; + } + .row-fluid .span11 { + width: 91.45299145%; + *width: 91.39979996%; + } + .row-fluid .span10 { + width: 82.90598291%; + *width: 82.85279142%; + } + .row-fluid .span9 { + width: 74.35897436%; + *width: 74.30578287%; + } + .row-fluid .span8 { + width: 65.81196581%; + *width: 65.75877432%; + } + .row-fluid .span7 { + width: 57.26495726%; + *width: 57.21176578%; + } + .row-fluid .span6 { + width: 48.71794872%; + *width: 48.66475723%; + } + .row-fluid .span5 { + width: 40.17094017%; + *width: 40.11774868%; + } + .row-fluid .span4 { + width: 31.62393162%; + *width: 31.57074013%; + } + .row-fluid .span3 { + width: 23.07692308%; + *width: 23.02373159%; + } + .row-fluid .span2 { + width: 14.52991453%; + *width: 14.47672304%; + } + .row-fluid .span1 { + width: 5.98290598%; + *width: 5.92971449%; + } + .row-fluid .offset12 { + margin-left: 105.12820513%; + *margin-left: 105.02182215%; + } + .row-fluid .offset12:first-child { + margin-left: 102.56410256%; + *margin-left: 102.45771959%; + } + .row-fluid .offset11 { + margin-left: 96.58119658%; + *margin-left: 96.4748136%; + } + .row-fluid .offset11:first-child { + margin-left: 94.01709402%; + *margin-left: 93.91071104%; + } + .row-fluid .offset10 { + margin-left: 88.03418803%; + *margin-left: 87.92780506%; + } + .row-fluid .offset10:first-child { + margin-left: 85.47008547%; + *margin-left: 85.36370249%; + } + .row-fluid .offset9 { + margin-left: 79.48717949%; + *margin-left: 79.38079651%; + } + .row-fluid .offset9:first-child { + margin-left: 76.92307692%; + *margin-left: 76.81669394%; + } + .row-fluid .offset8 { + margin-left: 70.94017094%; + *margin-left: 70.83378796%; + } + .row-fluid .offset8:first-child { + margin-left: 68.37606838%; + *margin-left: 68.2696854%; + } + .row-fluid .offset7 { + margin-left: 62.39316239%; + *margin-left: 62.28677941%; + } + .row-fluid .offset7:first-child { + margin-left: 59.82905983%; + *margin-left: 59.72267685%; + } + .row-fluid .offset6 { + margin-left: 53.84615385%; + *margin-left: 53.73977087%; + } + .row-fluid .offset6:first-child { + margin-left: 51.28205128%; + *margin-left: 51.1756683%; + } + .row-fluid .offset5 { + margin-left: 45.2991453%; + *margin-left: 45.19276232%; + } + .row-fluid .offset5:first-child { + margin-left: 42.73504274%; + *margin-left: 42.62865976%; + } + .row-fluid .offset4 { + margin-left: 36.75213675%; + *margin-left: 36.64575377%; + } + .row-fluid .offset4:first-child { + margin-left: 34.18803419%; + *margin-left: 34.08165121%; + } + .row-fluid .offset3 { + margin-left: 28.20512821%; + *margin-left: 28.09874523%; + } + .row-fluid .offset3:first-child { + margin-left: 25.64102564%; + *margin-left: 25.53464266%; + } + .row-fluid .offset2 { + margin-left: 19.65811966%; + *margin-left: 19.55173668%; + } + .row-fluid .offset2:first-child { + margin-left: 17.09401709%; + *margin-left: 16.98763412%; + } + .row-fluid .offset1 { + margin-left: 11.11111111%; + *margin-left: 11.00472813%; + } + .row-fluid .offset1:first-child { + margin-left: 8.54700855%; + *margin-left: 8.44062557%; + } + input, + textarea, + .uneditable-input { + margin-left: 0; + } + .controls-row [class*="span"] + [class*="span"] { + margin-left: 30px; + } + input.span12, + textarea.span12, + .uneditable-input.span12 { + width: 1156px; + } + input.span11, + textarea.span11, + .uneditable-input.span11 { + width: 1056px; + } + input.span10, + textarea.span10, + .uneditable-input.span10 { + width: 956px; + } + input.span9, + textarea.span9, + .uneditable-input.span9 { + width: 856px; + } + input.span8, + textarea.span8, + .uneditable-input.span8 { + width: 756px; + } + input.span7, + textarea.span7, + .uneditable-input.span7 { + width: 656px; + } + input.span6, + textarea.span6, + .uneditable-input.span6 { + width: 556px; + } + input.span5, + textarea.span5, + .uneditable-input.span5 { + width: 456px; + } + input.span4, + textarea.span4, + .uneditable-input.span4 { + width: 356px; + } + input.span3, + textarea.span3, + .uneditable-input.span3 { + width: 256px; + } + input.span2, + textarea.span2, + .uneditable-input.span2 { + width: 156px; + } + input.span1, + textarea.span1, + .uneditable-input.span1 { + width: 56px; + } + .thumbnails { + margin-left: -30px; + } + .thumbnails > li { + margin-left: 30px; + } + .row-fluid .thumbnails { + margin-left: 0; + } +} +@media (min-width: 768px) and (max-width: 979px) { + .row { + margin-left: -20px; + *zoom: 1; + } + .row:before, + .row:after { + display: table; + content: ""; + line-height: 0; + } + .row:after { + clear: both; + } + [class*="span"] { + float: left; + min-height: 1px; + margin-left: 20px; + } + .container, + .navbar-static-top .container, + .navbar-fixed-top .container, + .navbar-fixed-bottom .container { + width: 724px; + } + .span12 { + width: 724px; + } + .span11 { + width: 662px; + } + .span10 { + width: 600px; + } + .span9 { + width: 538px; + } + .span8 { + width: 476px; + } + .span7 { + width: 414px; + } + .span6 { + width: 352px; + } + .span5 { + width: 290px; + } + .span4 { + width: 228px; + } + .span3 { + width: 166px; + } + .span2 { + width: 104px; + } + .span1 { + width: 42px; + } + .offset12 { + margin-left: 764px; + } + .offset11 { + margin-left: 702px; + } + .offset10 { + margin-left: 640px; + } + .offset9 { + margin-left: 578px; + } + .offset8 { + margin-left: 516px; + } + .offset7 { + margin-left: 454px; + } + .offset6 { + margin-left: 392px; + } + .offset5 { + margin-left: 330px; + } + .offset4 { + margin-left: 268px; + } + .offset3 { + margin-left: 206px; + } + .offset2 { + margin-left: 144px; + } + .offset1 { + margin-left: 82px; + } + .row-fluid { + width: 100%; + *zoom: 1; + } + .row-fluid:before, + .row-fluid:after { + display: table; + content: ""; + line-height: 0; + } + .row-fluid:after { + clear: both; + } + .row-fluid [class*="span"] { + display: block; + width: 100%; + min-height: 31px; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + float: left; + margin-left: 2.76243094%; + *margin-left: 2.70923945%; + } + .row-fluid [class*="span"]:first-child { + margin-left: 0; + } + .row-fluid .controls-row [class*="span"] + [class*="span"] { + margin-left: 2.76243094%; + } + .row-fluid .span12 { + width: 100%; + *width: 99.94680851%; + } + .row-fluid .span11 { + width: 91.43646409%; + *width: 91.3832726%; + } + .row-fluid .span10 { + width: 82.87292818%; + *width: 82.81973669%; + } + .row-fluid .span9 { + width: 74.30939227%; + *width: 74.25620078%; + } + .row-fluid .span8 { + width: 65.74585635%; + *width: 65.69266486%; + } + .row-fluid .span7 { + width: 57.18232044%; + *width: 57.12912895%; + } + .row-fluid .span6 { + width: 48.61878453%; + *width: 48.56559304%; + } + .row-fluid .span5 { + width: 40.05524862%; + *width: 40.00205713%; + } + .row-fluid .span4 { + width: 31.49171271%; + *width: 31.43852122%; + } + .row-fluid .span3 { + width: 22.9281768%; + *width: 22.87498531%; + } + .row-fluid .span2 { + width: 14.36464088%; + *width: 14.31144939%; + } + .row-fluid .span1 { + width: 5.80110497%; + *width: 5.74791348%; + } + .row-fluid .offset12 { + margin-left: 105.52486188%; + *margin-left: 105.4184789%; + } + .row-fluid .offset12:first-child { + margin-left: 102.76243094%; + *margin-left: 102.65604796%; + } + .row-fluid .offset11 { + margin-left: 96.96132597%; + *margin-left: 96.85494299%; + } + .row-fluid .offset11:first-child { + margin-left: 94.19889503%; + *margin-left: 94.09251205%; + } + .row-fluid .offset10 { + margin-left: 88.39779006%; + *margin-left: 88.29140708%; + } + .row-fluid .offset10:first-child { + margin-left: 85.63535912%; + *margin-left: 85.52897614%; + } + .row-fluid .offset9 { + margin-left: 79.83425414%; + *margin-left: 79.72787116%; + } + .row-fluid .offset9:first-child { + margin-left: 77.0718232%; + *margin-left: 76.96544023%; + } + .row-fluid .offset8 { + margin-left: 71.27071823%; + *margin-left: 71.16433525%; + } + .row-fluid .offset8:first-child { + margin-left: 68.50828729%; + *margin-left: 68.40190431%; + } + .row-fluid .offset7 { + margin-left: 62.70718232%; + *margin-left: 62.60079934%; + } + .row-fluid .offset7:first-child { + margin-left: 59.94475138%; + *margin-left: 59.8383684%; + } + .row-fluid .offset6 { + margin-left: 54.14364641%; + *margin-left: 54.03726343%; + } + .row-fluid .offset6:first-child { + margin-left: 51.38121547%; + *margin-left: 51.27483249%; + } + .row-fluid .offset5 { + margin-left: 45.5801105%; + *margin-left: 45.47372752%; + } + .row-fluid .offset5:first-child { + margin-left: 42.81767956%; + *margin-left: 42.71129658%; + } + .row-fluid .offset4 { + margin-left: 37.01657459%; + *margin-left: 36.91019161%; + } + .row-fluid .offset4:first-child { + margin-left: 34.25414365%; + *margin-left: 34.14776067%; + } + .row-fluid .offset3 { + margin-left: 28.45303867%; + *margin-left: 28.3466557%; + } + .row-fluid .offset3:first-child { + margin-left: 25.69060773%; + *margin-left: 25.58422476%; + } + .row-fluid .offset2 { + margin-left: 19.88950276%; + *margin-left: 19.78311978%; + } + .row-fluid .offset2:first-child { + margin-left: 17.12707182%; + *margin-left: 17.02068884%; + } + .row-fluid .offset1 { + margin-left: 11.32596685%; + *margin-left: 11.21958387%; + } + .row-fluid .offset1:first-child { + margin-left: 8.56353591%; + *margin-left: 8.45715293%; + } + input, + textarea, + .uneditable-input { + margin-left: 0; + } + .controls-row [class*="span"] + [class*="span"] { + margin-left: 20px; + } + input.span12, + textarea.span12, + .uneditable-input.span12 { + width: 710px; + } + input.span11, + textarea.span11, + .uneditable-input.span11 { + width: 648px; + } + input.span10, + textarea.span10, + .uneditable-input.span10 { + width: 586px; + } + input.span9, + textarea.span9, + .uneditable-input.span9 { + width: 524px; + } + input.span8, + textarea.span8, + .uneditable-input.span8 { + width: 462px; + } + input.span7, + textarea.span7, + .uneditable-input.span7 { + width: 400px; + } + input.span6, + textarea.span6, + .uneditable-input.span6 { + width: 338px; + } + input.span5, + textarea.span5, + .uneditable-input.span5 { + width: 276px; + } + input.span4, + textarea.span4, + .uneditable-input.span4 { + width: 214px; + } + input.span3, + textarea.span3, + .uneditable-input.span3 { + width: 152px; + } + input.span2, + textarea.span2, + .uneditable-input.span2 { + width: 90px; + } + input.span1, + textarea.span1, + .uneditable-input.span1 { + width: 28px; + } +} +@media (max-width: 767px) { + body { + padding-left: 20px; + padding-right: 20px; + } + .navbar-fixed-top, + .navbar-fixed-bottom, + .navbar-static-top { + margin-left: -20px; + margin-right: -20px; + } + .container-fluid { + padding: 0; + } + .dl-horizontal dt { + float: none; + clear: none; + width: auto; + text-align: left; + } + .dl-horizontal dd { + margin-left: 0; + } + .container { + width: auto; + } + .row-fluid { + width: 100%; + } + .row, + .thumbnails { + margin-left: 0; + } + .thumbnails > li { + float: none; + margin-left: 0; + } + [class*="span"], + .uneditable-input[class*="span"], + .row-fluid [class*="span"] { + float: none; + display: block; + width: 100%; + margin-left: 0; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + } + .span12, + .row-fluid .span12 { + width: 100%; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + } + .row-fluid [class*="offset"]:first-child { + margin-left: 0; + } + .input-large, + .input-xlarge, + .input-xxlarge, + input[class*="span"], + select[class*="span"], + textarea[class*="span"], + .uneditable-input { + display: block; + width: 100%; + min-height: 31px; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + } + .input-prepend input, + .input-append input, + .input-prepend input[class*="span"], + .input-append input[class*="span"] { + display: inline-block; + width: auto; + } + .controls-row [class*="span"] + [class*="span"] { + margin-left: 0; + } + .modal { + position: fixed; + top: 20px; + left: 20px; + right: 20px; + width: auto; + margin: 0; + } + .modal.fade { + top: -100px; + } + .modal.fade.in { + top: 20px; + } +} +@media (max-width: 480px) { + .nav-collapse { + -webkit-transform: translate3d(0, 0, 0); + } + .page-header h1 small { + display: block; + line-height: 21px; + } + input[type="checkbox"], + input[type="radio"] { + border: 1px solid #ccc; + } + .form-horizontal .control-label { + float: none; + width: auto; + padding-top: 0; + text-align: left; + } + .form-horizontal .controls { + margin-left: 0; + } + .form-horizontal .control-list { + padding-top: 0; + } + .form-horizontal .form-actions { + padding-left: 10px; + padding-right: 10px; + } + .media .pull-left, + .media .pull-right { + float: none; + display: block; + margin-bottom: 10px; + } + .media-object { + margin-right: 0; + margin-left: 0; + } + .modal { + top: 10px; + left: 10px; + right: 10px; + } + .modal-header .close { + padding: 10px; + margin: -10px; + } + .carousel-caption { + position: static; + } +} +@media (max-width: 979px) { + body { + padding-top: 0; + } + .navbar-fixed-top, + .navbar-fixed-bottom { + position: static; + } + .navbar-fixed-top { + margin-bottom: 21px; + } + .navbar-fixed-bottom { + margin-top: 21px; + } + .navbar-fixed-top .navbar-inner, + .navbar-fixed-bottom .navbar-inner { + padding: 5px; + } + .navbar .container { + width: auto; + padding: 0; + } + .navbar .brand { + padding-left: 10px; + padding-right: 10px; + margin: 0 0 0 -5px; + } + .nav-collapse { + clear: both; + } + .nav-collapse .nav { + float: none; + margin: 0 0 10.5px; + } + .nav-collapse .nav > li { + float: none; + } + .nav-collapse .nav > li > a { + margin-bottom: 2px; + } + .nav-collapse .nav > .divider-vertical { + display: none; + } + .nav-collapse .nav .nav-header { + color: #777777; + text-shadow: none; + } + .nav-collapse .nav > li > a, + .nav-collapse .dropdown-menu a { + padding: 9px 15px; + font-weight: bold; + color: #777777; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; + } + .nav-collapse .btn { + padding: 4px 10px 4px; + font-weight: normal; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; + } + .nav-collapse .dropdown-menu li + li a { + margin-bottom: 2px; + } + .nav-collapse .nav > li > a:hover, + .nav-collapse .nav > li > a:focus, + .nav-collapse .dropdown-menu a:hover, + .nav-collapse .dropdown-menu a:focus { + background-color: #f2f2f2; + } + .navbar-inverse .nav-collapse .nav > li > a, + .navbar-inverse .nav-collapse .dropdown-menu a { + color: #999999; + } + .navbar-inverse .nav-collapse .nav > li > a:hover, + .navbar-inverse .nav-collapse .nav > li > a:focus, + .navbar-inverse .nav-collapse .dropdown-menu a:hover, + .navbar-inverse .nav-collapse .dropdown-menu a:focus { + background-color: #111111; + } + .nav-collapse.in .btn-group { + margin-top: 5px; + padding: 0; + } + .nav-collapse .dropdown-menu { + position: static; + top: auto; + left: auto; + float: none; + display: none; + max-width: none; + margin: 0 15px; + padding: 0; + background-color: transparent; + border: none; + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; + -webkit-box-shadow: none; + -moz-box-shadow: none; + box-shadow: none; + } + .nav-collapse .open > .dropdown-menu { + display: block; + } + .nav-collapse .dropdown-menu:before, + .nav-collapse .dropdown-menu:after { + display: none; + } + .nav-collapse .dropdown-menu .divider { + display: none; + } + .nav-collapse .nav > li > .dropdown-menu:before, + .nav-collapse .nav > li > .dropdown-menu:after { + display: none; + } + .nav-collapse .navbar-form, + .nav-collapse .navbar-search { + float: none; + padding: 10.5px 15px; + margin: 10.5px 0; + border-top: 1px solid #f2f2f2; + border-bottom: 1px solid #f2f2f2; + -webkit-box-shadow: inset 0 1px 0 rgba(255,255,255,.1), 0 1px 0 rgba(255,255,255,.1); + -moz-box-shadow: inset 0 1px 0 rgba(255,255,255,.1), 0 1px 0 rgba(255,255,255,.1); + box-shadow: inset 0 1px 0 rgba(255,255,255,.1), 0 1px 0 rgba(255,255,255,.1); + } + .navbar-inverse .nav-collapse .navbar-form, + .navbar-inverse .nav-collapse .navbar-search { + border-top-color: #111111; + border-bottom-color: #111111; + } + .navbar .nav-collapse .nav.pull-right { + float: none; + margin-left: 0; + } + .nav-collapse, + .nav-collapse.collapse { + overflow: hidden; + height: 0; + } + .navbar .btn-navbar { + display: block; + } + .navbar-static .navbar-inner { + padding-left: 10px; + padding-right: 10px; + } +} +@media (min-width: 979px + 1) { + .nav-collapse.collapse { + height: auto !important; + overflow: visible !important; + } +} diff --git a/4.5/_static/css/spc-extend.css b/4.5/_static/css/spc-extend.css new file mode 100644 index 000000000..264a62bfb --- /dev/null +++ b/4.5/_static/css/spc-extend.css @@ -0,0 +1,92 @@ +body { + background-color: white; +} +.container { + width: 90%; +} +.underline { + border-bottom: 1.5px solid #eeeeee; +} +.header { + margin-top: 15px; + margin-bottom: 15px; + margin-left: 0px; + margin-right: 0px; +} +.spc-navbar { + margin-top: 15px; + margin-bottom: 5px; + margin-left: 0px; + margin-right: 0px; +} +.spc-navbar .nav-pills { + margin-bottom: 0px; + font-size: 12px; +} +.spc-navbar .nav-pills > li > a { + padding-top: 2.5px; + padding-bottom: 2.5px; +} +.spc-page-title h1, +.spc-page-title h2, +.spc-page-title h3, +.spc-page-title h4 { + font-weight: normal; + border-bottom: 1.5px solid #eeeeee; +} +.tags .btn { + border: none; + font-size: 9.5px; + font-weight: bold; +} +.spc-search-result-title h1, +.spc-search-result-title h2, +.spc-search-result-title h3, +.spc-search-result-title h4 { + font-weight: normal; +} +.spc-snippet-header { + margin-bottom: 5px; +} +.spc-snippet-info { + padding-top: 10px; +} +.spc-snippet-info .dl-horizontal { + margin: 5px; +} +.spc-snippet-info .dl-horizontal dt { + font-weight: normal; +} +.spc-snippet-body { + padding: 10px; +} +.spc-snippet-body .accordion-group { + border: none; +} +.spc-snippet-body .accordion-heading { + text-transform: uppercase; + font-size: 14px; + border-bottom: 1px solid #e5e5e5; +} +.spc-snippet-body .accordion-heading .accordion-toggle { + padding-top: 10px; + padding-bottom: 5px; +} +.spc-rightsidebar { + color: #555555; +} +.spc-rightsidebar .navigation { + padding: 2px 10px; + font-size: 11.9px; +} +.spc-rightsidebar .navigation .nav-title { + font-weight: bold; + text-transform: uppercase; +} +.spc-rightsidebar .navigation li { + margin: 5px; +} +.footer { + padding: 5px; + font-size: small; +} diff --git a/4.5/_static/doctools.js b/4.5/_static/doctools.js new file mode 100644 index 000000000..344db17dd --- /dev/null +++ b/4.5/_static/doctools.js @@ -0,0 +1,315 @@ +/* + * doctools.js + * ~~~~~~~~~~~ + * + * Sphinx JavaScript utilities for all documentation. + * + * :copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ + +/** + * select a different prefix for underscore + */ +$u = _.noConflict(); + +/** + * make the code below compatible with browsers without + * an installed firebug like debugger +if (!window.console || !console.firebug) { + var names = ["log", "debug", "info", "warn", "error", "assert", "dir", + "dirxml", "group", "groupEnd", "time", "timeEnd", "count", "trace", + "profile", "profileEnd"]; + window.console = {}; + for (var i = 0; i < names.length; ++i) + window.console[names[i]] = function() {}; +} + */ + +/** + * small helper function to urldecode strings + */ +jQuery.urldecode = function(x) { + return decodeURIComponent(x).replace(/\+/g, ' '); +}; + +/** + * small helper function to urlencode strings + */ +jQuery.urlencode = encodeURIComponent; + +/** + * This function returns the parsed url parameters of the + * current request. Multiple values per key are supported, + * it will always return arrays of strings for the value parts. + */ +jQuery.getQueryParameters = function(s) { + if (typeof s === 'undefined') + s = document.location.search; + var parts = s.substr(s.indexOf('?') + 1).split('&'); + var result = {}; + for (var i = 0; i < parts.length; i++) { + var tmp = parts[i].split('=', 2); + var key = jQuery.urldecode(tmp[0]); + var value = jQuery.urldecode(tmp[1]); + if (key in result) + result[key].push(value); + else + result[key] = [value]; + } + return result; +}; + +/** + * highlight a given string on a jquery object by wrapping it in + * span elements with the given class name. + */ +jQuery.fn.highlightText = function(text, className) { + function highlight(node, addItems) { + if (node.nodeType === 3) { + var val = node.nodeValue; + var pos = val.toLowerCase().indexOf(text); + if (pos >= 0 && + !jQuery(node.parentNode).hasClass(className) && + !jQuery(node.parentNode).hasClass("nohighlight")) { + var span; + var isInSVG = jQuery(node).closest("body, svg, foreignObject").is("svg"); + if (isInSVG) { + span = document.createElementNS("http://www.w3.org/2000/svg", "tspan"); + } else { + span = document.createElement("span"); + span.className = className; + } + span.appendChild(document.createTextNode(val.substr(pos, text.length))); + node.parentNode.insertBefore(span, node.parentNode.insertBefore( + document.createTextNode(val.substr(pos + text.length)), + node.nextSibling)); + node.nodeValue = val.substr(0, pos); + if (isInSVG) { + var bbox = span.getBBox(); + var rect = document.createElementNS("http://www.w3.org/2000/svg", "rect"); + rect.x.baseVal.value = bbox.x; + rect.y.baseVal.value = bbox.y; + rect.width.baseVal.value = bbox.width; + rect.height.baseVal.value = bbox.height; + rect.setAttribute('class', className); + var parentOfText = node.parentNode.parentNode; + addItems.push({ + "parent": node.parentNode, + "target": rect}); + } + } + } + else if (!jQuery(node).is("button, select, textarea")) { + jQuery.each(node.childNodes, function() { + highlight(this, addItems); + }); + } + } + var addItems = []; + var result = this.each(function() { + highlight(this, addItems); + }); + for (var i = 0; i < addItems.length; ++i) { + jQuery(addItems[i].parent).before(addItems[i].target); + } + return result; +}; + +/* + * backward compatibility for jQuery.browser + * This will be supported until firefox bug is fixed. + */ +if (!jQuery.browser) { + jQuery.uaMatch = function(ua) { + ua = ua.toLowerCase(); + + var match = /(chrome)[ \/]([\w.]+)/.exec(ua) || + /(webkit)[ \/]([\w.]+)/.exec(ua) || + /(opera)(?:.*version|)[ \/]([\w.]+)/.exec(ua) || + /(msie) ([\w.]+)/.exec(ua) || + ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec(ua) || + []; + + return { + browser: match[ 1 ] || "", + version: match[ 2 ] || "0" + }; + }; + jQuery.browser = {}; + jQuery.browser[jQuery.uaMatch(navigator.userAgent).browser] = true; +} + +/** + * Small JavaScript module for the documentation. + */ +var Documentation = { + + init : function() { + this.fixFirefoxAnchorBug(); + this.highlightSearchWords(); + this.initIndexTable(); + if (DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS) { + this.initOnKeyListeners(); + } + }, + + /** + * i18n support + */ + TRANSLATIONS : {}, + PLURAL_EXPR : function(n) { return n === 1 ? 0 : 1; }, + LOCALE : 'unknown', + + // gettext and ngettext don't access this so that the functions + // can safely bound to a different name (_ = Documentation.gettext) + gettext : function(string) { + var translated = Documentation.TRANSLATIONS[string]; + if (typeof translated === 'undefined') + return string; + return (typeof translated === 'string') ? translated : translated[0]; + }, + + ngettext : function(singular, plural, n) { + var translated = Documentation.TRANSLATIONS[singular]; + if (typeof translated === 'undefined') + return (n == 1) ? singular : plural; + return translated[Documentation.PLURALEXPR(n)]; + }, + + addTranslations : function(catalog) { + for (var key in catalog.messages) + this.TRANSLATIONS[key] = catalog.messages[key]; + this.PLURAL_EXPR = new Function('n', 'return +(' + catalog.plural_expr + ')'); + this.LOCALE = catalog.locale; + }, + + /** + * add context elements like header anchor links + */ + addContextElements : function() { + $('div[id] > :header:first').each(function() { + $('\u00B6'). + attr('href', '#' + this.id). + attr('title', _('Permalink to this headline')). + appendTo(this); + }); + $('dt[id]').each(function() { + $('\u00B6'). + attr('href', '#' + this.id). + attr('title', _('Permalink to this definition')). + appendTo(this); + }); + }, + + /** + * workaround a firefox stupidity + * see: https://bugzilla.mozilla.org/show_bug.cgi?id=645075 + */ + fixFirefoxAnchorBug : function() { + if (document.location.hash && $.browser.mozilla) + window.setTimeout(function() { + document.location.href += ''; + }, 10); + }, + + /** + * highlight the search words provided in the url in the text + */ + highlightSearchWords : function() { + var params = $.getQueryParameters(); + var terms = (params.highlight) ? params.highlight[0].split(/\s+/) : []; + if (terms.length) { + var body = $('div.body'); + if (!body.length) { + body = $('body'); + } + window.setTimeout(function() { + $.each(terms, function() { + body.highlightText(this.toLowerCase(), 'highlighted'); + }); + }, 10); + $('') + .appendTo($('#searchbox')); + } + }, + + /** + * init the domain index toggle buttons + */ + initIndexTable : function() { + var togglers = $('img.toggler').click(function() { + var src = $(this).attr('src'); + var idnum = $(this).attr('id').substr(7); + $('tr.cg-' + idnum).toggle(); + if (src.substr(-9) === 'minus.png') + $(this).attr('src', src.substr(0, src.length-9) + 'plus.png'); + else + $(this).attr('src', src.substr(0, src.length-8) + 'minus.png'); + }).css('display', ''); + if (DOCUMENTATION_OPTIONS.COLLAPSE_INDEX) { + togglers.click(); + } + }, + + /** + * helper function to hide the search marks again + */ + hideSearchWords : function() { + $('#searchbox .highlight-link').fadeOut(300); + $('span.highlighted').removeClass('highlighted'); + }, + + /** + * make the url absolute + */ + makeURL : function(relativeURL) { + return DOCUMENTATION_OPTIONS.URL_ROOT + '/' + relativeURL; + }, + + /** + * get the current relative url + */ + getCurrentURL : function() { + var path = document.location.pathname; + var parts = path.split(/\//); + $.each(DOCUMENTATION_OPTIONS.URL_ROOT.split(/\//), function() { + if (this === '..') + parts.pop(); + }); + var url = parts.join('/'); + return path.substring(url.lastIndexOf('/') + 1, path.length - 1); + }, + + initOnKeyListeners: function() { + $(document).keyup(function(event) { + var activeElementType = document.activeElement.tagName; + // don't navigate when in search box or textarea + if (activeElementType !== 'TEXTAREA' && activeElementType !== 'INPUT' && activeElementType !== 'SELECT') { + switch (event.keyCode) { + case 37: // left + var prevHref = $('link[rel="prev"]').prop('href'); + if (prevHref) { + window.location.href = prevHref; + return false; + } + case 39: // right + var nextHref = $('link[rel="next"]').prop('href'); + if (nextHref) { + window.location.href = nextHref; + return false; + } + } + } + }); + } +}; + +// quick alias for translations +_ = Documentation.gettext; + +$(document).ready(function() { + Documentation.init(); +}); diff --git a/4.5/_static/documentation_options.js b/4.5/_static/documentation_options.js new file mode 100644 index 000000000..df8bd0767 --- /dev/null +++ b/4.5/_static/documentation_options.js @@ -0,0 +1,10 @@ +var DOCUMENTATION_OPTIONS = { + URL_ROOT: document.getElementById("documentation_options").getAttribute('data-url_root'), + VERSION: '4.6.0.dev77', + LANGUAGE: 'None', + COLLAPSE_INDEX: false, + FILE_SUFFIX: '.html', + HAS_SOURCE: true, + SOURCELINK_SUFFIX: '.txt', + NAVIGATION_WITH_KEYS: false, +}; \ No newline at end of file diff --git a/_static/down-pressed.png b/4.5/_static/down-pressed.png similarity index 100% rename from _static/down-pressed.png rename to 4.5/_static/down-pressed.png diff --git a/_static/down.png b/4.5/_static/down.png similarity index 100% rename from _static/down.png rename to 4.5/_static/down.png diff --git a/4.5/_static/enthought.css b/4.5/_static/enthought.css new file mode 100644 index 000000000..32ddcacb7 --- /dev/null +++ b/4.5/_static/enthought.css @@ -0,0 +1,412 @@ +/* -*- css -*- + * + * sphinxdoc.css_t + * ~~~~~~~~~~~~~~~ + * + * Sphinx stylesheet -- sphinxdoc theme. Originally created by + * Armin Ronacher for Werkzeug. + * + * :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ + +@import url("basic.css"); + +/* @import url("css/scipy-central.css"); */ + +@font-face { + font-family: 'Source Code Pro'; + font-weight: 400; + font-style: normal; + font-stretch: normal; + src: local('Source Code Pro'), local('SourceCodePro-Regular'), url('fonts/SourceCodePro-Regular.otf.woff') format('woff'); +} + +@font-face { + font-family: 'Source Code Pro'; + font-weight: 600; + font-style: normal; + font-stretch: normal; + src: local('Source Code Pro Semibold'), local('SourceCodePro-Semibold'), url('fonts/SourceCodePro-Semibold.otf.woff') format('woff'); +} + +@font-face{ + font-family: 'Source Sans Pro'; + font-weight: 400; + font-style: normal; + font-stretch: normal; + src: local('Source Sans Pro'), local('SourceSansPro-Regular'), url('fonts/SourceSansPro-Regular.otf.woff') format('woff'); +} + +@font-face{ + font-family: 'Source Sans Pro'; + font-weight: 600; + font-style: normal; + font-stretch: normal; + src: local('Source Sans Pro Semibold'), local('SourceSansPro-Semibold'), url('fonts/SourceSansPro-Semibold.otf.woff') format('woff'); +} + +@font-face{ + font-family: 'Source Sans Pro'; + font-weight: 400; + font-style: italic; + font-stretch: normal; + src: local('Source Sans Pro Italic'), local('SourceSansPro-It'), url('fonts/SourceSansPro-It.otf.woff') format('woff'); +} + +@font-face{ + font-family: 'Source Sans Pro'; + font-weight: 600; + font-style: italic; + font-stretch: normal; + src: local('Source Sans Pro Semibold Italic'), local('SourceSansPro-SemiboldIt'), url('fonts/SourceSansPro-SemiboldIt.otf.woff') format('woff'); +} + +/* + * General tweaks + */ + +div.container-navbar-bottom { + margin-top: 0; +} + +div.container-navbar-bottom div.spc-navbar { + margin-top: 0; +} + +div.spc-navbar { + margin: 0; +} + +tt { + color: inherit; + font: inherit; +} + +tt.literal { + font-family: 'Source Code Pro', monospace; + padding-left: 2px; + background-color: rgb(242, 242, 242); +} + +a tt.literal { + border-bottom: none; + background-color: inherit; +} + +tt.xref { + border-bottom: none; + background-color: inherit; + font-weight: inherit; + padding-left: 0px; +} + +tt.descclassname { + font-family: 'Source Code Pro', monospace; +} + +tt.descname { + font-family: 'Source Code Pro', monospace; + font-size: 20px; +} + +code { + color: inherit; + font: inherit; + padding: 2px 0px; + border: inherit; +} + +code.literal { + font-family: monospace; + padding-left: 2px; + background-color: rgb(242, 242, 242); +} + +a code.literal { + border: none; + background-color: inherit; +} + +code.xref { + font-family: inherit; + border-bottom: none; + background-color: inherit; + padding-left: 0px; +} + +code.descname { + font-size: 16px; +} + +dl.class, +dl.function, +dl.data +{ + border-top: 2px solid #888; + padding-top: 1px; +} + +dl.attribute, +dl.classmethod, +dl.staticmethod, +dl.method +{ + border-top: 1px solid #aaa; + padding-top: 1px; +} + +dl.attribute > dt > tt.descname, +dl.classmethod > dt > tt.descname, +dl.staticmethod > dt > tt.descname, +dl.method > dt > tt.descname +{ + font-size: inherit; +} + +dl.class > dt, +dl.attribute > dt, +dl.data > dt, +dl.function > dt, +dl.exception > dt, +dl.classmethod > dt, +dl.staticmethod > dt, +dl.method > dt +{ + font-weight: normal; + /* Fake a hanging indent. If the text has to linewrap, it will indent more + * than the following
. + */ + text-indent: -60px; + padding-left: 60px; +} + +pre { + border-radius: 0; + border: none; + font-family: 'Source Code Pro', monospace; +} + +.nav-pills > .active > a, +.nav-pills > .active > a:hover, +.nav-pills > .active > a:focus { + color: #ffffff; + background-color: #253370; +} + +.nav-pills.pull-right > li { + float: right; +} + +a { + color: #253370; + text-decoration: none; +} + +/* + * Field lists + */ + +table.field-list { + border-collapse: collapse; + border-spacing: 5px; + margin-left: 1px; + border-left: 5px solid #DFDFDF !important; +} + +table.field-list th.field-name { + display: block; + text-align: left; + padding: 1px 8px 1px 5px; + white-space: nowrap; + background-color: #DFDFDF; +} + +table.field-list td.field-body { + display: block; + border-left: none !important; + padding-left: 1em; +} + +table.field-list td.field-body > ul { + padding-left: 1em; +} + +table.field-list td.field-body > p, +table.field-list td.field-body > ul > li > p +{ + display: inline; +} + +table.field-list td.field-body > p > strong { + font-style: normal; +} + +td.field-body blockquote { + border-left: none; + margin: 0; + padding-left: 30px; +} + +td.field-body blockquote p, +dl.class blockquote p, +dl.function blockquote p, +dl.classmethod blockquote p, +dl.staticmethod blockquote p, +dl.method blockquote p +{ + font-family: inherit; + font-size: inherit; + font-weight: inherit; + line-height: inherit; +} + + +/* + * Sidebars and top logo + */ + +div.sphinxsidebarwrapper { + overflow: hidden; +} + +div.sphinxsidebarwrapper p.logo { + text-align: center; +} + +div.spc-rightsidebar h3 { + font-size: 120%; + line-height: inherit; + border-bottom: 1px solid #656565; +} + +div.spc-rightsidebar h4 { + font-size: 110%; + line-height: inherit; + border-bottom: 1px solid #656565; +} + +form.search > input[type="text"] { + width: auto; +} + +/* + * Headers + */ + +h1 a { color: #333333; } +h2 a { color: #333333; } +h3 a { color: #333333; } +h4 a { color: #333333; } +h5 a { color: #333333; } +h6 a { color: #333333; } + +h1 tt { font: inherit; border-bottom: none; } +h2 tt { font: inherit; border-bottom: none; } +h3 tt { font: inherit; border-bottom: none; } +h4 tt { font: inherit; border-bottom: none; } +h5 tt { font: inherit; border-bottom: none; } +h6 tt { font: inherit; border-bottom: none; } + +div#spc-section-body h1, h2, h3, h4, h5, h6{ + color: #444444; + font-weight: normal; + border-bottom: 0px solid #656565; + margin-bottom: 0.5em; +} +div#spc-section-body h1 { font-size: 200%; font-weight: bold; color: #333333; } +div#spc-section-body h2 { font-size: 160%; font-weight: bold; } +div#spc-section-body h3 { font-size: 140%; } +div#spc-section-body h4 { font-size: 120%; border-bottom: none; } +div#spc-section-body h5 { font-size: 110%; border-bottom: none; } +div#spc-section-body h6 { font-size: 100%; border-bottom: none; } + +/* Styling for hyperlinks */ +div#spc-section-body a{ + text-decoration: none; +} +div#spc-section-body a:hover{ + text-decoration: underline; +} + +/* Styling for images and figures: images are inline, figures are centered */ +div#spc-section-body .align-center{ + text-align: center; +} + +p.rubric { + color: #333333; + font-size: 120%; + font-weight: normal; + border-bottom: 1px solid #DDDDDD; +} + +.highlight-python pre { + border-top: 1px solid #656565; + border-bottom: 1px solid #656565; +} + +/* Docutils uses this tag for footnote backrefs. By coincidence, Bootstrap also + * uses this class and assigns an obnoxious color to it. Use a less obnoxious + * color. + */ +td.label { + background-color: rgb(242, 242, 242); +} + +/* + * Tables + */ + +table.citation { + border: none; +} + +table.docutils td, table.docutils th { + border: none; +} + +table.docutils { + margin-bottom: 9.5px; +} + + +/* + * Admonitions + */ + +p.admonition-title { + display: inline; +} + +p.admonition-title:after { + content: ":"; +} + +div.seealso { + background-color: #ffc; + border: 1px solid #ff6; +} + +div.seealso dt { + float: left; + clear: left; + min-width: 4em; + padding-right: 1em; +} + +div.seealso dd { + margin-top: 0; + margin-bottom: 0; +} + +div.warning { + background-color: #ffe4e4; + border: 1px solid #f66; +} + +div.note { + background-color: #eee; + border: 1px solid #ccc; +} \ No newline at end of file diff --git a/4.5/_static/file.png b/4.5/_static/file.png new file mode 100644 index 000000000..a858a410e Binary files /dev/null and b/4.5/_static/file.png differ diff --git a/4.5/_static/fonts/SourceCodePro-Regular.otf.woff b/4.5/_static/fonts/SourceCodePro-Regular.otf.woff new file mode 100644 index 000000000..46e7bd058 Binary files /dev/null and b/4.5/_static/fonts/SourceCodePro-Regular.otf.woff differ diff --git a/4.5/_static/fonts/SourceCodePro-Semibold.otf.woff b/4.5/_static/fonts/SourceCodePro-Semibold.otf.woff new file mode 100644 index 000000000..d0f6f758f Binary files /dev/null and b/4.5/_static/fonts/SourceCodePro-Semibold.otf.woff differ diff --git a/4.5/_static/fonts/SourceSansPro-It.otf.woff b/4.5/_static/fonts/SourceSansPro-It.otf.woff new file mode 100644 index 000000000..9cae9b4b9 Binary files /dev/null and b/4.5/_static/fonts/SourceSansPro-It.otf.woff differ diff --git a/4.5/_static/fonts/SourceSansPro-Regular.otf.woff b/4.5/_static/fonts/SourceSansPro-Regular.otf.woff new file mode 100644 index 000000000..6bc912b76 Binary files /dev/null and b/4.5/_static/fonts/SourceSansPro-Regular.otf.woff differ diff --git a/4.5/_static/fonts/SourceSansPro-Semibold.otf.woff b/4.5/_static/fonts/SourceSansPro-Semibold.otf.woff new file mode 100644 index 000000000..475c49971 Binary files /dev/null and b/4.5/_static/fonts/SourceSansPro-Semibold.otf.woff differ diff --git a/4.5/_static/fonts/SourceSansPro-SemiboldIt.otf.woff b/4.5/_static/fonts/SourceSansPro-SemiboldIt.otf.woff new file mode 100644 index 000000000..62c2997d3 Binary files /dev/null and b/4.5/_static/fonts/SourceSansPro-SemiboldIt.otf.woff differ diff --git a/4.5/_static/img/contents.png b/4.5/_static/img/contents.png new file mode 100644 index 000000000..7fb82154a Binary files /dev/null and b/4.5/_static/img/contents.png differ diff --git a/4.5/_static/img/e-logo.png b/4.5/_static/img/e-logo.png new file mode 100644 index 000000000..3874ef07a Binary files /dev/null and b/4.5/_static/img/e-logo.png differ diff --git a/4.5/_static/img/favicon.ico b/4.5/_static/img/favicon.ico new file mode 100644 index 000000000..6ff4b1d2f Binary files /dev/null and b/4.5/_static/img/favicon.ico differ diff --git a/4.5/_static/img/glyphicons-halflings-white.png b/4.5/_static/img/glyphicons-halflings-white.png new file mode 100644 index 000000000..3bf6484a2 Binary files /dev/null and b/4.5/_static/img/glyphicons-halflings-white.png differ diff --git a/4.5/_static/img/glyphicons-halflings.png b/4.5/_static/img/glyphicons-halflings.png new file mode 100644 index 000000000..a99699932 Binary files /dev/null and b/4.5/_static/img/glyphicons-halflings.png differ diff --git a/4.5/_static/img/navigation.png b/4.5/_static/img/navigation.png new file mode 100644 index 000000000..1081dc143 Binary files /dev/null and b/4.5/_static/img/navigation.png differ diff --git a/4.5/_static/img/transparent-pixel.gif b/4.5/_static/img/transparent-pixel.gif new file mode 100644 index 000000000..e4994d9ef Binary files /dev/null and b/4.5/_static/img/transparent-pixel.gif differ diff --git a/4.5/_static/img/ui-anim_basic_16x16.gif b/4.5/_static/img/ui-anim_basic_16x16.gif new file mode 100644 index 000000000..084ecb879 Binary files /dev/null and b/4.5/_static/img/ui-anim_basic_16x16.gif differ diff --git a/_static/jquery-3.2.1.js b/4.5/_static/jquery-3.2.1.js similarity index 100% rename from _static/jquery-3.2.1.js rename to 4.5/_static/jquery-3.2.1.js diff --git a/4.5/_static/jquery.js b/4.5/_static/jquery.js new file mode 100644 index 000000000..644d35e27 --- /dev/null +++ b/4.5/_static/jquery.js @@ -0,0 +1,4 @@ +/*! jQuery v3.2.1 | (c) JS Foundation and other contributors | jquery.org/license */ +!function(a,b){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=a.document?b(a,!0):function(a){if(!a.document)throw new Error("jQuery requires a window with a document");return b(a)}:b(a)}("undefined"!=typeof window?window:this,function(a,b){"use strict";var c=[],d=a.document,e=Object.getPrototypeOf,f=c.slice,g=c.concat,h=c.push,i=c.indexOf,j={},k=j.toString,l=j.hasOwnProperty,m=l.toString,n=m.call(Object),o={};function p(a,b){b=b||d;var c=b.createElement("script");c.text=a,b.head.appendChild(c).parentNode.removeChild(c)}var q="3.2.1",r=function(a,b){return new r.fn.init(a,b)},s=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,t=/^-ms-/,u=/-([a-z])/g,v=function(a,b){return b.toUpperCase()};r.fn=r.prototype={jquery:q,constructor:r,length:0,toArray:function(){return f.call(this)},get:function(a){return null==a?f.call(this):a<0?this[a+this.length]:this[a]},pushStack:function(a){var b=r.merge(this.constructor(),a);return b.prevObject=this,b},each:function(a){return r.each(this,a)},map:function(a){return this.pushStack(r.map(this,function(b,c){return a.call(b,c,b)}))},slice:function(){return this.pushStack(f.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(a){var b=this.length,c=+a+(a<0?b:0);return this.pushStack(c>=0&&c0&&b-1 in a)}var x=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u="sizzle"+1*new Date,v=a.document,w=0,x=0,y=ha(),z=ha(),A=ha(),B=function(a,b){return a===b&&(l=!0),0},C={}.hasOwnProperty,D=[],E=D.pop,F=D.push,G=D.push,H=D.slice,I=function(a,b){for(var c=0,d=a.length;c+~]|"+K+")"+K+"*"),S=new RegExp("="+K+"*([^\\]'\"]*?)"+K+"*\\]","g"),T=new RegExp(N),U=new RegExp("^"+L+"$"),V={ID:new RegExp("^#("+L+")"),CLASS:new RegExp("^\\.("+L+")"),TAG:new RegExp("^("+L+"|[*])"),ATTR:new RegExp("^"+M),PSEUDO:new RegExp("^"+N),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+K+"*(even|odd|(([+-]|)(\\d*)n|)"+K+"*(?:([+-]|)"+K+"*(\\d+)|))"+K+"*\\)|)","i"),bool:new RegExp("^(?:"+J+")$","i"),needsContext:new RegExp("^"+K+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+K+"*((?:-\\d)?\\d*)"+K+"*\\)|)(?=[^-]|$)","i")},W=/^(?:input|select|textarea|button)$/i,X=/^h\d$/i,Y=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,$=/[+~]/,_=new RegExp("\\\\([\\da-f]{1,6}"+K+"?|("+K+")|.)","ig"),aa=function(a,b,c){var d="0x"+b-65536;return d!==d||c?b:d<0?String.fromCharCode(d+65536):String.fromCharCode(d>>10|55296,1023&d|56320)},ba=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,ca=function(a,b){return b?"\0"===a?"\ufffd":a.slice(0,-1)+"\\"+a.charCodeAt(a.length-1).toString(16)+" ":"\\"+a},da=function(){m()},ea=ta(function(a){return a.disabled===!0&&("form"in a||"label"in a)},{dir:"parentNode",next:"legend"});try{G.apply(D=H.call(v.childNodes),v.childNodes),D[v.childNodes.length].nodeType}catch(fa){G={apply:D.length?function(a,b){F.apply(a,H.call(b))}:function(a,b){var c=a.length,d=0;while(a[c++]=b[d++]);a.length=c-1}}}function ga(a,b,d,e){var f,h,j,k,l,o,r,s=b&&b.ownerDocument,w=b?b.nodeType:9;if(d=d||[],"string"!=typeof a||!a||1!==w&&9!==w&&11!==w)return d;if(!e&&((b?b.ownerDocument||b:v)!==n&&m(b),b=b||n,p)){if(11!==w&&(l=Z.exec(a)))if(f=l[1]){if(9===w){if(!(j=b.getElementById(f)))return d;if(j.id===f)return d.push(j),d}else if(s&&(j=s.getElementById(f))&&t(b,j)&&j.id===f)return d.push(j),d}else{if(l[2])return G.apply(d,b.getElementsByTagName(a)),d;if((f=l[3])&&c.getElementsByClassName&&b.getElementsByClassName)return G.apply(d,b.getElementsByClassName(f)),d}if(c.qsa&&!A[a+" "]&&(!q||!q.test(a))){if(1!==w)s=b,r=a;else if("object"!==b.nodeName.toLowerCase()){(k=b.getAttribute("id"))?k=k.replace(ba,ca):b.setAttribute("id",k=u),o=g(a),h=o.length;while(h--)o[h]="#"+k+" "+sa(o[h]);r=o.join(","),s=$.test(a)&&qa(b.parentNode)||b}if(r)try{return G.apply(d,s.querySelectorAll(r)),d}catch(x){}finally{k===u&&b.removeAttribute("id")}}}return i(a.replace(P,"$1"),b,d,e)}function ha(){var a=[];function b(c,e){return a.push(c+" ")>d.cacheLength&&delete b[a.shift()],b[c+" "]=e}return b}function ia(a){return a[u]=!0,a}function ja(a){var b=n.createElement("fieldset");try{return!!a(b)}catch(c){return!1}finally{b.parentNode&&b.parentNode.removeChild(b),b=null}}function ka(a,b){var c=a.split("|"),e=c.length;while(e--)d.attrHandle[c[e]]=b}function la(a,b){var c=b&&a,d=c&&1===a.nodeType&&1===b.nodeType&&a.sourceIndex-b.sourceIndex;if(d)return d;if(c)while(c=c.nextSibling)if(c===b)return-1;return a?1:-1}function ma(a){return function(b){var c=b.nodeName.toLowerCase();return"input"===c&&b.type===a}}function na(a){return function(b){var c=b.nodeName.toLowerCase();return("input"===c||"button"===c)&&b.type===a}}function oa(a){return function(b){return"form"in b?b.parentNode&&b.disabled===!1?"label"in b?"label"in b.parentNode?b.parentNode.disabled===a:b.disabled===a:b.isDisabled===a||b.isDisabled!==!a&&ea(b)===a:b.disabled===a:"label"in b&&b.disabled===a}}function pa(a){return ia(function(b){return b=+b,ia(function(c,d){var e,f=a([],c.length,b),g=f.length;while(g--)c[e=f[g]]&&(c[e]=!(d[e]=c[e]))})})}function qa(a){return a&&"undefined"!=typeof a.getElementsByTagName&&a}c=ga.support={},f=ga.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return!!b&&"HTML"!==b.nodeName},m=ga.setDocument=function(a){var b,e,g=a?a.ownerDocument||a:v;return g!==n&&9===g.nodeType&&g.documentElement?(n=g,o=n.documentElement,p=!f(n),v!==n&&(e=n.defaultView)&&e.top!==e&&(e.addEventListener?e.addEventListener("unload",da,!1):e.attachEvent&&e.attachEvent("onunload",da)),c.attributes=ja(function(a){return a.className="i",!a.getAttribute("className")}),c.getElementsByTagName=ja(function(a){return a.appendChild(n.createComment("")),!a.getElementsByTagName("*").length}),c.getElementsByClassName=Y.test(n.getElementsByClassName),c.getById=ja(function(a){return o.appendChild(a).id=u,!n.getElementsByName||!n.getElementsByName(u).length}),c.getById?(d.filter.ID=function(a){var b=a.replace(_,aa);return function(a){return a.getAttribute("id")===b}},d.find.ID=function(a,b){if("undefined"!=typeof b.getElementById&&p){var c=b.getElementById(a);return c?[c]:[]}}):(d.filter.ID=function(a){var b=a.replace(_,aa);return function(a){var c="undefined"!=typeof a.getAttributeNode&&a.getAttributeNode("id");return c&&c.value===b}},d.find.ID=function(a,b){if("undefined"!=typeof b.getElementById&&p){var c,d,e,f=b.getElementById(a);if(f){if(c=f.getAttributeNode("id"),c&&c.value===a)return[f];e=b.getElementsByName(a),d=0;while(f=e[d++])if(c=f.getAttributeNode("id"),c&&c.value===a)return[f]}return[]}}),d.find.TAG=c.getElementsByTagName?function(a,b){return"undefined"!=typeof b.getElementsByTagName?b.getElementsByTagName(a):c.qsa?b.querySelectorAll(a):void 0}:function(a,b){var c,d=[],e=0,f=b.getElementsByTagName(a);if("*"===a){while(c=f[e++])1===c.nodeType&&d.push(c);return d}return f},d.find.CLASS=c.getElementsByClassName&&function(a,b){if("undefined"!=typeof b.getElementsByClassName&&p)return b.getElementsByClassName(a)},r=[],q=[],(c.qsa=Y.test(n.querySelectorAll))&&(ja(function(a){o.appendChild(a).innerHTML="",a.querySelectorAll("[msallowcapture^='']").length&&q.push("[*^$]="+K+"*(?:''|\"\")"),a.querySelectorAll("[selected]").length||q.push("\\["+K+"*(?:value|"+J+")"),a.querySelectorAll("[id~="+u+"-]").length||q.push("~="),a.querySelectorAll(":checked").length||q.push(":checked"),a.querySelectorAll("a#"+u+"+*").length||q.push(".#.+[+~]")}),ja(function(a){a.innerHTML="";var b=n.createElement("input");b.setAttribute("type","hidden"),a.appendChild(b).setAttribute("name","D"),a.querySelectorAll("[name=d]").length&&q.push("name"+K+"*[*^$|!~]?="),2!==a.querySelectorAll(":enabled").length&&q.push(":enabled",":disabled"),o.appendChild(a).disabled=!0,2!==a.querySelectorAll(":disabled").length&&q.push(":enabled",":disabled"),a.querySelectorAll("*,:x"),q.push(",.*:")})),(c.matchesSelector=Y.test(s=o.matches||o.webkitMatchesSelector||o.mozMatchesSelector||o.oMatchesSelector||o.msMatchesSelector))&&ja(function(a){c.disconnectedMatch=s.call(a,"*"),s.call(a,"[s!='']:x"),r.push("!=",N)}),q=q.length&&new RegExp(q.join("|")),r=r.length&&new RegExp(r.join("|")),b=Y.test(o.compareDocumentPosition),t=b||Y.test(o.contains)?function(a,b){var c=9===a.nodeType?a.documentElement:a,d=b&&b.parentNode;return a===d||!(!d||1!==d.nodeType||!(c.contains?c.contains(d):a.compareDocumentPosition&&16&a.compareDocumentPosition(d)))}:function(a,b){if(b)while(b=b.parentNode)if(b===a)return!0;return!1},B=b?function(a,b){if(a===b)return l=!0,0;var d=!a.compareDocumentPosition-!b.compareDocumentPosition;return d?d:(d=(a.ownerDocument||a)===(b.ownerDocument||b)?a.compareDocumentPosition(b):1,1&d||!c.sortDetached&&b.compareDocumentPosition(a)===d?a===n||a.ownerDocument===v&&t(v,a)?-1:b===n||b.ownerDocument===v&&t(v,b)?1:k?I(k,a)-I(k,b):0:4&d?-1:1)}:function(a,b){if(a===b)return l=!0,0;var c,d=0,e=a.parentNode,f=b.parentNode,g=[a],h=[b];if(!e||!f)return a===n?-1:b===n?1:e?-1:f?1:k?I(k,a)-I(k,b):0;if(e===f)return la(a,b);c=a;while(c=c.parentNode)g.unshift(c);c=b;while(c=c.parentNode)h.unshift(c);while(g[d]===h[d])d++;return d?la(g[d],h[d]):g[d]===v?-1:h[d]===v?1:0},n):n},ga.matches=function(a,b){return ga(a,null,null,b)},ga.matchesSelector=function(a,b){if((a.ownerDocument||a)!==n&&m(a),b=b.replace(S,"='$1']"),c.matchesSelector&&p&&!A[b+" "]&&(!r||!r.test(b))&&(!q||!q.test(b)))try{var d=s.call(a,b);if(d||c.disconnectedMatch||a.document&&11!==a.document.nodeType)return d}catch(e){}return ga(b,n,null,[a]).length>0},ga.contains=function(a,b){return(a.ownerDocument||a)!==n&&m(a),t(a,b)},ga.attr=function(a,b){(a.ownerDocument||a)!==n&&m(a);var e=d.attrHandle[b.toLowerCase()],f=e&&C.call(d.attrHandle,b.toLowerCase())?e(a,b,!p):void 0;return void 0!==f?f:c.attributes||!p?a.getAttribute(b):(f=a.getAttributeNode(b))&&f.specified?f.value:null},ga.escape=function(a){return(a+"").replace(ba,ca)},ga.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)},ga.uniqueSort=function(a){var b,d=[],e=0,f=0;if(l=!c.detectDuplicates,k=!c.sortStable&&a.slice(0),a.sort(B),l){while(b=a[f++])b===a[f]&&(e=d.push(f));while(e--)a.splice(d[e],1)}return k=null,a},e=ga.getText=function(a){var b,c="",d=0,f=a.nodeType;if(f){if(1===f||9===f||11===f){if("string"==typeof a.textContent)return a.textContent;for(a=a.firstChild;a;a=a.nextSibling)c+=e(a)}else if(3===f||4===f)return a.nodeValue}else while(b=a[d++])c+=e(b);return c},d=ga.selectors={cacheLength:50,createPseudo:ia,match:V,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(a){return a[1]=a[1].replace(_,aa),a[3]=(a[3]||a[4]||a[5]||"").replace(_,aa),"~="===a[2]&&(a[3]=" "+a[3]+" "),a.slice(0,4)},CHILD:function(a){return a[1]=a[1].toLowerCase(),"nth"===a[1].slice(0,3)?(a[3]||ga.error(a[0]),a[4]=+(a[4]?a[5]+(a[6]||1):2*("even"===a[3]||"odd"===a[3])),a[5]=+(a[7]+a[8]||"odd"===a[3])):a[3]&&ga.error(a[0]),a},PSEUDO:function(a){var b,c=!a[6]&&a[2];return V.CHILD.test(a[0])?null:(a[3]?a[2]=a[4]||a[5]||"":c&&T.test(c)&&(b=g(c,!0))&&(b=c.indexOf(")",c.length-b)-c.length)&&(a[0]=a[0].slice(0,b),a[2]=c.slice(0,b)),a.slice(0,3))}},filter:{TAG:function(a){var b=a.replace(_,aa).toLowerCase();return"*"===a?function(){return!0}:function(a){return a.nodeName&&a.nodeName.toLowerCase()===b}},CLASS:function(a){var b=y[a+" "];return b||(b=new RegExp("(^|"+K+")"+a+"("+K+"|$)"))&&y(a,function(a){return b.test("string"==typeof a.className&&a.className||"undefined"!=typeof a.getAttribute&&a.getAttribute("class")||"")})},ATTR:function(a,b,c){return function(d){var e=ga.attr(d,a);return null==e?"!="===b:!b||(e+="","="===b?e===c:"!="===b?e!==c:"^="===b?c&&0===e.indexOf(c):"*="===b?c&&e.indexOf(c)>-1:"$="===b?c&&e.slice(-c.length)===c:"~="===b?(" "+e.replace(O," ")+" ").indexOf(c)>-1:"|="===b&&(e===c||e.slice(0,c.length+1)===c+"-"))}},CHILD:function(a,b,c,d,e){var f="nth"!==a.slice(0,3),g="last"!==a.slice(-4),h="of-type"===b;return 1===d&&0===e?function(a){return!!a.parentNode}:function(b,c,i){var j,k,l,m,n,o,p=f!==g?"nextSibling":"previousSibling",q=b.parentNode,r=h&&b.nodeName.toLowerCase(),s=!i&&!h,t=!1;if(q){if(f){while(p){m=b;while(m=m[p])if(h?m.nodeName.toLowerCase()===r:1===m.nodeType)return!1;o=p="only"===a&&!o&&"nextSibling"}return!0}if(o=[g?q.firstChild:q.lastChild],g&&s){m=q,l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),j=k[a]||[],n=j[0]===w&&j[1],t=n&&j[2],m=n&&q.childNodes[n];while(m=++n&&m&&m[p]||(t=n=0)||o.pop())if(1===m.nodeType&&++t&&m===b){k[a]=[w,n,t];break}}else if(s&&(m=b,l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),j=k[a]||[],n=j[0]===w&&j[1],t=n),t===!1)while(m=++n&&m&&m[p]||(t=n=0)||o.pop())if((h?m.nodeName.toLowerCase()===r:1===m.nodeType)&&++t&&(s&&(l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),k[a]=[w,t]),m===b))break;return t-=e,t===d||t%d===0&&t/d>=0}}},PSEUDO:function(a,b){var c,e=d.pseudos[a]||d.setFilters[a.toLowerCase()]||ga.error("unsupported pseudo: "+a);return e[u]?e(b):e.length>1?(c=[a,a,"",b],d.setFilters.hasOwnProperty(a.toLowerCase())?ia(function(a,c){var d,f=e(a,b),g=f.length;while(g--)d=I(a,f[g]),a[d]=!(c[d]=f[g])}):function(a){return e(a,0,c)}):e}},pseudos:{not:ia(function(a){var b=[],c=[],d=h(a.replace(P,"$1"));return d[u]?ia(function(a,b,c,e){var f,g=d(a,null,e,[]),h=a.length;while(h--)(f=g[h])&&(a[h]=!(b[h]=f))}):function(a,e,f){return b[0]=a,d(b,null,f,c),b[0]=null,!c.pop()}}),has:ia(function(a){return function(b){return ga(a,b).length>0}}),contains:ia(function(a){return a=a.replace(_,aa),function(b){return(b.textContent||b.innerText||e(b)).indexOf(a)>-1}}),lang:ia(function(a){return U.test(a||"")||ga.error("unsupported lang: "+a),a=a.replace(_,aa).toLowerCase(),function(b){var c;do if(c=p?b.lang:b.getAttribute("xml:lang")||b.getAttribute("lang"))return c=c.toLowerCase(),c===a||0===c.indexOf(a+"-");while((b=b.parentNode)&&1===b.nodeType);return!1}}),target:function(b){var c=a.location&&a.location.hash;return c&&c.slice(1)===b.id},root:function(a){return a===o},focus:function(a){return a===n.activeElement&&(!n.hasFocus||n.hasFocus())&&!!(a.type||a.href||~a.tabIndex)},enabled:oa(!1),disabled:oa(!0),checked:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&!!a.checked||"option"===b&&!!a.selected},selected:function(a){return a.parentNode&&a.parentNode.selectedIndex,a.selected===!0},empty:function(a){for(a=a.firstChild;a;a=a.nextSibling)if(a.nodeType<6)return!1;return!0},parent:function(a){return!d.pseudos.empty(a)},header:function(a){return X.test(a.nodeName)},input:function(a){return W.test(a.nodeName)},button:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&"button"===a.type||"button"===b},text:function(a){var b;return"input"===a.nodeName.toLowerCase()&&"text"===a.type&&(null==(b=a.getAttribute("type"))||"text"===b.toLowerCase())},first:pa(function(){return[0]}),last:pa(function(a,b){return[b-1]}),eq:pa(function(a,b,c){return[c<0?c+b:c]}),even:pa(function(a,b){for(var c=0;c=0;)a.push(d);return a}),gt:pa(function(a,b,c){for(var d=c<0?c+b:c;++d1?function(b,c,d){var e=a.length;while(e--)if(!a[e](b,c,d))return!1;return!0}:a[0]}function va(a,b,c){for(var d=0,e=b.length;d-1&&(f[j]=!(g[j]=l))}}else r=wa(r===g?r.splice(o,r.length):r),e?e(null,g,r,i):G.apply(g,r)})}function ya(a){for(var b,c,e,f=a.length,g=d.relative[a[0].type],h=g||d.relative[" "],i=g?1:0,k=ta(function(a){return a===b},h,!0),l=ta(function(a){return I(b,a)>-1},h,!0),m=[function(a,c,d){var e=!g&&(d||c!==j)||((b=c).nodeType?k(a,c,d):l(a,c,d));return b=null,e}];i1&&ua(m),i>1&&sa(a.slice(0,i-1).concat({value:" "===a[i-2].type?"*":""})).replace(P,"$1"),c,i0,e=a.length>0,f=function(f,g,h,i,k){var l,o,q,r=0,s="0",t=f&&[],u=[],v=j,x=f||e&&d.find.TAG("*",k),y=w+=null==v?1:Math.random()||.1,z=x.length;for(k&&(j=g===n||g||k);s!==z&&null!=(l=x[s]);s++){if(e&&l){o=0,g||l.ownerDocument===n||(m(l),h=!p);while(q=a[o++])if(q(l,g||n,h)){i.push(l);break}k&&(w=y)}c&&((l=!q&&l)&&r--,f&&t.push(l))}if(r+=s,c&&s!==r){o=0;while(q=b[o++])q(t,u,g,h);if(f){if(r>0)while(s--)t[s]||u[s]||(u[s]=E.call(i));u=wa(u)}G.apply(i,u),k&&!f&&u.length>0&&r+b.length>1&&ga.uniqueSort(i)}return k&&(w=y,j=v),t};return c?ia(f):f}return h=ga.compile=function(a,b){var c,d=[],e=[],f=A[a+" "];if(!f){b||(b=g(a)),c=b.length;while(c--)f=ya(b[c]),f[u]?d.push(f):e.push(f);f=A(a,za(e,d)),f.selector=a}return f},i=ga.select=function(a,b,c,e){var f,i,j,k,l,m="function"==typeof a&&a,n=!e&&g(a=m.selector||a);if(c=c||[],1===n.length){if(i=n[0]=n[0].slice(0),i.length>2&&"ID"===(j=i[0]).type&&9===b.nodeType&&p&&d.relative[i[1].type]){if(b=(d.find.ID(j.matches[0].replace(_,aa),b)||[])[0],!b)return c;m&&(b=b.parentNode),a=a.slice(i.shift().value.length)}f=V.needsContext.test(a)?0:i.length;while(f--){if(j=i[f],d.relative[k=j.type])break;if((l=d.find[k])&&(e=l(j.matches[0].replace(_,aa),$.test(i[0].type)&&qa(b.parentNode)||b))){if(i.splice(f,1),a=e.length&&sa(i),!a)return G.apply(c,e),c;break}}}return(m||h(a,n))(e,b,!p,c,!b||$.test(a)&&qa(b.parentNode)||b),c},c.sortStable=u.split("").sort(B).join("")===u,c.detectDuplicates=!!l,m(),c.sortDetached=ja(function(a){return 1&a.compareDocumentPosition(n.createElement("fieldset"))}),ja(function(a){return a.innerHTML="","#"===a.firstChild.getAttribute("href")})||ka("type|href|height|width",function(a,b,c){if(!c)return a.getAttribute(b,"type"===b.toLowerCase()?1:2)}),c.attributes&&ja(function(a){return a.innerHTML="",a.firstChild.setAttribute("value",""),""===a.firstChild.getAttribute("value")})||ka("value",function(a,b,c){if(!c&&"input"===a.nodeName.toLowerCase())return a.defaultValue}),ja(function(a){return null==a.getAttribute("disabled")})||ka(J,function(a,b,c){var d;if(!c)return a[b]===!0?b.toLowerCase():(d=a.getAttributeNode(b))&&d.specified?d.value:null}),ga}(a);r.find=x,r.expr=x.selectors,r.expr[":"]=r.expr.pseudos,r.uniqueSort=r.unique=x.uniqueSort,r.text=x.getText,r.isXMLDoc=x.isXML,r.contains=x.contains,r.escapeSelector=x.escape;var y=function(a,b,c){var d=[],e=void 0!==c;while((a=a[b])&&9!==a.nodeType)if(1===a.nodeType){if(e&&r(a).is(c))break;d.push(a)}return d},z=function(a,b){for(var c=[];a;a=a.nextSibling)1===a.nodeType&&a!==b&&c.push(a);return c},A=r.expr.match.needsContext;function B(a,b){return a.nodeName&&a.nodeName.toLowerCase()===b.toLowerCase()}var C=/^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i,D=/^.[^:#\[\.,]*$/;function E(a,b,c){return r.isFunction(b)?r.grep(a,function(a,d){return!!b.call(a,d,a)!==c}):b.nodeType?r.grep(a,function(a){return a===b!==c}):"string"!=typeof b?r.grep(a,function(a){return i.call(b,a)>-1!==c}):D.test(b)?r.filter(b,a,c):(b=r.filter(b,a),r.grep(a,function(a){return i.call(b,a)>-1!==c&&1===a.nodeType}))}r.filter=function(a,b,c){var d=b[0];return c&&(a=":not("+a+")"),1===b.length&&1===d.nodeType?r.find.matchesSelector(d,a)?[d]:[]:r.find.matches(a,r.grep(b,function(a){return 1===a.nodeType}))},r.fn.extend({find:function(a){var b,c,d=this.length,e=this;if("string"!=typeof a)return this.pushStack(r(a).filter(function(){for(b=0;b1?r.uniqueSort(c):c},filter:function(a){return this.pushStack(E(this,a||[],!1))},not:function(a){return this.pushStack(E(this,a||[],!0))},is:function(a){return!!E(this,"string"==typeof a&&A.test(a)?r(a):a||[],!1).length}});var F,G=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/,H=r.fn.init=function(a,b,c){var e,f;if(!a)return this;if(c=c||F,"string"==typeof a){if(e="<"===a[0]&&">"===a[a.length-1]&&a.length>=3?[null,a,null]:G.exec(a),!e||!e[1]&&b)return!b||b.jquery?(b||c).find(a):this.constructor(b).find(a);if(e[1]){if(b=b instanceof r?b[0]:b,r.merge(this,r.parseHTML(e[1],b&&b.nodeType?b.ownerDocument||b:d,!0)),C.test(e[1])&&r.isPlainObject(b))for(e in b)r.isFunction(this[e])?this[e](b[e]):this.attr(e,b[e]);return this}return f=d.getElementById(e[2]),f&&(this[0]=f,this.length=1),this}return a.nodeType?(this[0]=a,this.length=1,this):r.isFunction(a)?void 0!==c.ready?c.ready(a):a(r):r.makeArray(a,this)};H.prototype=r.fn,F=r(d);var I=/^(?:parents|prev(?:Until|All))/,J={children:!0,contents:!0,next:!0,prev:!0};r.fn.extend({has:function(a){var b=r(a,this),c=b.length;return this.filter(function(){for(var a=0;a-1:1===c.nodeType&&r.find.matchesSelector(c,a))){f.push(c);break}return this.pushStack(f.length>1?r.uniqueSort(f):f)},index:function(a){return a?"string"==typeof a?i.call(r(a),this[0]):i.call(this,a.jquery?a[0]:a):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(a,b){return this.pushStack(r.uniqueSort(r.merge(this.get(),r(a,b))))},addBack:function(a){return this.add(null==a?this.prevObject:this.prevObject.filter(a))}});function K(a,b){while((a=a[b])&&1!==a.nodeType);return a}r.each({parent:function(a){var b=a.parentNode;return b&&11!==b.nodeType?b:null},parents:function(a){return y(a,"parentNode")},parentsUntil:function(a,b,c){return y(a,"parentNode",c)},next:function(a){return K(a,"nextSibling")},prev:function(a){return K(a,"previousSibling")},nextAll:function(a){return y(a,"nextSibling")},prevAll:function(a){return y(a,"previousSibling")},nextUntil:function(a,b,c){return y(a,"nextSibling",c)},prevUntil:function(a,b,c){return y(a,"previousSibling",c)},siblings:function(a){return z((a.parentNode||{}).firstChild,a)},children:function(a){return z(a.firstChild)},contents:function(a){return B(a,"iframe")?a.contentDocument:(B(a,"template")&&(a=a.content||a),r.merge([],a.childNodes))}},function(a,b){r.fn[a]=function(c,d){var e=r.map(this,b,c);return"Until"!==a.slice(-5)&&(d=c),d&&"string"==typeof d&&(e=r.filter(d,e)),this.length>1&&(J[a]||r.uniqueSort(e),I.test(a)&&e.reverse()),this.pushStack(e)}});var L=/[^\x20\t\r\n\f]+/g;function M(a){var b={};return r.each(a.match(L)||[],function(a,c){b[c]=!0}),b}r.Callbacks=function(a){a="string"==typeof a?M(a):r.extend({},a);var b,c,d,e,f=[],g=[],h=-1,i=function(){for(e=e||a.once,d=b=!0;g.length;h=-1){c=g.shift();while(++h-1)f.splice(c,1),c<=h&&h--}),this},has:function(a){return a?r.inArray(a,f)>-1:f.length>0},empty:function(){return f&&(f=[]),this},disable:function(){return e=g=[],f=c="",this},disabled:function(){return!f},lock:function(){return e=g=[],c||b||(f=c=""),this},locked:function(){return!!e},fireWith:function(a,c){return e||(c=c||[],c=[a,c.slice?c.slice():c],g.push(c),b||i()),this},fire:function(){return j.fireWith(this,arguments),this},fired:function(){return!!d}};return j};function N(a){return a}function O(a){throw a}function P(a,b,c,d){var e;try{a&&r.isFunction(e=a.promise)?e.call(a).done(b).fail(c):a&&r.isFunction(e=a.then)?e.call(a,b,c):b.apply(void 0,[a].slice(d))}catch(a){c.apply(void 0,[a])}}r.extend({Deferred:function(b){var c=[["notify","progress",r.Callbacks("memory"),r.Callbacks("memory"),2],["resolve","done",r.Callbacks("once memory"),r.Callbacks("once memory"),0,"resolved"],["reject","fail",r.Callbacks("once memory"),r.Callbacks("once memory"),1,"rejected"]],d="pending",e={state:function(){return d},always:function(){return f.done(arguments).fail(arguments),this},"catch":function(a){return e.then(null,a)},pipe:function(){var a=arguments;return r.Deferred(function(b){r.each(c,function(c,d){var e=r.isFunction(a[d[4]])&&a[d[4]];f[d[1]](function(){var a=e&&e.apply(this,arguments);a&&r.isFunction(a.promise)?a.promise().progress(b.notify).done(b.resolve).fail(b.reject):b[d[0]+"With"](this,e?[a]:arguments)})}),a=null}).promise()},then:function(b,d,e){var f=0;function g(b,c,d,e){return function(){var h=this,i=arguments,j=function(){var a,j;if(!(b=f&&(d!==O&&(h=void 0,i=[a]),c.rejectWith(h,i))}};b?k():(r.Deferred.getStackHook&&(k.stackTrace=r.Deferred.getStackHook()),a.setTimeout(k))}}return r.Deferred(function(a){c[0][3].add(g(0,a,r.isFunction(e)?e:N,a.notifyWith)),c[1][3].add(g(0,a,r.isFunction(b)?b:N)),c[2][3].add(g(0,a,r.isFunction(d)?d:O))}).promise()},promise:function(a){return null!=a?r.extend(a,e):e}},f={};return r.each(c,function(a,b){var g=b[2],h=b[5];e[b[1]]=g.add,h&&g.add(function(){d=h},c[3-a][2].disable,c[0][2].lock),g.add(b[3].fire),f[b[0]]=function(){return f[b[0]+"With"](this===f?void 0:this,arguments),this},f[b[0]+"With"]=g.fireWith}),e.promise(f),b&&b.call(f,f),f},when:function(a){var b=arguments.length,c=b,d=Array(c),e=f.call(arguments),g=r.Deferred(),h=function(a){return function(c){d[a]=this,e[a]=arguments.length>1?f.call(arguments):c,--b||g.resolveWith(d,e)}};if(b<=1&&(P(a,g.done(h(c)).resolve,g.reject,!b),"pending"===g.state()||r.isFunction(e[c]&&e[c].then)))return g.then();while(c--)P(e[c],h(c),g.reject);return g.promise()}});var Q=/^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/;r.Deferred.exceptionHook=function(b,c){a.console&&a.console.warn&&b&&Q.test(b.name)&&a.console.warn("jQuery.Deferred exception: "+b.message,b.stack,c)},r.readyException=function(b){a.setTimeout(function(){throw b})};var R=r.Deferred();r.fn.ready=function(a){return R.then(a)["catch"](function(a){r.readyException(a)}),this},r.extend({isReady:!1,readyWait:1,ready:function(a){(a===!0?--r.readyWait:r.isReady)||(r.isReady=!0,a!==!0&&--r.readyWait>0||R.resolveWith(d,[r]))}}),r.ready.then=R.then;function S(){d.removeEventListener("DOMContentLoaded",S), +a.removeEventListener("load",S),r.ready()}"complete"===d.readyState||"loading"!==d.readyState&&!d.documentElement.doScroll?a.setTimeout(r.ready):(d.addEventListener("DOMContentLoaded",S),a.addEventListener("load",S));var T=function(a,b,c,d,e,f,g){var h=0,i=a.length,j=null==c;if("object"===r.type(c)){e=!0;for(h in c)T(a,b,h,c[h],!0,f,g)}else if(void 0!==d&&(e=!0,r.isFunction(d)||(g=!0),j&&(g?(b.call(a,d),b=null):(j=b,b=function(a,b,c){return j.call(r(a),c)})),b))for(;h1,null,!0)},removeData:function(a){return this.each(function(){X.remove(this,a)})}}),r.extend({queue:function(a,b,c){var d;if(a)return b=(b||"fx")+"queue",d=W.get(a,b),c&&(!d||Array.isArray(c)?d=W.access(a,b,r.makeArray(c)):d.push(c)),d||[]},dequeue:function(a,b){b=b||"fx";var c=r.queue(a,b),d=c.length,e=c.shift(),f=r._queueHooks(a,b),g=function(){r.dequeue(a,b)};"inprogress"===e&&(e=c.shift(),d--),e&&("fx"===b&&c.unshift("inprogress"),delete f.stop,e.call(a,g,f)),!d&&f&&f.empty.fire()},_queueHooks:function(a,b){var c=b+"queueHooks";return W.get(a,c)||W.access(a,c,{empty:r.Callbacks("once memory").add(function(){W.remove(a,[b+"queue",c])})})}}),r.fn.extend({queue:function(a,b){var c=2;return"string"!=typeof a&&(b=a,a="fx",c--),arguments.length\x20\t\r\n\f]+)/i,la=/^$|\/(?:java|ecma)script/i,ma={option:[1,""],thead:[1,"","
"],col:[2,"","
"],tr:[2,"","
"],td:[3,"","
"],_default:[0,"",""]};ma.optgroup=ma.option,ma.tbody=ma.tfoot=ma.colgroup=ma.caption=ma.thead,ma.th=ma.td;function na(a,b){var c;return c="undefined"!=typeof a.getElementsByTagName?a.getElementsByTagName(b||"*"):"undefined"!=typeof a.querySelectorAll?a.querySelectorAll(b||"*"):[],void 0===b||b&&B(a,b)?r.merge([a],c):c}function oa(a,b){for(var c=0,d=a.length;c-1)e&&e.push(f);else if(j=r.contains(f.ownerDocument,f),g=na(l.appendChild(f),"script"),j&&oa(g),c){k=0;while(f=g[k++])la.test(f.type||"")&&c.push(f)}return l}!function(){var a=d.createDocumentFragment(),b=a.appendChild(d.createElement("div")),c=d.createElement("input");c.setAttribute("type","radio"),c.setAttribute("checked","checked"),c.setAttribute("name","t"),b.appendChild(c),o.checkClone=b.cloneNode(!0).cloneNode(!0).lastChild.checked,b.innerHTML="",o.noCloneChecked=!!b.cloneNode(!0).lastChild.defaultValue}();var ra=d.documentElement,sa=/^key/,ta=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,ua=/^([^.]*)(?:\.(.+)|)/;function va(){return!0}function wa(){return!1}function xa(){try{return d.activeElement}catch(a){}}function ya(a,b,c,d,e,f){var g,h;if("object"==typeof b){"string"!=typeof c&&(d=d||c,c=void 0);for(h in b)ya(a,h,c,d,b[h],f);return a}if(null==d&&null==e?(e=c,d=c=void 0):null==e&&("string"==typeof c?(e=d,d=void 0):(e=d,d=c,c=void 0)),e===!1)e=wa;else if(!e)return a;return 1===f&&(g=e,e=function(a){return r().off(a),g.apply(this,arguments)},e.guid=g.guid||(g.guid=r.guid++)),a.each(function(){r.event.add(this,b,e,d,c)})}r.event={global:{},add:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,n,o,p,q=W.get(a);if(q){c.handler&&(f=c,c=f.handler,e=f.selector),e&&r.find.matchesSelector(ra,e),c.guid||(c.guid=r.guid++),(i=q.events)||(i=q.events={}),(g=q.handle)||(g=q.handle=function(b){return"undefined"!=typeof r&&r.event.triggered!==b.type?r.event.dispatch.apply(a,arguments):void 0}),b=(b||"").match(L)||[""],j=b.length;while(j--)h=ua.exec(b[j])||[],n=p=h[1],o=(h[2]||"").split(".").sort(),n&&(l=r.event.special[n]||{},n=(e?l.delegateType:l.bindType)||n,l=r.event.special[n]||{},k=r.extend({type:n,origType:p,data:d,handler:c,guid:c.guid,selector:e,needsContext:e&&r.expr.match.needsContext.test(e),namespace:o.join(".")},f),(m=i[n])||(m=i[n]=[],m.delegateCount=0,l.setup&&l.setup.call(a,d,o,g)!==!1||a.addEventListener&&a.addEventListener(n,g)),l.add&&(l.add.call(a,k),k.handler.guid||(k.handler.guid=c.guid)),e?m.splice(m.delegateCount++,0,k):m.push(k),r.event.global[n]=!0)}},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,n,o,p,q=W.hasData(a)&&W.get(a);if(q&&(i=q.events)){b=(b||"").match(L)||[""],j=b.length;while(j--)if(h=ua.exec(b[j])||[],n=p=h[1],o=(h[2]||"").split(".").sort(),n){l=r.event.special[n]||{},n=(d?l.delegateType:l.bindType)||n,m=i[n]||[],h=h[2]&&new RegExp("(^|\\.)"+o.join("\\.(?:.*\\.|)")+"(\\.|$)"),g=f=m.length;while(f--)k=m[f],!e&&p!==k.origType||c&&c.guid!==k.guid||h&&!h.test(k.namespace)||d&&d!==k.selector&&("**"!==d||!k.selector)||(m.splice(f,1),k.selector&&m.delegateCount--,l.remove&&l.remove.call(a,k));g&&!m.length&&(l.teardown&&l.teardown.call(a,o,q.handle)!==!1||r.removeEvent(a,n,q.handle),delete i[n])}else for(n in i)r.event.remove(a,n+b[j],c,d,!0);r.isEmptyObject(i)&&W.remove(a,"handle events")}},dispatch:function(a){var b=r.event.fix(a),c,d,e,f,g,h,i=new Array(arguments.length),j=(W.get(this,"events")||{})[b.type]||[],k=r.event.special[b.type]||{};for(i[0]=b,c=1;c=1))for(;j!==this;j=j.parentNode||this)if(1===j.nodeType&&("click"!==a.type||j.disabled!==!0)){for(f=[],g={},c=0;c-1:r.find(e,this,null,[j]).length),g[e]&&f.push(d);f.length&&h.push({elem:j,handlers:f})}return j=this,i\x20\t\r\n\f]*)[^>]*)\/>/gi,Aa=/\s*$/g;function Ea(a,b){return B(a,"table")&&B(11!==b.nodeType?b:b.firstChild,"tr")?r(">tbody",a)[0]||a:a}function Fa(a){return a.type=(null!==a.getAttribute("type"))+"/"+a.type,a}function Ga(a){var b=Ca.exec(a.type);return b?a.type=b[1]:a.removeAttribute("type"),a}function Ha(a,b){var c,d,e,f,g,h,i,j;if(1===b.nodeType){if(W.hasData(a)&&(f=W.access(a),g=W.set(b,f),j=f.events)){delete g.handle,g.events={};for(e in j)for(c=0,d=j[e].length;c1&&"string"==typeof q&&!o.checkClone&&Ba.test(q))return a.each(function(e){var f=a.eq(e);s&&(b[0]=q.call(this,e,f.html())),Ja(f,b,c,d)});if(m&&(e=qa(b,a[0].ownerDocument,!1,a,d),f=e.firstChild,1===e.childNodes.length&&(e=f),f||d)){for(h=r.map(na(e,"script"),Fa),i=h.length;l")},clone:function(a,b,c){var d,e,f,g,h=a.cloneNode(!0),i=r.contains(a.ownerDocument,a);if(!(o.noCloneChecked||1!==a.nodeType&&11!==a.nodeType||r.isXMLDoc(a)))for(g=na(h),f=na(a),d=0,e=f.length;d0&&oa(g,!i&&na(a,"script")),h},cleanData:function(a){for(var b,c,d,e=r.event.special,f=0;void 0!==(c=a[f]);f++)if(U(c)){if(b=c[W.expando]){if(b.events)for(d in b.events)e[d]?r.event.remove(c,d):r.removeEvent(c,d,b.handle);c[W.expando]=void 0}c[X.expando]&&(c[X.expando]=void 0)}}}),r.fn.extend({detach:function(a){return Ka(this,a,!0)},remove:function(a){return Ka(this,a)},text:function(a){return T(this,function(a){return void 0===a?r.text(this):this.empty().each(function(){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||(this.textContent=a)})},null,a,arguments.length)},append:function(){return Ja(this,arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=Ea(this,a);b.appendChild(a)}})},prepend:function(){return Ja(this,arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=Ea(this,a);b.insertBefore(a,b.firstChild)}})},before:function(){return Ja(this,arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this)})},after:function(){return Ja(this,arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this.nextSibling)})},empty:function(){for(var a,b=0;null!=(a=this[b]);b++)1===a.nodeType&&(r.cleanData(na(a,!1)),a.textContent="");return this},clone:function(a,b){return a=null!=a&&a,b=null==b?a:b,this.map(function(){return r.clone(this,a,b)})},html:function(a){return T(this,function(a){var b=this[0]||{},c=0,d=this.length;if(void 0===a&&1===b.nodeType)return b.innerHTML;if("string"==typeof a&&!Aa.test(a)&&!ma[(ka.exec(a)||["",""])[1].toLowerCase()]){a=r.htmlPrefilter(a);try{for(;c1)}});function _a(a,b,c,d,e){return new _a.prototype.init(a,b,c,d,e)}r.Tween=_a,_a.prototype={constructor:_a,init:function(a,b,c,d,e,f){this.elem=a,this.prop=c,this.easing=e||r.easing._default,this.options=b,this.start=this.now=this.cur(),this.end=d,this.unit=f||(r.cssNumber[c]?"":"px")},cur:function(){var a=_a.propHooks[this.prop];return a&&a.get?a.get(this):_a.propHooks._default.get(this)},run:function(a){var b,c=_a.propHooks[this.prop];return this.options.duration?this.pos=b=r.easing[this.easing](a,this.options.duration*a,0,1,this.options.duration):this.pos=b=a,this.now=(this.end-this.start)*b+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),c&&c.set?c.set(this):_a.propHooks._default.set(this),this}},_a.prototype.init.prototype=_a.prototype,_a.propHooks={_default:{get:function(a){var b;return 1!==a.elem.nodeType||null!=a.elem[a.prop]&&null==a.elem.style[a.prop]?a.elem[a.prop]:(b=r.css(a.elem,a.prop,""),b&&"auto"!==b?b:0)},set:function(a){r.fx.step[a.prop]?r.fx.step[a.prop](a):1!==a.elem.nodeType||null==a.elem.style[r.cssProps[a.prop]]&&!r.cssHooks[a.prop]?a.elem[a.prop]=a.now:r.style(a.elem,a.prop,a.now+a.unit)}}},_a.propHooks.scrollTop=_a.propHooks.scrollLeft={set:function(a){a.elem.nodeType&&a.elem.parentNode&&(a.elem[a.prop]=a.now)}},r.easing={linear:function(a){return a},swing:function(a){return.5-Math.cos(a*Math.PI)/2},_default:"swing"},r.fx=_a.prototype.init,r.fx.step={};var ab,bb,cb=/^(?:toggle|show|hide)$/,db=/queueHooks$/;function eb(){bb&&(d.hidden===!1&&a.requestAnimationFrame?a.requestAnimationFrame(eb):a.setTimeout(eb,r.fx.interval),r.fx.tick())}function fb(){return a.setTimeout(function(){ab=void 0}),ab=r.now()}function gb(a,b){var c,d=0,e={height:a};for(b=b?1:0;d<4;d+=2-b)c=ca[d],e["margin"+c]=e["padding"+c]=a;return b&&(e.opacity=e.width=a),e}function hb(a,b,c){for(var d,e=(kb.tweeners[b]||[]).concat(kb.tweeners["*"]),f=0,g=e.length;f1)},removeAttr:function(a){return this.each(function(){r.removeAttr(this,a)})}}),r.extend({attr:function(a,b,c){var d,e,f=a.nodeType;if(3!==f&&8!==f&&2!==f)return"undefined"==typeof a.getAttribute?r.prop(a,b,c):(1===f&&r.isXMLDoc(a)||(e=r.attrHooks[b.toLowerCase()]||(r.expr.match.bool.test(b)?lb:void 0)),void 0!==c?null===c?void r.removeAttr(a,b):e&&"set"in e&&void 0!==(d=e.set(a,c,b))?d:(a.setAttribute(b,c+""),c):e&&"get"in e&&null!==(d=e.get(a,b))?d:(d=r.find.attr(a,b), +null==d?void 0:d))},attrHooks:{type:{set:function(a,b){if(!o.radioValue&&"radio"===b&&B(a,"input")){var c=a.value;return a.setAttribute("type",b),c&&(a.value=c),b}}}},removeAttr:function(a,b){var c,d=0,e=b&&b.match(L);if(e&&1===a.nodeType)while(c=e[d++])a.removeAttribute(c)}}),lb={set:function(a,b,c){return b===!1?r.removeAttr(a,c):a.setAttribute(c,c),c}},r.each(r.expr.match.bool.source.match(/\w+/g),function(a,b){var c=mb[b]||r.find.attr;mb[b]=function(a,b,d){var e,f,g=b.toLowerCase();return d||(f=mb[g],mb[g]=e,e=null!=c(a,b,d)?g:null,mb[g]=f),e}});var nb=/^(?:input|select|textarea|button)$/i,ob=/^(?:a|area)$/i;r.fn.extend({prop:function(a,b){return T(this,r.prop,a,b,arguments.length>1)},removeProp:function(a){return this.each(function(){delete this[r.propFix[a]||a]})}}),r.extend({prop:function(a,b,c){var d,e,f=a.nodeType;if(3!==f&&8!==f&&2!==f)return 1===f&&r.isXMLDoc(a)||(b=r.propFix[b]||b,e=r.propHooks[b]),void 0!==c?e&&"set"in e&&void 0!==(d=e.set(a,c,b))?d:a[b]=c:e&&"get"in e&&null!==(d=e.get(a,b))?d:a[b]},propHooks:{tabIndex:{get:function(a){var b=r.find.attr(a,"tabindex");return b?parseInt(b,10):nb.test(a.nodeName)||ob.test(a.nodeName)&&a.href?0:-1}}},propFix:{"for":"htmlFor","class":"className"}}),o.optSelected||(r.propHooks.selected={get:function(a){var b=a.parentNode;return b&&b.parentNode&&b.parentNode.selectedIndex,null},set:function(a){var b=a.parentNode;b&&(b.selectedIndex,b.parentNode&&b.parentNode.selectedIndex)}}),r.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){r.propFix[this.toLowerCase()]=this});function pb(a){var b=a.match(L)||[];return b.join(" ")}function qb(a){return a.getAttribute&&a.getAttribute("class")||""}r.fn.extend({addClass:function(a){var b,c,d,e,f,g,h,i=0;if(r.isFunction(a))return this.each(function(b){r(this).addClass(a.call(this,b,qb(this)))});if("string"==typeof a&&a){b=a.match(L)||[];while(c=this[i++])if(e=qb(c),d=1===c.nodeType&&" "+pb(e)+" "){g=0;while(f=b[g++])d.indexOf(" "+f+" ")<0&&(d+=f+" ");h=pb(d),e!==h&&c.setAttribute("class",h)}}return this},removeClass:function(a){var b,c,d,e,f,g,h,i=0;if(r.isFunction(a))return this.each(function(b){r(this).removeClass(a.call(this,b,qb(this)))});if(!arguments.length)return this.attr("class","");if("string"==typeof a&&a){b=a.match(L)||[];while(c=this[i++])if(e=qb(c),d=1===c.nodeType&&" "+pb(e)+" "){g=0;while(f=b[g++])while(d.indexOf(" "+f+" ")>-1)d=d.replace(" "+f+" "," ");h=pb(d),e!==h&&c.setAttribute("class",h)}}return this},toggleClass:function(a,b){var c=typeof a;return"boolean"==typeof b&&"string"===c?b?this.addClass(a):this.removeClass(a):r.isFunction(a)?this.each(function(c){r(this).toggleClass(a.call(this,c,qb(this),b),b)}):this.each(function(){var b,d,e,f;if("string"===c){d=0,e=r(this),f=a.match(L)||[];while(b=f[d++])e.hasClass(b)?e.removeClass(b):e.addClass(b)}else void 0!==a&&"boolean"!==c||(b=qb(this),b&&W.set(this,"__className__",b),this.setAttribute&&this.setAttribute("class",b||a===!1?"":W.get(this,"__className__")||""))})},hasClass:function(a){var b,c,d=0;b=" "+a+" ";while(c=this[d++])if(1===c.nodeType&&(" "+pb(qb(c))+" ").indexOf(b)>-1)return!0;return!1}});var rb=/\r/g;r.fn.extend({val:function(a){var b,c,d,e=this[0];{if(arguments.length)return d=r.isFunction(a),this.each(function(c){var e;1===this.nodeType&&(e=d?a.call(this,c,r(this).val()):a,null==e?e="":"number"==typeof e?e+="":Array.isArray(e)&&(e=r.map(e,function(a){return null==a?"":a+""})),b=r.valHooks[this.type]||r.valHooks[this.nodeName.toLowerCase()],b&&"set"in b&&void 0!==b.set(this,e,"value")||(this.value=e))});if(e)return b=r.valHooks[e.type]||r.valHooks[e.nodeName.toLowerCase()],b&&"get"in b&&void 0!==(c=b.get(e,"value"))?c:(c=e.value,"string"==typeof c?c.replace(rb,""):null==c?"":c)}}}),r.extend({valHooks:{option:{get:function(a){var b=r.find.attr(a,"value");return null!=b?b:pb(r.text(a))}},select:{get:function(a){var b,c,d,e=a.options,f=a.selectedIndex,g="select-one"===a.type,h=g?null:[],i=g?f+1:e.length;for(d=f<0?i:g?f:0;d-1)&&(c=!0);return c||(a.selectedIndex=-1),f}}}}),r.each(["radio","checkbox"],function(){r.valHooks[this]={set:function(a,b){if(Array.isArray(b))return a.checked=r.inArray(r(a).val(),b)>-1}},o.checkOn||(r.valHooks[this].get=function(a){return null===a.getAttribute("value")?"on":a.value})});var sb=/^(?:focusinfocus|focusoutblur)$/;r.extend(r.event,{trigger:function(b,c,e,f){var g,h,i,j,k,m,n,o=[e||d],p=l.call(b,"type")?b.type:b,q=l.call(b,"namespace")?b.namespace.split("."):[];if(h=i=e=e||d,3!==e.nodeType&&8!==e.nodeType&&!sb.test(p+r.event.triggered)&&(p.indexOf(".")>-1&&(q=p.split("."),p=q.shift(),q.sort()),k=p.indexOf(":")<0&&"on"+p,b=b[r.expando]?b:new r.Event(p,"object"==typeof b&&b),b.isTrigger=f?2:3,b.namespace=q.join("."),b.rnamespace=b.namespace?new RegExp("(^|\\.)"+q.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,b.result=void 0,b.target||(b.target=e),c=null==c?[b]:r.makeArray(c,[b]),n=r.event.special[p]||{},f||!n.trigger||n.trigger.apply(e,c)!==!1)){if(!f&&!n.noBubble&&!r.isWindow(e)){for(j=n.delegateType||p,sb.test(j+p)||(h=h.parentNode);h;h=h.parentNode)o.push(h),i=h;i===(e.ownerDocument||d)&&o.push(i.defaultView||i.parentWindow||a)}g=0;while((h=o[g++])&&!b.isPropagationStopped())b.type=g>1?j:n.bindType||p,m=(W.get(h,"events")||{})[b.type]&&W.get(h,"handle"),m&&m.apply(h,c),m=k&&h[k],m&&m.apply&&U(h)&&(b.result=m.apply(h,c),b.result===!1&&b.preventDefault());return b.type=p,f||b.isDefaultPrevented()||n._default&&n._default.apply(o.pop(),c)!==!1||!U(e)||k&&r.isFunction(e[p])&&!r.isWindow(e)&&(i=e[k],i&&(e[k]=null),r.event.triggered=p,e[p](),r.event.triggered=void 0,i&&(e[k]=i)),b.result}},simulate:function(a,b,c){var d=r.extend(new r.Event,c,{type:a,isSimulated:!0});r.event.trigger(d,null,b)}}),r.fn.extend({trigger:function(a,b){return this.each(function(){r.event.trigger(a,b,this)})},triggerHandler:function(a,b){var c=this[0];if(c)return r.event.trigger(a,b,c,!0)}}),r.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(a,b){r.fn[b]=function(a,c){return arguments.length>0?this.on(b,null,a,c):this.trigger(b)}}),r.fn.extend({hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)}}),o.focusin="onfocusin"in a,o.focusin||r.each({focus:"focusin",blur:"focusout"},function(a,b){var c=function(a){r.event.simulate(b,a.target,r.event.fix(a))};r.event.special[b]={setup:function(){var d=this.ownerDocument||this,e=W.access(d,b);e||d.addEventListener(a,c,!0),W.access(d,b,(e||0)+1)},teardown:function(){var d=this.ownerDocument||this,e=W.access(d,b)-1;e?W.access(d,b,e):(d.removeEventListener(a,c,!0),W.remove(d,b))}}});var tb=a.location,ub=r.now(),vb=/\?/;r.parseXML=function(b){var c;if(!b||"string"!=typeof b)return null;try{c=(new a.DOMParser).parseFromString(b,"text/xml")}catch(d){c=void 0}return c&&!c.getElementsByTagName("parsererror").length||r.error("Invalid XML: "+b),c};var wb=/\[\]$/,xb=/\r?\n/g,yb=/^(?:submit|button|image|reset|file)$/i,zb=/^(?:input|select|textarea|keygen)/i;function Ab(a,b,c,d){var e;if(Array.isArray(b))r.each(b,function(b,e){c||wb.test(a)?d(a,e):Ab(a+"["+("object"==typeof e&&null!=e?b:"")+"]",e,c,d)});else if(c||"object"!==r.type(b))d(a,b);else for(e in b)Ab(a+"["+e+"]",b[e],c,d)}r.param=function(a,b){var c,d=[],e=function(a,b){var c=r.isFunction(b)?b():b;d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(null==c?"":c)};if(Array.isArray(a)||a.jquery&&!r.isPlainObject(a))r.each(a,function(){e(this.name,this.value)});else for(c in a)Ab(c,a[c],b,e);return d.join("&")},r.fn.extend({serialize:function(){return r.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var a=r.prop(this,"elements");return a?r.makeArray(a):this}).filter(function(){var a=this.type;return this.name&&!r(this).is(":disabled")&&zb.test(this.nodeName)&&!yb.test(a)&&(this.checked||!ja.test(a))}).map(function(a,b){var c=r(this).val();return null==c?null:Array.isArray(c)?r.map(c,function(a){return{name:b.name,value:a.replace(xb,"\r\n")}}):{name:b.name,value:c.replace(xb,"\r\n")}}).get()}});var Bb=/%20/g,Cb=/#.*$/,Db=/([?&])_=[^&]*/,Eb=/^(.*?):[ \t]*([^\r\n]*)$/gm,Fb=/^(?:about|app|app-storage|.+-extension|file|res|widget):$/,Gb=/^(?:GET|HEAD)$/,Hb=/^\/\//,Ib={},Jb={},Kb="*/".concat("*"),Lb=d.createElement("a");Lb.href=tb.href;function Mb(a){return function(b,c){"string"!=typeof b&&(c=b,b="*");var d,e=0,f=b.toLowerCase().match(L)||[];if(r.isFunction(c))while(d=f[e++])"+"===d[0]?(d=d.slice(1)||"*",(a[d]=a[d]||[]).unshift(c)):(a[d]=a[d]||[]).push(c)}}function Nb(a,b,c,d){var e={},f=a===Jb;function g(h){var i;return e[h]=!0,r.each(a[h]||[],function(a,h){var j=h(b,c,d);return"string"!=typeof j||f||e[j]?f?!(i=j):void 0:(b.dataTypes.unshift(j),g(j),!1)}),i}return g(b.dataTypes[0])||!e["*"]&&g("*")}function Ob(a,b){var c,d,e=r.ajaxSettings.flatOptions||{};for(c in b)void 0!==b[c]&&((e[c]?a:d||(d={}))[c]=b[c]);return d&&r.extend(!0,a,d),a}function Pb(a,b,c){var d,e,f,g,h=a.contents,i=a.dataTypes;while("*"===i[0])i.shift(),void 0===d&&(d=a.mimeType||b.getResponseHeader("Content-Type"));if(d)for(e in h)if(h[e]&&h[e].test(d)){i.unshift(e);break}if(i[0]in c)f=i[0];else{for(e in c){if(!i[0]||a.converters[e+" "+i[0]]){f=e;break}g||(g=e)}f=f||g}if(f)return f!==i[0]&&i.unshift(f),c[f]}function Qb(a,b,c,d){var e,f,g,h,i,j={},k=a.dataTypes.slice();if(k[1])for(g in a.converters)j[g.toLowerCase()]=a.converters[g];f=k.shift();while(f)if(a.responseFields[f]&&(c[a.responseFields[f]]=b),!i&&d&&a.dataFilter&&(b=a.dataFilter(b,a.dataType)),i=f,f=k.shift())if("*"===f)f=i;else if("*"!==i&&i!==f){if(g=j[i+" "+f]||j["* "+f],!g)for(e in j)if(h=e.split(" "),h[1]===f&&(g=j[i+" "+h[0]]||j["* "+h[0]])){g===!0?g=j[e]:j[e]!==!0&&(f=h[0],k.unshift(h[1]));break}if(g!==!0)if(g&&a["throws"])b=g(b);else try{b=g(b)}catch(l){return{state:"parsererror",error:g?l:"No conversion from "+i+" to "+f}}}return{state:"success",data:b}}r.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:tb.href,type:"GET",isLocal:Fb.test(tb.protocol),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":Kb,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/\bxml\b/,html:/\bhtml/,json:/\bjson\b/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":JSON.parse,"text xml":r.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(a,b){return b?Ob(Ob(a,r.ajaxSettings),b):Ob(r.ajaxSettings,a)},ajaxPrefilter:Mb(Ib),ajaxTransport:Mb(Jb),ajax:function(b,c){"object"==typeof b&&(c=b,b=void 0),c=c||{};var e,f,g,h,i,j,k,l,m,n,o=r.ajaxSetup({},c),p=o.context||o,q=o.context&&(p.nodeType||p.jquery)?r(p):r.event,s=r.Deferred(),t=r.Callbacks("once memory"),u=o.statusCode||{},v={},w={},x="canceled",y={readyState:0,getResponseHeader:function(a){var b;if(k){if(!h){h={};while(b=Eb.exec(g))h[b[1].toLowerCase()]=b[2]}b=h[a.toLowerCase()]}return null==b?null:b},getAllResponseHeaders:function(){return k?g:null},setRequestHeader:function(a,b){return null==k&&(a=w[a.toLowerCase()]=w[a.toLowerCase()]||a,v[a]=b),this},overrideMimeType:function(a){return null==k&&(o.mimeType=a),this},statusCode:function(a){var b;if(a)if(k)y.always(a[y.status]);else for(b in a)u[b]=[u[b],a[b]];return this},abort:function(a){var b=a||x;return e&&e.abort(b),A(0,b),this}};if(s.promise(y),o.url=((b||o.url||tb.href)+"").replace(Hb,tb.protocol+"//"),o.type=c.method||c.type||o.method||o.type,o.dataTypes=(o.dataType||"*").toLowerCase().match(L)||[""],null==o.crossDomain){j=d.createElement("a");try{j.href=o.url,j.href=j.href,o.crossDomain=Lb.protocol+"//"+Lb.host!=j.protocol+"//"+j.host}catch(z){o.crossDomain=!0}}if(o.data&&o.processData&&"string"!=typeof o.data&&(o.data=r.param(o.data,o.traditional)),Nb(Ib,o,c,y),k)return y;l=r.event&&o.global,l&&0===r.active++&&r.event.trigger("ajaxStart"),o.type=o.type.toUpperCase(),o.hasContent=!Gb.test(o.type),f=o.url.replace(Cb,""),o.hasContent?o.data&&o.processData&&0===(o.contentType||"").indexOf("application/x-www-form-urlencoded")&&(o.data=o.data.replace(Bb,"+")):(n=o.url.slice(f.length),o.data&&(f+=(vb.test(f)?"&":"?")+o.data,delete o.data),o.cache===!1&&(f=f.replace(Db,"$1"),n=(vb.test(f)?"&":"?")+"_="+ub++ +n),o.url=f+n),o.ifModified&&(r.lastModified[f]&&y.setRequestHeader("If-Modified-Since",r.lastModified[f]),r.etag[f]&&y.setRequestHeader("If-None-Match",r.etag[f])),(o.data&&o.hasContent&&o.contentType!==!1||c.contentType)&&y.setRequestHeader("Content-Type",o.contentType),y.setRequestHeader("Accept",o.dataTypes[0]&&o.accepts[o.dataTypes[0]]?o.accepts[o.dataTypes[0]]+("*"!==o.dataTypes[0]?", "+Kb+"; q=0.01":""):o.accepts["*"]);for(m in o.headers)y.setRequestHeader(m,o.headers[m]);if(o.beforeSend&&(o.beforeSend.call(p,y,o)===!1||k))return y.abort();if(x="abort",t.add(o.complete),y.done(o.success),y.fail(o.error),e=Nb(Jb,o,c,y)){if(y.readyState=1,l&&q.trigger("ajaxSend",[y,o]),k)return y;o.async&&o.timeout>0&&(i=a.setTimeout(function(){y.abort("timeout")},o.timeout));try{k=!1,e.send(v,A)}catch(z){if(k)throw z;A(-1,z)}}else A(-1,"No Transport");function A(b,c,d,h){var j,m,n,v,w,x=c;k||(k=!0,i&&a.clearTimeout(i),e=void 0,g=h||"",y.readyState=b>0?4:0,j=b>=200&&b<300||304===b,d&&(v=Pb(o,y,d)),v=Qb(o,v,y,j),j?(o.ifModified&&(w=y.getResponseHeader("Last-Modified"),w&&(r.lastModified[f]=w),w=y.getResponseHeader("etag"),w&&(r.etag[f]=w)),204===b||"HEAD"===o.type?x="nocontent":304===b?x="notmodified":(x=v.state,m=v.data,n=v.error,j=!n)):(n=x,!b&&x||(x="error",b<0&&(b=0))),y.status=b,y.statusText=(c||x)+"",j?s.resolveWith(p,[m,x,y]):s.rejectWith(p,[y,x,n]),y.statusCode(u),u=void 0,l&&q.trigger(j?"ajaxSuccess":"ajaxError",[y,o,j?m:n]),t.fireWith(p,[y,x]),l&&(q.trigger("ajaxComplete",[y,o]),--r.active||r.event.trigger("ajaxStop")))}return y},getJSON:function(a,b,c){return r.get(a,b,c,"json")},getScript:function(a,b){return r.get(a,void 0,b,"script")}}),r.each(["get","post"],function(a,b){r[b]=function(a,c,d,e){return r.isFunction(c)&&(e=e||d,d=c,c=void 0),r.ajax(r.extend({url:a,type:b,dataType:e,data:c,success:d},r.isPlainObject(a)&&a))}}),r._evalUrl=function(a){return r.ajax({url:a,type:"GET",dataType:"script",cache:!0,async:!1,global:!1,"throws":!0})},r.fn.extend({wrapAll:function(a){var b;return this[0]&&(r.isFunction(a)&&(a=a.call(this[0])),b=r(a,this[0].ownerDocument).eq(0).clone(!0),this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstElementChild)a=a.firstElementChild;return a}).append(this)),this},wrapInner:function(a){return r.isFunction(a)?this.each(function(b){r(this).wrapInner(a.call(this,b))}):this.each(function(){var b=r(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){var b=r.isFunction(a);return this.each(function(c){r(this).wrapAll(b?a.call(this,c):a)})},unwrap:function(a){return this.parent(a).not("body").each(function(){r(this).replaceWith(this.childNodes)}),this}}),r.expr.pseudos.hidden=function(a){return!r.expr.pseudos.visible(a)},r.expr.pseudos.visible=function(a){return!!(a.offsetWidth||a.offsetHeight||a.getClientRects().length)},r.ajaxSettings.xhr=function(){try{return new a.XMLHttpRequest}catch(b){}};var Rb={0:200,1223:204},Sb=r.ajaxSettings.xhr();o.cors=!!Sb&&"withCredentials"in Sb,o.ajax=Sb=!!Sb,r.ajaxTransport(function(b){var c,d;if(o.cors||Sb&&!b.crossDomain)return{send:function(e,f){var g,h=b.xhr();if(h.open(b.type,b.url,b.async,b.username,b.password),b.xhrFields)for(g in b.xhrFields)h[g]=b.xhrFields[g];b.mimeType&&h.overrideMimeType&&h.overrideMimeType(b.mimeType),b.crossDomain||e["X-Requested-With"]||(e["X-Requested-With"]="XMLHttpRequest");for(g in e)h.setRequestHeader(g,e[g]);c=function(a){return function(){c&&(c=d=h.onload=h.onerror=h.onabort=h.onreadystatechange=null,"abort"===a?h.abort():"error"===a?"number"!=typeof h.status?f(0,"error"):f(h.status,h.statusText):f(Rb[h.status]||h.status,h.statusText,"text"!==(h.responseType||"text")||"string"!=typeof h.responseText?{binary:h.response}:{text:h.responseText},h.getAllResponseHeaders()))}},h.onload=c(),d=h.onerror=c("error"),void 0!==h.onabort?h.onabort=d:h.onreadystatechange=function(){4===h.readyState&&a.setTimeout(function(){c&&d()})},c=c("abort");try{h.send(b.hasContent&&b.data||null)}catch(i){if(c)throw i}},abort:function(){c&&c()}}}),r.ajaxPrefilter(function(a){a.crossDomain&&(a.contents.script=!1)}),r.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/\b(?:java|ecma)script\b/},converters:{"text script":function(a){return r.globalEval(a),a}}}),r.ajaxPrefilter("script",function(a){void 0===a.cache&&(a.cache=!1),a.crossDomain&&(a.type="GET")}),r.ajaxTransport("script",function(a){if(a.crossDomain){var b,c;return{send:function(e,f){b=r(" + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +
+

API documentation

+

This section contains auto-generated API documentation for AppTools.

+ +
+ + +
+
+
+
+
+ +

Previous topic

+

The selection service

+

Next topic

+

apptools

+

This Page

+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/api/apptools.appscripting.action.html b/4.5/api/apptools.appscripting.action.html similarity index 100% rename from api/apptools.appscripting.action.html rename to 4.5/api/apptools.appscripting.action.html diff --git a/api/apptools.appscripting.html b/4.5/api/apptools.appscripting.html similarity index 100% rename from api/apptools.appscripting.html rename to 4.5/api/apptools.appscripting.html diff --git a/api/apptools.help.help_plugin.action.html b/4.5/api/apptools.help.help_plugin.action.html similarity index 100% rename from api/apptools.help.help_plugin.action.html rename to 4.5/api/apptools.help.help_plugin.action.html diff --git a/api/apptools.help.help_plugin.html b/4.5/api/apptools.help.help_plugin.html similarity index 100% rename from api/apptools.help.help_plugin.html rename to 4.5/api/apptools.help.help_plugin.html diff --git a/api/apptools.help.html b/4.5/api/apptools.help.html similarity index 100% rename from api/apptools.help.html rename to 4.5/api/apptools.help.html diff --git a/4.5/api/apptools.html b/4.5/api/apptools.html new file mode 100644 index 000000000..b29d38a87 --- /dev/null +++ b/4.5/api/apptools.html @@ -0,0 +1,596 @@ + + + + + + + apptools package — Apptools Documentation + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +
+

apptools package

+
+

Subpackages

+
+ +
+
+
+

Module contents

+
+
+ + +
+
+
+
+
+ +

Table of Contents

+ + +

Previous topic

+

apptools

+

Next topic

+

apptools.appscripting package

+

This Page

+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/4.5/api/apptools.io.h5.html b/4.5/api/apptools.io.h5.html new file mode 100644 index 000000000..163444cf8 --- /dev/null +++ b/4.5/api/apptools.io.h5.html @@ -0,0 +1,775 @@ + + + + + + + apptools.io.h5 package — Apptools Documentation + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+ +
+ + +
+
+ +
+
+ +
+

apptools.io.h5 package

+
+

Submodules

+
+
+

apptools.io.h5.dict_node module

+
+
+apptools.io.h5.dict_node.ARRAY_PROXY_KEY = '__array__'
+

The key name which identifies array objects in the JSON dict.

+
+ +
+
+class apptools.io.h5.dict_node.H5DictNode(h5_group, auto_flush=True)[source]
+

Bases: object

+

Dictionary-like node interface.

+

Data for the dict is stored as a JSON file in a PyTables FileNode. This +allows easy storage of Python objects, such as dictionaries and lists of +different data types.

+

Note that this is implemented using a group-node assuming that arrays are +valid inputs and will be stored as H5 array nodes.

+ +++ + + + +
Parameters:
    +
  • h5_group (H5Group instance) – Group node which will be used as a dictionary store.
  • +
  • auto_flush (bool) – If True, write data to disk whenever the dict data is altered. +Otherwise, call flush() explicitly to write data to disk.
  • +
+
+
+
+classmethod add_to_h5file(h5, node_path, data=None, **kwargs)[source]
+

Add dict node to an H5 file at the specified path.

+ +++ + + + +
Parameters:
    +
  • h5 (H5File) – The H5 file where the dictionary data will be stored.
  • +
  • node_path (str) – Path to node where data is stored (e.g. ‘/path/to/my_dict’)
  • +
  • data (dict) – Data for initialization, if desired.
  • +
+
+
+ +
+
+data
+
+ +
+
+flush()[source]
+

Write buffered data to disk.

+
+ +
+
+classmethod is_dict_node(pytables_node)[source]
+

Return True if PyTables node looks like an H5DictNode.

+

NOTE: That this returns False if the node is an H5DictNode instance, +since the input node should be a normal PyTables Group node.

+
+ +
+
+keys()[source]
+
+ +
+ +
+
+

apptools.io.h5.file module

+
+
+class apptools.io.h5.file.H5Attrs(node_attrs)[source]
+

Bases: collections.abc.MutableMapping

+

An attributes dictionary for an h5 node.

+

This intercepts __setitem__ so that python sequences can be converted to +numpy arrays. This helps preserve the readability of our HDF5 files by +other (non-python) programs.

+
+
+get(k[, d]) → D[k] if k in D, else d. d defaults to None.[source]
+
+ +
+
+items() → a set-like object providing a view on D's items[source]
+
+ +
+
+keys() → a set-like object providing a view on D's keys[source]
+
+ +
+
+values() → an object providing a view on D's values[source]
+
+ +
+ +
+
+class apptools.io.h5.file.H5File(filename, mode='r+', delete_existing=False, auto_groups=True, auto_open=True, h5filters=None)[source]
+

Bases: collections.abc.Mapping

+

File object for HDF5 files.

+

This class wraps PyTables to provide a cleaner, but only implements an +interface for accessing arrays.

+ +++ + + + +
Parameters:
    +
  • filename (str or a tables.File instance) – Filename for an HDF5 file, or a PyTables File object.
  • +
  • mode (str) –

    Mode to open the file:

    +
    +
    ’r’ : Read-only +‘w’ : Write; create new file (an existing file would be deleted). +‘a’ : Read and write to file; create if not existing +‘r+’: Read and write to file; must already exist
    +
  • +
  • delete_existing (bool) – If True, an existing node will be deleted when a create_* method is +called. Otherwise, a ValueError will be raise.
  • +
  • auto_groups (bool) – If True, create_array will automatically create parent groups.
  • +
  • auto_open (bool) – If True, open the file automatically on initialization. Otherwise, +you can call H5File.open() explicitly after initialization.
  • +
  • chunked (bool) – If True, the default behavior of create_array will be a chunked +array (see PyTables create_carray).
  • +
+
+
+
+close()[source]
+
+ +
+
+create_array(node_path, array_or_shape, dtype=None, chunked=False, extendable=False, **kwargs)[source]
+

Create node to store an array.

+ +++ + + + +
Parameters:
    +
  • node_path (str) – PyTable node path; e.g. ‘/path/to/node’.
  • +
  • array_or_shape (array or shape tuple) – Array or shape tuple for an array. If given a shape tuple, the +dtype parameter must also specified.
  • +
  • dtype (str or numpy.dtype) – Data type of array. Only necessary if array_or_shape is a shape.
  • +
  • chunked (bool) – Controls whether the array is chunked.
  • +
  • extendable ({None | bool}) – Controls whether the array is extendable.
  • +
  • kwargs (key/value pairs) – Keyword args passed to PyTables File.create_(c|e)array.
  • +
+
+
+ +
+
+create_dict(node_path, data=None, **kwargs)[source]
+

Create dict node at the specified path.

+ +++ + + + +
Parameters:
    +
  • node_path (str) – Path to node where data is stored (e.g. ‘/path/to/my_dict’)
  • +
  • data (dict) – Data for initialization, if desired.
  • +
+
+
+ +
+
+create_group(group_path, **kwargs)[source]
+

Create group.

+ +++ + + + +
Parameters:
    +
  • group_path (str) – PyTable group path; e.g. ‘/path/to/group’.
  • +
  • kwargs (key/value pairs) – Keyword args passed to PyTables File.create_group.
  • +
+
+
+ +
+
+create_table(node_path, description, **kwargs)[source]
+

Create table node at the specified path.

+ +++ + + + +
Parameters:
    +
  • node_path (str) – Path to node where data is stored (e.g. ‘/path/to/my_dict’)
  • +
  • description (dict or numpy dtype object) – The description of the columns in the table. This is either a dict +of column name -> dtype items or a numpy record array dtype. For +more information, see the documentation for Table in pytables.
  • +
+
+
+ +
+
+exists_error = "'{}' exists in '{}'; set `delete_existing` attribute to True to overwrite existing calculations."
+
+ +
+
+is_open
+
+ +
+
+iteritems(path='/')[source]
+

Iterate over node paths and nodes of the h5 file.

+
+ +
+
+classmethod join_path(*args)[source]
+

Join parts of an h5 path.

+

For example, the 3 argmuments ‘path’, ‘to’, ‘node’ will return +‘/path/to/node’.

+ +++ + + + +
Parameters:args (str) – Parts of path to be joined.
+
+ +
+
+open()[source]
+
+ +
+
+remove_group(group_path, **kwargs)[source]
+

Remove group

+ +++ + + + +
Parameters:group_path (str) – PyTable group path; e.g. ‘/path/to/group’.
+
+ +
+
+remove_node(node_path)[source]
+

Remove node

+ +++ + + + +
Parameters:node_path (str) – PyTable node path; e.g. ‘/path/to/node’.
+
+ +
+
+root
+
+ +
+
+classmethod split_path(node_path)[source]
+

Split node path returning the base path and node name.

+

For example: ‘/path/to/node’ will return ‘/path/to’ and ‘node’

+ +++ + + + +
Parameters:node_path (str) – PyTable node path; e.g. ‘/path/to/node’.
+
+ +
+ +
+
+class apptools.io.h5.file.H5Group(pytables_group)[source]
+

Bases: collections.abc.Mapping

+

A group node in an H5File.

+

This is a thin wrapper around PyTables’ Group object to expose attributes +and maintain the dict interface of H5File.

+
+
+children_names
+
+ +
+
+create_array(node_subpath, array_or_shape, dtype=None, chunked=False, extendable=False, **kwargs)[source]
+

** H5Group wrapper for H5File.create_array: ** +Note that the first argument is a nodepath relative to the group, rather than +an absolute path. Below is the original docstring:

+
+

Create node to store an array.

+
+
+
node_path : str
+
PyTable node path; e.g. ‘/path/to/node’.
+
array_or_shape : array or shape tuple
+
Array or shape tuple for an array. If given a shape tuple, the +dtype parameter must also specified.
+
dtype : str or numpy.dtype
+
Data type of array. Only necessary if array_or_shape is a shape.
+
chunked : bool
+
Controls whether the array is chunked.
+
extendable : {None | bool}
+
Controls whether the array is extendable.
+
kwargs : key/value pairs
+
Keyword args passed to PyTables File.create_(c|e)array.
+
+
+
+
+ +
+
+create_dict(node_subpath, data=None, **kwargs)[source]
+

** H5Group wrapper for H5File.create_dict: ** +Note that the first argument is a nodepath relative to the group, rather than +an absolute path. Below is the original docstring:

+
+

Create dict node at the specified path.

+
+
+
node_path : str
+
Path to node where data is stored (e.g. ‘/path/to/my_dict’)
+
data : dict
+
Data for initialization, if desired.
+
+
+
+
+ +
+
+create_group(group_subpath, delete_existing=False, **kwargs)[source]
+

** H5Group wrapper for H5File.create_group: ** +Note that the first argument is a nodepath relative to the group, rather than +an absolute path. Below is the original docstring:

+
+

Create group.

+
+
+
group_path : str
+
PyTable group path; e.g. ‘/path/to/group’.
+
kwargs : key/value pairs
+
Keyword args passed to PyTables File.create_group.
+
+
+
+
+ +
+
+create_table(node_subpath, description, *args, **kwargs)[source]
+

** H5Group wrapper for H5File.create_table: ** +Note that the first argument is a nodepath relative to the group, rather than +an absolute path. Below is the original docstring:

+
+

Create table node at the specified path.

+
+
+
node_path : str
+
Path to node where data is stored (e.g. ‘/path/to/my_dict’)
+
description : dict or numpy dtype object
+
The description of the columns in the table. This is either a dict +of column name -> dtype items or a numpy record array dtype. For +more information, see the documentation for Table in pytables.
+
+
+
+
+ +
+
+filename
+
+ +
+
+iter_groups()[source]
+

Iterate over H5Group nodes that are children of this group.

+
+ +
+
+name
+
+ +
+
+pathname
+
+ +
+
+remove_group(group_subpath, **kwargs)[source]
+

** H5Group wrapper for H5File.remove_group: ** +Note that the first argument is a nodepath relative to the group, rather than +an absolute path. Below is the original docstring:

+
+

Remove group

+
+
+
group_path : str
+
PyTable group path; e.g. ‘/path/to/group’.
+
+
+
+
+ +
+
+remove_node(node_subpath, **kwargs)[source]
+

** H5Group wrapper for H5File.remove_node: ** +Note that the first argument is a nodepath relative to the group, rather than +an absolute path. Below is the original docstring:

+
+

Remove node

+
+
+
node_path : str
+
PyTable node path; e.g. ‘/path/to/node’.
+
+
+
+
+ +
+
+root
+
+ +
+
+subgroup_names
+
+ +
+ +
+
+apptools.io.h5.file.get_atom(dtype)[source]
+

Return a PyTables Atom for the given dtype or dtype string.

+
+ +
+
+apptools.io.h5.file.h5_group_wrapper(original)[source]
+
+ +
+
+apptools.io.h5.file.iterator_length(iterator)[source]
+
+ +
+
+

apptools.io.h5.table_node module

+
+
+class apptools.io.h5.table_node.H5TableNode(node)[source]
+

Bases: object

+

A wrapper for PyTables Table nodes.

+ +++ + + + +
Parameters:node (tables.Table instance) – An H5 node which is a pytables.Table or H5TableNode instance
+
+
+classmethod add_to_h5file(h5, node_path, description, **kwargs)[source]
+

Add table node to an H5 file at the specified path.

+ +++ + + + +
Parameters:
    +
  • h5 (H5File) – The H5 file where the table node will be stored.
  • +
  • node_path (str) – Path to node where data is stored (e.g. ‘/path/to/my_table’)
  • +
  • description (list of tuples or numpy dtype object) – The description of the columns in the table. This is either a list +of (column name, dtype, [, shape or itemsize]) tuples or a numpy +record array dtype. For more information, see the documentation for +Table in PyTables.
  • +
  • **kwargs (dict) – Additional keyword arguments to pass to pytables.File.create_table
  • +
+
+
+ +
+
+append(data)[source]
+

Add some data to the table.

+ +++ + + + +
Parameters:data (dict) – A dictionary of column name -> values items
+
+ +
+
+classmethod is_table_node(pytables_node)[source]
+

Return True if pytables_node is a pytables.Table or a H5TableNode.

+
+ +
+
+ix
+

Return an object which provides access to row data.

+
+ +
+
+keys()[source]
+
+ +
+
+to_dataframe()[source]
+

Return table data as a pandas DataFrame.

+

XXX: This does not work if the table contains a multidimensional column

+
+ +
+ +
+
+

apptools.io.h5.utils module

+
+
+apptools.io.h5.utils.open_h5file(filename, mode='r+', **kwargs)[source]
+

Context manager for reading an HDF5 file as an H5File object.

+ +++ + + + +
Parameters:
    +
  • filename (str) – HDF5 file name.
  • +
  • mode (str) –

    Mode to open the file:

    +

    ’r’ : Read-only +‘w’ : Write; create new file (an existing file would be deleted). +‘a’ : Read and write to file; create if not existing +‘r+’: Read and write to file; must already exist

    +
  • +
  • H5File for additional keyword arguments. (See) –
  • +
+
+
+ +
+
+

Module contents

+
+
+ + +
+
+
+ +
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/4.5/api/apptools.io.html b/4.5/api/apptools.io.html new file mode 100644 index 000000000..7bcdea83d --- /dev/null +++ b/4.5/api/apptools.io.html @@ -0,0 +1,256 @@ + + + + + + + apptools.io package — Apptools Documentation + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +
+

apptools.io package

+ +
+

Submodules

+
+
+

apptools.io.api module

+
+
+

apptools.io.file module

+

A representation of files and folders in a file system.

+
+
+class apptools.io.file.File(path, **traits)[source]
+

Bases: traits.has_traits.HasPrivateTraits

+

A representation of files and folders in a file system.

+
+
+copy(destination)[source]
+

Copies this file/folder.

+
+ +
+
+create_file(contents='')[source]
+

Creates a file at this path.

+
+ +
+
+create_folder()[source]
+

Creates a folder at this path.

+

All intermediate folders MUST already exist.

+
+ +
+
+create_folders()[source]
+

Creates a folder at this path.

+

This will attempt to create any missing intermediate folders.

+
+ +
+
+create_package()[source]
+

Creates a package at this path.

+

All intermediate folders/packages MUST already exist.

+
+ +
+
+delete()[source]
+

Deletes this file/folder.

+

Does nothing if the file/folder does not exist.

+
+ +
+
+make_writeable()[source]
+

Attempt to make the file/folder writeable.

+
+ +
+
+move(destination)[source]
+

Moves this file/folder.

+
+ +
+ +
+
+

Module contents

+

Provides an abstraction for files and folders in a file system. +Part of the AppTools project of the Enthought Tool Suite.

+
+
+ + +
+
+
+
+
+ +

Table of Contents

+ + +

Previous topic

+

apptools.help.help_plugin.action package

+

Next topic

+

apptools.io.h5 package

+

This Page

+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/4.5/api/apptools.logger.agent.html b/4.5/api/apptools.logger.agent.html new file mode 100644 index 000000000..32534d42e --- /dev/null +++ b/4.5/api/apptools.logger.agent.html @@ -0,0 +1,286 @@ + + + + + + + apptools.logger.agent package — Apptools Documentation + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+ +
+ + +
+
+ +
+
+ +
+

apptools.logger.agent package

+
+

Submodules

+
+
+

apptools.logger.agent.attachments module

+

Attach relevant project files.

+

FIXME: there are no public project plugins for Envisage 3, yet. In any case, +this stuff should not be hard-coded, but extensible via extension points. The +code remains here because we can reuse the zip utility code in that extensible +rewrite.

+
+
+class apptools.logger.agent.attachments.Attachments(message, **traits)[source]
+

Bases: traits.has_traits.HasTraits

+
+
+package_any_relevant_files()[source]
+
+ +
+
+package_single_project()[source]
+
+ +
+
+package_workspace()[source]
+
+ +
+ +
+
+

apptools.logger.agent.quality_agent_mailer module

+
+
+apptools.logger.agent.quality_agent_mailer.create_email_message(fromaddr, toaddrs, ccaddrs, subject, priority, include_project=False, stack_trace='', comments='')[source]
+
+ +
+
+

apptools.logger.agent.quality_agent_view module

+
+
+class apptools.logger.agent.quality_agent_view.QualityAgentView(*args, **kwargs)[source]
+

Bases: pyface.base_toolkit.Unimplemented

+
+
+cc_address = <traits.trait_types.Str object>
+
+ +
+
+comments = <traits.trait_types.Str object>
+
+ +
+
+from_address = <traits.trait_types.Str object>
+
+ +
+
+help_id = 'enlib|HID_Quality_Agent_Dlg'
+
+ +
+
+include_userdata
+

alias of traits.trait_types.Any

+
+ +
+
+msg = <traits.trait_types.Str object>
+
+ +
+
+priority = <traits.trait_types.Str object>
+
+ +
+
+service = <traits.trait_types.Any object>
+
+ +
+
+size = <traits.trait_types.Tuple object>
+
+ +
+
+smtp_server = <traits.trait_types.Str object>
+
+ +
+
+subject = <traits.trait_types.Str object>
+
+ +
+
+title = <traits.trait_types.Str object>
+
+ +
+
+to_address = <traits.trait_types.Str object>
+
+ +
+ +
+
+

Module contents

+

lib.apptools.logger.agent

+
+
+ + +
+
+
+ +
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/4.5/api/apptools.logger.html b/4.5/api/apptools.logger.html new file mode 100644 index 000000000..754b0e181 --- /dev/null +++ b/4.5/api/apptools.logger.html @@ -0,0 +1,442 @@ + + + + + + + apptools.logger package — Apptools Documentation + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +
+

apptools.logger package

+ +
+

Submodules

+
+
+

apptools.logger.api module

+
+
+

apptools.logger.custom_excepthook module

+
+
+apptools.logger.custom_excepthook.custom_excepthook(type, value, traceback)[source]
+

Pass on the exception to the logging system.

+
+ +
+
+

apptools.logger.filtering_handler module

+

A log handler that allows filtering of messages by origin.

+
+
+class apptools.logger.filtering_handler.FilteringHandler(include=None, exclude=None)[source]
+

Bases: logging.Handler

+

A log handler that allows filtering of messages by origin.

+

Example

+
from apptools.logger.api import DebugHandler, logger
+
+handler = FilteringHandler(
+    include = {
+        'envisage.core' : True
+    },
+
+    exclude = {
+        'envisage.core.application' : False
+    }
+)
+
+logger.addHandler(handler)
+
+
+

Notes

+

The boolean value specified for each name in the include and exclude +dictionaries indicates whether or not the include or exclude should pertain +to any sub-packages and modules.

+

The above example includes all log messages from anything contained in, or +under the ‘envisage.core’ package, EXCEPT for any log messages +from the ‘envisage.core.application’ module.

+
+
+emit(record)[source]
+

Emits a log record.

+
+ +
+
+filtered_emit(record)[source]
+

Emits a log record if it has not been filtered.

+
+ +
+ +
+
+

apptools.logger.log_point module

+

Prints a stack trace every time it is called but does not halt execution +of the application.

+

Copied from Uche Ogbuji’s blog

+
+
+apptools.logger.log_point.log_point(msg='\n')[source]
+
+ +
+
+

apptools.logger.log_queue_handler module

+
+
+class apptools.logger.log_queue_handler.LogQueueHandler(size=1000)[source]
+

Bases: logging.Handler

+

Buffers up the log messages so that we can display them later. +This is important on startup when log messages are generated before +the ui has started. By putting them in this queue we can display +them once the ui is ready.

+
+
+emit(record)[source]
+

Actually this is more like an enqueue than an emit().

+
+ +
+
+get()[source]
+
+ +
+
+has_new_records()[source]
+
+ +
+
+reset()[source]
+
+ +
+ +
+
+

apptools.logger.logger module

+

Convenience functions for creating logging handlers etc.

+
+
+class apptools.logger.logger.LogFileHandler(path, maxBytes=1000000, backupCount=3, level=None, formatter=None)[source]
+

Bases: logging.handlers.RotatingFileHandler

+

The default log file handler.

+
+ +
+
+apptools.logger.logger.add_log_queue_handler(logger, level=None, formatter=None)[source]
+

Adds a queueing log handler to a logger.

+
+ +
+
+apptools.logger.logger.create_log_file_handler(path, maxBytes=1000000, backupCount=3, level=None, formatter=None)[source]
+

Creates a log file handler.

+

This is just a convenience function to make it easy to create the same +kind of handlers across applications.

+

It sets the handler’s formatter to the default formatter, and its logging +level to the default logging level.

+
+ +
+
+

apptools.logger.null_handler module

+

A null log handler.

+
+
+class apptools.logger.null_handler.NullHandler(level=0)[source]
+

Bases: logging.Handler

+

A null log handler.

+

This is a quick hack so that we can start to refactor the ‘logger’ +module since it used to add actual handlers at module load time.

+

Now we only add this handler so that people using just the ETS library and +not one of our applications won’t see the warning about ‘no handlers’.

+
+
+emit(record)[source]
+

Emits a log record.

+
+ +
+ +
+
+

apptools.logger.ring_buffer module

+

Copied from Python Cookbook.

+
+
+class apptools.logger.ring_buffer.RingBuffer(size_max)[source]
+

Bases: object

+
+
+append(x)[source]
+

append an element at the end of the buffer

+
+ +
+
+get()[source]
+

return a list of elements from the oldest to the newest

+
+ +
+ +
+
+class apptools.logger.ring_buffer.RingBufferFull(n)[source]
+

Bases: object

+
+
+append(x)[source]
+
+ +
+
+get()[source]
+
+ +
+ +
+
+

apptools.logger.util module

+

Utility functions.

+

fixme: I don’t like random collections of utility functions! Where should +this go?

+
+
+apptools.logger.util.get_module_name(filename)[source]
+

Get the fully qualified module name for a filename.

+

For example, if the filename is

+

/enthought/envisage/core/core_plugin_definition.py

+

this method would return

+

envisage.core.core_plugin_definition

+
+ +
+
+apptools.logger.util.get_module_name_from_zip(filename)[source]
+
+ +
+
+apptools.logger.util.get_zip_path(filename)[source]
+

Returns the path to the zip file contained in the filename.

+

fixme: An example here would help.

+
+ +
+
+apptools.logger.util.is_zip_path(path)[source]
+

Returns True if the path refers to a zip file.

+
+ +
+
+apptools.logger.util.path_exists_in_zip(zfile, path)[source]
+
+ +
+
+

Module contents

+

Convenience functions for creating logging handlers. +Part of the EnthoughtBase project.

+
+
+ + +
+
+
+ +
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/4.5/api/apptools.logger.plugin.html b/4.5/api/apptools.logger.plugin.html new file mode 100644 index 000000000..247f5e15c --- /dev/null +++ b/4.5/api/apptools.logger.plugin.html @@ -0,0 +1,275 @@ + + + + + + + apptools.logger.plugin package — Apptools Documentation + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+ +
+ + +
+
+ +
+
+ +
+

apptools.logger.plugin package

+ +
+

Submodules

+
+
+

apptools.logger.plugin.logger_plugin module

+

Logger plugin.

+
+
+class apptools.logger.plugin.logger_plugin.LoggerPlugin[source]
+

Bases: envisage.plugin.Plugin

+

Logger plugin.

+
+
+MAIL_FILES = 'apptools.logger.plugin.mail_files'
+
+ +
+
+PREFERENCES = 'envisage.preferences'
+
+ +
+
+PREFERENCES_PAGES = 'envisage.ui.workbench.preferences_pages'
+
+ +
+
+VIEWS = 'envisage.ui.workbench.views'
+
+ +
+
+start()[source]
+

Starts the plugin.

+
+ +
+
+stop()[source]
+

Stops the plugin.

+
+ +
+ +
+
+

apptools.logger.plugin.logger_preferences module

+
+
+class apptools.logger.plugin.logger_preferences.LoggerPreferences(**traits)[source]
+

Bases: apptools.preferences.preferences_helper.PreferencesHelper

+

The persistent service exposing the Logger plugin’s API.

+
+ +
+
+

apptools.logger.plugin.logger_service module

+
+
+class apptools.logger.plugin.logger_service.LoggerService[source]
+

Bases: traits.has_traits.HasTraits

+

The persistent service exposing the Logger plugin’s API.

+
+
+create_email_message(fromaddr, toaddrs, ccaddrs, subject, priority, include_userdata=False, stack_trace='', comments='', include_environment=True)[source]
+

Format a bug report email from the log files.

+
+ +
+
+save_preferences()[source]
+

Save the preferences.

+
+ +
+
+send_bug_report(smtp_server, fromaddr, toaddrs, ccaddrs, message)[source]
+

Send a bug report email.

+
+ +
+
+whole_log_text()[source]
+

Return all of the logged data as formatted text.

+
+ +
+ +
+
+

Module contents

+
+
+ + +
+
+
+ +
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/4.5/api/apptools.logger.plugin.view.html b/4.5/api/apptools.logger.plugin.view.html new file mode 100644 index 000000000..2d797113e --- /dev/null +++ b/4.5/api/apptools.logger.plugin.view.html @@ -0,0 +1,303 @@ + + + + + + + apptools.logger.plugin.view package — Apptools Documentation + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ + + + +
+
+ +
+
+ +
+

apptools.logger.plugin.view package

+
+

Submodules

+
+
+

apptools.logger.plugin.view.logger_preferences_page module

+
+
+class apptools.logger.plugin.view.logger_preferences_page.LoggerPreferencesPage(**traits)[source]
+

Bases: apptools.preferences.ui.preferences_page.PreferencesPage

+

A preference page for the logger plugin.

+
+ +
+
+

apptools.logger.plugin.view.logger_view module

+
+
+class apptools.logger.plugin.view.logger_view.LogRecordAdapter[source]
+

Bases: traitsui.tabular_adapter.TabularAdapter

+

A TabularEditor adapter for logging.LogRecord objects.

+
+
+column_widths = [80, 100, 120, -1]
+
+ +
+
+get_width(object, trait, column)[source]
+

Returns the width to use for a specified column.

+

If the value is <= 0, the column will have a default width, which is +the same as specifying a width of 0.1.

+

If the value is > 1.0, it is converted to an integer and the result is +the width of the column in pixels. This is referred to as a +fixed width column.

+

If the value is a float such that 0.0 < value <= 1.0, it is treated as +the unnormalized fraction of the available space that is to be +assigned to the column. What this means requires a little explanation.

+

To arrive at the size in pixels of the column at any given time, the +editor adds together all of the unnormalized fraction values +returned for all columns in the table to arrive at a total value. Each +unnormalized fraction is then divided by the total to create a +normalized fraction. Each column is then assigned an amount of space +in pixels equal to the maximum of 30 or its normalized fraction +multiplied by the available space. The available space is defined +as the actual width of the table minus the width of all fixed width +columns. Note that this calculation is performed each time the table is +resized in the user interface, thus allowing columns of this type to +increase or decrease their width dynamically, while leaving fixed +width columns unchanged.

+
+ +
+ +
+
+class apptools.logger.plugin.view.logger_view.LoggerView(*args, **kwargs)[source]
+

Bases: pyface.workbench.traits_ui_view.TraitsUIView

+

The Workbench View showing the list of log items.

+
+
+activated = <traits.trait_types.Instance object>
+
+ +
+
+activated_text = <traits.traits.ForwardProperty object>
+
+ +
+
+code_editor = <traitsui.editors.code_editor.ToolkitEditorFactory object>
+
+ +
+
+copy_button = <traits.trait_types.Button object>
+
+ +
+
+formatted_records = <traits.traits.ForwardProperty object>
+
+ +
+
+id = <traits.trait_types.Str object>
+
+ +
+
+log_records = <traits.trait_types.List object>
+
+ +
+
+log_records_editor = <traitsui.editors.tabular_editor.TabularEditor object>
+
+ +
+
+name = <traits.trait_types.Str object>
+
+ +
+
+reset_button = <traits.trait_types.Button object>
+
+ +
+
+service = <traits.trait_types.Instance object>
+
+ +
+
+show_button = <traits.trait_types.Button object>
+
+ +
+
+trait_view = ( Group( Item( 'log_records' object = 'object', style = 'simple', show_label = False ), Group( Item( 'reset_button' object = 'object', style = 'simple', show_label = False ), Item( 'trait_modified' object = 'object', style = 'simple' ), Item( 'show_button' object = 'object', style = 'simple', show_label = False ), Item( 'copy_button' object = 'object', style = 'simple', show_label = False ), orientation = 'horizontal', show_labels = False, object = 'object', style = 'simple' ), show_labels = False, object = 'object', style = 'simple' ) )
+
+ +
+
+update(force=False)[source]
+

Update ‘log_records’ if our handler has new records or ‘force’ is +set.

+
+ +
+ +
+
+

Module contents

+
+
+ + +
+
+
+ +
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/api/apptools.lru_cache.html b/4.5/api/apptools.lru_cache.html similarity index 100% rename from api/apptools.lru_cache.html rename to 4.5/api/apptools.lru_cache.html diff --git a/api/apptools.naming.adapter.html b/4.5/api/apptools.naming.adapter.html similarity index 100% rename from api/apptools.naming.adapter.html rename to 4.5/api/apptools.naming.adapter.html diff --git a/4.5/api/apptools.naming.html b/4.5/api/apptools.naming.html new file mode 100644 index 000000000..ed313f58a --- /dev/null +++ b/4.5/api/apptools.naming.html @@ -0,0 +1,901 @@ + + + + + + + apptools.naming package — Apptools Documentation + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +
+

apptools.naming package

+ +
+

Submodules

+
+
+

apptools.naming.address module

+

The address of a commuications endpoint.

+
+
+class apptools.naming.address.Address[source]
+

Bases: traits.has_traits.HasTraits

+

The address of a communications end-point.

+

It contains a type that describes the communication mechanism, and the +actual address content.

+
+ +
+
+

apptools.naming.api module

+
+
+

apptools.naming.binding module

+

The representation of a name-to-object binding in a context.

+
+
+class apptools.naming.binding.Binding[source]
+

Bases: traits.has_traits.HasTraits

+

The representation of a name-to-object binding in a context.

+
+ +
+
+

apptools.naming.context module

+

The base class for all naming contexts.

+
+
+class apptools.naming.context.Context[source]
+

Bases: traits.has_traits.HasTraits

+

The base class for all naming contexts.

+
+
+INITIAL_CONTEXT_FACTORY = 'apptools.naming.factory.initial'
+
+ +
+
+OBJECT_FACTORIES = 'apptools.naming.factory.object'
+
+ +
+
+STATE_FACTORIES = 'apptools.naming.factory.state'
+
+ +
+
+TYPE_MANAGER = 'apptools.naming.factory.type.manager'
+
+ +
+
+bind(name, obj, make_contexts=False)[source]
+

Binds a name to an object.

+

If ‘make_contexts’ is True then any missing intermediate contexts are +created automatically.

+
+ +
+
+create_subcontext(name)[source]
+

Creates a sub-context.

+
+ +
+
+destroy_subcontext(name)[source]
+

Destroys a sub-context.

+
+ +
+
+get_unique_name(prefix)[source]
+

Returns a name that is unique within the context.

+

The name returned will start with the specified prefix.

+
+ +
+
+is_context(name)[source]
+

Returns True if the name is bound to a context.

+
+ +
+
+list_bindings(name='')[source]
+

Lists the bindings in a context.

+
+ +
+
+list_names(name='')[source]
+

Lists the names bound in a context.

+
+ +
+
+lookup(name)[source]
+

Resolves a name relative to this context.

+
+ +
+
+lookup_binding(name)[source]
+

Looks up the binding for a name relative to this context.

+
+ +
+
+lookup_context(name)[source]
+

Resolves a name relative to this context.

+

The name MUST resolve to a context. This method is useful to return +context adapters.

+
+ +
+
+rebind(name, obj, make_contexts=False)[source]
+

Binds an object to a name that may already be bound.

+

If ‘make_contexts’ is True then any missing intermediate contexts are +created automatically.

+

The object may be a different object but may also be the same object +that is already bound to the specified name. The name may or may not be +already used. Think of this as a safer version of ‘bind’ since this +one will never raise an exception regarding a name being used.

+
+ +
+
+rename(old_name, new_name)[source]
+

Binds a new name to an object.

+
+ +
+
+search(obj)[source]
+

Returns a list of namespace names that are bound to obj.

+
+ +
+
+unbind(name)[source]
+

Unbinds a name.

+
+ +
+ +
+
+

apptools.naming.context_adapter module

+

The base class for all context adapters.

+
+
+class apptools.naming.context_adapter.ContextAdapter[source]
+

Bases: apptools.naming.context.Context

+

The base class for all context adapters.

+
+ +
+
+

apptools.naming.context_adapter_factory module

+

The base class for all context adapter factories.

+
+
+class apptools.naming.context_adapter_factory.ContextAdapterFactory[source]
+

Bases: apptools.type_manager.adapter_factory.AdapterFactory

+

The base class for all context adapter factories.

+
+ +
+
+

apptools.naming.dir_context module

+

The base class for all directory contexts.

+
+
+class apptools.naming.dir_context.DirContext[source]
+

Bases: apptools.naming.context.Context

+

The base class for all directory contexts.

+
+
+find_bindings(visitor)[source]
+

Find bindings with attributes matching criteria in visitor.

+

Visitor is a function that is passed the bindings for each level of the +heirarchy and the attribute dictionary for those bindings. The visitor +examines the bindings and dictionary and returns the bindings it is +interested in.

+
+ +
+
+get_attributes(name)[source]
+

Returns the attributes associated with a named object.

+
+ +
+
+set_attributes(name, attributes)[source]
+

Sets the attributes associated with a named object.

+
+ +
+ +
+
+

apptools.naming.dynamic_context module

+

Provider of a framework that dynamically determines the contents of a +context at the time of interaction with the contents rather than at the +time a class is written.

+

This capability is particularly useful when the object acting as a context +is part of a plug-in application – such as Envisage. In general, this +capability allows the context to be:

+
    +
  • Extendable by contributions from somewhere other than the original +code writer
  • +
  • Dynamic in that the elements it is composed of can change each time +someone interacts with the contents of the context.
  • +
+

It should be noted that this capability is explicitly different from +contexts that look at another container to determine their contents, such +as a file system context!

+

Users of this framework contribute items to a dynamic context by adding +traits to the dynamic context instance. (This addition can happen +statically through the use of a Traits Category.) The trait value is the +context item’s value and the trait definition’s metadata determines how the +item is treated within the context. The support metadata is:

+
+
context_name: A non-empty string
+
Represents the name of the item within this context. This must be +present for the trait to show up as a context item though the value +may change over time as the item gets bound to different names.
+
context_order: A float value
+
Indicates the position for the item within this context. All +dynamically contributed context items are sorted by ascending order +of this value using the standard list sort function.
+
is_context: A boolean value
+
True if the item is itself a context.
+
+
+
+class apptools.naming.dynamic_context.DynamicContext[source]
+

Bases: apptools.naming.context.Context

+

A framework that dynamically determines the contents of a context at +the time of interaction with the contents rather than at the time a +context class is written.

+

It should be noted that this capability is explicitly different from +contexts that look at another container to determine their contents, +such as a file system context!

+
+ +
+
+

apptools.naming.exception module

+

Naming exceptions.

+
+
+exception apptools.naming.exception.InvalidNameError[source]
+

Bases: apptools.naming.exception.NamingError

+

Invalid name.

+

This exception is thrown when the name passed to a naming operation does +not conform to the syntax of the naming system (or is empty etc).

+
+ +
+
+exception apptools.naming.exception.NameAlreadyBoundError[source]
+

Bases: apptools.naming.exception.NamingError

+

Name already bound.

+

This exception is thrown when an attempt is made to bind a name that is +already bound in the current context.

+
+ +
+
+exception apptools.naming.exception.NameNotFoundError[source]
+

Bases: apptools.naming.exception.NamingError

+

Name not found.

+

This exception is thrown when a component of a name cannot be resolved +because it is not bound in the current context.

+
+ +
+
+exception apptools.naming.exception.NamingError[source]
+

Bases: Exception

+

Base class for all naming exceptions.

+
+ +
+
+exception apptools.naming.exception.NotContextError[source]
+

Bases: apptools.naming.exception.NamingError

+

Not a context.

+

This exception is thrown when a naming operation has reached a point where +a context is required to continue the operation, but the resolved object +is not a context.

+
+ +
+
+exception apptools.naming.exception.OperationNotSupportedError[source]
+

Bases: apptools.naming.exception.NamingError

+

The context does support the requested operation.

+
+ +
+
+

apptools.naming.initial_context module

+

The starting point for performing naming operations.

+
+
+apptools.naming.initial_context.InitialContext(environment)[source]
+

Creates an initial context for beginning name resolution.

+
+ +
+
+

apptools.naming.initial_context_factory module

+

The base class for all initial context factories.

+
+
+class apptools.naming.initial_context_factory.InitialContextFactory[source]
+

Bases: traits.has_traits.HasTraits

+

The base class for all initial context factories.

+
+
+get_initial_context(environment)[source]
+

Creates an initial context for beginning name resolution.

+
+ +
+ +
+
+

apptools.naming.naming_event module

+

The event fired by the tree model when it changes.

+
+
+class apptools.naming.naming_event.NamingEvent[source]
+

Bases: traits.has_traits.HasTraits

+

Information about tree model changes.

+
+ +
+
+

apptools.naming.naming_manager module

+

The naming manager.

+
+
+class apptools.naming.naming_manager.NamingManager[source]
+

Bases: traits.has_traits.HasTraits

+

The naming manager.

+
+
+get_object_instance(info, name, context)[source]
+

Creates an object using the specified state information.

+

The naming manager asks the context for its list of OBJECT factories +and calls them one by one until it gets a non-None result, indicating +that the factory recognised the information and created an object.

+

If none of the factories recognize the state information (or if the +context has no factories) then the state information itself is +returned.

+
+ +
+
+get_state_to_bind(obj, name, context)[source]
+

Returns the state of an object for binding.

+

The naming manager asks the context for its list of STATE factories +and then calls them one by one until it gets a non-None result +indicating that the factory recognised the object and created state +information for it.

+

If none of the factories recognize the object (or if the context +has no factories) then the object itself is returned.

+
+ +
+ +
+
+

apptools.naming.object_factory module

+

The base class for all object factories.

+
+
+class apptools.naming.object_factory.ObjectFactory[source]
+

Bases: traits.has_traits.HasTraits

+

The base class for all object factories.

+

An object factory accepts some information about how to create an object +(such as a reference) and returns an instance of that object.

+
+
+get_object_instance(state, name, context)[source]
+

Creates an object using the specified state information.

+

Returns None if the factory cannot create the object (ie. it does not +recognise the state passed to it).

+
+ +
+ +
+
+

apptools.naming.object_serializer module

+

The base class for all object serializers.

+
+
+class apptools.naming.object_serializer.ObjectSerializer[source]
+

Bases: traits.has_traits.HasTraits

+

The base class for all object serializers.

+
+
+can_load(path)[source]
+

Returns True if the serializer can load a file.

+
+ +
+
+can_save(obj)[source]
+

Returns True if the serializer can save an object.

+
+ +
+
+load(path)[source]
+

Loads an object from a file.

+
+ +
+
+save(path, obj)[source]
+

Saves an object to a file.

+
+ +
+ +
+
+

apptools.naming.py_context module

+

A naming context for a Python namespace.

+
+
+class apptools.naming.py_context.PyContext(**traits)[source]
+

Bases: apptools.naming.context.Context, apptools.naming.referenceable.Referenceable

+

A naming context for a Python namespace.

+
+ +
+
+

apptools.naming.py_object_factory module

+

Object factory for Python namespace contexts.

+
+
+class apptools.naming.py_object_factory.PyObjectFactory[source]
+

Bases: apptools.naming.object_factory.ObjectFactory

+

Object factory for Python namespace contexts.

+
+
+get_object_instance(state, name, context)[source]
+

Creates an object using the specified state information.

+
+ +
+ +
+
+

apptools.naming.pyfs_context module

+

A Python File System context.

+
+
+class apptools.naming.pyfs_context.PyFSContext(**traits)[source]
+

Bases: apptools.naming.dir_context.DirContext, apptools.naming.referenceable.Referenceable

+

A Python File System context.

+

This context represents a directory on a local file system.

+
+
+ATTRIBUTES_FILE = '__attributes__'
+
+ +
+
+FILTERS = 'apptools.naming.pyfs.filters'
+
+ +
+
+OBJECT_SERIALIZERS = 'apptools.naming.pyfs.object.serializers'
+
+ +
+
+get_unique_name(name)[source]
+

Returns a name that is unique within the context.

+

The name returned will start with the specified prefix.

+
+ +
+
+refresh()[source]
+

Refresh the context to reflect changes in the file system.

+
+ +
+ +
+
+

apptools.naming.pyfs_context_factory module

+

Object factory for Python File System contexts.

+
+
+class apptools.naming.pyfs_context_factory.PyFSContextFactory[source]
+

Bases: apptools.naming.object_factory.ObjectFactory

+

Object factory for Python File System contexts.

+
+
+get_object_instance(state, name, context)[source]
+

Creates an object using the specified state information.

+
+ +
+ +
+
+

apptools.naming.pyfs_initial_context_factory module

+

The initial context factory for Python file system contexts.

+
+
+class apptools.naming.pyfs_initial_context_factory.PyFSInitialContextFactory[source]
+

Bases: apptools.naming.initial_context_factory.InitialContextFactory

+

The initial context factory for Python file system contexts.

+
+
+get_initial_context(environment)[source]
+

Creates an initial context for beginning name resolution.

+
+ +
+ +
+
+

apptools.naming.pyfs_object_factory module

+

Object factory for Python File System contexts.

+
+
+class apptools.naming.pyfs_object_factory.PyFSObjectFactory[source]
+

Bases: apptools.naming.object_factory.ObjectFactory

+

Object factory for Python File System contexts.

+
+
+get_object_instance(state, name, context)[source]
+

Creates an object using the specified state information.

+
+ +
+ +
+
+

apptools.naming.pyfs_state_factory module

+

State factory for Python File System contexts.

+
+
+class apptools.naming.pyfs_state_factory.PyFSStateFactory[source]
+

Bases: apptools.naming.state_factory.StateFactory

+

State factory for Python File System contexts.

+
+
+get_state_to_bind(obj, name, context)[source]
+

Returns the state of an object for binding.

+
+ +
+ +
+
+

apptools.naming.reference module

+

A reference to an object that lives outside of the naming system.

+
+
+class apptools.naming.reference.Reference[source]
+

Bases: traits.has_traits.HasPrivateTraits

+

A reference to an object that lives outside of the naming system.

+

References provide a way to store the address(s) of objects that live +outside of the naming system. A reference consists of a list of +addresses that represent a communications endpoint for the object being +referenced.

+

A reference also contains information to assist in the creation of an +instance of the object to which it refers. It contains the name of +the class that will be created and the class name and location of a +factory that will be used to do the actual instance creation.

+
+ +
+
+

apptools.naming.referenceable module

+

Base class for classes that can produce a reference to themselves.

+
+
+class apptools.naming.referenceable.Referenceable[source]
+

Bases: traits.has_traits.HasPrivateTraits

+

Base class for classes that can produce a reference to themselves.

+
+ +
+
+

apptools.naming.referenceable_state_factory module

+

State factory for referenceable objects.

+
+
+class apptools.naming.referenceable_state_factory.ReferenceableStateFactory[source]
+

Bases: apptools.naming.state_factory.StateFactory

+

State factory for referenceable objects.

+
+
+get_state_to_bind(obj, name, context)[source]
+

Returns the state of an object for binding.

+
+ +
+ +
+
+

apptools.naming.state_factory module

+

The base class for all state factories.

+
+
+class apptools.naming.state_factory.StateFactory[source]
+

Bases: traits.has_traits.HasPrivateTraits

+

The base class for all state factories.

+

A state factory accepts an object and returns some data representing the +object that is suitable for storing in a particular context.

+
+
+get_state_to_bind(obj, name, context)[source]
+

Returns the state of an object for binding.

+

Returns None if the factory cannot create the state (ie. it does not +recognise the object passed to it).

+
+ +
+ +
+
+

apptools.naming.unique_name module

+

A re-usable method for calculating a unique name given a list of existing +names.

+
+
+apptools.naming.unique_name.make_unique_name(base, existing=[], format='%s_%s')[source]
+

Return a name, unique within a context, based on the specified name.

+

base: the desired base name of the generated unique name. +existing: a sequence of the existing names to avoid returning. +format: a formatting specification for how the name is made unique.

+
+ +
+
+

Module contents

+

Manages naming contexts. Supports non-string data types and scoped +preferences. Part of the AppTools project of the Enthought Tool Suite.

+
+
+ + +
+
+
+ +
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/4.5/api/apptools.naming.trait_defs.html b/4.5/api/apptools.naming.trait_defs.html new file mode 100644 index 000000000..d1ad34696 --- /dev/null +++ b/4.5/api/apptools.naming.trait_defs.html @@ -0,0 +1,287 @@ + + + + + + + apptools.naming.trait_defs package — Apptools Documentation + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+ +
+ + +
+
+ +
+
+ +
+

apptools.naming.trait_defs package

+
+

Submodules

+
+
+

apptools.naming.trait_defs.api module

+
+
+

apptools.naming.trait_defs.naming_traits module

+
+
+class apptools.naming.trait_defs.naming_traits.NamingTraitHandler(aClass, or_none, module)[source]
+

Bases: traits.trait_handlers.TraitHandler

+
+
+find_class()[source]
+
+ +
+
+get_editor(trait)[source]
+

Returns a trait editor that allows the user to modify the trait +trait.

+ +++ + + + +
Parameters:
    +
  • trait (Trait) – The trait to be edited.
  • +
  • Description
  • +
  • -----------
  • +
  • method only needs to be specified if traits defined using this (This) –
  • +
  • handler require a non-default trait editor in trait user (trait) –
  • +
  • The default implementation of this method returns a trait (interfaces.) –
  • +
  • that allows the user to type an arbitrary string as the value. (editor) –
  • +
  • more information on trait user interfaces, refer to the *Traits UI (For) –
  • +
  • Guide*. (User) –
  • +
+
+
+ +
+
+info()[source]
+

Must return a string describing the type of value accepted by the +trait handler.

+

The string should be a phrase describing the type defined by the +TraitHandler subclass, rather than a complete sentence. For example, use +the phrase, “a square sprocket” instead of the sentence, “The value must +be a square sprocket.” The value returned by info() is combined with +other information whenever an error occurs and therefore makes more +sense to the user if the result is a phrase. The info() method is +similar in purpose and use to the info attribute of a validator +function.

+

Note that the result can include information specific to the particular +trait handler instance. For example, TraitRange instances return a +string indicating the range of values acceptable to the handler (e.g., +“an integer in the range from 1 to 9”). If the info() method is not +overridden, the default method returns the value of the ‘info_text’ +attribute.

+
+ +
+
+post_setattr(object, name, value)[source]
+
+ +
+
+resolve_class(object, name, value)[source]
+
+ +
+
+validate(object, name, value)[source]
+

Verifies whether a new value assigned to a trait attribute is valid.

+ +++ + + + + + +
Parameters:
    +
  • object (object) – The object whose attribute is being assigned.
  • +
  • name (str) – The name of the attribute being assigned.
  • +
  • value – The proposed new value for the attribute.
  • +
+
Returns:

    +
  • If the new value is valid, this method must return either the original
  • +
  • value passed to it, or an alternate value to be assigned in place of the
  • +
  • original value. Whatever value this method returns is the actual value
  • +
  • assigned to *object.name.*
  • +
  • Description
  • +
  • ———–
  • +
  • This method *must be implemented by subclasses of TraitHandler. It is*
  • +
  • called whenever a new value is assigned to a trait attribute defined
  • +
  • using this trait handler.
  • +
  • If the value received by validate() is not valid for the trait
  • +
  • attribute, the method must called the predefined error() method to
  • +
  • raise a TraitError exception
  • +
+

+
+
+ +
+
+validate_failed(object, name, value)[source]
+
+ +
+ +
+
+

Module contents

+
+
+ + +
+
+
+ +
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/api/apptools.naming.ui.html b/4.5/api/apptools.naming.ui.html similarity index 100% rename from api/apptools.naming.ui.html rename to 4.5/api/apptools.naming.ui.html diff --git a/api/apptools.permissions.action.html b/4.5/api/apptools.permissions.action.html similarity index 100% rename from api/apptools.permissions.action.html rename to 4.5/api/apptools.permissions.action.html diff --git a/api/apptools.permissions.adapters.html b/4.5/api/apptools.permissions.adapters.html similarity index 100% rename from api/apptools.permissions.adapters.html rename to 4.5/api/apptools.permissions.adapters.html diff --git a/api/apptools.permissions.default.html b/4.5/api/apptools.permissions.default.html similarity index 100% rename from api/apptools.permissions.default.html rename to 4.5/api/apptools.permissions.default.html diff --git a/api/apptools.permissions.html b/4.5/api/apptools.permissions.html similarity index 100% rename from api/apptools.permissions.html rename to 4.5/api/apptools.permissions.html diff --git a/4.5/api/apptools.persistence.html b/4.5/api/apptools.persistence.html new file mode 100644 index 000000000..ea6967ed4 --- /dev/null +++ b/4.5/api/apptools.persistence.html @@ -0,0 +1,806 @@ + + + + + + + apptools.persistence package — Apptools Documentation + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +
+

apptools.persistence package

+
+

Submodules

+
+
+

apptools.persistence.file_path module

+

Simple class to support file path objects that work well in the +context of persistent storage with the state_pickler.

+
+
+class apptools.persistence.file_path.FilePath(value='')[source]
+

Bases: object

+

This class stores two paths to the file. A relative path and +an absolute one. The absolute path is used by the end user. When +this object is pickled the state_pickler sets the relative path +relative to the file that is being generated. When unpickled, the +stored relative path is used to set the absolute path correctly +based on the path of the saved file.

+
+
+get()[source]
+

Get the path.

+
+ +
+
+set(value)[source]
+

Sets the value of the path.

+
+ +
+
+set_absolute(base_f_name)[source]
+

Sets the absolute file name for the current relative file +name with respect to the given base_f_name.

+
+ +
+
+set_relative(base_f_name)[source]
+

Sets the path relative to base_f_name. Note that +base_f_name and self.rel_pth should be valid file names +correct on the current os. The set name is a file name that +has a POSIX path.

+
+ +
+ +
+
+

apptools.persistence.project_loader module

+
+
+apptools.persistence.project_loader.load_project(pickle_filename, updater_path, application_version, protocol, max_pass=-1)[source]
+

Reads a project from a pickle file and if necessary will update it to +the latest version of the application.

+
+ +
+
+apptools.persistence.project_loader.upgrade_project(pickle_filename, updater_path, project_version, application_version, protocol, max_pass=-1)[source]
+

Repeatedly read and write the project to disk updating it one version +at a time.

+

Example the p5.project is at version 0 +The application is at version 3

+

p5.project — Update1 —> p5.project.v1 +p5.project.v1 — Update2 —> p5.project.v2 +p5.project.v2 — Update3 —> p5.project.v3 +p5.project.v3 —> loaded into app

+

The user then has the option to save the updated project as p5.project

+
+ +
+
+

apptools.persistence.spickle module

+
+
+

apptools.persistence.state_pickler module

+

This module provides code that allows one to pickle the state of a +Python object to a dictionary.

+

The motivation for this is simple. The standard Python +pickler/unpickler is best used to pickle simple objects and does not +work too well for complex code. Specifically, there are two major +problems (1) the pickle file format is not easy to edit with a text +editor and (2) when a pickle is unpickled, it creates all the +necessary objects and sets the state of these objects.

+

Issue (2) might not appear to be a problem. However, often, the +determination of the entire ‘state’ of an application requires the +knowledge of the state of many objects that are not really in the +users concern. The user would ideally like to pickle just what he +thinks is relevant. Now, given that the user is not going to save the +entire state of the application, the use of pickle is insufficient +since the state is no longer completely known (or worth knowing). The +default Unpickler recreates the objects and the typical +implementation of __setstate__ is usually to simply update the +object’s __dict__ attribute. This is inadequate because the pickled +information is taken out of the real context when it was saved.

+

The StatePickler basically pickles the ‘state’ of an object into a +large dictionary. This pickled data may be easily unpickled and +modified on the interpreter or edited with a text editor +(pprint.saferepr is a friend). The second problem is also +eliminated. When this state is unpickled using StateUnpickler, what +you get is a special dictionary (a State instance). This allows one +to navigate the state just like the original object. Its up to the +user to create any new objects and set their states using this +information. This allows for a lot of flexibility while allowing one +to save and set the state of (almost) any Python object.

+

The StateSetter class helps set the state of a known instance. When +setting the state of an instance it checks to see if there is a +__set_pure_state__ method that in turn calls StateSetter.set +appropriately.

+

Additionally, there is support for versioning. The class’ version is +obtain from the __version__ class attribute. This version along +with the versions of the bases of a class is embedded into the +metadata of the state and stored. By using version_registry.py a +user may register a handler for a particular class and module. When +the state of an object is set using StateSetter.set_state, then +these handlers are called in reverse order of their MRO. This gives +the handler an opportunity to upgrade the state depending on its +version. Builtin classes are not scanned for versions. If a class +has no version, then by default it is assumed to be -1.

+

Example:

+
>>> class A:
+...    def __init__(self):
+...        self.a = 'a'
+...
+>>> a = A()
+>>> a.a = 100
+>>> import state_pickler
+>>> s = state_pickler.dumps(a)               # Dump the state of `a`.
+>>> state = state_pickler.loads_state(s)     # Get the state back.
+>>> b = state_pickler.create_instance(state) # Create the object.
+>>> state_pickler.set_state(b, state)        # Set the object's state.
+>>> assert b.a == 100
+
+
+
+

Features

+
+
    +
  • The output is a plain old dictionary so is easy to parse, edit etc.
  • +
  • Handles references to avoid duplication.
  • +
  • Gzips Numeric arrays when dumping them.
  • +
  • Support for versioning.
  • +
+
+
+
+

Caveats

+
+
    +
  • Does not pickle a whole bunch of stuff including code objects and +functions.
  • +
  • The output is a pure dictionary and does not contain instances. So +using this as it is in __setstate__ will not work. Instead +define a __set_pure_state__ and use the StateSetter class or +the set_state function provided by this module.
  • +
+
+

Notes

+

Browsing the code from XMarshaL and pickle.py proved useful for +ideas. None of the code is taken from there though.

+
+
+class apptools.persistence.state_pickler.State(**kw)[source]
+

Bases: dict

+

Used to encapsulate the state of an instance in a very +convenient form. The ‘__metadata__’ attribute/key is a dictionary +that has class specific details like the class name, module name +etc.

+
+ +
+
+class apptools.persistence.state_pickler.StateDict(**kw)[source]
+

Bases: dict

+

Used to encapsulate a dictionary stored in a State instance. +The has_instance attribute specifies if the dict has an instance +embedded in it.

+
+ +
+
+class apptools.persistence.state_pickler.StateList(seq=None)[source]
+

Bases: list

+

Used to encapsulate a list stored in a State instance. The +has_instance attribute specifies if the list has an instance +embedded in it.

+
+ +
+
+class apptools.persistence.state_pickler.StatePickler[source]
+

Bases: object

+

Pickles the state of an object into a dictionary. The +dictionary is itself either saved as a pickled file (dump) or +pickled string (dumps). Alternatively, the dump_state method +will return the dictionary that is pickled.

+

The format of the state dict is quite strightfoward. Basic types +(bool, int, long, float, complex, None, string and unicode) are +represented as they are. Everything else is stored as a +dictionary containing metadata information on the object’s type +etc. and also the actual object in the ‘data’ key. For example:

+
>>> p = StatePickler()
+>>> p.dump_state(1)
+1
+>>> l = [1,2.0, None, [1,2,3]]
+>>> p.dump_state(l)
+{'data': [1, 2.0, None, {'data': [1, 2, 3], 'type': 'list', 'id': 1}],
+ 'id': 0,
+ 'type': 'list'}
+
+
+

Classes are also represented similarly. The state in this case is +obtained from the __getstate__ method or from the __dict__. +Here is an example:

+
>>> class A:
+...     __version__ = 1  # State version
+...     def __init__(self):
+...         self.attribute = 1
+...
+>>> a = A()
+>>> p = StatePickler()
+>>> p.dump_state(a)
+{'class_name': 'A',
+ 'data': {'data': {'attribute': 1}, 'type': 'dict', 'id': 2},
+ 'id': 0,
+ 'initargs': {'data': (), 'type': 'tuple', 'id': 1},
+ 'module': '__main__',
+ 'type': 'instance',
+ 'version': [(('A', '__main__'), 1)]}
+
+
+

When pickling data, references are taken care of. Numeric arrays +can be pickled and are stored as a gzipped base64 encoded string.

+
+
+dump(value, file)[source]
+

Pickles the state of the object (value) into the passed +file.

+
+ +
+
+dump_state(value)[source]
+

Returns a dictionary or a basic type representing the +complete state of the object (value).

+

This value is pickled by the dump and dumps methods.

+
+ +
+
+dumps(value)[source]
+

Pickles the state of the object (value) and returns a +string.

+
+ +
+ +
+
+exception apptools.persistence.state_pickler.StatePicklerError[source]
+

Bases: Exception

+
+ +
+
+class apptools.persistence.state_pickler.StateSetter[source]
+

Bases: object

+

This is a convenience class that helps a user set the +attributes of an object given its saved state. For instances it +checks to see if a __set_pure_state__ method exists and calls +that when it sets the state.

+
+
+set(obj, state, ignore=None, first=None, last=None)[source]
+

Sets the state of the object.

+

This is to be used as a means to simplify loading the state of +an object from its __setstate__ method using the dictionary +describing its state. Note that before the state is set, the +registered handlers for the particular class are called in +order to upgrade the version of the state to the latest +version.

+ +++ + + + +
Parameters:
    +
  • obj (-) – The object whose state is to be set. If this is None +(default) then the object is created.
  • +
  • state (-) – The dictionary representing the state of the object.
  • +
  • ignore (-) – The list of attributes specified in this list are ignored +and the state of these attributes are not set (this excludes +the ones specified in first and last). If one specifies +a ‘*’ then all attributes are ignored except the ones +specified in first and last.
  • +
  • first (-) – The list of attributes specified in this list are set first (in +order), before any other attributes are set.
  • +
  • last (-) – The list of attributes specified in this list are set last (in +order), after all other attributes are set.
  • +
+
+
+ +
+ +
+
+exception apptools.persistence.state_pickler.StateSetterError[source]
+

Bases: Exception

+
+ +
+
+class apptools.persistence.state_pickler.StateTuple[source]
+

Bases: tuple

+

Used to encapsulate a tuple stored in a State instance. The +has_instance attribute specifies if the tuple has an instance +embedded in it.

+
+ +
+
+class apptools.persistence.state_pickler.StateUnpickler[source]
+

Bases: object

+

Unpickles the state of an object saved using StatePickler.

+

Please note that unlike the standard Unpickler, no instances of +any user class are created. The data for the state is obtained +from the file or string, reference objects are setup to refer to +the same state value and this state is returned in the form +usually in the form of a dictionary. For example:

+
>>> class A:
+...     def __init__(self):
+...         self.attribute = 1
+...
+>>> a = A()
+>>> p = StatePickler()
+>>> s = p.dumps(a)
+>>> up = StateUnpickler()
+>>> state = up.loads_state(s)
+>>> state.__class__.__name__
+'State'
+>>> state.attribute
+1
+>>> state.__metadata__
+{'class_name': 'A',
+ 'has_instance': True,
+ 'id': 0,
+ 'initargs': (),
+ 'module': '__main__',
+ 'type': 'instance',
+ 'version': [(('A', '__main__'), -1)]}
+
+
+

Note that the state is actually a State instance and is +navigable just like the original object. The details of the +instance are stored in the __metadata__ attribute. This is +highly convenient since it is possible for someone to view and +modify the state very easily.

+
+
+load_state(file)[source]
+

Returns the state of an object loaded from the pickled data +in the given file.

+
+ +
+
+loads_state(string)[source]
+

Returns the state of an object loaded from the pickled data +in the given string.

+
+ +
+ +
+
+exception apptools.persistence.state_pickler.StateUnpicklerError[source]
+

Bases: Exception

+
+ +
+
+apptools.persistence.state_pickler.create_instance(state)[source]
+

Create an instance from the state if possible.

+
+ +
+
+apptools.persistence.state_pickler.dump(value, file)[source]
+

Pickles the state of the object (value) into the passed file +(or file name).

+
+ +
+
+apptools.persistence.state_pickler.dumps(value)[source]
+

Pickles the state of the object (value) and returns a string.

+
+ +
+
+apptools.persistence.state_pickler.get_state(obj)[source]
+

Returns the state of the object (usually as a dictionary). The +returned state may be used directy to set the state of the object +via set_state.

+
+ +
+
+apptools.persistence.state_pickler.gunzip_string(data)[source]
+

Given a gzipped string (data) this unzips the string and +returns it.

+
+ +
+
+apptools.persistence.state_pickler.gzip_string(data)[source]
+

Given a string (data) this gzips the string and returns it.

+
+ +
+
+apptools.persistence.state_pickler.load_state(file)[source]
+

Returns the state of an object loaded from the pickled data in +the given file (or file name).

+
+ +
+
+apptools.persistence.state_pickler.loads_state(string)[source]
+

Returns the state of an object loaded from the pickled data +in the given string.

+
+ +
+
+apptools.persistence.state_pickler.set_state(obj, state, ignore=None, first=None, last=None)[source]
+

Sets the state of the object.

+

This is to be used as a means to simplify loading the state of +an object from its __setstate__ method using the dictionary +describing its state. Note that before the state is set, the +registered handlers for the particular class are called in +order to upgrade the version of the state to the latest +version.

+ +++ + + + +
Parameters:
    +
  • obj (-) – The object whose state is to be set. If this is None +(default) then the object is created.
  • +
  • state (-) – The dictionary representing the state of the object.
  • +
  • ignore (-) – The list of attributes specified in this list are ignored +and the state of these attributes are not set (this excludes +the ones specified in first and last). If one specifies +a ‘*’ then all attributes are ignored except the ones +specified in first and last.
  • +
  • first (-) – The list of attributes specified in this list are set first (in +order), before any other attributes are set.
  • +
  • last (-) – The list of attributes specified in this list are set last (in +order), after all other attributes are set.
  • +
+
+
+ +
+
+apptools.persistence.state_pickler.update_state(state)[source]
+

Given the state of an object, this updates the state to the +latest version using the handlers given in the version registry. +The state is modified in-place.

+
+ +
+
+
+

apptools.persistence.updater module

+
+
+class apptools.persistence.updater.Updater[source]
+

Bases: object

+

An abstract class to provide functionality common to the updaters.

+
+
+get_latest(module, name)[source]
+

The refactorings dictionary contains mappings between old and new +module names. Since we only bump the version number one increment +there is only one possible answer.

+
+ +
+
+strip(string)[source]
+
+ +
+ +
+
+

apptools.persistence.version_registry module

+

A version registry that manages handlers for different state +versions.

+
+
+class apptools.persistence.version_registry.HandlerRegistry[source]
+

Bases: object

+

A simple version conversion handler registry. Classes register +handlers in order to convert the state version to the latest +version. When an object’s state is about to be set, the update +method of the registy is called. This in turn calls any handlers +registered for the class/module and this handler is then called +with the state and the version of the state. The state is +modified in-place by the handlers.

+
+
+register(class_name, module, handler)[source]
+

Register handler that handles versioning for class having +class name (class_name) and module name (module). The +handler function will be passed the state and its version to fix.

+
+ +
+
+unregister(class_name, module)[source]
+

Unregisters any handlers for a class and module.

+
+ +
+
+update(state)[source]
+

Updates the given state using the handlers. Note that the +state is modified in-place.

+
+ +
+ +
+
+apptools.persistence.version_registry.get_version(obj)[source]
+

Walks the class hierarchy and obtains the versions of the +various classes and returns a list of tuples of the form +((class_name, module), version) in reverse order of the MRO.

+
+ +
+
+

apptools.persistence.versioned_unpickler module

+
+
+class apptools.persistence.versioned_unpickler.NewUnpickler[source]
+

Bases: _pickle.Unpickler

+

An unpickler that implements a two-stage pickling process to make it +possible to unpickle complicated Python object hierarchies where the +unserialized state of an object depends on the state of other objects in +the same pickle.

+
+
+initialize(max_pass)[source]
+
+ +
+
+load(max_pass=-1)[source]
+

Read a pickled object representation from the open file.

+

Return the reconstituted object hierarchy specified in the file.

+
+ +
+
+classmethod load_build(obj)[source]
+
+ +
+ +
+
+class apptools.persistence.versioned_unpickler.VersionedUnpickler(file, updater=None)[source]
+

Bases: apptools.persistence.versioned_unpickler.NewUnpickler

+

This class reads in a pickled file created at revision version ‘n’ +and then applies the transforms specified in the updater class to +generate a new set of objects which are at revision version ‘n+1’.

+

I decided to keep the loading of the updater out of this generic class +because we will want updaters to be generated for each plugin’s type +of project.

+

This ensures that the VersionedUnpickler can remain ignorant about the +actual version numbers - all it needs to do is upgrade one release.

+
+
+add_updater(module, name, klass)[source]
+

If there is an updater defined for this class we will add it to the +class as the __setstate__ method.

+
+ +
+
+backup_setstate(module, klass)[source]
+

If the class has a user defined __setstate__ we back it up.

+
+ +
+
+find_class(module, name)[source]
+

Overridden method from Unpickler.

+

NB __setstate__ is not called until later.

+
+ +
+
+import_name(module, name)[source]
+

If the class is needed for the latest version of the application then +it should presumably exist.

+

If the class no longer exists then we should perhaps return +a proxy of the class.

+

If the persisted file is at v1 say and the application is at v3 then +objects that are required for v1 and v2 do not have to exist they only +need to be placeholders for the state during an upgrade.

+
+ +
+ +
+
+

Module contents

+

Supports flexible pickling and unpickling of the state of a Python object +to a dictionary. Part of the AppTools project of the Enthought Tool Suite.

+
+
+ + +
+
+
+ +
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/4.5/api/apptools.preferences.html b/4.5/api/apptools.preferences.html new file mode 100644 index 000000000..f3ddadb12 --- /dev/null +++ b/4.5/api/apptools.preferences.html @@ -0,0 +1,650 @@ + + + + + + + apptools.preferences package — Apptools Documentation + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +
+

apptools.preferences package

+ +
+

Submodules

+
+
+

apptools.preferences.api module

+
+
+

apptools.preferences.i_preferences module

+

The interface for a node in a preferences hierarchy.

+
+
+class apptools.preferences.i_preferences.IPreferences[source]
+

Bases: traits.has_traits.Interface

+

The interface for a node in a preferences hierarchy.

+
+
+clear(path='')[source]
+

Remove all preference from the node at the specified path.

+

If the path is the empty string (the default) then remove the +preferences in this node.

+

This does not affect any of the node’s children.

+

e.g. To clear the preferences out of a node directly:

+
preferences.clear()
+
+
+

Or to clear the preferences of a node at a given path:

+
preferences.clear('acme.ui')
+
+
+
+ +
+
+flush()[source]
+

Force any changes in the node to the backing store.

+

This includes any changes to the node’s descendants.

+
+ +
+
+get(path, default=None, inherit=False)[source]
+

Get the value of the preference at the specified path.

+

If no value exists for the path (or any part of the path does not +exist) then return the default value.

+

Preference values are always returned as strings.

+

e.g:

+
preferences.set('acme.ui.bgcolor', 'blue')
+preferences.get('acme.ui.bgcolor') -> 'blue'
+
+preferences.set('acme.ui.width', 100)
+preferences.get('acme.ui.width') -> '100'
+
+preferences.set('acme.ui.visible', True)
+preferences.get('acme.ui.visible') -> 'True'
+
+
+

If ‘inherit’ is True then we allow ‘inherited’ preference values.

+

e.g. If we are looking up:

+
'acme.ui.widget.bgcolor'
+
+
+

and it does not exist then we will also try:

+
'acme.ui.bgcolor'
+'acme.bgcolor'
+'bgcolor'
+
+
+

Raise a ‘ValueError’ exception if the path is the empty string.

+
+ +
+
+keys(path='')[source]
+

Return the preference keys of the node at the specified path.

+

If the path is the empty string (the default) then return the +preference keys of this node.

+

e.g:

+
keys = preferences.keys('acme.ui')
+
+
+
+ +
+
+node(path='')[source]
+

Return the node at the specified path.

+

If the path is the empty string (the default) then return this node.

+

Any missing nodes are created automatically.

+

e.g:

+
node = preferences.node('acme.ui')
+bgcolor = node.get('bgcolor')
+
+
+
+ +
+
+node_exists(path='')[source]
+

Return True if the node at the specified path exists

+

If the path is the empty string (the default) then return True.

+

e.g:

+
exists = preferences.exists('acme.ui')
+
+
+
+ +
+
+node_names(path='')[source]
+

Return the names of the children of the node at the specified path.

+

If the path is the empty string (the default) then return the names of +the children of this node.

+

e.g:

+
names = preferences.node_names('acme.ui')
+
+
+
+ +
+
+remove(path)[source]
+

Remove the preference at the specified path.

+

Does nothing if no value exists for the path (or any part of the path +does not exist.

+

Raise a ‘ValueError’ exception if the path is the empty string.

+

e.g.:

+
preferences.remove('acme.ui.bgcolor')
+
+
+
+ +
+
+set(path, value)[source]
+

Set the value of the preference at the specified path.

+

Any missing nodes are created automatically.

+

Primitive Python types can be set, but preferences are always +stored and returned as strings.

+

e.g:

+
preferences.set('acme.ui.bgcolor', 'blue')
+preferences.get('acme.ui.bgcolor') -> 'blue'
+
+preferences.set('acme.ui.width', 100)
+preferences.get('acme.ui.width') -> '100'
+
+preferences.set('acme.ui.visible', True)
+preferences.get('acme.ui.visible') -> 'True'
+
+
+

Raise a ‘ValueError’ exception if the path is the empty string.

+
+ +
+ +
+
+

apptools.preferences.package_globals module

+

Package-scope globals.

+

The default preferences node is currently used by ‘PreferencesHelper’ and +‘PreferencesBinding’ instances if no specific preferences node is set. This +makes it easy for them to access the root node of an application-wide +preferences hierarchy.

+
+
+apptools.preferences.package_globals.get_default_preferences()[source]
+

Get the default preferences node.

+
+ +
+
+apptools.preferences.package_globals.set_default_preferences(default_preferences)[source]
+

Set the default preferences node.

+
+ +
+
+

apptools.preferences.preference_binding module

+

A binding between a trait on an object and a preference value.

+
+
+class apptools.preferences.preference_binding.PreferenceBinding(**traits)[source]
+

Bases: traits.has_traits.HasTraits

+

A binding between a trait on an object and a preference value.

+
+ +
+
+apptools.preferences.preference_binding.bind_preference(obj, trait_name, preference_path, preferences=None)[source]
+

Create a new preference binding.

+
+ +
+
+

apptools.preferences.preferences module

+

The default implementation of a node in a preferences hierarchy.

+
+
+class apptools.preferences.preferences.Preferences(**traits)[source]
+

Bases: traits.has_traits.HasTraits

+

The default implementation of a node in a preferences hierarchy.

+
+
+add_preferences_listener(listener, path='')[source]
+

Add a listener for changes to a node’s preferences.

+
+ +
+
+clear(path='')[source]
+

Remove all preferences from the node at the specified path.

+
+ +
+
+dump(indent='')[source]
+

Dump the preferences hierarchy to stdout.

+
+ +
+
+flush()[source]
+

Force any changes in the node to the backing store.

+

This includes any changes to the node’s descendants.

+
+ +
+
+get(path, default=None, inherit=False)[source]
+

Get the value of the preference at the specified path.

+
+ +
+
+keys(path='')[source]
+

Return the preference keys of the node at the specified path.

+
+ +
+
+load(file_or_filename=None)[source]
+

Load preferences from a file.

+

This is a merge operation i.e. the contents of the file are added to +the node.

+

This implementation uses ‘ConfigObj’ files.

+
+ +
+
+node(path='')[source]
+

Return the node at the specified path.

+
+ +
+
+node_exists(path='')[source]
+

Return True if the node at the specified path exists.

+
+ +
+
+node_names(path='')[source]
+

Return the names of the children of the node at the specified path.

+
+ +
+
+remove(path)[source]
+

Remove the preference at the specified path.

+
+ +
+
+remove_preferences_listener(listener, path='')[source]
+

Remove a listener for changes to a node’s preferences.

+
+ +
+
+save(file_or_filename=None)[source]
+

Save the node’s preferences to a file.

+

This implementation uses ‘ConfigObj’ files.

+
+ +
+
+set(path, value)[source]
+

Set the value of the preference at the specified path.

+
+ +
+ +
+
+

apptools.preferences.preferences_helper module

+

An object that can be initialized from a preferences node.

+
+
+class apptools.preferences.preferences_helper.PreferencesHelper(**traits)[source]
+

Bases: traits.has_traits.HasTraits

+

An object that can be initialized from a preferences node.

+
+ +
+
+

apptools.preferences.scoped_preferences module

+

A preferences node that adds the notion of preferences scopes.

+
+
+class apptools.preferences.scoped_preferences.ScopedPreferences(**traits)[source]
+

Bases: apptools.preferences.preferences.Preferences

+

A preferences node that adds the notion of preferences scopes.

+

Scopes provide a way to access preferences in a precedence order, usually +depending on where they came from, for example from the command-line, +or set by the user in a preferences file, or the defaults (set by the +developer).

+

By default, this class provides two scopes - ‘application’ which is +persistent and ‘default’ which is not.

+

Path names passed to ‘ScopedPreferences’ nodes can be either:

+
    +
  1. a preference path as used in a standard ‘Preferences’ node, e.g:

    +
    'acme.widget.bgcolor'.
    +
    +
    +

    In this case the operation either takes place in the primary scope +(for operations such as ‘set’ etc), or on all scopes in precedence order +(for operations such as ‘get’ etc).

    +
  2. +
+

or

+
    +
  1. a preference path that refers to a specific scope e.g:

    +
    'default/acme.widget.bgcolor'
    +
    +
    +

    In this case the operation takes place only in the specified scope.

    +
  2. +
+

There is one drawback to this scheme. If you want to access a scope node +itself via the ‘clear’, ‘keys’, ‘node’, ‘node_exists’ or ‘node_names’ +methods then you have to append a trailing ‘/’ to the path. Without that, +the node would try to perform the operation in the primary scope.

+

e.g. To get the names of the children of the ‘application’ scope, use:

+
scoped.node_names('application/')
+
+
+

If you did this:

+
scoped.node_names('application')
+
+
+

Then the node would get the primary scope and try to find its child node +called ‘application’.

+

Of course you can just get the scope via:

+
application_scope = scoped.get_scope('application')
+
+
+

and then call whatever methods you like on it - which is definitely more +intentional and is highly recommended:

+
application_scope.node_names()
+
+
+
+
+add_preferences_listener(listener, path='')[source]
+

Add a listener for changes to a node’s preferences.

+
+ +
+
+clear(path='')[source]
+

Remove all preference from the node at the specified path.

+
+ +
+
+dump(indent='')[source]
+

Dump the preferences hierarchy to stdout.

+
+ +
+
+get(path, default=None, inherit=False)[source]
+

Get the value of the preference at the specified path.

+
+ +
+
+get_scope(scope_name)[source]
+

Return the scope with the specified name.

+

Return None if no such scope exists.

+
+ +
+
+keys(path='')[source]
+

Return the preference keys of the node at the specified path.

+
+ +
+
+load(file_or_filename=None)[source]
+

Load preferences from a file.

+

This loads the preferences into the primary scope.

+

fixme: I’m not sure it is worth providing an implentation here. I +think it would be better to encourage people to explicitly reference +a particular scope.

+
+ +
+
+node(path='')[source]
+

Return the node at the specified path.

+
+ +
+
+node_exists(path='')[source]
+

Return True if the node at the specified path exists.

+
+ +
+
+node_names(path='')[source]
+

Return the names of the children of the node at the specified path.

+
+ +
+
+remove(path)[source]
+

Remove the preference at the specified path.

+
+ +
+
+remove_preferences_listener(listener, path='')[source]
+

Remove a listener for changes to a node’s preferences.

+
+ +
+
+save(file_or_filename=None)[source]
+

Save the node’s preferences to a file.

+

This asks each scope in turn to save its preferences.

+

If a file or filename is specified then it is only passed to the +primary scope.

+
+ +
+
+set(path, value)[source]
+

Set the value of the preference at the specified path.

+
+ +
+ +
+
+

Module contents

+

Manages application preferences. +Part of the AppTools project of the Enthought Tool Suite

+
+
+ + +
+
+
+ +
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/4.5/api/apptools.preferences.ui.html b/4.5/api/apptools.preferences.ui.html new file mode 100644 index 000000000..237700746 --- /dev/null +++ b/4.5/api/apptools.preferences.ui.html @@ -0,0 +1,373 @@ + + + + + + + apptools.preferences.ui package — Apptools Documentation + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ + + + +
+
+ +
+
+ +
+

apptools.preferences.ui package

+
+

Submodules

+
+
+

apptools.preferences.ui.api module

+
+
+

apptools.preferences.ui.i_preferences_page module

+

The interface for pages in a preferences dialog.

+
+
+class apptools.preferences.ui.i_preferences_page.IPreferencesPage[source]
+

Bases: traits.has_traits.Interface

+

The interface for pages in a preferences dialog.

+
+
+apply()[source]
+

Apply the page’s preferences.

+
+ +
+ +
+
+

apptools.preferences.ui.preferences_manager module

+

The preferences manager.

+
+
+class apptools.preferences.ui.preferences_manager.PreferencesHelpWindow[source]
+

Bases: traits.has_traits.HasTraits

+

Container class to present a view with string info.

+
+
+traits_view()[source]
+

Default view to show for this class.

+
+ +
+ +
+
+class apptools.preferences.ui.preferences_manager.PreferencesManager[source]
+

Bases: traits.has_traits.HasTraits

+

The preferences manager.

+
+
+apply()[source]
+

Apply all changes made in the manager.

+
+ +
+
+traits_view()[source]
+

Default traits view for this class.

+
+ +
+ +
+
+class apptools.preferences.ui.preferences_manager.PreferencesManagerHandler[source]
+

Bases: traitsui.handler.Handler

+

The traits UI handler for the preferences manager.

+
+
+apply(info)[source]
+

Handle the Apply button being clicked.

+
+ +
+
+close(info, is_ok)[source]
+

Close a dialog-based user interface.

+
+ +
+
+init(info)[source]
+

Initialize the controls of a user interface.

+
+ +
+
+preferences_help(info)[source]
+

Custom preferences help panel. The Traits help doesn’t work.

+
+ +
+ +
+
+

apptools.preferences.ui.preferences_node module

+

Abstract base class for a node in a preferences dialog.

+
+
+class apptools.preferences.ui.preferences_node.PreferencesNode[source]
+

Bases: apptools.preferences.ui.tree_item.TreeItem

+

Abstract base class for a node in a preferences dialog.

+

A preferences node has a name and an image which are used to represent the +node in a preferences dialog (usually in the form of a tree).

+
+
+create_page(parent)[source]
+

Creates the preference page for this node.

+
+ +
+
+dump(indent='')[source]
+

Pretty-print the node to stdout.

+
+ +
+
+lookup(name)[source]
+

Returns the child of this node with the specified Id.

+

Returns None if no such child exists.

+
+ +
+ +
+
+

apptools.preferences.ui.preferences_page module

+

A page in a preferences dialog.

+
+
+class apptools.preferences.ui.preferences_page.PreferencesPage(**traits)[source]
+

Bases: apptools.preferences.preferences_helper.PreferencesHelper

+

A page in a preferences dialog.

+
+
+apply()[source]
+

Apply the page’s preferences.

+
+ +
+ +
+
+

apptools.preferences.ui.tree_item module

+

A generic base-class for items in a tree data structure.

+

An example:-

+

root = TreeItem(data=’Root’)

+

fruit = TreeItem(data=’Fruit’) +fruit.append(TreeItem(data=’Apple’, allows_children=False)) +fruit.append(TreeItem(data=’Orange’, allows_children=False)) +fruit.append(TreeItem(data=’Pear’, allows_children=False)) +root.append(fruit)

+

veg = TreeItem(data=’Veg’) +veg.append(TreeItem(data=’Carrot’, allows_children=False)) +veg.append(TreeItem(data=’Cauliflower’, allows_children=False)) +veg.append(TreeItem(data=’Sprout’, allows_children=False)) +root.append(veg)

+
+
+class apptools.preferences.ui.tree_item.TreeItem[source]
+

Bases: traits.has_traits.HasTraits

+

A generic base-class for items in a tree data structure.

+
+
+append(child)[source]
+

Appends a child to this item.

+

This removes the child from its current parent (if it has one).

+
+ +
+
+insert(index, child)[source]
+

Inserts a child into this item at the specified index.

+

This removes the child from its current parent (if it has one).

+
+ +
+
+insert_after(after, child)[source]
+

Inserts a child into this item after the specified item.

+

This removes the child from its current parent (if it has one).

+
+ +
+
+insert_before(before, child)[source]
+

Inserts a child into this item before the specified item.

+

This removes the child from its current parent (if it has one).

+
+ +
+
+remove(child)[source]
+

Removes a child from this item.

+
+ +
+ +
+
+

apptools.preferences.ui.widget_editor module

+
+
+

Module contents

+
+
+ + +
+
+
+ +
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/4.5/api/apptools.scripting.html b/4.5/api/apptools.scripting.html new file mode 100644 index 000000000..ec7c7b92d --- /dev/null +++ b/4.5/api/apptools.scripting.html @@ -0,0 +1,402 @@ + + + + + + + apptools.scripting package — Apptools Documentation + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +
+

apptools.scripting package

+
+

Submodules

+
+
+

apptools.scripting.api module

+

Public API for the scripting package.

+
+
+

apptools.scripting.package_globals module

+

Globals for the scripting package.

+
+
+apptools.scripting.package_globals.get_recorder()[source]
+

Return the global recorder. Does not create a new one if none +exists.

+
+ +
+
+apptools.scripting.package_globals.set_recorder(rec)[source]
+

Set the global recorder instance.

+
+ +
+
+

apptools.scripting.recordable module

+

Decorator to mark functions and methods as recordable.

+
+
+apptools.scripting.recordable.recordable(func)[source]
+

A decorator that wraps a function into one that is recordable.

+

This will record the function only if the global recorder has been +set via a set_recorder function call.

+

This is almost entirely copied from the +apptools.appscripting.scriptable.scriptable decorator.

+
+ +
+
+

apptools.scripting.recorder module

+

Code to support recording to a readable and executable Python script.

+
+
+class apptools.scripting.recorder.Recorder[source]
+

Bases: traits.has_traits.HasTraits

+
+
+clear()[source]
+

Clears all previous recorded state and unregisters all +registered objects.

+
+ +
+
+get_code()[source]
+

Returns the recorded lines as a string of printable code.

+
+ +
+
+get_object_path(object)[source]
+

Returns the path in the object hierarchy of a registered +object. Useful for debugging.

+
+ +
+
+get_script_id(object)[source]
+

Returns the script_id of a registered object. Useful when +you want to manually add a record statement.

+
+ +
+
+is_registered(object)[source]
+

Returns True if the given object is registered with the +recorder.

+
+ +
+
+record(code)[source]
+

Record a string to be stored to the output file.

+

code - A string of text.

+
+ +
+
+record_function(func, args, kw)[source]
+

Record a function call given the function and its +arguments.

+
+ +
+
+register(object, parent=None, trait_name_on_parent='', ignore=None, known=False, script_id=None)[source]
+

Register an object with the recorder. This sets up the +object for recording.

+

By default all traits (except those starting and ending with +‘_’) are recorded. For attributes that are themselves +recordable, one may mark traits with a ‘record’ metadata as +follows:

+
    +
  • If metadata record=False is set, the nested object will not be +recorded.
  • +
  • If record=True, then that object is also recorded if it is +not None.
  • +
+

If the object is a list or dict that is marked with +record=True, the list is itself not listened to for changes +but all its contents are registered.

+

If the object has a trait named recorder then this recorder +instance will be set to it if possible.

+
+
object : Instance(HasTraits)
+
The object to register in the registry.
+
parent : Instance(HasTraits)
+
An optional parent object in which object is contained
+
trait_name_on_parent : str
+
An optional trait name of the object in the parent.
+
ignore : list(str)
+
An optional list of trait names on the object to be +ignored.
+
known : bool
+
Optional specification if the object id is known on the +interpreter. This is needed if you are manually injecting +code to define/create an object.
+
script_id : str
+
Optionally specify a script_id to use for this object. It +is not guaranteed that this ID will be used since it may +already be in use.
+
+
+ +
+
+save(file)[source]
+

Save the recorded lines to the given file. It does not close +the file.

+
+ +
+
+ui_save()[source]
+

Save recording to file, pop up a UI dialog to find out where +and close the file when done.

+
+ +
+
+unregister(object)[source]
+

Unregister the given object from the recorder. This inverts +the logic of the register(…) method.

+
+ +
+
+write_script_id_in_namespace(script_id)[source]
+

If a script_id is not known in the current script’s namespace, +this sets it using the path of the object or actually +instantiating it. If this is not possible (since the script_id +matches no existing object), nothing is recorded but the +framework is notified that the particular script_id is available +in the namespace. This is useful when you want to inject code +in the namespace to create a particular object.

+
+ +
+ +
+
+exception apptools.scripting.recorder.RecorderError[source]
+

Bases: Exception

+
+ +
+
+

apptools.scripting.recorder_with_ui module

+

A Recorder subclass that presents a simple user interface.

+
+
+class apptools.scripting.recorder_with_ui.CloseHandler[source]
+

Bases: traitsui.handler.Handler

+

This class cleans up after the UI for the recorder is closed.

+
+
+close(info, is_ok)[source]
+

This method is invoked when the user closes the UI.

+
+ +
+ +
+
+class apptools.scripting.recorder_with_ui.RecorderWithUI[source]
+

Bases: apptools.scripting.recorder.Recorder

+

This class represents a Recorder but with a simple user interface.

+
+
+on_ui_close()[source]
+

Called from the CloseHandler when the UI is closed. This +method basically stops the recording.

+
+ +
+ +
+
+

apptools.scripting.util module

+

Simple utility functions provided by the scripting API.

+
+
+apptools.scripting.util.start_recording(object, ui=True, **kw)[source]
+

Convenience function to start recording. Returns the recorder.

+

object : object to record.

+

ui : bool specifying if a UI is to be shown or not

+

kw : Keyword arguments to pass to the register function of the +recorder.

+
+ +
+
+apptools.scripting.util.stop_recording(object, save=True)[source]
+

Stop recording the object. If save is True, this will pop up +a UI to ask where to save the script.

+
+ +
+
+

Module contents

+

Automatic script recording framework, part of the AppTools project +of the Enthought Tool Suite.

+
+
+ + +
+
+
+ +
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/4.5/api/apptools.selection.html b/4.5/api/apptools.selection.html new file mode 100644 index 000000000..234176a75 --- /dev/null +++ b/4.5/api/apptools.selection.html @@ -0,0 +1,509 @@ + + + + + + + apptools.selection package — Apptools Documentation + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +
+

apptools.selection package

+
+

Submodules

+
+
+

apptools.selection.api module

+
+
+

apptools.selection.errors module

+
+
+exception apptools.selection.errors.IDConflictError(provider_id)[source]
+

Bases: Exception

+

Raised when a provider is added and its ID is already registered.

+
+ +
+
+exception apptools.selection.errors.ListenerNotConnectedError(provider_id, listener)[source]
+

Bases: Exception

+

Raised when a listener that was never connected is disconnected.

+
+ +
+
+exception apptools.selection.errors.ProviderNotRegisteredError(provider_id)[source]
+

Bases: Exception

+

Raised when a provider is requested by ID and not found.

+
+ +
+
+

apptools.selection.i_selection module

+
+
+class apptools.selection.i_selection.IListSelection[source]
+

Bases: apptools.selection.i_selection.ISelection

+

Selection for ordered sequences of items.

+
+
+indices = List
+

Indices of the selected objects in the selection provider.

+
+ +
+
+items = List
+

Selected objects.

+
+ +
+ +
+
+class apptools.selection.i_selection.ISelection[source]
+

Bases: traits.has_traits.Interface

+

Collection of selected items.

+
+
+is_empty()[source]
+

Is the selection empty?

+
+ +
+
+provider_id = Str
+

ID of the selection provider that created this selection object.

+
+ +
+ +
+
+

apptools.selection.i_selection_provider module

+
+
+class apptools.selection.i_selection_provider.ISelectionProvider[source]
+

Bases: traits.has_traits.Interface

+

Source of selections.

+
+
+get_selection()[source]
+

Return the current selection.

+ +++ + + + +
Returns:
+
selection – ISelection
+
Object representing the current selection.
+
+
+
+ +
+
+provider_id = Str()
+

Unique ID identifying the provider.

+
+ +
+
+selection = Event
+

Event triggered when the selection changes. +The content of the event is an ISelection instance.

+
+ +
+
+set_selection(items, ignore_missing=False)[source]
+

Set the current selection to the given items.

+

If ignore_missing is True, items that are not available in the +selection provider are silently ignored. If it is False (default), +an ValueError should be raised.

+ +++ + + + +
Parameters:
    +
  • -- list (items) – List of items to be selected.
  • +
  • -- bool (ignore_missing) – If False (default), the provider raises an exception if any +of the items in items is not available to be selected. +Otherwise, missing elements are silently ignored, and the rest +is selected.
  • +
+
+
+ +
+ +
+
+

apptools.selection.list_selection module

+
+
+class apptools.selection.list_selection.ListSelection[source]
+

Bases: traits.has_traits.HasTraits

+

Selection for ordered sequences of items.

+

This is the default implementation of the IListSelection +interface.

+
+
+classmethod from_available_items(provider_id, selected, all_items)[source]
+

Create a list selection given a list of all available items.

+

Fills in the required information (in particular, the indices) based +on a list of selected items and a list of all available items.

+
+

Note

+
    +
  • The list of available items must not contain any duplicate items.
  • +
  • It is expected that selected is populated by items in +all_items.
  • +
+
+
+ +
+
+indices = List
+

Indices of the selected objects in the selection provider.

+
+ +
+
+is_empty()[source]
+

Is the selection empty?

+
+ +
+
+items = List
+

Selected objects.

+
+ +
+
+provider_id = Str
+

ID of the selection provider that created this selection object.

+
+ +
+ +
+
+

apptools.selection.selection_service module

+
+
+class apptools.selection.selection_service.SelectionService[source]
+

Bases: traits.has_traits.HasTraits

+

The selection service connects selection providers and listeners.

+

The selection service is a register of selection providers, i.e., objects +that publish their current selection.

+

Selections can be requested actively, by explicitly requesting the current +selection in a provider (get_selection(id)()), or passively by +connecting selection listeners.

+
+
+add_selection_provider(provider)[source]
+

Add a selection provider.

+

The provider is identified by its ID. If a provider with the same +ID has been already registered, an IDConflictError +is raised.

+ +++ + + + +
Parameters:-- ISelectionProvider (provider) – The selection provider added to the internal registry.
+
+ +
+
+connect_selection_listener(provider_id, func)[source]
+

Connect a listener to selection events from a specific provider.

+

The signature if the listener callback is func(i_selection). +The listener is called:

+
    +
  1. When a provider with the given ID is registered, with its initial +selection as argument, or
  2. +
  3. whenever the provider fires a selection event.
  4. +
+

It is perfectly valid to connect a listener before a provider with the +given ID is registered. The listener will remain connected even if +the provider is repeatedly connected and disconnected.

+ +++ + + + +
Parameters:
    +
  • -- str (provider_id) – The selection provider ID.
  • +
  • -- callable (func) – A callable object that is notified when the selection changes.
  • +
+
+
+ +
+
+disconnect_selection_listener(provider_id, func)[source]
+

Disconnect a listener from a specific provider.

+ +++ + + + +
Parameters:
    +
  • -- str (provider_id) – The selection provider ID.
  • +
  • -- callable (func) – A callable object that is notified when the selection changes.
  • +
+
+
+ +
+
+get_selection(provider_id)[source]
+

Return the current selection of the provider with the given ID.

+

If a provider with that ID has not been registered, a +ProviderNotRegisteredError is raised.

+ +++ + + + + + +
Parameters:-- str (provider_id) – The selection provider ID.
Returns:
+
selection – ISelection
+
The current selection of the provider.
+
+
+
+ +
+
+has_selection_provider(provider_id)[source]
+

Has a provider with the given ID been registered?

+
+ +
+
+remove_selection_provider(provider)[source]
+

Remove a selection provider.

+

If the provider has not been registered, a +ProviderNotRegisteredError is raised.

+ +++ + + + +
Parameters:-- ISelectionProvider (provider) – The selection provider added to the internal registry.
+
+ +
+
+set_selection(provider_id, items, ignore_missing=False)[source]
+

Set the current selection in a provider to the given items.

+

If a provider with the given ID has not been registered, a +ProviderNotRegisteredError is raised.

+

If ignore_missing is True, items that are not available in the +selection provider are silently ignored. If it is False (default), +a ValueError should be raised.

+ +++ + + + +
Parameters:
    +
  • -- str (provider_id) – The selection provider ID.
  • +
  • -- list (items) – List of items to be selected.
  • +
  • -- bool (ignore_missing) – If False (default), the provider raises an exception if any +of the items in items is not available to be selected. +Otherwise, missing elements are silently ignored, and the rest +is selected.
  • +
+
+
+ +
+ +
+
+

Module contents

+
+
+ + +
+
+
+ +
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/api/apptools.sweet_pickle.html b/4.5/api/apptools.sweet_pickle.html similarity index 100% rename from api/apptools.sweet_pickle.html rename to 4.5/api/apptools.sweet_pickle.html diff --git a/api/apptools.template.html b/4.5/api/apptools.template.html similarity index 100% rename from api/apptools.template.html rename to 4.5/api/apptools.template.html diff --git a/api/apptools.template.impl.html b/4.5/api/apptools.template.impl.html similarity index 100% rename from api/apptools.template.impl.html rename to 4.5/api/apptools.template.impl.html diff --git a/api/apptools.template.test.html b/4.5/api/apptools.template.test.html similarity index 100% rename from api/apptools.template.test.html rename to 4.5/api/apptools.template.test.html diff --git a/api/apptools.type_manager.html b/4.5/api/apptools.type_manager.html similarity index 100% rename from api/apptools.type_manager.html rename to 4.5/api/apptools.type_manager.html diff --git a/4.5/api/apptools.type_registry.html b/4.5/api/apptools.type_registry.html new file mode 100644 index 000000000..acc76f891 --- /dev/null +++ b/4.5/api/apptools.type_registry.html @@ -0,0 +1,352 @@ + + + + + + + apptools.type_registry package — Apptools Documentation + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +
+

apptools.type_registry package

+
+

Submodules

+
+
+

apptools.type_registry.api module

+
+
+

apptools.type_registry.type_registry module

+
+
+class apptools.type_registry.type_registry.LazyRegistry[source]
+

Bases: apptools.type_registry.type_registry.TypeRegistry

+

A type registry that will lazily import the registered objects.

+

Register ‘__module__:__name__’ strings for the lazily imported objects. +These will only be imported when the matching type is looked up. The module +name must be a fully-qualified absolute name with all of the parent +packages specified.

+
+
+lookup_by_type(typ)[source]
+

Look up the registered object for a type.

+
+ +
+ +
+
+class apptools.type_registry.type_registry.TypeRegistry[source]
+

Bases: object

+

Register objects for types.

+

Each type maintains a stack of registered objects that can be pushed and +popped.

+
+
+lookup(instance)[source]
+

Look up the registered object for the given instance.

+ +++ + + + + + + + + + +
Parameters:instance (object) – An instance of a possibly registered type.
Returns:obj – The registered object for the type of the instance, one of the +type’s superclasses, or else one of the ABCs the type implements.
Return type:object
Raises:KeyError if the instance’s type has not been registered.
+
+ +
+
+lookup_all(instance)[source]
+

Look up all the registered objects for the given instance.

+ +++ + + + + + + + + + +
Parameters:instance (object) – An instance of a possibly registered type.
Returns:objs – The list of registered objects for the instance. If the given +instance is not registered, its superclasses are searched. If none +of the superclasses are registered, search the possible ABCs.
Return type:list of objects
Raises:KeyError if the instance’s type has not been registered.
+
+ +
+
+lookup_all_by_type(typ)[source]
+

Look up all the registered objects for a type.

+ +++ + + + + + + + + + +
Parameters:typ (type) –
Returns:objs – The list of registered objects for the type. If the given type is +not registered, its superclasses are searched. If none of the +superclasses are registered, search the possible ABCs.
Return type:list of objects
Raises:KeyError if the type has not been registered.
+
+ +
+
+lookup_by_type(typ)[source]
+

Look up the registered object for a type.

+ +++ + + + + + + + + + +
Parameters:typ (type) –
Returns:obj – The registered object for the type, one of its superclasses, or +else one of the ABCs it implements.
Return type:object
Raises:KeyError if the type has not been registered.
+
+ +
+
+pop(typ)[source]
+

Pop a registered object for the given type.

+ +++ + + + + + + + + + +
Parameters:typ (type or '__module__:__name__' string for a type) –
Returns:obj – The last registered object for the type.
Return type:object
Raises:KeyError if the type is not registered.
+
+ +
+
+push(typ, obj)[source]
+

Push an object onto the stack for the given type.

+ +++ + + + +
Parameters:
    +
  • typ (type or '__module__:__name__' string for a type) –
  • +
  • obj (object) – The object to register.
  • +
+
+
+ +
+
+push_abc(typ, obj)[source]
+

Push an object onto the stack for the given ABC.

+ +++ + + + +
Parameters:
    +
  • typ (abc.ABCMeta) –
  • +
  • obj (object) –
  • +
+
+
+ +
+ +
+
+apptools.type_registry.type_registry.get_mro(obj_class)[source]
+

Get a reasonable method resolution order of a class and its +superclasses for both old-style and new-style classes.

+
+ +
+
+

Module contents

+
+
+ + +
+
+
+
+
+ +

Table of Contents

+ + +

Previous topic

+

apptools.type_manager package

+

Next topic

+

apptools.undo package

+

This Page

+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/4.5/api/apptools.undo.action.html b/4.5/api/apptools.undo.action.html new file mode 100644 index 000000000..131590f77 --- /dev/null +++ b/4.5/api/apptools.undo.action.html @@ -0,0 +1,241 @@ + + + + + + + apptools.undo.action package — Apptools Documentation + + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ + + + +
+
+ +
+
+ +
+

apptools.undo.action package

+
+

Submodules

+
+
+

apptools.undo.action.abstract_command_stack_action module

+
+
+class apptools.undo.action.abstract_command_stack_action.AbstractCommandStackAction(**traits)[source]
+

Bases: pyface.action.action.Action

+

The abstract base class for all actions that operate on a command +stack.

+
+
+destroy()[source]
+

Called when the action is no longer required.

+

By default this method does nothing, but this would be a great place to +unhook trait listeners etc.

+
+ +
+ +
+
+

apptools.undo.action.api module

+
+
+

apptools.undo.action.command_action module

+
+
+class apptools.undo.action.command_action.CommandAction[source]
+

Bases: pyface.action.action.Action

+

The CommandAction class is an Action class that wraps undo/redo +commands. It is only useful for commands that do not take any arguments or +return any result.

+
+
+perform(event)[source]
+

This is reimplemented to push a new command instance onto the +command stack.

+
+ +
+ +
+
+

apptools.undo.action.redo_action module

+
+
+class apptools.undo.action.redo_action.RedoAction(**traits)[source]
+

Bases: apptools.undo.action.abstract_command_stack_action.AbstractCommandStackAction

+

An action that redos the last command undone of the active command +stack.

+
+
+perform(event)[source]
+

Perform the action.

+
+ +
+ +
+
+

apptools.undo.action.undo_action module

+
+
+class apptools.undo.action.undo_action.UndoAction(**traits)[source]
+

Bases: apptools.undo.action.abstract_command_stack_action.AbstractCommandStackAction

+

An action that undos the last command of the active command stack.

+
+
+perform(event)[source]
+

Perform the action.

+
+ +
+ +
+
+

Module contents

+
+
+ + +
+
+
+ +
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/4.5/api/apptools.undo.html b/4.5/api/apptools.undo.html new file mode 100644 index 000000000..1adf77962 --- /dev/null +++ b/4.5/api/apptools.undo.html @@ -0,0 +1,468 @@ + + + + + + + apptools.undo package — Apptools Documentation + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +
+

apptools.undo package

+ +
+

Submodules

+
+
+

apptools.undo.abstract_command module

+
+
+class apptools.undo.abstract_command.AbstractCommand[source]
+

Bases: traits.has_traits.HasTraits

+

The AbstractCommand class is an abstract base class that implements the +ICommand interface.

+
+
+do()[source]
+

This is called by the command stack to do the command and to return +any value. The command must save any state necessary for the ‘redo()’ +and ‘undo()’ methods to work. The class’s __init__() must also ensure +that deep copies of any arguments are made if appropriate. It is +guaranteed that this will only ever be called once and that it will be +called before any call to ‘redo()’ or ‘undo()’.

+
+ +
+
+merge(other)[source]
+

This is called by the command stack to try and merge another +command with this one. True is returned if the commands were merged. +‘other’ is the command that is about to be executed. If the commands +are merged then ‘other’ will discarded and not placed on the command +stack. A subsequent undo or redo of this modified command must have +the same effect as the two original commands.

+
+ +
+
+redo()[source]
+

This is called by the command stack to redo the command. Any +returned value will replace the value that the command stack references +from the original call to ‘do()’ or previous call to ‘redo()’.

+
+ +
+
+undo()[source]
+

This is called by the command stack to undo the command.

+
+ +
+ +
+
+

apptools.undo.api module

+
+
+

apptools.undo.command_stack module

+
+
+class apptools.undo.command_stack.CommandStack[source]
+

Bases: traits.has_traits.HasTraits

+

The CommandStack class is the default implementation of the +ICommandStack interface.

+
+
+begin_macro(name)[source]
+

This begins a macro by creating an empty command with the given +‘name’. All subsequent calls to ‘push()’ create commands that will be +children of the empty command until the next call to ‘end_macro()’. +Macros may be nested. The stack is disabled (ie. nothing can be undone +or redone) while a macro is being created (ie. while there is an +outstanding ‘end_macro()’ call).

+
+ +
+
+clear()[source]
+

This clears the stack, without undoing or redoing any commands, and +leaves the stack in a clean state. It is typically used when all +changes to the data have been abandoned.

+
+ +
+
+end_macro()[source]
+

This ends a macro.

+
+ +
+
+push(command)[source]
+

This executes a command and saves it on the command stack so that +it can be subsequently undone and redone. ‘command’ is an instance +that implements the ICommand interface. Its ‘do()’ method is called +to execute the command. If any value is returned by ‘do()’ then it is +returned by ‘push()’.

+
+ +
+
+redo(sequence_nr=0)[source]
+

If ‘sequence_nr’ is 0 then the last command that was undone is +redone and any result returned. Otherwise commands are redone up to +and including the given ‘sequence_nr’ and any result of the last of +these is returned.

+
+ +
+
+undo(sequence_nr=0)[source]
+

If ‘sequence_nr’ is 0 then the last command is undone. Otherwise +commands are undone up to and including the given ‘sequence_nr’.

+
+ +
+ +
+
+

apptools.undo.i_command module

+
+
+class apptools.undo.i_command.ICommand[source]
+

Bases: traits.has_traits.Interface

+

The command interface. The state of the data can be changed by passing +an instance that implements this interface to the ‘push()’ method of a +command stack along with any arguments.

+
+
+do()[source]
+

This is called by the command stack to do the command and to return +any value. The command must save any state necessary for the ‘redo()’ +and ‘undo()’ methods to work. The class’s __init__() must also ensure +that deep copies of any arguments are made if appropriate. It is +guaranteed that this will only ever be called once and that it will be +called before any call to ‘redo()’ or ‘undo()’.

+
+ +
+
+merge(other)[source]
+

This is called by the command stack to try and merge another +command with this one. True is returned if the commands were merged. +‘other’ is the command that is about to be executed. If the commands +are merged then ‘other’ will discarded and not placed on the command +stack. A subsequent undo or redo of this modified command must have +the same effect as the two original commands.

+
+ +
+
+redo()[source]
+

This is called by the command stack to redo the command. Any +returned value will replace the value that the command stack references +from the original call to ‘do()’ or previous call to ‘redo()’.

+
+ +
+
+undo()[source]
+

This is called by the command stack to undo the command.

+
+ +
+ +
+
+

apptools.undo.i_command_stack module

+
+
+class apptools.undo.i_command_stack.ICommandStack[source]
+

Bases: traits.has_traits.Interface

+

The command stack interface. A command stack is responsible for +managing the changes to a data model and recording those changes so that +they can be undone or redone.

+
+
+begin_macro(name)[source]
+

This begins a macro by creating an empty command with the given +‘name’. The commands passed to all subsequent calls to ‘push()’ will +be contained in the macro until the next call to ‘end_macro()’. Macros +may be nested. The stack is disabled (ie. nothing can be undone or +redone) while a macro is being created (ie. while there is an +outstanding ‘end_macro()’ call).

+
+ +
+
+clear()[source]
+

This clears the stack, without undoing or redoing any commands, and +leaves the stack in a clean state. It is typically used when all +changes to the data have been abandoned.

+
+ +
+
+end_macro()[source]
+

This ends a macro.

+
+ +
+
+push(command)[source]
+

This executes a command and saves it on the command stack so that +it can be subsequently undone and redone. ‘command’ is an instance +that implements the ICommand interface. Its ‘do()’ method is called +to execute the command. If any value is returned by ‘do()’ then it is +returned by ‘push()’. The command stack will keep a reference to the +result so that it can recognise it as an argument to a subsequent +command (which allows a script to properly save a result needed later).

+
+ +
+
+redo(sequence_nr=0)[source]
+

If ‘sequence_nr’ is 0 then the last command that was undone is +redone and any result returned. Otherwise commands are redone up to +and including the given ‘sequence_nr’ and any result of the last of +these is returned.

+
+ +
+
+undo(sequence_nr=0)[source]
+

If ‘sequence_nr’ is 0 then the last command is undone. Otherwise +commands are undone up to and including the given ‘sequence_nr’.

+
+ +
+ +
+
+

apptools.undo.i_undo_manager module

+
+
+class apptools.undo.i_undo_manager.IUndoManager[source]
+

Bases: traits.has_traits.Interface

+

The undo manager interface. An undo manager is responsible for one or +more command stacks. Typically an application would have a single undo +manager.

+
+
+redo()[source]
+

Redo the last undone command of the active command stack.

+
+ +
+
+undo()[source]
+

Undo the last command of the active command stack.

+
+ +
+ +
+
+

apptools.undo.undo_manager module

+
+
+class apptools.undo.undo_manager.UndoManager[source]
+

Bases: traits.has_traits.HasTraits

+

The UndoManager class is the default implementation of the +IUndoManager interface.

+
+
+redo()[source]
+

Redo the last undone command of the active command stack.

+
+ +
+
+undo()[source]
+

Undo the last command of the active command stack.

+
+ +
+ +
+
+

Module contents

+

Supports undoing and scripting application commands. +Part of the AppTools project of the Enthought Tool Suite.

+
+
+ + +
+
+
+ +
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/4.5/api/modules.html b/4.5/api/modules.html new file mode 100644 index 000000000..dd10caaf1 --- /dev/null +++ b/4.5/api/modules.html @@ -0,0 +1,373 @@ + + + + + + + apptools — Apptools Documentation + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +
+

apptools

+
+ +
+
+ + +
+
+
+
+
+ +

Previous topic

+

API documentation

+

Next topic

+

apptools package

+

This Page

+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/appscripting/Introduction.html b/4.5/appscripting/Introduction.html similarity index 100% rename from appscripting/Introduction.html rename to 4.5/appscripting/Introduction.html diff --git a/4.5/genindex.html b/4.5/genindex.html new file mode 100644 index 000000000..7470f3e5e --- /dev/null +++ b/4.5/genindex.html @@ -0,0 +1,2712 @@ + + + + + + + + Index — Apptools Documentation + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ + +

Index

+ +
+ A + | B + | C + | D + | E + | F + | G + | H + | I + | J + | K + | L + | M + | N + | O + | P + | Q + | R + | S + | T + | U + | V + | W + +
+

A

+ + + +
+ +

B

+ + + +
+ +

C

+ + + +
+ +

D

+ + + +
+ +

E

+ + + +
+ +

F

+ + + +
+ +

G

+ + + +
+ +

H

+ + + +
+ +

I

+ + + +
+ +

J

+ + +
+ +

K

+ + +
+ +

L

+ + + +
+ +

M

+ + + +
+ +

N

+ + + +
+ +

O

+ + + +
+ +

P

+ + + +
+ +

Q

+ + +
+ +

R

+ + + +
+ +

S

+ + + +
+ +

T

+ + + +
+ +

U

+ + + +
+ +

V

+ + + +
+ +

W

+ + + +
+ + + +
+
+
+
+
+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/4.5/index.html b/4.5/index.html new file mode 100644 index 000000000..18a4b7a37 --- /dev/null +++ b/4.5/index.html @@ -0,0 +1,212 @@ + + + + + + + AppTools Documentation — Apptools Documentation + + + + + + + + + + + + + + + + + + + +
+
+
+
+ + + +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/4.5/objects.inv b/4.5/objects.inv new file mode 100644 index 000000000..8594ce6a4 Binary files /dev/null and b/4.5/objects.inv differ diff --git a/permissions/ApplicationAPI.html b/4.5/permissions/ApplicationAPI.html similarity index 100% rename from permissions/ApplicationAPI.html rename to 4.5/permissions/ApplicationAPI.html diff --git a/permissions/DefaultPolicyManagerDataAPI.html b/4.5/permissions/DefaultPolicyManagerDataAPI.html similarity index 100% rename from permissions/DefaultPolicyManagerDataAPI.html rename to 4.5/permissions/DefaultPolicyManagerDataAPI.html diff --git a/permissions/DefaultUserManagerDataAPI.html b/4.5/permissions/DefaultUserManagerDataAPI.html similarity index 100% rename from permissions/DefaultUserManagerDataAPI.html rename to 4.5/permissions/DefaultUserManagerDataAPI.html diff --git a/permissions/Introduction.html b/4.5/permissions/Introduction.html similarity index 100% rename from permissions/Introduction.html rename to 4.5/permissions/Introduction.html diff --git a/4.5/preferences/Preferences.html b/4.5/preferences/Preferences.html new file mode 100644 index 000000000..2e1a1e387 --- /dev/null +++ b/4.5/preferences/Preferences.html @@ -0,0 +1,481 @@ + + + + + + + Preferences — Apptools Documentation + + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +
+

Preferences

+

The preferences package provides a simple API for managing application +preferences. The classes in the package are implemented using a layered +approach where the lowest layer provides access to the raw preferences +mechanism and each layer on top providing more convenient ways to get and set +preference values.

+
+
+

The Basic Preferences Mechanism

+

Lets start by taking a look at the lowest layer which consists of the +IPreferences interface and its default implementation in the Preferences +class. This layer implements the basic preferences system which is a +hierarchical arrangement of preferences ‘nodes’ (where each node is simply an +object that implements the IPreferences interface). Nodes in the hierarchy can +contain preference settings and/or child nodes. This layer also provides a +default way to read and write preferences from the filesystem using the +excellent ConfigObj package.

+

This all sounds a bit complicated but, believe me, it isn’t! To prove it +(hopefully) lets look at an example. Say I have the following preferences in +a file ‘example.ini’:

+
[acme.ui]
+bgcolor = blue
+width = 50
+ratio = 1.0
+visible = True
+
+[acme.ui.splash_screen]
+image = splash
+fgcolor = red
+
+
+

I can create a preferences hierarchy from this file by:

+
>>> from apptools.preferences.api import Preferences
+>>> preferences = Preferences(filename='example.ini')
+>>> preferences.dump()
+
+ Node() {}
+    Node(acme) {}
+      Node(ui) {'bgcolor': 'blue', 'ratio': '1.0', 'width': '50', 'visible': 'True'}
+        Node(splash_screen) {'image': 'splash', 'fgcolor': 'red'}
+
+
+

The ‘dump’ method (useful for debugging etc) simply ‘pretty prints’ a +preferences hierarchy. The dictionary next to each node contains the node’s +actual preferences. In this case, the root node (the node with no name) is the +preferences object that we created. This node now has one child node ‘acme’, +which contains no preferences. The ‘acme’ node has one child, ‘ui’, which +contains some preferences (e.g. ‘bgcolor’) and also a child node +‘splash_screen’ which also contains preferences (e.g. ‘image’).

+

To look up a preference we use:

+
>>> preferences.get('acme.ui.bgcolor')
+'blue'
+
+
+

If no such preferences exists then, by default, None is returned:

+
>>> preferences.get('acme.ui.bogus') is None
+True
+
+
+

You can also specify an explicit default value:

+
>>> preferences.get('acme.ui.bogus', 'fred')
+'fred'
+
+
+

To set a preference we use:

+
>>> preferences.set('acme.ui.bgcolor', 'red')
+>>> preferences.get('acme.ui.bgcolor')
+'red'
+
+
+

And to make sure the preferences are saved back to disk:

+
>>> preferences.flush()
+
+
+

To add a new preference value we simply set it:

+
>>> preferences.set('acme.ui.fgcolor', 'black')
+>>> preferences.get('acme.ui.fgcolor')
+'black'
+
+
+

Any missing nodes in a call to ‘set’ are created automatically, hence:

+
>>> preferences.set('acme.ui.button.fgcolor', 'white')
+>>> preferences.get('acme.ui.button.fgcolor')
+'white'
+
+
+

Preferences can also be ‘inherited’. e.g. Notice that the ‘splash_screen’ +node does not contain a ‘bgcolor’ preference, and hence:

+
>>> preferences.get('acme.ui.splash_screen.bgcolor') is None
+True
+
+
+

But if we allow the ‘inheritance’ of preference values then:

+
>>> preferences.get('acme.ui.splash_screen.bgcolor', inherit=True)
+'red'
+
+
+

By using ‘inheritance’ here the preferences system will try the following +preferences:

+
'acme.ui.splash_screen.bgcolor'
+'acme.ui.bgcolor'
+'acme.bgcolor'
+'bgcolor'
+
+
+
+

Strings, Glorious Strings

+

At this point it is worth mentioning that preferences are always stored and +returned as strings. This is because of the limitations of the traditional +‘.ini’ file format i.e. they don’t contain any type information! Now before you +start panicking, this doesn’t mean that all of your preferences have to be +strings! Currently the preferences system allows, strings(!), booleans, ints, +longs, floats and complex numbers. When you store a non-string value it gets +converted to a string for you, but you always get a string back:

+
>>> preferences.get('acme.ui.width')
+'50'
+>>> preferences.set('acme.ui.width', 100)
+>>> preferences.get('acme.ui.width')
+'100'
+
+>>> preferences.get('acme.ui.visible')
+'True'
+>>> preferences.set('acme.ui.visible', False)
+>>> preferences.get('acme.ui.visible')
+'False'
+
+
+

This is obviously not terribly convenient, and so the following section +discusses how we associate type information with our preferences to make +getting and setting them more natural.

+
+
+
+

Preferences and Types

+

As mentioned previously, we would like to be able to get and set non-string +preferences in a more convenient way. This is where the PreferencesHelper +class comes in.

+

Let’s take another look at ‘example.ini’:

+
[acme.ui]
+bgcolor = blue
+width = 50
+ratio = 1.0
+visible = True
+
+[acme.ui.splash_screen]
+image = splash
+fgcolor = red
+
+
+

Say, I am interested in the preferences in the ‘acme.ui’ section. I can use a +preferences helper as follows:

+
from apptools.preferences.api import PreferencesHelper
+
+class SplashScreenPreferences(PreferencesHelper):
+    """ A preferences helper for the splash screen. """
+
+    PREFERENCES_PATH = 'acme.ui'
+
+    bgcolor = Str
+    width   = Int
+    ratio   = Float
+    visible = Bool
+
+>>> preferences = Preferences(filename='example.ini')
+>>> helper = SplashScreenPreferences(preferences=preferences)
+>>> helper.bgcolor
+'blue'
+>>> helper.width
+100
+>>> helper.ratio
+1.0
+>>> helper.visible
+True
+
+
+

And, obviously, I can set the value of the preferences via the helper too:

+
>>> helper.ratio = 0.5
+
+
+

And if you want to prove to yourself it really did set the preference:

+
>>> preferences.get('acme.ui.ratio')
+'0.5'
+
+
+

Using a preferences helper you also get notified via the usual trait +mechanism when the preferences are changed (either via the helper or via the +preferences node directly:

+
def listener(obj, trait_name, old, new):
+    print(trait_name, old, new)
+
+>>> helper.on_trait_change(listener)
+>>> helper.ratio = 0.75
+ratio 0.5 0.75
+>>> preferences.set('acme.ui.ratio', 0.33)
+ratio 0.75 0.33
+
+
+

If you always use the same preference node as the root of your preferences you +can also set the class attribute ‘PreferencesHelper.preferences’ to be that +node and from then on in, you don’t have to pass a preferences collection in +each time you create a helper:

+
>>> PreferencesHelper.preferences = Preferences(filename='example.ini')
+>>> helper = SplashScreenPreferences()
+>>> helper.bgcolor
+'blue'
+>>> helper.width
+100
+>>> helper.ratio
+1.0
+>>> helper.visible
+True
+
+
+
+
+

Scoped Preferences

+

In many applications the idea of preferences scopes is useful. In a scoped +system, an actual preference value can be stored in any scope and when a call +is made to the ‘get’ method the scopes are searched in order of precedence.

+

The default implementation (in the ScopedPreferences class) provides two +scopes by default:

+
    +
  1. The application scope
  2. +
+

This scope stores itself in the ‘ETSConfig.application_home’ directory. This +scope is generally used when setting any user preferences.

+
    +
  1. The default scope
  2. +
+

This scope is transient (i.e. it does not store itself anywhere). This scope +is generally used to load any predefined default values into the preferences +system.

+

If you are happy with the default arrangement, then using the scoped +preferences is just like using the plain old non-scoped version:

+
>>> from apptools.preferences.api import ScopedPreferences
+>>> preferences = ScopedPreferences(filename='example.ini')
+>>> preferences.load('example.ini')
+>>> p.dump()
+
+  Node() {}
+    Node(application) {}
+      Node(acme) {}
+        Node(ui) {'bgcolor': 'blue', 'ratio': '1.0', 'width': '50', 'visible': 'True'}
+          Node(splash_screen) {'image': 'splash', 'fgcolor': 'red'}
+    Node(default) {}
+
+
+

Here you can see that the root node now has a child node representing each +scope.

+

When we are getting and setting preferences using scopes we generally want the +following behaviour:

+

a) When we get a preference we want to look it up in each scope in order. The +first scope that contains a value ‘wins’.

+

b) When we set a preference, we want to set it in the first scope. By default +this means that when we set a preference it will be set in the application +scope. This is exactly what we want as the application scope is the scope that +is persistent.

+

So usually, we just use the scoped preferences as before:

+
>>> preferences.get('acme.ui.bgcolor')
+'blue'
+>>> preferences.set('acme.ui.bgcolor', 'red')
+>>> preferences.dump()
+
+  Node() {}
+    Node(application) {}
+      Node(acme) {}
+        Node(ui) {'bgcolor': 'red', 'ratio': '1.0', 'width': '50', 'visible': 'True'}
+          Node(splash_screen) {'image': 'splash', 'fgcolor': 'red'}
+    Node(default) {}
+
+
+

And, conveniently, preference helpers work just the same with scoped +preferences too:

+
>>> PreferencesHelper.preferences = ScopedPreferences(filename='example.ini')
+>>> helper = SplashScreenPreferences()
+>>> helper.bgcolor
+'blue'
+>>> helper.width
+100
+>>> helper.ratio
+1.0
+>>> helper.visible
+True
+
+
+
+

Accessing a particular scope

+

Should you care about getting or setting a preference in a particular scope +then you use the following syntax:

+
>>> preferences.set('default/acme.ui.bgcolor', 'red')
+>>> preferences.get('default/acme.ui.bgcolor')
+'red'
+>>> preferences.dump()
+
+  Node() {}
+    Node(application) {}
+      Node(acme) {}
+        Node(ui) {'bgcolor': 'red', 'ratio': '1.0', 'width': '50', 'visible': 'True'}
+          Node(splash_screen) {'image': 'splash', 'fgcolor': 'red'}
+    Node(default) {}
+      Node(acme) {}
+        Node(ui) {'bgcolor': 'red'}
+
+
+

You can also get hold of a scope via:

+
>>> default = preferences.get_scope('default')
+
+
+

And then perform any of the usual operations on it.

+
+
+
+

Further Reading

+

So that’s a quick tour around the basic useage of the preferences API. For more +imformation about what is provided take a look at the API documentation.

+

If you are using Envisage to build your applications then you might also be +interested in the Preferences in Envisage section.

+
+ + +
+
+
+ +
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/4.5/preferences/PreferencesInEnvisage.html b/4.5/preferences/PreferencesInEnvisage.html new file mode 100644 index 000000000..016305c71 --- /dev/null +++ b/4.5/preferences/PreferencesInEnvisage.html @@ -0,0 +1,189 @@ + + + + + + + Preferences in Envisage — Apptools Documentation + + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +
+

Preferences in Envisage

+

This section discusses how an Envisage application uses the preferences +mechanism. Envisage tries not to dictate too much, and so this describes the +default behaviour, but you are free to override it as desired.

+

Envisage uses the default implementation of the ScopedPreferences class which +is made available via the application’s ‘preferences’ trait:

+
>>> application = Application(id='myapplication')
+>>> application.preferences.set('acme.ui.bgcolor', 'yellow')
+>>> application.preferences.get('acme.ui.bgcolor')
+'yellow'
+
+
+

Hence, you use the Envisage preferences just like you would any other scoped +preferences.

+

It also registers itself as the default preferences node used by the +PreferencesHelper class. Hence you don’t need to provide a preferences node +explicitly to your helper:

+
>>> helper = SplashScreenPreferences()
+>>> helper.bgcolor
+'blue'
+>>> helper.width
+100
+>>> helper.ratio
+1.0
+>>> helper.visible
+True
+
+
+

The only extra thing that Envisage does for you is to provide an extension +point that allows you to contribute any number of ‘.ini’ files that are +loaded into the default scope when the application is started.

+

e.g. To contribute a preference file for my plugin I might use:

+
class MyPlugin(Plugin):
+    ...
+
+    @contributes_to('envisage.preferences')
+    def get_preferences(self, application):
+        return ['pkgfile://mypackage:preferences.ini']
+
+
+
+ + +
+
+
+
+
+ +

Previous topic

+

Preferences

+

Next topic

+

Automatic script recording

+

This Page

+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/4.5/py-modindex.html b/4.5/py-modindex.html new file mode 100644 index 000000000..f93b3a7a6 --- /dev/null +++ b/4.5/py-modindex.html @@ -0,0 +1,1367 @@ + + + + + + + Python Module Index — Apptools Documentation + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ + +

Python Module Index

+ +
+ a +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
 
+ a
+ apptools +
    + apptools.appscripting +
    + apptools.appscripting.action +
    + apptools.appscripting.action.api +
    + apptools.appscripting.action.start_recording_action +
    + apptools.appscripting.action.stop_recording_action +
    + apptools.appscripting.api +
    + apptools.appscripting.bind_event +
    + apptools.appscripting.i_bind_event +
    + apptools.appscripting.i_script_manager +
    + apptools.appscripting.lazy_namespace +
    + apptools.appscripting.package_globals +
    + apptools.appscripting.script_manager +
    + apptools.appscripting.scriptable +
    + apptools.appscripting.scriptable_type +
    + apptools.help +
    + apptools.help.help_plugin +
    + apptools.help.help_plugin.action +
    + apptools.help.help_plugin.action.demo_action +
    + apptools.help.help_plugin.action.doc_action +
    + apptools.help.help_plugin.action.example_action +
    + apptools.help.help_plugin.action.load_url_action +
    + apptools.help.help_plugin.action.util +
    + apptools.help.help_plugin.api +
    + apptools.help.help_plugin.examples_preferences +
    + apptools.help.help_plugin.help_code +
    + apptools.help.help_plugin.help_doc +
    + apptools.help.help_plugin.help_plugin +
    + apptools.help.help_plugin.help_submenu_manager +
    + apptools.help.help_plugin.i_help_code +
    + apptools.help.help_plugin.i_help_doc +
    + apptools.help.help_plugin.preferences_pages +
    + apptools.io +
    + apptools.io.api +
    + apptools.io.file +
    + apptools.io.h5 +
    + apptools.io.h5.dict_node +
    + apptools.io.h5.file +
    + apptools.io.h5.table_node +
    + apptools.io.h5.utils +
    + apptools.logger +
    + apptools.logger.agent +
    + apptools.logger.agent.attachments +
    + apptools.logger.agent.quality_agent_mailer +
    + apptools.logger.agent.quality_agent_view +
    + apptools.logger.api +
    + apptools.logger.custom_excepthook +
    + apptools.logger.filtering_handler +
    + apptools.logger.log_point +
    + apptools.logger.log_queue_handler +
    + apptools.logger.logger +
    + apptools.logger.null_handler +
    + apptools.logger.plugin +
    + apptools.logger.plugin.logger_plugin +
    + apptools.logger.plugin.logger_preferences +
    + apptools.logger.plugin.logger_service +
    + apptools.logger.plugin.view +
    + apptools.logger.plugin.view.logger_preferences_page +
    + apptools.logger.plugin.view.logger_view +
    + apptools.logger.ring_buffer +
    + apptools.logger.util +
    + apptools.lru_cache +
    + apptools.lru_cache.lru_cache +
    + apptools.naming +
    + apptools.naming.adapter +
    + apptools.naming.adapter.api +
    + apptools.naming.adapter.dict_context_adapter +
    + apptools.naming.adapter.dict_context_adapter_factory +
    + apptools.naming.adapter.instance_context_adapter +
    + apptools.naming.adapter.instance_context_adapter_factory +
    + apptools.naming.adapter.list_context_adapter +
    + apptools.naming.adapter.list_context_adapter_factory +
    + apptools.naming.adapter.trait_dict_context_adapter +
    + apptools.naming.adapter.trait_dict_context_adapter_factory +
    + apptools.naming.adapter.trait_list_context_adapter +
    + apptools.naming.adapter.trait_list_context_adapter_factory +
    + apptools.naming.adapter.tuple_context_adapter +
    + apptools.naming.adapter.tuple_context_adapter_factory +
    + apptools.naming.address +
    + apptools.naming.api +
    + apptools.naming.binding +
    + apptools.naming.context +
    + apptools.naming.context_adapter +
    + apptools.naming.context_adapter_factory +
    + apptools.naming.dir_context +
    + apptools.naming.dynamic_context +
    + apptools.naming.exception +
    + apptools.naming.initial_context +
    + apptools.naming.initial_context_factory +
    + apptools.naming.naming_event +
    + apptools.naming.naming_manager +
    + apptools.naming.object_factory +
    + apptools.naming.object_serializer +
    + apptools.naming.py_context +
    + apptools.naming.py_object_factory +
    + apptools.naming.pyfs_context +
    + apptools.naming.pyfs_context_factory +
    + apptools.naming.pyfs_initial_context_factory +
    + apptools.naming.pyfs_object_factory +
    + apptools.naming.pyfs_state_factory +
    + apptools.naming.reference +
    + apptools.naming.referenceable +
    + apptools.naming.referenceable_state_factory +
    + apptools.naming.state_factory +
    + apptools.naming.trait_defs +
    + apptools.naming.trait_defs.api +
    + apptools.naming.trait_defs.naming_traits +
    + apptools.naming.ui +
    + apptools.naming.ui.api +
    + apptools.naming.ui.context_monitor +
    + apptools.naming.ui.context_node_type +
    + apptools.naming.ui.explorer +
    + apptools.naming.ui.naming_node_manager +
    + apptools.naming.ui.naming_tree +
    + apptools.naming.ui.naming_tree_model +
    + apptools.naming.ui.object_node_type +
    + apptools.naming.unique_name +
    + apptools.permissions +
    + apptools.permissions.action +
    + apptools.permissions.action.api +
    + apptools.permissions.action.login_action +
    + apptools.permissions.action.logout_action +
    + apptools.permissions.action.user_menu_manager +
    + apptools.permissions.adapter_base +
    + apptools.permissions.adapters +
    + apptools.permissions.adapters.pyface_action +
    + apptools.permissions.api +
    + apptools.permissions.default +
    + apptools.permissions.default.api +
    + apptools.permissions.default.i_policy_storage +
    + apptools.permissions.default.i_user_database +
    + apptools.permissions.default.i_user_storage +
    + apptools.permissions.default.persistent +
    + apptools.permissions.default.policy_data +
    + apptools.permissions.default.policy_manager +
    + apptools.permissions.default.policy_storage +
    + apptools.permissions.default.role_assignment +
    + apptools.permissions.default.role_definition +
    + apptools.permissions.default.select_role +
    + apptools.permissions.default.select_user +
    + apptools.permissions.default.user_database +
    + apptools.permissions.default.user_manager +
    + apptools.permissions.default.user_storage +
    + apptools.permissions.i_policy_manager +
    + apptools.permissions.i_user +
    + apptools.permissions.i_user_manager +
    + apptools.permissions.package_globals +
    + apptools.permissions.permission +
    + apptools.permissions.permissions_manager +
    + apptools.permissions.secure_proxy +
    + apptools.persistence +
    + apptools.persistence.file_path +
    + apptools.persistence.project_loader +
    + apptools.persistence.state_pickler +
    + apptools.persistence.updater +
    + apptools.persistence.version_registry +
    + apptools.persistence.versioned_unpickler +
    + apptools.preferences +
    + apptools.preferences.api +
    + apptools.preferences.i_preferences +
    + apptools.preferences.package_globals +
    + apptools.preferences.preference_binding +
    + apptools.preferences.preferences +
    + apptools.preferences.preferences_helper +
    + apptools.preferences.scoped_preferences +
    + apptools.preferences.ui +
    + apptools.preferences.ui.api +
    + apptools.preferences.ui.i_preferences_page +
    + apptools.preferences.ui.preferences_manager +
    + apptools.preferences.ui.preferences_node +
    + apptools.preferences.ui.preferences_page +
    + apptools.preferences.ui.tree_item +
    + apptools.scripting +
    + apptools.scripting.api +
    + apptools.scripting.package_globals +
    + apptools.scripting.recordable +
    + apptools.scripting.recorder +
    + apptools.scripting.recorder_with_ui +
    + apptools.scripting.util +
    + apptools.selection +
    + apptools.selection.api +
    + apptools.selection.errors +
    + apptools.selection.i_selection +
    + apptools.selection.i_selection_provider +
    + apptools.selection.list_selection +
    + apptools.selection.selection_service +
    + apptools.sweet_pickle +
    + apptools.sweet_pickle.global_registry +
    + apptools.sweet_pickle.placeholder +
    + apptools.sweet_pickle.updater +
    + apptools.sweet_pickle.versioned_unpickler +
    + apptools.template +
    + apptools.template.impl +
    + apptools.template.impl.any_context_data_name_item +
    + apptools.template.impl.any_data_name_item +
    + apptools.template.impl.api +
    + apptools.template.impl.context_data_name_item +
    + apptools.template.impl.helper +
    + apptools.template.impl.template_data_context +
    + apptools.template.impl.template_data_source +
    + apptools.template.impl.value_data_name_item +
    + apptools.template.impl.value_nd_data_name_item +
    + apptools.template.imutable_template +
    + apptools.template.itemplate +
    + apptools.template.itemplate_choice +
    + apptools.template.itemplate_data_context +
    + apptools.template.itemplate_data_name_item +
    + apptools.template.itemplate_data_source +
    + apptools.template.mutable_template +
    + apptools.template.template_choice +
    + apptools.template.template_data_name +
    + apptools.template.template_impl +
    + apptools.template.template_traits +
    + apptools.template.test +
    + apptools.type_manager +
    + apptools.type_manager.abstract_adapter_factory +
    + apptools.type_manager.abstract_factory +
    + apptools.type_manager.abstract_type_system +
    + apptools.type_manager.adaptable +
    + apptools.type_manager.adapter +
    + apptools.type_manager.adapter_factory +
    + apptools.type_manager.adapter_manager +
    + apptools.type_manager.api +
    + apptools.type_manager.factory +
    + apptools.type_manager.hook +
    + apptools.type_manager.python_type_system +
    + apptools.type_manager.type_manager +
    + apptools.type_manager.util +
    + apptools.type_registry +
    + apptools.type_registry.api +
    + apptools.type_registry.type_registry +
    + apptools.undo +
    + apptools.undo.abstract_command +
    + apptools.undo.action +
    + apptools.undo.action.abstract_command_stack_action +
    + apptools.undo.action.api +
    + apptools.undo.action.command_action +
    + apptools.undo.action.redo_action +
    + apptools.undo.action.undo_action +
    + apptools.undo.api +
    + apptools.undo.command_stack +
    + apptools.undo.i_command +
    + apptools.undo.i_command_stack +
    + apptools.undo.i_undo_manager +
    + apptools.undo.undo_manager +
+ + +
+
+
+
+
+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/4.5/scripting/introduction.html b/4.5/scripting/introduction.html new file mode 100644 index 000000000..cfb8e1bf4 --- /dev/null +++ b/4.5/scripting/introduction.html @@ -0,0 +1,335 @@ + + + + + + + Automatic script recording — Apptools Documentation + + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +
+

Automatic script recording

+

This package provides a very handy and powerful Python script recording +facility. This can be used to:

+
+
    +
  • record all actions performed on a traits based UI into a human +readable, Python script that should be able to recreate your UI +actions.
  • +
  • easily learn the scripting API of an application.
  • +
+
+

This package is not just a toy framework and is powerful enough to +provide full script recording to the Mayavi application. Mayavi is a +powerful 3D visualization tool that is part of ETS.

+
+

The scripting API

+

The scripting API primarily allows you to record UI actions for objects +that have Traits. Technically the framework listens to all trait +changes so will work outside a UI. We do not document the full API +here, the best place to look for that is the +apptools.scripting.recorder module which is reasonably well +documented. We provide a high level overview of the library.

+

The quickest way to get started is to look at a small example.

+
+

A tour by example

+

The following example is taken from the test suite. Consider a set of +simple objects organized in a hierarchy:

+
from traits.api import (HasTraits, Float, Instance,
+        Str, List, Bool, HasStrictTraits, Tuple, Range, TraitPrefixMap,
+        Trait)
+from apptools.scripting.api import (Recorder, recordable,
+    set_recorder)
+
+class Property(HasStrictTraits):
+    color = Tuple(Range(0.0, 1.0), Range(0.0, 1.0), Range(0.0, 1.0))
+    opacity = Range(0.0, 1.0, 1.0)
+    representation = Trait('surface',
+                           TraitPrefixMap({'surface':2,
+                                           'wireframe': 1,
+                                           'points': 0}))
+class Toy(HasTraits):
+    color = Str
+    type = Str
+    # Note the use of the trait metadata to ignore this trait.
+    ignore = Bool(False, record=False)
+
+class Child(HasTraits):
+    name = Str('child')
+    age = Float(10.0)
+    # The recorder walks through sub-instances if they are marked
+    # with record=True
+    property = Instance(Property, (), record=True)
+    toy = Instance(Toy, record=True)
+    friends = List(Str)
+
+    # The decorator records the method.
+    @recordable
+    def grow(self, x):
+        """Increase age by x years."""
+        self.age += x
+
+class Parent(HasTraits):
+    children = List(Child, record=True)
+    recorder = Instance(Recorder, record=False)
+
+
+

Using these simple classes we first create a simple object hierarchy as +follows:

+
p = Parent()
+c = Child()
+t = Toy()
+c.toy = t
+p.children.append(c)
+
+
+

Given this hierarchy, we’d like to be able to record a script. To do +this we setup the recording infrastructure:

+
from mayavi.core.recorder import Recorder, set_recorder
+# Create a recorder.
+r = Recorder()
+# Set the global recorder so the decorator works.
+set_recorder(r)
+r.register(p)
+r.recording = True
+
+
+

The key method here is the r.register(p) call above. It looks at +the traits of p and finds all traits and nested objects that specify +a record=True in their trait metadata (all methods starting and +ending with _ are ignored). All sub-objects are in turn registered +with the recorder and so on. Callbacks are attached to traits changes +and these are wired up to produce readable and executable code. The +set_recorder(r) call is also very important and sets the global +recorder so the framework listens to any functions that are decorated +with the recordable decorator.

+

Now lets test this out like so:

+
# The following will be recorded.
+c.name = 'Shiva'
+c.property.representation = 'w'
+c.property.opacity = 0.4
+c.grow(1)
+
+
+

To see what’s been recorded do this:

+
print(r.script)
+
+
+

This prints:

+
child = parent.children[0]
+child.name = 'Shiva'
+child.property.representation = 'wireframe'
+child.property.opacity = 0.40000000000000002
+child.grow(1)
+
+
+

The recorder internally maintains a mapping between objects and unique +names for each object. It also stores the information about the +location of a particular object in the object hierarchy. For example, +the path to the Toy instance in the hierarchy above is +parent.children[0].toy. Since scripting with lists this way can be +tedious, the recorder first instantiates the child:

+
child = parent.children[0]
+
+
+

Subsequent lines use the child attribute. The recorder always tries +to instantiate the object referred to using its path information in this +manner.

+

To record a function or method call one must simply decorate the +function/method with the recordable decorator. Nested recordable +functions are not recorded and trait changes are also not recorded if +done inside a recordable function.

+
+

Note

+
    +
  1. It is very important to note that the global recorder must be set +via the set_recorder method. The recordable decorator +relies on this being set to work.
  2. +
  3. The recordable decorator will work with plain Python classes +and with functions too.
  4. +
+
+

To stop recording do this:

+
r.unregister(p)
+r.recording = False
+
+
+

The r.unregister(p) reverses the r.register(p) call and +unregisters all nested objects as well.

+
+
+

Advanced use cases

+

Here are a few advanced use cases.

+
+
    +
  • The API also provides a RecorderWithUI class that provides a +simple user interface that prints the recorded script and allows the +user to save the script.
  • +
  • Sometimes it is not enough to just record trait changes, one may want +to pass an arbitrary string or command when recording is occurring. +To allow for this, if one defines a recorder trait on the object, +it is set to the current recorder. One can then use this recorder to +do whatever one wants. This is very convenient.
  • +
  • To ignore specific traits one must specify either a record=False +metadata to the trait definition or specify a list of strings to the +register method in the ignore keyword argument.
  • +
  • If you want to use a specific name for an object on the script you +can pass the script_id parameter to the register function.
  • +
+
+

For more details on the recorder itself we suggest reading the module +source code. It is fairly well documented and with the above background +should be enough to get you going.

+
+
+
+ + +
+
+
+
+
+ +

Table of Contents

+ + +

Previous topic

+

Preferences in Envisage

+

Next topic

+

Undo Framework

+

This Page

+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/4.5/search.html b/4.5/search.html new file mode 100644 index 000000000..6c532ed43 --- /dev/null +++ b/4.5/search.html @@ -0,0 +1,145 @@ + + + + + + + Search — Apptools Documentation + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +

Search

+
+ +

+ Please activate JavaScript to enable the search + functionality. +

+
+

+ From here you can search these documents. Enter your search + words into the box below and click "search". Note that the search + function will automatically search for all of the words. Pages + containing fewer words won't appear in the result list. +

+
+ + + +
+ +
+ +
+ +
+
+
+
+
+ +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/4.5/searchindex.js b/4.5/searchindex.js new file mode 100644 index 000000000..69be7e726 --- /dev/null +++ b/4.5/searchindex.js @@ -0,0 +1 @@ +Search.setIndex({docnames:["api","api/apptools","api/apptools.appscripting","api/apptools.appscripting.action","api/apptools.help","api/apptools.help.help_plugin","api/apptools.help.help_plugin.action","api/apptools.io","api/apptools.io.h5","api/apptools.logger","api/apptools.logger.agent","api/apptools.logger.plugin","api/apptools.logger.plugin.view","api/apptools.lru_cache","api/apptools.naming","api/apptools.naming.adapter","api/apptools.naming.trait_defs","api/apptools.naming.ui","api/apptools.permissions","api/apptools.permissions.action","api/apptools.permissions.adapters","api/apptools.permissions.default","api/apptools.persistence","api/apptools.preferences","api/apptools.preferences.ui","api/apptools.scripting","api/apptools.selection","api/apptools.sweet_pickle","api/apptools.template","api/apptools.template.impl","api/apptools.template.test","api/apptools.type_manager","api/apptools.type_registry","api/apptools.undo","api/apptools.undo.action","api/modules","appscripting/Introduction","index","permissions/ApplicationAPI","permissions/DefaultPolicyManagerDataAPI","permissions/DefaultUserManagerDataAPI","permissions/Introduction","preferences/Preferences","preferences/PreferencesInEnvisage","scripting/introduction","selection/selection","undo/Introduction"],envversion:{"sphinx.domains.c":1,"sphinx.domains.changeset":1,"sphinx.domains.cpp":1,"sphinx.domains.javascript":1,"sphinx.domains.math":2,"sphinx.domains.python":1,"sphinx.domains.rst":1,"sphinx.domains.std":1,"sphinx.ext.viewcode":1,sphinx:55},filenames:["api.rst","api/apptools.rst","api/apptools.appscripting.rst","api/apptools.appscripting.action.rst","api/apptools.help.rst","api/apptools.help.help_plugin.rst","api/apptools.help.help_plugin.action.rst","api/apptools.io.rst","api/apptools.io.h5.rst","api/apptools.logger.rst","api/apptools.logger.agent.rst","api/apptools.logger.plugin.rst","api/apptools.logger.plugin.view.rst","api/apptools.lru_cache.rst","api/apptools.naming.rst","api/apptools.naming.adapter.rst","api/apptools.naming.trait_defs.rst","api/apptools.naming.ui.rst","api/apptools.permissions.rst","api/apptools.permissions.action.rst","api/apptools.permissions.adapters.rst","api/apptools.permissions.default.rst","api/apptools.persistence.rst","api/apptools.preferences.rst","api/apptools.preferences.ui.rst","api/apptools.scripting.rst","api/apptools.selection.rst","api/apptools.sweet_pickle.rst","api/apptools.template.rst","api/apptools.template.impl.rst","api/apptools.template.test.rst","api/apptools.type_manager.rst","api/apptools.type_registry.rst","api/apptools.undo.rst","api/apptools.undo.action.rst","api/modules.rst","appscripting/Introduction.rst","index.rst","permissions/ApplicationAPI.rst","permissions/DefaultPolicyManagerDataAPI.rst","permissions/DefaultUserManagerDataAPI.rst","permissions/Introduction.rst","preferences/Preferences.rst","preferences/PreferencesInEnvisage.rst","scripting/introduction.rst","selection/selection.rst","undo/Introduction.rst"],objects:{"":{apptools:[1,0,0,"-"]},"apptools.appscripting":{action:[3,0,0,"-"],api:[2,0,0,"-"],bind_event:[2,0,0,"-"],i_bind_event:[2,0,0,"-"],i_script_manager:[2,0,0,"-"],lazy_namespace:[2,0,0,"-"],package_globals:[2,0,0,"-"],script_manager:[2,0,0,"-"],scriptable:[2,0,0,"-"],scriptable_type:[2,0,0,"-"]},"apptools.appscripting.action":{api:[3,0,0,"-"],start_recording_action:[3,0,0,"-"],stop_recording_action:[3,0,0,"-"]},"apptools.appscripting.action.start_recording_action":{StartRecordingAction:[3,1,1,""]},"apptools.appscripting.action.start_recording_action.StartRecordingAction":{perform:[3,2,1,""]},"apptools.appscripting.action.stop_recording_action":{StopRecordingAction:[3,1,1,""]},"apptools.appscripting.action.stop_recording_action.StopRecordingAction":{perform:[3,2,1,""]},"apptools.appscripting.bind_event":{BindEvent:[2,1,1,""]},"apptools.appscripting.i_bind_event":{IBindEvent:[2,1,1,""]},"apptools.appscripting.i_script_manager":{IScriptManager:[2,1,1,""]},"apptools.appscripting.i_script_manager.IScriptManager":{bind:[2,2,1,""],bind_factory:[2,2,1,""],run:[2,2,1,""],run_file:[2,2,1,""],start_recording:[2,2,1,""],stop_recording:[2,2,1,""]},"apptools.appscripting.lazy_namespace":{FactoryWrapper:[2,1,1,""],LazyNamespace:[2,1,1,""],add_to_namespace:[2,3,1,""]},"apptools.appscripting.lazy_namespace.FactoryWrapper":{create_scriptable_object:[2,2,1,""]},"apptools.appscripting.package_globals":{get_script_manager:[2,3,1,""],set_script_manager:[2,3,1,""]},"apptools.appscripting.script_manager":{ScriptManager:[2,1,1,""]},"apptools.appscripting.script_manager.ScriptManager":{arg_as_string:[2,4,1,""],args_as_string_list:[2,4,1,""],bind:[2,2,1,""],bind_factory:[2,2,1,""],new_object:[2,2,1,""],record_method:[2,2,1,""],record_trait_get:[2,2,1,""],record_trait_set:[2,2,1,""],run:[2,2,1,""],run_file:[2,2,1,""],start_recording:[2,2,1,""],stop_recording:[2,2,1,""]},"apptools.appscripting.scriptable":{Scriptable:[2,3,1,""],scriptable:[2,3,1,""]},"apptools.appscripting.scriptable_type":{create_scriptable_type:[2,3,1,""],make_object_scriptable:[2,3,1,""]},"apptools.help":{help_plugin:[5,0,0,"-"]},"apptools.help.help_plugin":{action:[6,0,0,"-"],api:[5,0,0,"-"],examples_preferences:[5,0,0,"-"],help_code:[5,0,0,"-"],help_doc:[5,0,0,"-"],help_plugin:[5,0,0,"-"],help_submenu_manager:[5,0,0,"-"],i_help_code:[5,0,0,"-"],i_help_doc:[5,0,0,"-"],preferences_pages:[5,0,0,"-"]},"apptools.help.help_plugin.action":{demo_action:[6,0,0,"-"],doc_action:[6,0,0,"-"],example_action:[6,0,0,"-"],load_url_action:[6,0,0,"-"],util:[6,0,0,"-"]},"apptools.help.help_plugin.action.demo_action":{DemoAction:[6,1,1,""],DemoImageResource:[6,1,1,""]},"apptools.help.help_plugin.action.demo_action.DemoAction":{perform:[6,2,1,""]},"apptools.help.help_plugin.action.doc_action":{DocAction:[6,1,1,""],DocImageResource:[6,1,1,""]},"apptools.help.help_plugin.action.doc_action.DocAction":{perform:[6,2,1,""]},"apptools.help.help_plugin.action.example_action":{ExampleAction:[6,1,1,""]},"apptools.help.help_plugin.action.example_action.ExampleAction":{perform:[6,2,1,""]},"apptools.help.help_plugin.action.load_url_action":{LoadURLAction:[6,1,1,""]},"apptools.help.help_plugin.action.util":{get_sys_prefix_relative_filename:[6,3,1,""]},"apptools.help.help_plugin.examples_preferences":{ExamplesPreferences:[5,1,1,""]},"apptools.help.help_plugin.help_code":{HelpCode:[5,1,1,""]},"apptools.help.help_plugin.help_doc":{HelpDoc:[5,1,1,""]},"apptools.help.help_plugin.help_plugin":{HelpPlugin:[5,1,1,""]},"apptools.help.help_plugin.help_plugin.HelpPlugin":{HELP_DEMOS:[5,5,1,""],HELP_DOCS:[5,5,1,""],HELP_DOWNLOADS:[5,5,1,""],HELP_EXAMPLES:[5,5,1,""],PREFERENCES:[5,5,1,""],PREFERENCES_PAGES:[5,5,1,""],WORKBENCH_ACTION_SETS:[5,5,1,""]},"apptools.help.help_plugin.help_submenu_manager":{DemosMenuManager:[5,1,1,""],DocumentsMenuManager:[5,1,1,""],DownloadsMenuManager:[5,1,1,""],ExamplesMenuManager:[5,1,1,""],HelpSubmenuManager:[5,1,1,""]},"apptools.help.help_plugin.i_help_code":{IHelpCode:[5,1,1,""]},"apptools.help.help_plugin.i_help_doc":{IHelpDoc:[5,1,1,""]},"apptools.help.help_plugin.preferences_pages":{DemosPreferencesPage:[5,1,1,""],DocumentsPreferencesPage:[5,1,1,""],ExamplesPreferencesPage:[5,1,1,""],HelpDemoPreferencesPage:[5,1,1,""],HelpDocPreferencesPage:[5,1,1,""],HelpExamplePreferencesPage:[5,1,1,""],HelpPreferencesPage:[5,1,1,""]},"apptools.io":{api:[7,0,0,"-"],file:[7,0,0,"-"],h5:[8,0,0,"-"]},"apptools.io.file":{File:[7,1,1,""]},"apptools.io.file.File":{"delete":[7,2,1,""],copy:[7,2,1,""],create_file:[7,2,1,""],create_folder:[7,2,1,""],create_folders:[7,2,1,""],create_package:[7,2,1,""],make_writeable:[7,2,1,""],move:[7,2,1,""]},"apptools.io.h5":{dict_node:[8,0,0,"-"],file:[8,0,0,"-"],table_node:[8,0,0,"-"],utils:[8,0,0,"-"]},"apptools.io.h5.dict_node":{ARRAY_PROXY_KEY:[8,6,1,""],H5DictNode:[8,1,1,""]},"apptools.io.h5.dict_node.H5DictNode":{add_to_h5file:[8,7,1,""],data:[8,5,1,""],flush:[8,2,1,""],is_dict_node:[8,7,1,""],keys:[8,2,1,""]},"apptools.io.h5.file":{H5Attrs:[8,1,1,""],H5File:[8,1,1,""],H5Group:[8,1,1,""],get_atom:[8,3,1,""],h5_group_wrapper:[8,3,1,""],iterator_length:[8,3,1,""]},"apptools.io.h5.file.H5Attrs":{get:[8,2,1,""],items:[8,2,1,""],keys:[8,2,1,""],values:[8,2,1,""]},"apptools.io.h5.file.H5File":{close:[8,2,1,""],create_array:[8,2,1,""],create_dict:[8,2,1,""],create_group:[8,2,1,""],create_table:[8,2,1,""],exists_error:[8,5,1,""],is_open:[8,5,1,""],iteritems:[8,2,1,""],join_path:[8,7,1,""],open:[8,2,1,""],remove_group:[8,2,1,""],remove_node:[8,2,1,""],root:[8,5,1,""],split_path:[8,7,1,""]},"apptools.io.h5.file.H5Group":{children_names:[8,5,1,""],create_array:[8,2,1,""],create_dict:[8,2,1,""],create_group:[8,2,1,""],create_table:[8,2,1,""],filename:[8,5,1,""],iter_groups:[8,2,1,""],name:[8,5,1,""],pathname:[8,5,1,""],remove_group:[8,2,1,""],remove_node:[8,2,1,""],root:[8,5,1,""],subgroup_names:[8,5,1,""]},"apptools.io.h5.table_node":{H5TableNode:[8,1,1,""]},"apptools.io.h5.table_node.H5TableNode":{add_to_h5file:[8,7,1,""],append:[8,2,1,""],is_table_node:[8,7,1,""],ix:[8,5,1,""],keys:[8,2,1,""],to_dataframe:[8,2,1,""]},"apptools.io.h5.utils":{open_h5file:[8,3,1,""]},"apptools.logger":{agent:[10,0,0,"-"],api:[9,0,0,"-"],custom_excepthook:[9,0,0,"-"],filtering_handler:[9,0,0,"-"],log_point:[9,0,0,"-"],log_queue_handler:[9,0,0,"-"],logger:[9,0,0,"-"],null_handler:[9,0,0,"-"],plugin:[11,0,0,"-"],ring_buffer:[9,0,0,"-"],util:[9,0,0,"-"]},"apptools.logger.agent":{attachments:[10,0,0,"-"],quality_agent_mailer:[10,0,0,"-"],quality_agent_view:[10,0,0,"-"]},"apptools.logger.agent.attachments":{Attachments:[10,1,1,""]},"apptools.logger.agent.attachments.Attachments":{package_any_relevant_files:[10,2,1,""],package_single_project:[10,2,1,""],package_workspace:[10,2,1,""]},"apptools.logger.agent.quality_agent_mailer":{create_email_message:[10,3,1,""]},"apptools.logger.agent.quality_agent_view":{QualityAgentView:[10,1,1,""]},"apptools.logger.agent.quality_agent_view.QualityAgentView":{cc_address:[10,5,1,""],comments:[10,5,1,""],from_address:[10,5,1,""],help_id:[10,5,1,""],include_userdata:[10,5,1,""],msg:[10,5,1,""],priority:[10,5,1,""],service:[10,5,1,""],size:[10,5,1,""],smtp_server:[10,5,1,""],subject:[10,5,1,""],title:[10,5,1,""],to_address:[10,5,1,""]},"apptools.logger.custom_excepthook":{custom_excepthook:[9,3,1,""]},"apptools.logger.filtering_handler":{FilteringHandler:[9,1,1,""]},"apptools.logger.filtering_handler.FilteringHandler":{emit:[9,2,1,""],filtered_emit:[9,2,1,""]},"apptools.logger.log_point":{log_point:[9,3,1,""]},"apptools.logger.log_queue_handler":{LogQueueHandler:[9,1,1,""]},"apptools.logger.log_queue_handler.LogQueueHandler":{emit:[9,2,1,""],get:[9,2,1,""],has_new_records:[9,2,1,""],reset:[9,2,1,""]},"apptools.logger.logger":{LogFileHandler:[9,1,1,""],add_log_queue_handler:[9,3,1,""],create_log_file_handler:[9,3,1,""]},"apptools.logger.null_handler":{NullHandler:[9,1,1,""]},"apptools.logger.null_handler.NullHandler":{emit:[9,2,1,""]},"apptools.logger.plugin":{logger_plugin:[11,0,0,"-"],logger_preferences:[11,0,0,"-"],logger_service:[11,0,0,"-"],view:[12,0,0,"-"]},"apptools.logger.plugin.logger_plugin":{LoggerPlugin:[11,1,1,""]},"apptools.logger.plugin.logger_plugin.LoggerPlugin":{MAIL_FILES:[11,5,1,""],PREFERENCES:[11,5,1,""],PREFERENCES_PAGES:[11,5,1,""],VIEWS:[11,5,1,""],start:[11,2,1,""],stop:[11,2,1,""]},"apptools.logger.plugin.logger_preferences":{LoggerPreferences:[11,1,1,""]},"apptools.logger.plugin.logger_service":{LoggerService:[11,1,1,""]},"apptools.logger.plugin.logger_service.LoggerService":{create_email_message:[11,2,1,""],save_preferences:[11,2,1,""],send_bug_report:[11,2,1,""],whole_log_text:[11,2,1,""]},"apptools.logger.plugin.view":{logger_preferences_page:[12,0,0,"-"],logger_view:[12,0,0,"-"]},"apptools.logger.plugin.view.logger_preferences_page":{LoggerPreferencesPage:[12,1,1,""]},"apptools.logger.plugin.view.logger_view":{LogRecordAdapter:[12,1,1,""],LoggerView:[12,1,1,""]},"apptools.logger.plugin.view.logger_view.LogRecordAdapter":{column_widths:[12,5,1,""],get_width:[12,2,1,""]},"apptools.logger.plugin.view.logger_view.LoggerView":{activated:[12,5,1,""],activated_text:[12,5,1,""],code_editor:[12,5,1,""],copy_button:[12,5,1,""],formatted_records:[12,5,1,""],id:[12,5,1,""],log_records:[12,5,1,""],log_records_editor:[12,5,1,""],name:[12,5,1,""],reset_button:[12,5,1,""],service:[12,5,1,""],show_button:[12,5,1,""],trait_view:[12,5,1,""],update:[12,2,1,""]},"apptools.logger.ring_buffer":{RingBuffer:[9,1,1,""],RingBufferFull:[9,1,1,""]},"apptools.logger.ring_buffer.RingBuffer":{append:[9,2,1,""],get:[9,2,1,""]},"apptools.logger.ring_buffer.RingBufferFull":{append:[9,2,1,""],get:[9,2,1,""]},"apptools.logger.util":{get_module_name:[9,3,1,""],get_module_name_from_zip:[9,3,1,""],get_zip_path:[9,3,1,""],is_zip_path:[9,3,1,""],path_exists_in_zip:[9,3,1,""]},"apptools.lru_cache":{lru_cache:[13,0,0,"-"]},"apptools.lru_cache.lru_cache":{LRUCache:[13,1,1,""]},"apptools.lru_cache.lru_cache.LRUCache":{clear:[13,2,1,""],get:[13,2,1,""],items:[13,2,1,""],keys:[13,2,1,""],values:[13,2,1,""]},"apptools.naming":{adapter:[15,0,0,"-"],address:[14,0,0,"-"],api:[14,0,0,"-"],binding:[14,0,0,"-"],context:[14,0,0,"-"],context_adapter:[14,0,0,"-"],context_adapter_factory:[14,0,0,"-"],dir_context:[14,0,0,"-"],dynamic_context:[14,0,0,"-"],exception:[14,0,0,"-"],initial_context:[14,0,0,"-"],initial_context_factory:[14,0,0,"-"],naming_event:[14,0,0,"-"],naming_manager:[14,0,0,"-"],object_factory:[14,0,0,"-"],object_serializer:[14,0,0,"-"],py_context:[14,0,0,"-"],py_object_factory:[14,0,0,"-"],pyfs_context:[14,0,0,"-"],pyfs_context_factory:[14,0,0,"-"],pyfs_initial_context_factory:[14,0,0,"-"],pyfs_object_factory:[14,0,0,"-"],pyfs_state_factory:[14,0,0,"-"],reference:[14,0,0,"-"],referenceable:[14,0,0,"-"],referenceable_state_factory:[14,0,0,"-"],state_factory:[14,0,0,"-"],trait_defs:[16,0,0,"-"],ui:[17,0,0,"-"],unique_name:[14,0,0,"-"]},"apptools.naming.adapter":{api:[15,0,0,"-"],dict_context_adapter:[15,0,0,"-"],dict_context_adapter_factory:[15,0,0,"-"],instance_context_adapter:[15,0,0,"-"],instance_context_adapter_factory:[15,0,0,"-"],list_context_adapter:[15,0,0,"-"],list_context_adapter_factory:[15,0,0,"-"],trait_dict_context_adapter:[15,0,0,"-"],trait_dict_context_adapter_factory:[15,0,0,"-"],trait_list_context_adapter:[15,0,0,"-"],trait_list_context_adapter_factory:[15,0,0,"-"],tuple_context_adapter:[15,0,0,"-"],tuple_context_adapter_factory:[15,0,0,"-"]},"apptools.naming.adapter.dict_context_adapter":{DictContextAdapter:[15,1,1,""]},"apptools.naming.adapter.dict_context_adapter_factory":{DictContextAdapterFactory:[15,1,1,""]},"apptools.naming.adapter.instance_context_adapter":{InstanceContextAdapter:[15,1,1,""]},"apptools.naming.adapter.instance_context_adapter_factory":{InstanceContextAdapterFactory:[15,1,1,""]},"apptools.naming.adapter.list_context_adapter":{ListContextAdapter:[15,1,1,""]},"apptools.naming.adapter.list_context_adapter_factory":{ListContextAdapterFactory:[15,1,1,""]},"apptools.naming.adapter.trait_dict_context_adapter":{TraitDictContextAdapter:[15,1,1,""]},"apptools.naming.adapter.trait_dict_context_adapter_factory":{TraitDictContextAdapterFactory:[15,1,1,""]},"apptools.naming.adapter.trait_list_context_adapter":{TraitListContextAdapter:[15,1,1,""]},"apptools.naming.adapter.trait_list_context_adapter_factory":{TraitListContextAdapterFactory:[15,1,1,""]},"apptools.naming.adapter.tuple_context_adapter":{TupleContextAdapter:[15,1,1,""]},"apptools.naming.adapter.tuple_context_adapter_factory":{TupleContextAdapterFactory:[15,1,1,""]},"apptools.naming.address":{Address:[14,1,1,""]},"apptools.naming.binding":{Binding:[14,1,1,""]},"apptools.naming.context":{Context:[14,1,1,""]},"apptools.naming.context.Context":{INITIAL_CONTEXT_FACTORY:[14,5,1,""],OBJECT_FACTORIES:[14,5,1,""],STATE_FACTORIES:[14,5,1,""],TYPE_MANAGER:[14,5,1,""],bind:[14,2,1,""],create_subcontext:[14,2,1,""],destroy_subcontext:[14,2,1,""],get_unique_name:[14,2,1,""],is_context:[14,2,1,""],list_bindings:[14,2,1,""],list_names:[14,2,1,""],lookup:[14,2,1,""],lookup_binding:[14,2,1,""],lookup_context:[14,2,1,""],rebind:[14,2,1,""],rename:[14,2,1,""],search:[14,2,1,""],unbind:[14,2,1,""]},"apptools.naming.context_adapter":{ContextAdapter:[14,1,1,""]},"apptools.naming.context_adapter_factory":{ContextAdapterFactory:[14,1,1,""]},"apptools.naming.dir_context":{DirContext:[14,1,1,""]},"apptools.naming.dir_context.DirContext":{find_bindings:[14,2,1,""],get_attributes:[14,2,1,""],set_attributes:[14,2,1,""]},"apptools.naming.dynamic_context":{DynamicContext:[14,1,1,""]},"apptools.naming.exception":{InvalidNameError:[14,8,1,""],NameAlreadyBoundError:[14,8,1,""],NameNotFoundError:[14,8,1,""],NamingError:[14,8,1,""],NotContextError:[14,8,1,""],OperationNotSupportedError:[14,8,1,""]},"apptools.naming.initial_context":{InitialContext:[14,3,1,""]},"apptools.naming.initial_context_factory":{InitialContextFactory:[14,1,1,""]},"apptools.naming.initial_context_factory.InitialContextFactory":{get_initial_context:[14,2,1,""]},"apptools.naming.naming_event":{NamingEvent:[14,1,1,""]},"apptools.naming.naming_manager":{NamingManager:[14,1,1,""]},"apptools.naming.naming_manager.NamingManager":{get_object_instance:[14,2,1,""],get_state_to_bind:[14,2,1,""]},"apptools.naming.object_factory":{ObjectFactory:[14,1,1,""]},"apptools.naming.object_factory.ObjectFactory":{get_object_instance:[14,2,1,""]},"apptools.naming.object_serializer":{ObjectSerializer:[14,1,1,""]},"apptools.naming.object_serializer.ObjectSerializer":{can_load:[14,2,1,""],can_save:[14,2,1,""],load:[14,2,1,""],save:[14,2,1,""]},"apptools.naming.py_context":{PyContext:[14,1,1,""]},"apptools.naming.py_object_factory":{PyObjectFactory:[14,1,1,""]},"apptools.naming.py_object_factory.PyObjectFactory":{get_object_instance:[14,2,1,""]},"apptools.naming.pyfs_context":{PyFSContext:[14,1,1,""]},"apptools.naming.pyfs_context.PyFSContext":{ATTRIBUTES_FILE:[14,5,1,""],FILTERS:[14,5,1,""],OBJECT_SERIALIZERS:[14,5,1,""],get_unique_name:[14,2,1,""],refresh:[14,2,1,""]},"apptools.naming.pyfs_context_factory":{PyFSContextFactory:[14,1,1,""]},"apptools.naming.pyfs_context_factory.PyFSContextFactory":{get_object_instance:[14,2,1,""]},"apptools.naming.pyfs_initial_context_factory":{PyFSInitialContextFactory:[14,1,1,""]},"apptools.naming.pyfs_initial_context_factory.PyFSInitialContextFactory":{get_initial_context:[14,2,1,""]},"apptools.naming.pyfs_object_factory":{PyFSObjectFactory:[14,1,1,""]},"apptools.naming.pyfs_object_factory.PyFSObjectFactory":{get_object_instance:[14,2,1,""]},"apptools.naming.pyfs_state_factory":{PyFSStateFactory:[14,1,1,""]},"apptools.naming.pyfs_state_factory.PyFSStateFactory":{get_state_to_bind:[14,2,1,""]},"apptools.naming.reference":{Reference:[14,1,1,""]},"apptools.naming.referenceable":{Referenceable:[14,1,1,""]},"apptools.naming.referenceable_state_factory":{ReferenceableStateFactory:[14,1,1,""]},"apptools.naming.referenceable_state_factory.ReferenceableStateFactory":{get_state_to_bind:[14,2,1,""]},"apptools.naming.state_factory":{StateFactory:[14,1,1,""]},"apptools.naming.state_factory.StateFactory":{get_state_to_bind:[14,2,1,""]},"apptools.naming.trait_defs":{api:[16,0,0,"-"],naming_traits:[16,0,0,"-"]},"apptools.naming.trait_defs.naming_traits":{NamingTraitHandler:[16,1,1,""]},"apptools.naming.trait_defs.naming_traits.NamingTraitHandler":{find_class:[16,2,1,""],get_editor:[16,2,1,""],info:[16,2,1,""],post_setattr:[16,2,1,""],resolve_class:[16,2,1,""],validate:[16,2,1,""],validate_failed:[16,2,1,""]},"apptools.naming.ui":{api:[17,0,0,"-"],context_monitor:[17,0,0,"-"],context_node_type:[17,0,0,"-"],explorer:[17,0,0,"-"],naming_node_manager:[17,0,0,"-"],naming_tree:[17,0,0,"-"],naming_tree_model:[17,0,0,"-"],object_node_type:[17,0,0,"-"]},"apptools.naming.ui.context_monitor":{ContextMonitor:[17,1,1,""]},"apptools.naming.ui.context_monitor.ContextMonitor":{start:[17,2,1,""],stop:[17,2,1,""]},"apptools.naming.ui.context_node_type":{ContextNodeType:[17,1,1,""]},"apptools.naming.ui.context_node_type.ContextNodeType":{allows_children:[17,2,1,""],can_set_text:[17,2,1,""],get_children:[17,2,1,""],get_drag_value:[17,2,1,""],get_monitor:[17,2,1,""],get_text:[17,2,1,""],has_children:[17,2,1,""],is_editable:[17,2,1,""],is_type_for:[17,2,1,""],set_text:[17,2,1,""]},"apptools.naming.ui.explorer":{Explorer:[17,1,1,""],explore:[17,3,1,""]},"apptools.naming.ui.explorer.Explorer":{direction:[17,5,1,""],ratio:[17,5,1,""],root:[17,5,1,""],title:[17,5,1,""]},"apptools.naming.ui.naming_node_manager":{NamingNodeManager:[17,1,1,""]},"apptools.naming.ui.naming_node_manager.NamingNodeManager":{get_key:[17,2,1,""]},"apptools.naming.ui.naming_tree":{NamingTree:[17,1,1,""]},"apptools.naming.ui.naming_tree.NamingTree":{ensure_visible:[17,2,1,""],model:[17,5,1,""]},"apptools.naming.ui.naming_tree_model":{NamingTreeModel:[17,1,1,""]},"apptools.naming.ui.object_node_type":{ObjectNodeType:[17,1,1,""]},"apptools.naming.ui.object_node_type.ObjectNodeType":{allows_children:[17,2,1,""],can_set_text:[17,2,1,""],get_drag_value:[17,2,1,""],get_text:[17,2,1,""],is_editable:[17,2,1,""],is_type_for:[17,2,1,""],set_text:[17,2,1,""]},"apptools.naming.unique_name":{make_unique_name:[14,3,1,""]},"apptools.permissions":{"default":[21,0,0,"-"],action:[19,0,0,"-"],adapter_base:[18,0,0,"-"],adapters:[20,0,0,"-"],api:[18,0,0,"-"],i_policy_manager:[18,0,0,"-"],i_user:[18,0,0,"-"],i_user_manager:[18,0,0,"-"],package_globals:[18,0,0,"-"],permission:[18,0,0,"-"],permissions_manager:[18,0,0,"-"],secure_proxy:[18,0,0,"-"]},"apptools.permissions.action":{api:[19,0,0,"-"],login_action:[19,0,0,"-"],logout_action:[19,0,0,"-"],user_menu_manager:[19,0,0,"-"]},"apptools.permissions.action.login_action":{LoginAction:[19,1,1,""]},"apptools.permissions.action.login_action.LoginAction":{perform:[19,2,1,""]},"apptools.permissions.action.logout_action":{LogoutAction:[19,1,1,""]},"apptools.permissions.action.logout_action.LogoutAction":{perform:[19,2,1,""]},"apptools.permissions.action.user_menu_manager":{UserMenuManager:[19,1,1,""]},"apptools.permissions.adapter_base":{AdapterBase:[18,1,1,""]},"apptools.permissions.adapter_base.AdapterBase":{adapt:[18,2,1,""],factory:[18,7,1,""],get_enabled:[18,2,1,""],get_visible:[18,2,1,""],register_adapter:[18,7,1,""],set_enabled:[18,2,1,""],set_visible:[18,2,1,""],setattr:[18,2,1,""],update_enabled:[18,2,1,""],update_visible:[18,2,1,""]},"apptools.permissions.adapters":{pyface_action:[20,0,0,"-"]},"apptools.permissions.adapters.pyface_action":{ActionAdapter:[20,1,1,""]},"apptools.permissions.adapters.pyface_action.ActionAdapter":{get_enabled:[20,2,1,""],get_visible:[20,2,1,""],set_enabled:[20,2,1,""],set_visible:[20,2,1,""],setattr:[20,2,1,""]},"apptools.permissions.default":{api:[21,0,0,"-"],i_policy_storage:[21,0,0,"-"],i_user_database:[21,0,0,"-"],i_user_storage:[21,0,0,"-"],persistent:[21,0,0,"-"],policy_data:[21,0,0,"-"],policy_manager:[21,0,0,"-"],policy_storage:[21,0,0,"-"],role_assignment:[21,0,0,"-"],role_definition:[21,0,0,"-"],select_role:[21,0,0,"-"],select_user:[21,0,0,"-"],user_database:[21,0,0,"-"],user_manager:[21,0,0,"-"],user_storage:[21,0,0,"-"]},"apptools.permissions.default.i_policy_storage":{IPolicyStorage:[21,1,1,""],PolicyStorageError:[21,8,1,""]},"apptools.permissions.default.i_policy_storage.IPolicyStorage":{add_role:[21,2,1,""],all_roles:[21,2,1,""],delete_role:[21,2,1,""],get_assignment:[21,2,1,""],get_policy:[21,2,1,""],is_empty:[21,2,1,""],matching_roles:[21,2,1,""],modify_role:[21,2,1,""],set_assignment:[21,2,1,""]},"apptools.permissions.default.i_user_database":{IUserDatabase:[21,1,1,""]},"apptools.permissions.default.i_user_database.IUserDatabase":{add_user:[21,2,1,""],authenticate_user:[21,2,1,""],bootstrapping:[21,2,1,""],change_password:[21,2,1,""],delete_user:[21,2,1,""],matching_user:[21,2,1,""],modify_user:[21,2,1,""],unauthenticate_user:[21,2,1,""],user_factory:[21,2,1,""]},"apptools.permissions.default.i_user_storage":{IUserStorage:[21,1,1,""],UserStorageError:[21,8,1,""]},"apptools.permissions.default.i_user_storage.IUserStorage":{add_user:[21,2,1,""],authenticate_user:[21,2,1,""],delete_user:[21,2,1,""],is_empty:[21,2,1,""],matching_users:[21,2,1,""],modify_user:[21,2,1,""],unauthenticate_user:[21,2,1,""],update_blob:[21,2,1,""],update_password:[21,2,1,""]},"apptools.permissions.default.persistent":{Persistent:[21,1,1,""],PersistentError:[21,8,1,""]},"apptools.permissions.default.persistent.Persistent":{lock:[21,2,1,""],read:[21,2,1,""],unlock:[21,2,1,""],write:[21,2,1,""]},"apptools.permissions.default.policy_data":{Assignment:[21,1,1,""],Role:[21,1,1,""]},"apptools.permissions.default.policy_manager":{PolicyManager:[21,1,1,""]},"apptools.permissions.default.policy_manager.PolicyManager":{bootstrapping:[21,2,1,""],load_policy:[21,2,1,""],register_permission:[21,2,1,""]},"apptools.permissions.default.policy_storage":{PolicyStorage:[21,1,1,""]},"apptools.permissions.default.policy_storage.PolicyStorage":{add_role:[21,2,1,""],all_roles:[21,2,1,""],delete_role:[21,2,1,""],get_assignment:[21,2,1,""],get_policy:[21,2,1,""],is_empty:[21,2,1,""],matching_roles:[21,2,1,""],modify_role:[21,2,1,""],set_assignment:[21,2,1,""]},"apptools.permissions.default.role_assignment":{role_assignment:[21,3,1,""]},"apptools.permissions.default.role_definition":{role_definition:[21,3,1,""]},"apptools.permissions.default.select_role":{select_role:[21,3,1,""]},"apptools.permissions.default.select_user":{select_user:[21,3,1,""]},"apptools.permissions.default.user_database":{User:[21,1,1,""],UserDatabase:[21,1,1,""]},"apptools.permissions.default.user_database.UserDatabase":{add_user:[21,2,1,""],authenticate_user:[21,2,1,""],bootstrapping:[21,2,1,""],change_password:[21,2,1,""],delete_user:[21,2,1,""],matching_user:[21,2,1,""],modify_user:[21,2,1,""],unauthenticate_user:[21,2,1,""],user_factory:[21,2,1,""]},"apptools.permissions.default.user_manager":{UserManager:[21,1,1,""]},"apptools.permissions.default.user_manager.UserManager":{authenticate_user:[21,2,1,""],bootstrapping:[21,2,1,""],matching_user:[21,2,1,""],unauthenticate_user:[21,2,1,""]},"apptools.permissions.default.user_storage":{UserStorage:[21,1,1,""]},"apptools.permissions.default.user_storage.UserStorage":{add_user:[21,2,1,""],authenticate_user:[21,2,1,""],capabilities:[21,5,1,""],delete_user:[21,2,1,""],is_empty:[21,2,1,""],matching_users:[21,2,1,""],modify_user:[21,2,1,""],unauthenticate_user:[21,2,1,""],update_blob:[21,2,1,""],update_password:[21,2,1,""]},"apptools.permissions.i_policy_manager":{IPolicyManager:[18,1,1,""]},"apptools.permissions.i_policy_manager.IPolicyManager":{bootstrapping:[18,2,1,""],load_user:[18,2,1,""],register_permission:[18,2,1,""]},"apptools.permissions.i_user":{IUser:[18,1,1,""]},"apptools.permissions.i_user_manager":{IUserManager:[18,1,1,""]},"apptools.permissions.i_user_manager.IUserManager":{authenticate_user:[18,2,1,""],bootstrapping:[18,2,1,""],select_user:[18,2,1,""],unauthenticate_user:[18,2,1,""]},"apptools.permissions.package_globals":{get_permissions_manager:[18,3,1,""],set_permissions_manager:[18,3,1,""]},"apptools.permissions.permission":{ManagePolicyPermission:[18,1,1,""],ManageUsersPermission:[18,1,1,""],Permission:[18,1,1,""]},"apptools.permissions.permissions_manager":{PermissionsManager:[18,1,1,""]},"apptools.permissions.permissions_manager.PermissionsManager":{check_permissions:[18,2,1,""]},"apptools.permissions.secure_proxy":{SecureHandler:[18,1,1,""],SecureProxy:[18,1,1,""]},"apptools.permissions.secure_proxy.SecureHandler":{init_info:[18,2,1,""]},"apptools.persistence":{file_path:[22,0,0,"-"],project_loader:[22,0,0,"-"],state_pickler:[22,0,0,"-"],updater:[22,0,0,"-"],version_registry:[22,0,0,"-"],versioned_unpickler:[22,0,0,"-"]},"apptools.persistence.file_path":{FilePath:[22,1,1,""]},"apptools.persistence.file_path.FilePath":{get:[22,2,1,""],set:[22,2,1,""],set_absolute:[22,2,1,""],set_relative:[22,2,1,""]},"apptools.persistence.project_loader":{load_project:[22,3,1,""],upgrade_project:[22,3,1,""]},"apptools.persistence.state_pickler":{State:[22,1,1,""],StateDict:[22,1,1,""],StateList:[22,1,1,""],StatePickler:[22,1,1,""],StatePicklerError:[22,8,1,""],StateSetter:[22,1,1,""],StateSetterError:[22,8,1,""],StateTuple:[22,1,1,""],StateUnpickler:[22,1,1,""],StateUnpicklerError:[22,8,1,""],create_instance:[22,3,1,""],dump:[22,3,1,""],dumps:[22,3,1,""],get_state:[22,3,1,""],gunzip_string:[22,3,1,""],gzip_string:[22,3,1,""],load_state:[22,3,1,""],loads_state:[22,3,1,""],set_state:[22,3,1,""],update_state:[22,3,1,""]},"apptools.persistence.state_pickler.StatePickler":{dump:[22,2,1,""],dump_state:[22,2,1,""],dumps:[22,2,1,""]},"apptools.persistence.state_pickler.StateSetter":{set:[22,2,1,""]},"apptools.persistence.state_pickler.StateUnpickler":{load_state:[22,2,1,""],loads_state:[22,2,1,""]},"apptools.persistence.updater":{Updater:[22,1,1,""]},"apptools.persistence.updater.Updater":{get_latest:[22,2,1,""],strip:[22,2,1,""]},"apptools.persistence.version_registry":{HandlerRegistry:[22,1,1,""],get_version:[22,3,1,""]},"apptools.persistence.version_registry.HandlerRegistry":{register:[22,2,1,""],unregister:[22,2,1,""],update:[22,2,1,""]},"apptools.persistence.versioned_unpickler":{NewUnpickler:[22,1,1,""],VersionedUnpickler:[22,1,1,""]},"apptools.persistence.versioned_unpickler.NewUnpickler":{initialize:[22,2,1,""],load:[22,2,1,""],load_build:[22,7,1,""]},"apptools.persistence.versioned_unpickler.VersionedUnpickler":{add_updater:[22,2,1,""],backup_setstate:[22,2,1,""],find_class:[22,2,1,""],import_name:[22,2,1,""]},"apptools.preferences":{api:[23,0,0,"-"],i_preferences:[23,0,0,"-"],package_globals:[23,0,0,"-"],preference_binding:[23,0,0,"-"],preferences:[23,0,0,"-"],preferences_helper:[23,0,0,"-"],scoped_preferences:[23,0,0,"-"],ui:[24,0,0,"-"]},"apptools.preferences.i_preferences":{IPreferences:[23,1,1,""]},"apptools.preferences.i_preferences.IPreferences":{clear:[23,2,1,""],flush:[23,2,1,""],get:[23,2,1,""],keys:[23,2,1,""],node:[23,2,1,""],node_exists:[23,2,1,""],node_names:[23,2,1,""],remove:[23,2,1,""],set:[23,2,1,""]},"apptools.preferences.package_globals":{get_default_preferences:[23,3,1,""],set_default_preferences:[23,3,1,""]},"apptools.preferences.preference_binding":{PreferenceBinding:[23,1,1,""],bind_preference:[23,3,1,""]},"apptools.preferences.preferences":{Preferences:[23,1,1,""]},"apptools.preferences.preferences.Preferences":{add_preferences_listener:[23,2,1,""],clear:[23,2,1,""],dump:[23,2,1,""],flush:[23,2,1,""],get:[23,2,1,""],keys:[23,2,1,""],load:[23,2,1,""],node:[23,2,1,""],node_exists:[23,2,1,""],node_names:[23,2,1,""],remove:[23,2,1,""],remove_preferences_listener:[23,2,1,""],save:[23,2,1,""],set:[23,2,1,""]},"apptools.preferences.preferences_helper":{PreferencesHelper:[23,1,1,""]},"apptools.preferences.scoped_preferences":{ScopedPreferences:[23,1,1,""]},"apptools.preferences.scoped_preferences.ScopedPreferences":{add_preferences_listener:[23,2,1,""],clear:[23,2,1,""],dump:[23,2,1,""],get:[23,2,1,""],get_scope:[23,2,1,""],keys:[23,2,1,""],load:[23,2,1,""],node:[23,2,1,""],node_exists:[23,2,1,""],node_names:[23,2,1,""],remove:[23,2,1,""],remove_preferences_listener:[23,2,1,""],save:[23,2,1,""],set:[23,2,1,""]},"apptools.preferences.ui":{api:[24,0,0,"-"],i_preferences_page:[24,0,0,"-"],preferences_manager:[24,0,0,"-"],preferences_node:[24,0,0,"-"],preferences_page:[24,0,0,"-"],tree_item:[24,0,0,"-"]},"apptools.preferences.ui.i_preferences_page":{IPreferencesPage:[24,1,1,""]},"apptools.preferences.ui.i_preferences_page.IPreferencesPage":{apply:[24,2,1,""]},"apptools.preferences.ui.preferences_manager":{PreferencesHelpWindow:[24,1,1,""],PreferencesManager:[24,1,1,""],PreferencesManagerHandler:[24,1,1,""]},"apptools.preferences.ui.preferences_manager.PreferencesHelpWindow":{traits_view:[24,2,1,""]},"apptools.preferences.ui.preferences_manager.PreferencesManager":{apply:[24,2,1,""],traits_view:[24,2,1,""]},"apptools.preferences.ui.preferences_manager.PreferencesManagerHandler":{apply:[24,2,1,""],close:[24,2,1,""],init:[24,2,1,""],preferences_help:[24,2,1,""]},"apptools.preferences.ui.preferences_node":{PreferencesNode:[24,1,1,""]},"apptools.preferences.ui.preferences_node.PreferencesNode":{create_page:[24,2,1,""],dump:[24,2,1,""],lookup:[24,2,1,""]},"apptools.preferences.ui.preferences_page":{PreferencesPage:[24,1,1,""]},"apptools.preferences.ui.preferences_page.PreferencesPage":{apply:[24,2,1,""]},"apptools.preferences.ui.tree_item":{TreeItem:[24,1,1,""]},"apptools.preferences.ui.tree_item.TreeItem":{append:[24,2,1,""],insert:[24,2,1,""],insert_after:[24,2,1,""],insert_before:[24,2,1,""],remove:[24,2,1,""]},"apptools.scripting":{api:[25,0,0,"-"],package_globals:[25,0,0,"-"],recordable:[25,0,0,"-"],recorder:[25,0,0,"-"],recorder_with_ui:[25,0,0,"-"],util:[25,0,0,"-"]},"apptools.scripting.package_globals":{get_recorder:[25,3,1,""],set_recorder:[25,3,1,""]},"apptools.scripting.recordable":{recordable:[25,3,1,""]},"apptools.scripting.recorder":{Recorder:[25,1,1,""],RecorderError:[25,8,1,""]},"apptools.scripting.recorder.Recorder":{clear:[25,2,1,""],get_code:[25,2,1,""],get_object_path:[25,2,1,""],get_script_id:[25,2,1,""],is_registered:[25,2,1,""],record:[25,2,1,""],record_function:[25,2,1,""],register:[25,2,1,""],save:[25,2,1,""],ui_save:[25,2,1,""],unregister:[25,2,1,""],write_script_id_in_namespace:[25,2,1,""]},"apptools.scripting.recorder_with_ui":{CloseHandler:[25,1,1,""],RecorderWithUI:[25,1,1,""]},"apptools.scripting.recorder_with_ui.CloseHandler":{close:[25,2,1,""]},"apptools.scripting.recorder_with_ui.RecorderWithUI":{on_ui_close:[25,2,1,""]},"apptools.scripting.util":{start_recording:[25,3,1,""],stop_recording:[25,3,1,""]},"apptools.selection":{api:[26,0,0,"-"],errors:[45,0,0,"-"],i_selection:[45,0,0,"-"],i_selection_provider:[45,0,0,"-"],list_selection:[45,0,0,"-"],selection_service:[45,0,0,"-"]},"apptools.selection.errors":{IDConflictError:[45,8,1,""],ListenerNotConnectedError:[45,8,1,""],ProviderNotRegisteredError:[45,8,1,""]},"apptools.selection.i_selection":{IListSelection:[45,1,1,""],ISelection:[45,1,1,""]},"apptools.selection.i_selection.IListSelection":{indices:[45,5,1,""],items:[45,5,1,""]},"apptools.selection.i_selection.ISelection":{is_empty:[45,2,1,""],provider_id:[45,5,1,""]},"apptools.selection.i_selection_provider":{ISelectionProvider:[45,1,1,""]},"apptools.selection.i_selection_provider.ISelectionProvider":{get_selection:[45,2,1,""],provider_id:[45,5,1,""],selection:[45,5,1,""],set_selection:[45,2,1,""]},"apptools.selection.list_selection":{ListSelection:[45,1,1,""]},"apptools.selection.list_selection.ListSelection":{from_available_items:[45,7,1,""],indices:[45,5,1,""],is_empty:[45,2,1,""],items:[45,5,1,""],provider_id:[45,5,1,""]},"apptools.selection.selection_service":{SelectionService:[45,1,1,""]},"apptools.selection.selection_service.SelectionService":{add_selection_provider:[45,2,1,""],connect_selection_listener:[45,2,1,""],disconnect_selection_listener:[45,2,1,""],get_selection:[45,2,1,""],has_selection_provider:[45,2,1,""],remove_selection_provider:[45,2,1,""],set_selection:[45,2,1,""]},"apptools.sweet_pickle":{dump:[27,3,1,""],dumps:[27,3,1,""],global_registry:[27,0,0,"-"],load:[27,3,1,""],loads:[27,3,1,""],placeholder:[27,0,0,"-"],updater:[27,0,0,"-"],versioned_unpickler:[27,0,0,"-"]},"apptools.sweet_pickle.global_registry":{get_global_registry:[27,3,1,""]},"apptools.sweet_pickle.placeholder":{PlaceHolder:[27,1,1,""]},"apptools.sweet_pickle.updater":{Updater:[27,1,1,""]},"apptools.sweet_pickle.updater.Updater":{add_mapping:[27,2,1,""],add_mapping_to_class:[27,2,1,""],add_mappings:[27,2,1,""],add_state_function:[27,2,1,""],add_state_function_for_class:[27,2,1,""],declare_version_attribute:[27,2,1,""],declare_version_attribute_for_class:[27,2,1,""],get_version_attribute:[27,2,1,""],has_class_mapping:[27,2,1,""],has_state_function:[27,2,1,""],merge_updater:[27,2,1,""]},"apptools.sweet_pickle.versioned_unpickler":{NewUnpickler:[27,1,1,""],VersionedUnpickler:[27,1,1,""],load_build_with_meta_data:[27,3,1,""]},"apptools.sweet_pickle.versioned_unpickler.NewUnpickler":{initialize:[27,2,1,""],load:[27,2,1,""],load_build:[27,7,1,""]},"apptools.sweet_pickle.versioned_unpickler.VersionedUnpickler":{find_class:[27,2,1,""],modify_state:[27,2,1,""]},"apptools.template":{impl:[29,0,0,"-"],imutable_template:[28,0,0,"-"],itemplate:[28,0,0,"-"],itemplate_choice:[28,0,0,"-"],itemplate_data_context:[28,0,0,"-"],itemplate_data_name_item:[28,0,0,"-"],itemplate_data_source:[28,0,0,"-"],mutable_template:[28,0,0,"-"],template_choice:[28,0,0,"-"],template_data_name:[28,0,0,"-"],template_impl:[28,0,0,"-"],template_traits:[28,0,0,"-"],test:[30,0,0,"-"]},"apptools.template.impl":{any_context_data_name_item:[29,0,0,"-"],any_data_name_item:[29,0,0,"-"],api:[29,0,0,"-"],context_data_name_item:[29,0,0,"-"],helper:[29,0,0,"-"],template_data_context:[29,0,0,"-"],template_data_source:[29,0,0,"-"],value_data_name_item:[29,0,0,"-"],value_nd_data_name_item:[29,0,0,"-"]},"apptools.template.impl.any_context_data_name_item":{AnyContextDataNameItem:[29,1,1,""]},"apptools.template.impl.any_context_data_name_item.AnyContextDataNameItem":{filter:[29,2,1,""],inputs_changed:[29,2,1,""]},"apptools.template.impl.any_data_name_item":{AnyDataNameItem:[29,1,1,""]},"apptools.template.impl.any_data_name_item.AnyDataNameItem":{filter:[29,2,1,""],inputs_changed:[29,2,1,""]},"apptools.template.impl.context_data_name_item":{ContextDataNameItem:[29,1,1,""]},"apptools.template.impl.context_data_name_item.ContextDataNameItem":{filter:[29,2,1,""]},"apptools.template.impl.helper":{parse_name:[29,3,1,""],path_for:[29,3,1,""]},"apptools.template.impl.template_data_context":{TemplateDataContext:[29,1,1,""]},"apptools.template.impl.template_data_context.TemplateDataContext":{get_data_context:[29,2,1,""],get_data_context_value:[29,2,1,""]},"apptools.template.impl.template_data_source":{TemplateDataSource:[29,1,1,""]},"apptools.template.impl.template_data_source.TemplateDataSource":{name_from_data_source:[29,2,1,""]},"apptools.template.impl.value_data_name_item":{ValueDataNameItem:[29,1,1,""]},"apptools.template.impl.value_data_name_item.ValueDataNameItem":{filter:[29,2,1,""]},"apptools.template.impl.value_nd_data_name_item":{Value1DDataNameItem:[29,1,1,""],Value2DDataNameItem:[29,1,1,""],Value3DDataNameItem:[29,1,1,""],ValueNDDataNameItem:[29,1,1,""]},"apptools.template.impl.value_nd_data_name_item.ValueNDDataNameItem":{filter:[29,2,1,""]},"apptools.template.imutable_template":{IMutableTemplate:[28,1,1,""]},"apptools.template.itemplate":{ITemplate:[28,1,1,""]},"apptools.template.itemplate.ITemplate":{activate_template:[28,2,1,""],names_from_template:[28,2,1,""],object_from_template:[28,2,1,""],template_from_object:[28,2,1,""]},"apptools.template.itemplate_choice":{ITemplateChoice:[28,1,1,""]},"apptools.template.itemplate_data_context":{ITemplateDataContext:[28,1,1,""],ITemplateDataContextError:[28,8,1,""]},"apptools.template.itemplate_data_context.ITemplateDataContext":{get_data_context:[28,2,1,""],get_data_context_value:[28,2,1,""]},"apptools.template.itemplate_data_name_item":{ITemplateDataNameItem:[28,1,1,""]},"apptools.template.itemplate_data_source":{ITemplateDataSource:[28,1,1,""]},"apptools.template.itemplate_data_source.ITemplateDataSource":{name_from_data_source:[28,2,1,""]},"apptools.template.mutable_template":{MutableTemplate:[28,1,1,""]},"apptools.template.template_choice":{TemplateChoice:[28,1,1,""]},"apptools.template.template_data_name":{TemplateDataName:[28,1,1,""]},"apptools.template.template_impl":{Template:[28,1,1,""],instance_or_datasource:[28,3,1,""],is_none:[28,3,1,""]},"apptools.template.template_impl.Template":{activate_template:[28,2,1,""],names_from_template:[28,2,1,""],object_from_template:[28,2,1,""],template_from_object:[28,2,1,""]},"apptools.template.template_traits":{TDerived:[28,1,1,""],TEnum:[28,3,1,""],TInstance:[28,3,1,""],TList:[28,3,1,""],TRange:[28,3,1,""]},"apptools.template.template_traits.TDerived":{get:[28,2,1,""],metadata:[28,5,1,""],set:[28,2,1,""]},"apptools.type_manager":{abstract_adapter_factory:[31,0,0,"-"],abstract_factory:[31,0,0,"-"],abstract_type_system:[31,0,0,"-"],adaptable:[31,0,0,"-"],adapter:[31,0,0,"-"],adapter_factory:[31,0,0,"-"],adapter_manager:[31,0,0,"-"],api:[31,0,0,"-"],factory:[31,0,0,"-"],hook:[31,0,0,"-"],python_type_system:[31,0,0,"-"],type_manager:[31,0,0,"-"],util:[31,0,0,"-"]},"apptools.type_manager.abstract_adapter_factory":{AbstractAdapterFactory:[31,1,1,""]},"apptools.type_manager.abstract_adapter_factory.AbstractAdapterFactory":{adapt:[31,2,1,""]},"apptools.type_manager.abstract_factory":{AbstractFactory:[31,1,1,""]},"apptools.type_manager.abstract_factory.AbstractFactory":{create:[31,2,1,""]},"apptools.type_manager.abstract_type_system":{AbstractTypeSystem:[31,1,1,""]},"apptools.type_manager.abstract_type_system.AbstractTypeSystem":{get_mro:[31,2,1,""],is_a:[31,2,1,""]},"apptools.type_manager.adaptable":{Adaptable:[31,1,1,""]},"apptools.type_manager.adaptable.Adaptable":{adapt:[31,2,1,""]},"apptools.type_manager.adapter":{Adapter:[31,1,1,""]},"apptools.type_manager.adapter_factory":{AdapterFactory:[31,1,1,""]},"apptools.type_manager.adapter_manager":{AdapterManager:[31,1,1,""]},"apptools.type_manager.adapter_manager.AdapterManager":{adapt:[31,2,1,""],register_adapters:[31,2,1,""],register_instance_adapters:[31,2,1,""],register_type_adapters:[31,2,1,""],unregister_adapters:[31,2,1,""],unregister_instance_adapters:[31,2,1,""],unregister_type_adapters:[31,2,1,""]},"apptools.type_manager.factory":{Factory:[31,1,1,""]},"apptools.type_manager.factory.Factory":{can_create:[31,2,1,""],create:[31,2,1,""]},"apptools.type_manager.hook":{add_post:[31,3,1,""],add_pre:[31,3,1,""],remove_post:[31,3,1,""],remove_pre:[31,3,1,""]},"apptools.type_manager.python_type_system":{PythonObject:[31,1,1,""],PythonTypeSystem:[31,1,1,""]},"apptools.type_manager.python_type_system.PythonTypeSystem":{get_mro:[31,2,1,""],is_a:[31,2,1,""]},"apptools.type_manager.type_manager":{TypeManager:[31,1,1,""]},"apptools.type_manager.type_manager.TypeManager":{add_category:[31,2,1,""],add_post:[31,2,1,""],add_pre:[31,2,1,""],object_as:[31,2,1,""],register_adapters:[31,2,1,""],register_instance_adapters:[31,2,1,""],register_type_adapters:[31,2,1,""],remove_post:[31,2,1,""],remove_pre:[31,2,1,""],unregister_adapters:[31,2,1,""],unregister_instance_adapters:[31,2,1,""],unregister_type_adapters:[31,2,1,""]},"apptools.type_manager.util":{get_classes:[31,3,1,""],sort_by_class_tree:[31,3,1,""]},"apptools.type_registry":{api:[32,0,0,"-"],type_registry:[32,0,0,"-"]},"apptools.type_registry.type_registry":{LazyRegistry:[32,1,1,""],TypeRegistry:[32,1,1,""],get_mro:[32,3,1,""]},"apptools.type_registry.type_registry.LazyRegistry":{lookup_by_type:[32,2,1,""]},"apptools.type_registry.type_registry.TypeRegistry":{lookup:[32,2,1,""],lookup_all:[32,2,1,""],lookup_all_by_type:[32,2,1,""],lookup_by_type:[32,2,1,""],pop:[32,2,1,""],push:[32,2,1,""],push_abc:[32,2,1,""]},"apptools.undo":{abstract_command:[33,0,0,"-"],action:[34,0,0,"-"],api:[33,0,0,"-"],command_stack:[33,0,0,"-"],i_command:[33,0,0,"-"],i_command_stack:[33,0,0,"-"],i_undo_manager:[33,0,0,"-"],undo_manager:[33,0,0,"-"]},"apptools.undo.abstract_command":{AbstractCommand:[33,1,1,""]},"apptools.undo.abstract_command.AbstractCommand":{"do":[33,2,1,""],merge:[33,2,1,""],redo:[33,2,1,""],undo:[33,2,1,""]},"apptools.undo.action":{abstract_command_stack_action:[34,0,0,"-"],api:[34,0,0,"-"],command_action:[34,0,0,"-"],redo_action:[34,0,0,"-"],undo_action:[34,0,0,"-"]},"apptools.undo.action.abstract_command_stack_action":{AbstractCommandStackAction:[34,1,1,""]},"apptools.undo.action.abstract_command_stack_action.AbstractCommandStackAction":{destroy:[34,2,1,""]},"apptools.undo.action.command_action":{CommandAction:[34,1,1,""]},"apptools.undo.action.command_action.CommandAction":{perform:[34,2,1,""]},"apptools.undo.action.redo_action":{RedoAction:[34,1,1,""]},"apptools.undo.action.redo_action.RedoAction":{perform:[34,2,1,""]},"apptools.undo.action.undo_action":{UndoAction:[34,1,1,""]},"apptools.undo.action.undo_action.UndoAction":{perform:[34,2,1,""]},"apptools.undo.command_stack":{CommandStack:[33,1,1,""]},"apptools.undo.command_stack.CommandStack":{begin_macro:[33,2,1,""],clear:[33,2,1,""],end_macro:[33,2,1,""],push:[33,2,1,""],redo:[33,2,1,""],undo:[33,2,1,""]},"apptools.undo.i_command":{ICommand:[33,1,1,""]},"apptools.undo.i_command.ICommand":{"do":[33,2,1,""],merge:[33,2,1,""],redo:[33,2,1,""],undo:[33,2,1,""]},"apptools.undo.i_command_stack":{ICommandStack:[33,1,1,""]},"apptools.undo.i_command_stack.ICommandStack":{begin_macro:[33,2,1,""],clear:[33,2,1,""],end_macro:[33,2,1,""],push:[33,2,1,""],redo:[33,2,1,""],undo:[33,2,1,""]},"apptools.undo.i_undo_manager":{IUndoManager:[33,1,1,""]},"apptools.undo.i_undo_manager.IUndoManager":{redo:[33,2,1,""],undo:[33,2,1,""]},"apptools.undo.undo_manager":{UndoManager:[33,1,1,""]},"apptools.undo.undo_manager.UndoManager":{redo:[33,2,1,""],undo:[33,2,1,""]},apptools:{appscripting:[2,0,0,"-"],help:[4,0,0,"-"],io:[7,0,0,"-"],logger:[9,0,0,"-"],lru_cache:[13,0,0,"-"],naming:[14,0,0,"-"],permissions:[18,0,0,"-"],persistence:[22,0,0,"-"],preferences:[23,0,0,"-"],scripting:[25,0,0,"-"],selection:[26,0,0,"-"],sweet_pickle:[27,0,0,"-"],template:[28,0,0,"-"],type_manager:[31,0,0,"-"],type_registry:[32,0,0,"-"],undo:[33,0,0,"-"]}},objnames:{"0":["py","module","Python module"],"1":["py","class","Python class"],"2":["py","method","Python method"],"3":["py","function","Python function"],"4":["py","staticmethod","Python static method"],"5":["py","attribute","Python attribute"],"6":["py","data","Python data"],"7":["py","classmethod","Python class method"],"8":["py","exception","Python exception"]},objtypes:{"0":"py:module","1":"py:class","2":"py:method","3":"py:function","4":"py:staticmethod","5":"py:attribute","6":"py:data","7":"py:classmethod","8":"py:exception"},terms:{"abstract":[7,22,24,29,31,33,34,46],"boolean":[9,14,42,46],"break":27,"case":[2,10,22,23,27,28,31,36,40,42,45],"class":[2,3,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,31,32,33,34,36,38,41,42,43,44,45,46],"default":[1,2,8,9,12,13,16,18,22,23,24,25,26,27,28,31,33,34,36,37,38,42,43,45,46],"final":[27,45],"float":[12,14,17,22,42,44],"function":[2,6,9,14,16,22,25,27,31,38,44,45],"import":[9,22,27,32,36,38,41,42,44,45],"int":[22,36,38,42],"long":[22,42,46],"new":[2,8,12,14,16,18,21,22,23,25,27,28,31,32,34,36,38,40,42,45],"null":[5,6,9,19],"public":[2,10,25,36,45],"return":[2,8,9,11,12,13,14,16,17,18,21,22,23,24,25,26,27,28,29,31,32,33,34,36,38,41,42,43,45,46],"static":[2,14],"transient":[28,42],"true":[2,8,9,11,14,17,18,21,22,23,25,26,27,28,29,31,33,36,40,42,43,44,45,46],"try":[18,23,33,41,42,46],"while":[12,22,33,38,45,46],AND:27,Adding:36,Age:38,And:42,But:[27,42],ETS:[9,38,39,40,44],For:[8,9,16,22,25,27,36,38,40,42,44,45],Has:[26,45],Ids:38,Its:[21,22,33,46],NOT:27,Not:14,One:[36,44],That:[8,27,28],The:[2,5,8,9,10,11,12,14,16,17,18,21,22,23,24,25,26,27,28,29,31,32,33,34,36,37,38,39,40,41,43,46],Then:23,There:23,These:[32,36,38],Used:22,Useful:[25,31],Using:[37,42,44,46],With:36,__array__:8,__attributes__:14,__class__:22,__dict__:22,__getstate__:22,__init__:[2,22,33,46],__main__:22,__metadata__:22,__module__:32,__name__:[22,32],__set_pure_state__:22,__setitem__:8,__setstate__:[22,27],__version__:22,_image_not_found:6,_new_person:38,_new_person_action_default:38,_pickl:22,_unpickl:27,aaa:36,abandon:[33,46],abc:[2,8,32],abcmeta:32,abil:[28,40,41],abl:[40,42,44],about:[9,14,22,27,33,41,42,44,45],abov:[9,27,36,44],absolut:[8,22,32],abstract_adapter_factori:[1,35],abstract_command:[1,35],abstract_command_stack_act:[1,33],abstract_factori:[1,35],abstract_type_system:[1,35],abstractadapterfactori:31,abstractcommand:33,abstractcommandstackact:34,abstractfactori:31,abstracttypesystem:31,accept:[14,16,27,38],access:[8,13,18,21,23,28,37,38,40,41,45],accord:[18,38,41],account:[21,41],aclass:16,acm:[23,42,43],across:9,act:[14,27,38,45],action:[1,2,4,5,18,20,28,33,36,37,41,44,45,46],action_set:5,actionadapt:20,activ:[12,26,28,33,34,46],activate_templ:28,activated_text:12,active_stack:46,active_stack_clean:46,actual:[9,12,14,16,21,22,25,27,38,42],adapt:[1,5,12,14,18,35,37],adapte:31,adaptee_class:31,adapter_bas:[1,20,35,38],adapter_factori:[1,14,35],adapter_manag:[1,35],adapterbas:[18,20,38],adapterfactori:[14,31],adaptermanag:31,add:[2,8,9,12,21,22,23,25,26,27,31,38,40,41,42,45,46],add_categori:31,add_log_queue_handl:9,add_map:27,add_mapping_to_class:27,add_post:31,add_pr:31,add_preferences_listen:23,add_rol:21,add_selection_provid:[26,45],add_state_funct:27,add_state_function_for_class:27,add_to_h5fil:8,add_to_namespac:2,add_updat:22,add_us:[21,40],added:[2,23,26,27,36,38,45],addhandl:9,adding:[14,27],addit:[8,14,27,28,38,40],addition:[22,27],address:[1,35],administr:41,adpter:31,advanc:27,advantag:36,affect:23,after:[8,18,22,24,25],again:41,age:[38,44],age_perm:38,agent:[1,9],alia:10,all:[2,5,7,9,11,12,13,14,18,19,21,22,23,24,25,26,27,28,29,31,32,33,34,36,38,40,41,42,44,45,46],all_item:[26,45],all_rol:21,alloc:46,allow:[8,9,12,14,16,17,18,22,23,27,28,29,31,33,36,38,40,41,42,43,44,46],allows_children:[17,24],almost:[22,25],along:[22,33,36],alreadi:[2,7,8,14,25,26,36,45],also:[8,14,22,23,25,27,28,33,36,38,41,42,43,44,45,46],alter:8,altern:[16,22,28,36,37,39,40,46],although:29,alwai:[2,23,36,42,44],amount:12,ani:[2,7,9,10,12,13,14,21,22,23,26,27,28,29,33,34,36,38,41,42,43,44,45,46],annot:2,anoth:[2,14,27,33,36,40,42],answer:[22,41],any_context_data_name_item:[1,28],any_data_name_item:[1,28],anycontextdatanameitem:29,anydatanameitem:29,anymor:45,anyth:9,anywher:42,api:[1,4,11,27,35,37,42],app:22,appear:[22,46],append:[8,9,23,24,44],appl:24,appli:[2,22,24,27,37],applic:[2,5,9,14,17,18,22,23,28,29,33,37,41,42,43,44,45,46],application_hom:[41,42],application_scop:23,application_vers:22,approach:[36,42],appropri:[2,22,27,31,33,36,38,41,46],appscript:[1,25,35,36],apptool:[0,36,38,41,42,44],arbitrari:[16,41,44],architectur:41,arg:[2,5,8,10,12,17,25,28,31,46],arg_as_str:2,argmument:8,args_as_string_list:2,argument:[2,8,13,25,26,27,33,34,36,38,44,45,46],around:[2,8,42,46],arrai:[8,22,29],arrang:42,array_or_shap:8,array_proxy_kei:8,arriv:12,ascend:14,ascii:27,ask:[14,23,25],assert:22,assign:[12,16,18,21,28,38,39,41],assist:14,associ:[14,21,28,29,41,42],assum:[2,5,8,22,27,28],atom:8,attach:[1,9,18,38,41,44],attempt:[7,14,27],attribut:[2,8,13,14,16,18,20,21,22,25,27,28,38,42,44],attribute_nam:27,attributes_fil:14,authent:[18,19,21,37,41],authenticate_us:[18,21,38],author:[5,6],authoris:[18,21,40,41],auto:[0,2,36],auto_flush:8,auto_group:8,auto_open:8,automat:[2,8,14,23,25,36,37,38,42,46],avail:[12,25,26,31,36,38,41,43,45,46],avoid:[14,22],back:[22,23,42],background:44,backup_setst:22,backupcount:9,bad:38,bar:[27,36],base64:22,base:[2,3,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,31,32,33,34,36,38,40,41,44,45,46],base_f_nam:22,base_toolkit:10,basic:[21,22,25,27,37,41],baz:[27,36],bbb:36,bear:36,becaus:[10,14,22,27,36,42,45],becom:[27,38,41,45,46],been:[2,9,18,21,25,26,27,28,32,33,38,40,44,45,46],befor:[9,22,24,26,33,42,45,46],begin:[2,14,27,33,36,40,46],begin_macro:[33,46],behav:[18,38],behavior:8,behaviour:[31,42,43],behest:27,being:[2,5,14,16,22,24,27,29,33,36,38,40,44,46],believ:42,below:[8,27,38],benefit:27,best:[22,44],better:[23,36],between:[18,22,23,41,44,45],beyond:27,bgcolor:[23,42,43],binari:38,bind:[1,2,23,28,29,35,36],bind_ev:[1,35,36],bind_factori:[2,36],bind_polici:[2,36],bind_prefer:23,bindabl:28,bindev:2,biometr:40,bit:[31,42],black:42,blank:5,blob:[21,38,40,41],blog:9,blue:[23,42,43],bogu:42,bool:[8,22,25,26,36,40,42,44,45],bootstrap:[18,21,40],both:[32,38,41,46],bound:[2,14,28,36],brief:[38,46],broken:31,broker:45,brows:22,browser:6,bsd:[5,6],buffer:[8,9],bug:11,build:42,builtin:22,bump:22,bunch:22,button:[12,24,42,45],bypass:36,cach:13,calcul:[8,12,14],call:[2,8,9,14,16,21,22,23,25,26,27,29,33,34,36,38,40,41,42,44,45,46],callabl:[26,31,45,46],callback:[26,44,45],came:23,can:[2,8,9,10,14,16,17,18,22,23,26,27,28,31,32,33,36,38,40,41,42,44,45,46],can_:40,can_add_us:[21,40],can_change_password:21,can_creat:31,can_delete_us:21,can_load:14,can_modify_us:21,can_sav:14,can_set_text:17,cannot:[14,28,31,36],capabl:[14,21,27,40],care:[22,42,46],carrot:24,categori:[14,27,31],category_class:31,cauliflow:24,caus:[27,38],caveat:1,cc_address:10,ccaddr:[10,11],ccc:36,central:45,certain:36,chain:27,chang:[2,3,14,17,18,21,23,24,25,26,27,28,29,33,36,38,42,44,45,46],change_password:21,charact:[2,36,46],check:[18,22],check_permiss:18,child:[23,24,42,44],children:[8,17,23,33,44],children_nam:8,choos:[27,36],chunk:8,clarifi:41,class_nam:[22,27],classmethod:[8,18,22,26,27,45],clean:[25,33,46],cleaner:8,clear:[2,13,23,25,33,46],click:24,close:[8,24,25,45],closehandl:25,code:[5,10,14,22,25,27,38,40,44],code_editor:12,collaps:46,collect:[8,9,26,28,31,42,45],color:44,column:[8,12],column_width:12,combin:16,come:[31,42],command:[23,33,34,44,46],command_act:[1,33],command_stack:[1,35,46],commandact:34,commandstack:33,comment:[10,11],common:[22,27,31,45,46],commuic:14,commun:[14,45],complet:[2,16,22,27,36,38,41,46],complex:[22,36,42,45],complic:[22,27,42],compon:[14,36,41,45,46],compos:14,compound:29,compris:41,concept:[37,38],concern:22,concret:[28,29],configobj:[23,42],configur:[36,41,46],conform:14,confus:46,connect:[26,45],connect_selection_listen:[26,45],consequ:41,consid:44,consist:[14,27,36,42],constitut:36,construct:27,consumpt:45,contain:[0,8,9,13,14,19,21,22,24,25,26,27,28,29,33,36,38,41,42,45,46],content:[35,45],context:[1,8,15,17,22,28,29,35],context_adapt:[1,15,35],context_adapter_factori:[1,15,35],context_data_name_item:[1,28],context_monitor:[1,14],context_nam:14,context_node_typ:[1,14],context_ord:14,contextadapt:[14,15],contextadapterfactori:[14,15],contextdatanameitem:29,contextmonitor:17,contextnodetyp:17,continu:14,contribut:[5,14,43],contributes_to:43,contributor:27,control:[5,8,24,41,45],conveni:[9,22,25,27,38,42,44,45,46],convent:38,convention:38,convers:[2,22],convert:[8,12,22,27,28,42],cookbook:[9,18],cooper:41,copi:[7,9,25,33,46],copy_button:12,copyright:[5,6],core:[9,44],core_plugin_definit:9,corpor:41,correct:22,correctli:[22,38],correspond:[2,13,27,36,38,40,41,45],could:[36,40,45],couldn:46,cours:23,coveni:27,cover:41,cpickl:27,creat:[2,7,8,9,12,14,18,21,22,23,24,25,26,28,29,31,33,36,38,40,42,44,45,46],create_:8,create_arrai:8,create_carrai:8,create_dict:8,create_email_messag:[10,11],create_fil:7,create_fold:7,create_group:8,create_inst:22,create_log_file_handl:9,create_packag:7,create_pag:24,create_scriptable_object:2,create_scriptable_typ:[2,36],create_subcontext:14,create_t:8,creation:[14,27,36],criteria:14,current:[14,18,19,21,22,23,24,25,26,27,31,36,38,41,42,44,45,46],custom:[24,27],custom_excepthook:[1,35],data:[8,11,14,21,22,24,27,28,29,33,36,37,41,46],databas:[21,39,40,41],datafram:8,datamodel:36,date:38,debug:[25,42],debughandl:9,decid:22,declare_version_attribut:27,declare_version_attribute_for_class:27,decor:[2,25,36,44],decreas:12,deep:[33,46],def:[2,22,36,38,42,43,44],default_prefer:23,default_valu:28,defin:[2,5,12,13,16,18,21,22,25,28,29,31,36,37,39,40,41,44,45,46],definit:[5,14,21,23,27,28,41,44],delai:2,deleg:40,delet:[7,8,21,27,38,41],delete_exist:8,delete_rol:21,delete_us:21,demo:[5,6],demo_act:[1,4,5],demoact:6,demoimageresourc:6,demonstr:[36,38,46],demosmenumanag:5,demospreferencespag:5,deni:[38,41],depend:[22,23,27,28,29,36,38,41,45],deploi:37,deriv:28,desc:21,descend:23,describ:[14,16,22,28,29,40,43],descript:[2,8,13,16,21,28,29,36,38],design:[27,36,39,40],desir:[8,14,38,43],destin:7,destroi:[14,34,45],destroy_subcontext:14,detail:[21,22,27,41,44],detect:17,determin:[2,14,18,21,22,31,36,38,40,41],develop:[23,36,38,39,40,41,45,46],dialog:[24,25,38,45],dict:[2,8,13,15,22,25,36],dict_context_adapt:[1,14],dict_context_adapter_factori:[1,14],dict_nod:[1,7],dictat:43,dictcontextadapt:15,dictcontextadapterfactori:15,dictionari:[8,9,13,14,15,22,27,42],did:[23,42],differ:[8,14,22,27,36,38,41],difficult:[36,38],dimension:29,dir_context:[1,35],dircontext:14,direct:[17,45],directi:22,directli:[21,23,36,42,45],directori:[14,38,41,42],disabl:[18,33,38,41,46],disadvantag:36,disappear:45,discard:[2,33],disconnect:[26,45],disconnect_selection_listen:[26,45],discuss:[42,43],disk:[8,22,42,46],displai:[5,6,9,21,38,39,40,45],distinct:45,divid:12,doc:[5,6],doc_act:[1,4,5],docact:6,docimageresourc:6,docstr:8,document:[2,5,6,8,36,41,42,44,46],documentsmenumanag:5,documentspreferencespag:5,doe:[2,7,8,9,13,14,17,22,23,25,34,36,41,42,43],doesn:[24,42],doing:27,don:[9,21,31,42,43],done:[25,27,38,41,44,45,46],dot:[2,36,38],download:5,downloadsmenumanag:5,drag:17,drawback:23,drop:[13,27],dtype:8,dual:31,due:27,dump:[22,23,24,27,42],dump_stat:22,duplic:[22,26,27,45],dure:[22,27],dynam:[12,14],dynamic_context:[1,35],dynamiccontext:14,each:[9,12,13,14,21,22,23,27,28,31,32,36,40,41,42,44,46],easi:[8,9,22,23],easier:[39,41],easili:[22,44],edit:[16,17,22,46],editor:[12,16,22,45,46],effect:[33,36,46],egg:41,either:[2,8,16,22,23,31,41,42,44],element:[9,14,21,26,28,29,45,46],elimin:22,els:[8,22,27,32],email:11,embed:[22,36],emit:9,empti:[14,21,23,26,27,33,36,40,45,46],enabl:[18,20,27,38,41],enable_editor:[1,28],enabled_when:38,encapsul:22,encod:[22,27],encount:27,encourag:23,end:[9,14,22,25,33,36,44,46],end_macro:[33,46],endo:[36,41,46],endpoint:14,enforc:[21,40],enlib:10,enough:44,enqueu:9,ensur:[18,22,27,33,36,38,46],ensure_vis:17,enterpris:38,enthought:[2,4,5,6,7,9,14,18,22,23,25,27,28,31,33,36,41,46],enthoughtbas:9,entir:[22,25],entri:46,environ:[14,41],envisag:[4,5,9,10,11,14,27,37,42,45],equal:12,error:[1,16,21,27,35,39,40],especi:45,etc:[9,14,22,23,28,34,42],ets:38,ets_perms_data_dir:41,ets_perms_policydb:41,ets_perms_userdb:41,etsconfig:[41,42],evalu:38,even:[26,27,45],event:[2,3,6,14,19,26,34,36,39,40,45,46],ever:[21,33,46],everi:[9,27],everyth:22,exactli:[18,31,42],examin:14,exampl:[5,6,8,9,16,22,23,24,27,36,38,40,41,42,45,46],example_act:[1,4,5],exampleact:6,examples_prefer:[1,4],examplesmenumanag:5,examplesprefer:5,examplespreferencespag:5,excel:42,except:[1,2,9,16,21,22,23,25,26,28,35,36,39,40,45],exclud:[2,9,22,36],exec:36,execut:[2,9,25,27,33,44,46],exist:[7,8,14,21,22,23,24,25,31,36,41,42],exists_error:8,expect:[21,26,31,41,45],explan:[12,36],explicit:[27,36,42],explicitli:[2,8,14,23,26,27,36,43,45,46],explor:[1,14],expos:[8,11,27,36,45],express:[18,21],extend:[8,14,28,40],extens:[10,31,43,45],extern:[40,41,45],extra:[21,43],extract:38,extrem:27,facil:[41,44],fact:27,factori:[1,2,14,15,18,21,35,36,46],factoryfor:15,factorywrapp:2,fail:21,fairli:44,fake:31,fallback:38,fals:[2,8,9,10,11,12,14,17,23,24,25,26,29,38,42,44,45],featur:[1,36,46],few:44,fgcolor:42,file:[1,2,9,10,11,14,17,21,22,23,25,27,35,36,39,40,41,42,43],file_nam:[2,21,36],file_or_filenam:23,file_path:[1,35],filenam:[5,6,8,9,23,42],filenod:8,filepath:22,filesystem:[41,42],filiba:18,fill:[26,45],filter:[9,14,29],filtered_emit:9,filtering_handl:[1,35],filteringhandl:9,find:[14,23,25,44],find_bind:14,find_class:[16,22,27],fire:[2,14,26,36,45,46],first:[2,8,22,36,41,42,44,45],fix:[12,22],fix_import:27,fixm:[9,10,23,31,38],flexibl:[22,39,40],flush:[8,23,42],folder:[7,17],follow:[25,36,38,41,42,44,46],foo:[27,36],forc:[2,12,23,36],form:[22,24],format:[11,14,22,42],formatt:9,formatted_record:12,forwardproperti:12,found:[14,26,29,41,45],fraction:12,fragment:38,framework:[2,14,25,27,37,38,39,40,44],fred:42,free:43,friend:[22,44],from:[2,5,9,11,13,14,16,21,22,23,24,25,26,27,28,31,33,36,38,41,42,44,45],from_address:10,from_available_item:[26,45],fromaddr:[10,11],fruit:24,full:[21,44],fulli:[9,27,28,32,39,40],func:[2,25,26,45],fundament:36,further:[37,38,41],gather:27,gener:[0,9,14,17,22,24,27,31,36,38,41,42,46],get:[2,8,9,13,14,17,18,20,22,23,27,28,32,37,41,42,43,44,45],get_assign:21,get_atom:8,get_attribut:14,get_children:17,get_class:31,get_cod:25,get_data_context:[28,29],get_data_context_valu:[28,29],get_default_prefer:23,get_drag_valu:17,get_editor:16,get_en:[18,20,38],get_global_registri:27,get_initial_context:14,get_kei:17,get_latest:22,get_module_nam:9,get_module_name_from_zip:9,get_monitor:17,get_mro:[31,32],get_object_inst:14,get_object_path:25,get_permissions_manag:[18,38],get_polici:21,get_prefer:43,get_record:25,get_scop:[23,42],get_script_id:25,get_script_manag:[2,36],get_select:[26,45],get_stat:22,get_state_to_bind:14,get_sys_prefix_relative_filenam:6,get_text:17,get_unique_nam:14,get_vers:22,get_version_attribut:27,get_vis:[18,20,38],get_width:12,get_zip_path:9,getter:2,give:[22,36,38,46],given:[2,8,12,14,18,21,22,23,25,26,27,32,33,38,44,45,46],global:[23,25,27,44],global_registri:[1,35],gloriou:37,goal:27,going:[22,44],gone:27,grant:[38,41],great:34,group:[8,12,41],group_path:8,group_subpath:8,grow:44,guarante:[25,33,46],gui:[38,40,41,45,46],guid:16,gunzip_str:22,gzip:22,gzip_str:22,h5_group:8,h5_group_wrapp:8,h5attr:8,h5dictnod:8,h5file:8,h5filter:8,h5group:8,h5tablenod:8,hack:9,halt:9,handi:[31,44],handl:[2,21,22,24,27,28,29,38,45,46],handler:[9,12,16,18,22,24,25,38],handlerregistri:22,happen:[2,14,36],happi:42,hard:10,has:[2,9,12,14,17,18,22,24,25,26,27,28,31,32,36,38,40,41,42,45,46],has_children:17,has_class_map:27,has_inst:22,has_new_record:9,has_selection_provid:[26,45],has_side_effect:[2,36],has_state_funct:27,has_trait:[2,5,7,10,11,13,14,18,21,23,24,25,26,27,28,29,31,33,45],hasprivatetrait:[7,14,27,28,29],hasstricttrait:[13,44],hastrait:[2,10,11,14,18,21,23,24,25,26,27,31,33,36,38,44,45],have:[2,12,18,21,22,23,27,28,31,33,36,38,40,41,42,44,45,46],hdf5:8,heirarchi:14,help:[1,8,9,22,24,27,35],help_cod:[1,4],help_demo:5,help_doc:[1,4],help_download:5,help_exampl:5,help_id:10,help_plugin:[1,4],help_submenu_manag:[1,4],helpcod:5,helpdemopreferencespag:5,helpdoc:5,helpdocpreferencespag:5,helper:[1,28,42,43],helpexamplepreferencespag:5,helpplugin:5,helppreferencespag:5,helpsubmenumanag:5,henc:[42,43],here:[2,9,10,22,23,27,42,44],hid_quality_agent_dlg:10,hidden:[38,41],hide:38,hierarch:42,hierarchi:[22,23,25,27,28,31,42,44],high:44,highli:[22,23],hold:[38,42],home:41,hook:[1,27,35],hopefulli:[41,42],horizont:12,how:[14,18,21,27,36,38,41,42,43,46],howev:[22,27,28,38,46],html:[36,41,46],human:[38,44],i_bind_ev:[1,35],i_command:[1,35],i_command_stack:[1,35],i_context_adapt:[1,28],i_help_cod:[1,4],i_help_doc:[1,4],i_policy_manag:[1,35],i_policy_storag:[1,18],i_prefer:[1,35],i_preferences_pag:[1,23],i_script_manag:[1,35],i_select:[1,35,45],i_selection_provid:[1,35],i_undo_manag:[1,35],i_us:[1,35],i_user_databas:[1,18],i_user_manag:[1,35],i_user_storag:[1,18],ibindev:2,icommand:33,icommandstack:[33,46],idconflicterror:[26,45],idea:[22,38,42],ideal:[22,45],ident:41,identifi:[8,26,27,41,45,46],ids:38,ignor:[2,22,25,26,36,44,45,46],ignore_miss:[26,45],ihelpcod:5,ihelpdoc:5,ilistselect:[26,45],imag:[24,42],image_resourc:6,imageresourc:6,imform:42,immedi:46,immut:28,impl:[1,28],implement:[2,5,6,8,16,18,21,22,23,26,27,28,29,31,32,33,37,38,39,40,42,43,45,46],implent:23,import_nam:22,improv:27,imutable_templ:[1,35],imutabletempl:28,inadequ:22,inappropri:[39,46],inc:[5,6],includ:[2,9,13,16,22,23,27,29,31,33,36,38,41,46],include_environ:11,include_project:10,include_userdata:[10,11],increas:[12,44],increment:[22,27,46],indent:[23,24],independ:[36,46],index:[24,46],indic:[9,14,16,26,45,46],individu:31,info:[14,16,18,24,25],info_text:16,inform:[8,14,16,21,22,26,27,41,42,44,45],infrastructur:[41,44],inherit:[23,31,42],ini:[42,43],init:24,init_info:18,initarg:22,initi:[8,14,22,23,24,26,27,38,40,45],initial_context:[1,35],initial_context_factori:[1,35],initialcontext:14,initialcontextfactori:14,inject:25,input:[8,28,29],input_data_context:28,inputs_chang:29,insecur:21,insert:24,insert_aft:24,insert_befor:24,insid:44,instac:27,instanc:[2,8,12,14,15,16,17,18,21,22,23,25,26,27,31,32,33,34,36,38,44,45,46],instance_context_adapt:[1,14],instance_context_adapter_factori:[1,14],instance_or_datasourc:28,instancecontextadapt:15,instancecontextadapterfactori:15,instanti:[25,27,44],instead:[16,22,36,41,45],insuffici:[22,40],integ:[12,16,46],integr:[37,41],intend:[2,29,46],intent:23,interact:[14,27],intercept:[8,20,38],interdepend:36,interest:[14,42],interfac:[2,5,8,12,16,18,21,23,24,25,26,28,29,31,33,36,38,39,40,41,42,44,45,46],intermedi:[7,14,27,36],intermediari:2,intern:[26,44,45],interpret:[18,21,22,25,36],intervent:2,introduct:37,invalid:14,invalidnameerror:14,invert:25,invok:[2,25,36,38,46],ipermissionsmanag:18,ipolicymanag:[18,41],ipolicystorag:[21,37,41],iprefer:[23,42],ipreferencespag:24,irrelev:38,irrespect:[2,36,46],is_a:31,is_context:14,is_dict_nod:8,is_edit:17,is_empti:[21,26,45],is_non:28,is_ok:[24,25],is_open:8,is_regist:25,is_table_nod:8,is_type_for:17,is_zip_path:9,iscriptabledatamodel:36,iscriptmanag:[2,36],iselect:[26,45],iselectionprovid:[26,45],ish:31,isn:[2,21,36,39,40,41,42],issu:22,item:[5,8,12,13,14,18,24,26,31,41,45,46],itempl:[1,35],itemplate_choic:[1,35],itemplate_data_context:[1,35],itemplate_data_name_item:[1,35],itemplate_data_sourc:[1,35],itemplatechoic:28,itemplatedatacontext:[28,29],itemplatedatacontexterror:[28,29],itemplatedatanameitem:[28,29],itemplatedatasourc:[28,29],items:8,iter:8,iter_group:8,iterator_length:8,iteritem:8,its:[2,9,12,14,17,21,22,23,24,25,26,27,28,29,32,41,42,44,45,46],itself:[5,14,22,23,25,28,36,38,42,43,44,46],iundomanag:[33,46],iuser:[18,21,38,40,41],iuserdatabas:[21,37,41],iusermanag:[18,41],iuserstorag:[21,37,41],janet:[5,6],join:[8,29],join_path:8,json:8,jump:27,just:[9,22,23,38,42,43,44],keep:[22,33,45],kei:[8,13,17,22,23,36,44],kept:27,keyboard:46,keyerror:32,keyword:[2,8,25,44,45],kind:9,klass:[22,27,31],know:[22,27],knowledg:22,known:[21,22,25,27],kwarg:[2,8,10,12,17],kws:27,label:[5,17],larg:22,last:[22,32,33,34,36,46],later:[2,9,22,33,38],latest:22,latter:27,layer:[41,42],lazi:[2,27,46],lazili:32,lazy_namespac:[1,35],lazynamespac:2,lazyregistri:32,ldap:41,learn:44,least:[13,31,38],leav:[12,21,33,46],let:[42,44],level:[9,14,21,44],lib:10,librari:[9,44],licens:[5,6],like:[2,8,9,18,22,23,31,36,38,42,43,44],limit:[18,37,41,42],line:[23,25,44],link:[18,46],list:[2,8,9,12,13,14,15,18,21,22,25,26,27,28,31,32,36,38,44,45],list_bind:14,list_context_adapt:[1,14],list_context_adapter_factori:[1,14],list_nam:14,list_select:[1,35],listcontextadapt:15,listcontextadapterfactori:15,listen:[17,23,25,26,34,37,42,44],listenernotconnectederror:[26,45],listselect:[26,45],littl:12,live:[14,28],load:[9,14,18,21,22,23,27,42,43,46],load_build:[22,27],load_build_with_meta_data:27,load_polici:21,load_project:22,load_stat:22,load_url_act:[1,4,5],load_us:18,loads_stat:22,loadurlact:6,local:[14,21,39,40,41],locat:[14,39,40,41,44],lock:21,log:[9,11,12],log_point:[1,35],log_queue_handl:[1,35],log_record:12,log_records_editor:12,logfilehandl:9,logger:[1,35],logger_plugin:[1,9],logger_prefer:[1,9],logger_preferences_pag:[1,9,11],logger_servic:[1,9],logger_view:[1,9,11],loggerplugin:11,loggerprefer:11,loggerpreferencespag:12,loggerservic:11,loggerview:12,logic:25,login:[18,38],login_act:[1,18],loginact:[19,38],logout:[18,38],logout_act:[1,18],logoutact:[19,38],logqueuehandl:9,logrecord:12,logrecordadapt:12,longer:[22,34,45],look:[8,13,14,23,29,32,41,42,44],lookup:[14,24,32],lookup_al:32,lookup_all_by_typ:32,lookup_bind:14,lookup_by_typ:32,lookup_context:14,lose:27,lot:22,low:21,lower:[2,36],lowest:42,lru_cach:[1,35],lrucach:13,macro:[33,46],made:[2,14,24,33,36,42,43,46],mai:[2,5,14,18,21,22,25,27,28,29,33,36,38,41,44,46],mail_fil:11,main:[17,45],maintain:[8,32,41,44,46],major:[22,36,41,46],make:[2,7,9,16,17,22,23,27,36,38,39,41,42,45],make_context:14,make_object_script:[2,36],make_unique_nam:14,make_writ:7,manag:[2,5,8,14,17,18,21,22,23,24,27,31,33,36,37,42,45,46],management_act:38,managepolicypermiss:18,manageuserspermiss:18,mani:[22,27,36,42,46],manipul:46,manner:[27,44],manual:25,map:[8,22,27,44],mark:[2,25,28,36,44,46],match:[14,21,25,28,29,32],matching_rol:21,matching_us:21,matter:27,max_pass:[22,27],maxbyt:9,maximum:12,mayavi:44,mean:[12,22,27,28,36,42],mechan:[14,37,43],meet:41,mention:42,menu:[5,19,38,46],menu_manag:[5,19],menumanag:[5,19],merg:[23,27,33,46],merge_updat:27,messag:[9,10,11,21,39,40],meta:27,metadata:[2,14,22,25,28,44],method:[2,8,9,14,16,22,23,25,27,28,29,31,32,33,34,36,38,39,40,42,44,45,46],method_nam:31,might:[22,41,42,43,45],minu:12,miss:[7,14,23,26,42,45],mode:8,model:[14,17,33,36,38],modif:27,modifi:[16,21,22,27,28,33,38,46],modify_rol:21,modify_st:27,modify_us:21,modul:[35,38,44],monitor:17,more:[8,9,16,18,21,23,27,29,33,36,38,39,40,41,42,44,45,46],most:[27,31,38,40],motiv:22,move:[7,46],mro:[22,31],msg:[9,10],much:43,multidimension:8,multipl:[27,45,46],multipli:12,must:[7,8,14,16,26,27,28,32,33,36,38,39,40,41,44,45,46],mutable_templ:[1,35],mutablemap:8,mutabletempl:28,my_dict:8,my_tabl:8,myapplic:43,mypackag:43,myplugin:43,name:[1,2,6,8,9,12,13,18,20,21,22,23,24,25,27,28,29,31,32,33,35,36,38,40,41,42,44,46],name_from_data_sourc:[28,29],namealreadybounderror:14,namenotfounderror:14,names_from_templ:28,namespac:[2,14,25,27,36,41],naming_ev:[1,35],naming_manag:[1,35],naming_node_manag:[1,14],naming_trait:[1,14],naming_tre:[1,14],naming_tree_model:[1,14],namingerror:14,namingev:14,namingmanag:14,namingnodemanag:17,namingtraithandl:16,namingtre:17,namingtreemodel:17,natur:42,navig:22,necessari:[2,8,22,33,36,41,46],need:[2,16,21,22,25,27,33,36,37,38,40,43,45,46],nest:[25,33,44,46],never:[14,26,27,45],new_nam:14,new_object:2,newest:9,newpersonperm:38,newunpickl:[22,27],next:[33,42,46],node:[2,5,8,17,23,24,42,43],node_attr:8,node_exist:23,node_manag:17,node_monitor:17,node_nam:23,node_path:8,node_subpath:8,node_tre:17,node_tree_model:17,node_typ:17,nodefaultspecifi:28,nodemanag:17,nodemonitor:17,nodepath:8,nodetre:17,nodetreemodel:17,nodetyp:17,non:[8,14,16,17,36,42],none:[2,6,8,9,13,14,18,21,22,23,24,25,28,31,32,36,42,46],normal:[8,12,38,41],notat:38,notcontexterror:14,note:[8,9,12,14,16,21,22,27,28,36,41,44],noth:[7,23,25,33,34,46],notic:42,notif:45,notifi:[25,26,42,45],notion:23,now:[9,22,36,42,44],nspace:2,null_handl:[1,35],nullhandl:9,number:[22,39,40,42,43,46],numer:[2,22,36],numpi:8,obj1:36,obj2:36,obj:[2,14,17,22,23,27,31,32,36,42],obj_class:32,object:[2,3,8,9,10,12,13,14,16,17,18,20,21,22,23,25,26,27,28,29,31,32,37,38,40,41,42,44,46],object_a:31,object_factori:[1,35],object_from_templ:28,object_node_typ:[1,14],object_seri:[1,35],objectfactori:14,objectnodetyp:17,objectseri:14,obtain:[21,22],obvious:42,occur:[16,21,28,44],often:22,ogbuji:9,old:[22,27,31,32,42],old_nam:14,older:13,oldest:9,omit:28,on_perform:38,on_trait_chang:42,on_ui_clos:25,onc:[9,21,28,33,38,46],one:[2,9,14,18,21,22,23,24,25,27,28,29,31,32,33,36,38,41,42,44,45,46],ones:22,onli:[2,8,9,16,18,21,22,23,25,27,28,29,32,33,34,36,38,40,41,43,45,46],onlin:[4,5],onto:[32,34,46],opac:44,open:[8,22,27,45],open_h5fil:8,oper:[14,23,34,36,41,42,46],operationnotsupportederror:14,opportun:22,option:[2,22,25,28,29,41,45,46],or_non:16,orang:24,order:[14,22,23,26,31,32,38,41,42,45],ordinari:40,organ:[44,45],organis:[41,46],orient:12,origin:[8,9,14,16,22,27,28,33,38,46],other:[2,5,8,14,16,18,21,22,27,33,36,38,40,41,43,45,46],otherwis:[2,8,17,26,27,29,33,36,38,41,45,46],our:[8,9,12,27,42],out:[22,23,25,27,44],output:[22,25,28,29],output_data_context:[28,29],outsid:[14,44],outstand:[33,46],over:[8,14],overrid:[6,43],overridden:[16,22,27,28],overview:[37,38,44],overwrit:8,own:[27,41],packag:[0,35,41,42,44],package_any_relevant_fil:10,package_glob:[1,35],package_single_project:10,package_workspac:10,page:[5,12,24,37],pair:[8,13],panda:8,panel:24,panick:42,paramet:[8,13,16,22,26,28,29,32,44,45],parent:[8,24,25,32,44],pars:[22,29],parse_nam:29,part:[2,4,7,8,9,14,18,22,23,25,27,28,31,33,36,38,39,40,41,44,45],particular:[14,16,22,23,25,26,31,36,37,40,41,44,45,46],particularli:[14,46],pass:[2,8,9,13,14,16,22,23,25,33,36,42,44,46],passiv:26,password:[21,38,40,41],patch:38,path:[7,8,9,14,22,23,25,29,44],path_exists_in_zip:9,path_for:29,pathnam:8,pattern:46,pear:24,peopl:[9,23],perfectli:[26,45],perform:[3,6,12,14,18,19,23,27,34,42,44],perhap:22,perm_id:21,permiss:[1,35,37,39,40],permissions_manag:[1,35],permissionsmanag:18,persist:[1,11,18,23,35,39,40,41,42],persistenterror:21,person:38,personsalaryperm:38,pertain:9,phrase:16,pickl:[21,22,27,39,40,41],pickle_filenam:22,pickler:22,piec:41,pixel:12,pkgfile:43,place:[16,22,23,27,33,34,44,46],placehold:[1,22,35],plain:[22,42,44],playback:36,pleas:22,plot:28,plug:14,plugin:[1,5,6,9,10,22,27,36,38,43,45,46],point:[10,14,27,42,43,44,46],polici:[2,18,21,37,38,41],policy_data:[1,18],policy_manag:[1,18,41],policy_storag:[1,18,41],policymanag:[21,41],policystorag:[21,41],policystorageerror:[21,39],pop:[25,32],popul:[26,28,38,41,45],posit:[2,14,46],posix:22,possibl:[18,22,25,27,28,29,32,36,38,41,45,46],post:31,post_setattr:16,potenti:46,power:44,pprint:22,pre:31,preced:[23,42],predefin:[16,42],prefer:[1,5,11,12,14,35,37,40,41],preference_bind:[1,35],preference_path:23,preferencebind:23,preferences_help:[1,5,11,24,35],preferences_manag:[1,23],preferences_nod:[1,23],preferences_pag:[1,4,11,12,23],preferences_path:42,preferencesbind:23,preferenceshelp:[5,11,23,24,42,43],preferenceshelpwindow:24,preferencesmanag:24,preferencesmanagerhandl:24,preferencesnod:24,preferencespag:[5,12,24],prefix:[14,38,40],present:[14,24,25],preserv:8,presum:22,pretti:[24,42],previou:[2,25,33,46],previous:[27,42],primari:23,primarili:44,prime:27,primit:23,princip:18,print:[9,24,42,44],printabl:25,prior:27,prioriti:[10,11],probabl:38,problem:22,process:[22,27],produc:[14,31,36,44],profil:41,program:[5,8],project:[2,4,7,9,10,14,18,22,23,25,27,28,31,33],project_load:[1,35],project_vers:22,properli:[29,33],properti:[28,44],propos:16,protect:41,protocol:[22,27],prove:[22,36,40,42],provid:[2,7,8,14,18,22,23,25,26,27,28,29,31,36,37,38,39,40,41,42,43,44,46],provider_id:[26,45],providernotregisterederror:[26,45],proxi:[18,20,22,38],publish:[26,45],pure:22,purpos:16,push:[32,33,34,46],push_abc:32,put:9,py_context:[1,35],py_object_factori:[1,35],pycontext:14,pyf:14,pyfac:[3,5,6,10,12,17,19,20,34,36,38,41,46],pyface_act:[1,18],pyfs_context:[1,35],pyfs_context_factori:[1,35],pyfs_initial_context_factori:[1,35],pyfs_object_factori:[1,35],pyfs_state_factori:[1,35],pyfscontext:14,pyfscontextfactori:14,pyfsinitialcontextfactori:14,pyfsobjectfactori:14,pyfsstatefactori:14,pyobjectfactori:14,pyqt:38,pytabl:8,pytables_group:8,pytables_nod:8,python:[8,9,14,15,17,22,23,25,27,31,36,38,41,44],python_type_system:[1,35],pythonobject:31,pythontypesystem:31,qt4_widget:[1,18],qualifi:[9,32],quality_agent_mail:[1,9],quality_agent_view:[1,9],qualityagentview:10,question:41,queue:9,quick:[9,42],quickest:44,quit:[22,45],rais:[2,8,14,16,21,23,26,28,29,32,36,39,40,45],random:9,rang:[16,44],rare:41,rather:[8,14,16,21,27,36],ratio:[17,42,43],raw:42,rdbm:[40,41],reach:14,react:45,read:[2,8,21,22,27,28,36,37,38,39,40,44],readabl:[8,25,38,44],readi:9,real:[22,28],realli:[22,31,42],reason:[32,44],rebind:[2,14,36],rec:25,receiv:[16,27,45],recent:13,recip:18,recogn:[14,17],recognis:[14,33],recommend:[23,27],reconstitut:[22,27],record:[1,2,3,8,9,12,27,33,35,36,37,41],record_funct:25,record_method:2,record_trait_get:2,record_trait_set:2,recorder_with_ui:[1,35],recordererror:25,recorderwithui:[25,44],recreat:[22,44],red:42,redirect:27,redo:[33,34,46],redo_act:[1,33],redo_nam:46,redoabl:46,redoact:34,redon:[33,46],refactor:[9,22,27],refer:[1,2,9,12,16,22,23,27,33,35,36,37,38,44,46],referenc:[1,2,35],referenceable_state_factori:[1,35],referenceablestatefactori:14,reflect:[14,27,38,46],refresh:14,regard:[14,45],regist:[2,18,21,22,25,26,27,31,32,38,43,44,45],register_adapt:[18,31,38],register_instance_adapt:31,register_permiss:[18,21],register_type_adapt:31,registi:22,registri:[22,25,26,27,32,45],regular:[18,21],reimplement:[18,20,21,34,37,38],rel:[8,14,22],rel_pth:22,relat:[19,21,36,40],relationship:41,relax:40,releas:[21,22],relev:[10,22,38],reli:44,remain:[2,10,22,26,28,45],remot:[39,40,41],remov:[8,23,24,26,27,31,45,46],remove_group:8,remove_nod:8,remove_post:31,remove_pr:31,remove_preferences_listen:23,remove_selection_provid:[26,45],renam:14,repeat:46,repeatedli:[22,26,45],replac:[18,27,33,36],replai:36,report:11,repositori:27,repres:[14,21,22,24,25,26,27,36,42,45],represent:[2,7,14,21,22,27,39,40,44],request:[13,14,26,45],requir:[2,12,14,16,22,26,27,28,29,31,34,38,40,41,45,46],reset:9,reset_button:12,resiz:12,resolut:[14,32],resolv:[14,28],resolve_class:16,respect:[18,22,38,41],respons:[2,31,33,36,38,41,46],rest:[26,45],restat:41,restor:46,restrict:41,result:[2,12,13,14,16,27,33,34,46],reus:[10,27],revers:[22,44],revert:46,revis:22,rewrit:10,ring_buff:[1,35],ringbuff:9,ringbufferful:9,roam:41,role:[21,38,39,41],role_assign:[1,18],role_definit:[1,18],role_nam:21,root:[5,8,17,23,24,31,42],rotatingfilehandl:9,row:8,rpc:41,run:[2,5,6,36],run_fil:[2,36],safe:[27,28],safer:14,saferepr:22,sai:[22,42],salari:38,salary_perm:38,same:[2,9,12,14,22,26,27,28,33,36,38,40,42,45,46],save:[11,14,18,21,22,23,25,33,42,44,46],save_prefer:11,scan:22,scatter_plot:[1,28],scatter_plot_2:[1,28],scatter_plot_nm:[1,28],scenario:31,scheme:23,scope:[14,23,31,37,43],scope_nam:23,scoped_prefer:[1,35],scopedprefer:[23,42,43],scratch:36,screen:42,script:[1,2,3,33,35,37],script_id:[25,44],script_init:[2,36],script_manag:[1,35,36],script_typ:36,script_upd:36,scriptabl:[1,3,25,35,36],scriptable_typ:[1,35],scriptabledatamodel:36,scriptableobject:2,scripted_typ:2,scriptmanag:2,search:[14,32,37,42],search_path:6,second:22,section:[0,36,38,39,40,42,43,46],secur:[18,38,39,40,41],secure_proxi:[1,35],securehandl:[18,38],secureproxi:[18,37],see:[2,8,9,21,22,27,31,36,38,41,42,44],select:[1,18,21,35,37],select_rol:[1,18],select_us:[1,18],selection_servic:[1,35],selectionservic:[26,37],self:[22,27,36,38,43,44],semant:31,send:[11,45],send_bug_report:11,sens:16,sensit:[40,41],sentenc:16,separ:[29,38],seq:22,sequenc:[8,14,26,45,46],sequence_nr:[33,46],serial:[14,28],serv:27,server:[39,40,41],servic:[10,11,12,26,37,38,41],set:[2,8,9,12,14,17,18,20,21,22,23,25,26,28,36,37,40,41,42,43,44,46],set_absolut:22,set_assign:21,set_attribut:14,set_default_prefer:23,set_en:[18,20,38],set_permissions_manag:18,set_record:[25,44],set_rel:22,set_script_manag:[2,36],set_select:[26,45],set_stat:22,set_text:17,set_vis:[18,20,38],setattr:[18,20,38],setstat:27,setup:[22,44],sever:41,shape:8,share:21,shell:36,shiva:44,shortcut:[13,46],should:[8,9,10,14,16,18,22,26,27,28,29,31,38,39,40,41,42,44,45,46],shouldn:40,show:[12,14,18,24,38,45],show_button:12,show_label:12,shown:25,signatur:[26,45],silent:[26,45],similar:[16,46],similarli:22,simpl:[12,22,25,36,38,39,40,41,42,44],simpli:[22,27,38,42,44],simplifi:22,sinc:[8,9,14,22,25,27,44,46],singl:[2,21,27,33,36,38,46],singleton:[18,27,41],situat:[27,40],size:[9,10,12,13],size_max:9,small:44,smallest:27,smtp_server:[10,11],so_need:2,some:[8,14,36,42,46],someon:[14,22,27],someth:36,sometim:44,somewher:14,soon:45,sophist:36,sort:[14,21,31,46],sort_by_class_tre:31,sound:42,sourc:[2,3,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,31,32,33,34,44,45],source_modul:27,source_nam:27,space:12,special:[22,40],specif:[14,16,18,22,23,25,26,31,38,41,44,45],specifi:[8,9,12,13,14,16,17,22,23,24,25,27,28,29,31,32,36,41,42,44,45],spickl:[1,35],splash:42,splash_screen:42,splashscreenprefer:[42,43],split:[8,41],split_application_window:17,split_path:8,splitapplicationwindow:17,sprocket:16,sprout:24,sql:[39,40],squar:16,srinivasan:6,stack:[9,32,33,34,46],stack_trac:[10,11],stack_upd:46,stage:[22,27],standard:[14,18,22,23,27,31,36,38,46],start:[2,3,9,11,14,17,25,36,42,43,44],start_record:[2,25,36],start_recording_act:[1,2],startrecordingact:3,startup:9,state:[14,18,20,22,25,27,33,38,46],state_factori:[1,35],state_pickl:[1,35],statedict:22,statefactori:14,statelist:22,statement:[25,36,39,40],statepickl:22,statepicklererror:22,statesett:22,statesettererror:22,statetupl:22,stateunpickl:22,stateunpicklererror:22,statu:46,stdout:[23,24],stop:[2,3,11,17,25,36,44],stop_record:[2,25,36],stop_recording_act:[1,2],stoprecordingact:3,storag:[8,21,22,37,40],store:[8,14,18,21,22,23,25,38,39,40,41,42,44],str:[8,10,12,16,17,25,26,27,36,42,44,45],strict:27,strightfoward:22,string:[2,8,13,14,16,21,22,23,24,25,28,29,32,36,37,38,39,40,44],strip:22,strongli:27,structur:[24,38,41],stuff:[10,22],style:[12,31,32,38],sub:[9,14,18,29,36,38,44,46],subclass:[16,25,28,29],subgroup_nam:8,subject:[10,11],submenu:5,submodul:[1,4,35],subpackag:35,subsequ:[2,33,36,38,44,46],substitut:28,success:[18,21],successfulli:[18,21],suffici:[39,40,46],suffix:[2,36],suggest:44,suit:[2,4,7,14,18,22,23,25,27,28,31,33,36,41,44,46],suitabl:14,superclass:32,suppli:[40,41],support:[4,14,18,21,22,25,27,28,33,36,38,40,41,45,46],sure:[2,17,23,31,42,45],surfac:44,sweet_pickl:[1,35],swisher:[5,6],synchron:45,synchronis:46,syntax:[14,42],system:[7,9,14,17,31,40,41,42],tabl:[8,12],table_nod:[1,7],tabular_adapt:12,tabular_editor:12,tabularadapt:12,tabulareditor:12,take:[23,28,34,36,42,45,46],taken:[22,44],target:[27,31],target_class:[27,31],target_modul:27,target_nam:27,target_vers:27,tderiv:28,technic:44,tediou:44,tell:46,templat:[1,35],template_choic:[1,35],template_data_context:[1,28],template_data_nam:[1,29,35],template_data_sourc:[1,28],template_from_object:28,template_impl:[1,29,35],template_trait:[1,35],template_view:[1,28],templatechoic:28,templatedatacontext:29,templatedatanam:[28,29],templatedatasourc:29,templatiz:28,tend:38,tenum:28,term:[36,38],terribl:42,test:[1,28,44],text:[11,17,22,25,36,46],than:[8,9,13,14,16,21,27,29,36,38,39,40,41],thei:[18,21,22,23,27,28,29,33,36,38,41,42,44,45,46],them:[2,9,14,22,23,28,31,38,41,42,46],themselv:[14,25,36,38,41],therefor:[16,41],thi:[0,2,5,7,8,9,10,12,14,16,17,18,20,21,22,23,24,25,26,27,28,29,31,33,34,36,38,39,40,41,42,43,44,45,46],thin:8,thing:43,think:[14,22,23],those:[2,14,18,25,27,29,33,36,41,46],though:[14,22,27],thought:46,through:[14,27,44,45],thrown:14,thu:[12,27],time:[2,9,12,14,22,27,42,45,46],tinstanc:28,titl:[10,17],tlist:28,to_address:10,to_datafram:8,toaddr:[10,11],todo:38,togeth:12,toi:44,toler:27,tomer:18,too:[22,42,43,44],tool:[2,4,7,14,18,22,23,25,27,28,31,33,36,41,44,46],toolbar:45,toolkit:[38,41],toolkiteditorfactori:12,top:42,total:12,tour:42,trace:9,traceback:9,tradit:42,trail:23,trait:[2,3,4,5,6,7,10,11,12,13,14,15,16,17,18,19,21,23,24,25,26,27,28,29,31,33,34,36,38,40,42,43,44,45,46],trait_def:[1,14],trait_dict_context_adapt:[1,14],trait_dict_context_adapter_factori:[1,14],trait_handl:[16,28],trait_list_context_adapt:[1,14],trait_list_context_adapter_factori:[1,14],trait_modifi:12,trait_nam:[23,42],trait_name_on_par:25,trait_typ:[2,10,12,17],trait_view:12,traitdictcontextadapt:15,traitdictcontextadapterfactori:15,traiterror:16,traithandl:16,traitlistcontextadapt:15,traitlistcontextadapterfactori:15,traitprefixmap:44,traitrang:16,traits_ui_view:12,traits_view:[24,38],traitsui:[12,18,24,25,41],traitsuiview:12,traittyp:28,trang:28,transform:[22,27],treat:[12,14,27,40,46],tree:[5,14,17,24,31,45],tree_item:[1,23],treeitem:24,tri:[43,44],trigger:[26,45],tupl:[8,10,15,21,22,44],tuple_context_adapt:[1,14],tuple_context_adapter_factori:[1,14],tuplecontextadapt:15,tuplecontextadapterfactori:15,turn:[22,23,44],two:[22,23,27,33,38,40,42,45,46],typ:32,type:[2,8,9,12,14,16,17,18,22,23,27,28,29,31,32,36,37,38,44,46],type_manag:[1,14,35],type_registri:[1,35],typemanag:31,typeregistri:32,typic:[2,18,21,22,33,36,38,40,41,45,46],uch:9,ui_sav:25,uiinfo:18,unauthent:[18,19,21],unauthenticate_us:[18,21,38],unauthoris:[38,41],unbind:14,unbound:[2,36],unchang:12,under:9,underscor:[2,36],understand:27,undo:[1,35,37],undo_act:[1,33],undo_manag:[1,35,46],undo_nam:46,undoabl:46,undoact:34,undomanag:33,undon:[33,34,46],unhook:34,unicod:[22,38,46],unifi:31,unimpl:10,uniqu:[2,14,17,26,36,38,44,45,46],unique_nam:[1,35],unless:[36,41,45],unlik:22,unload:18,unlock:21,unnorm:12,unpickl:[22,27],unregist:[22,25,31,44],unregister_adapt:31,unregister_instance_adapt:31,unregister_type_adapt:31,unresolv:28,unscript:36,unseri:[22,27],until:[14,22,33,46],unzip:22,updat:[1,2,12,18,21,35,36,38,46],update1:22,update2:22,update3:22,update_blob:21,update_en:[18,38],update_password:21,update_st:22,update_vis:[18,38],updatepersonageperm:38,updater_path:22,upgrad:22,upgrade_project:22,upon:28,url:6,usabl:14,usag:46,use:[2,12,14,16,18,21,22,23,25,27,29,36,38,41,42,43,45],useag:42,used:[2,5,6,8,9,13,14,21,22,23,24,25,27,28,29,31,33,36,38,39,40,41,42,43,44,45,46],useful:[14,22,25,27,28,34,41,42],user:[2,12,14,16,18,19,21,22,23,24,25,27,37,39,41,42,44,45,46],user_act:38,user_add:21,user_databas:[1,18,41],user_delet:21,user_factori:[21,40],user_manag:[1,18,38,41],user_menu_manag:[1,18],user_modifi:21,user_nam:21,user_password:21,user_storag:[1,18,41],userdatabas:[21,40,41],usermanag:[21,41],usermenumanag:[19,38],userstorag:[21,41],userstorageerror:[21,40],uses:[2,23,31,36,38,39,40,41,43],using:[8,9,14,16,18,21,22,25,27,28,31,36,38,39,40,41,42,44,45],usual:[22,23,24,42],util:[1,4,5,7,10,35],valid:[8,16,22,26,38,45],validate_fail:16,valu:[2,8,9,12,13,14,16,17,18,20,22,23,27,28,29,33,36,38,41,42,46],value1ddatanameitem:29,value2ddatanameitem:29,value3ddatanameitem:29,value_data_name_item:[1,28],value_nd_data_name_item:[1,28],valuedatanameitem:29,valueerror:[8,23,26,45],valuenddatanameitem:29,variabl:[27,41],variou:[22,27,38,46],veg:24,veri:[22,41,44],verifi:16,version:[14,22,27,28,42],version_registri:[1,35],versioned_unpickl:[1,35],versionedunpickl:[22,27],via:[10,17,22,23,25,38,42,43,44],vibha:6,view:[1,8,9,11,17,18,22,24,41,45],view_menu_manag:5,viewer:5,viewmenumanag:5,visibl:[17,18,20,23,38,42,43],visible_when:38,visitor:14,visual:44,wai:[14,23,27,36,42,44],walk:[22,31,44],want:[22,23,25,31,38,39,40,41,42,44,45],warn:9,web:6,weebl:36,well:[22,44],were:[2,33,46],what:[2,12,22,27,36,37,42,44,45],whatev:[16,23,44],when:[2,8,9,14,18,21,22,25,26,27,28,29,31,32,33,34,36,38,40,41,42,43,44,45,46],whenev:[8,16,26,36,38,45,46],where:[8,9,14,21,22,23,25,27,31,38,42,45],wherea:41,whether:[8,9,16,31,36,38],which:[8,12,14,21,22,23,24,25,27,28,33,36,38,39,40,41,42,43,44,45,46],white:42,who:[27,39,40,41],whole:22,whole_log_text:11,whose:[13,16,18,22,28,36],wide:23,widget:[23,38,41],widget_editor:[1,23],width:[12,23,42,43],win:42,window:[17,45],wire:44,wirefram:44,wish:45,within:[14,27,28,36],without:[2,23,27,33,46],won:[9,36],word:[41,46],work:[8,22,24,27,33,36,41,42,44,46],workbench:[5,6,11,12,46],workbench_act:6,workbench_action_set:5,workbenchact:6,worth:[22,23,42],would:[2,8,9,22,23,27,33,34,38,42,43,45],wrap:[2,8,25,34,36,46],wrapper:[2,8,18,36,46],write:[8,21,22,37,39,40,42],write_script_id_in_namespac:25,writeabl:[7,41],writer:14,written:[14,36,38],wx_window:[1,18],xmarshal:22,xml:41,xxx:8,xyz:2,year:[38,44],yellow:43,yes:41,yet:[10,40],you:[8,22,23,25,27,36,38,41,42,43,44],your:[27,36,38,41,42,43,44],yourself:42,zfile:9,zip:[9,10]},titles:["API documentation","apptools package","apptools.appscripting package","apptools.appscripting.action package","apptools.help package","apptools.help.help_plugin package","apptools.help.help_plugin.action package","apptools.io package","apptools.io.h5 package","apptools.logger package","apptools.logger.agent package","apptools.logger.plugin package","apptools.logger.plugin.view package","apptools.lru_cache package","apptools.naming package","apptools.naming.adapter package","apptools.naming.trait_defs package","apptools.naming.ui package","apptools.permissions package","apptools.permissions.action package","apptools.permissions.adapters package","apptools.permissions.default package","apptools.persistence package","apptools.preferences package","apptools.preferences.ui package","apptools.scripting package","apptools.selection package","apptools.sweet_pickle package","apptools.template package","apptools.template.impl package","apptools.template.test package","apptools.type_manager package","apptools.type_registry package","apptools.undo package","apptools.undo.action package","apptools","Application Scripting Framework","AppTools Documentation","Application API","Default Policy Manager Data API","Default User Manager Data API","Permissions Framework - Introduction","Preferences","Preferences in Envisage","Automatic script recording","The selection service","Undo Framework"],titleterms:{"case":44,"default":[21,39,40,41],"static":36,The:[42,44,45],Using:41,__init__:36,abstract_adapter_factori:31,abstract_command:33,abstract_command_stack_act:34,abstract_factori:31,abstract_type_system:31,abstractcommand:46,access:42,action:[3,6,19,34,38],activ:45,adapt:[15,20,31,38],adapter_bas:18,adapter_factori:31,adapter_manag:31,address:14,advanc:44,agent:10,altern:41,any_context_data_name_item:29,any_data_name_item:29,api:[0,2,3,5,7,9,14,15,16,17,18,19,21,23,24,25,26,28,29,31,32,33,34,36,38,39,40,41,44,45,46],appli:38,applic:[36,38],appscript:[2,3],apptool:[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,37,45],attach:10,authent:38,automat:44,basic:42,bind:14,bind_ev:2,caveat:22,command_act:34,command_stack:33,commandact:46,commandstack:46,concept:[36,41,46],content:[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],context:14,context_adapt:14,context_adapter_factori:14,context_data_name_item:29,context_monitor:17,context_node_typ:17,custom_excepthook:9,data:[38,39,40],defin:38,demo_act:6,deploi:41,dict_context_adapt:15,dict_context_adapter_factori:15,dict_nod:8,dir_context:14,doc_act:6,document:[0,37],dynam:36,dynamic_context:14,enable_editor:30,envisag:43,error:[26,45],exampl:44,example_act:6,examples_prefer:5,except:14,explor:17,factori:31,featur:22,file:[7,8],file_path:22,filtering_handl:9,framework:[36,41,46],further:42,get:38,global_registri:27,gloriou:42,help:[4,5,6],help_cod:5,help_doc:5,help_plugin:[5,6],help_submenu_manag:5,helper:29,hook:31,i_bind_ev:2,i_command:33,i_command_stack:33,i_context_adapt:29,i_help_cod:5,i_help_doc:5,i_policy_manag:18,i_policy_storag:21,i_prefer:23,i_preferences_pag:24,i_script_manag:2,i_select:26,i_selection_provid:[26,45],i_undo_manag:33,i_us:18,i_user_databas:21,i_user_manag:18,i_user_storag:21,ibindev:36,icommand:46,impl:29,implement:[36,41],imutable_templ:28,initial_context:14,initial_context_factori:14,instance_context_adapt:15,instance_context_adapter_factori:15,integr:38,introduct:41,ipolicystorag:39,is_select:45,item:38,itempl:28,itemplate_choic:28,itemplate_data_context:28,itemplate_data_name_item:28,itemplate_data_sourc:28,iuserdatabas:40,iuserstorag:40,lazy_namespac:2,level:36,limit:36,list_context_adapt:15,list_context_adapter_factori:15,list_select:[26,45],listen:45,load_url_act:6,log_point:9,log_queue_handl:9,logger:[9,10,11,12],logger_plugin:11,logger_prefer:11,logger_preferences_pag:12,logger_servic:11,logger_view:12,login_act:19,logout_act:19,lru_cach:13,manag:[38,39,40,41],mechan:42,modul:[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,36,45],mutable_templ:28,name:[14,15,16,17],naming_ev:14,naming_manag:14,naming_node_manag:17,naming_trait:16,naming_tre:17,naming_tree_model:17,need:41,null_handl:9,object:[36,45],object_factori:14,object_node_typ:17,object_seri:14,overview:[36,39,40,46],packag:[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,45],package_glob:[2,18,23,25],particular:42,passiv:45,permiss:[18,19,20,21,38,41],permissions_manag:18,persist:[21,22],placehold:27,plugin:[11,12],polici:39,policy_data:21,policy_manag:21,policy_storag:21,prefer:[23,24,42,43],preference_bind:23,preferences_help:23,preferences_manag:24,preferences_nod:24,preferences_pag:[5,24],project_load:22,provid:45,py_context:14,py_object_factori:14,pyface_act:20,pyfs_context:14,pyfs_context_factori:14,pyfs_initial_context_factori:14,pyfs_object_factori:14,pyfs_state_factori:14,python_type_system:31,qt4_widget:20,quality_agent_mail:10,quality_agent_view:10,queri:45,read:42,record:[25,44],recorder_with_ui:25,redo_act:34,redoact:46,refer:[14,45],referenc:14,referenceable_state_factori:14,registr:45,reimplement:41,ring_buff:9,role_assign:21,role_definit:21,scatter_plot:30,scatter_plot_2:30,scatter_plot_nm:30,scope:42,scoped_prefer:23,script:[25,36,44],script_manag:2,scriptabl:2,scriptable_typ:2,scriptmanag:36,secure_proxi:18,secureproxi:38,select:[26,45],select_rol:21,select_us:21,selection_servic:[26,45],selectionservic:45,servic:45,set:[38,45],specif:36,spickl:22,start_recording_act:3,startrecordingact:36,state_factori:14,state_pickl:22,stop_recording_act:3,stoprecordingact:36,storag:41,string:42,submodul:[2,3,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],subpackag:[1,2,4,5,7,9,11,14,18,23,28,33],sweet_pickl:27,table_nod:8,templat:[28,29,30],template_choic:28,template_data_context:29,template_data_nam:28,template_data_sourc:29,template_impl:28,template_trait:28,template_view:30,test:30,tour:44,trait_def:16,trait_dict_context_adapt:15,trait_dict_context_adapter_factori:15,trait_list_context_adapt:15,trait_list_context_adapter_factori:15,traitsui:38,tree_item:24,tuple_context_adapt:15,tuple_context_adapter_factori:15,type:42,type_manag:31,type_registri:32,undo:[33,34,46],undo_act:34,undo_manag:33,undoact:46,undomanag:46,unique_nam:14,updat:[22,27],use:44,user:[38,40],user_databas:21,user_manag:21,user_menu_manag:19,user_storag:21,util:[6,8,9,25,31],value_data_name_item:29,value_nd_data_name_item:29,version_registri:22,versioned_unpickl:[22,27],view:[12,38],what:41,widget_editor:24,wrap:38,write:38,wx_window:20}}) \ No newline at end of file diff --git a/4.5/selection/selection.html b/4.5/selection/selection.html new file mode 100644 index 000000000..364171dac --- /dev/null +++ b/4.5/selection/selection.html @@ -0,0 +1,632 @@ + + + + + + + The selection service — Apptools Documentation + + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +
+

The selection service

+

It is quite common in GUI applications to have a UI element displaying a +collection of items that a user can select (“selection providers”), while +other parts of the application must react to changes in the selection +(“selection listeners”).

+

Ideally, the listeners would not have a direct dependency on the UI object. +This is especially important in extensible envisage applications, where +a plugin might need to react to a selection change, but we do not want to +expose the internal organization of the application to external developers.

+

This package defines a selection service that manages the communication +between providers and listener.

+
+

The SelectionService object

+

The SelectionService object is the central manager that handles +the communication between selection providers and listener.

+

Selection providers are components that wish to +publish information about their current selection for public consumption. +They register to a selection +service instance when they first have a selection available (e.g., when the +UI showing a list of selectable items is initialized), and un-register as soon +as the selection is not available anymore (e.g., the UI is destroyed when the +windows is closed).

+

Selection listeners can query the selection +service to get the current selection published by a provider, using the +provider unique ID.

+

The service acts as a broker between providers and listeners, making sure that +they are notified when the +selection +event is fired.

+
+
+

Selection providers

+

Any object can become a selection provider by implementing the +ISelectionProvider +interface, and registering to the selection service.

+

Selection providers must provide a unique ID +provider_id, +which is used by listeners to request its current selection.

+

Whenever its selection changes, providers fire a +selection +event. The content of the event is an instance implementing +ISelection that contains information about the selected items. +For example, a ListSelection object contains a list of selected +items, and their indices.

+

Selection providers can also be queried directly about their current selection +using the +get_selection +method, and can be requested to change their selection to a new one with the +set_selection +method.

+
+

Registration

+

Selection providers publish their selection by registering to the selection +service using the +add_selection_provider +method. When the selection is no longer available, selection providers +should un-register through +remove_selection_provider.

+

Typically, selection providers are UI objects showing a list or tree of items, +they register as soon as the UI component is initialized, and un-register +when the UI component disappears (e.g., because their window has been closed). +In more complex applications, the registration could be done by a controller +object instead.

+
+
+
+

Selection listeners

+

Selection listeners request information regarding the current selection +of a selection provider given their provider ID. The SelectionService +supports two distinct use cases:

+
+
    +
  1. Passively listening to selection changes: listener connect to a specific +provider and are notified when the provider’s selection changes.
  2. +
  3. Actively querying a provider for its current selection: the selection +service can be used to query a provider using its unique ID.
  4. +
+
+
+

Passive listening

+

Listeners connect to the selection events for a given provider using the +connect_selection_listener +method. They need to provide the unique ID of the provider, and a function +(or callable) that is called to send the event. This callback function takes +one argument, an implementation of the ISelection that represents +the selection.

+

It is possible for a listener to connect to a provider ID before it is +registered. As soon as the provider is registered, the listener will receive +a notification containing the provider’s initial selection.

+

To disconnect a listener use the methods +disconnect_selection_listener.

+
+
+

Active querying

+

In other instances, an element of the application only needs the current +selection at a specific time. For example, a toolbar button could open dialog +representing a user action based on what is currently selected in the active +editor.

+

The +get_selection +method calls the corresponding method on the provider with the given ID and +returns an ISelection instance.

+
+
+

Setting a selection

+

Finally, it is possible to request a provider to set its selection to a given +set of objects with +set_selection. +The main use case for this method is multiple views of the same list of +objects, which need to keep their selection synchronized.

+

If the items specified in the arguments are not available in the provider, +a ProviderNotRegisteredError is raised, +unless the optional keyword argument ignore_missing is set to True.

+
+
+
+

API Reference

+
+

apptools.selection Package

+

Users of the apptools.selection package can access the objects that are +part of the public API through the convenience apptools.selection.api.

+
+

selection_service Module

+
+
+class apptools.selection.selection_service.SelectionService[source]
+

Bases: traits.has_traits.HasTraits

+

The selection service connects selection providers and listeners.

+

The selection service is a register of selection providers, i.e., objects +that publish their current selection.

+

Selections can be requested actively, by explicitly requesting the current +selection in a provider (get_selection(id)()), or passively by +connecting selection listeners.

+
+
+add_selection_provider(provider)[source]
+

Add a selection provider.

+

The provider is identified by its ID. If a provider with the same +ID has been already registered, an IDConflictError +is raised.

+ +++ + + + +
Parameters:-- ISelectionProvider (provider) – The selection provider added to the internal registry.
+
+ +
+
+connect_selection_listener(provider_id, func)[source]
+

Connect a listener to selection events from a specific provider.

+

The signature if the listener callback is func(i_selection). +The listener is called:

+
    +
  1. When a provider with the given ID is registered, with its initial +selection as argument, or
  2. +
  3. whenever the provider fires a selection event.
  4. +
+

It is perfectly valid to connect a listener before a provider with the +given ID is registered. The listener will remain connected even if +the provider is repeatedly connected and disconnected.

+ +++ + + + +
Parameters:
    +
  • -- str (provider_id) – The selection provider ID.
  • +
  • -- callable (func) – A callable object that is notified when the selection changes.
  • +
+
+
+ +
+
+disconnect_selection_listener(provider_id, func)[source]
+

Disconnect a listener from a specific provider.

+ +++ + + + +
Parameters:
    +
  • -- str (provider_id) – The selection provider ID.
  • +
  • -- callable (func) – A callable object that is notified when the selection changes.
  • +
+
+
+ +
+
+get_selection(provider_id)[source]
+

Return the current selection of the provider with the given ID.

+

If a provider with that ID has not been registered, a +ProviderNotRegisteredError is raised.

+ +++ + + + + + +
Parameters:-- str (provider_id) – The selection provider ID.
Returns:
+
selection – ISelection
+
The current selection of the provider.
+
+
+
+ +
+
+has_selection_provider(provider_id)[source]
+

Has a provider with the given ID been registered?

+
+ +
+
+remove_selection_provider(provider)[source]
+

Remove a selection provider.

+

If the provider has not been registered, a +ProviderNotRegisteredError is raised.

+ +++ + + + +
Parameters:-- ISelectionProvider (provider) – The selection provider added to the internal registry.
+
+ +
+
+set_selection(provider_id, items, ignore_missing=False)[source]
+

Set the current selection in a provider to the given items.

+

If a provider with the given ID has not been registered, a +ProviderNotRegisteredError is raised.

+

If ignore_missing is True, items that are not available in the +selection provider are silently ignored. If it is False (default), +a ValueError should be raised.

+ +++ + + + +
Parameters:
    +
  • -- str (provider_id) – The selection provider ID.
  • +
  • -- list (items) – List of items to be selected.
  • +
  • -- bool (ignore_missing) – If False (default), the provider raises an exception if any +of the items in items is not available to be selected. +Otherwise, missing elements are silently ignored, and the rest +is selected.
  • +
+
+
+ +
+ +
+
+

i_selection_provider Module

+
+
+class apptools.selection.i_selection_provider.ISelectionProvider[source]
+

Bases: traits.has_traits.Interface

+

Source of selections.

+
+
+get_selection()[source]
+

Return the current selection.

+ +++ + + + +
Returns:
+
selection – ISelection
+
Object representing the current selection.
+
+
+
+ +
+
+provider_id = Str()
+

Unique ID identifying the provider.

+
+ +
+
+selection = Event
+

Event triggered when the selection changes. +The content of the event is an ISelection instance.

+
+ +
+
+set_selection(items, ignore_missing=False)[source]
+

Set the current selection to the given items.

+

If ignore_missing is True, items that are not available in the +selection provider are silently ignored. If it is False (default), +an ValueError should be raised.

+ +++ + + + +
Parameters:
    +
  • -- list (items) – List of items to be selected.
  • +
  • -- bool (ignore_missing) – If False (default), the provider raises an exception if any +of the items in items is not available to be selected. +Otherwise, missing elements are silently ignored, and the rest +is selected.
  • +
+
+
+ +
+ +
+
+

is_selection Module

+
+
+class apptools.selection.i_selection.IListSelection[source]
+

Bases: apptools.selection.i_selection.ISelection

+

Selection for ordered sequences of items.

+
+
+indices = List
+

Indices of the selected objects in the selection provider.

+
+ +
+
+items = List
+

Selected objects.

+
+ +
+ +
+
+class apptools.selection.i_selection.ISelection[source]
+

Bases: traits.has_traits.Interface

+

Collection of selected items.

+
+
+is_empty()[source]
+

Is the selection empty?

+
+ +
+
+provider_id = Str
+

ID of the selection provider that created this selection object.

+
+ +
+ +
+
+

list_selection Module

+
+
+class apptools.selection.list_selection.ListSelection[source]
+

Bases: traits.has_traits.HasTraits

+

Selection for ordered sequences of items.

+

This is the default implementation of the IListSelection +interface.

+
+
+classmethod from_available_items(provider_id, selected, all_items)[source]
+

Create a list selection given a list of all available items.

+

Fills in the required information (in particular, the indices) based +on a list of selected items and a list of all available items.

+
+

Note

+
    +
  • The list of available items must not contain any duplicate items.
  • +
  • It is expected that selected is populated by items in +all_items.
  • +
+
+
+ +
+
+indices = List
+

Indices of the selected objects in the selection provider.

+
+ +
+
+is_empty()[source]
+

Is the selection empty?

+
+ +
+
+items = List
+

Selected objects.

+
+ +
+
+provider_id = Str
+

ID of the selection provider that created this selection object.

+
+ +
+ +
+
+

errors Module

+
+
+exception apptools.selection.errors.IDConflictError(provider_id)[source]
+

Bases: Exception

+

Raised when a provider is added and its ID is already registered.

+
+ +
+
+exception apptools.selection.errors.ListenerNotConnectedError(provider_id, listener)[source]
+

Bases: Exception

+

Raised when a listener that was never connected is disconnected.

+
+ +
+
+exception apptools.selection.errors.ProviderNotRegisteredError(provider_id)[source]
+

Bases: Exception

+

Raised when a provider is requested by ID and not found.

+
+ +
+
+
+
+ + +
+
+
+ +
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/4.5/undo/Introduction.html b/4.5/undo/Introduction.html new file mode 100644 index 000000000..de995060a --- /dev/null +++ b/4.5/undo/Introduction.html @@ -0,0 +1,386 @@ + + + + + + + Undo Framework — Apptools Documentation + + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +
+

Undo Framework

+

The Undo Framework is a component of the Enthought Tool Suite that provides +developers with an API that implements the standard pattern for do/undo/redo +commands.

+

The framework is completely configurable. Alternate implementations of all +major components can be provided if necessary.

+
+

Framework Concepts

+

The following are the concepts supported by the framework.

+
    +
  • Command

    +

    A command is an application defined operation that can be done (i.e. +executed), undone (i.e. reverted) and redone (i.e. repeated).

    +

    A command operates on some data and maintains sufficient state to allow it to +revert or repeat a change to the data.

    +

    Commands may be merged so that potentially long sequences of similar +commands (e.g. to add a character to some text) can be collapsed into a +single command (e.g. to add a word to some text).

    +
  • +
  • Macro

    +

    A macro is a sequence of commands that is treated as a single command when +being undone or redone.

    +
  • +
  • Command Stack

    +

    A command is done by pushing it onto a command stack. The last command can +be undone and redone by calling appropriate command stack methods. It is +also possible to move the stack’s position to any point and the command stack +will ensure that commands are undone or redone as required.

    +

    A command stack maintains a clean state which is updated as commands are +done and undone. It may be explicitly set, for example when the data being +manipulated by the commands is saved to disk.

    +

    Canned PyFace actions are provided as wrappers around command stack methods +to implement common menu items.

    +
  • +
  • Undo Manager

    +

    An undo manager is responsible for one or more command stacks and maintains +a reference to the currently active stack. It provides convenience undo and +redo methods that operate on the currently active stack.

    +

    An undo manager ensures that each command execution is allocated a unique +sequence number, irrespective of which command stack it is pushed to. Using +this it is possible to synchronise multiple command stacks and restore them +to a particular point in time.

    +

    An undo manager will generate an event whenever the clean state of the active +stack changes. This can be used to maintain some sort of GUI status +indicator to tell the user that their data has been modified since it was +last saved.

    +
  • +
+

Typically an application will have one undo manager and one undo stack for +each data type that can be edited. However this is not a requirement: how the +command stack’s in particular are organised and linked (with the user +manager’s sequence number) can need careful thought so as not to confuse the +user - particularly in a plugin based application that may have many editors.

+

To support this typical usage the PyFace Workbench class has an +undo_manager trait and the PyFace Editor class has a command_stack +trait. Both are lazy loaded so can be completely ignored if they are not used.

+
+
+

API Overview

+

This section gives a brief overview of the various classes implemented in the +framework. The complete API documentation is available as endo generated +HTML.

+

The example application demonstrates all the major features of the framework.

+
+

UndoManager

+

The UndoManager class is the default implementation of the IUndoManager +interface.

+
+
active_stack
+
This trait is a reference to the currently active command stack and may be +None. Typically it is set when some sort of editor becomes active.
+
active_stack_clean
+
This boolean trait reflects the clean state of the currently active +command stack. It is intended to support a “document modified” indicator +in the GUI. It is maintained by the undo manager.
+
stack_updated
+
This event is fired when the index of a command stack is changed. A +reference to the stack is passed as an argument to the event and may not +be the currently active stack.
+
undo_name
+
This Unicode trait is the name of the command that can be undone, and will +be empty if there is no such command. It is maintained by the undo +manager.
+
redo_name
+
This Unicode trait is the name of the command that can be redone, and will +be empty if there is no such command. It is maintained by the undo +manager.
+
sequence_nr
+
This integer trait is the sequence number of the next command to be +executed. It is incremented immediately before a command’s do() +method is called. A particular sequence number identifies the state of +all command stacks handled by the undo manager and allows those stacks to +be set to the point they were at at a particular point in time. In other +words, the sequence number allows otherwise independent command stacks to +be synchronised.
+
undo()
+
This method calls the undo() method of the last command on the active +command stack.
+
redo()
+
This method calls the redo() method of the last undone command on the +active command stack.
+
+
+
+

CommandStack

+

The CommandStack class is the default implementation of the +ICommandStack interface.

+
+
clean
+
This boolean traits reflects the clean state of the command stack. Its +value changes as commands are executed, undone and redone. It may also be +explicitly set to mark the current stack position as being clean (when +data is saved to disk for example).
+
undo_name
+
This Unicode trait is the name of the command that can be undone, and will +be empty if there is no such command. It is maintained by the command +stack.
+
redo_name
+
This Unicode trait is the name of the command that can be redone, and will +be empty if there is no such command. It is maintained by the command +stack.
+
undo_manager
+
This trait is a reference to the undo manager that manages the command +stack.
+
push(command)
+
This method executes the given command by calling its do() method. +Any value returned by do() is returned by push(). If the command +couldn’t be merged with the previous one then it is saved on the command +stack.
+
undo(sequence_nr=0)
+
This method undoes the last command. If a sequence number is given then +all commands are undone up to an including the sequence number.
+
redo(sequence_nr=0)
+
This method redoes the last command and returns any result. If a sequence +number is given then all commands are redone up to an including the +sequence number and any result of the last of these is returned.
+
clear()
+
This method clears the command stack, without undoing or redoing any +commands, and leaves the stack in a clean state. It is typically used +when all changes to the data have been abandoned.
+
begin_macro(name)
+
This method begins a macro by creating an empty command with the given +name. The commands passed to all subsequent calls to push() will be +contained in the macro until the next call to end_macro(). Macros may +be nested. The command stack is disabled (ie. nothing can be undone or +redone) while a macro is being created (ie. while there is an outstanding +end_macro() call).
+
end_macro()
+
This method ends the current macro.
+
+
+
+

ICommand

+

The ICommand interface defines the interface that must be implemented by +any undoable/redoable command.

+
+
data
+
This optional trait is a reference to the data object that the command +operates on. It is not used by the framework itself.
+
name
+
This Unicode trait is the name of the command as it will appear in any GUI +element (e.g. in the text of an undo and redo menu entry). It may include +& to indicate a keyboard shortcut which will be automatically removed +whenever it is inappropriate.
+
__init__(*args)
+
If the command takes arguments then the command must ensure that deep +copies should be made if appropriate.
+
do()
+
This method is called by a command stack to execute the command and to +return any result. The command must save any state necessary for the +undo() and redo() methods to work. It is guaranteed that this +will only ever be called once and that it will be called before any call +to undo() or redo().
+
undo()
+
This method is called by a command stack to undo the command.
+
redo()
+
This method is called by a command stack to redo the command and to return +any result.
+
merge(other)
+
This method is called by the command stack to try and merge the other +command with this one. True should be returned if the commands were +merged. If the commands are merged then other will not be placed on +the command stack. A subsequent undo or redo of this modified command +must have the same effect as the two original commands.
+
+
+
+

AbstractCommand

+

AbstractCommand is an abstract base class that implements the ICommand +interface. It provides a default implementation of the merge() method.

+
+
+

CommandAction

+

The CommandAction class is a sub-class of the PyFace Action class that +is used to wrap commands.

+
+
command
+
This callable trait must be set to a factory that will return an object +that implements ICommand. It will be called when the action is invoked +and the object created pushed onto the command stack.
+
command_stack
+
This instance trait must be set to the command stack that commands invoked +by the action are pushed to.
+
data
+
This optional trait is a reference to the data object that will be passed +to the command factory when it is called.
+
+
+
+

UndoAction

+

The UndoAction class is a canned PyFace action that undoes the last +command of the active command stack.

+
+
+

RedoAction

+

The RedoAction class is a canned PyFace action that redoes the last +command undone of the active command stack.

+
+
+
+ + +
+
+
+
+
+ +

Table of Contents

+ + +

Previous topic

+

Automatic script recording

+

Next topic

+

The selection service

+

This Page

+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/5.0/_modules/apptools/io/file.html b/5.0/_modules/apptools/io/file.html new file mode 100644 index 000000000..a996811e5 --- /dev/null +++ b/5.0/_modules/apptools/io/file.html @@ -0,0 +1,443 @@ + + + + + + + apptools.io.file — Apptools Documentation + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +

Source code for apptools.io.file

+# (C) Copyright 2005-2020 Enthought, Inc., Austin, TX
+# All rights reserved.
+#
+# This software is provided without warranty under the terms of the BSD
+# license included in LICENSE.txt and may be redistributed only under
+# the conditions described in the aforementioned license. The license
+# is also available online at http://www.enthought.com/licenses/BSD.txt
+#
+# Thanks for using Enthought open source!
+""" A representation of files and folders in a file system. """
+
+
+# Standard/built-in imports.
+import mimetypes
+import os
+import shutil
+import stat
+
+# Enthought library imports.
+from traits.api import Bool, HasPrivateTraits, Instance, List, Property
+from traits.api import Str
+
+
+
[docs]class File(HasPrivateTraits): + """ A representation of files and folders in a file system. """ + + #### 'File' interface ##################################################### + + # The absolute path name of this file/folder. + absolute_path = Property(Str) + + # The folder's children (for files this is always None). + children = Property(List("File")) + + # The file extension (for folders this is always the empty string). + # + # fixme: Currently the extension includes the '.' (ie. we have '.py' and + # not 'py'). This is because things like 'os.path.splitext' leave the '.' + # on, but I'm not sure that this is a good idea! + ext = Property(Str) + + # Does the file/folder exist? + exists = Property(Bool) + + # Is this an existing file? + is_file = Property(Bool) + + # Is this an existing folder? + is_folder = Property(Bool) + + # Is this a Python package (ie. a folder contaning an '__init__.py' file. + is_package = Property(Bool) + + # Is the file/folder readonly? + is_readonly = Property(Bool) + + # The MIME type of the file (for a folder this will always be + # 'context/unknown' (is that what it should be?)). + mime_type = Property(Str) + + # The last component of the path without the extension. + name = Property(Str) + + # The parent of this file/folder (None if it has no parent). + parent = Property(Instance("File")) + + # The path name of this file/folder. + path = Str + + # A URL reference to the file. + url = Property(Str) + + ########################################################################### + # 'object' interface. + ########################################################################### + + def __init__(self, path, **traits): + """ Creates a new representation of the specified path. """ + + super(File, self).__init__(path=path, **traits) + + def __str__(self): + """ Returns an 'informal' string representation of the object. """ + + return "File(%s)" % self.path + + ########################################################################### + # 'File' interface. + ########################################################################### + + #### Properties ########################################################### + + def _get_absolute_path(self): + """ Returns the absolute path of this file/folder. """ + + return os.path.abspath(self.path) + + def _get_children(self): + """Returns the folder's children. + + Returns None if the path does not exist or is not a folder. + + """ + + if self.is_folder: + children = [] + for name in os.listdir(self.path): + children.append(File(os.path.join(self.path, name))) + + else: + children = None + + return children + + def _get_exists(self): + """ Returns True if the file exists, otherwise False. """ + + return os.path.exists(self.path) + + def _get_ext(self): + """ Returns the file extension. """ + + name, ext = os.path.splitext(self.path) + + return ext + + def _get_is_file(self): + """ Returns True if the path exists and is a file. """ + + return self.exists and os.path.isfile(self.path) + + def _get_is_folder(self): + """ Returns True if the path exists and is a folder. """ + + return self.exists and os.path.isdir(self.path) + + def _get_is_package(self): + """ Returns True if the path exists and is a Python package. """ + + return self.is_folder and "__init__.py" in os.listdir(self.path) + + def _get_is_readonly(self): + """ Returns True if the file/folder is readonly, otherwise False. """ + + # If the File object is a folder, os.access cannot be used because it + # returns True for both read-only and writable folders on Windows + # systems. + if self.is_folder: + + # Mask for the write-permission bits on the folder. If these bits + # are set to zero, the folder is read-only. + WRITE_MASK = 0x92 + permissions = os.stat(self.path)[0] + + if permissions & WRITE_MASK == 0: + readonly = True + else: + readonly = False + + elif self.is_file: + readonly = not os.access(self.path, os.W_OK) + + else: + readonly = False + + return readonly + + def _get_mime_type(self): + """ Returns the mime-type of this file/folder. """ + + mime_type, encoding = mimetypes.guess_type(self.path) + if mime_type is None: + mime_type = "content/unknown" + + return mime_type + + def _get_name(self): + """ Returns the last component of the path without the extension. """ + + basename = os.path.basename(self.path) + + name, ext = os.path.splitext(basename) + + return name + + def _get_parent(self): + """ Returns the parent of this file/folder. """ + + return File(os.path.dirname(self.path)) + + def _get_url(self): + """ Returns the path as a URL. """ + + # Strip out the leading slash on POSIX systems. + return "file:///%s" % self.absolute_path.lstrip("/") + + #### Methods ############################################################## + +
[docs] def copy(self, destination): + """ Copies this file/folder. """ + + # Allow the destination to be a string. + if not isinstance(destination, File): + destination = File(destination) + + if self.is_folder: + shutil.copytree(self.path, destination.path) + + elif self.is_file: + shutil.copyfile(self.path, destination.path)
+ +
[docs] def create_file(self, contents=""): + """ Creates a file at this path. """ + + if self.exists: + raise ValueError("file %s already exists" % self.path) + + f = open(self.path, "w") + f.write(contents) + f.close()
+ +
[docs] def create_folder(self): + """Creates a folder at this path. + + All intermediate folders MUST already exist. + + """ + + if self.exists: + raise ValueError("folder %s already exists" % self.path) + + os.mkdir(self.path)
+ +
[docs] def create_folders(self): + """Creates a folder at this path. + + This will attempt to create any missing intermediate folders. + + """ + + if self.exists: + raise ValueError("folder %s already exists" % self.path) + + os.makedirs(self.path)
+ +
[docs] def create_package(self): + """Creates a package at this path. + + All intermediate folders/packages MUST already exist. + + """ + + if self.exists: + raise ValueError("package %s already exists" % self.path) + + os.mkdir(self.path) + + # Create the '__init__.py' file that actually turns the folder into a + # package! + init = File(os.path.join(self.path, "__init__.py")) + init.create_file()
+ +
[docs] def delete(self): + """Deletes this file/folder. + + Does nothing if the file/folder does not exist. + + """ + + if self.is_folder: + # Try to make sure that everything in the folder is writeable. + self.make_writeable() + + # Delete it! + shutil.rmtree(self.path) + + elif self.is_file: + # Try to make sure that the file is writeable. + self.make_writeable() + + # Delete it! + os.remove(self.path)
+ +
[docs] def make_writeable(self): + """ Attempt to make the file/folder writeable. """ + + if self.is_folder: + # Try to make sure that everything in the folder is writeable + # (i.e., can be deleted!). This comes in especially handy when + # deleting '.svn' directories. + for path, dirnames, filenames in os.walk(self.path): + for name in dirnames + filenames: + filename = os.path.join(path, name) + if not os.access(filename, os.W_OK): + os.chmod(filename, stat.S_IWUSR) + + elif self.is_file: + # Try to make sure that the file is writeable (i.e., can be + # deleted!). + if not os.access(self.path, os.W_OK): + os.chmod(self.path, stat.S_IWUSR)
+ +
[docs] def move(self, destination): + """ Moves this file/folder. """ + + # Allow the destination to be a string. + if not isinstance(destination, File): + destination = File(destination) + + # Try to make sure that everything in the directory is writeable. + self.make_writeable() + + # Move it! + shutil.move(self.path, destination.path)
+
+ +
+
+
+
+
+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/5.0/_modules/apptools/io/h5/dict_node.html b/5.0/_modules/apptools/io/h5/dict_node.html new file mode 100644 index 000000000..1497f2caa --- /dev/null +++ b/5.0/_modules/apptools/io/h5/dict_node.html @@ -0,0 +1,362 @@ + + + + + + + apptools.io.h5.dict_node — Apptools Documentation + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +

Source code for apptools.io.h5.dict_node

+# (C) Copyright 2005-2020 Enthought, Inc., Austin, TX
+# All rights reserved.
+#
+# This software is provided without warranty under the terms of the BSD
+# license included in LICENSE.txt and may be redistributed only under
+# the conditions described in the aforementioned license. The license
+# is also available online at http://www.enthought.com/licenses/BSD.txt
+#
+# Thanks for using Enthought open source!
+from contextlib import closing
+import json
+
+from numpy import ndarray
+
+from tables import Group as PyTablesGroup
+from tables.nodes import filenode
+
+
+#: The key name which identifies array objects in the JSON dict.
+ARRAY_PROXY_KEY = "__array__"
+NODE_KEY = "node_name"
+
+
+
[docs]class H5DictNode(object): + """Dictionary-like node interface. + + Data for the dict is stored as a JSON file in a PyTables FileNode. This + allows easy storage of Python objects, such as dictionaries and lists of + different data types. + + Note that this is implemented using a group-node assuming that arrays are + valid inputs and will be stored as H5 array nodes. + + Parameters + ---------- + h5_group : H5Group instance + Group node which will be used as a dictionary store. + auto_flush : bool + If True, write data to disk whenever the dict data is altered. + Otherwise, call `flush()` explicitly to write data to disk. + """ + + #: Name of filenode where dict data is stored. + _pyobject_data_node = "_pyobject_data" + + def __init__(self, h5_group, auto_flush=True): + assert self.is_dict_node(h5_group) + + h5_group = self._get_pyt_group(h5_group) + self._h5_group = h5_group + self.auto_flush = auto_flush + + # Load dict data from the file node. + dict_node = getattr(h5_group, self._pyobject_data_node) + with closing(filenode.open_node(dict_node)) as f: + self._pyobject_data = json.loads( + f.read().decode("ascii"), object_hook=self._object_hook + ) + + # -------------------------------------------------------------------------- + # Dictionary interface + # -------------------------------------------------------------------------- + + def __getitem__(self, key): + return self.data[key] + + def __setitem__(self, key, value): + self.data[key] = value + if self.auto_flush: + self.flush() + + def __delitem__(self, key): + del self.data[key] + if self.auto_flush: + self.flush() + + def __contains__(self, key): + return key in self.data + +
[docs] def keys(self): + return self.data.keys()
+ + # -------------------------------------------------------------------------- + # Public interface + # -------------------------------------------------------------------------- + + @property + def data(self): + return self._pyobject_data + + @data.setter + def data(self, new_data_dict): + self._pyobject_data = new_data_dict + if self.auto_flush: + self.flush() + +
[docs] def flush(self): + """ Write buffered data to disk. """ + self._remove_pyobject_node() + self._write_pyobject_node()
+ +
[docs] @classmethod + def add_to_h5file(cls, h5, node_path, data=None, **kwargs): + """Add dict node to an H5 file at the specified path. + + Parameters + ---------- + h5 : H5File + The H5 file where the dictionary data will be stored. + node_path : str + Path to node where data is stored (e.g. '/path/to/my_dict') + data : dict + Data for initialization, if desired. + """ + h5.create_group(node_path) + group = h5[node_path] + + cls._create_pyobject_node(h5._h5, node_path, data=data) + return cls(group, **kwargs)
+ +
[docs] @classmethod + def is_dict_node(cls, pytables_node): + """Return True if PyTables node looks like an H5DictNode. + + NOTE: That this returns False if the node is an `H5DictNode` instance, + since the input node should be a normal PyTables Group node. + """ + # Import here to prevent circular imports + from .file import H5Group + + if isinstance(pytables_node, H5Group): + pytables_node = cls._get_pyt_group(pytables_node) + + if not isinstance(pytables_node, PyTablesGroup): + return False + + return cls._pyobject_data_node in pytables_node._v_children
+ + # -------------------------------------------------------------------------- + # Private interface + # -------------------------------------------------------------------------- + + def _f_remove(self): + """This is called by H5File whenever a node is removed. + + All nodes in `_h5_group` will be removed. + """ + for name in self._h5_group._v_children.keys(): + if name != self._pyobject_data_node: + self._h5_group.__getattr__(name)._f_remove() + # Remove the dict node + self._remove_pyobject_node() + # Remove the group node + self._h5_group._f_remove() + + def _object_hook(self, dct): + """This gets passed object dictionaries by `json.load(s)` and if it + finds `ARRAY_PROXY_KEY` in the object description it returns the + proxied array object. + """ + if ARRAY_PROXY_KEY in dct: + node_name = dct[NODE_KEY] + return getattr(self._h5_group, node_name)[:] + return dct + + def _remove_pyobject_node(self): + node = getattr(self._h5_group, self._pyobject_data_node) + node._f_remove() + + def _write_pyobject_node(self): + pyt_file = self._h5_group._v_file + node_path = self._h5_group._v_pathname + self._create_pyobject_node(pyt_file, node_path, self.data) + + @classmethod + def _create_pyobject_node(cls, pyt_file, node_path, data=None): + if data is None: + data = {} + + # Stash the array values in their own h5 nodes and return a dictionary + # which is appropriate for JSON serialization. + out_data = cls._handle_array_values(pyt_file, node_path, data) + + kwargs = dict(where=node_path, name=cls._pyobject_data_node) + with closing(filenode.new_node(pyt_file, **kwargs)) as f: + f.write(json.dumps(out_data).encode("ascii")) + + @classmethod + def _get_pyt_group(self, group): + if hasattr(group, "_h5_group"): + group = group._h5_group + return group + + @classmethod + def _array_proxy(cls, pyt_file, group, key, array): + """Stores an array as a normal H5 node and returns the proxy object + which will be serialized to JSON. + + `ARRAY_PROXY_KEY` marks the object dictionary as an array proxy so that + `_object_hook` can recognize it. `NODE_KEY` stores the node name of the + array so that `_object_hook` can load the array data when the dict node + is deserialized. + + """ + if key in group: + pyt_file.remove_node(group, key) + pyt_file.create_array(group, key, array) + return {ARRAY_PROXY_KEY: True, NODE_KEY: key} + + @classmethod + def _handle_array_values(cls, pyt_file, group_path, data): + group = pyt_file.get_node(group_path) + + # Convert numpy array values to H5 array nodes. + out_data = {} + for key in data.keys(): + value = data[key] + if isinstance(value, ndarray): + out_data[key] = cls._array_proxy(pyt_file, group, key, value) + else: + out_data[key] = value + + # Remove stored arrays which are no longer in the data dictionary. + pyt_children = group._v_children + nodes_to_remove = [] + for key in pyt_children.keys(): + if key not in data: + nodes_to_remove.append(key) + + for key in nodes_to_remove: + pyt_file.remove_node(group, key) + + return out_data
+
+ +
+
+
+
+
+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/5.0/_modules/apptools/io/h5/file.html b/5.0/_modules/apptools/io/h5/file.html new file mode 100644 index 000000000..5fdccad23 --- /dev/null +++ b/5.0/_modules/apptools/io/h5/file.html @@ -0,0 +1,671 @@ + + + + + + + apptools.io.h5.file — Apptools Documentation + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +

Source code for apptools.io.h5.file

+# (C) Copyright 2005-2020 Enthought, Inc., Austin, TX
+# All rights reserved.
+#
+# This software is provided without warranty under the terms of the BSD
+# license included in LICENSE.txt and may be redistributed only under
+# the conditions described in the aforementioned license. The license
+# is also available online at http://www.enthought.com/licenses/BSD.txt
+#
+# Thanks for using Enthought open source!
+from collections import Mapping, MutableMapping
+from functools import partial
+import inspect
+
+import numpy as np
+import tables
+
+from .dict_node import H5DictNode
+from .table_node import H5TableNode
+
+
+
[docs]def get_atom(dtype): + """Return a PyTables Atom for the given dtype or dtype string.""" + return tables.Atom.from_dtype(np.dtype(dtype))
+ + +
[docs]def iterator_length(iterator): + return sum(1 for _ in iterator)
+ + +def _update_wrapped_docstring(wrapped, original=None): + PREAMBLE = """\ +** H5Group wrapper for H5File.{func_name}: ** +Note that the first argument is a nodepath relative to the group, rather than +an absolute path. Below is the original docstring: + +""".format( + func_name=wrapped.__name__ + ) + wrapped.__doc__ = PREAMBLE + inspect.cleandoc(original.__doc__) + return wrapped + + +
[docs]def h5_group_wrapper(original): + return partial(_update_wrapped_docstring, original=original)
+ + +
[docs]class H5File(Mapping): + """File object for HDF5 files. + + This class wraps PyTables to provide a cleaner, but only implements an + interface for accessing arrays. + + Parameters + ---------- + filename : str or a `tables.File` instance + Filename for an HDF5 file, or a PyTables `File` object. + mode : str + Mode to open the file: + + 'r' : Read-only + 'w' : Write; create new file (an existing file would be deleted). + 'a' : Read and write to file; create if not existing + 'r+': Read and write to file; must already exist + + delete_existing : bool + If True, an existing node will be deleted when a `create_*` method is + called. Otherwise, a ValueError will be raise. + auto_groups : bool + If True, `create_array` will automatically create parent groups. + auto_open : bool + If True, open the file automatically on initialization. Otherwise, + you can call `H5File.open()` explicitly after initialization. + chunked : bool + If True, the default behavior of `create_array` will be a chunked + array (see PyTables `create_carray`). + + """ + + exists_error = ( + "'{}' exists in '{}'; set `delete_existing` attribute " + "to True to overwrite existing calculations." + ) + + def __init__( + self, + filename, + mode="r+", + delete_existing=False, + auto_groups=True, + auto_open=True, + h5filters=None, + ): + self.mode = mode + self.delete_existing = delete_existing + self.auto_groups = auto_groups + if h5filters is None: + self.h5filters = tables.Filters( + complib="blosc", complevel=5, shuffle=True + ) + self._h5 = None + + if isinstance(filename, tables.File): + pyt_file = filename + filename = pyt_file.filename + if pyt_file.isopen: + self._h5 = pyt_file + + self.filename = filename + if auto_open: + self.open() + +
[docs] def open(self): + if not self.is_open: + self._h5 = tables.open_file(self.filename, mode=self.mode)
+ +
[docs] def close(self): + if self.is_open: + self._h5.close() + self._h5 = None
+ + @property + def root(self): + return self["/"] + + @property + def is_open(self): + return self._h5 is not None + + def __str__(self): + return str(self._h5) + + def __repr__(self): + return repr(self._h5) + + def __contains__(self, node_path): + return node_path in self._h5 + + def __getitem__(self, node_path): + try: + node = self._h5.get_node(node_path) + except tables.NoSuchNodeError: + msg = "Node {0!r} not found in {1!r}" + raise NameError(msg.format(node_path, self.filename)) + return _wrap_node(node) + + def __iter__(self): + return (_wrap_node(n) for n in self._h5.iter_nodes(where="/")) + + def __len__(self): + return iterator_length(self) + +
[docs] def iteritems(self, path="/"): + """ Iterate over node paths and nodes of the h5 file. """ + for node in self._h5.walk_nodes(where=path): + node_path = node._v_pathname + yield node_path, _wrap_node(node)
+ +
[docs] def create_array( + self, + node_path, + array_or_shape, + dtype=None, + chunked=False, + extendable=False, + **kwargs + ): + """Create node to store an array. + + Parameters + ---------- + node_path : str + PyTable node path; e.g. '/path/to/node'. + array_or_shape : array or shape tuple + Array or shape tuple for an array. If given a shape tuple, the + `dtype` parameter must also specified. + dtype : str or numpy.dtype + Data type of array. Only necessary if `array_or_shape` is a shape. + chunked : bool + Controls whether the array is chunked. + extendable : {None | bool} + Controls whether the array is extendable. + kwargs : key/value pairs + Keyword args passed to PyTables `File.create_(c|e)array`. + """ + self._check_node(node_path) + self._assert_valid_path(node_path) + + h5 = self._h5 + + if isinstance(array_or_shape, tuple): + if dtype is None: + msg = "`dtype` must be specified if only given array shape." + raise ValueError(msg) + array = None + dtype = dtype + shape = array_or_shape + else: + array = array_or_shape + dtype = array.dtype.name + shape = array.shape + + path, name = self.split_path(node_path) + if extendable: + shape = (0,) + shape[1:] + atom = get_atom(dtype) + node = h5.create_earray( + path, name, atom, shape, filters=self.h5filters, **kwargs + ) + if array is not None: + node.append(array) + elif chunked: + atom = get_atom(dtype) + node = h5.create_carray( + path, name, atom, shape, filters=self.h5filters, **kwargs + ) + if array is not None: + node[:] = array + else: + if array is None: + array = np.zeros(shape, dtype=dtype) + node = h5.create_array(path, name, array, **kwargs) + return node
+ +
[docs] def create_group(self, group_path, **kwargs): + """Create group. + + Parameters + ---------- + group_path : str + PyTable group path; e.g. '/path/to/group'. + kwargs : key/value pairs + Keyword args passed to PyTables `File.create_group`. + """ + self._check_node(group_path) + self._assert_valid_path(group_path) + path, name = self.split_path(group_path) + self._h5.create_group(path, name, **kwargs) + return self[group_path]
+ +
[docs] def create_dict(self, node_path, data=None, **kwargs): + """Create dict node at the specified path. + + Parameters + ---------- + node_path : str + Path to node where data is stored (e.g. '/path/to/my_dict') + data : dict + Data for initialization, if desired. + """ + self._check_node(node_path) + self._assert_valid_path(node_path) + H5DictNode.add_to_h5file(self, node_path, data=data, **kwargs) + return self[node_path]
+ +
[docs] def create_table(self, node_path, description, **kwargs): + """Create table node at the specified path. + + Parameters + ---------- + node_path : str + Path to node where data is stored (e.g. '/path/to/my_dict') + description : dict or numpy dtype object + The description of the columns in the table. This is either a dict + of column name -> dtype items or a numpy record array dtype. For + more information, see the documentation for Table in pytables. + """ + self._check_node(node_path) + self._assert_valid_path(node_path) + H5TableNode.add_to_h5file(self, node_path, description, **kwargs) + return self[node_path]
+ + def _check_node(self, node_path): + """Check if node exists and create parent groups if necessary. + + Either raise error or delete depending on `delete_existing` attribute. + """ + if self.auto_groups: + path, name = self.split_path(node_path) + self._create_required_groups(path) + + if node_path in self: + if self.delete_existing: + if isinstance(self[node_path], H5Group): + self.remove_group(node_path, recursive=True) + else: + self.remove_node(node_path) + else: + msg = self.exists_error.format(node_path, self.filename) + raise ValueError(msg) + + def _create_required_groups(self, path): + if path not in self: + parent, missing = self.split_path(path) + # Call recursively to ensure that all parent groups exist. + self._create_required_groups(parent) + self.create_group(path) + +
[docs] def remove_node(self, node_path): + """Remove node + + Parameters + ---------- + node_path : str + PyTable node path; e.g. '/path/to/node'. + """ + node = self[node_path] + if isinstance(node, H5Group): + msg = "{!r} is a group. Use `remove_group` to remove group nodes." + raise ValueError(msg.format(node.pathname)) + node._f_remove()
+ +
[docs] def remove_group(self, group_path, **kwargs): + """Remove group + + Parameters + ---------- + group_path : str + PyTable group path; e.g. '/path/to/group'. + """ + self[group_path]._h5_group._g_remove(**kwargs)
+ + @classmethod + def _assert_valid_path(self, node_path): + if "attrs" in node_path.split("/"): + raise ValueError("'attrs' is an invalid node name.") + +
[docs] @classmethod + def split_path(cls, node_path): + """Split node path returning the base path and node name. + + For example: '/path/to/node' will return '/path/to' and 'node' + + Parameters + ---------- + node_path : str + PyTable node path; e.g. '/path/to/node'. + """ + i = node_path.rfind("/") + if i == 0: + return "/", node_path[1:] + else: + return node_path[:i], node_path[i + 1:]
+ +
[docs] @classmethod + def join_path(cls, *args): + """Join parts of an h5 path. + + For example, the 3 argmuments 'path', 'to', 'node' will return + '/path/to/node'. + + Parameters + ---------- + args : str + Parts of path to be joined. + """ + path = "/".join(part.strip("/") for part in args) + if not path.startswith("/"): + path = "/" + path + return path
+ + +
[docs]class H5Attrs(MutableMapping): + """An attributes dictionary for an h5 node. + + This intercepts `__setitem__` so that python sequences can be converted to + numpy arrays. This helps preserve the readability of our HDF5 files by + other (non-python) programs. + """ + + def __init__(self, node_attrs): + self._node_attrs = node_attrs + + def __delitem__(self, key): + del self._node_attrs[key] + + def __getitem__(self, key): + return self._node_attrs[key] + + def __iter__(self): + return iter(self.keys()) + + def __len__(self): + return len(self._node_attrs._f_list()) + + def __setitem__(self, key, value): + if isinstance(value, tuple) or isinstance(value, list): + value = np.array(value) + self._node_attrs[key] = value + +
[docs] def get(self, key, default=None): + return default if key not in self else self[key]
+ +
[docs] def keys(self): + return self._node_attrs._f_list()
+ +
[docs] def values(self): + return [self[k] for k in self.keys()]
+ +
[docs] def items(self): + return [(k, self[k]) for k in self.keys()]
+ + +
[docs]class H5Group(Mapping): + """A group node in an H5File. + + This is a thin wrapper around PyTables' Group object to expose attributes + and maintain the dict interface of H5File. + """ + + def __init__(self, pytables_group): + self._h5_group = pytables_group + self.attrs = H5Attrs(self._h5_group._v_attrs) + + def __contains__(self, node_path): + return node_path in self._h5_group + + def __str__(self): + return str(self._h5_group) + + def __repr__(self): + return repr(self._h5_group) + + def __getitem__(self, node_path): + parts = node_path.split("/") + # PyTables stores children as attributes + node = self._h5_group.__getattr__(parts[0]) + node = _wrap_node(node) + if len(parts) == 1: + return node + else: + return node["/".join(parts[1:])] + + def __iter__(self): + return (_wrap_node(c) for c in self._h5_group) + + def __len__(self): + return iterator_length(self) + + @property + def pathname(self): + return self._h5_group._v_pathname + + @property + def name(self): + return self._h5_group._v_name + + @property + def filename(self): + return self._h5_group._v_file.filename + + @property + def root(self): + return _wrap_node(self._h5_group._v_file.root) + + @property + def children_names(self): + return list(self._h5_group._v_children.keys()) + + @property + def subgroup_names(self): + return list(self._h5_group._v_groups.keys()) + +
[docs] def iter_groups(self): + """ Iterate over `H5Group` nodes that are children of this group. """ + groups = self._h5_group._v_groups + + # not using the groups.values() method here, because groups is a + # `proxydict` object whose .values() method is non-lazy. Related: + # PyTables/PyTables#784. + return (_wrap_node(groups[group_name]) for group_name in groups)
+ +
[docs] @h5_group_wrapper(H5File.create_group) + def create_group(self, group_subpath, delete_existing=False, **kwargs): + return self._delegate_to_h5file( + "create_group", + group_subpath, + delete_existing=delete_existing, + **kwargs + )
+ +
[docs] @h5_group_wrapper(H5File.remove_group) + def remove_group(self, group_subpath, **kwargs): + return self._delegate_to_h5file( + "remove_group", group_subpath, **kwargs + )
+ +
[docs] @h5_group_wrapper(H5File.create_array) + def create_array( + self, + node_subpath, + array_or_shape, + dtype=None, + chunked=False, + extendable=False, + **kwargs + ): + return self._delegate_to_h5file( + "create_array", + node_subpath, + array_or_shape, + dtype=dtype, + chunked=chunked, + extendable=extendable, + **kwargs + )
+ +
[docs] @h5_group_wrapper(H5File.create_table) + def create_table(self, node_subpath, description, *args, **kwargs): + return self._delegate_to_h5file( + "create_table", node_subpath, description, *args, **kwargs + )
+ +
[docs] @h5_group_wrapper(H5File.create_dict) + def create_dict(self, node_subpath, data=None, **kwargs): + return self._delegate_to_h5file( + "create_dict", node_subpath, data=data, **kwargs + )
+ +
[docs] @h5_group_wrapper(H5File.remove_node) + def remove_node(self, node_subpath, **kwargs): + return self._delegate_to_h5file("remove_node", node_subpath, **kwargs)
+ + def _delegate_to_h5file( + self, function_name, node_subpath, *args, **kwargs + ): + delete_existing = kwargs.pop("delete_existing", False) + h5 = H5File(self._h5_group._v_file, delete_existing=delete_existing) + group_path = h5.join_path(self.pathname, node_subpath) + func = getattr(h5, function_name) + return func(group_path, *args, **kwargs)
+ + +def _wrap_node(node): + """ Wrap PyTables node object, if necessary. """ + if isinstance(node, tables.Group): + if H5DictNode.is_dict_node(node): + node = H5DictNode(node) + else: + node = H5Group(node) + elif H5TableNode.is_table_node(node): + node = H5TableNode(node) + return node +
+ +
+
+
+
+
+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/5.0/_modules/apptools/io/h5/table_node.html b/5.0/_modules/apptools/io/h5/table_node.html new file mode 100644 index 000000000..755c69191 --- /dev/null +++ b/5.0/_modules/apptools/io/h5/table_node.html @@ -0,0 +1,287 @@ + + + + + + + apptools.io.h5.table_node — Apptools Documentation + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +

Source code for apptools.io.h5.table_node

+# (C) Copyright 2005-2020 Enthought, Inc., Austin, TX
+# All rights reserved.
+#
+# This software is provided without warranty under the terms of the BSD
+# license included in LICENSE.txt and may be redistributed only under
+# the conditions described in the aforementioned license. The license
+# is also available online at http://www.enthought.com/licenses/BSD.txt
+#
+# Thanks for using Enthought open source!
+import numpy as np
+
+from tables.table import Table as PyTablesTable
+
+
+class _TableRowAccessor(object):
+    """A simple object which provides read access to the rows in a Table."""
+
+    def __init__(self, h5_table):
+        self._h5_table = h5_table
+
+    def __getitem__(self, key):
+        return self._h5_table[key]
+
+
+
[docs]class H5TableNode(object): + """A wrapper for PyTables Table nodes. + + Parameters + ---------- + node : tables.Table instance + An H5 node which is a pytables.Table or H5TableNode instance + """ + + def __init__(self, node): + # Avoid a circular import + from .file import H5Attrs + + assert self.is_table_node(node) + self._h5_table = node._h5_table if hasattr(node, "_h5_table") else node + self.attrs = H5Attrs(self._h5_table._v_attrs) + + # -------------------------------------------------------------------------- + # Creation methods + # -------------------------------------------------------------------------- + +
[docs] @classmethod + def add_to_h5file(cls, h5, node_path, description, **kwargs): + """Add table node to an H5 file at the specified path. + + Parameters + ---------- + h5 : H5File + The H5 file where the table node will be stored. + node_path : str + Path to node where data is stored (e.g. '/path/to/my_table') + description : list of tuples or numpy dtype object + The description of the columns in the table. This is either a list + of (column name, dtype, [, shape or itemsize]) tuples or a numpy + record array dtype. For more information, see the documentation for + `Table` in PyTables. + **kwargs : dict + Additional keyword arguments to pass to pytables.File.create_table + """ + if isinstance(description, (tuple, list)): + description = np.dtype(description) + + cls._create_pytables_node(h5, node_path, description, **kwargs) + node = h5[node_path] + + return cls(node)
+ +
[docs] @classmethod + def is_table_node(cls, pytables_node): + """Return True if pytables_node is a pytables.Table or a H5TableNode. + """ + return isinstance(pytables_node, (PyTablesTable, H5TableNode))
+ + # -------------------------------------------------------------------------- + # Public interface + # -------------------------------------------------------------------------- + +
[docs] def append(self, data): + """Add some data to the table. + + Parameters + ---------- + data : dict + A dictionary of column name -> values items + """ + rows = list(zip(*[data[name] for name in self.keys()])) + self._h5_table.append(rows)
+ + def __getitem__(self, col_or_cols): + """Return one or more columns of data from the table. + + Parameters + ---------- + col_or_cols : str or list of str + A single column name or a list of column names + + Return + ------ + data : ndarray + An array of column data with the column order matching that of + `col_or_cols`. + """ + if isinstance(col_or_cols, str): + return self._h5_table.col(col_or_cols) + + column_data = [self._h5_table.col(name) for name in col_or_cols] + return np.column_stack(column_data) + + @property + def ix(self): + """Return an object which provides access to row data.""" + return _TableRowAccessor(self._h5_table) + +
[docs] def keys(self): + return self._h5_table.colnames
+ +
[docs] def to_dataframe(self): + """Return table data as a pandas `DataFrame`. + + XXX: This does not work if the table contains a multidimensional column + + This method requires pandas to have been installed in the environment. + """ + from pandas import DataFrame + + # Slicing rows gives a numpy struct array, which DataFrame understands. + return DataFrame(self.ix[:])
+ + # -------------------------------------------------------------------------- + # Object interface + # -------------------------------------------------------------------------- + + def __repr__(self): + return repr(self._h5_table) + + def __len__(self): + return self._h5_table.nrows + + # -------------------------------------------------------------------------- + # Private interface + # -------------------------------------------------------------------------- + + def _f_remove(self): + """Implement the PyTables `Node._f_remove` method so that H5File + doesn't choke when trying to remove our node. + """ + self._h5_table._f_remove() + self._h5_table = None + + @classmethod + def _create_pytables_node(cls, h5, node_path, description, **kwargs): + path, name = h5.split_path(node_path) + pyt_file = h5._h5 + pyt_file.create_table(path, name, description, **kwargs)
+
+ +
+
+
+
+
+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/5.0/_modules/apptools/io/h5/utils.html b/5.0/_modules/apptools/io/h5/utils.html new file mode 100644 index 000000000..a35477daa --- /dev/null +++ b/5.0/_modules/apptools/io/h5/utils.html @@ -0,0 +1,166 @@ + + + + + + + apptools.io.h5.utils — Apptools Documentation + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +

Source code for apptools.io.h5.utils

+# (C) Copyright 2005-2020 Enthought, Inc., Austin, TX
+# All rights reserved.
+#
+# This software is provided without warranty under the terms of the BSD
+# license included in LICENSE.txt and may be redistributed only under
+# the conditions described in the aforementioned license. The license
+# is also available online at http://www.enthought.com/licenses/BSD.txt
+#
+# Thanks for using Enthought open source!
+from contextlib import contextmanager
+
+from .file import H5File
+
+
+
[docs]@contextmanager +def open_h5file(filename, mode="r+", **kwargs): + """Context manager for reading an HDF5 file as an H5File object. + + Parameters + ---------- + filename : str + HDF5 file name. + mode : str + Mode to open the file: + + 'r' : Read-only + 'w' : Write; create new file (an existing file would be deleted). + 'a' : Read and write to file; create if not existing + 'r+': Read and write to file; must already exist + + See `H5File` for additional keyword arguments. + """ + h5 = H5File(filename, mode=mode, **kwargs) + try: + yield h5 + finally: + h5.close()
+
+ +
+
+
+
+
+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/5.0/_modules/apptools/logger/agent/attachments.html b/5.0/_modules/apptools/logger/agent/attachments.html new file mode 100644 index 000000000..f0d664cbb --- /dev/null +++ b/5.0/_modules/apptools/logger/agent/attachments.html @@ -0,0 +1,235 @@ + + + + + + + apptools.logger.agent.attachments — Apptools Documentation + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +

Source code for apptools.logger.agent.attachments

+# (C) Copyright 2005-2020 Enthought, Inc., Austin, TX
+# All rights reserved.
+#
+# This software is provided without warranty under the terms of the BSD
+# license included in LICENSE.txt and may be redistributed only under
+# the conditions described in the aforementioned license. The license
+# is also available online at http://www.enthought.com/licenses/BSD.txt
+#
+# Thanks for using Enthought open source!
+""" Attach relevant project files.
+
+FIXME: there are no public project plugins for Envisage 3, yet. In any case,
+this stuff should not be hard-coded, but extensible via extension points. The
+code remains here because we can reuse the zip utility code in that extensible
+rewrite.
+"""
+
+import logging
+import os.path
+from email import encoders
+from email.mime.base import MIMEBase
+
+from traits.api import Any, HasTraits
+
+
+logger = logging.getLogger(__name__)
+
+
+
[docs]class Attachments(HasTraits): + + application = Any() + message = Any() + + def __init__(self, message, **traits): + traits = traits.copy() + traits["message"] = message + super(Attachments, self).__init__(**traits) + + # FIXME: all of the package_*() methods refer to deprecated project plugins + +
[docs] def package_workspace(self): + if self.application is None: + pass + + workspace = self.application.get_service("envisage.project.IWorkspace") + if workspace is not None: + dir = workspace.path + self._attach_directory(dir)
+ +
[docs] def package_single_project(self): + if self.application is None: + pass + + single_project = self.application.get_service( + "envisage.single_project.ModelService" + ) + if single_project is not None: + dir = single_project.location + self._attach_directory(dir)
+ +
[docs] def package_any_relevant_files(self): + self.package_workspace() + self.package_single_project()
+ + def _attach_directory(self, dir): + relpath = os.path.basename(dir) + + import zipfile + from io import BytesIO + + ctype = "application/octet-stream" + maintype, subtype = ctype.split("/", 1) + msg = MIMEBase(maintype, subtype) + + file_object = BytesIO() + zip = zipfile.ZipFile(file_object, "w") + _append_to_zip_archive(zip, dir, relpath) + zip.close() + + msg.set_payload(file_object.getvalue()) + + encoders.encode_base64(msg) # Encode the payload using Base64 + msg.add_header( + "Content-Disposition", "attachment", filename="project.zip" + ) + + self.message.attach(msg) + + file_object.close()
+ + +def _append_to_zip_archive(zip, dir, relpath): + """ Add all files in and below directory dir into zip archive""" + for filename in os.listdir(dir): + path = os.path.join(dir, filename) + + if os.path.isfile(path): + name = os.path.join(relpath, filename) + zip.write(path, name) + logger.debug("adding %s to error report" % path) + else: + if filename != ".svn": # skip svn files if any + subdir = os.path.join(dir, filename) + _append_to_zip_archive( + zip, subdir, os.path.join(relpath, filename) + ) +
+ +
+
+
+
+
+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/5.0/_modules/apptools/logger/agent/quality_agent_mailer.html b/5.0/_modules/apptools/logger/agent/quality_agent_mailer.html new file mode 100644 index 000000000..d6d7b3c5c --- /dev/null +++ b/5.0/_modules/apptools/logger/agent/quality_agent_mailer.html @@ -0,0 +1,244 @@ + + + + + + + apptools.logger.agent.quality_agent_mailer — Apptools Documentation + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +

Source code for apptools.logger.agent.quality_agent_mailer

+# (C) Copyright 2005-2020 Enthought, Inc., Austin, TX
+# All rights reserved.
+#
+# This software is provided without warranty under the terms of the BSD
+# license included in LICENSE.txt and may be redistributed only under
+# the conditions described in the aforementioned license. The license
+# is also available online at http://www.enthought.com/licenses/BSD.txt
+#
+# Thanks for using Enthought open source!
+
+# Standard library imports.
+import logging
+import os
+
+# Enthought library imports.
+from traits.util.home_directory import get_home_directory
+
+
+# Setup a logger for this module.
+logger = logging.getLogger(__name__)
+
+
+
[docs]def create_email_message( + fromaddr, + toaddrs, + ccaddrs, + subject, + priority, + include_project=False, + stack_trace="", + comments="", +): + # format a message suitable to be sent to the Roundup bug tracker + + from email.MIMEMultipart import MIMEMultipart + from email.MIMEText import MIMEText + from email.MIMEBase import MIMEBase + + message = MIMEMultipart() + message["Subject"] = "%s [priority=%s]" % (subject, priority) + message["To"] = ", ".join(toaddrs) + message["Cc"] = ", ".join(ccaddrs) + message["From"] = fromaddr + message.preamble = "You will not see this in a MIME-aware mail reader.\n" + message.epilogue = " " # To guarantee the message ends with a newline + + # First section is simple ASCII data ... + m = [] + m.append("Bug Report") + m.append("==============================") + m.append("") + + if len(comments) > 0: + m.append("Comments:") + m.append("========") + m.append(comments) + m.append("") + + if len(stack_trace) > 0: + m.append("Stack Trace:") + m.append("===========") + m.append(stack_trace) + m.append("") + + msg = MIMEText("\n".join(m)) + message.attach(msg) + + # Include the log file ... + if True: + try: + log = os.path.join(get_home_directory(), "envisage.log") + f = open(log, "r") + entries = f.readlines() + f.close() + + ctype = "application/octet-stream" + maintype, subtype = ctype.split("/", 1) + msg = MIMEBase(maintype, subtype) + + msg = MIMEText("".join(entries)) + msg.add_header( + "Content-Disposition", "attachment", filename="logfile.txt" + ) + message.attach(msg) + except Exception: + logger.exception("Failed to include log file with message") + + # Include the environment variables ... + if True: + """ + Transmit the user's environment settings as well. Main purpose is to + work out the user name to help with following up on bug reports and + in future we should probably send less data. + """ + try: + entries = [] + for key, value in os.environ.items(): + entries.append("%30s : %s\n" % (key, value)) + + ctype = "application/octet-stream" + maintype, subtype = ctype.split("/", 1) + msg = MIMEBase(maintype, subtype) + + msg = MIMEText("".join(entries)) + msg.add_header( + "Content-Disposition", "attachment", filename="environment.txt" + ) + message.attach(msg) + + except Exception: + logger.exception( + "Failed to include environment variables with message" + ) + + return message
+
+ +
+
+
+
+
+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/5.0/_modules/apptools/logger/agent/quality_agent_view.html b/5.0/_modules/apptools/logger/agent/quality_agent_view.html new file mode 100644 index 000000000..8a09b4bfa --- /dev/null +++ b/5.0/_modules/apptools/logger/agent/quality_agent_view.html @@ -0,0 +1,510 @@ + + + + + + + apptools.logger.agent.quality_agent_view — Apptools Documentation + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +

Source code for apptools.logger.agent.quality_agent_view

+# (C) Copyright 2005-2020 Enthought, Inc., Austin, TX
+# All rights reserved.
+#
+# This software is provided without warranty under the terms of the BSD
+# license included in LICENSE.txt and may be redistributed only under
+# the conditions described in the aforementioned license. The license
+# is also available online at http://www.enthought.com/licenses/BSD.txt
+#
+# Thanks for using Enthought open source!
+
+# Standard library imports.
+import logging
+
+# Enthought library imports.
+from pyface.api import Dialog
+from traits.api import Any, Str, Tuple
+
+
+# Setup a logger for this module.
+logger = logging.getLogger(__name__)
+
+
+priority_levels = ["Low", "Medium", "High", "Critical"]
+
+
+
[docs]class QualityAgentView(Dialog): + + size = Tuple((700, 900)) + title = Str("Quality Agent") + + # The associated LoggerService. + service = Any() + + msg = Str("") + subject = Str("Untitled Error Report") + to_address = Str() + cc_address = Str("") + from_address = Str() + smtp_server = Str() + priority = Str(priority_levels[2]) + comments = Str("None") + include_userdata = Any + + ########################################################################### + # Protected 'Dialog' interface. + ########################################################################### + + # fixme: Ideally, this should be passed in; this topic ID belongs to the + # Enlib help project/plug-in. + help_id = "enlib|HID_Quality_Agent_Dlg" + + def _create_dialog_area(self, parent): + """ Creates the main content of the dialog. """ + import wx + + parent.SetSizeHints(minW=300, minH=575) + + # Add the main panel + sizer = wx.BoxSizer(wx.VERTICAL) + panel = wx.Panel(parent, -1) + panel.SetSizer(sizer) + panel.SetAutoLayout(True) + + # Add a descriptive label at the top ... + label = wx.StaticText(panel, -1, "Send a comment or bug report ...") + sizer.Add(label, 0, wx.ALL, border=5) + + # Add the stack trace view ... + error_panel = self._create_error_panel(panel) + sizer.Add( + error_panel, 1, wx.ALL | wx.EXPAND | wx.CLIP_CHILDREN, border=5 + ) + + # Update the layout: + sizer.Fit(panel) + + # Add the error report view ... + report_panel = self._create_report_panel(panel) + sizer.Add( + report_panel, 2, wx.ALL | wx.EXPAND | wx.CLIP_CHILDREN, border=5 + ) + + # Update the layout: + sizer.Fit(panel) + + return panel + + def _create_buttons(self, parent): + """ Creates the buttons. """ + import wx + + sizer = wx.BoxSizer(wx.HORIZONTAL) + + # 'Send' button. + send = wx.Button(parent, wx.ID_OK, "Send") + wx.EVT_BUTTON(parent, wx.ID_OK, self._on_send) + sizer.Add(send) + send.SetDefault() + + # 'Cancel' button. + cancel = wx.Button(parent, wx.ID_CANCEL, "Cancel") + wx.EVT_BUTTON(parent, wx.ID_CANCEL, self._wx_on_cancel) + sizer.Add(cancel, 0, wx.LEFT, 10) + + # 'Help' button. + if len(self.help_id) > 0: + help = wx.Button(parent, wx.ID_HELP, "Help") + wx.EVT_BUTTON(parent, wx.ID_HELP, self._wx_on_help) + sizer.Add(help, 0, wx.LEFT, 10) + + return sizer + + ### Utility methods ####################################################### + + def _create_error_panel(self, parent): + import wx + + box = wx.StaticBox(parent, -1, "Message:") + sizer = wx.StaticBoxSizer(box, wx.VERTICAL) + + # Print the stack trace + label2 = wx.StaticText( + parent, + -1, + "The following information will be included in the report:", + ) + sizer.Add( + label2, + 0, + wx.LEFT | wx.TOP | wx.BOTTOM | wx.CLIP_CHILDREN, + border=5, + ) + + details = wx.TextCtrl( + parent, + -1, + self.msg, + size=(-1, 75), + style=wx.TE_MULTILINE + | wx.TE_READONLY + | wx.HSCROLL + | wx.VSCROLL + | wx.TE_RICH2 + | wx.CLIP_CHILDREN, + ) + details.SetSizeHints(minW=-1, minH=75) + # Set the font to not be proportional + font = wx.Font(12, wx.MODERN, wx.NORMAL, wx.NORMAL) + details.SetStyle(0, len(self.msg), wx.TextAttr(font=font)) + sizer.Add(details, 1, wx.EXPAND | wx.ALL | wx.CLIP_CHILDREN, 5) + + return sizer + + def _create_report_panel(self, parent): + import wx + + box = wx.StaticBox(parent, -1, "Report Information:") + sizer = wx.StaticBoxSizer(box, wx.VERTICAL) + + # Add email info ... + sizer.Add(self._create_email_info(parent), 0, wx.ALL | wx.EXPAND, 5) + + # Add priority combo: + sizer.Add(self._create_priority_combo(parent), 0, wx.ALL | wx.RIGHT, 5) + + # Extra comments from the user: + label3 = wx.StaticText(parent, -1, "Additional Comments:") + sizer.Add( + label3, 0, wx.LEFT | wx.TOP | wx.BOTTOM | wx.CLIP_CHILDREN, 5 + ) + + comments_field = wx.TextCtrl( + parent, + -1, + self.comments, + size=(-1, 75), + style=wx.TE_MULTILINE | wx.TE_RICH2 | wx.CLIP_CHILDREN, + ) + comments_field.SetSizeHints(minW=-1, minH=75) + font = wx.Font(12, wx.MODERN, wx.NORMAL, wx.NORMAL) + comments_field.SetStyle(0, len(self.comments), wx.TextAttr(font=font)) + sizer.Add(comments_field, 1, wx.ALL | wx.EXPAND | wx.CLIP_CHILDREN, 5) + wx.EVT_TEXT(parent, comments_field.GetId(), self._on_comments) + + # Include the project combobox? + if len(self.service.mail_files) > 0: + sizer.Add(self._create_project_upload(parent), 0, wx.ALL, border=5) + + return sizer + + def _create_email_info(self, parent): + import wx + + # Layout setup .. + sizer = wx.FlexGridSizer(5, 2, 10, 10) + sizer.AddGrowableCol(1) + + title_label = wx.StaticText(parent, -1, "Subject:") + sizer.Add(title_label, 0, wx.ALL | wx.ALIGN_RIGHT) + title_field = wx.TextCtrl(parent, -1, self.subject, wx.Point(-1, -1)) + sizer.Add( + title_field, + 1, + wx.EXPAND | wx.ALL | wx.ALIGN_RIGHT | wx.CLIP_CHILDREN, + ) + wx.EVT_TEXT(parent, title_field.GetId(), self._on_subject) + + to_label = wx.StaticText(parent, -1, "To:") + sizer.Add(to_label, 0, wx.ALL | wx.ALIGN_RIGHT) + to_field = wx.TextCtrl(parent, -1, self.to_address) + sizer.Add( + to_field, 1, wx.EXPAND | wx.ALL | wx.ALIGN_RIGHT | wx.CLIP_CHILDREN + ) + wx.EVT_TEXT(parent, to_field.GetId(), self._on_to) + + cc_label = wx.StaticText(parent, -1, "Cc:") + sizer.Add(cc_label, 0, wx.ALL | wx.ALIGN_RIGHT) + cc_field = wx.TextCtrl(parent, -1, "") + sizer.Add( + cc_field, 1, wx.EXPAND | wx.ALL | wx.ALIGN_RIGHT | wx.CLIP_CHILDREN + ) + wx.EVT_TEXT(parent, cc_field.GetId(), self._on_cc) + + from_label = wx.StaticText(parent, -1, "From:") + sizer.Add(from_label, 0, wx.ALL | wx.ALIGN_RIGHT) + from_field = wx.TextCtrl(parent, -1, self.from_address) + sizer.Add( + from_field, + 1, + wx.EXPAND | wx.ALL | wx.ALIGN_RIGHT | wx.CLIP_CHILDREN, + ) + wx.EVT_TEXT(parent, from_field.GetId(), self._on_from) + + smtp_label = wx.StaticText(parent, -1, "SMTP Server:") + sizer.Add(smtp_label, 0, wx.ALL | wx.ALIGN_RIGHT) + smtp_server_field = wx.TextCtrl(parent, -1, self.smtp_server) + sizer.Add( + smtp_server_field, + 1, + wx.EXPAND | wx.ALL | wx.ALIGN_RIGHT | wx.CLIP_CHILDREN, + ) + wx.EVT_TEXT(parent, smtp_server_field.GetId(), self._on_smtp_server) + + return sizer + + def _create_priority_combo(self, parent): + import wx + + sizer = wx.BoxSizer(wx.HORIZONTAL) + + label = wx.StaticText(parent, -1, "How critical is this issue?") + sizer.Add(label, 0, wx.ALL, border=0) + + cb = wx.ComboBox( + parent, + -1, + self.priority, + wx.Point(90, 50), + wx.Size(95, -1), + priority_levels, + wx.CB_READONLY, + ) + sizer.Add(cb, 1, wx.EXPAND | wx.LEFT | wx.CLIP_CHILDREN, border=10) + + wx.EVT_COMBOBOX(parent, cb.GetId(), self._on_priority) + + return sizer + + def _create_project_upload(self, parent): + import wx + + id = wx.NewId() + cb = wx.CheckBox( + parent, + id, + "Include Workspace Files (will increase email size) ", + wx.Point(65, 80), + wx.Size(-1, 20), + wx.NO_BORDER, + ) + wx.EVT_CHECKBOX(parent, id, self._on_project) + + return cb + + ## UI Listeners ########################################################### + + def _on_subject(self, event): + self.subject = event.GetEventObject().GetValue() + + def _on_to(self, event): + self.to_address = event.GetEventObject().GetValue() + + def _on_cc(self, event): + self.cc_address = event.GetEventObject().GetValue() + + def _on_from(self, event): + self.from_address = event.GetEventObject().GetValue() + + def _on_smtp_server(self, event): + self.smtp_server = event.GetEventObject().GetValue() + + def _on_priority(self, event): + self.priority = event.GetEventObject().GetStringSelection() + + def _on_comments(self, event): + self.comments = event.GetEventObject().GetValue() + + def _on_project(self, event): + self.include_userdata = event.Checked() + cb = event.GetEventObject() + + if event.Checked(): + cb.SetLabel( + "Include Workspace Files (approx. %.2f MBytes)" + % self._compute_project_size() + ) + else: + cb.SetLabel("Include Workspace Files (will increase email size)") + + def _on_send(self, event): + + # Disable the Send button while we go through the possibly + # time-consuming email-sending process. + button = event.GetEventObject() + button.Enable(0) + + fromaddr, toaddrs, ccaddrs = self._create_email_addresses() + message = self._create_email(fromaddr, toaddrs, ccaddrs) + + self.service.send_bug_report( + self.smtp_server, fromaddr, toaddrs, ccaddrs, message + ) + + # save the user's preferences + self.service.preferences.smtp_server = self.smtp_server + self.service.preferences.to_address = self.to_address + self.service.preferences.from_address = self.from_address + + # finally we close the dialog + self._wx_on_ok(event) + + ## Private ################################################################ + + def _create_email_addresses(self): + # utility function map addresses from ui into the standard format + # FIXME: We should use standard To: header parsing instead of this ad + # hoc whitespace-only approach. + fromaddr = self.from_address + if "" == fromaddr.strip(): + fromaddr = "anonymous" + toaddrs = self.to_address.split() + ccaddrs = self.cc_address.split() + + return fromaddr, toaddrs, ccaddrs + + def _compute_project_size(self): + # determine size of email in MBytes + fromaddr, toaddrs, ccaddrs = self._create_email_addresses() + message = self._create_email(fromaddr, toaddrs, ccaddrs) + return len(message.as_string()) / (2.0 ** 20) + + def _create_email(self, fromaddr, toaddrs, ccaddrs): + return self.service.create_email_message( + fromaddr, + toaddrs, + ccaddrs, + self.subject, + self.priority, + self.include_userdata, + self.msg, + self.comments, + ) + + def _to_address_default(self): + return self.service.preferences.to_address + + def _from_address_default(self): + return self.service.preferences.from_address + + def _smtp_server_default(self): + return self.service.preferences.smtp_server
+
+ +
+
+
+
+
+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/5.0/_modules/apptools/logger/custom_excepthook.html b/5.0/_modules/apptools/logger/custom_excepthook.html new file mode 100644 index 000000000..371e3aa28 --- /dev/null +++ b/5.0/_modules/apptools/logger/custom_excepthook.html @@ -0,0 +1,165 @@ + + + + + + + apptools.logger.custom_excepthook — Apptools Documentation + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +

Source code for apptools.logger.custom_excepthook

+# (C) Copyright 2005-2020 Enthought, Inc., Austin, TX
+# All rights reserved.
+#
+# This software is provided without warranty under the terms of the BSD
+# license included in LICENSE.txt and may be redistributed only under
+# the conditions described in the aforementioned license. The license
+# is also available online at http://www.enthought.com/licenses/BSD.txt
+#
+# Thanks for using Enthought open source!
+
+
+# Standard library imports.
+import logging
+from traceback import format_exception
+
+
+"""
+    To catch exceptions with our own code this code needs to be added
+    sys.excepthook = custom_excepthook
+"""
+
+
+
[docs]def custom_excepthook(type, value, traceback): + """ Pass on the exception to the logging system. """ + + msg = "Custom - Traceback (most recent call last):\n" + list = format_exception(type, value, traceback) + + msg = "".join(list) + + # Try to find the module that the exception actually came from. + name = getattr(traceback.tb_frame, "f_globals", {}).get( + "__name__", __name__ + ) + logger = logging.getLogger(name) + logger.error(msg)
+
+ +
+
+
+
+
+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/5.0/_modules/apptools/logger/log_point.html b/5.0/_modules/apptools/logger/log_point.html new file mode 100644 index 000000000..b1b3cd71c --- /dev/null +++ b/5.0/_modules/apptools/logger/log_point.html @@ -0,0 +1,170 @@ + + + + + + + apptools.logger.log_point — Apptools Documentation + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +

Source code for apptools.logger.log_point

+# (C) Copyright 2005-2020 Enthought, Inc., Austin, TX
+# All rights reserved.
+#
+# This software is provided without warranty under the terms of the BSD
+# license included in LICENSE.txt and may be redistributed only under
+# the conditions described in the aforementioned license. The license
+# is also available online at http://www.enthought.com/licenses/BSD.txt
+#
+# Thanks for using Enthought open source!
+""" Prints a stack trace every time it is called but does not halt execution
+    of the application.
+
+    Copied from Uche Ogbuji's blog
+"""
+
+# Standard library imports.
+import inspect
+from io import StringIO
+
+
+
[docs]def log_point(msg="\n"): + stack = inspect.stack() + # get rid of logPoint's part of the stack: + stack = stack[1:] + stack.reverse() + output = StringIO() + if msg: + output.write(str(msg) + "\n") + for stackLine in stack: + frame, filename, line, funcname, lines, unknown = stackLine + if filename.endswith("/unittest.py"): + # unittest.py code is a boring part of the traceback + continue + if filename.startswith("./"): + filename = filename[2:] + output.write("%s:%s in %s:\n" % (filename, line, funcname)) + if lines: + output.write(" %s\n" % "".join(lines)[:-1]) + s = output.getvalue() + + return s
+
+ +
+
+
+
+
+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/5.0/_modules/apptools/logger/log_queue_handler.html b/5.0/_modules/apptools/logger/log_queue_handler.html new file mode 100644 index 000000000..30cce403c --- /dev/null +++ b/5.0/_modules/apptools/logger/log_queue_handler.html @@ -0,0 +1,198 @@ + + + + + + + apptools.logger.log_queue_handler — Apptools Documentation + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +

Source code for apptools.logger.log_queue_handler

+# (C) Copyright 2005-2020 Enthought, Inc., Austin, TX
+# All rights reserved.
+#
+# This software is provided without warranty under the terms of the BSD
+# license included in LICENSE.txt and may be redistributed only under
+# the conditions described in the aforementioned license. The license
+# is also available online at http://www.enthought.com/licenses/BSD.txt
+#
+# Thanks for using Enthought open source!
+
+# Standard library imports.
+from logging import Handler
+
+# Local imports.
+from .ring_buffer import RingBuffer
+
+
+
[docs]class LogQueueHandler(Handler): + + """Buffers up the log messages so that we can display them later. + This is important on startup when log messages are generated before + the ui has started. By putting them in this queue we can display + them once the ui is ready. + """ + + # The view where updates will go + _view = None + + def __init__(self, size=1000): + Handler.__init__(self) + # only buffer 1000 log records + self.size = size + self.ring = RingBuffer(self.size) + self.dirty = False + +
[docs] def emit(self, record): + """ Actually this is more like an enqueue than an emit().""" + self.ring.append(record) + if self._view is not None: + try: + self._view.update() + except Exception: + pass + self.dirty = True
+ +
[docs] def get(self): + self.dirty = False + + try: + result = self.ring.get() + except Exception: + # we did our best and it won't cause too much damage + # to just return a bogus message + result = [] + + return result
+ +
[docs] def has_new_records(self): + return self.dirty
+ +
[docs] def reset(self): + # start over with a new empty buffer + self.ring = RingBuffer(self.size) + if self._view is not None: + try: + self._view.update() + except Exception: + pass + self.dirty = True
+
+ +
+
+
+
+
+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/5.0/_modules/apptools/logger/logger.html b/5.0/_modules/apptools/logger/logger.html new file mode 100644 index 000000000..7c65ef5cc --- /dev/null +++ b/5.0/_modules/apptools/logger/logger.html @@ -0,0 +1,188 @@ + + + + + + + apptools.logger.logger — Apptools Documentation + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +

Source code for apptools.logger.logger

+# (C) Copyright 2005-2020 Enthought, Inc., Austin, TX
+# All rights reserved.
+#
+# This software is provided without warranty under the terms of the BSD
+# license included in LICENSE.txt and may be redistributed only under
+# the conditions described in the aforementioned license. The license
+# is also available online at http://www.enthought.com/licenses/BSD.txt
+#
+# Thanks for using Enthought open source!
+""" Convenience functions for creating logging handlers etc. """
+
+
+# Standard library imports.
+import logging
+from logging.handlers import RotatingFileHandler
+
+# Local imports.
+from .log_queue_handler import LogQueueHandler
+
+
+# The default logging level.
+LEVEL = logging.DEBUG
+
+# The default formatter.
+FORMATTER = logging.Formatter("%(levelname)s|%(asctime)s|%(message)s")
+
+
+
[docs]class LogFileHandler(RotatingFileHandler): + """The default log file handler.""" + + def __init__( + self, path, maxBytes=1000000, backupCount=3, level=None, formatter=None + ): + RotatingFileHandler.__init__( + self, path, maxBytes=maxBytes, backupCount=3 + ) + + if level is None: + level = LEVEL + if formatter is None: + formatter = FORMATTER + # Set our default formatter and log level. + self.setFormatter(formatter) + self.setLevel(level)
+ + +
[docs]def add_log_queue_handler(logger, level=None, formatter=None): + """Adds a queueing log handler to a logger.""" + if level is None: + level = LEVEL + if formatter is None: + formatter = FORMATTER + + # Add the handler to the root logger. + log_queue_handler = LogQueueHandler() + log_queue_handler.setLevel(level) + log_queue_handler.setFormatter(formatter) + logger.addHandler(log_queue_handler) + return log_queue_handler
+
+ +
+
+
+
+
+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/5.0/_modules/apptools/logger/plugin/logger_plugin.html b/5.0/_modules/apptools/logger/plugin/logger_plugin.html new file mode 100644 index 000000000..467379f49 --- /dev/null +++ b/5.0/_modules/apptools/logger/plugin/logger_plugin.html @@ -0,0 +1,238 @@ + + + + + + + apptools.logger.plugin.logger_plugin — Apptools Documentation + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +

Source code for apptools.logger.plugin.logger_plugin

+# (C) Copyright 2005-2020 Enthought, Inc., Austin, TX
+# All rights reserved.
+#
+# This software is provided without warranty under the terms of the BSD
+# license included in LICENSE.txt and may be redistributed only under
+# the conditions described in the aforementioned license. The license
+# is also available online at http://www.enthought.com/licenses/BSD.txt
+#
+# Thanks for using Enthought open source!
+""" Logger plugin.
+"""
+
+# Standard library imports.
+import logging
+
+# Enthought library imports.
+from envisage.api import ExtensionPoint, Plugin
+from apptools.logger.log_queue_handler import LogQueueHandler
+from traits.api import Callable, List
+
+# Local imports.
+from .logger_preferences import LoggerPreferences
+from .logger_service import LoggerService
+
+
+ID = "apptools.logger"
+ILOGGER = ID + ".plugin.logger_service.LoggerService"
+
+
+
[docs]class LoggerPlugin(Plugin): + """Logger plugin.""" + + id = ID + name = "Logger plugin" + + #### Extension points for this plugin ##################################### + + MAIL_FILES = "apptools.logger.plugin.mail_files" + + mail_files = ExtensionPoint( + List(Callable), + id=MAIL_FILES, + desc=""" + + This extension point allows you to contribute functions which will be + called to add project files to the zip file that the user mails back + with bug reports from the Quality Agent. + + The function will be passed a zipfile.ZipFile object. + + """, + ) + + #### Contributions to extension points made by this plugin ################ + + PREFERENCES = "envisage.preferences" + PREFERENCES_PAGES = "envisage.ui.workbench.preferences_pages" + VIEWS = "envisage.ui.workbench.views" + + preferences = List(contributes_to=PREFERENCES) + preferences_pages = List(contributes_to=PREFERENCES_PAGES) + views = List(contributes_to=VIEWS) + + def _preferences_default(self): + return ["pkgfile://%s/plugin/preferences.ini" % ID] + + def _preferences_pages_default(self): + from apptools.logger.plugin.view.logger_preferences_page import ( + LoggerPreferencesPage, + ) + + return [LoggerPreferencesPage] + + def _views_default(self): + return [self._logger_view_factory] + + #### Plugin interface ##################################################### + +
[docs] def start(self): + """Starts the plugin.""" + preferences = LoggerPreferences() + service = LoggerService( + application=self.application, preferences=preferences + ) + formatter = logging.Formatter("%(levelname)s|%(asctime)s|%(message)s") + handler = LogQueueHandler() + handler.setLevel(preferences.level_) + handler.setFormatter(formatter) + root_logger = logging.getLogger() + root_logger.addHandler(handler) + root_logger.setLevel(preferences.level_) + service.handler = handler + self.application.register_service(ILOGGER, service)
+ +
[docs] def stop(self): + """Stops the plugin.""" + service = self.application.get_service(ILOGGER) + service.save_preferences()
+ + #### LoggerPlugin private interface ####################################### + + def _logger_view_factory(self, **traits): + from apptools.logger.plugin.view.logger_view import LoggerView + + service = self.application.get_service(ILOGGER) + view = LoggerView(service=service, **traits) + # Record the created view on the service. + service.plugin_view = view + return view
+
+ +
+
+
+
+
+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/5.0/_modules/apptools/logger/plugin/logger_preferences.html b/5.0/_modules/apptools/logger/plugin/logger_preferences.html new file mode 100644 index 000000000..d3be2d62e --- /dev/null +++ b/5.0/_modules/apptools/logger/plugin/logger_preferences.html @@ -0,0 +1,169 @@ + + + + + + + apptools.logger.plugin.logger_preferences — Apptools Documentation + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +

Source code for apptools.logger.plugin.logger_preferences

+# (C) Copyright 2005-2020 Enthought, Inc., Austin, TX
+# All rights reserved.
+#
+# This software is provided without warranty under the terms of the BSD
+# license included in LICENSE.txt and may be redistributed only under
+# the conditions described in the aforementioned license. The license
+# is also available online at http://www.enthought.com/licenses/BSD.txt
+#
+# Thanks for using Enthought open source!
+import logging
+
+from apptools.preferences.api import PreferencesHelper
+from traits.api import Bool, Str, Trait
+
+
+
[docs]class LoggerPreferences(PreferencesHelper): + """The persistent service exposing the Logger plugin's API.""" + + #### Preferences ########################################################## + + # The log levels + level = Trait( + "Info", + { + "Debug": logging.DEBUG, + "Info": logging.INFO, + "Warning": logging.WARNING, + "Error": logging.ERROR, + "Critical": logging.CRITICAL, + }, + is_str=True, + ) + + enable_agent = Bool(False) + smtp_server = Str() + to_address = Str() + from_address = Str() + + # The path to the preferences node that contains the preferences. + preferences_path = Str("apptools.logger")
+
+ +
+
+
+
+
+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/5.0/_modules/apptools/logger/plugin/logger_service.html b/5.0/_modules/apptools/logger/plugin/logger_service.html new file mode 100644 index 000000000..69028d2ce --- /dev/null +++ b/5.0/_modules/apptools/logger/plugin/logger_service.html @@ -0,0 +1,310 @@ + + + + + + + apptools.logger.plugin.logger_service — Apptools Documentation + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +

Source code for apptools.logger.plugin.logger_service

+# (C) Copyright 2005-2020 Enthought, Inc., Austin, TX
+# All rights reserved.
+#
+# This software is provided without warranty under the terms of the BSD
+# license included in LICENSE.txt and may be redistributed only under
+# the conditions described in the aforementioned license. The license
+# is also available online at http://www.enthought.com/licenses/BSD.txt
+#
+# Thanks for using Enthought open source!
+# Standard library imports
+from io import BytesIO
+import logging
+import os
+import zipfile
+
+# Enthought library imports
+from pyface.workbench.api import View as WorkbenchView
+from traits.api import (
+    Any,
+    Callable,
+    HasTraits,
+    Instance,
+    List,
+    Property,
+    Undefined,
+    on_trait_change,
+)
+
+root_logger = logging.getLogger()
+logger = logging.getLogger(__name__)
+
+
+
[docs]class LoggerService(HasTraits): + """The persistent service exposing the Logger plugin's API.""" + + # The Envisage application. + application = Any() + + # The logging Handler we use. + handler = Any() + + # Our associated LoggerPreferences. + preferences = Any() + + # The view we use. + plugin_view = Instance(WorkbenchView) + + # Contributions from other plugins. + mail_files = Property(List(Callable)) + +
[docs] def save_preferences(self): + """Save the preferences.""" + self.preferences.preferences.save()
+ +
[docs] def whole_log_text(self): + """Return all of the logged data as formatted text.""" + lines = [self.handler.format(rec) for rec in self.handler.get()] + # Ensure that we end with a newline. + lines.append("") + text = "\n".join(lines) + return text
+ +
[docs] def create_email_message( + self, + fromaddr, + toaddrs, + ccaddrs, + subject, + priority, + include_userdata=False, + stack_trace="", + comments="", + include_environment=True, + ): + """Format a bug report email from the log files.""" + from email.mime.application import MIMEApplication + from email.mime.multipart import MIMEMultipart + from email.mime.text import MIMEText + + message = MIMEMultipart() + message["Subject"] = "%s [priority=%s]" % (subject, priority) + message["To"] = ", ".join(toaddrs) + message["Cc"] = ", ".join(ccaddrs) + message["From"] = fromaddr + message.preamble = ( + "You will not see this in a MIME-aware mail " "reader.\n" + ) + message.epilogue = " " # To guarantee the message ends with a newline + + # First section is simple ASCII data ... + m = [] + m.append("Bug Report") + m.append("==============================") + m.append("") + + if len(comments) > 0: + m.append("Comments:") + m.append("========") + m.append(comments) + m.append("") + + if len(stack_trace) > 0: + m.append("Stack Trace:") + m.append("===========") + m.append(stack_trace) + m.append("") + + msg = MIMEText("\n".join(m)) + message.attach(msg) + + # Include the log file ... + logtext = self.whole_log_text() + msg = MIMEText(logtext) + msg.add_header( + "Content-Disposition", "attachment", filename="logfile.txt" + ) + message.attach(msg) + + # Include the environment variables ... + # FIXME: ask the user, maybe? + if include_environment: + # Transmit the user's environment settings as well. Main purpose + # is to work out the user name to help with following up on bug + # reports and in future we should probably send less data. + entries = [] + for key, value in sorted(os.environ.items()): + entries.append("%30s : %s\n" % (key, value)) + + msg = MIMEText("".join(entries)) + msg.add_header( + "Content-Disposition", "attachment", filename="environment.txt" + ) + message.attach(msg) + + if include_userdata and len(self.mail_files) != 0: + f = BytesIO() + zf = zipfile.ZipFile(f, "w") + for mf in self.mail_files: + mf(zf) + zf.close() + + msg = MIMEApplication(f.getvalue()) + msg.add_header( + "Content-Disposition", "attachment", filename="userdata.zip" + ) + message.attach(msg) + + return message
+ +
[docs] def send_bug_report( + self, smtp_server, fromaddr, toaddrs, ccaddrs, message + ): + """Send a bug report email.""" + try: + import smtplib + + logger.debug("Connecting to: %s" % smtp_server) + server = smtplib.SMTP(host=smtp_server) + logger.debug("Connected: %s" % server) + # server.set_debuglevel(1) + server.sendmail(fromaddr, toaddrs + ccaddrs, message.as_string()) + server.quit() + except Exception: + logger.exception("Problem sending error report")
+ + #### Traits stuff ######################################################### + + def _get_mail_files(self): + return self.application.get_extensions( + "apptools.logger.plugin.mail_files" + ) + + @on_trait_change("preferences.level_") + def _level_changed(self, new): + if ( + new is not None + and new is not Undefined + and self.handler is not None + ): + root_logger.setLevel(self.preferences.level_) + self.handler.setLevel(self.preferences.level_)
+
+ +
+
+
+
+
+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/5.0/_modules/apptools/logger/plugin/view/logger_preferences_page.html b/5.0/_modules/apptools/logger/plugin/view/logger_preferences_page.html new file mode 100644 index 000000000..a0f07b780 --- /dev/null +++ b/5.0/_modules/apptools/logger/plugin/view/logger_preferences_page.html @@ -0,0 +1,226 @@ + + + + + + + apptools.logger.plugin.view.logger_preferences_page — Apptools Documentation + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +

Source code for apptools.logger.plugin.view.logger_preferences_page

+# (C) Copyright 2005-2020 Enthought, Inc., Austin, TX
+# All rights reserved.
+#
+# This software is provided without warranty under the terms of the BSD
+# license included in LICENSE.txt and may be redistributed only under
+# the conditions described in the aforementioned license. The license
+# is also available online at http://www.enthought.com/licenses/BSD.txt
+#
+# Thanks for using Enthought open source!
+
+import logging
+
+from apptools.preferences.ui.api import PreferencesPage
+from traits.api import Bool, Trait, Str
+from traitsui.api import EnumEditor, Group, Item, View
+
+
+
[docs]class LoggerPreferencesPage(PreferencesPage): + """A preference page for the logger plugin.""" + + #### 'PreferencesPage' interface ########################################## + + # The page's category (e.g. 'General/Appearance'). The empty string means + # that this is a top-level page. + category = "" + + # The page's help identifier (optional). If a help Id *is* provided then + # there will be a 'Help' button shown on the preference page. + help_id = "" + + # The page name (this is what is shown in the preferences dialog. + name = "Logger" + + # The path to the preferences node that contains the preferences. + preferences_path = "apptools.logger" + + #### Preferences ########################################################## + + # The log levels + level = Trait( + "Info", + { + "Debug": logging.DEBUG, + "Info": logging.INFO, + "Warning": logging.WARNING, + "Error": logging.ERROR, + "Critical": logging.CRITICAL, + }, + is_str=True, + ) + + enable_agent = Bool(False) + smtp_server = Str + to_address = Str + from_address = Str + + # The view used to change the plugin preferences + traits_view = View( + Group( + Group( + Item( + name="level", + editor=EnumEditor( + values={ + "Debug": "1:Debug", + "Info": "2:Info", + "Warning": "3:Warning", + "Error": "4:Error", + "Critical": "5:Critical", + }, + ), + style="simple", + ), + label="Logger Settings", + show_border=True, + ), + Group(Item(name="10")), + Group( + Group( + Group( + Item( + name="enable_agent", label="Enable quality agent" + ), + show_left=False, + ), + Group( + Item(name="smtp_server", label="SMTP server"), + Item(name="from_address"), + Item(name="to_address"), + enabled_when="enable_agent==True", + ), + ), + label="Quality Agent Settings", + show_border=True, + ), + ), + )
+
+ +
+
+
+
+
+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/5.0/_modules/apptools/logger/plugin/view/logger_view.html b/5.0/_modules/apptools/logger/plugin/view/logger_view.html new file mode 100644 index 000000000..237263148 --- /dev/null +++ b/5.0/_modules/apptools/logger/plugin/view/logger_view.html @@ -0,0 +1,343 @@ + + + + + + + apptools.logger.plugin.view.logger_view — Apptools Documentation + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +

Source code for apptools.logger.plugin.view.logger_view

+# (C) Copyright 2005-2020 Enthought, Inc., Austin, TX
+# All rights reserved.
+#
+# This software is provided without warranty under the terms of the BSD
+# license included in LICENSE.txt and may be redistributed only under
+# the conditions described in the aforementioned license. The license
+# is also available online at http://www.enthought.com/licenses/BSD.txt
+#
+# Thanks for using Enthought open source!
+
+# Standard library imports
+from datetime import datetime
+import logging
+
+# Enthought library imports.
+from pyface.api import ImageResource, clipboard
+from pyface.workbench.api import TraitsUIView
+from traits.api import (
+    Button,
+    Instance,
+    List,
+    Property,
+    Str,
+    cached_property,
+    on_trait_change,
+)
+from traitsui.api import View, Group, Item, CodeEditor, TabularEditor, spring
+from traitsui.tabular_adapter import TabularAdapter
+
+# Local imports
+from apptools.logger.agent.quality_agent_view import QualityAgentView
+from apptools.logger.plugin.logger_service import LoggerService
+
+# Constants
+_IMAGE_MAP = {
+    logging.DEBUG: ImageResource("debug"),
+    logging.INFO: ImageResource("info"),
+    logging.WARNING: ImageResource("warning"),
+    logging.ERROR: ImageResource("error"),
+    logging.CRITICAL: ImageResource("crit_error"),
+}
+
+
+
[docs]class LogRecordAdapter(TabularAdapter): + """A TabularEditor adapter for logging.LogRecord objects.""" + + columns = [ + ("Level", "level"), + ("Date", "date"), + ("Time", "time"), + ("Message", "message"), + ] + column_widths = [80, 100, 120, -1] + + level_image = Property + level_text = Property(Str) + date_text = Property(Str) + time_text = Property(Str) + message_text = Property(Str) + +
[docs] def get_width(self, object, trait, column): + return self.column_widths[column]
+ + def _get_level_image(self): + return _IMAGE_MAP[self.item.levelno] + + def _get_level_text(self): + return self.item.levelname.capitalize() + + def _get_date_text(self): + dt = datetime.fromtimestamp(self.item.created) + return dt.date().isoformat() + + def _get_time_text(self): + dt = datetime.fromtimestamp(self.item.created) + return dt.time().isoformat() + + def _get_message_text(self): + # Just display the first line of multiline messages, like stacktraces. + msg = self.item.getMessage() + msgs = msg.strip().split("\n") + if len(msgs) > 1: + suffix = "... [double click for details]" + else: + suffix = "" + abbrev_msg = msgs[0] + suffix + return abbrev_msg
+ + +
[docs]class LoggerView(TraitsUIView): + """The Workbench View showing the list of log items.""" + + id = Str("apptools.logger.plugin.view.logger_view.LoggerView") + name = Str("Logger") + service = Instance(LoggerService) + + log_records = List(Instance(logging.LogRecord)) + formatted_records = Property(Str, depends_on="log_records") + + activated = Instance(logging.LogRecord) + activated_text = Property(Str, depends_on="activated") + reset_button = Button("Reset Logs") + show_button = Button("Complete Text Log") + copy_button = Button("Copy Log to Clipboard") + + code_editor = CodeEditor(lexer="null", show_line_numbers=False) + log_records_editor = TabularEditor( + adapter=LogRecordAdapter(), editable=False, activated="activated" + ) + trait_view = View( + Group( + Item("log_records", editor=log_records_editor), + Group( + Item("reset_button"), + spring, + Item("show_button"), + Item("copy_button"), + orientation="horizontal", + show_labels=False, + ), + show_labels=False, + ) + ) + + ########################################################################### + # LogQueueHandler view interface + ########################################################################### + +
[docs] def update(self, force=False): + """Update 'log_records' if our handler has new records or 'force' is + set. + """ + service = self.service + if service.handler.has_new_records() or force: + log_records = [ + rec + for rec in service.handler.get() + if rec.levelno >= service.preferences.level_ + ] + log_records.reverse() + self.log_records = log_records
+ + ########################################################################### + # Private interface + ########################################################################### + + @on_trait_change("service.preferences.level_") + def _update_log_records(self): + self.service.handler._view = self + self.update(force=True) + + def _reset_button_fired(self): + self.service.handler.reset() + self.log_records = [] + + def _show_button_fired(self): + self.edit_traits( + view=View( + Item( + "formatted_records", + editor=self.code_editor, + style="readonly", + show_label=False, + ), + width=800, + height=600, + resizable=True, + buttons=["OK"], + title="Complete Text Log", + ) + ) + + def _copy_button_fired(self): + clipboard.text_data = self.formatted_records + + @cached_property + def _get_formatted_records(self): + return "\n".join( + [ + self.service.handler.formatter.format(record) + for record in self.log_records + ] + ) + + def _activated_changed(self): + if self.activated is None: + return + msg = self.activated.getMessage() + if self.service.preferences.enable_agent: + dialog = QualityAgentView(msg=msg, service=self.service) + dialog.open() + else: + self.edit_traits( + view=View( + Item( + "activated_text", + editor=self.code_editor, + style="readonly", + show_label=False, + ), + width=800, + height=600, + resizable=True, + buttons=["OK"], + title="Log Message Detail", + ) + ) + + @cached_property + def _get_activated_text(self): + if self.activated is None: + return "" + else: + return self.activated.getMessage()
+
+ +
+
+
+
+
+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/5.0/_modules/apptools/logger/ring_buffer.html b/5.0/_modules/apptools/logger/ring_buffer.html new file mode 100644 index 000000000..bbfb99f9f --- /dev/null +++ b/5.0/_modules/apptools/logger/ring_buffer.html @@ -0,0 +1,183 @@ + + + + + + + apptools.logger.ring_buffer — Apptools Documentation + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +

Source code for apptools.logger.ring_buffer

+# (C) Copyright 2005-2020 Enthought, Inc., Austin, TX
+# All rights reserved.
+#
+# This software is provided without warranty under the terms of the BSD
+# license included in LICENSE.txt and may be redistributed only under
+# the conditions described in the aforementioned license. The license
+# is also available online at http://www.enthought.com/licenses/BSD.txt
+#
+# Thanks for using Enthought open source!
+"""
+Copied from Python Cookbook.
+
+"""
+
+
+
[docs]class RingBuffer: + def __init__(self, size_max): + self.max = size_max + self.data = [] + +
[docs] def append(self, x): + """append an element at the end of the buffer""" + self.data.append(x) + if len(self.data) == self.max: + self.cur = 0 + self.__class__ = RingBufferFull
+ +
[docs] def get(self): + """ return a list of elements from the oldest to the newest""" + return self.data
+ + +
[docs]class RingBufferFull: + def __init__(self, n): + raise Exception("you should use RingBuffer") + +
[docs] def append(self, x): + self.data[self.cur] = x + self.cur = (self.cur + 1) % self.max
+ +
[docs] def get(self): + return self.data[self.cur:] + self.data[: self.cur]
+ + +# sample of use +"""x=RingBuffer(5) +x.append(1); x.append(2); x.append(3); x.append(4) +print(x.__class__,x.get()) +x.append(5) +print(x.__class__,x.get()) +x.append(6) +print(x.data,x.get()) +x.append(7); x.append(8); x.append(9); x.append(10) +print(x.data,x.get())""" +
+ +
+
+
+
+
+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/5.0/_modules/apptools/naming/address.html b/5.0/_modules/apptools/naming/address.html new file mode 100644 index 000000000..c0bb64dc7 --- /dev/null +++ b/5.0/_modules/apptools/naming/address.html @@ -0,0 +1,158 @@ + + + + + + + apptools.naming.address — Apptools Documentation + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +

Source code for apptools.naming.address

+# (C) Copyright 2005-2020 Enthought, Inc., Austin, TX
+# All rights reserved.
+#
+# This software is provided without warranty under the terms of the BSD
+# license included in LICENSE.txt and may be redistributed only under
+# the conditions described in the aforementioned license. The license
+# is also available online at http://www.enthought.com/licenses/BSD.txt
+#
+# Thanks for using Enthought open source!
+""" The address of a commuications endpoint. """
+
+
+# Enthought library imports.
+from traits.api import Any, HasTraits, Str
+
+
+
[docs]class Address(HasTraits): + """The address of a communications end-point. + + It contains a type that describes the communication mechanism, and the + actual address content. + + """ + + # The type of the address. + type = Str + + # The actual content. + content = Any
+
+ +
+
+
+
+
+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/5.0/_modules/apptools/naming/binding.html b/5.0/_modules/apptools/naming/binding.html new file mode 100644 index 000000000..396897ce3 --- /dev/null +++ b/5.0/_modules/apptools/naming/binding.html @@ -0,0 +1,233 @@ + + + + + + + apptools.naming.binding — Apptools Documentation + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +

Source code for apptools.naming.binding

+# (C) Copyright 2005-2020 Enthought, Inc., Austin, TX
+# All rights reserved.
+#
+# This software is provided without warranty under the terms of the BSD
+# license included in LICENSE.txt and may be redistributed only under
+# the conditions described in the aforementioned license. The license
+# is also available online at http://www.enthought.com/licenses/BSD.txt
+#
+# Thanks for using Enthought open source!
+""" The representation of a name-to-object binding in a context. """
+
+
+# Enthought libary imports.
+from traits.api import Any, HasTraits, Property, Str
+
+
+
[docs]class Binding(HasTraits): + """ The representation of a name-to-object binding in a context. """ + + #### 'Binding' interface ################################################## + + # The class name of the object bound to the name in the binding. + class_name = Property(Str) + + # The name. + name = Str + + # The object bound to the name in the binding. + obj = Any + + #### Experimental 'Binding' interface ##################################### + + # fixme: These is not part of the JNDI spec, but they do seem startlingly + # useful! + # + # fixme: And, errr, startlingly broken! If the context that the binding + # is in is required then just look up the name minus the last component! + # + # The context that the binding came from. + context = Any + + # The name of the bound object within the namespace. + namespace_name = Property(Str) + + #### 'Private' interface ################################################## + + # Shadow trait for the 'class_name' property. + _class_name = Str + + ########################################################################### + # 'object' interface. + ########################################################################### + + def __str__(self): + """ Returns an informal string representation of the object. """ + + return super(Binding, self).__str__() + "(name=%s, obj=%s)" % ( + self.name, + self.obj, + ) + + ########################################################################### + # 'Binding' interface. + ########################################################################### + + #### Properties ########################################################### + + # class_name + def _get_class_name(self): + """ Returns the class name of the object. """ + + if len(self._class_name) == 0: + if self.obj is None: + class_name = None + + else: + klass = self.obj.__class__ + + class_name = "%s.%s" % (klass.__module__, klass.__name__) + + return class_name + + def _set_class_name(self, class_name): + """ Sets the class name of the object. """ + + self._class_name = class_name + + # namespace_name + def _get_namespace_name(self): + """ Returns the name of the context within its own namespace. """ + + if self.context is not None: + base = self.context.namespace_name + + else: + base = "" + + if len(base) > 0: + namespace_name = base + "/" + self.name + + else: + namespace_name = self.name + + return namespace_name
+
+ +
+
+
+
+
+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/5.0/_modules/apptools/naming/context.html b/5.0/_modules/apptools/naming/context.html new file mode 100644 index 000000000..d87dae45b --- /dev/null +++ b/5.0/_modules/apptools/naming/context.html @@ -0,0 +1,813 @@ + + + + + + + apptools.naming.context — Apptools Documentation + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +

Source code for apptools.naming.context

+# (C) Copyright 2005-2020 Enthought, Inc., Austin, TX
+# All rights reserved.
+#
+# This software is provided without warranty under the terms of the BSD
+# license included in LICENSE.txt and may be redistributed only under
+# the conditions described in the aforementioned license. The license
+# is also available online at http://www.enthought.com/licenses/BSD.txt
+#
+# Thanks for using Enthought open source!
+""" The base class for all naming contexts. """
+
+
+# Enthought library imports.
+from traits.api import Any, Dict, Event, HasTraits
+from traits.api import Property, Str
+
+# Local imports.
+from .binding import Binding
+from .exception import InvalidNameError, NameAlreadyBoundError
+from .exception import NameNotFoundError, NotContextError
+from .naming_event import NamingEvent
+from .naming_manager import naming_manager
+from .unique_name import make_unique_name
+
+
+# Constants for environment property keys.
+INITIAL_CONTEXT_FACTORY = "apptools.naming.factory.initial"
+OBJECT_FACTORIES = "apptools.naming.factory.object"
+STATE_FACTORIES = "apptools.naming.factory.state"
+
+
+# The default environment.
+ENVIRONMENT = {
+    # 'Context' properties.
+    OBJECT_FACTORIES: [],
+    STATE_FACTORIES: [],
+}
+
+
+
[docs]class Context(HasTraits): + """ The base class for all naming contexts. """ + + # Keys for environment properties. + INITIAL_CONTEXT_FACTORY = INITIAL_CONTEXT_FACTORY + OBJECT_FACTORIES = OBJECT_FACTORIES + STATE_FACTORIES = STATE_FACTORIES + + #### 'Context' interface ################################################## + + # The naming environment in effect for this context. + environment = Dict(ENVIRONMENT) + + # The name of the context within its own namespace. + namespace_name = Property(Str) + + #### Events #### + + # Fired when an object has been added to the context (either via 'bind' or + # 'create_subcontext'). + object_added = Event(NamingEvent) + + # Fired when an object has been changed (via 'rebind'). + object_changed = Event(NamingEvent) + + # Fired when an object has been removed from the context (either via + # 'unbind' or 'destroy_subcontext'). + object_removed = Event(NamingEvent) + + # Fired when an object in the context has been renamed (via 'rename'). + object_renamed = Event(NamingEvent) + + # Fired when the contents of the context have changed dramatically. + context_changed = Event(NamingEvent) + + #### Protected 'Context' interface ####################################### + + # The bindings in the context. + _bindings = Dict(Str, Any) + + ########################################################################### + # 'Context' interface. + ########################################################################### + + #### Properties ########################################################### + + def _get_namespace_name(self): + """ + Return the name of the context within its own namespace. + + That is the full-path, through the namespace this context participates + in, to get to this context. For example, if the root context of the + namespace was called 'Foo', and there was a subcontext of that called + 'Bar', and we were within that and called 'Baz', then this should + return 'Foo/Bar/Baz'. + + """ + + # FIXME: We'd like to raise an exception and force implementors to + # decide what to do. However, it appears to be pretty common that + # most Context implementations do not override this method -- possibly + # because the comments aren't clear on what this is supposed to be? + # + # Anyway, if we raise an exception then it is impossible to use any + # evaluations when building a Traits UI for a Context. That is, the + # Traits UI can't include items that have a 'visible_when' or + # 'enabled_when' evaluation. This is because the Traits evaluation + # code calls the 'get()' method on the Context which attempts to + # retrieve the current namespace_name value. + # raise OperationNotSupportedError() + return "" + + #### Methods ############################################################## + +
[docs] def bind(self, name, obj, make_contexts=False): + """Binds a name to an object. + + If 'make_contexts' is True then any missing intermediate contexts are + created automatically. + + """ + + if len(name) == 0: + raise InvalidNameError("empty name") + + # Parse the name. + components = self._parse_name(name) + + # If there is exactly one component in the name then the operation + # takes place in this context. + if len(components) == 1: + atom = components[0] + + # Is the name already bound? + if self._is_bound(atom): + raise NameAlreadyBoundError(name) + + # Do the actual bind. + self._bind(atom, obj) + + # Trait event notification. + self.object_added = NamingEvent( + new_binding=Binding(name=name, obj=obj, context=self) + ) + + # Otherwise, attempt to continue resolution into the next context. + else: + if not self._is_bound(components[0]): + if make_contexts: + self._create_subcontext(components[0]) + + else: + raise NameNotFoundError(components[0]) + + next_context = self._get_next_context(components[0]) + next_context.bind("/".join(components[1:]), obj, make_contexts)
+ +
[docs] def rebind(self, name, obj, make_contexts=False): + """Binds an object to a name that may already be bound. + + If 'make_contexts' is True then any missing intermediate contexts are + created automatically. + + The object may be a different object but may also be the same object + that is already bound to the specified name. The name may or may not be + already used. Think of this as a safer version of 'bind' since this + one will never raise an exception regarding a name being used. + + """ + + if len(name) == 0: + raise InvalidNameError("empty name") + + # Parse the name. + components = self._parse_name(name) + + # If there is exactly one component in the name then the operation + # takes place in this context. + if len(components) == 1: + # Do the actual rebind. + self._rebind(components[0], obj) + + # Trait event notification. + self.object_changed = NamingEvent( + new_binding=Binding(name=name, obj=obj, context=self) + ) + + # Otherwise, attempt to continue resolution into the next context. + else: + if not self._is_bound(components[0]): + if make_contexts: + self._create_subcontext(components[0]) + + else: + raise NameNotFoundError(components[0]) + + next_context = self._get_next_context(components[0]) + next_context.rebind("/".join(components[1:]), obj, make_contexts)
+ +
[docs] def unbind(self, name): + """ Unbinds a name. """ + + if len(name) == 0: + raise InvalidNameError("empty name") + + # Parse the name. + components = self._parse_name(name) + + # If there is exactly one component in the name then the operation + # takes place in this context. + if len(components) == 1: + atom = components[0] + + if not self._is_bound(atom): + raise NameNotFoundError(name) + + # Lookup the object that we are unbinding to use in the event + # notification. + obj = self._lookup(atom) + + # Do the actual unbind. + self._unbind(atom) + + # Trait event notification. + self.object_removed = NamingEvent( + old_binding=Binding(name=name, obj=obj, context=self) + ) + + # Otherwise, attempt to continue resolution into the next context. + else: + if not self._is_bound(components[0]): + raise NameNotFoundError(components[0]) + + next_context = self._get_next_context(components[0]) + next_context.unbind("/".join(components[1:]))
+ +
[docs] def rename(self, old_name, new_name): + """ Binds a new name to an object. """ + + if len(old_name) == 0 or len(new_name) == 0: + raise InvalidNameError("empty name") + + # Parse the names. + old_components = self._parse_name(old_name) + new_components = self._parse_name(new_name) + + # If there is axactly one component in BOTH names then the operation + # takes place ENTIRELY in this context. + if len(old_components) == 1 and len(new_components) == 1: + # Is the old name actually bound? + if not self._is_bound(old_name): + raise NameNotFoundError(old_name) + + # Is the new name already bound? + if self._is_bound(new_name): + raise NameAlreadyBoundError(new_name) + + # Do the actual rename. + self._rename(old_name, new_name) + + # Lookup the object that we are renaming to use in the event + # notification. + obj = self._lookup(new_name) + + # Trait event notification. + self.object_renamed = NamingEvent( + old_binding=Binding(name=old_name, obj=obj, context=self), + new_binding=Binding(name=new_name, obj=obj, context=self), + ) + + else: + # fixme: This really needs to be transactional in case the bind + # succeeds but the unbind fails. To be safe should we just not + # support cross-context renaming for now?!?! + # + # Lookup the object. + obj = self.lookup(old_name) + + # Bind the new name. + self.bind(new_name, obj) + + # Unbind the old one. + self.unbind(old_name)
+ +
[docs] def lookup(self, name): + """ Resolves a name relative to this context. """ + + # If the name is empty we return the context itself. + if len(name) == 0: + # fixme: The JNDI spec. says that this should return a COPY of + # the context. + return self + + # Parse the name. + components = self._parse_name(name) + + # If there is exactly one component in the name then the operation + # takes place in this context. + if len(components) == 1: + atom = components[0] + + if not self._is_bound(atom): + raise NameNotFoundError(name) + + # Do the actual lookup. + obj = self._lookup(atom) + + # Otherwise, attempt to continue resolution into the next context. + else: + if not self._is_bound(components[0]): + raise NameNotFoundError(components[0]) + + next_context = self._get_next_context(components[0]) + obj = next_context.lookup("/".join(components[1:])) + + return obj
+ + # fixme: Non-JNDI +
[docs] def lookup_binding(self, name): + """ Looks up the binding for a name relative to this context. """ + + if len(name) == 0: + raise InvalidNameError("empty name") + + # Parse the name. + components = self._parse_name(name) + + # If there is exactly one component in the name then the operation + # takes place in this context. + if len(components) == 1: + atom = components[0] + + if not self._is_bound(atom): + raise NameNotFoundError(name) + + # Do the actual lookup. + binding = self._lookup_binding(atom) + + # Otherwise, attempt to continue resolution into the next context. + else: + if not self._is_bound(components[0]): + raise NameNotFoundError(components[0]) + + next_context = self._get_next_context(components[0]) + binding = next_context.lookup_binding("/".join(components[1:])) + + return binding
+ + # fixme: Non-JNDI +
[docs] def lookup_context(self, name): + """Resolves a name relative to this context. + + The name MUST resolve to a context. + + """ + + # If the name is empty we return the context itself. + if len(name) == 0: + # fixme: The JNDI spec. says that this should return a COPY of + # the context. + return self + + # Parse the name. + components = self._parse_name(name) + + # If there is exactly one component in the name then the operation + # takes place in this context. + if len(components) == 1: + atom = components[0] + + if not self._is_bound(atom): + raise NameNotFoundError(name) + + # Do the actual lookup. + obj = self._get_next_context(atom) + + # Otherwise, attempt to continue resolution into the next context. + else: + if not self._is_bound(components[0]): + raise NameNotFoundError(components[0]) + + next_context = self._get_next_context(components[0]) + obj = next_context.lookup("/".join(components[1:])) + + return obj
+ +
[docs] def create_subcontext(self, name): + """ Creates a sub-context. """ + + if len(name) == 0: + raise InvalidNameError("empty name") + + # Parse the name. + components = self._parse_name(name) + + # If there is exactly one component in the name then the operation + # takes place in this context. + if len(components) == 1: + atom = components[0] + + # Is the name already bound? + if self._is_bound(atom): + raise NameAlreadyBoundError(name) + + # Do the actual creation of the sub-context. + sub = self._create_subcontext(atom) + + # Trait event notification. + self.object_added = NamingEvent( + new_binding=Binding(name=name, obj=sub, context=self) + ) + + # Otherwise, attempt to continue resolution into the next context. + else: + if not self._is_bound(components[0]): + raise NameNotFoundError(components[0]) + + next_context = self._get_next_context(components[0]) + sub = next_context.create_subcontext("/".join(components[1:])) + + return sub
+ +
[docs] def destroy_subcontext(self, name): + """ Destroys a sub-context. """ + + if len(name) == 0: + raise InvalidNameError("empty name") + + # Parse the name. + components = self._parse_name(name) + + # If there is exactly one component in the name then the operation + # takes place in this context. + if len(components) == 1: + atom = components[0] + + if not self._is_bound(atom): + raise NameNotFoundError(name) + + obj = self._lookup(atom) + if not self._is_context(atom): + raise NotContextError(name) + + # Do the actual destruction of the sub-context. + self._destroy_subcontext(atom) + + # Trait event notification. + self.object_removed = NamingEvent( + old_binding=Binding(name=name, obj=obj, context=self) + ) + + # Otherwise, attempt to continue resolution into the next context. + else: + if not self._is_bound(components[0]): + raise NameNotFoundError(components[0]) + + next_context = self._get_next_context(components[0]) + next_context.destroy_subcontext("/".join(components[1:]))
+ + # fixme: Non-JNDI +
[docs] def get_unique_name(self, prefix): + """Returns a name that is unique within the context. + + The name returned will start with the specified prefix. + + """ + + return make_unique_name( + prefix, existing=self.list_names(""), format="%s (%d)" + )
+ +
[docs] def list_names(self, name=""): + """ Lists the names bound in a context. """ + + # If the name is empty then the operation takes place in this context. + if len(name) == 0: + names = self._list_names() + + # Otherwise, attempt to continue resolution into the next context. + else: + # Parse the name. + components = self._parse_name(name) + + if not self._is_bound(components[0]): + raise NameNotFoundError(components[0]) + + next_context = self._get_next_context(components[0]) + names = next_context.list_names("/".join(components[1:])) + + return names
+ +
[docs] def list_bindings(self, name=""): + """ Lists the bindings in a context. """ + + # If the name is empty then the operation takes place in this context. + if len(name) == 0: + bindings = self._list_bindings() + + # Otherwise, attempt to continue resolution into the next context. + else: + # Parse the name. + components = self._parse_name(name) + + if not self._is_bound(components[0]): + raise NameNotFoundError(components[0]) + + next_context = self._get_next_context(components[0]) + bindings = next_context.list_bindings("/".join(components[1:])) + + return bindings
+ + # fixme: Non-JNDI +
[docs] def is_context(self, name): + """ Returns True if the name is bound to a context. """ + + # If the name is empty then it refers to this context. + if len(name) == 0: + is_context = True + + else: + # Parse the name. + components = self._parse_name(name) + + # If there is exactly one component in the name then the operation + # takes place in this context. + if len(components) == 1: + atom = components[0] + + if not self._is_bound(atom): + raise NameNotFoundError(name) + + # Do the actual check. + is_context = self._is_context(atom) + + # Otherwise, attempt to continue resolution into the next context. + else: + if not self._is_bound(components[0]): + raise NameNotFoundError(components[0]) + + next_context = self._get_next_context(components[0]) + is_context = next_context.is_context("/".join(components[1:])) + + return is_context
+ + # fixme: Non-JNDI +
[docs] def search(self, obj): + """ Returns a list of namespace names that are bound to obj. """ + + # don't look for None + if obj is None: + return [] + + # Obj is bound to these names relative to this context + names = [] + + # path contain the name components down to the current context + path = [] + + self._search(obj, names, path, {}) + + return names
+ + ########################################################################### + # Protected 'Context' interface. + ########################################################################### + + def _parse_name(self, name): + """Parse a name into a list of components. + + e.g. 'foo/bar/baz' -> ['foo', 'bar', 'baz'] + + """ + + return name.split("/") + + def _is_bound(self, name): + """ Is a name bound in this context? """ + + return name in self._bindings + + def _lookup(self, name): + """ Looks up a name in this context. """ + + obj = self._bindings[name] + + return naming_manager.get_object_instance(obj, name, self) + + def _lookup_binding(self, name): + """ Looks up the binding for a name in this context. """ + + return Binding(name=name, obj=self._lookup(name), context=self) + + def _bind(self, name, obj): + """ Binds a name to an object in this context. """ + + state = naming_manager.get_state_to_bind(obj, name, self) + self._bindings[name] = state + + def _rebind(self, name, obj): + """ Rebinds a name to an object in this context. """ + + self._bind(name, obj) + + def _unbind(self, name): + """ Unbinds a name from this context. """ + + del self._bindings[name] + + def _rename(self, old_name, new_name): + """ Renames an object in this context. """ + + # Bind the new name. + self._bindings[new_name] = self._bindings[old_name] + + # Unbind the old one. + del self._bindings[old_name] + + def _create_subcontext(self, name): + """ Creates a sub-context of this context. """ + + sub = self.__class__(environment=self.environment) + self._bindings[name] = sub + + return sub + + def _destroy_subcontext(self, name): + """ Destroys a sub-context of this context. """ + + del self._bindings[name] + + def _list_bindings(self): + """ Lists the bindings in this context. """ + + bindings = [] + for name in self._list_names(): + bindings.append( + Binding(name=name, obj=self._lookup(name), context=self) + ) + + return bindings + + def _list_names(self): + """ Lists the names bound in this context. """ + + return list(self._bindings.keys()) + + def _is_context(self, name): + """ Returns True if a name is bound to a context. """ + + return self._get_next_context(name) is not None + + def _get_next_context(self, name): + """ Returns the next context. """ + + obj = self._lookup(name) + + # If the object is a context then everything is just dandy. + if isinstance(obj, Context): + next_context = obj + else: + raise NotContextError(name) + + return next_context + + def _search(self, obj, names, path, searched): + """Append to names any name bound to obj. + Join path and name with '/' to for a complete name from the + top context. + """ + + # Check the bindings recursively. + for binding in self.list_bindings(): + if binding.obj is obj: + path.append(binding.name) + names.append("/".join(path)) + path.pop() + + if ( + isinstance(binding.obj, Context) + and binding.obj not in searched + ): + path.append(binding.name) + searched[binding.obj] = True + binding.obj._search(obj, names, path, searched) + path.pop()
+
+ +
+
+
+
+
+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/5.0/_modules/apptools/naming/dir_context.html b/5.0/_modules/apptools/naming/dir_context.html new file mode 100644 index 000000000..edc6864a6 --- /dev/null +++ b/5.0/_modules/apptools/naming/dir_context.html @@ -0,0 +1,293 @@ + + + + + + + apptools.naming.dir_context — Apptools Documentation + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +

Source code for apptools.naming.dir_context

+# (C) Copyright 2005-2020 Enthought, Inc., Austin, TX
+# All rights reserved.
+#
+# This software is provided without warranty under the terms of the BSD
+# license included in LICENSE.txt and may be redistributed only under
+# the conditions described in the aforementioned license. The license
+# is also available online at http://www.enthought.com/licenses/BSD.txt
+#
+# Thanks for using Enthought open source!
+""" The base class for all directory contexts. """
+
+
+# Enthought library imports.
+from traits.api import Dict
+
+# Local imports.
+from .context import Context
+from .exception import NameNotFoundError
+
+
+
[docs]class DirContext(Context): + """ The base class for all directory contexts. """ + + # The attributes of every object in the context. The attributes for the + # context itself have the empty string as the key. + # + # {str name : dict attributes} + _attributes = Dict + + ########################################################################### + # 'DirContext' interface. + ########################################################################### + +
[docs] def get_attributes(self, name): + """ Returns the attributes associated with a named object. """ + + # If the name is empty then we return the attributes of this context. + if len(name) == 0: + attributes = self._get_attributes(name) + + else: + # Parse the name. + components = self._parse_name(name) + + # If there is exactly one component in the name then the operation + # takes place in this context. + if len(components) == 1: + atom = components[0] + + if not self._is_bound(atom): + raise NameNotFoundError(name) + + # Do the actual get. + attributes = self._get_attributes(atom) + + # Otherwise, attempt to continue resolution into the next context. + else: + if not self._is_bound(components[0]): + raise NameNotFoundError(components[0]) + + next_context = self._get_next_context(components[0]) + attributes = next_context.get_attributes( + "/".join(components[1:]) + ) + + return attributes
+ +
[docs] def set_attributes(self, name, attributes): + """ Sets the attributes associated with a named object. """ + + # If the name is empty then we set the attributes of this context. + if len(name) == 0: + attributes = self._set_attributes(name, attributes) + + else: + # Parse the name. + components = self._parse_name(name) + + # If there is exactly one component in the name then the operation + # takes place in this context. + if len(components) == 1: + atom = components[0] + + if not self._is_bound(atom): + raise NameNotFoundError(name) + + # Do the actual set. + self._set_attributes(atom, attributes) + + # Otherwise, attempt to continue resolution into the next context. + else: + if not self._is_bound(components[0]): + raise NameNotFoundError(components[0]) + + next_context = self._get_next_context(components[0]) + next_context.set_attributes( + "/".join(components[1:]), attributes + )
+ + # fixme: Non-JNDI +
[docs] def find_bindings(self, visitor): + """Find bindings with attributes matching criteria in visitor. + + Visitor is a function that is passed the bindings for each level of the + heirarchy and the attribute dictionary for those bindings. The visitor + examines the bindings and dictionary and returns the bindings it is + interested in. + + """ + + bindings = visitor(self.list_bindings(), self._attributes) + + # recursively check other sub contexts. + for binding in self.list_bindings(): + obj = binding.obj + if isinstance(obj, DirContext): + bindings.extend(obj.find_bindings(visitor)) + + return bindings
+ + ########################################################################### + # Protected 'DirContext' interface. + ########################################################################### + + def _get_attributes(self, name): + """ Returns the attributes of an object in this context. """ + + attributes = self._attributes.setdefault(name, {}) + + return attributes.copy() + + def _set_attributes(self, name, attributes): + """ Sets the attributes of an object in this context. """ + + self._attributes[name] = attributes + + ########################################################################### + # Protected 'Context' interface. + ########################################################################### + + def _unbind(self, name): + """ Unbinds a name from this context. """ + + super(DirContext, self)._unbind(name) + + if name in self._attributes: + del self._attributes[name] + + def _rename(self, old_name, new_name): + """ Renames an object in this context. """ + + super(DirContext, self)._rename(old_name, new_name) + + if old_name in self._attributes: + self._attributes[new_name] = self._attributes[old_name] + del self._attributes[old_name] + + def _destroy_subcontext(self, name): + """ Destroys a sub-context of this context. """ + + super(DirContext, self)._destroy_subcontext(name) + + if name in self._attributes: + del self._attributes[name]
+
+ +
+
+
+
+
+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/5.0/_modules/apptools/naming/dynamic_context.html b/5.0/_modules/apptools/naming/dynamic_context.html new file mode 100644 index 000000000..5b69be61c --- /dev/null +++ b/5.0/_modules/apptools/naming/dynamic_context.html @@ -0,0 +1,308 @@ + + + + + + + apptools.naming.dynamic_context — Apptools Documentation + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +

Source code for apptools.naming.dynamic_context

+# (C) Copyright 2005-2020 Enthought, Inc., Austin, TX
+# All rights reserved.
+#
+# This software is provided without warranty under the terms of the BSD
+# license included in LICENSE.txt and may be redistributed only under
+# the conditions described in the aforementioned license. The license
+# is also available online at http://www.enthought.com/licenses/BSD.txt
+#
+# Thanks for using Enthought open source!
+
+""" Provider of a framework that dynamically determines the contents of a
+    context at the time of interaction with the contents rather than at the
+    time a class is written.
+
+    This capability is particularly useful when the object acting as a context
+    is part of a plug-in application -- such as Envisage.  In general, this
+    capability allows the context to be:
+
+    - Extendable by contributions from somewhere other than the original
+      code writer
+    - Dynamic in that the elements it is composed of can change each time
+      someone interacts with the contents of the context.
+
+    It should be noted that this capability is explicitly different from
+    contexts that look at another container to determine their contents, such
+    as a file system context!
+
+    Users of this framework contribute items to a dynamic context by adding
+    traits to the dynamic context instance.  (This addition can happen
+    statically through the use of a Traits Category.)  The trait value is the
+    context item's value and the trait definition's metadata determines how the
+    item is treated within the context.  The support metadata is:
+
+    context_name: A non-empty string
+        Represents the name of the item within this context.  This must be
+        present for the trait to show up as a context item though the value
+        may change over time as the item gets bound to different names.
+    context_order: A float value
+        Indicates the position for the item within this context.  All
+        dynamically contributed context items are sorted by ascending order
+        of this value using the standard list sort function.
+    is_context: A boolean value
+        True if the item is itself a context.
+"""
+
+# Standardlibrary imports
+import logging
+
+# Local imports
+from .binding import Binding
+from .context import Context
+from .exception import OperationNotSupportedError
+
+
+# Setup a logger for this module.
+logger = logging.getLogger(__name__)
+
+
+
[docs]class DynamicContext(Context): + """A framework that dynamically determines the contents of a context at + the time of interaction with the contents rather than at the time a + context class is written. + + It should be noted that this capability is explicitly different from + contexts that look at another container to determine their contents, + such as a file system context! + """ + + ########################################################################## + # 'Context' interface. + ########################################################################## + + ### protected interface ################################################## + + def _is_bound(self, name): + """Is a name bound in this context?""" + + item = self._get_contributed_context_item(name) + result = item != (None, None) + + return result + + def _is_context(self, name): + """Returns True if a name is bound to a context.""" + item = self._get_contributed_context_item(name) + if item != (None, None): + obj, trait = item + result = trait.is_context is True + else: + result = False + + return result + + def _list_bindings(self): + """Lists the bindings in this context.""" + result = [ + Binding(name=n, obj=o, context=self) + for n, o, t in self._get_contributed_context_items() + ] + + return result + + def _list_names(self): + """Lists the names bound in this context.""" + result = [n for n, o, t in self._get_contributed_context_items()] + + return result + + def _lookup(self, name): + """Looks up a name in this context.""" + item = self._get_contributed_context_item(name) + if item != (None, None): + obj, trait = item + result = obj + else: + result = None + + return result + + def _rename(self, old_name, new_name): + """Renames an object in this context.""" + + item = self._get_contributed_context_item(old_name) + if item != (None, None): + obj, trait = item + trait.context_name = new_name + else: + raise ValueError('Name "%s" not in context', old_name) + + def _unbind(self, name): + """Unbinds a name from this context.""" + # It is an error to try to unbind any contributed context items + item = self._get_contributed_context_item(name) + if item != (None, None): + raise OperationNotSupportedError( + "Unable to unbind " + "built-in with name [%s]" % name + ) + + ########################################################################## + # 'DynamicContext' interface. + ########################################################################## + + ### protected interface ################################################## + + def _get_contributed_context_item(self, name): + """If the specified name matches a contributed context item then + returns a tuple of the item's current value and trait definition + (in that order.) Otherwise, returns a tuple of (None, None). + """ + result = (None, None) + + for n, o, t in self._get_contributed_context_items(): + if n == name: + result = (o, t) + + return result + + def _get_contributed_context_items(self): + """Returns an ordered list of items to be treated as part of our + context. + + Each item in the list is a tuple of its name, object, and trait + definition (in that order.) + """ + # Our traits that get treated as context items are those that declare + # themselves via metadata on the trait definition. + filter = {"context_name": lambda v: v is not None and len(v) > 0} + traits = self.traits(**filter) + + # Sort the list of context items according to the name of the item. + traits = [(t.context_order, n, t) for n, t in traits.items()] + traits.sort() + + # Convert these trait definitions into a list of name and object tuples + result = [ + (t.context_name, getattr(self, n), t) for order, n, t in traits + ] + + return result
+
+ +
+
+
+
+
+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/5.0/_modules/apptools/naming/exception.html b/5.0/_modules/apptools/naming/exception.html new file mode 100644 index 000000000..8c73dc462 --- /dev/null +++ b/5.0/_modules/apptools/naming/exception.html @@ -0,0 +1,184 @@ + + + + + + + apptools.naming.exception — Apptools Documentation + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +

Source code for apptools.naming.exception

+# (C) Copyright 2005-2020 Enthought, Inc., Austin, TX
+# All rights reserved.
+#
+# This software is provided without warranty under the terms of the BSD
+# license included in LICENSE.txt and may be redistributed only under
+# the conditions described in the aforementioned license. The license
+# is also available online at http://www.enthought.com/licenses/BSD.txt
+#
+# Thanks for using Enthought open source!
+""" Naming exceptions. """
+
+
+
[docs]class NamingError(Exception): + """Base class for all naming exceptions."""
+ + +
[docs]class InvalidNameError(NamingError): + """Invalid name. + + This exception is thrown when the name passed to a naming operation does + not conform to the syntax of the naming system (or is empty etc). + + """
+ + +
[docs]class NameAlreadyBoundError(NamingError): + """Name already bound. + + This exception is thrown when an attempt is made to bind a name that is + already bound in the current context. + + """
+ + +
[docs]class NameNotFoundError(NamingError): + """Name not found. + + This exception is thrown when a component of a name cannot be resolved + because it is not bound in the current context. + + """
+ + +
[docs]class NotContextError(NamingError): + """Not a context. + + This exception is thrown when a naming operation has reached a point where + a context is required to continue the operation, but the resolved object + is not a context. + + """
+ + +
[docs]class OperationNotSupportedError(NamingError): + """The context does support the requested operation."""
+
+ +
+
+
+
+
+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/5.0/_modules/apptools/naming/initial_context.html b/5.0/_modules/apptools/naming/initial_context.html new file mode 100644 index 000000000..d26ad66b5 --- /dev/null +++ b/5.0/_modules/apptools/naming/initial_context.html @@ -0,0 +1,185 @@ + + + + + + + apptools.naming.initial_context — Apptools Documentation + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +

Source code for apptools.naming.initial_context

+# (C) Copyright 2005-2020 Enthought, Inc., Austin, TX
+# All rights reserved.
+#
+# This software is provided without warranty under the terms of the BSD
+# license included in LICENSE.txt and may be redistributed only under
+# the conditions described in the aforementioned license. The license
+# is also available online at http://www.enthought.com/licenses/BSD.txt
+#
+# Thanks for using Enthought open source!
+""" The starting point for performing naming operations. """
+
+
+# Local imports.
+from .context import Context
+
+
+
[docs]def InitialContext(environment): + """ Creates an initial context for beginning name resolution. """ + + # Get the class name of the factory that will produce the initial context. + klass_name = environment.get(Context.INITIAL_CONTEXT_FACTORY) + if klass_name is None: + raise ValueError("No initial context factory specified") + + # Import the factory class. + klass = _import_symbol(klass_name) + + # Create the factory. + factory = klass() + + # Ask the factory for a context implementation instance. + return factory.get_initial_context(environment)
+ + +# fixme: This is the same code as in the Envisage import manager but we don't +# want naming to be dependent on Envisage, so we need some other package +# for useful 'Python' tools etc. +def _import_symbol(symbol_path): + """Imports the symbol defined by 'symbol_path'. + + 'symbol_path' is a string in the form 'foo.bar.baz' which is turned + into an import statement 'from foo.bar import baz' (ie. the last + component of the name is the symbol name, the rest is the package/ + module path to load it from). + + """ + + components = symbol_path.split(".") + + module_name = ".".join(components[:-1]) + symbol_name = components[-1] + + module = __import__(module_name, globals(), locals(), [symbol_name]) + symbol = getattr(module, symbol_name) + + return symbol +
+ +
+
+
+
+
+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/5.0/_modules/apptools/naming/initial_context_factory.html b/5.0/_modules/apptools/naming/initial_context_factory.html new file mode 100644 index 000000000..8c80347bc --- /dev/null +++ b/5.0/_modules/apptools/naming/initial_context_factory.html @@ -0,0 +1,159 @@ + + + + + + + apptools.naming.initial_context_factory — Apptools Documentation + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +

Source code for apptools.naming.initial_context_factory

+# (C) Copyright 2005-2020 Enthought, Inc., Austin, TX
+# All rights reserved.
+#
+# This software is provided without warranty under the terms of the BSD
+# license included in LICENSE.txt and may be redistributed only under
+# the conditions described in the aforementioned license. The license
+# is also available online at http://www.enthought.com/licenses/BSD.txt
+#
+# Thanks for using Enthought open source!
+""" The base class for all initial context factories. """
+
+
+# Enthought library imports.
+from traits.api import HasTraits
+
+# Local imports.
+from .context import Context
+
+
+
[docs]class InitialContextFactory(HasTraits): + """ The base class for all initial context factories. """ + + ########################################################################### + # 'InitialContextFactory' interface. + ########################################################################### + +
[docs] def get_initial_context(self, environment): + """ Creates an initial context for beginning name resolution. """ + + return Context(environment=environment)
+
+ +
+
+
+
+
+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/5.0/_modules/apptools/naming/naming_event.html b/5.0/_modules/apptools/naming/naming_event.html new file mode 100644 index 000000000..e119c59e8 --- /dev/null +++ b/5.0/_modules/apptools/naming/naming_event.html @@ -0,0 +1,157 @@ + + + + + + + apptools.naming.naming_event — Apptools Documentation + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +

Source code for apptools.naming.naming_event

+# (C) Copyright 2005-2020 Enthought, Inc., Austin, TX
+# All rights reserved.
+#
+# This software is provided without warranty under the terms of the BSD
+# license included in LICENSE.txt and may be redistributed only under
+# the conditions described in the aforementioned license. The license
+# is also available online at http://www.enthought.com/licenses/BSD.txt
+#
+# Thanks for using Enthought open source!
+""" The event fired by the tree model when it changes. """
+
+
+# Enthought library imports.
+from traits.api import HasTraits, Instance
+
+# Local imports.
+from .binding import Binding
+
+
+# Classes for event traits.
+
[docs]class NamingEvent(HasTraits): + """ Information about tree model changes. """ + + # The old binding. + old_binding = Instance(Binding) + + # The new binding. + new_binding = Instance(Binding)
+
+ +
+
+
+
+
+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/5.0/_modules/apptools/naming/naming_manager.html b/5.0/_modules/apptools/naming/naming_manager.html new file mode 100644 index 000000000..124e9b884 --- /dev/null +++ b/5.0/_modules/apptools/naming/naming_manager.html @@ -0,0 +1,213 @@ + + + + + + + apptools.naming.naming_manager — Apptools Documentation + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +

Source code for apptools.naming.naming_manager

+# (C) Copyright 2005-2020 Enthought, Inc., Austin, TX
+# All rights reserved.
+#
+# This software is provided without warranty under the terms of the BSD
+# license included in LICENSE.txt and may be redistributed only under
+# the conditions described in the aforementioned license. The license
+# is also available online at http://www.enthought.com/licenses/BSD.txt
+#
+# Thanks for using Enthought open source!
+""" The naming manager. """
+
+
+# Enthought library imports.
+from traits.api import HasTraits
+
+
+
[docs]class NamingManager(HasTraits): + """ The naming manager. """ + + ########################################################################### + # 'NamingManager' interface. + ########################################################################### + +
[docs] def get_state_to_bind(self, obj, name, context): + """Returns the state of an object for binding. + + The naming manager asks the context for its list of STATE factories + and then calls them one by one until it gets a non-None result + indicating that the factory recognised the object and created state + information for it. + + If none of the factories recognize the object (or if the context + has no factories) then the object itself is returned. + + """ + + # Local imports. + from .context import Context + + # We get the state factories from the context's environment. + state_factories = context.environment[Context.STATE_FACTORIES] + + for state_factory in state_factories: + state = state_factory.get_state_to_bind(obj, name, context) + if state is not None: + break + + else: + state = obj + + return state
+ +
[docs] def get_object_instance(self, info, name, context): + """Creates an object using the specified state information. + + The naming manager asks the context for its list of OBJECT factories + and calls them one by one until it gets a non-None result, indicating + that the factory recognised the information and created an object. + + If none of the factories recognize the state information (or if the + context has no factories) then the state information itself is + returned. + + """ + + # Local imports. + from .context import Context + + # We get the object factories from the context's environment. + object_factories = context.environment[Context.OBJECT_FACTORIES] + + for object_factory in object_factories: + obj = object_factory.get_object_instance(info, name, context) + if obj is not None: + break + + else: + obj = info + + return obj
+ + +# Singleton instance. +naming_manager = NamingManager() +
+ +
+
+
+
+
+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/5.0/_modules/apptools/naming/object_factory.html b/5.0/_modules/apptools/naming/object_factory.html new file mode 100644 index 000000000..8277c2eec --- /dev/null +++ b/5.0/_modules/apptools/naming/object_factory.html @@ -0,0 +1,166 @@ + + + + + + + apptools.naming.object_factory — Apptools Documentation + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +

Source code for apptools.naming.object_factory

+# (C) Copyright 2005-2020 Enthought, Inc., Austin, TX
+# All rights reserved.
+#
+# This software is provided without warranty under the terms of the BSD
+# license included in LICENSE.txt and may be redistributed only under
+# the conditions described in the aforementioned license. The license
+# is also available online at http://www.enthought.com/licenses/BSD.txt
+#
+# Thanks for using Enthought open source!
+""" The base class for all object factories. """
+
+
+# Enthought library imports.
+from traits.api import HasTraits
+
+
+
[docs]class ObjectFactory(HasTraits): + """The base class for all object factories. + + An object factory accepts some information about how to create an object + (such as a reference) and returns an instance of that object. + + """ + + ########################################################################### + # 'ObjectFactory' interface. + ########################################################################### + +
[docs] def get_object_instance(self, state, name, context): + """Creates an object using the specified state information. + + Returns None if the factory cannot create the object (ie. it does not + recognise the state passed to it). + + """ + + raise NotImplementedError
+
+ +
+
+
+
+
+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/5.0/_modules/apptools/naming/object_serializer.html b/5.0/_modules/apptools/naming/object_serializer.html new file mode 100644 index 000000000..8df9f1aab --- /dev/null +++ b/5.0/_modules/apptools/naming/object_serializer.html @@ -0,0 +1,222 @@ + + + + + + + apptools.naming.object_serializer — Apptools Documentation + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +

Source code for apptools.naming.object_serializer

+# (C) Copyright 2005-2020 Enthought, Inc., Austin, TX
+# All rights reserved.
+#
+# This software is provided without warranty under the terms of the BSD
+# license included in LICENSE.txt and may be redistributed only under
+# the conditions described in the aforementioned license. The license
+# is also available online at http://www.enthought.com/licenses/BSD.txt
+#
+# Thanks for using Enthought open source!
+""" The base class for all object serializers. """
+
+
+# Standard library imports.
+import logging
+from traceback import print_exc
+from os.path import splitext
+import pickle
+
+# Enthought library imports.
+from apptools.persistence.versioned_unpickler import VersionedUnpickler
+from traits.api import HasTraits, Str
+
+
+# Setup a logger for this module.
+logger = logging.getLogger(__name__)
+
+
+
[docs]class ObjectSerializer(HasTraits): + """ The base class for all object serializers. """ + + #### 'ObjectSerializer' interface ######################################### + + # The file extension recognized by this serializer. + ext = Str(".pickle") + + ########################################################################### + # 'ObjectSerializer' interface. + ########################################################################### + +
[docs] def can_load(self, path): + """ Returns True if the serializer can load a file. """ + + rest, ext = splitext(path) + + return ext == self.ext
+ +
[docs] def load(self, path): + """ Loads an object from a file. """ + + # Unpickle the object. + f = open(path, "rb") + try: + try: + obj = VersionedUnpickler(f).load() + except Exception as ex: + print_exc() + logger.exception( + "Failed to load pickle file: %s, %s" % (path, ex) + ) + + raise + finally: + f.close() + + return obj
+ +
[docs] def can_save(self, obj): + """ Returns True if the serializer can save an object. """ + + return True
+ +
[docs] def save(self, path, obj): + """ Saves an object to a file. """ + + if not path.endswith(self.ext): + actual_path = path + self.ext + + else: + actual_path = path + + # Pickle the object. + f = open(actual_path, "wb") + try: + pickle.dump(obj, f, 1) + except Exception as ex: + logger.exception( + "Failed to pickle into file: %s, %s, object:%s" + % (path, ex, obj) + ) + print_exc() + f.close() + + return actual_path
+
+ +
+
+
+
+
+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/5.0/_modules/apptools/naming/py_context.html b/5.0/_modules/apptools/naming/py_context.html new file mode 100644 index 000000000..b3bb934f3 --- /dev/null +++ b/5.0/_modules/apptools/naming/py_context.html @@ -0,0 +1,311 @@ + + + + + + + apptools.naming.py_context — Apptools Documentation + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +

Source code for apptools.naming.py_context

+# (C) Copyright 2005-2020 Enthought, Inc., Austin, TX
+# All rights reserved.
+#
+# This software is provided without warranty under the terms of the BSD
+# license included in LICENSE.txt and may be redistributed only under
+# the conditions described in the aforementioned license. The license
+# is also available online at http://www.enthought.com/licenses/BSD.txt
+#
+# Thanks for using Enthought open source!
+""" A naming context for a Python namespace. """
+
+
+# Enthought library imports.
+from traits.api import Any, Dict, Instance, Property
+
+# Local imports.
+from .address import Address
+from .binding import Binding
+from .context import Context
+from .naming_manager import naming_manager
+from .py_object_factory import PyObjectFactory
+from .reference import Reference
+from .referenceable import Referenceable
+from .referenceable_state_factory import ReferenceableStateFactory
+
+
+# The default environment.
+ENVIRONMENT = {
+    # 'Context' properties.
+    Context.OBJECT_FACTORIES: [PyObjectFactory()],
+    Context.STATE_FACTORIES: [ReferenceableStateFactory()],
+}
+
+
+
[docs]class PyContext(Context, Referenceable): + """ A naming context for a Python namespace. """ + + #### 'Context' interface ################################################## + + # The naming environment in effect for this context. + environment = Dict(ENVIRONMENT) + + #### 'PyContext' interface ################################################ + + # The Python namespace that we represent. + namespace = Any + + # If the namespace is actual a Python object that has a '__dict__' + # attribute, then this will be that object (the namespace will be the + # object's '__dict__'. + obj = Any + + #### 'Referenceable' interface ############################################ + + # The object's reference suitable for binding in a naming context. + reference = Property(Instance(Reference)) + + ########################################################################### + # 'object' interface. + ########################################################################### + + def __init__(self, **traits): + """ Creates a new context. """ + + # Base class constructor. + super(PyContext, self).__init__(**traits) + + if type(self.namespace) is not dict: + if hasattr(self.namespace, "__dict__"): + self.obj = self.namespace + self.namespace = self.namespace.__dict__ + + else: + raise ValueError("Need a dictionary or a __dict__ attribute") + + ########################################################################### + # 'Referenceable' interface. + ########################################################################### + + #### Properties ########################################################### + + def _get_reference(self): + """ Returns a reference to this object suitable for binding. """ + + reference = Reference( + class_name=self.__class__.__name__, + addresses=[Address(type="py_context", content=self.namespace)], + ) + + return reference + + ########################################################################### + # Protected 'Context' interface. + ########################################################################### + + def _is_bound(self, name): + """ Is a name bound in this context? """ + + return name in self.namespace + + def _lookup(self, name): + """ Looks up a name in this context. """ + + obj = self.namespace[name] + + return naming_manager.get_object_instance(obj, name, self) + + def _bind(self, name, obj): + """ Binds a name to an object in this context. """ + + state = naming_manager.get_state_to_bind(obj, name, self) + self.namespace[name] = state + + def _rebind(self, name, obj): + """ Rebinds a name to a object in this context. """ + + self._bind(name, obj) + + def _unbind(self, name): + """ Unbinds a name from this context. """ + + del self.namespace[name] + + # Trait event notification. + self.trait_property_changed("context_changed", None, None) + + def _rename(self, old_name, new_name): + """ Renames an object in this context. """ + + state = self.namespace[old_name] + + # Bind the new name. + self.namespace[new_name] = state + + # Unbind the old one. + del self.namespace[old_name] + + # Trait event notification. + self.context_changed = True + + def _create_subcontext(self, name): + """ Creates a sub-context of this context. """ + + sub = self._context_factory(name, {}) + self.namespace[name] = sub + + # Trait event notification. + self.trait_property_changed("context_changed", None, None) + + return sub + + def _destroy_subcontext(self, name): + """ Destroys a sub-context of this context. """ + + del self.namespace[name] + + # Trait event notification. + self.trait_property_changed("context_changed", None, None) + + def _list_bindings(self): + """ Lists the bindings in this context. """ + + bindings = [] + for name, value in self.namespace.items(): + bindings.append( + Binding(name=name, obj=self._lookup(name), context=self) + ) + return bindings + + def _list_names(self): + """ Lists the names bound in this context. """ + + return list(self.namespace.keys()) + + ########################################################################### + # Private interface. + ########################################################################### + + def _context_factory(self, name, namespace): + """ Create a sub-context. """ + + return self.__class__(namespace=namespace)
+
+ +
+
+
+
+
+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/5.0/_modules/apptools/naming/py_object_factory.html b/5.0/_modules/apptools/naming/py_object_factory.html new file mode 100644 index 000000000..4a049b8ad --- /dev/null +++ b/5.0/_modules/apptools/naming/py_object_factory.html @@ -0,0 +1,171 @@ + + + + + + + apptools.naming.py_object_factory — Apptools Documentation + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +

Source code for apptools.naming.py_object_factory

+# (C) Copyright 2005-2020 Enthought, Inc., Austin, TX
+# All rights reserved.
+#
+# This software is provided without warranty under the terms of the BSD
+# license included in LICENSE.txt and may be redistributed only under
+# the conditions described in the aforementioned license. The license
+# is also available online at http://www.enthought.com/licenses/BSD.txt
+#
+# Thanks for using Enthought open source!
+""" Object factory for Python namespace contexts. """
+
+
+# Local imports.
+from .object_factory import ObjectFactory
+from .reference import Reference
+
+
+
[docs]class PyObjectFactory(ObjectFactory): + """ Object factory for Python namespace contexts. """ + + ########################################################################### + # 'ObjectFactory' interface. + ########################################################################### + +
[docs] def get_object_instance(self, state, name, context): + """ Creates an object using the specified state information. """ + + obj = None + + if isinstance(state, Reference): + if len(state.addresses) > 0: + if state.addresses[0].type == "py_context": + namespace = state.addresses[0].content + obj = context._context_factory(name, namespace) + + elif hasattr(state, "__dict__"): + from apptools.naming.py_context import PyContext + + if not isinstance(state, PyContext): + obj = context._context_factory(name, state) + + return obj
+
+ +
+
+
+
+
+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/5.0/_modules/apptools/naming/pyfs_context.html b/5.0/_modules/apptools/naming/pyfs_context.html new file mode 100644 index 000000000..819d1dbd6 --- /dev/null +++ b/5.0/_modules/apptools/naming/pyfs_context.html @@ -0,0 +1,674 @@ + + + + + + + apptools.naming.pyfs_context — Apptools Documentation + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +

Source code for apptools.naming.pyfs_context

+# (C) Copyright 2005-2020 Enthought, Inc., Austin, TX
+# All rights reserved.
+#
+# This software is provided without warranty under the terms of the BSD
+# license included in LICENSE.txt and may be redistributed only under
+# the conditions described in the aforementioned license. The license
+# is also available online at http://www.enthought.com/licenses/BSD.txt
+#
+# Thanks for using Enthought open source!
+""" A Python File System context. """
+
+
+# Standard library imports.
+import glob
+import logging
+import os
+from os.path import join, splitext
+import pickle
+
+# Enthought library imports.
+from apptools.io.api import File
+from traits.api import Any, Dict, Instance, Property, Str
+
+# Local imports.
+from .address import Address
+from .binding import Binding
+from .context import Context
+from .dir_context import DirContext
+from .naming_event import NamingEvent
+from .naming_manager import naming_manager
+from .object_serializer import ObjectSerializer
+from .pyfs_context_factory import PyFSContextFactory
+from .pyfs_object_factory import PyFSObjectFactory
+from .pyfs_state_factory import PyFSStateFactory
+from .reference import Reference
+from .referenceable import Referenceable
+
+
+# Setup a logger for this module.
+logger = logging.getLogger(__name__)
+
+
+# The name of the 'special' file in which we store object attributes.
+ATTRIBUTES_FILE = "__attributes__"
+
+# Constants for environment property keys.
+FILTERS = "apptools.naming.pyfs.filters"
+OBJECT_SERIALIZERS = "apptools.naming.pyfs.object.serializers"
+
+
+# The default environment.
+ENVIRONMENT = {
+    #### 'Context' properties #################################################
+    # Object factories.
+    Context.OBJECT_FACTORIES: [PyFSObjectFactory(), PyFSContextFactory()],
+    # State factories.
+    Context.STATE_FACTORIES: [PyFSStateFactory()],
+    #### 'PyFSContext' properties #############################################
+    # Object serializers.
+    OBJECT_SERIALIZERS: [ObjectSerializer()],
+    # List of filename patterns to ignore.  These patterns are passed to
+    # 'glob.glob', so things like '*.pyc' will do what you expect.
+    #
+    # fixme: We should have a generalized filter mechanism here, and '.svn'
+    # should be moved elsewhere!
+    FILTERS: [ATTRIBUTES_FILE, ".svn"],
+}
+
+
+
[docs]class PyFSContext(DirContext, Referenceable): + """A Python File System context. + + This context represents a directory on a local file system. + + """ + + # The name of the 'special' file in which we store object attributes. + ATTRIBUTES_FILE = ATTRIBUTES_FILE + + # Environment property keys. + FILTERS = FILTERS + OBJECT_SERIALIZERS = OBJECT_SERIALIZERS + + #### 'Context' interface ################################################## + + # The naming environment in effect for this context. + environment = Dict(ENVIRONMENT) + + # The name of the context within its own namespace. + namespace_name = Property(Str) + + #### 'PyFSContext' interface ############################################## + + # The name of the context (the last component of the path). + name = Str + + # The path name of the directory on the local file system. + path = Str + + #### 'Referenceable' interface ############################################ + + # The object's reference suitable for binding in a naming context. + reference = Property(Instance(Reference)) + + #### Private interface #################################################### + + # A mapping from bound name to the name of the corresponding file or + # directory on the file system. + _name_to_filename_map = Dict # (Str, Str) + + # The attributes of every object in the context. The attributes for the + # context itself have the empty string as the key. + # + # {str name : dict attributes} + # + # fixme: Don't use 'Dict' here as it causes problems when pickling because + # trait dicts have a reference back to the parent object (hence we end up + # pickling all kinds of things that we don't need or want to!). + _attributes = Any + + ########################################################################### + # 'object' interface. + ########################################################################### + + def __init__(self, **traits): + """ Creates a new context. """ + + # Base class constructor. + super(PyFSContext, self).__init__(**traits) + + # We cache each object as it is looked up so that all accesses to a + # serialized Python object return a reference to exactly the same one. + self._cache = {} + + ########################################################################### + # 'PyFSContext' interface. + ########################################################################### + + #### Properties ########################################################### + + def _get_namespace_name(self): + """ Returns the name of the context within its own namespace. """ + + # fixme: clean this up with an initial context API! + if "root" in self.environment: + root = self.environment["root"] + + namespace_name = self.path[len(root) + 1:] + + else: + namespace_name = self.path + + # fixme: This is a bit dodgy 'cos we actually return a name that can + # be looked up, and not the file system name... + namespace_name = "/".join(namespace_name.split(os.path.sep)) + + return namespace_name + + #### methods ############################################################## + +
[docs] def refresh(self): + """ Refresh the context to reflect changes in the file system. """ + + # fixme: This needs more work 'cos if we refresh a context then we + # will load new copies of serialized Python objects! + + # This causes the initializer to run again the next time the trait is + # accessed. + self.reset_traits(["_name_to_filename_map"]) + + # Clear out the cache. + self._cache = {} + + # fixme: This is a bit hacky since the context in the binding may + # not be None! + self.context_changed = NamingEvent( + new_binding=Binding(name=self.name, obj=self, context=None) + )
+ + ########################################################################### + # 'Referenceable' interface. + ########################################################################### + + #### Properties ########################################################### + + def _get_reference(self): + """ Returns a reference to this object suitable for binding. """ + + abspath = os.path.abspath(self.path) + + reference = Reference( + class_name=self.__class__.__name__, + addresses=[Address(type="pyfs_context", content=abspath)], + ) + + return reference + + ########################################################################### + # Protected 'Context' interface. + ########################################################################### + + def _is_bound(self, name): + """ Is a name bound in this context? """ + + return name in self._name_to_filename_map + + def _lookup(self, name): + """ Looks up a name in this context. """ + + if name in self._cache: + obj = self._cache[name] + + else: + # Get the full path to the file. + path = join(self.path, self._name_to_filename_map[name]) + + # If the file contains a serialized Python object then load it. + for serializer in self._get_object_serializers(): + if serializer.can_load(path): + try: + state = serializer.load(path) + + # If the load fails then we create a generic file resource + # (the idea being that it might be useful to have access to + # the file to see what went wrong). + except: # noqa: E722 + state = File(path) + logger.exception("Error loading resource at %s" % path) + + break + + # Otherwise, it must just be a file or folder. + else: + # Directories are contexts. + if os.path.isdir(path): + state = self._context_factory(name, path) + + # Files are just files! + elif os.path.isfile(path): + state = File(path) + + else: + raise ValueError("unrecognized file for %s" % name) + + # Get the actual object from the naming manager. + obj = naming_manager.get_object_instance(state, name, self) + + # Update the cache. + self._cache[name] = obj + + return obj + + def _bind(self, name, obj): + """ Binds a name to an object in this context. """ + + # Get the actual state to bind from the naming manager. + state = naming_manager.get_state_to_bind(obj, name, self) + + # If the object is actually an abstract file then we don't have to + # do anything. + if isinstance(state, File): + if not state.exists: + state.create_file() + + filename = name + + # Otherwise we are binding an arbitrary Python object, so find a + # serializer for it. + else: + for serializer in self._get_object_serializers(): + if serializer.can_save(obj): + path = serializer.save(join(self.path, name), obj) + filename = os.path.basename(path) + break + + else: + raise ValueError("cannot serialize object %s" % name) + + # Update the name to filename map. + self._name_to_filename_map[name] = filename + + # Update the cache. + self._cache[name] = obj + + return state + + def _rebind(self, name, obj): + """ Rebinds a name to an object in this context. """ + + self._bind(name, obj) + + def _unbind(self, name): + """ Unbinds a name from this context. """ + + # Get the full path to the file. + path = join(self.path, self._name_to_filename_map[name]) + + # Remove it! + f = File(path) + f.delete() + + # Update the name to filename map. + del self._name_to_filename_map[name] + + # Update the cache. + if name in self._cache: + del self._cache[name] + + # Remove any attributes. + if name in self._attributes: + del self._attributes[name] + self._save_attributes() + + def _rename(self, old_name, new_name): + """ Renames an object in this context. """ + + # Get the old filename. + old_filename = self._name_to_filename_map[old_name] + old_file = File(join(self.path, old_filename)) + + # Lookup the object bound to the old name. This has the side effect + # of adding the object to the cache under the name 'old_name'. + obj = self._lookup(old_name) + + # We are renaming a LOCAL context (ie. a folder)... + if old_file.is_folder: + # Create the new filename. + new_filename = new_name + new_file = File(join(self.path, new_filename)) + + # Move the folder. + old_file.move(new_file) + + # Update the 'Context' object. + obj.path = new_file.path + + # Update the cache. + self._cache[new_name] = obj + del self._cache[old_name] + + # Refreshing the context makes sure that all of its contents + # reflect the new name (i.e., sub-folders and files have the + # correct path). + # + # fixme: This currently results in new copies of serialized + # Python objects! We need to be a bit more judicious in the + # refresh. + obj.refresh() + + # We are renaming a file... + elif isinstance(obj, File): + # Create the new filename. + new_filename = new_name + new_file = File(join(self.path, new_filename)) + + # Move the file. + old_file.move(new_file) + + # Update the 'File' object. + obj.path = new_file.path + + # Update the cache. + self._cache[new_name] = obj + del self._cache[old_name] + + # We are renaming a serialized Python object... + else: + # Create the new filename. + new_filename = new_name + old_file.ext + new_file = File(join(self.path, new_filename)) + + old_file.delete() + + # Update the cache. + if old_name in self._cache: + self._cache[new_name] = self._cache[old_name] + del self._cache[old_name] + + # Force the creation of the new file. + # + # fixme: I'm not sure that this is really the place for this. We + # do it because often the 'name' of the object is actually an + # attribute of the object itself, and hence we want the serialized + # state to reflect the new name... Hmmm... + self._rebind(new_name, obj) + + # Update the name to filename map. + del self._name_to_filename_map[old_name] + self._name_to_filename_map[new_name] = new_filename + + # Move any attributes over to the new name. + if old_name in self._attributes: + self._attributes[new_name] = self._attributes[old_name] + del self._attributes[old_name] + self._save_attributes() + + def _create_subcontext(self, name): + """ Creates a sub-context of this context. """ + + path = join(self.path, name) + + # Create a directory. + os.mkdir(path) + + # Create a sub-context that represents the directory. + sub = self._context_factory(name, path) + + # Update the name to filename map. + self._name_to_filename_map[name] = name + + # Update the cache. + self._cache[name] = sub + + return sub + + def _destroy_subcontext(self, name): + """ Destroys a sub-context of this context. """ + + return self._unbind(name) + + def _list_names(self): + """ Lists the names bound in this context. """ + + return list(self._name_to_filename_map.keys()) + + # fixme: YFI this is not part of the protected 'Context' interface so + # what is it doing here? +
[docs] def get_unique_name(self, name): + + ext = splitext(name)[1] + + # specially handle '.py' files + if ext != ".py": + return super(PyFSContext, self).get_unique_name(name) + + body = splitext(name)[0] + names = self.list_names() + i = 2 + unique = name + while unique in names: + unique = body + "_" + str(i) + ".py" + i += 1 + + return unique
+ + ########################################################################### + # Protected 'DirContext' interface. + ########################################################################### + + def _get_attributes(self, name): + """ Returns the attributes of an object in this context. """ + + attributes = self._attributes.setdefault(name, {}) + + return attributes.copy() + + def _set_attributes(self, name, attributes): + """ Sets the attributes of an object in this context. """ + + self._attributes[name] = attributes + self._save_attributes() + + ########################################################################### + # Private interface. + ########################################################################### + + def _get_filters(self): + """ Returns the filters for this context. """ + + return self.environment.get(self.FILTERS, []) + + def _get_object_serializers(self): + """ Returns the object serializers for this context. """ + + return self.environment.get(self.OBJECT_SERIALIZERS, []) + + def _context_factory(self, name, path): + """ Create a sub-context. """ + + return self.__class__(path=path, environment=self.environment) + + def _save_attributes(self): + """ Saves all attributes to the attributes file. """ + + path = join(self.path, self.ATTRIBUTES_FILE) + + f = open(path, "wb") + pickle.dump(self._attributes, f, 1) + f.close() + + #### Trait initializers ################################################### + + def __name_to_filename_map_default(self): + """ Initializes the '_name_to_filename' trait. """ + + # fixme: We should have a generalized filter mechanism (instead of + # just 'glob' patterns we should have filter objects that can be a bit + # more flexible in how they do the filtering). + patterns = [join(self.path, filter) for filter in self._get_filters()] + + name_to_filename_map = {} + for filename in os.listdir(self.path): + path = join(self.path, filename) + for pattern in patterns: + if path in glob.glob(pattern): + break + + else: + for serializer in self._get_object_serializers(): + if serializer.can_load(filename): + # fixme: We should probably get the name from the + # serializer instead of assuming that we can just + # drop the file exension. + name, ext = os.path.splitext(filename) + break + + else: + name = filename + + name_to_filename_map[name] = filename + + return name_to_filename_map + + def __attributes_default(self): + """ Initializes the '_attributes' trait. """ + + attributes_file = File(join(self.path, self.ATTRIBUTES_FILE)) + if attributes_file.is_file: + f = open(attributes_file.path, "rb") + attributes = pickle.load(f) + f.close() + + else: + attributes = {} + + return attributes + + #### Trait event handlers ################################################# + + def _path_changed(self): + """ Called when the context's path has changed. """ + + basename = os.path.basename(self.path) + + self.name, ext = os.path.splitext(basename)
+
+ +
+
+
+
+
+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/5.0/_modules/apptools/naming/pyfs_context_factory.html b/5.0/_modules/apptools/naming/pyfs_context_factory.html new file mode 100644 index 000000000..13c30f4ea --- /dev/null +++ b/5.0/_modules/apptools/naming/pyfs_context_factory.html @@ -0,0 +1,165 @@ + + + + + + + apptools.naming.pyfs_context_factory — Apptools Documentation + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +

Source code for apptools.naming.pyfs_context_factory

+# (C) Copyright 2005-2020 Enthought, Inc., Austin, TX
+# All rights reserved.
+#
+# This software is provided without warranty under the terms of the BSD
+# license included in LICENSE.txt and may be redistributed only under
+# the conditions described in the aforementioned license. The license
+# is also available online at http://www.enthought.com/licenses/BSD.txt
+#
+# Thanks for using Enthought open source!
+""" Object factory for Python File System contexts. """
+
+
+# Local imports.
+from .object_factory import ObjectFactory
+from .reference import Reference
+
+
+
[docs]class PyFSContextFactory(ObjectFactory): + """ Object factory for Python File System contexts. """ + + ########################################################################### + # 'ObjectFactory' interface. + ########################################################################### + +
[docs] def get_object_instance(self, state, name, context): + """ Creates an object using the specified state information. """ + + obj = None + + if isinstance(state, Reference): + if len(state.addresses) > 0: + if state.addresses[0].type == "pyfs_context": + path = state.addresses[0].content + obj = context._context_factory(name, path) + + return obj
+
+ +
+
+
+
+
+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/5.0/_modules/apptools/naming/pyfs_initial_context_factory.html b/5.0/_modules/apptools/naming/pyfs_initial_context_factory.html new file mode 100644 index 000000000..6dc9fafdc --- /dev/null +++ b/5.0/_modules/apptools/naming/pyfs_initial_context_factory.html @@ -0,0 +1,174 @@ + + + + + + + apptools.naming.pyfs_initial_context_factory — Apptools Documentation + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +

Source code for apptools.naming.pyfs_initial_context_factory

+# (C) Copyright 2005-2020 Enthought, Inc., Austin, TX
+# All rights reserved.
+#
+# This software is provided without warranty under the terms of the BSD
+# license included in LICENSE.txt and may be redistributed only under
+# the conditions described in the aforementioned license. The license
+# is also available online at http://www.enthought.com/licenses/BSD.txt
+#
+# Thanks for using Enthought open source!
+""" The initial context factory for Python file system contexts. """
+
+
+# Local imports.
+from .context import Context
+from .initial_context_factory import InitialContextFactory
+from .object_serializer import ObjectSerializer
+from .pyfs_context import PyFSContext
+from .pyfs_context_factory import PyFSContextFactory
+from .pyfs_object_factory import PyFSObjectFactory
+from .pyfs_state_factory import PyFSStateFactory
+
+
+
[docs]class PyFSInitialContextFactory(InitialContextFactory): + """ The initial context factory for Python file system contexts. """ + + ########################################################################### + # 'InitialContextFactory' interface. + ########################################################################### + +
[docs] def get_initial_context(self, environment): + """ Creates an initial context for beginning name resolution. """ + + # Object factories. + object_factories = [PyFSObjectFactory(), PyFSContextFactory()] + environment[Context.OBJECT_FACTORIES] = object_factories + + # State factories. + state_factories = [PyFSStateFactory()] + environment[Context.STATE_FACTORIES] = state_factories + + # Object serializers. + object_serializers = [ObjectSerializer()] + environment[PyFSContext.OBJECT_SERIALIZERS] = object_serializers + + return PyFSContext(path=r"", environment=environment)
+
+ +
+
+
+
+
+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/5.0/_modules/apptools/naming/pyfs_object_factory.html b/5.0/_modules/apptools/naming/pyfs_object_factory.html new file mode 100644 index 000000000..394ba4730 --- /dev/null +++ b/5.0/_modules/apptools/naming/pyfs_object_factory.html @@ -0,0 +1,166 @@ + + + + + + + apptools.naming.pyfs_object_factory — Apptools Documentation + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +

Source code for apptools.naming.pyfs_object_factory

+# (C) Copyright 2005-2020 Enthought, Inc., Austin, TX
+# All rights reserved.
+#
+# This software is provided without warranty under the terms of the BSD
+# license included in LICENSE.txt and may be redistributed only under
+# the conditions described in the aforementioned license. The license
+# is also available online at http://www.enthought.com/licenses/BSD.txt
+#
+# Thanks for using Enthought open source!
+""" Object factory for Python File System contexts. """
+
+
+# Enthought library imports.
+from apptools.io.api import File
+
+# Local imports.
+from .object_factory import ObjectFactory
+from .reference import Reference
+
+
+
[docs]class PyFSObjectFactory(ObjectFactory): + """ Object factory for Python File System contexts. """ + + ########################################################################### + # 'ObjectFactory' interface. + ########################################################################### + +
[docs] def get_object_instance(self, state, name, context): + """ Creates an object using the specified state information. """ + + obj = None + + if isinstance(state, Reference): + if state.class_name == "File" and len(state.addresses) > 0: + obj = File(state.addresses[0].content) + + return obj
+
+ +
+
+
+
+
+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/5.0/_modules/apptools/naming/pyfs_state_factory.html b/5.0/_modules/apptools/naming/pyfs_state_factory.html new file mode 100644 index 000000000..b942c237e --- /dev/null +++ b/5.0/_modules/apptools/naming/pyfs_state_factory.html @@ -0,0 +1,172 @@ + + + + + + + apptools.naming.pyfs_state_factory — Apptools Documentation + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +

Source code for apptools.naming.pyfs_state_factory

+# (C) Copyright 2005-2020 Enthought, Inc., Austin, TX
+# All rights reserved.
+#
+# This software is provided without warranty under the terms of the BSD
+# license included in LICENSE.txt and may be redistributed only under
+# the conditions described in the aforementioned license. The license
+# is also available online at http://www.enthought.com/licenses/BSD.txt
+#
+# Thanks for using Enthought open source!
+""" State factory for Python File System contexts. """
+
+
+# Enthought library imports.
+from apptools.io.api import File
+
+# Local imports.
+from .address import Address
+from .reference import Reference
+from .state_factory import StateFactory
+
+
+
[docs]class PyFSStateFactory(StateFactory): + """ State factory for Python File System contexts. """ + + ########################################################################### + # 'StateFactory' interface. + ########################################################################### + +
[docs] def get_state_to_bind(self, obj, name, context): + """ Returns the state of an object for binding. """ + + state = None + + if isinstance(obj, File): + # If the file is not actually in the directory represented by the + # context then we create and bind a reference to it. + if obj.parent.path != context.path: + state = Reference( + class_name=obj.__class__.__name__, + addresses=[Address(type="file", content=obj.path)], + ) + + return state
+
+ +
+
+
+
+
+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/5.0/_modules/apptools/naming/reference.html b/5.0/_modules/apptools/naming/reference.html new file mode 100644 index 000000000..4e9f94dde --- /dev/null +++ b/5.0/_modules/apptools/naming/reference.html @@ -0,0 +1,173 @@ + + + + + + + apptools.naming.reference — Apptools Documentation + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +

Source code for apptools.naming.reference

+# (C) Copyright 2005-2020 Enthought, Inc., Austin, TX
+# All rights reserved.
+#
+# This software is provided without warranty under the terms of the BSD
+# license included in LICENSE.txt and may be redistributed only under
+# the conditions described in the aforementioned license. The license
+# is also available online at http://www.enthought.com/licenses/BSD.txt
+#
+# Thanks for using Enthought open source!
+""" A reference to an object that lives outside of the naming system. """
+
+
+# Enthought library imports.
+from traits.api import HasPrivateTraits, List, Str
+
+# Local imports.
+from .address import Address
+
+
+
[docs]class Reference(HasPrivateTraits): + """A reference to an object that lives outside of the naming system. + + References provide a way to store the address(s) of objects that live + outside of the naming system. A reference consists of a list of + addresses that represent a communications endpoint for the object being + referenced. + + A reference also contains information to assist in the creation of an + instance of the object to which it refers. It contains the name of + the class that will be created and the class name and location of a + factory that will be used to do the actual instance creation. + + """ + + #### 'Reference' interface ################################################ + + # The list of addresses that can be used to 'contact' the object. + addresses = List(Address) + + # The class name of the object that this reference refers to. + class_name = Str + + # The class name of the object factory. + factory_class_name = Str
+
+ +
+
+
+
+
+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/5.0/_modules/apptools/naming/referenceable.html b/5.0/_modules/apptools/naming/referenceable.html new file mode 100644 index 000000000..4989cb547 --- /dev/null +++ b/5.0/_modules/apptools/naming/referenceable.html @@ -0,0 +1,155 @@ + + + + + + + apptools.naming.referenceable — Apptools Documentation + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +

Source code for apptools.naming.referenceable

+# (C) Copyright 2005-2020 Enthought, Inc., Austin, TX
+# All rights reserved.
+#
+# This software is provided without warranty under the terms of the BSD
+# license included in LICENSE.txt and may be redistributed only under
+# the conditions described in the aforementioned license. The license
+# is also available online at http://www.enthought.com/licenses/BSD.txt
+#
+# Thanks for using Enthought open source!
+""" Base class for classes that can produce a reference to themselves. """
+
+
+# Enthought library imports.
+from traits.api import HasPrivateTraits, Instance
+
+# Local imports.
+from .reference import Reference
+
+
+
[docs]class Referenceable(HasPrivateTraits): + """ Base class for classes that can produce a reference to themselves. """ + + #### 'Referenceable' interface ############################################ + + # The object's reference suitable for binding in a naming context. + reference = Instance(Reference)
+
+ +
+
+
+
+
+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/5.0/_modules/apptools/naming/referenceable_state_factory.html b/5.0/_modules/apptools/naming/referenceable_state_factory.html new file mode 100644 index 000000000..6735d1441 --- /dev/null +++ b/5.0/_modules/apptools/naming/referenceable_state_factory.html @@ -0,0 +1,164 @@ + + + + + + + apptools.naming.referenceable_state_factory — Apptools Documentation + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +

Source code for apptools.naming.referenceable_state_factory

+# (C) Copyright 2005-2020 Enthought, Inc., Austin, TX
+# All rights reserved.
+#
+# This software is provided without warranty under the terms of the BSD
+# license included in LICENSE.txt and may be redistributed only under
+# the conditions described in the aforementioned license. The license
+# is also available online at http://www.enthought.com/licenses/BSD.txt
+#
+# Thanks for using Enthought open source!
+""" State factory for referenceable objects. """
+
+
+# Local imports.
+from .referenceable import Referenceable
+from .state_factory import StateFactory
+
+
+
[docs]class ReferenceableStateFactory(StateFactory): + """ State factory for referenceable objects. """ + + ########################################################################### + # 'StateFactory' interface. + ########################################################################### + +
[docs] def get_state_to_bind(self, obj, name, context): + """ Returns the state of an object for binding. """ + + state = None + + # If the object knows how to create a reference to it then let it + # do so. + if isinstance(obj, Referenceable): + state = obj.reference + + return state
+
+ +
+
+
+
+
+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/5.0/_modules/apptools/naming/state_factory.html b/5.0/_modules/apptools/naming/state_factory.html new file mode 100644 index 000000000..6e858ad08 --- /dev/null +++ b/5.0/_modules/apptools/naming/state_factory.html @@ -0,0 +1,166 @@ + + + + + + + apptools.naming.state_factory — Apptools Documentation + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +

Source code for apptools.naming.state_factory

+# (C) Copyright 2005-2020 Enthought, Inc., Austin, TX
+# All rights reserved.
+#
+# This software is provided without warranty under the terms of the BSD
+# license included in LICENSE.txt and may be redistributed only under
+# the conditions described in the aforementioned license. The license
+# is also available online at http://www.enthought.com/licenses/BSD.txt
+#
+# Thanks for using Enthought open source!
+""" The base class for all state factories. """
+
+
+# Enthought library imports.
+from traits.api import HasPrivateTraits
+
+
+
[docs]class StateFactory(HasPrivateTraits): + """The base class for all state factories. + + A state factory accepts an object and returns some data representing the + object that is suitable for storing in a particular context. + + """ + + ########################################################################### + # 'StateFactory' interface. + ########################################################################### + +
[docs] def get_state_to_bind(self, obj, name, context): + """Returns the state of an object for binding. + + Returns None if the factory cannot create the state (ie. it does not + recognise the object passed to it). + + """ + + raise NotImplementedError
+
+ +
+
+
+
+
+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/5.0/_modules/apptools/naming/trait_defs/naming_traits.html b/5.0/_modules/apptools/naming/trait_defs/naming_traits.html new file mode 100644 index 000000000..ad3cc1734 --- /dev/null +++ b/5.0/_modules/apptools/naming/trait_defs/naming_traits.html @@ -0,0 +1,300 @@ + + + + + + + apptools.naming.trait_defs.naming_traits — Apptools Documentation + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +

Source code for apptools.naming.trait_defs.naming_traits

+# (C) Copyright 2005-2020 Enthought, Inc., Austin, TX
+# All rights reserved.
+#
+# This software is provided without warranty under the terms of the BSD
+# license included in LICENSE.txt and may be redistributed only under
+# the conditions described in the aforementioned license. The license
+# is also available online at http://www.enthought.com/licenses/BSD.txt
+#
+# Thanks for using Enthought open source!
+
+# -------------------------------------------------------------------------------
+#  Imports:
+# -------------------------------------------------------------------------------
+
+import sys
+
+from traits.api import Trait, TraitHandler, TraitFactory
+
+from traits.trait_base import class_of, get_module_name
+
+from apptools.naming.api import Binding
+
+
+# -------------------------------------------------------------------------------
+#  'NamingInstance' trait factory:
+# -------------------------------------------------------------------------------
+
+
+def NamingInstance(klass=None, value="", allow_none=False, **metadata):
+    metadata.setdefault("copy", "deep")
+    return Trait(
+        value,
+        NamingTraitHandler(
+            klass, or_none=allow_none, module=get_module_name()
+        ),
+        **metadata
+    )
+
+
+NamingInstance = TraitFactory(NamingInstance)
+
+# -------------------------------------------------------------------------------
+#  'NamingTraitHandler' class:
+# -------------------------------------------------------------------------------
+
+
+
[docs]class NamingTraitHandler(TraitHandler): + + # --------------------------------------------------------------------------- + # Initializes the object: + # --------------------------------------------------------------------------- + + def __init__(self, aClass, or_none, module): + """Initializes the object.""" + self.or_none = or_none is not False + self.module = module + self.aClass = aClass + if (aClass is not None) and ( + not isinstance(aClass, (str, type)) + ): + self.aClass = aClass.__class__ + +
[docs] def validate(self, object, name, value): + if isinstance(value, str): + if value == "": + if self.or_none: + return "" + else: + self.validate_failed(object, name, value) + try: + value = self._get_binding_for(value) + except: # noqa: E722 + self.validate_failed(object, name, value) + + if isinstance(self.aClass, str): + self.resolve_class(object, name, value) + + if isinstance(value, Binding) and ( + (self.aClass is None) or isinstance(value.obj, self.aClass) + ): + return value.namespace_name + self.validate_failed(object, name, value)
+ +
[docs] def info(self): + aClass = self.aClass + if aClass is None: + result = "path" + else: + if type(aClass) is not str: + aClass = aClass.__name__ + result = "path to an instance of " + class_of(aClass) + if self.or_none is None: + return result + " or an empty string" + return result
+ +
[docs] def validate_failed(self, object, name, value): + if not isinstance(value, type): + msg = "class %s" % value.__class__.__name__ + else: + msg = "%s (i.e. %s)" % (str(type(value))[1:-1], repr(value)) + self.error(object, name, msg)
+ +
[docs] def get_editor(self, trait): + if self.editor is None: + from traitsui.api import DropEditor + + self.editor = DropEditor( + klass=self.aClass, binding=True, readonly=False + ) + return self.editor
+ +
[docs] def post_setattr(self, object, name, value): + other = None + if value != "": + other = self._get_binding_for(value).obj + object.__dict__[name + "_"] = other
+ + def _get_binding_for(self, value): + + result = None + + # FIXME: The following code makes this whole component have a + # dependency on envisage, and worse, assumes the use of a particular + # project plugin! This is horrible and should be refactored out, + # possibly to a custom sub-class of whoever needs this behavior. + try: + from envisage import get_application + + workspace = get_application().service_registry.get_service( + "envisage.project.IWorkspace" + ) + result = workspace.lookup_binding(value) + except ImportError: + pass + + return result + +
[docs] def resolve_class(self, object, name, value): + aClass = self.find_class() + if aClass is None: + self.validate_failed(object, name, value) + self.aClass = aClass + + # fixme: The following is quite ugly, because it wants to try and fix + # the trait referencing this handler to use the 'fast path' now that + # the actual class has been resolved. The problem is finding the trait, + # especially in the case of List(Instance('foo')), where the + # object.base_trait(...) value is the List trait, not the Instance + # trait, so we need to check for this and pull out the List + # 'item_trait'. Obviously this does not extend well to other traits + # containing nested trait references (Dict?)... + trait = object.base_trait(name) + handler = trait.handler + if (handler is not self) and hasattr(handler, "item_trait"): + trait = handler.item_trait + trait.validate(self.fast_validate)
+ +
[docs] def find_class(self): + module = self.module + aClass = self.aClass + col = aClass.rfind(".") + if col >= 0: + module = aClass[:col] + aClass = aClass[col + 1:] + theClass = getattr(sys.modules.get(module), aClass, None) + if (theClass is None) and (col >= 0): + try: + theClass = getattr(__import__(module), aClass, None) + except Exception: + pass + return theClass
+
+ +
+
+
+
+
+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/5.0/_modules/apptools/naming/unique_name.html b/5.0/_modules/apptools/naming/unique_name.html new file mode 100644 index 000000000..e33f1657a --- /dev/null +++ b/5.0/_modules/apptools/naming/unique_name.html @@ -0,0 +1,164 @@ + + + + + + + apptools.naming.unique_name — Apptools Documentation + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +

Source code for apptools.naming.unique_name

+# (C) Copyright 2005-2020 Enthought, Inc., Austin, TX
+# All rights reserved.
+#
+# This software is provided without warranty under the terms of the BSD
+# license included in LICENSE.txt and may be redistributed only under
+# the conditions described in the aforementioned license. The license
+# is also available online at http://www.enthought.com/licenses/BSD.txt
+#
+# Thanks for using Enthought open source!
+
+
+"""
+A re-usable method for calculating a unique name given a list of existing
+names.
+
+"""
+
+
+
[docs]def make_unique_name(base, existing=[], format="%s_%s"): + """ + Return a name, unique within a context, based on the specified name. + + base: the desired base name of the generated unique name. + existing: a sequence of the existing names to avoid returning. + format: a formatting specification for how the name is made unique. + + """ + + count = 2 + name = base + while name in existing: + name = format % (base, count) + count += 1 + + return name
+
+ +
+
+
+
+
+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/5.0/_modules/apptools/persistence/file_path.html b/5.0/_modules/apptools/persistence/file_path.html new file mode 100644 index 000000000..2391cf819 --- /dev/null +++ b/5.0/_modules/apptools/persistence/file_path.html @@ -0,0 +1,218 @@ + + + + + + + apptools.persistence.file_path — Apptools Documentation + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +

Source code for apptools.persistence.file_path

+# (C) Copyright 2005-2020 Enthought, Inc., Austin, TX
+# All rights reserved.
+#
+# This software is provided without warranty under the terms of the BSD
+# license included in LICENSE.txt and may be redistributed only under
+# the conditions described in the aforementioned license. The license
+# is also available online at http://www.enthought.com/licenses/BSD.txt
+#
+# Thanks for using Enthought open source!
+"""Simple class to support file path objects that work well in the
+context of persistent storage with the state_pickler.
+
+"""
+
+# Standard library imports.
+import os
+from os.path import abspath, normpath, dirname, join
+
+
+
[docs]class FilePath(object): + """This class stores two paths to the file. A relative path and + an absolute one. The absolute path is used by the end user. When + this object is pickled the state_pickler sets the relative path + relative to the file that is being generated. When unpickled, the + stored relative path is used to set the absolute path correctly + based on the path of the saved file. + """ + + def __init__(self, value=""): + self.set(value) + + def __str__(self): + return self.abs_pth + + def __repr__(self): + return self.abs_pth.__repr__() + +
[docs] def get(self): + """Get the path.""" + return self.abs_pth
+ +
[docs] def set(self, value): + """Sets the value of the path.""" + self.rel_pth = value + if value: + self.abs_pth = normpath(abspath(value)) + else: + self.abs_pth = ""
+ +
[docs] def set_relative(self, base_f_name): + """Sets the path relative to `base_f_name`. Note that + `base_f_name` and self.rel_pth should be valid file names + correct on the current os. The set name is a file name that + has a POSIX path. + """ + + # Get normalized paths. + _src = abspath(base_f_name) + _dst = self.abs_pth + + # Now strip out any common prefix between the two paths. + for part in _src.split(os.sep): + if _dst.startswith(part + os.sep): + length = len(part) + 1 + _src = _src[length:] + _dst = _dst[length:] + else: + break + + # For each directory in the source, we need to add a reference to + # the parent directory to the destination. + ret = (_src.count(os.sep) * (".." + os.sep)) + _dst + + # Make it posix style. + if os.sep != "/": + ret.replace(os.sep, "/") + + # Store it. + self.rel_pth = ret
+ +
[docs] def set_absolute(self, base_f_name): + """Sets the absolute file name for the current relative file + name with respect to the given `base_f_name`. + """ + base_f_name = normpath(abspath(base_f_name)) + rel_file_name = normpath(self.rel_pth) + file_name = join(dirname(base_f_name), rel_file_name) + file_name = os.path.normpath(file_name) + self.abs_pth = file_name
+
+ +
+
+
+
+
+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/5.0/_modules/apptools/persistence/project_loader.html b/5.0/_modules/apptools/persistence/project_loader.html new file mode 100644 index 000000000..75559d5eb --- /dev/null +++ b/5.0/_modules/apptools/persistence/project_loader.html @@ -0,0 +1,262 @@ + + + + + + + apptools.persistence.project_loader — Apptools Documentation + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +

Source code for apptools.persistence.project_loader

+# (C) Copyright 2005-2020 Enthought, Inc., Austin, TX
+# All rights reserved.
+#
+# This software is provided without warranty under the terms of the BSD
+# license included in LICENSE.txt and may be redistributed only under
+# the conditions described in the aforementioned license. The license
+# is also available online at http://www.enthought.com/licenses/BSD.txt
+#
+# Thanks for using Enthought open source!
+# Standard library imports
+import sys
+import pickle
+import logging
+
+# Enthought library imports
+from apptools.persistence.versioned_unpickler import VersionedUnpickler
+
+
+logger = logging.getLogger(__name__)
+
+
+
[docs]def load_project( + pickle_filename, updater_path, application_version, protocol, max_pass=-1 +): + """Reads a project from a pickle file and if necessary will update it to + the latest version of the application. + """ + + latest_file = pickle_filename + + # Read the pickled project's metadata. + f = open(latest_file, "rb") + metadata = VersionedUnpickler(f).load(max_pass) + f.close() + project_version = metadata.get("version", False) + + if not project_version: + raise ValueError("Could not read version number from the project file") + + logger.debug( + "Project version: %d, Application version: %d" + % (project_version, application_version) + ) + + # here you can temporarily force an upgrade each time for testing .... + # project_version = 0 + latest_file = upgrade_project( + pickle_filename, + updater_path, + project_version, + application_version, + protocol, + max_pass, + ) + + # Finally we can import the project ... + logger.info("loading %s" % latest_file) + i_f = open(latest_file, "rb") + project = VersionedUnpickler(i_f).load(max_pass) + i_f.close() + + return project
+ + +
[docs]def upgrade_project( + pickle_filename, + updater_path, + project_version, + application_version, + protocol, + max_pass=-1, +): + """Repeatedly read and write the project to disk updating it one version + at a time. + + Example the p5.project is at version 0 + The application is at version 3 + + p5.project --- Update1 ---> p5.project.v1 + p5.project.v1 --- Update2 ---> p5.project.v2 + p5.project.v2 --- Update3 ---> p5.project.v3 + p5.project.v3 ---> loaded into app + + The user then has the option to save the updated project as p5.project + """ + first_time = True + latest_file = pickle_filename + + # update the project until it's version matches the application's + while project_version < application_version: + + next_version = project_version + 1 + + if first_time: + i_f = open(pickle_filename, "rb") + data = i_f.read() + open("%s.bak" % pickle_filename, "wb").write(data) + i_f.seek(0) # rewind the file to the start + else: + name = "%s.v%d" % (pickle_filename, project_version) + i_f = open(name, "rb") + latest_file = name + + logger.info("converting %s" % latest_file) + + # find this version's updater ... + updater_name = "%s.update%d" % (updater_path, next_version) + __import__(updater_name) + mod = sys.modules[updater_name] + klass = getattr(mod, "Update%d" % next_version) + updater = klass() + + # load and update this version of the project + project = VersionedUnpickler(i_f, updater).load(max_pass) + i_f.close() + + # set the project version to be the same as the updater we just + # ran on the unpickled files ... + project.metadata["version"] = next_version + + # Persist the updated project ... + name = "%s.v%d" % (pickle_filename, next_version) + latest_file = name + o_f = open(name, "wb") + pickle.dump(project.metadata, o_f, protocol=protocol) + pickle.dump(project, o_f, protocol=protocol) + o_f.close() + + # Bump up the version number of the pickled project... + project_version += 1 + first_time = False + + return latest_file
+
+ +
+
+
+
+
+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/5.0/_modules/apptools/persistence/state_pickler.html b/5.0/_modules/apptools/persistence/state_pickler.html new file mode 100644 index 000000000..21a0effe1 --- /dev/null +++ b/5.0/_modules/apptools/persistence/state_pickler.html @@ -0,0 +1,1168 @@ + + + + + + + apptools.persistence.state_pickler — Apptools Documentation + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +

Source code for apptools.persistence.state_pickler

+# (C) Copyright 2005-2020 Enthought, Inc., Austin, TX
+# All rights reserved.
+#
+# This software is provided without warranty under the terms of the BSD
+# license included in LICENSE.txt and may be redistributed only under
+# the conditions described in the aforementioned license. The license
+# is also available online at http://www.enthought.com/licenses/BSD.txt
+#
+# Thanks for using Enthought open source!
+"""This module provides code that allows one to pickle the state of a
+Python object to a dictionary.
+
+The motivation for this is simple.  The standard Python
+pickler/unpickler is best used to pickle simple objects and does not
+work too well for complex code.  Specifically, there are two major
+problems (1) the pickle file format is not easy to edit with a text
+editor and (2) when a pickle is unpickled, it creates all the
+necessary objects and sets the state of these objects.
+
+Issue (2) might not appear to be a problem.  However, often, the
+determination of the entire 'state' of an application requires the
+knowledge of the state of many objects that are not really in the
+users concern.  The user would ideally like to pickle just what he
+thinks is relevant.  Now, given that the user is not going to save the
+entire state of the application, the use of pickle is insufficient
+since the state is no longer completely known (or worth knowing).  The
+default `Unpickler` recreates the objects and the typical
+implementation of `__setstate__` is usually to simply update the
+object's `__dict__` attribute.  This is inadequate because the pickled
+information is taken out of the real context when it was saved.
+
+The `StatePickler` basically pickles the 'state' of an object into a
+large dictionary.  This pickled data may be easily unpickled and
+modified on the interpreter or edited with a text editor
+(`pprint.saferepr` is a friend).  The second problem is also
+eliminated.  When this state is unpickled using `StateUnpickler`, what
+you get is a special dictionary (a `State` instance).  This allows one
+to navigate the state just like the original object.  Its up to the
+user to create any new objects and set their states using this
+information.  This allows for a lot of flexibility while allowing one
+to save and set the state of (almost) any Python object.
+
+The `StateSetter` class helps set the state of a known instance.  When
+setting the state of an instance it checks to see if there is a
+`__set_pure_state__` method that in turn calls `StateSetter.set`
+appropriately.
+
+Additionally, there is support for versioning.  The class' version is
+obtain from the `__version__` class attribute.  This version along
+with the versions of the bases of a class is embedded into the
+metadata of the state and stored.  By using `version_registry.py` a
+user may register a handler for a particular class and module.  When
+the state of an object is set using `StateSetter.set_state`, then
+these handlers are called in reverse order of their MRO.  This gives
+the handler an opportunity to upgrade the state depending on its
+version.  Builtin classes are not scanned for versions.  If a class
+has no version, then by default it is assumed to be -1.
+
+
+Example::
+
+  >>> class A:
+  ...    def __init__(self):
+  ...        self.a = 'a'
+  ...
+  >>> a = A()
+  >>> a.a = 100
+  >>> import state_pickler
+  >>> s = state_pickler.dumps(a)               # Dump the state of `a`.
+  >>> state = state_pickler.loads_state(s)     # Get the state back.
+  >>> b = state_pickler.create_instance(state) # Create the object.
+  >>> state_pickler.set_state(b, state)        # Set the object's state.
+  >>> assert b.a == 100
+
+
+Features
+--------
+
+ - The output is a plain old dictionary so is easy to parse, edit etc.
+ - Handles references to avoid duplication.
+ - Gzips Numeric arrays when dumping them.
+ - Support for versioning.
+
+
+Caveats
+-------
+
+ - Does not pickle a whole bunch of stuff including code objects and
+   functions.
+ - The output is a pure dictionary and does not contain instances.  So
+   using this *as it is* in `__setstate__` will not work.  Instead
+   define a `__set_pure_state__` and use the `StateSetter` class or
+   the `set_state` function provided by this module.
+
+
+Notes
+-----
+
+  Browsing the code from XMarshaL_ and pickle.py proved useful for
+  ideas.  None of the code is taken from there though.
+
+.. _XMarshaL:  http://www.dezentral.de/soft/XMarshaL
+
+"""
+# Author: Prabhu Ramachandran <prabhu_r@users.sf.net>
+# Copyright (c) 2005-2015, Enthought, Inc.
+# License: BSD Style.
+
+# Standard library imports.
+import base64
+import sys
+import pickle
+import gzip
+from io import BytesIO, StringIO
+
+import numpy
+
+# Local imports.
+from . import version_registry
+from .file_path import FilePath
+
+NumpyArrayType = type(numpy.array([]))
+
+
+
[docs]def gzip_string(data): + """Given a string (`data`) this gzips the string and returns it.""" + s = BytesIO() + writer = gzip.GzipFile(mode="wb", fileobj=s) + writer.write(data) + writer.close() + s.seek(0) + return s.read()
+ + +
[docs]def gunzip_string(data): + """Given a gzipped string (`data`) this unzips the string and + returns it. + """ + if type(data) is bytes: + s = BytesIO(data) + else: + s = StringIO(data) + writer = gzip.GzipFile(mode="rb", fileobj=s) + data = writer.read() + writer.close() + return data
+ + +
[docs]class StatePicklerError(Exception): + pass
+ + +
[docs]class StateUnpicklerError(Exception): + pass
+ + +
[docs]class StateSetterError(Exception): + pass
+ + +###################################################################### +# `State` class +###################################################################### +
[docs]class State(dict): + """Used to encapsulate the state of an instance in a very + convenient form. The '__metadata__' attribute/key is a dictionary + that has class specific details like the class name, module name + etc. + """ + + def __init__(self, **kw): + dict.__init__(self, **kw) + self.__dict__ = self
+ + +###################################################################### +# `StateDict` class +###################################################################### +
[docs]class StateDict(dict): + """Used to encapsulate a dictionary stored in a `State` instance. + The has_instance attribute specifies if the dict has an instance + embedded in it. + """ + + def __init__(self, **kw): + dict.__init__(self, **kw) + self.has_instance = False
+ + +###################################################################### +# `StateList` class +###################################################################### +
[docs]class StateList(list): + """Used to encapsulate a list stored in a `State` instance. The + has_instance attribute specifies if the list has an instance + embedded in it. + """ + + def __init__(self, seq=None): + if seq: + list.__init__(self, seq) + else: + list.__init__(self) + self.has_instance = False
+ + +###################################################################### +# `StateTuple` class +###################################################################### +
[docs]class StateTuple(tuple): + """Used to encapsulate a tuple stored in a `State` instance. The + has_instance attribute specifies if the tuple has an instance + embedded in it. + """ + + def __new__(cls, seq=None): + if seq: + obj = super(StateTuple, cls).__new__(cls, tuple(seq)) + else: + obj = super(StateTuple, cls).__new__(cls) + obj.has_instance = False + return obj
+ + +###################################################################### +# `StatePickler` class +###################################################################### +
[docs]class StatePickler: + """Pickles the state of an object into a dictionary. The + dictionary is itself either saved as a pickled file (`dump`) or + pickled string (`dumps`). Alternatively, the `dump_state` method + will return the dictionary that is pickled. + + The format of the state dict is quite strightfoward. Basic types + (bool, int, long, float, complex, None, string) are + represented as they are. Everything else is stored as a + dictionary containing metadata information on the object's type + etc. and also the actual object in the 'data' key. For example:: + + >>> p = StatePickler() + >>> p.dump_state(1) + 1 + >>> l = [1,2.0, None, [1,2,3]] + >>> p.dump_state(l) + {'data': [1, 2.0, None, {'data': [1, 2, 3], 'type': 'list', 'id': 1}], + 'id': 0, + 'type': 'list'} + + Classes are also represented similarly. The state in this case is + obtained from the `__getstate__` method or from the `__dict__`. + Here is an example:: + + >>> class A: + ... __version__ = 1 # State version + ... def __init__(self): + ... self.attribute = 1 + ... + >>> a = A() + >>> p = StatePickler() + >>> p.dump_state(a) + {'class_name': 'A', + 'data': {'data': {'attribute': 1}, 'type': 'dict', 'id': 2}, + 'id': 0, + 'initargs': {'data': (), 'type': 'tuple', 'id': 1}, + 'module': '__main__', + 'type': 'instance', + 'version': [(('A', '__main__'), 1)]} + + When pickling data, references are taken care of. Numeric arrays + can be pickled and are stored as a gzipped base64 encoded string. + + """ + + def __init__(self): + self._clear() + type_map = { + bool: self._do_basic_type, + complex: self._do_basic_type, + float: self._do_basic_type, + int: self._do_basic_type, + type(None): self._do_basic_type, + str: self._do_basic_type, + bytes: self._do_basic_type, + tuple: self._do_tuple, + list: self._do_list, + dict: self._do_dict, + NumpyArrayType: self._do_numeric, + State: self._do_state, + } + self.type_map = type_map + +
[docs] def dump(self, value, file): + """Pickles the state of the object (`value`) into the passed + file. + """ + try: + # Store the file name we are writing to so we can munge + # file paths suitably. + self.file_name = file.name + except AttributeError: + pass + pickle.dump(self._do(value), file)
+ +
[docs] def dumps(self, value): + """Pickles the state of the object (`value`) and returns a + string. + """ + return pickle.dumps(self._do(value))
+ +
[docs] def dump_state(self, value): + """Returns a dictionary or a basic type representing the + complete state of the object (`value`). + + This value is pickled by the `dump` and `dumps` methods. + """ + return self._do(value)
+ + ###################################################################### + # Non-public methods + ###################################################################### + def _clear(self): + # Stores the file name of the file being used to dump the + # state. This is used to change any embedded paths relative + # to the saved file. + self.file_name = "" + # Caches id's to handle references. + self.obj_cache = {} + # Misc cache to cache things that are not persistent. For + # example, object.__getstate__()/__getinitargs__() usually + # returns a copy of a dict/tuple that could possibly be reused + # on another object's __getstate__. Caching these prevents + # some wierd problems with the `id` of the object. + self._misc_cache = [] + + def _flush_traits(self, obj): + """Checks if the object has traits and ensures that the traits + are set in the `__dict__` so we can pickle it. + """ + # Not needed with Traits3. + + def _do(self, obj): + obj_type = type(obj) + key = self._get_id(obj) + if key in self.obj_cache: + return self._do_reference(obj) + elif obj_type in self.type_map: + return self.type_map[obj_type](obj) + elif isinstance(obj, tuple): + # Takes care of StateTuples. + return self._do_tuple(obj) + elif isinstance(obj, list): + # Takes care of TraitListObjects. + return self._do_list(obj) + elif isinstance(obj, dict): + # Takes care of TraitDictObjects. + return self._do_dict(obj) + elif hasattr(obj, "__dict__"): + return self._do_instance(obj) + + def _get_id(self, value): + try: + key = hash(value) + except TypeError: + key = id(value) + return key + + def _register(self, value): + key = self._get_id(value) + cache = self.obj_cache + idx = len(cache) + cache[key] = idx + return idx + + def _do_basic_type(self, value): + return value + + def _do_reference(self, value): + key = self._get_id(value) + idx = self.obj_cache[key] + return dict(type="reference", id=idx, data=None) + + def _do_instance(self, value): + # Flush out the traits. + self._flush_traits(value) + + # Setup the relative paths of FilePaths before dumping. + if self.file_name and isinstance(value, FilePath): + value.set_relative(self.file_name) + + # Get the initargs. + args = () + if hasattr(value, "__getinitargs__") and value.__getinitargs__: + args = value.__getinitargs__() + + # Get the object state. + if hasattr(value, "__get_pure_state__"): + state = value.__get_pure_state__() + elif hasattr(value, "__getstate__"): + state = value.__getstate__() + else: + state = value.__dict__ + + state.pop("__traits_version__", None) + + # Cache the args and state since they are likely to be gc'd. + self._misc_cache.extend([args, state]) + # Register and process. + idx = self._register(value) + args_data = self._do(args) + data = self._do(state) + + # Get the version of the object. + version = version_registry.get_version(value) + module = value.__class__.__module__ + class_name = value.__class__.__name__ + + return dict( + type="instance", + module=module, + class_name=class_name, + version=version, + id=idx, + initargs=args_data, + data=data, + ) + + def _do_state(self, value): + metadata = value.__metadata__ + args = metadata.get("initargs") + state = dict(value) + state.pop("__metadata__") + + self._misc_cache.extend([args, state]) + + idx = self._register(value) + args_data = self._do(args) + data = self._do(state) + + return dict( + type="instance", + module=metadata["module"], + class_name=metadata["class_name"], + version=metadata["version"], + id=idx, + initargs=args_data, + data=data, + ) + + def _do_tuple(self, value): + idx = self._register(value) + data = tuple([self._do(x) for x in value]) + return dict(type="tuple", id=idx, data=data) + + def _do_list(self, value): + idx = self._register(value) + data = [self._do(x) for x in value] + return dict(type="list", id=idx, data=data) + + def _do_dict(self, value): + idx = self._register(value) + vals = [self._do(x) for x in value.values()] + data = dict(zip(value.keys(), vals)) + return dict(type="dict", id=idx, data=data) + + def _do_numeric(self, value): + idx = self._register(value) + data = base64.encodebytes(gzip_string(numpy.ndarray.dumps(value))) + return dict(type="numeric", id=idx, data=data)
+ + +###################################################################### +# `StateUnpickler` class +###################################################################### +
[docs]class StateUnpickler: + """Unpickles the state of an object saved using StatePickler. + + Please note that unlike the standard Unpickler, no instances of + any user class are created. The data for the state is obtained + from the file or string, reference objects are setup to refer to + the same state value and this state is returned in the form + usually in the form of a dictionary. For example:: + + >>> class A: + ... def __init__(self): + ... self.attribute = 1 + ... + >>> a = A() + >>> p = StatePickler() + >>> s = p.dumps(a) + >>> up = StateUnpickler() + >>> state = up.loads_state(s) + >>> state.__class__.__name__ + 'State' + >>> state.attribute + 1 + >>> state.__metadata__ + {'class_name': 'A', + 'has_instance': True, + 'id': 0, + 'initargs': (), + 'module': '__main__', + 'type': 'instance', + 'version': [(('A', '__main__'), -1)]} + + Note that the state is actually a `State` instance and is + navigable just like the original object. The details of the + instance are stored in the `__metadata__` attribute. This is + highly convenient since it is possible for someone to view and + modify the state very easily. + """ + + def __init__(self): + self._clear() + self.type_map = { + "reference": self._do_reference, + "instance": self._do_instance, + "tuple": self._do_tuple, + "list": self._do_list, + "dict": self._do_dict, + "numeric": self._do_numeric, + } + +
[docs] def load_state(self, file): + """Returns the state of an object loaded from the pickled data + in the given file. + """ + try: + self.file_name = file.name + except AttributeError: + pass + data = pickle.load(file) + result = self._process(data) + return result
+ +
[docs] def loads_state(self, string): + """Returns the state of an object loaded from the pickled data + in the given string. + """ + data = pickle.loads(string) + result = self._process(data) + return result
+ + ###################################################################### + # Non-public methods + ###################################################################### + def _clear(self): + # The file from which we are being loaded. + self.file_name = "" + # Cache of the objects. + self._obj_cache = {} + # Paths to the instances. + self._instances = [] + # Caches the references. + self._refs = {} + # Numeric arrays. + self._numeric = {} + + def _set_has_instance(self, obj, value): + if isinstance(obj, State): + obj.__metadata__["has_instance"] = value + elif isinstance(obj, (StateDict, StateList, StateTuple)): + obj.has_instance = value + + def _process(self, data): + result = self._do(data) + + # Setup all the Numeric arrays. Do this first since + # references use this. + for key, (path, val) in self._numeric.items(): + if isinstance(result, StateTuple): + result = list(result) + exec("result%s = val" % path) + result = StateTuple(result) + else: + exec("result%s = val" % path) + + # Setup the references so they really are references. + for key, paths in self._refs.items(): + for path in paths: + x = self._obj_cache[key] + if isinstance(result, StateTuple): + result = list(result) + exec("result%s = x" % path) + result = StateTuple(result) + else: + exec("result%s = x" % path) + # if the reference is to an instance append its path. + if isinstance(x, State): + self._instances.append(path) + + # Now setup the 'has_instance' attribute. If 'has_instance' + # is True then the object contains an instance somewhere + # inside it. + for path in self._instances: + pth = path + while pth: + ns = {"result": result} + exec("val = result%s" % pth, ns, ns) + self._set_has_instance(ns["val"], True) + end = pth.rfind("[") + pth = pth[:end] + # Now make sure that the first element also has_instance. + self._set_has_instance(result, True) + return result + + def _do(self, data, path=""): + if type(data) is dict: + return self.type_map[data["type"]](data, path) + else: + return data + + def _do_reference(self, value, path): + id = value["id"] + if id in self._refs: + self._refs[id].append(path) + else: + self._refs[id] = [path] + return State(__metadata__=value) + + def _handle_file_path(self, value): + if ( + (value["class_name"] == "FilePath") + and ("file_path" in value["module"]) + and self.file_name + ): + data = value["data"]["data"] + fp = FilePath(data["rel_pth"]) + fp.set_absolute(self.file_name) + data["abs_pth"] = fp.abs_pth + + def _do_instance(self, value, path): + self._instances.append(path) + initargs = self._do( + value["initargs"], path + '.__metadata__["initargs"]' + ) + # Handle FilePaths. + self._handle_file_path(value) + + d = self._do(value["data"], path) + md = dict( + type="instance", + module=value["module"], + class_name=value["class_name"], + version=value["version"], + id=value["id"], + initargs=initargs, + has_instance=True, + ) + result = State(**d) + result.__metadata__ = md + self._obj_cache[value["id"]] = result + return result + + def _do_tuple(self, value, path): + res = [] + for i, x in enumerate(value["data"]): + res.append(self._do(x, path + "[%d]" % i)) + result = StateTuple(res) + self._obj_cache[value["id"]] = result + return result + + def _do_list(self, value, path): + result = StateList() + for i, x in enumerate(value["data"]): + result.append(self._do(x, path + "[%d]" % i)) + self._obj_cache[value["id"]] = result + return result + + def _do_dict(self, value, path): + result = StateDict() + for key, val in value["data"].items(): + result[key] = self._do(val, path + '["%s"]' % key) + self._obj_cache[value["id"]] = result + return result + + def _do_numeric(self, value, path): + data = value["data"] + if isinstance(data, str): + data = value["data"].encode("utf-8") + junk = gunzip_string(base64.decodebytes(data)) + result = pickle.loads(junk, encoding="bytes") + self._numeric[value["id"]] = (path, result) + self._obj_cache[value["id"]] = result + return result
+ + +###################################################################### +# `StateSetter` class +###################################################################### +
[docs]class StateSetter: + """This is a convenience class that helps a user set the + attributes of an object given its saved state. For instances it + checks to see if a `__set_pure_state__` method exists and calls + that when it sets the state. + """ + + def __init__(self): + # Stores the ids of instances already done. + self._instance_ids = [] + self.type_map = { + State: self._do_instance, + StateTuple: self._do_tuple, + StateList: self._do_list, + StateDict: self._do_dict, + } + +
[docs] def set(self, obj, state, ignore=None, first=None, last=None): + """Sets the state of the object. + + This is to be used as a means to simplify loading the state of + an object from its `__setstate__` method using the dictionary + describing its state. Note that before the state is set, the + registered handlers for the particular class are called in + order to upgrade the version of the state to the latest + version. + + Parameters + ---------- + + - obj : `object` + + The object whose state is to be set. If this is `None` + (default) then the object is created. + + - state : `dict` + + The dictionary representing the state of the object. + + - ignore : `list(str)` + + The list of attributes specified in this list are ignored + and the state of these attributes are not set (this excludes + the ones specified in `first` and `last`). If one specifies + a '*' then all attributes are ignored except the ones + specified in `first` and `last`. + + - first : `list(str)` + + The list of attributes specified in this list are set first (in + order), before any other attributes are set. + + - last : `list(str)` + + The list of attributes specified in this list are set last (in + order), after all other attributes are set. + + """ + if (not isinstance(state, State)) and state.__metadata__[ + "type" + ] != "instance": + raise StateSetterError( + "Can only set the attributes of an instance." + ) + + # Upgrade the state to the latest using the registry. + self._update_and_check_state(obj, state) + + self._register(obj) + + # This wierdness is needed since the state's own `keys` might + # be set to something else. + state_keys = list(dict.keys(state)) + state_keys.remove("__metadata__") + + if first is None: + first = [] + if last is None: + last = [] + + # Remove all the ignored keys. + if ignore: + if "*" in ignore: + state_keys = first + last + else: + for name in ignore: + try: + state_keys.remove(name) + except KeyError: + pass + + # Do the `first` attributes. + for key in first: + state_keys.remove(key) + self._do(obj, key, state[key]) + + # Remove the `last` attributes. + for key in last: + state_keys.remove(key) + + # Set the remaining attributes. + for key in state_keys: + self._do(obj, key, state[key]) + + # Do the last ones in order. + for key in last: + self._do(obj, key, state[key])
+ + ###################################################################### + # Non-public methods. + ###################################################################### + def _register(self, obj): + idx = id(obj) + if idx not in self._instance_ids: + self._instance_ids.append(idx) + + def _is_registered(self, obj): + return id(obj) in self._instance_ids + + def _has_instance(self, value): + """Given something (`value`) that is part of the state this + returns if the value has an instance embedded in it or not. + """ + if isinstance(value, State): + return True + elif isinstance(value, (StateDict, StateList, StateTuple)): + return value.has_instance + return False + + def _get_pure(self, value): + """Returns the Python representation of the object (usually a + list, tuple or dict) that has no instances embedded within it. + """ + result = value + if self._has_instance(value): + raise StateSetterError("Value has an instance: %s" % value) + if isinstance(value, (StateList, StateTuple)): + result = [self._get_pure(x) for x in value] + if isinstance(value, StateTuple): + result = tuple(result) + elif isinstance(value, StateDict): + result = {} + for k, v in value.items(): + result[k] = self._get_pure(v) + return result + + def _update_and_check_state(self, obj, state): + """Updates the state from the registry and then checks if the + object and state have same class. + """ + # Upgrade this state object to the latest using the registry. + # This is done before testing because updating may change the + # class name/module. + version_registry.registry.update(state) + + # Make sure object and state have the same class and module names. + metadata = state.__metadata__ + cls = obj.__class__ + if metadata["class_name"] != cls.__name__: + raise StateSetterError( + "Instance (%s) and state (%s) do not have the same class" + " name!" % (cls.__name__, metadata["class_name"]) + ) + if metadata["module"] != cls.__module__: + raise StateSetterError( + "Instance (%s) and state (%s) do not have the same module" + " name!" % (cls.__module__, metadata["module"]) + ) + + def _do(self, obj, key, value): + try: + getattr(obj, key) + except AttributeError: + raise StateSetterError( + "Object %s does not have an attribute called: %s" % (obj, key) + ) + + if isinstance(value, (State, StateDict, StateList, StateTuple)): + # Special handlers are needed. + if not self._has_instance(value): + result = self._get_pure(value) + setattr(obj, key, result) + elif isinstance(value, StateTuple): + setattr(obj, key, self._do_tuple(getattr(obj, key), value)) + else: + self._do_object(getattr(obj, key), value) + else: + setattr(obj, key, value) + + def _do_object(self, obj, state): + self.type_map[state.__class__](obj, state) + + def _do_instance(self, obj, state): + if self._is_registered(obj): + return + else: + self._register(obj) + + metadata = state.__metadata__ + if hasattr(obj, "__set_pure_state__"): + self._update_and_check_state(obj, state) + obj.__set_pure_state__(state) + elif "tvtk_classes" in metadata["module"]: + self._update_and_check_state(obj, state) + tmp = self._get_pure(StateDict(**state)) + del tmp["__metadata__"] + obj.__setstate__(tmp) + else: + # No need to update or check since `set` does it for us. + self.set(obj, state) + + def _do_tuple(self, obj, state): + if not self._has_instance(state): + return self._get_pure(state) + else: + result = list(obj) + self._do_list(result, state) + return tuple(result) + + def _do_list(self, obj, state): + if len(obj) == len(state): + for i in range(len(obj)): + if not self._has_instance(state[i]): + obj[i] = self._get_pure(state[i]) + elif isinstance(state[i], tuple): + obj[i] = self._do_tuple(state[i]) + else: + self._do_object(obj[i], state[i]) + else: + raise StateSetterError( + "Cannot set state of list of incorrect size." + ) + + def _do_dict(self, obj, state): + for key, value in state.items(): + if not self._has_instance(value): + obj[key] = self._get_pure(value) + elif isinstance(value, tuple): + obj[key] = self._do_tuple(value) + else: + self._do_object(obj[key], value)
+ + +###################################################################### +# Internal Utility functions. +###################################################################### +def _get_file_read(f): + if hasattr(f, "read"): + return f + else: + return open(f, "rb") + + +def _get_file_write(f): + if hasattr(f, "write"): + return f + else: + return open(f, "wb") + + +###################################################################### +# Utility functions. +###################################################################### +
[docs]def dump(value, file): + """Pickles the state of the object (`value`) into the passed file + (or file name). + """ + f = _get_file_write(file) + try: + StatePickler().dump(value, f) + finally: + f.flush() + if f is not file: + f.close()
+ + +
[docs]def dumps(value): + """Pickles the state of the object (`value`) and returns a string.""" + return StatePickler().dumps(value)
+ + +
[docs]def load_state(file): + """Returns the state of an object loaded from the pickled data in + the given file (or file name). + """ + f = _get_file_read(file) + try: + state = StateUnpickler().load_state(f) + finally: + if f is not file: + f.close() + return state
+ + +
[docs]def loads_state(string): + """Returns the state of an object loaded from the pickled data + in the given string. + """ + return StateUnpickler().loads_state(string)
+ + +
[docs]def get_state(obj): + """Returns the state of the object (usually as a dictionary). The + returned state may be used directy to set the state of the object + via `set_state`. + """ + s = dumps(obj) + return loads_state(s)
+ + +
[docs]def set_state(obj, state, ignore=None, first=None, last=None): + StateSetter().set(obj, state, ignore, first, last)
+ + +set_state.__doc__ = StateSetter.set.__doc__ + + +
[docs]def update_state(state): + """Given the state of an object, this updates the state to the + latest version using the handlers given in the version registry. + The state is modified in-place. + """ + version_registry.registry.update(state)
+ + +
[docs]def create_instance(state): + """Create an instance from the state if possible.""" + if (not isinstance(state, State)) and ( + "class_name" not in state.__metadata__ + ): + raise StateSetterError("No class information in state") + metadata = state.__metadata__ + class_name = metadata.get("class_name") + mod_name = metadata.get("module") + if "tvtk_classes" in mod_name: + # FIXME: This sort of special-case is probably indicative of something + # that needs more thought, plus it makes it tought to decide whether + # this component depends on tvtk! + from tvtk.api import tvtk + + return getattr(tvtk, class_name)() + + initargs = metadata["initargs"] + if initargs.has_instance: + raise StateUnpicklerError("Cannot unpickle non-trivial initargs") + + __import__(mod_name, globals(), locals(), class_name) + mod = sys.modules[mod_name] + cls = getattr(mod, class_name) + return cls(*initargs)
+
+ +
+
+
+
+
+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/5.0/_modules/apptools/persistence/updater.html b/5.0/_modules/apptools/persistence/updater.html new file mode 100644 index 000000000..8d32271d2 --- /dev/null +++ b/5.0/_modules/apptools/persistence/updater.html @@ -0,0 +1,174 @@ + + + + + + + apptools.persistence.updater — Apptools Documentation + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +

Source code for apptools.persistence.updater

+# (C) Copyright 2005-2020 Enthought, Inc., Austin, TX
+# All rights reserved.
+#
+# This software is provided without warranty under the terms of the BSD
+# license included in LICENSE.txt and may be redistributed only under
+# the conditions described in the aforementioned license. The license
+# is also available online at http://www.enthought.com/licenses/BSD.txt
+#
+# Thanks for using Enthought open source!
+
+
+def __replacement_setstate__(self, state):
+    """"""
+    state = self.__updater__(state)
+    self.__dict__.update(state)
+
+
+
[docs]class Updater: + + """An abstract class to provide functionality common to the updaters.""" + +
[docs] def get_latest(self, module, name): + """The refactorings dictionary contains mappings between old and new + module names. Since we only bump the version number one increment + there is only one possible answer. + """ + if hasattr(self, "refactorings"): + module = self.strip(module) + name = self.strip(name) + # returns the new module and name if it exists otherwise defaults + # to using the original module and name + module, name = self.refactorings.get( + (module, name), (module, name) + ) + + return module, name
+ +
[docs] def strip(self, string): + # Who would have thought that pickle would pass us + # names with \013 on the end? Is this after the files have + # manually edited? + if ord(string[-1:]) == 13: + return string[:-1] + + return string
+
+ +
+
+
+
+
+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/5.0/_modules/apptools/persistence/version_registry.html b/5.0/_modules/apptools/persistence/version_registry.html new file mode 100644 index 000000000..040c4e8eb --- /dev/null +++ b/5.0/_modules/apptools/persistence/version_registry.html @@ -0,0 +1,239 @@ + + + + + + + apptools.persistence.version_registry — Apptools Documentation + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +

Source code for apptools.persistence.version_registry

+# (C) Copyright 2005-2020 Enthought, Inc., Austin, TX
+# All rights reserved.
+#
+# This software is provided without warranty under the terms of the BSD
+# license included in LICENSE.txt and may be redistributed only under
+# the conditions described in the aforementioned license. The license
+# is also available online at http://www.enthought.com/licenses/BSD.txt
+#
+# Thanks for using Enthought open source!
+"""A version registry that manages handlers for different state
+versions.
+"""
+
+
+# Standard library imports.
+import sys
+import inspect
+import logging
+
+
+logger = logging.getLogger(__name__)
+
+
+######################################################################
+# Utility functions.
+######################################################################
+
[docs]def get_version(obj): + """Walks the class hierarchy and obtains the versions of the + various classes and returns a list of tuples of the form + ((class_name, module), version) in reverse order of the MRO. + """ + res = [] + for cls in inspect.getmro(obj.__class__): + class_name, module = cls.__name__, cls.__module__ + if module in ["__builtin__"]: + # No point in versioning builtins. + continue + try: + version = cls.__version__ + except AttributeError: + version = -1 + res.append(((class_name, module), version)) + res.reverse() + return res
+ + +###################################################################### +# `HandlerRegistry` class. +###################################################################### +
[docs]class HandlerRegistry: + """A simple version conversion handler registry. Classes register + handlers in order to convert the state version to the latest + version. When an object's state is about to be set, the `update` + method of the registy is called. This in turn calls any handlers + registered for the class/module and this handler is then called + with the state and the version of the state. The state is + modified in-place by the handlers. + """ + + def __init__(self): + # The version conversion handlers. + # Key: (class_name, module), value: handler + self.handlers = {} + +
[docs] def register(self, class_name, module, handler): + """Register `handler` that handles versioning for class having + class name (`class_name`) and module name (`module`). The + handler function will be passed the state and its version to fix. + """ + key = (class_name, module) + if key in self.handlers: + msg = "Overwriting version handler for (%s, %s)" % (key[0], key[1]) + logger.warn(msg) + self.handlers[(class_name, module)] = handler
+ +
[docs] def unregister(self, class_name, module): + """Unregisters any handlers for a class and module.""" + self.handlers.pop((class_name, module))
+ +
[docs] def update(self, state): + """Updates the given state using the handlers. Note that the + state is modified in-place. + """ + if (not self.handlers) or (not hasattr(state, "__metadata__")): + return + versions = state.__metadata__["version"] + for ver in versions: + key = ver[0] + try: + self.handlers[key](state, ver[1]) + except KeyError: + pass
+ + +def _create_registry(): + """Creates a reload safe, singleton registry.""" + registry = None + for key in sys.modules.keys(): + if "version_registry" in key: + mod = sys.modules[key] + if hasattr(mod, "registry"): + registry = mod.registry + break + if not registry: + registry = HandlerRegistry() + return registry + + +# The singleton registry. +registry = _create_registry() +
+ +
+
+
+
+
+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/5.0/_modules/apptools/persistence/versioned_unpickler.html b/5.0/_modules/apptools/persistence/versioned_unpickler.html new file mode 100644 index 000000000..667bf909c --- /dev/null +++ b/5.0/_modules/apptools/persistence/versioned_unpickler.html @@ -0,0 +1,342 @@ + + + + + + + apptools.persistence.versioned_unpickler — Apptools Documentation + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +

Source code for apptools.persistence.versioned_unpickler

+# (C) Copyright 2005-2020 Enthought, Inc., Austin, TX
+# All rights reserved.
+#
+# This software is provided without warranty under the terms of the BSD
+# license included in LICENSE.txt and may be redistributed only under
+# the conditions described in the aforementioned license. The license
+# is also available online at http://www.enthought.com/licenses/BSD.txt
+#
+# Thanks for using Enthought open source!
+# Standard library imports
+from pickle import _Unpickler as Unpickler
+from pickle import UnpicklingError, BUILD
+import logging
+from types import GeneratorType
+
+# Enthought library imports
+from apptools.persistence.updater import __replacement_setstate__
+
+
+logger = logging.getLogger(__name__)
+
+
+##############################################################################
+# class 'NewUnpickler'
+##############################################################################
+
[docs]class NewUnpickler(Unpickler): + """An unpickler that implements a two-stage pickling process to make it + possible to unpickle complicated Python object hierarchies where the + unserialized state of an object depends on the state of other objects in + the same pickle. + """ + +
[docs] def load(self, max_pass=-1): + """Read a pickled object representation from the open file. + + Return the reconstituted object hierarchy specified in the file. + """ + # List of objects to be unpickled. + self.objects = [] + + # We overload the load_build method. + dispatch = self.dispatch + dispatch[BUILD[0]] = NewUnpickler.load_build + + # call the super class' method. + ret = Unpickler.load(self) + self.initialize(max_pass) + self.objects = [] + + # Reset the Unpickler's dispatch table. + dispatch[BUILD[0]] = Unpickler.load_build + return ret
+ +
[docs] def initialize(self, max_pass): + # List of (object, generator) tuples that initialize objects. + generators = [] + + # Execute object's initialize to setup the generators. + for obj in self.objects: + if hasattr(obj, "__initialize__") and callable(obj.__initialize__): + ret = obj.__initialize__() + if isinstance(ret, GeneratorType): + generators.append((obj, ret)) + elif ret is not None: + raise UnpicklingError( + "Unexpected return value from " + "__initialize__. %s returned %s" % (obj, ret) + ) + + # Ensure a maximum number of passes + if max_pass < 0: + max_pass = len(generators) + + # Now run the generators. + count = 0 + while len(generators) > 0: + count += 1 + if count > max_pass: + not_done = [x[0] for x in generators] + msg = """Reached maximum pass count %s. You may have + a deadlock! The following objects are + uninitialized: %s""" % ( + max_pass, + not_done, + ) + raise UnpicklingError(msg) + for o, g in generators[:]: + try: + next(g) + except StopIteration: + generators.remove((o, g))
+ + # Make this a class method since dispatch is a class variable. + # Otherwise, supposing the initial VersionedUnpickler.load call (which + # would have overloaded the load_build method) makes a pickle.load call at + # some point, we would have the dispatch still pointing to + # NewPickler.load_build whereas the object being passed in will be an + # Unpickler instance, causing a TypeError. +
[docs] def load_build(cls, obj): + # Just save the instance in the list of objects. + if isinstance(obj, NewUnpickler): + obj.objects.append(obj.stack[-2]) + Unpickler.load_build(obj)
+ + load_build = classmethod(load_build)
+ + +
[docs]class VersionedUnpickler(NewUnpickler): + """This class reads in a pickled file created at revision version 'n' + and then applies the transforms specified in the updater class to + generate a new set of objects which are at revision version 'n+1'. + + I decided to keep the loading of the updater out of this generic class + because we will want updaters to be generated for each plugin's type + of project. + + This ensures that the VersionedUnpickler can remain ignorant about the + actual version numbers - all it needs to do is upgrade one release. + """ + + def __init__(self, file, updater=None): + Unpickler.__init__(self, file) + self.updater = updater + +
[docs] def find_class(self, module, name): + """Overridden method from Unpickler. + + NB __setstate__ is not called until later. + """ + + if self.updater: + # check to see if this class needs to be mapped to a new class + # or module name + original_module, original_name = module, name + module, name = self.updater.get_latest(module, name) + + # load the class... + klass = self.import_name(module, name) + + # add the updater.... TODO - why the old name? + self.add_updater(original_module, original_name, klass) + + else: + # there is no updater so we will be reading in an up to date + # version of the file... + try: + klass = Unpickler.find_class(self, module, name) + except Exception: + logger.error("Looking for [%s] [%s]" % (module, name)) + logger.exception( + "Problem using default unpickle functionality" + ) + + # restore the original __setstate__ if necessary + fn = getattr(klass, "__setstate_original__", False) + if fn: + setattr(klass, "__setstate__", fn) + + return klass
+ +
[docs] def add_updater(self, module, name, klass): + """If there is an updater defined for this class we will add it to the + class as the __setstate__ method. + """ + + fn = self.updater.setstates.get((module, name), False) + + if fn: + # move the existing __setstate__ out of the way + self.backup_setstate(module, klass) + + # add the updater into the class + setattr(klass, "__updater__", fn) + + # hook up our __setstate__ which updates self.__dict__ + setattr(klass, "__setstate__", __replacement_setstate__) + + else: + pass
+ +
[docs] def backup_setstate(self, module, klass): + """If the class has a user defined __setstate__ we back it up.""" + if getattr(klass, "__setstate__", False): + + if getattr(klass, "__setstate_original__", False): + # don't overwrite the original __setstate__ + name = "__setstate__%s" % self.updater.__class__ + else: + # backup the original __setstate__ which we will restore + # and run later when we have finished updating the class + name = "__setstate_original__" + + method = getattr(klass, "__setstate__") + setattr(klass, name, method) + + else: + # the class has no __setstate__ method so do nothing + pass
+ +
[docs] def import_name(self, module, name): + """ + If the class is needed for the latest version of the application then + it should presumably exist. + + If the class no longer exists then we should perhaps return + a proxy of the class. + + If the persisted file is at v1 say and the application is at v3 then + objects that are required for v1 and v2 do not have to exist they only + need to be placeholders for the state during an upgrade. + """ + module = __import__(module, globals(), locals(), [name]) + return vars(module)[name]
+
+ +
+
+
+
+
+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/5.0/_modules/apptools/preferences/i_preferences.html b/5.0/_modules/apptools/preferences/i_preferences.html new file mode 100644 index 000000000..1b5559d48 --- /dev/null +++ b/5.0/_modules/apptools/preferences/i_preferences.html @@ -0,0 +1,310 @@ + + + + + + + apptools.preferences.i_preferences — Apptools Documentation + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +

Source code for apptools.preferences.i_preferences

+# (C) Copyright 2005-2020 Enthought, Inc., Austin, TX
+# All rights reserved.
+#
+# This software is provided without warranty under the terms of the BSD
+# license included in LICENSE.txt and may be redistributed only under
+# the conditions described in the aforementioned license. The license
+# is also available online at http://www.enthought.com/licenses/BSD.txt
+#
+# Thanks for using Enthought open source!
+""" The interface for a node in a preferences hierarchy. """
+
+
+# Enthought library imports.
+from traits.api import Instance, Interface, Str
+
+
+
[docs]class IPreferences(Interface): + """ The interface for a node in a preferences hierarchy. """ + + # The absolute path to this node from the root node (the empty string if + # this node *is* the root node). + path = Str + + # The parent node (None if this node *is* the root node). + parent = Instance("IPreferences") + + # The name of the node relative to its parent (the empty string if this + # node *is* the root node). + name = Str + + #### Methods where 'path' refers to a preference #### + +
[docs] def get(self, path, default=None, inherit=False): + """Get the value of the preference at the specified path. + + If no value exists for the path (or any part of the path does not + exist) then return the default value. + + Preference values are *always* returned as strings. + + e.g:: + + preferences.set('acme.ui.bgcolor', 'blue') + preferences.get('acme.ui.bgcolor') -> 'blue' + + preferences.set('acme.ui.width', 100) + preferences.get('acme.ui.width') -> '100' + + preferences.set('acme.ui.visible', True) + preferences.get('acme.ui.visible') -> 'True' + + If 'inherit' is True then we allow 'inherited' preference values. + + e.g. If we are looking up:: + + 'acme.ui.widget.bgcolor' + + and it does not exist then we will also try:: + + 'acme.ui.bgcolor' + 'acme.bgcolor' + 'bgcolor' + + Raise a 'ValueError' exception if the path is the empty string. + + """
+ +
[docs] def remove(self, path): + """Remove the preference at the specified path. + + Does nothing if no value exists for the path (or any part of the path + does not exist. + + Raise a 'ValueError' exception if the path is the empty string. + + e.g.:: + + preferences.remove('acme.ui.bgcolor') + + """
+ +
[docs] def set(self, path, value): + """Set the value of the preference at the specified path. + + Any missing nodes are created automatically. + + Primitive Python types can be set, but preferences are *always* + stored and returned as strings. + + e.g:: + + preferences.set('acme.ui.bgcolor', 'blue') + preferences.get('acme.ui.bgcolor') -> 'blue' + + preferences.set('acme.ui.width', 100) + preferences.get('acme.ui.width') -> '100' + + preferences.set('acme.ui.visible', True) + preferences.get('acme.ui.visible') -> 'True' + + Raise a 'ValueError' exception if the path is the empty string. + + """
+ + #### Methods where 'path' refers to a node #### + +
[docs] def clear(self, path=""): + """Remove all preference from the node at the specified path. + + If the path is the empty string (the default) then remove the + preferences in *this* node. + + This does not affect any of the node's children. + + e.g. To clear the preferences out of a node directly:: + + preferences.clear() + + Or to clear the preferences of a node at a given path:: + + preferences.clear('acme.ui') + + """
+ +
[docs] def keys(self, path=""): + """Return the preference keys of the node at the specified path. + + If the path is the empty string (the default) then return the + preference keys of *this* node. + + e.g:: + + keys = preferences.keys('acme.ui') + + """
+ +
[docs] def node(self, path=""): + """Return the node at the specified path. + + If the path is the empty string (the default) then return *this* node. + + Any missing nodes are created automatically. + + e.g:: + + node = preferences.node('acme.ui') + bgcolor = node.get('bgcolor') + + """
+ +
[docs] def node_exists(self, path=""): + """Return True if the node at the specified path exists + + If the path is the empty string (the default) then return True. + + e.g:: + + exists = preferences.exists('acme.ui') + + """
+ +
[docs] def node_names(self, path=""): + """Return the names of the children of the node at the specified path. + + If the path is the empty string (the default) then return the names of + the children of *this* node. + + e.g:: + + names = preferences.node_names('acme.ui') + + """
+ + #### Persistence methods #### + +
[docs] def flush(self): + """Force any changes in the node to the backing store. + + This includes any changes to the node's descendants. + + """
+
+ +
+
+
+
+
+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/5.0/_modules/apptools/preferences/package_globals.html b/5.0/_modules/apptools/preferences/package_globals.html new file mode 100644 index 000000000..e477fc92e --- /dev/null +++ b/5.0/_modules/apptools/preferences/package_globals.html @@ -0,0 +1,167 @@ + + + + + + + apptools.preferences.package_globals — Apptools Documentation + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +

Source code for apptools.preferences.package_globals

+# (C) Copyright 2005-2020 Enthought, Inc., Austin, TX
+# All rights reserved.
+#
+# This software is provided without warranty under the terms of the BSD
+# license included in LICENSE.txt and may be redistributed only under
+# the conditions described in the aforementioned license. The license
+# is also available online at http://www.enthought.com/licenses/BSD.txt
+#
+# Thanks for using Enthought open source!
+""" Package-scope globals.
+
+The default preferences node is currently used by 'PreferencesHelper' and
+'PreferencesBinding' instances if no specific preferences node is set. This
+makes it easy for them to access the root node of an application-wide
+preferences hierarchy.
+
+"""
+
+
+# The default preferences node.
+_default_preferences = None
+
+
+
[docs]def get_default_preferences(): + """ Get the default preferences node. """ + + return _default_preferences
+ + +
[docs]def set_default_preferences(default_preferences): + """ Set the default preferences node. """ + + global _default_preferences + + _default_preferences = default_preferences + + # For convenience. + return _default_preferences
+
+ +
+
+
+
+
+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/5.0/_modules/apptools/preferences/preference_binding.html b/5.0/_modules/apptools/preferences/preference_binding.html new file mode 100644 index 000000000..5cb1678c2 --- /dev/null +++ b/5.0/_modules/apptools/preferences/preference_binding.html @@ -0,0 +1,299 @@ + + + + + + + apptools.preferences.preference_binding — Apptools Documentation + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +

Source code for apptools.preferences.preference_binding

+# (C) Copyright 2005-2020 Enthought, Inc., Austin, TX
+# All rights reserved.
+#
+# This software is provided without warranty under the terms of the BSD
+# license included in LICENSE.txt and may be redistributed only under
+# the conditions described in the aforementioned license. The license
+# is also available online at http://www.enthought.com/licenses/BSD.txt
+#
+# Thanks for using Enthought open source!
+""" A binding between a trait on an object and a preference value. """
+
+
+# Enthought library imports.
+from traits.api import Any, HasTraits, Instance, Str, Undefined
+
+# Local imports.
+from .i_preferences import IPreferences
+from .package_globals import get_default_preferences
+
+
+
[docs]class PreferenceBinding(HasTraits): + """ A binding between a trait on an object and a preference value. """ + + #### 'PreferenceBinding' interface ######################################## + + # The object that we are binding the preference to. + obj = Any + + # The preferences node used by the binding. If this trait is not set then + # the package-global default preferences node is used (and if that is not + # set then the binding won't work ;^) + preferences = Instance(IPreferences) + + # The path to the preference value. + preference_path = Str + + # The name of the trait that we are binding the preference to. + trait_name = Str + + ########################################################################### + # 'object' interface. + ########################################################################### + + def __init__(self, **traits): + """ Constructor. """ + + super(PreferenceBinding, self).__init__(**traits) + + # Initialize the object's trait from the preference value. + self._set_trait(notify=False) + + # Wire-up trait change handlers etc. + self._initialize() + + ########################################################################### + # 'PreferenceBinding' interface. + ########################################################################### + + #### Trait initializers ################################################### + + def _preferences_default(self): + """ Trait initializer. """ + + return get_default_preferences() + + ########################################################################### + # Private interface. + ########################################################################### + + #### Trait change handlers ################################################ + + def _on_trait_changed(self, obj, trait_name, old, new): + """ Dynamic trait change handler. """ + + self.preferences.set(self.preference_path, new) + + #### Other observer pattern listeners ##################################### + + def _preferences_listener(self, node, key, old, new): + """ Listener called when a preference value is changed. """ + + components = self.preference_path.split(".") + if key == components[-1]: + self._set_trait() + + #### Methods ############################################################## + + # fixme: This method is mostly duplicated in 'PreferencesHelper' (the only + # difference is the line that gets the handler). + def _get_value(self, trait_name, value): + """Get the actual value to set. + + This method makes sure that any required work is done to convert the + preference value from a string. + + """ + + handler = self.obj.trait(trait_name).handler + + # If the trait type is 'Str' then we just take the raw value. + if type(handler) is Str: + pass + + # If the trait type is 'Str' then we convert the raw value. + elif type(handler) is Str: + value = str(value) + + # Otherwise, we eval it! + else: + try: + value = eval(value) + + # If the eval fails then there is probably a syntax error, but + # we will let the handler validation throw the exception. + except Exception: + pass + + return handler.validate(self, trait_name, value) + + def _initialize(self): + """ Wire-up trait change handlers etc. """ + + # Listen for the object's trait being changed. + self.obj.on_trait_change(self._on_trait_changed, self.trait_name) + + # Listen for the preference value being changed. + components = self.preference_path.split(".") + node = ".".join(components[:-1]) + + self.preferences.add_preferences_listener( + self._preferences_listener, node + ) + + def _set_trait(self, notify=True): + """ Set the object's trait to the value of the preference. """ + + value = self.preferences.get(self.preference_path, Undefined) + if value is not Undefined: + trait_value = self._get_value(self.trait_name, value) + traits = {self.trait_name: trait_value} + + self.obj.trait_set(trait_change_notify=notify, **traits)
+ + +# Factory function for creating bindings. +
[docs]def bind_preference(obj, trait_name, preference_path, preferences=None): + """ Create a new preference binding. """ + + # This may seem a bit wierd, but we manually build up a dictionary of + # the traits that need to be set at the time the 'PreferenceBinding' + # instance is created. + # + # This is because we only want to set the 'preferences' trait iff one + # is explicitly specified. If we passed it in with the default argument + # value of 'None' then it counts as 'setting' the trait which prevents + # the binding instance from defaulting to the package-global preferences. + # Also, if we try to set the 'preferences' trait *after* construction time + # then it is too late as the binding initialization is done in the + # constructor (we could of course split that out, which may be the 'right' + # way to do it ;^). + traits = { + "obj": obj, + "trait_name": trait_name, + "preference_path": preference_path, + } + + if preferences is not None: + traits["preferences"] = preferences + + return PreferenceBinding(**traits)
+
+ +
+
+
+
+
+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/5.0/_modules/apptools/preferences/preferences.html b/5.0/_modules/apptools/preferences/preferences.html new file mode 100644 index 000000000..380b6bf59 --- /dev/null +++ b/5.0/_modules/apptools/preferences/preferences.html @@ -0,0 +1,687 @@ + + + + + + + apptools.preferences.preferences — Apptools Documentation + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +

Source code for apptools.preferences.preferences

+# (C) Copyright 2005-2020 Enthought, Inc., Austin, TX
+# All rights reserved.
+#
+# This software is provided without warranty under the terms of the BSD
+# license included in LICENSE.txt and may be redistributed only under
+# the conditions described in the aforementioned license. The license
+# is also available online at http://www.enthought.com/licenses/BSD.txt
+#
+# Thanks for using Enthought open source!
+""" The default implementation of a node in a preferences hierarchy. """
+
+# Standard library imports.
+import logging
+import threading
+
+# Enthought library imports.
+from traits.api import Any, Callable, Dict, HasTraits, Instance, List
+from traits.api import Property, Str, Undefined, provides
+
+# Local imports.
+from .i_preferences import IPreferences
+
+
+# Logging.
+logger = logging.getLogger(__name__)
+
+
+
[docs]@provides(IPreferences) +class Preferences(HasTraits): + """ The default implementation of a node in a preferences hierarchy. """ + + #### 'IPreferences' interface ############################################# + + # The absolute path to this node from the root node (the empty string if + # this node *is* the root node). + path = Property(Str) + + # The parent node (None if this node *is* the root node). + parent = Instance(IPreferences) + + # The name of the node relative to its parent (the empty string if this + # node *is* the root node). + name = Str + + #### 'Preferences' interface ############################################## + + # The default name of the file used to persist the preferences (if no + # filename is passed in to the 'load' and 'save' methods, then this is + # used instead). + filename = Str + + #### Protected 'Preferences' interface #################################### + + # A lock to make access to the node thread-safe. + # + # fixme: There *should* be no need to declare this as a trait, but if we + # don't then we have problems using nodes in the preferences manager UI. + # It is something to do with 'cloning' the node for use in a 'modal' traits + # UI... Hmmm... + _lk = Any + + # The node's children. + _children = Dict(Str, IPreferences) + + # The node's preferences. + _preferences = Dict(Str, Any) + + # Listeners for changes to the node's preferences. + # + # The callable must take 4 arguments, e.g:: + # + # listener(node, key, old, new) + _preferences_listeners = List(Callable) + + ########################################################################### + # 'object' interface. + ########################################################################### + + def __init__(self, **traits): + """ Constructor. """ + + # A lock to make access to the '_children', '_preferences' and + # '_preferences_listeners' traits thread-safe. + self._lk = threading.Lock() + + # Base class constructor. + super(Preferences, self).__init__(**traits) + + # If a filename has been specified then load the preferences from it. + if len(self.filename) > 0: + self.load() + + ########################################################################### + # 'IPreferences' interface. + ########################################################################### + + #### Trait properties ##################################################### + + def _get_path(self): + """ Property getter. """ + + names = [] + + node = self + while node.parent is not None: + names.append(node.name) + node = node.parent + + names.reverse() + + return ".".join(names) + + #### Methods ############################################################## + + #### Methods where 'path' refers to a preference #### + +
[docs] def get(self, path, default=None, inherit=False): + """ Get the value of the preference at the specified path. """ + + if len(path) == 0: + raise ValueError("empty path") + + components = path.split(".") + + # If there is only one component in the path then the operation takes + # place in this node. + if len(components) == 1: + value = self._get(path, Undefined) + + # Otherwise, find the next node and pass the rest of the path to that. + else: + node = self._get_child(components[0]) + if node is not None: + value = node.get(".".join(components[1:]), Undefined) + + else: + value = Undefined + + # If inherited values are allowed then try those as well. + # + # e.g. 'acme.ui.widget.bgcolor' + # 'acme.ui.bgcolor' + # 'acme.bgcolor' + # 'bgcolor' + while inherit and value is Undefined and len(components) > 1: + # Remove the penultimate component... + # + # e.g. 'acme.ui.widget.bgcolor' -> 'acme.ui.bgcolor' + del components[-2] + + # ... and try that. + value = self.get(".".join(components), default=Undefined) + + if value is Undefined: + value = default + + return value
+ +
[docs] def remove(self, path): + """ Remove the preference at the specified path. """ + + if len(path) == 0: + raise ValueError("empty path") + + components = path.split(".") + + # If there is only one component in the path then the operation takes + # place in this node. + if len(components) == 1: + self._remove(path) + + # Otherwise, find the next node and pass the rest of the path to that. + else: + node = self._get_child(components[0]) + if node is not None: + node.remove(".".join(components[1:]))
+ +
[docs] def set(self, path, value): + """ Set the value of the preference at the specified path. """ + + if len(path) == 0: + raise ValueError("empty path") + + components = path.split(".") + + # If there is only one component in the path then the operation takes + # place in this node. + if len(components) == 1: + self._set(path, value) + + # Otherwise, find the next node (creating it if it doesn't exist) + # and pass the rest of the path to that. + else: + node = self._node(components[0]) + node.set(".".join(components[1:]), value)
+ + #### Methods where 'path' refers to a node #### + +
[docs] def clear(self, path=""): + """ Remove all preferences from the node at the specified path. """ + + # If the path is empty then the operation takes place in this node. + if len(path) == 0: + self._clear() + + # Otherwise, find the next node and pass the rest of the path to that. + else: + components = path.split(".") + + node = self._get_child(components[0]) + if node is not None: + node.clear(".".join(components[1:]))
+ +
[docs] def keys(self, path=""): + """ Return the preference keys of the node at the specified path. """ + + # If the path is empty then the operation takes place in this node. + if len(path) == 0: + keys = self._keys() + + # Otherwise, find the next node and pass the rest of the path to that. + else: + components = path.split(".") + + node = self._get_child(components[0]) + if node is not None: + keys = node.keys(".".join(components[1:])) + + else: + keys = [] + + return keys
+ +
[docs] def node(self, path=""): + """ Return the node at the specified path. """ + + # If the path is empty then the operation takes place in this node. + if len(path) == 0: + node = self + + # Otherwise, find the next node and pass the rest of the path to that. + else: + components = path.split(".") + + node = self._node(components[0]) + node = node.node(".".join(components[1:])) + + return node
+ +
[docs] def node_exists(self, path=""): + """ Return True if the node at the specified path exists. """ + + # If the path is empty then the operation takes place in this node. + if len(path) == 0: + exists = True + + # Otherwise, find the next node and pass the rest of the path to that. + else: + components = path.split(".") + + node = self._get_child(components[0]) + if node is not None: + exists = node.node_exists(".".join(components[1:])) + + else: + exists = False + + return exists
+ +
[docs] def node_names(self, path=""): + """Return the names of the children of the node at the specified path. + """ + + # If the path is empty then the operation takes place in this node. + if len(path) == 0: + names = self._node_names() + + # Otherwise, find the next node and pass the rest of the path to that. + else: + components = path.split(".") + + node = self._get_child(components[0]) + if node is not None: + names = node.node_names(".".join(components[1:])) + + else: + names = [] + + return names
+ + #### Persistence methods #### + +
[docs] def flush(self): + """Force any changes in the node to the backing store. + + This includes any changes to the node's descendants. + + """ + + self.save()
+ + ########################################################################### + # 'Preferences' interface. + ########################################################################### + + #### Listener methods #### + +
[docs] def add_preferences_listener(self, listener, path=""): + """ Add a listener for changes to a node's preferences. """ + + # If the path is empty then the operation takes place in this node. + if len(path) == 0: + self._add_preferences_listener(listener) + + # Otherwise, find the next node and pass the rest of the path to that. + else: + components = path.split(".") + + node = self._node(components[0]) + node.add_preferences_listener(listener, ".".join(components[1:]))
+ +
[docs] def remove_preferences_listener(self, listener, path=""): + """ Remove a listener for changes to a node's preferences. """ + + # If the path is empty then the operation takes place in this node. + if len(path) == 0: + self._remove_preferences_listener(listener) + + # Otherwise, find the next node and pass the rest of the path to that. + else: + components = path.split(".") + + node = self._node(components[0]) + node.remove_preferences_listener( + listener, ".".join(components[1:]) + )
+ + #### Persistence methods #### + +
[docs] def load(self, file_or_filename=None): + """Load preferences from a file. + + This is a *merge* operation i.e. the contents of the file are added to + the node. + + This implementation uses 'ConfigObj' files. + + """ + + if file_or_filename is None: + file_or_filename = self.filename + + logger.debug("loading preferences from <%s>", file_or_filename) + + # Do the import here so that we don't make 'ConfigObj' a requirement + # if preferences aren't ever persisted (or a derived class chooses to + # use a different persistence mechanism). + from configobj import ConfigObj + + config_obj = ConfigObj(file_or_filename, encoding="utf-8") + + # 'name' is the section name, 'value' is a dictionary containing the + # name/value pairs in the section (the actual preferences ;^). + for name, value in config_obj.items(): + # Create/get the node from the section name. + components = name.split(".") + + node = self + for component in components: + node = node._node(component) + + # Add the contents of the section to the node. + self._add_dictionary_to_node(node, value)
+ +
[docs] def save(self, file_or_filename=None): + """Save the node's preferences to a file. + + This implementation uses 'ConfigObj' files. + + """ + + if file_or_filename is None: + file_or_filename = self.filename + + # If no file or filename is specified then don't save the preferences! + if len(file_or_filename) > 0: + # Do the import here so that we don't make 'ConfigObj' a + # requirement if preferences aren't ever persisted (or a derived + # class chooses to use a different persistence mechanism). + from configobj import ConfigObj + + logger.debug("saving preferences to <%s>", file_or_filename) + + config_obj = ConfigObj(file_or_filename, encoding="utf-8") + self._add_node_to_dictionary(self, config_obj) + config_obj.write()
+ + ########################################################################### + # Protected 'Preferences' interface. + # + # These are the only methods that should access the protected '_children' + # and '_preferences' traits. This helps make it easy to subclass this class + # to create other implementations (all the subclass has to do is to + # implement these protected methods). + # + ########################################################################### + + def _add_dictionary_to_node(self, node, dictionary): + """ Add the contents of a dictionary to a node's preferences. """ + + self._lk.acquire() + node._preferences.update(dictionary) + self._lk.release() + + def _add_node_to_dictionary(self, node, dictionary): + """ Add a node's preferences to a dictionary. """ + + # This method never manipulates the '_preferences' trait directly. + # Instead it does eveything via the other protected methods and hence + # doesn't need to grab the lock. + if len(node._keys()) > 0: + dictionary[node.path] = {} + for key in node._keys(): + dictionary[node.path][key] = node._get(key) + + for name in node._node_names(): + self._add_node_to_dictionary(node._get_child(name), dictionary) + + def _add_preferences_listener(self, listener): + """ Add a listener for changes to thisnode's preferences. """ + + self._lk.acquire() + self._preferences_listeners.append(listener) + self._lk.release() + + def _clear(self): + """ Remove all preferences from this node. """ + + self._lk.acquire() + self._preferences.clear() + self._lk.release() + + def _create_child(self, name): + """ Create a child of this node with the specified name. """ + + self._lk.acquire() + child = self._children[name] = Preferences(name=name, parent=self) + self._lk.release() + + return child + + def _get(self, key, default=None): + """ Get the value of a preference in this node. """ + + self._lk.acquire() + value = self._preferences.get(key, default) + self._lk.release() + + return value + + def _get_child(self, name): + """Return the child of this node with the specified name. + + Return None if no such child exists. + + """ + + self._lk.acquire() + child = self._children.get(name) + self._lk.release() + + return child + + def _keys(self): + """ Return the preference keys of this node. """ + + self._lk.acquire() + keys = list(self._preferences.keys()) + self._lk.release() + + return keys + + def _node(self, name): + """Return the child of this node with the specified name. + + Create the child node if it does not exist. + + """ + + node = self._get_child(name) + if node is None: + node = self._create_child(name) + + return node + + def _node_names(self): + """ Return the names of the children of this node. """ + + self._lk.acquire() + node_names = list(self._children.keys()) + self._lk.release() + + return node_names + + def _remove(self, name): + """ Remove a preference value from this node. """ + + self._lk.acquire() + if name in self._preferences: + del self._preferences[name] + self._lk.release() + + def _remove_preferences_listener(self, listener): + """ Remove a listener for changes to the node's preferences. """ + + self._lk.acquire() + if listener in self._preferences_listeners: + self._preferences_listeners.remove(listener) + self._lk.release() + + def _set(self, key, value): + """ Set the value of a preference in this node. """ + + # everything must be unicode encoded so that ConfigObj configuration + # can properly serialize the data. Python str are supposed to be ASCII + # encoded. + value = str(value) + + self._lk.acquire() + old = self._preferences.get(key) + self._preferences[key] = value + + # If the value is unchanged then don't call the listeners! + if old == value: + listeners = [] + + else: + listeners = self._preferences_listeners[:] + self._lk.release() + + for listener in listeners: + listener(self, key, old, value) + + ########################################################################### + # Debugging interface. + ########################################################################### + +
[docs] def dump(self, indent=""): + """ Dump the preferences hierarchy to stdout. """ + + if indent == "": + print() + + print(indent, "Node(%s)" % self.name, self._preferences) + indent += " " + + for child in self._children.values(): + child.dump(indent)
+
+ +
+
+
+
+
+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/5.0/_modules/apptools/preferences/preferences_helper.html b/5.0/_modules/apptools/preferences/preferences_helper.html new file mode 100644 index 000000000..982d2dd8c --- /dev/null +++ b/5.0/_modules/apptools/preferences/preferences_helper.html @@ -0,0 +1,336 @@ + + + + + + + apptools.preferences.preferences_helper — Apptools Documentation + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +

Source code for apptools.preferences.preferences_helper

+# (C) Copyright 2005-2020 Enthought, Inc., Austin, TX
+# All rights reserved.
+#
+# This software is provided without warranty under the terms of the BSD
+# license included in LICENSE.txt and may be redistributed only under
+# the conditions described in the aforementioned license. The license
+# is also available online at http://www.enthought.com/licenses/BSD.txt
+#
+# Thanks for using Enthought open source!
+""" An object that can be initialized from a preferences node. """
+
+
+# Standard library imports.
+import logging
+
+# Enthought library imports.
+from traits.api import HasTraits, Instance, Str
+
+# Local imports.
+from .i_preferences import IPreferences
+from .package_globals import get_default_preferences
+
+
+# Logging.
+logger = logging.getLogger(__name__)
+
+
+
[docs]class PreferencesHelper(HasTraits): + """ A base class for objects that can be initialized from a preferences + node. + + Additional traits defined on subclasses will be listened to. Changes + are then synchronized with the preferences. Note that mutations on nested + containers e.g. List(List(Str)) cannot be synchronized and should be + avoided. + """ + + #### 'PreferencesHelper' interface ######################################## + + # The preferences node used by the helper. If this trait is not set then + # the package-global default preferences node is used. + # + # fixme: This introduces a 'sneaky' global reference to the preferences + # node! + preferences = Instance(IPreferences) + + # The path to the preference node that contains the preferences that we + # use to initialize instances of this class. + preferences_path = Str + + ########################################################################### + # 'object' interface. + ########################################################################### + + def __init__(self, **traits): + """ Constructor. """ + + super(PreferencesHelper, self).__init__(**traits) + + # Initialize the object's traits from the preferences node. + if self.preferences: + self._initialize(self.preferences) + + ########################################################################### + # Private interface. + ########################################################################### + + #### Trait initializers ################################################### + + def _preferences_default(self): + """ Trait initializer. """ + + # If no specific preferences node is set then we use the package-wide + # global node. + return get_default_preferences() + + #### Trait change handlers ################################################ + + def _anytrait_changed(self, trait_name, old, new): + """ Static trait change handler. """ + + if self.preferences is None: + return + + if self._is_preference_trait(trait_name): + self.preferences.set("%s.%s" % (self._get_path(), trait_name), new) + + # If the trait was a list or dict '_items' trait then just treat it as + # if the entire list or dict was changed. + elif trait_name.endswith('_items'): + trait_name = trait_name[:-6] + if self._is_preference_trait(trait_name): + self.preferences.set( + '%s.%s' % (self._get_path(), trait_name), + getattr(self, trait_name) + ) + + # If the change refers to a trait defined on this class, then + # the trait is not a preference trait and we do nothing. + + def _preferences_changed(self, old, new): + """ Static trait change handler. """ + + # Stop listening to the old preferences node. + if old is not None: + old.remove_preferences_listener( + self._preferences_changed_listener, self._get_path() + ) + + if new is not None: + # Initialize with the new preferences node (this also adds a + # listener for preferences being changed in the new node). + self._initialize(new, notify=True) + + #### Other observer pattern listeners ##################################### + + def _preferences_changed_listener(self, node, key, old, new): + """ Listener called when a preference value is changed. """ + + if key in self.trait_names(): + setattr(self, key, self._get_value(key, new)) + + #### Methods ############################################################## + + def _get_path(self): + """ Return the path to our preferences node. """ + + if len(self.preferences_path) > 0: + path = self.preferences_path + + else: + path = getattr(self, "PREFERENCES_PATH", None) + if path is None: + raise SystemError("no preferences path, %s" % self) + + else: + logger.warn('DEPRECATED: use "preferences_path" %s' % self) + + return path + + def _get_value(self, trait_name, value): + """Get the actual value to set. + + This method makes sure that any required work is done to convert the + preference value from a string. Str traits or those with the metadata + 'is_str=True' will just be passed the string itself. + + """ + + trait = self.trait(trait_name) + handler = trait.handler + + # If the trait type is 'Str' then we just take the raw value. + if isinstance(handler, Str) or trait.is_str: + pass + + # Otherwise, we eval it! + else: + try: + value = eval(value) + + # If the eval fails then there is probably a syntax error, but + # we will let the handler validation throw the exception. + except Exception: + pass + + if handler.validate is not None: + # Any traits have a validator of None. + validated = handler.validate(self, trait_name, value) + else: + validated = value + + return validated + + def _initialize(self, preferences, notify=False): + """ Initialize the object's traits from the preferences node. """ + + path = self._get_path() + keys = preferences.keys(path) + + traits_to_set = {} + for trait_name in self.trait_names(): + if trait_name in keys: + key = "%s.%s" % (path, trait_name) + value = self._get_value(trait_name, preferences.get(key)) + traits_to_set[trait_name] = value + + self.trait_set(trait_change_notify=notify, **traits_to_set) + + # Listen for changes to the node's preferences. + preferences.add_preferences_listener( + self._preferences_changed_listener, path + ) + + # fixme: Pretty much duplicated in 'PreferencesPage' (except for the + # class name of course!). + def _is_preference_trait(self, trait_name): + """ Return True if a trait represents a preference value. """ + + if ( + trait_name.startswith("_") + or trait_name.endswith("_") + or trait_name in PreferencesHelper.class_traits() + ): + return False + + return trait_name in self.editable_traits()
+
+ +
+
+
+
+
+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/5.0/_modules/apptools/preferences/scoped_preferences.html b/5.0/_modules/apptools/preferences/scoped_preferences.html new file mode 100644 index 000000000..e2937244e --- /dev/null +++ b/5.0/_modules/apptools/preferences/scoped_preferences.html @@ -0,0 +1,582 @@ + + + + + + + apptools.preferences.scoped_preferences — Apptools Documentation + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +

Source code for apptools.preferences.scoped_preferences

+# (C) Copyright 2005-2020 Enthought, Inc., Austin, TX
+# All rights reserved.
+#
+# This software is provided without warranty under the terms of the BSD
+# license included in LICENSE.txt and may be redistributed only under
+# the conditions described in the aforementioned license. The license
+# is also available online at http://www.enthought.com/licenses/BSD.txt
+#
+# Thanks for using Enthought open source!
+""" A preferences node that adds the notion of preferences scopes. """
+
+# Standard library imports.
+from os.path import join
+
+# Enthought library imports.
+from traits.etsconfig.api import ETSConfig
+from traits.api import List, Str, Undefined
+
+# Local imports.
+from .i_preferences import IPreferences
+from .preferences import Preferences
+
+
+
[docs]class ScopedPreferences(Preferences): + """A preferences node that adds the notion of preferences scopes. + + Scopes provide a way to access preferences in a precedence order, usually + depending on where they came from, for example from the command-line, + or set by the user in a preferences file, or the defaults (set by the + developer). + + By default, this class provides two scopes - 'application' which is + persistent and 'default' which is not. + + Path names passed to 'ScopedPreferences' nodes can be either:: + + a) a preference path as used in a standard 'Preferences' node, e.g:: + + 'acme.widget.bgcolor'. + + In this case the operation either takes place in the primary scope + (for operations such as 'set' etc), or on all scopes in precedence + order (for operations such as 'get' etc). + + or + + b) a preference path that refers to a specific scope e.g:: + + 'default/acme.widget.bgcolor' + + In this case the operation takes place *only* in the specified scope. + + There is one drawback to this scheme. If you want to access a scope node + itself via the 'clear', 'keys', 'node', 'node_exists' or 'node_names' + methods then you have to append a trailing '/' to the path. Without that, + the node would try to perform the operation in the primary scope. + + e.g. To get the names of the children of the 'application' scope, use:: + + scoped.node_names('application/') + + If you did this:: + + scoped.node_names('application') + + Then the node would get the primary scope and try to find its child node + called 'application'. + + Of course you can just get the scope via:: + + application_scope = scoped.get_scope('application') + + and then call whatever methods you like on it - which is definitely more + intentional and is highly recommended:: + + application_scope.node_names() + + """ + + #### 'ScopedPreferences' interface ######################################## + + # The file that the application scope preferences are stored in. + # + # Defaults to:- + # + # os.path.join(ETSConfig.application_home, 'preferences.ini') + application_preferences_filename = Str + + # The scopes (in the order that they should be searched when looking up + # preferences). + # + # By default, this class provides two scopes - 'application' which is + # persistent and 'default' which is not. + scopes = List(IPreferences) + + # The name of the 'primary' scope. + # + # This is the scope that operations take place in if no scope is specified + # in a given path (for the 'get' operation, if no scope is specified the + # operation takes place in *all* scopes in order of precedence). If this is + # the empty string (the default) then the primary scope is the first scope + # in the 'scopes' list. + primary_scope_name = Str + + ########################################################################### + # 'IPreferences' protocol. + ########################################################################### + + #### Methods where 'path' refers to a preference #### + +
[docs] def get(self, path, default=None, inherit=False): + """ Get the value of the preference at the specified path. """ + + if len(path) == 0: + raise ValueError("empty path") + + # If the path contains a specific scope then lookup the preference in + # just that scope. + if self._path_contains_scope(path): + scope_name, path = self._parse_path(path) + nodes = [self._get_scope(scope_name)] + + # Otherwise, try each scope in turn (i.e. in order of precedence). + else: + nodes = self.scopes + + # Try all nodes first (without inheritance even if specified). + value = self._get(path, Undefined, nodes, inherit=False) + if value is Undefined: + if inherit: + value = self._get(path, default, nodes, inherit=True) + + else: + value = default + + return value
+ +
[docs] def remove(self, path): + """ Remove the preference at the specified path. """ + + if len(path) == 0: + raise ValueError("empty path") + + # If the path contains a specific scope then remove the preference from + # just that scope. + if self._path_contains_scope(path): + scope_name, path = self._parse_path(path) + node = self._get_scope(scope_name) + + # Otherwise, remove the preference from the primary scope. + else: + node = self._get_primary_scope() + + node.remove(path)
+ +
[docs] def set(self, path, value): + """ Set the value of the preference at the specified path. """ + + if len(path) == 0: + raise ValueError("empty path") + + # If the path contains a specific scope then set the value in that + # scope. + if self._path_contains_scope(path): + scope_name, path = self._parse_path(path) + node = self._get_scope(scope_name) + + # Otherwise, set the value in the primary scope. + else: + node = self._get_primary_scope() + + node.set(path, value)
+ + #### Methods where 'path' refers to a node #### + +
[docs] def clear(self, path=""): + """ Remove all preference from the node at the specified path. """ + + # If the path contains a specific scope then remove the preferences + # from a node in that scope. + if self._path_contains_scope(path): + scope_name, path = self._parse_path(path) + node = self._get_scope(scope_name) + + # Otherwise, remove the preferences from a node in the primary scope. + else: + node = self._get_primary_scope() + + return node.clear(path)
+ +
[docs] def keys(self, path=""): + """ Return the preference keys of the node at the specified path. """ + + # If the path contains a specific scope then get the keys of the node + # in that scope. + if self._path_contains_scope(path): + scope_name, path = self._parse_path(path) + nodes = [self._get_scope(scope_name)] + + # Otherwise, merge the keys of the node in all scopes. + else: + nodes = self.scopes + + keys = set() + for node in nodes: + keys.update(node.node(path).keys()) + + return list(keys)
+ +
[docs] def node(self, path=""): + """ Return the node at the specified path. """ + + if len(path) == 0: + node = self + + else: + # If the path contains a specific scope then we get the node that + # scope. + if self._path_contains_scope(path): + scope_name, path = self._parse_path(path) + node = self._get_scope(scope_name) + + # Otherwise, get the node from the primary scope. + else: + node = self._get_primary_scope() + + node = node.node(path) + + return node
+ +
[docs] def node_exists(self, path=""): + """ Return True if the node at the specified path exists. """ + + # If the path contains a specific scope then look for the node in that + # scope. + if self._path_contains_scope(path): + scope_name, path = self._parse_path(path) + node = self._get_scope(scope_name) + + # Otherwise, look for the node in the primary scope. + else: + node = self._get_primary_scope() + + return node.node_exists(path)
+ +
[docs] def node_names(self, path=""): + """Return the names of the children of the node at the specified path. + """ + + # If the path contains a specific scope then get the names of the + # children of the node in that scope. + if self._path_contains_scope(path): + scope_name, path = self._parse_path(path) + nodes = [self._get_scope(scope_name)] + + # Otherwise, merge the names of the children of the node in all scopes. + else: + nodes = self.scopes + + names = set() + for node in nodes: + names.update(node.node(path).node_names()) + + return list(names)
+ + ########################################################################### + # 'Preferences' protocol. + ########################################################################### + + #### Listener methods #### + +
[docs] def add_preferences_listener(self, listener, path=""): + """ Add a listener for changes to a node's preferences. """ + + # If the path contains a specific scope then add a preferences listener + # to the node in that scope. + if self._path_contains_scope(path): + scope_name, path = self._parse_path(path) + nodes = [self._get_scope(scope_name)] + + # Otherwise, add a preferences listener to the node in all scopes. + else: + nodes = self.scopes + + for node in nodes: + node.add_preferences_listener(listener, path)
+ +
[docs] def remove_preferences_listener(self, listener, path=""): + """ Remove a listener for changes to a node's preferences. """ + + # If the path contains a specific scope then remove a preferences + # listener from the node in that scope. + if self._path_contains_scope(path): + scope_name, path = self._parse_path(path) + nodes = [self._get_scope(scope_name)] + + # Otherwise, remove a preferences listener from the node in all scopes. + else: + nodes = self.scopes + + for node in nodes: + node.remove_preferences_listener(listener, path)
+ + #### Persistence methods #### + +
[docs] def load(self, file_or_filename=None): + """Load preferences from a file. + + This loads the preferences into the primary scope. + + fixme: I'm not sure it is worth providing an implentation here. I + think it would be better to encourage people to explicitly reference + a particular scope. + + """ + + if file_or_filename is None and len(self.filename) > 0: + file_or_filename = self.filename + + node = self._get_primary_scope() + node.load(file_or_filename)
+ +
[docs] def save(self, file_or_filename=None): + """Save the node's preferences to a file. + + This asks each scope in turn to save its preferences. + + If a file or filename is specified then it is only passed to the + primary scope. + + """ + + if file_or_filename is None and len(self.filename) > 0: + file_or_filename = self.filename + + self._get_primary_scope().save(file_or_filename) + for scope in self.scopes: + if scope is not self._get_primary_scope(): + scope.save()
+ + ########################################################################### + # 'ScopedPreferences' protocol. + ########################################################################### + + def _application_preferences_filename_default(self): + """ Trait initializer. """ + + return join(ETSConfig.application_home, "preferences.ini") + + # fixme: In hindsight, I don't think this class should have provided + # default scopes. This should have been an 'abstract' class that could + # be subclassed by classes providing specific scopes. + def _scopes_default(self): + """ Trait initializer. """ + + scopes = [ + Preferences( + name="application", + filename=self.application_preferences_filename, + ), + Preferences(name="default"), + ] + + return scopes + +
[docs] def get_scope(self, scope_name): + """Return the scope with the specified name. + + Return None if no such scope exists. + + """ + + for scope in self.scopes: + if scope_name == scope.name: + break + + else: + scope = None + + return scope
+ + ########################################################################### + # Private protocol. + ########################################################################### + + def _get(self, path, default, nodes, inherit): + """ Get a preference from a list of nodes. """ + + for node in nodes: + value = node.get(path, Undefined, inherit) + if value is not Undefined: + break + + else: + value = default + + return value + + def _get_scope(self, scope_name): + """Return the scope with the specified name. + + Raise a 'ValueError' is no such scope exists. + + """ + + scope = self.get_scope(scope_name) + if scope is None: + raise ValueError("no such scope %s" % scope_name) + + return scope + + def _get_primary_scope(self): + """Return the primary scope. + + By default, this is the first scope. + + """ + + if len(self.primary_scope_name) > 0: + scope = self._get_scope(self.primary_scope_name) + + else: + scope = self.scopes[0] + + return scope + + def _path_contains_scope(self, path): + """ Return True if the path contains a scope component. """ + + return "/" in path + + def _parse_path(self, path): + """ 'Parse' the path into two parts, the scope name and the rest! """ + + components = path.split("/") + + return components[0], "/".join(components[1:]) + + ########################################################################### + # Debugging interface. + ########################################################################### + +
[docs] def dump(self, indent=""): + """ Dump the preferences hierarchy to stdout. """ + + if indent == "": + print() + + print(indent, "Node(%s)" % self.name, self._preferences) + indent += " " + + for child in self.scopes: + child.dump(indent)
+
+ +
+
+
+
+
+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/5.0/_modules/apptools/preferences/ui/i_preferences_page.html b/5.0/_modules/apptools/preferences/ui/i_preferences_page.html new file mode 100644 index 000000000..bada9bfa3 --- /dev/null +++ b/5.0/_modules/apptools/preferences/ui/i_preferences_page.html @@ -0,0 +1,162 @@ + + + + + + + apptools.preferences.ui.i_preferences_page — Apptools Documentation + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +

Source code for apptools.preferences.ui.i_preferences_page

+# (C) Copyright 2005-2020 Enthought, Inc., Austin, TX
+# All rights reserved.
+#
+# This software is provided without warranty under the terms of the BSD
+# license included in LICENSE.txt and may be redistributed only under
+# the conditions described in the aforementioned license. The license
+# is also available online at http://www.enthought.com/licenses/BSD.txt
+#
+# Thanks for using Enthought open source!
+""" The interface for pages in a preferences dialog. """
+
+
+# Enthought library imports.
+from traits.api import Interface, Str
+
+
+
[docs]class IPreferencesPage(Interface): + """ The interface for pages in a preferences dialog. """ + + # The page's category (e.g. 'General/Appearence'). The empty string means + # that this is a top-level page. + category = Str + + # The page's help identifier (optional). If a help Id *is* provided then + # there will be a 'Help' button shown on the preference page. + help_id = Str + + # The page name (this is what is shown in the preferences dialog). + name = Str + +
[docs] def apply(self): + """ Apply the page's preferences. """ + pass
+
+ +
+
+
+
+
+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/5.0/_modules/apptools/preferences/ui/preferences_manager.html b/5.0/_modules/apptools/preferences/ui/preferences_manager.html new file mode 100644 index 000000000..c084f3ff2 --- /dev/null +++ b/5.0/_modules/apptools/preferences/ui/preferences_manager.html @@ -0,0 +1,418 @@ + + + + + + + apptools.preferences.ui.preferences_manager — Apptools Documentation + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +

Source code for apptools.preferences.ui.preferences_manager

+# (C) Copyright 2005-2020 Enthought, Inc., Austin, TX
+# All rights reserved.
+#
+# This software is provided without warranty under the terms of the BSD
+# license included in LICENSE.txt and may be redistributed only under
+# the conditions described in the aforementioned license. The license
+# is also available online at http://www.enthought.com/licenses/BSD.txt
+#
+# Thanks for using Enthought open source!
+""" The preferences manager. """
+
+
+# Enthought library imports.
+from traits.api import HasTraits, Instance, List, Property, Bool
+from traitsui.api import Handler, HSplit, Item, TreeEditor
+from traitsui.api import TreeNode, View, HTMLEditor
+from traitsui.menu import Action
+
+# Local imports.
+from .preferences_node import PreferencesNode
+from .preferences_page import PreferencesPage
+
+
+# A tree editor for preferences nodes.
+tree_editor = TreeEditor(
+    nodes=[
+        TreeNode(
+            node_for=[PreferencesNode],
+            auto_open=False,
+            children="children",
+            label="name",
+            rename=False,
+            copy=False,
+            delete=False,
+            insert=False,
+            menu=None,
+        ),
+    ],
+    editable=False,
+    hide_root=True,
+    selected="selected_node",
+    show_icons=False,
+)
+
+
+
[docs]class PreferencesHelpWindow(HasTraits): + """ Container class to present a view with string info. """ + +
[docs] def traits_view(self): + """ Default view to show for this class. """ + args = [] + kw_args = { + "title": "Preferences Page Help", + "buttons": ["OK"], + "width": 800, + "height": 800, + "resizable": True, + "id": "apptools.preferences.ui.preferences_manager.help", + } + to_show = {} + + for name, trait_obj in self.traits().items(): + if name != "trait_added" and name != "trait_modified": + to_show[name] = trait_obj.help + for name in to_show: + args.append(Item(name, style="readonly", editor=HTMLEditor())) + + view = View(*args, **kw_args) + return view
+ + +
[docs]class PreferencesManagerHandler(Handler): + """ The traits UI handler for the preferences manager. """ + + model = Instance(HasTraits) + + ########################################################################### + # 'Handler' interface. + ########################################################################### + +
[docs] def apply(self, info): + """ Handle the **Apply** button being clicked. """ + + info.object.apply()
+ +
[docs] def init(self, info): + """ Initialize the controls of a user interface. """ + + # Select the first node in the tree (if there is one). + self._select_first_node(info) + + return super(PreferencesManagerHandler, self).init(info)
+ +
[docs] def close(self, info, is_ok): + """ Close a dialog-based user interface. """ + + if is_ok: + info.object.apply() + + return super(PreferencesManagerHandler, self).close(info, is_ok)
+ +
[docs] def preferences_help(self, info): + """ Custom preferences help panel. The Traits help doesn't work.""" + current_page = self.model.selected_page + to_show = {} + for trait_name, trait_obj in current_page.traits().items(): + if hasattr(trait_obj, "show_help") and trait_obj.show_help: + to_show[trait_name] = trait_obj.help + + help_obj = PreferencesHelpWindow(**to_show) + help_obj.edit_traits(kind="livemodal")
+ + ########################################################################### + # Private interface. + ########################################################################### + + def _select_first_node(self, info): + """ Select the first node in the tree (if there is one). """ + + root = info.object.root + + if len(root.children) > 0: + node = root.children[0] + info.object.selected_page = node.page
+ + +
[docs]class PreferencesManager(HasTraits): + """ The preferences manager. """ + + # All of the preferences pages known to the manager. + pages = List(PreferencesPage) + + # The root of the preferences node tree. + root = Property(Instance(PreferencesNode)) + + # The preferences node currently selected in the tree. + selected_node = Instance(PreferencesNode) + + # The preferences associated with the currently selected preferences node. + selected_page = Instance(PreferencesPage) + + # Should the custom Info button be shown? If this is True, then an + # Info button is shown that pops up a trait view with an HTML entry + # for each trait of the *selected_page* with the metadata 'show_help' + # set to True. + show_help = Bool(False) + + # Should the Apply button be shown? + show_apply = Bool(False) + + #### Traits UI views ###################################################### + +
[docs] def traits_view(self): + """ Default traits view for this class. """ + + help_action = Action(name="Info", action="preferences_help") + + buttons = ["OK", "Cancel"] + + if self.show_apply: + buttons = ["Apply"] + buttons + if self.show_help: + buttons = [help_action] + buttons + + # A tree editor for preferences nodes. + tree_editor = TreeEditor( + nodes=[ + TreeNode( + node_for=[PreferencesNode], + auto_open=False, + children="children", + label="name", + rename=False, + copy=False, + delete=False, + insert=False, + menu=None, + ), + ], + on_select=self._selection_changed, + editable=False, + hide_root=True, + selected="selected_node", + show_icons=False, + ) + + view = View( + HSplit( + Item( + name="root", + editor=tree_editor, + show_label=False, + width=250, + ), + Item( + name="selected_page", + # editor = WidgetEditor(), + show_label=False, + width=450, + style="custom", + ), + ), + buttons=buttons, + handler=PreferencesManagerHandler(model=self), + resizable=True, + title="Preferences", + width=0.3, + height=0.3, + kind="modal", + ) + self.selected_page = self.pages[0] + return view
+ + ########################################################################### + # 'PreferencesManager' interface. + ########################################################################### + + #### Trait properties ##################################################### + + def _get_root(self): + """ Property getter. """ + + # Sort the pages by the length of their category path. This makes it + # easy for us to create the preference hierarchy as we know that all of + # a node's ancestors will have already been created. + def sort_key(a): + # We have the guard because if the category is the empty string + # then split will still return a list containing one item (and not + # the empty list). + if len(a.category) == 0: + len_a = 0 + + else: + len_a = len(a.category.split("/")) + + return len_a + + self.pages.sort(key=sort_key) + + # Create a corresponding preference node hierarchy (the root of the + # hierachy is NOT displayed in the preference dialog). + # + # fixme: Currently we have to create a dummy page for the root node + # event though the root does not get shown in the tree! + root_page = PreferencesPage(name="Root", preferences_path="root") + root = PreferencesNode(page=root_page) + + for page in self.pages: + # Get the page's parent node. + parent = self._get_parent(root, page) + + # Add a child node representing the page. + parent.append(PreferencesNode(page=page)) + + return root + + #### Trait change handlers ################################################ + + def _selection_changed(self, new_selection): + self.selected_node = new_selection + + def _selected_node_changed(self, new): + """ Static trait change handler. """ + if self.selected_node: + self.selected_page = self.selected_node.page + + #### Methods ############################################################## + +
[docs] def apply(self): + """ Apply all changes made in the manager. """ + + for page in self.pages: + page.apply()
+ + ########################################################################### + # Private interface. + ########################################################################### + + def _get_parent(self, root, page): + """ Return the page's parent preference node. """ + + parent = root + + if len(page.category) > 0: + components = page.category.split("/") + for component in components: + parent = parent.lookup(component) + + return parent
+
+ +
+
+
+
+
+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/5.0/_modules/apptools/preferences/ui/preferences_node.html b/5.0/_modules/apptools/preferences/ui/preferences_node.html new file mode 100644 index 000000000..2aed6f3a0 --- /dev/null +++ b/5.0/_modules/apptools/preferences/ui/preferences_node.html @@ -0,0 +1,221 @@ + + + + + + + apptools.preferences.ui.preferences_node — Apptools Documentation + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +

Source code for apptools.preferences.ui.preferences_node

+# (C) Copyright 2005-2020 Enthought, Inc., Austin, TX
+# All rights reserved.
+#
+# This software is provided without warranty under the terms of the BSD
+# license included in LICENSE.txt and may be redistributed only under
+# the conditions described in the aforementioned license. The license
+# is also available online at http://www.enthought.com/licenses/BSD.txt
+#
+# Thanks for using Enthought open source!
+""" Abstract base class for a node in a preferences dialog. """
+
+# Enthought library imports.
+from traits.api import Delegate, Instance
+
+# Local imports.
+from .i_preferences_page import IPreferencesPage
+from .tree_item import TreeItem
+
+
+
[docs]class PreferencesNode(TreeItem): + """Abstract base class for a node in a preferences dialog. + + A preferences node has a name and an image which are used to represent the + node in a preferences dialog (usually in the form of a tree). + + """ + + #### 'PreferenceNode' interface ########################################### + + # The page's help identifier (optional). If a help Id *is* provided then + # there will be a 'Help' button shown on the preference page. + help_id = Delegate("page") + + # The page name (this is what is shown in the preferences dialog. + name = Delegate("page") + + # The page that we are a node for. + page = Instance(IPreferencesPage) + + ########################################################################### + # 'object' interface. + ########################################################################### + + def __str__(self): + """ Returns the string representation of the item. """ + + if self.page is None: + s = "root" + + else: + s = self.page.name + + return s + + __repr__ = __str__ + + ########################################################################### + # 'PreferencesNode' interface. + ########################################################################### + +
[docs] def create_page(self, parent): + """ Creates the preference page for this node. """ + + return self.page.create_control(parent)
+ +
[docs] def lookup(self, name): + """Returns the child of this node with the specified Id. + + Returns None if no such child exists. + + """ + + for node in self.children: + if node.name == name: + break + + else: + node = None + + return node
+ + ########################################################################### + # Debugging interface. + ########################################################################### + +
[docs] def dump(self, indent=""): + """ Pretty-print the node to stdout. """ + + print(indent, "Node", str(self)) + + for child in self.children: + child.dump(indent + " ")
+
+ +
+
+
+
+
+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/5.0/_modules/apptools/preferences/ui/preferences_page.html b/5.0/_modules/apptools/preferences/ui/preferences_page.html new file mode 100644 index 000000000..b9aa66f87 --- /dev/null +++ b/5.0/_modules/apptools/preferences/ui/preferences_page.html @@ -0,0 +1,233 @@ + + + + + + + apptools.preferences.ui.preferences_page — Apptools Documentation + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +

Source code for apptools.preferences.ui.preferences_page

+# (C) Copyright 2005-2020 Enthought, Inc., Austin, TX
+# All rights reserved.
+#
+# This software is provided without warranty under the terms of the BSD
+# license included in LICENSE.txt and may be redistributed only under
+# the conditions described in the aforementioned license. The license
+# is also available online at http://www.enthought.com/licenses/BSD.txt
+#
+# Thanks for using Enthought open source!
+""" A page in a preferences dialog. """
+
+
+# Enthought library imports.
+from apptools.preferences.api import PreferencesHelper
+from traits.api import Any, Dict, Str, provides
+
+# Local imports.
+from .i_preferences_page import IPreferencesPage
+
+
+
[docs]@provides(IPreferencesPage) +class PreferencesPage(PreferencesHelper): + """ A page in a preferences dialog. """ + + #### 'IPreferencesPage' interface ######################################### + + # The page's category (e.g. 'General/Appearance'). The empty string means + # that this is a top-level page. + category = Str + + # DEPRECATED: The help_id was never fully implemented, and it's been + # over two years (now 4/2009). The original goal was for the the Help + # button to automatically appear and connect to a help page with a + # help_id. Not removing the trait right now to avoid breaking code + # that may be checking for this. + # + # Use PreferencesManager.show_help and trait show_help metadata instead. + help_id = Str + + # The page name (this is what is shown in the preferences dialog. + name = Str + + #### Private interface #################################################### + + # The traits UI that represents the page. + _ui = Any + + # A dictionary containing the traits that have been changed since the + # last call to 'apply'. + _changed = Dict + + ########################################################################### + # 'IPreferencesPage' interface. + ########################################################################### + +
[docs] def apply(self): + """ Apply the page's preferences. """ + + path = self._get_path() + + for trait_name, value in self._changed.items(): + if self._is_preference_trait(trait_name): + self.preferences.set("%s.%s" % (path, trait_name), value) + + self._changed.clear()
+ + ########################################################################### + # Private interface. + ########################################################################### + + #### Trait change handlers ################################################ + + def _anytrait_changed(self, trait_name, old, new): + """Static trait change handler. + + This is an important override! In the base-class when a trait is + changed the preferences node is updated too. Here, we stop that from + happening and just make a note of what changes have been made. The + preferences node gets updated when the 'apply' method is called. + + """ + + if self._is_preference_trait(trait_name): + self._changed[trait_name] = new + elif trait_name.endswith("_items"): + # If the trait was a list or dict '_items' trait then just treat it + # as if the entire list or dict was changed. + trait_name = trait_name[:-6] + if self._is_preference_trait(trait_name): + self._changed[trait_name] = getattr(self, trait_name) + + # fixme: Pretty much duplicated in 'PreferencesHelper' (except for the + # class name of course!). + def _is_preference_trait(self, trait_name): + """ Return True if a trait represents a preference value. """ + + if ( + trait_name.startswith("_") + or trait_name.endswith("_") + or trait_name in PreferencesPage.class_traits() + ): + return False + + return trait_name in self.editable_traits()
+
+ +
+
+
+
+
+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/5.0/_modules/apptools/preferences/ui/tree_item.html b/5.0/_modules/apptools/preferences/ui/tree_item.html new file mode 100644 index 000000000..ffcc109ca --- /dev/null +++ b/5.0/_modules/apptools/preferences/ui/tree_item.html @@ -0,0 +1,269 @@ + + + + + + + apptools.preferences.ui.tree_item — Apptools Documentation + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +

Source code for apptools.preferences.ui.tree_item

+# (C) Copyright 2005-2020 Enthought, Inc., Austin, TX
+# All rights reserved.
+#
+# This software is provided without warranty under the terms of the BSD
+# license included in LICENSE.txt and may be redistributed only under
+# the conditions described in the aforementioned license. The license
+# is also available online at http://www.enthought.com/licenses/BSD.txt
+#
+# Thanks for using Enthought open source!
+""" A generic base-class for items in a tree data structure.
+
+An example:-
+
+root = TreeItem(data='Root')
+
+fruit = TreeItem(data='Fruit')
+fruit.append(TreeItem(data='Apple', allows_children=False))
+fruit.append(TreeItem(data='Orange', allows_children=False))
+fruit.append(TreeItem(data='Pear', allows_children=False))
+root.append(fruit)
+
+veg = TreeItem(data='Veg')
+veg.append(TreeItem(data='Carrot', allows_children=False))
+veg.append(TreeItem(data='Cauliflower', allows_children=False))
+veg.append(TreeItem(data='Sprout', allows_children=False))
+root.append(veg)
+
+"""
+
+
+# Enthought library imports.
+from traits.api import Any, Bool, HasTraits, Instance, List, Property
+
+
+
[docs]class TreeItem(HasTraits): + """ A generic base-class for items in a tree data structure. """ + + #### 'TreeItem' interface ################################################# + + # Does this item allow children? + allows_children = Bool(True) + + # The item's children. + children = List(Instance("TreeItem")) + + # Arbitrary data associated with the item. + data = Any + + # Does the item have any children? + has_children = Property(Bool) + + # The item's parent. + parent = Instance("TreeItem") + + ########################################################################### + # 'object' interface. + ########################################################################### + + def __str__(self): + """ Returns the informal string representation of the object. """ + + if self.data is None: + s = "" + + else: + s = str(self.data) + + return s + + ########################################################################### + # 'TreeItem' interface. + ########################################################################### + + #### Properties ########################################################### + + # has_children + def _get_has_children(self): + """ True iff the item has children. """ + + return len(self.children) != 0 + + #### Methods ############################################################## + +
[docs] def append(self, child): + """Appends a child to this item. + + This removes the child from its current parent (if it has one). + + """ + + return self.insert(len(self.children), child)
+ +
[docs] def insert(self, index, child): + """Inserts a child into this item at the specified index. + + This removes the child from its current parent (if it has one). + + """ + + if child.parent is not None: + child.parent.remove(child) + + child.parent = self + self.children.insert(index, child) + + return child
+ +
[docs] def remove(self, child): + """ Removes a child from this item. """ + + child.parent = None + self.children.remove(child) + + return child
+ +
[docs] def insert_before(self, before, child): + """Inserts a child into this item before the specified item. + + This removes the child from its current parent (if it has one). + + """ + + index = self.children.index(before) + + self.insert(index, child) + + return (index, child)
+ +
[docs] def insert_after(self, after, child): + """Inserts a child into this item after the specified item. + + This removes the child from its current parent (if it has one). + + """ + + index = self.children.index(after) + + self.insert(index + 1, child) + + return (index, child)
+
+ +
+
+
+
+
+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/5.0/_modules/apptools/preferences/ui/widget_editor.html b/5.0/_modules/apptools/preferences/ui/widget_editor.html new file mode 100644 index 000000000..431d64f87 --- /dev/null +++ b/5.0/_modules/apptools/preferences/ui/widget_editor.html @@ -0,0 +1,232 @@ + + + + + + + apptools.preferences.ui.widget_editor — Apptools Documentation + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +

Source code for apptools.preferences.ui.widget_editor

+# (C) Copyright 2005-2020 Enthought, Inc., Austin, TX
+# All rights reserved.
+#
+# This software is provided without warranty under the terms of the BSD
+# license included in LICENSE.txt and may be redistributed only under
+# the conditions described in the aforementioned license. The license
+# is also available online at http://www.enthought.com/licenses/BSD.txt
+#
+# Thanks for using Enthought open source!
+""" An instance editor that allows total control over widget creation. """
+
+
+# Enthought library imports.
+from traits.api import Any
+from traitsui.api import EditorFactory
+from traitsui.toolkit import toolkit_object
+Editor = toolkit_object('editor:Editor')
+
+
+class _WidgetEditor(Editor):
+    """ An instance editor that allows total control over widget creation. """
+
+    #### '_WidgetEditor' interface ############################################
+
+    # The toolkit-specific parent of the editor.
+    parent = Any
+
+    ###########################################################################
+    # '_WidgetEditor' interface.
+    ###########################################################################
+
+    def init(self, parent):
+        """ Initialize the editor. """
+
+        self.parent = parent
+
+        # fixme: What if there are no pages?!?
+        page = self.object.pages[0]
+
+        # Create the editor's control.
+        self.control = page.create_control(parent)
+
+        # Listen for the page being changed.
+        self.object.on_trait_change(self._on_page_changed, "selected_page")
+
+    def dispose(self):
+        """ Dispose of the editor. """
+
+        page = self.object.selected_page
+        page.destroy_control()
+
+    def update_editor(self):
+        """ Update the editor. """
+
+        pass
+
+    ###########################################################################
+    # Private interface.
+    ###########################################################################
+
+    def _on_page_changed(self, obj, trait_name, old, new):
+        """ Dynamic trait change handler. """
+
+        if old is not None:
+            old.destroy_control()
+
+        if new is not None:
+            self.control = new.create_control(self.parent)
+
+
+
[docs]class WidgetEditor(EditorFactory): + """ A factory widget editors. """ + + ########################################################################### + # 'object' interface. + ########################################################################### + + def __call__(self, *args, **traits): + """ Call the object. """ + + return self.trait_set(**traits) + + ########################################################################### + # 'EditorFactory' interface. + ########################################################################### + +
[docs] def simple_editor(self, ui, object, name, description, parent): + """ Create a simple editor. """ + + editor = _WidgetEditor( + parent, + factory=self, + ui=ui, + object=object, + name=name, + description=description, + ) + + return editor
+ + custom_editor = simple_editor + text_editor = simple_editor + readonly_editor = simple_editor
+
+ +
+
+
+
+
+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/5.0/_modules/apptools/scripting/package_globals.html b/5.0/_modules/apptools/scripting/package_globals.html new file mode 100644 index 000000000..34096d085 --- /dev/null +++ b/5.0/_modules/apptools/scripting/package_globals.html @@ -0,0 +1,159 @@ + + + + + + + apptools.scripting.package_globals — Apptools Documentation + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +

Source code for apptools.scripting.package_globals

+# (C) Copyright 2005-2020 Enthought, Inc., Austin, TX
+# All rights reserved.
+#
+# This software is provided without warranty under the terms of the BSD
+# license included in LICENSE.txt and may be redistributed only under
+# the conditions described in the aforementioned license. The license
+# is also available online at http://www.enthought.com/licenses/BSD.txt
+#
+# Thanks for using Enthought open source!
+"""
+Globals for the scripting package.
+"""
+
+
+# The global recorder.
+_recorder = None
+
+
+
[docs]def get_recorder(): + """Return the global recorder. Does not create a new one if none + exists. + """ + global _recorder + return _recorder
+ + +
[docs]def set_recorder(rec): + """Set the global recorder instance.""" + global _recorder + _recorder = rec
+
+ +
+
+
+
+
+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/5.0/_modules/apptools/scripting/recordable.html b/5.0/_modules/apptools/scripting/recordable.html new file mode 100644 index 000000000..324ccca9d --- /dev/null +++ b/5.0/_modules/apptools/scripting/recordable.html @@ -0,0 +1,186 @@ + + + + + + + apptools.scripting.recordable — Apptools Documentation + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +

Source code for apptools.scripting.recordable

+# (C) Copyright 2005-2020 Enthought, Inc., Austin, TX
+# All rights reserved.
+#
+# This software is provided without warranty under the terms of the BSD
+# license included in LICENSE.txt and may be redistributed only under
+# the conditions described in the aforementioned license. The license
+# is also available online at http://www.enthought.com/licenses/BSD.txt
+#
+# Thanks for using Enthought open source!
+"""
+Decorator to mark functions and methods as recordable.
+"""
+
+from .package_globals import get_recorder
+
+
+# Guard to ensure that only the outermost recordable call is recorded
+# and nested calls ignored.
+_outermost_call = True
+
+
+
[docs]def recordable(func): + """A decorator that wraps a function into one that is recordable. + + This will record the function only if the global recorder has been + set via a `set_recorder` function call. + """ + + def _wrapper(*args, **kw): + """A wrapper returned to replace the decorated function.""" + global _outermost_call + + # Boolean to specify if the method was recorded or not. + record = False + if _outermost_call: + # Get the recorder. + rec = get_recorder() + if rec is not None: + _outermost_call = False + # Record the method if recorder is available. + record = True + try: + result = rec.record_function(func, args, kw) + finally: + _outermost_call = True + if not record: + # If the method was not recorded, just call it. + result = func(*args, **kw) + + return result + + # Mimic the actual function. + _wrapper.__name__ = func.__name__ + _wrapper.__doc__ = func.__doc__ + _wrapper.__dict__.update(func.__dict__) + + return _wrapper
+
+ +
+
+
+
+
+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/5.0/_modules/apptools/scripting/recorder.html b/5.0/_modules/apptools/scripting/recorder.html new file mode 100644 index 000000000..2c84d2f66 --- /dev/null +++ b/5.0/_modules/apptools/scripting/recorder.html @@ -0,0 +1,874 @@ + + + + + + + apptools.scripting.recorder — Apptools Documentation + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +

Source code for apptools.scripting.recorder

+# (C) Copyright 2005-2020 Enthought, Inc., Austin, TX
+# All rights reserved.
+#
+# This software is provided without warranty under the terms of the BSD
+# license included in LICENSE.txt and may be redistributed only under
+# the conditions described in the aforementioned license. The license
+# is also available online at http://www.enthought.com/licenses/BSD.txt
+#
+# Thanks for using Enthought open source!
+"""
+Code to support recording to a readable and executable Python script.
+
+FIXME:
+    - Support for dictionaries?
+"""
+
+import builtins
+import warnings
+
+from traits.api import (
+    HasTraits,
+    List,
+    Str,
+    Dict,
+    Bool,
+    Property,
+    Int,
+    Instance,
+)
+from traits.util.camel_case import camel_case_to_python
+
+
+###############################################################################
+# `_RegistryData` class.
+###############################################################################
+class _RegistryData(HasTraits):
+    # Object's script ID
+    script_id = Property(Str)
+
+    # Path to object in object hierarchy.
+    path = Property(Str)
+
+    # Parent data for this object if any.
+    parent_data = Instance("_RegistryData", allow_none=True)
+
+    # The name of the trait on the parent which is this object.
+    trait_name_on_parent = Str("")
+
+    # List of traits we are listening for on this object.
+    names = List(Str)
+
+    # Nested recordable instances on the object.
+    sub_recordables = List(Str)
+
+    # List of traits that are lists.
+    list_names = List(Str)
+
+    _script_id = Str("")
+
+    ###########################################################################
+    # Non-public interface.
+    ###########################################################################
+    def _get_path(self):
+        pdata = self.parent_data
+        path = ""
+        if pdata is not None:
+            pid = pdata.script_id
+            ppath = pdata.path
+            tnop = self.trait_name_on_parent
+            if "[" in tnop:
+                # If the object is a nested object through an iterator,
+                # we instantiate it and don't refer to it through the
+                # path, this makes scripting convenient.
+                if len(ppath) == 0:
+                    path = pid + "." + tnop
+                else:
+                    path = ppath + "." + tnop
+            else:
+                path = ppath + "." + tnop
+
+        return path
+
+    def _get_script_id(self):
+        sid = self._script_id
+        if len(sid) == 0:
+            pdata = self.parent_data
+            sid = pdata.script_id + "." + self.trait_name_on_parent
+        return sid
+
+    def _set_script_id(self, id):
+        self._script_id = id
+
+
+###############################################################################
+# `RecorderError` class.
+###############################################################################
+
[docs]class RecorderError(Exception): + pass
+ + +############################################################################### +# `Recorder` class. +############################################################################### +
[docs]class Recorder(HasTraits): + + # The lines of code recorded. + lines = List(Str) + + # Are we recording or not? + recording = Bool(False, desc="if script recording is enabled or not") + + # The Python script we have recorded so far. This is just a + # convenience trait for the `get_code()` method. + script = Property(Str) + + ######################################## + # Private traits. + + # Dict used to store information on objects registered. It stores a + # unique name for the object and its path in the object hierarchy + # traversed. + _registry = Dict + + # Reverse registry with keys as script_id and object as value. + _reverse_registry = Dict + + # A mapping to generate unique names for objects. The key is the + # name used (which is something derived from the class name of the + # object) and the value is an integer describing the number of times + # that variable name has been used earlier. + _name_map = Dict(Str, Int) + + # A list of special reserved script IDs. This is handy when you + # want a particular object to have an easy to read script ID and not + # the default one based on its class name. This leads to slightly + # easier to read scripts. + _special_ids = List + + # What are the known names in the script? By known names we mean + # names which are actually bound to objects. + _known_ids = List(Str) + + # The known types in the namespace. + _known_types = List(Str) + + # A guard to check if we are currently in a recorded function call, + # in which case we don't want to do any recording. + _in_function = Bool(False) + + ########################################################################### + # `Recorder` interface. + ########################################################################### +
[docs] def record(self, code): + """Record a string to be stored to the output file. + + Parameters + ---------- + + code : str + A string of text. + """ + if self.recording and not self._in_function: + lines = self.lines + # Analyze the code and add extra code if needed. + self._analyze_code(code) + # Add the code. + lines.append(code)
+ +
[docs] def register( + self, + object, + parent=None, + trait_name_on_parent="", + ignore=None, + known=False, + script_id=None, + ): + """Register an object with the recorder. This sets up the + object for recording. + + By default all traits (except those starting and ending with + '_') are recorded. For attributes that are themselves + recordable, one may mark traits with a 'record' metadata as + follows: + + - If metadata `record=False` is set, the nested object will not be + recorded. + + - If `record=True`, then that object is also recorded if it is + not `None`. + + If the object is a list or dict that is marked with + `record=True`, the list is itself not listened to for changes + but all its contents are registered. + + If the `object` has a trait named `recorder` then this recorder + instance will be set to it if possible. + + Parameters + ---------- + + object : Instance(HasTraits) + The object to register in the registry. + + parent : Instance(HasTraits) + An optional parent object in which `object` is contained + + trait_name_on_parent : str + An optional trait name of the `object` in the `parent`. + + ignore : list(str) + An optional list of trait names on the `object` to be + ignored. + + known : bool + Optional specification if the `object` id is known on the + interpreter. This is needed if you are manually injecting + code to define/create an object. + + script_id : str + Optionally specify a script_id to use for this object. It + is not guaranteed that this ID will be used since it may + already be in use. + """ + registry = self._registry + + # Do nothing if the object is already registered. + if object in registry: + return + + # When parent is specified the trait_name_on_parent must also be. + if parent is not None: + assert len(trait_name_on_parent) > 0 + + if ignore is None: + ignore = [] + + if isinstance(object, HasTraits): + # Always ignore these. + ignore.extend(["trait_added", "trait_modified"]) + + sub_recordables = list(object.traits(record=True).keys()) + # Find all the trait names we must ignore. + ignore.extend(object.traits(record=False).keys()) + # The traits to listen for. + tnames = [ + t + for t in object.trait_names() + if not t.startswith("_") + and not t.endswith("_") + and t not in ignore + ] + # Find all list traits. + trts = object.traits() + list_names = [] + for t in tnames: + tt = trts[t].trait_type + if ( + hasattr(tt, "default_value_type") + and tt.default_value_type == 5 + ): + list_names.append(t) + else: + # No traits, so we can't do much. + sub_recordables = [] + tnames = [] + list_names = [] + + # Setup the registry data. + + # If a script id is supplied try and use it. + sid = "" + if script_id is not None: + r_registry = self._reverse_registry + while script_id in r_registry: + script_id = "%s1" % script_id + sid = script_id + # Add the chosen id to special_id list. + self._special_ids.append(sid) + + if parent is None: + pdata = None + if len(sid) == 0: + sid = self._get_unique_name(object) + else: + pdata = self._get_registry_data(parent) + tnop = trait_name_on_parent + if "[" in tnop: + # If the object is a nested object through an iterator, + # we instantiate it and don't refer to it through the + # path, this makes scripting convenient. + sid = self._get_unique_name(object) + + # Register the object with the data. + data = _RegistryData( + script_id=sid, + parent_data=pdata, + trait_name_on_parent=trait_name_on_parent, + names=tnames, + sub_recordables=sub_recordables, + list_names=list_names, + ) + registry[object] = data + + # Now get the script id of the object -- note that if sid is '' + # above then the script_id is computed from that of the parent. + sid = data.script_id + # Setup reverse registry so we can get the object from the + # script_id. + self._reverse_registry[sid] = object + + # Record the script_id if the known argument is explicitly set to + # True. + if known: + self._known_ids.append(sid) + + # Try and set the recorder attribute if necessary. + if hasattr(object, "recorder"): + try: + object.recorder = self + except Exception as e: + msg = "Cannot set 'recorder' trait of object %r: " "%s" % ( + object, + e, + ) + warnings.warn(msg, warnings.RuntimeWarning) + + if isinstance(object, HasTraits): + # Add handler for lists. + for name in list_names: + object.on_trait_change( + self._list_items_listner, "%s_items" % name + ) + + # Register all sub-recordables. + for name in sub_recordables: + obj = getattr(object, name) + if isinstance(obj, list): + # Don't register the object itself but register its + # children. + for i, child in enumerate(obj): + attr = "%s[%d]" % (name, i) + self.register( + child, parent=object, trait_name_on_parent=attr + ) + elif obj is not None: + self.register( + obj, parent=object, trait_name_on_parent=name + ) + # Listen for changes to the trait itself so the newly + # assigned object can also be listened to. + object.on_trait_change(self._object_changed_handler, name) + # Now add listner for the object itself. + object.on_trait_change(self._listner, tnames)
+ +
[docs] def unregister(self, object): + """Unregister the given object from the recorder. This inverts + the logic of the `register(...)` method. + """ + registry = self._registry + # Do nothing if the object isn't registered. + if object not in registry: + return + + data = registry[object] + + # Try and unset the recorder attribute if necessary. + if hasattr(object, "recorder"): + try: + object.recorder = None + except Exception as e: + msg = "Cannot unset 'recorder' trait of object %r:" "%s" % ( + object, + e, + ) + warnings.warn(msg, warnings.RuntimeWarning) + + if isinstance(object, HasTraits): + # Remove all list_items handlers. + for name in data.list_names: + object.on_trait_change( + self._list_items_listner, "%s_items" % name, remove=True + ) + + # Unregister all sub-recordables. + for name in data.sub_recordables: + obj = getattr(object, name) + if isinstance(obj, list): + # Unregister the children. + for i, child in enumerate(obj): + self.unregister(child) + elif obj is not None: + self.unregister(obj) + # Remove the trait handler for trait assignments. + object.on_trait_change( + self._object_changed_handler, name, remove=True + ) + # Now remove listner for the object itself. + object.on_trait_change(self._listner, data.names, remove=True) + + # Remove the object data from the registry etc. + if data.script_id in self._known_ids: + self._known_ids.remove(data.script_id) + del self._reverse_registry[data.script_id] + del registry[object]
+ +
[docs] def save(self, file): + """Save the recorded lines to the given file. It does not close + the file. + """ + file.write(self.get_code()) + file.flush()
+ +
[docs] def record_function(self, func, args, kw): + """Record a function call given the function and its + arguments.""" + if self.recording and not self._in_function: + # Record the function name and arguments. + call_str = self._function_as_string(func, args, kw) + # Call the function. + try: + self._in_function = True + result = func(*args, **kw) + finally: + self._in_function = False + + # Register the result if it is not None. + if func.__name__ == "__init__": + f_self = args[0] + code = self._import_class_string(f_self.__class__) + self.lines.append(code) + return_str = self._registry.get(f_self).script_id + else: + return_str = self._return_as_string(result) + if len(return_str) > 0: + self.lines.append("%s = %s" % (return_str, call_str)) + else: + self.lines.append("%s" % (call_str)) + else: + result = func(*args, **kw) + return result
+ +
[docs] def ui_save(self): + """Save recording to file, pop up a UI dialog to find out where + and close the file when done. + """ + from pyface.api import FileDialog, OK + + wildcard = "Python files (*.py)|*.py|" + FileDialog.WILDCARD_ALL + dialog = FileDialog( + title="Save Script", action="save as", wildcard=wildcard + ) + if dialog.open() == OK: + fname = dialog.path + f = open(fname, "w") + self.save(f) + f.close()
+ +
[docs] def clear(self): + """Clears all previous recorded state and unregisters all + registered objects.""" + # First unregister any registered objects. + registry = self._registry + while len(registry) > 0: + self.unregister(list(registry.keys())[0]) + # Clear the various lists. + self.lines[:] = [] + self._registry.clear() + self._known_ids[:] = [] + self._name_map.clear() + self._reverse_registry.clear() + self._known_types[:] = [] + self._special_ids[:] = []
+ +
[docs] def get_code(self): + """Returns the recorded lines as a string of printable code.""" + return "\n".join(self.lines) + "\n"
+ +
[docs] def is_registered(self, object): + """Returns True if the given object is registered with the + recorder.""" + return object in self._registry
+ +
[docs] def get_script_id(self, object): + """Returns the script_id of a registered object. Useful when + you want to manually add a record statement.""" + return self._get_registry_data(object).script_id
+ +
[docs] def get_object_path(self, object): + """Returns the path in the object hierarchy of a registered + object. Useful for debugging.""" + return self._get_registry_data(object).path
+ +
[docs] def write_script_id_in_namespace(self, script_id): + """If a script_id is not known in the current script's namespace, + this sets it using the path of the object or actually + instantiating it. If this is not possible (since the script_id + matches no existing object), nothing is recorded but the + framework is notified that the particular script_id is available + in the namespace. This is useful when you want to inject code + in the namespace to create a particular object. + """ + if not self.recording: + return + known_ids = self._known_ids + if script_id not in known_ids: + obj = self._reverse_registry.get(script_id) + # Add the ID to the known_ids. + known_ids.append(script_id) + if obj is not None: + data = self._registry.get(obj) + result = "" + if len(data.path) > 0: + # Record code for instantiation of object. + result = "%s = %s" % (script_id, data.path) + else: + # This is not the best thing to do but better than + # nothing. + result = self._import_class_string(obj.__class__) + cls = obj.__class__.__name__ + result += "\n%s = %s()" % (script_id, cls) + + if len(result) > 0: + self.lines.extend(result.split("\n"))
+ + ########################################################################### + # Non-public interface. + ########################################################################### + def _get_unique_name(self, obj): + """Return a unique object name (a string). Note that this does + not cache the object, so if called with the same object 3 times + you'll get three different names. + """ + cname = obj.__class__.__name__ + nm = self._name_map + result = "" + builtin = False + if cname in builtins.__dict__: + builtin = True + if hasattr(obj, "__name__"): + cname = obj.__name__ + else: + cname = camel_case_to_python(cname) + + special_ids = self._special_ids + while len(result) == 0 or result in special_ids: + if cname in nm: + id = nm[cname] + 1 + nm[cname] = id + result = "%s%d" % (cname, id) + else: + nm[cname] = 0 + # The first id doesn't need a number if it isn't builtin. + if builtin: + result = "%s0" % (cname) + else: + result = cname + return result + + def _get_registry_data(self, object): + """Get the data for an object from registry.""" + data = self._registry.get(object) + if data is None: + msg = ( + "Recorder: Can't get script_id since object %s not registered" + ) + raise RecorderError(msg % (object)) + return data + + def _listner(self, object, name, old, new): + """The listner for trait changes on an object. + + This is called by child listners or when any of the recordable + object's traits change when recording to a script is enabled. + + Parameters: + ----------- + + object : Object which has changed. + + name : extended name of attribute that changed. + + old : Old value. + + new : New value. + + """ + if self.recording and not self._in_function: + new_repr = repr(new) + sid = self._get_registry_data(object).script_id + if len(sid) == 0: + msg = "%s = %r" % (name, new) + else: + msg = "%s.%s = %r" % (sid, name, new) + if new_repr.startswith("<") and new_repr.endswith(">"): + self.record("# " + msg) + else: + self.record(msg) + + def _list_items_listner(self, object, name, old, event): + """The listner for *_items on list traits of the object.""" + # Set the path of registered objects in the modified list and + # all their children. This is done by unregistering the object + # and re-registering them. This is slow but. + registry = self._registry + sid = registry.get(object).script_id + trait_name = name[:-6] + items = getattr(object, trait_name) + for (i, item) in enumerate(items): + if item in registry: + data = registry.get(item) + tnop = data.trait_name_on_parent + if len(tnop) > 0: + data.trait_name_on_parent = "%s[%d]" % (trait_name, i) + + # Record the change. + if self.recording and not self._in_function: + index = event.index + removed = event.removed + added = event.added + nr = len(removed) + slice = "[%d:%d]" % (index, index + nr) + rhs = [self._object_as_string(item) for item in added] + rhs = ", ".join(rhs) + obj = "%s.%s" % (sid, name[:-6]) + msg = "%s%s = [%s]" % (obj, slice, rhs) + self.record(msg) + + def _object_changed_handler(self, object, name, old, new): + """Called when a child recordable object has been reassigned.""" + registry = self._registry + if old is not None: + if old in registry: + self.unregister(old) + if new is not None: + if new not in registry: + self.register(new, parent=object, trait_name_on_parent=name) + + def _get_script(self): + return self.get_code() + + def _analyze_code(self, code): + """Analyze the code and return extra code if needed.""" + lhs = "" + try: + lhs = code.split()[0] + except IndexError: + pass + + if "." in lhs: + ob_name = lhs.split(".")[0] + self.write_script_id_in_namespace(ob_name) + + def _function_as_string(self, func, args, kw): + """Return a string representing the function call.""" + func_name = func.__name__ + func_code = func.__code__ + # Even if func is really a decorated method it never shows up as + # a bound or unbound method here, so we have to inspect the + # argument names to figure out if this is a method or function. + if func_code.co_argcount > 0 and func_code.co_varnames[0] == "self": + # This is a method, the first argument is bound to self. + f_self = args[0] + # Convert the remaining arguments to strings. + argl = [self._object_as_string(arg) for arg in args[1:]] + + # If this is __init__ we special case it. + if func_name == "__init__": + # Register the object. + self.register(f_self, known=True) + func_name = f_self.__class__.__name__ + else: + sid = self._object_as_string(f_self) + func_name = "%s.%s" % (sid, func_name) + else: + argl = [self._object_as_string(arg) for arg in args] + + # Convert the keyword args. + kwl = [ + "%s=%s" % (key, self._object_as_string(value)) + for key, value in kw.items() + ] + argl.extend(kwl) + + # Make a string representation of the args, kw. + argstr = ", ".join(argl) + return "%s(%s)" % (func_name, argstr) + + def _is_arbitrary_object(self, object): + """Return True if the object is an arbitrary non-primitive object. + + We assume that if the hex id of the object is in its string + representation then it is an arbitrary object. + """ + ob_id = id(object) + orepr = repr(object) + hex_id = "%x" % ob_id + return hex_id.upper() in orepr.upper() + + def _object_as_string(self, object): + """Return a string representing the object.""" + registry = self._registry + if object in registry: + # Return script id if the object is known; create the script + # id on the namespace if needed before that. + sid = registry.get(object).script_id + base_id = sid.split(".")[0] + self.write_script_id_in_namespace(base_id) + return sid + else: + if not self._is_arbitrary_object(object): + return repr(object) + + # If we get here, we just register the object and call ourselves + # again to do the needful. + self.register(object) + return self._object_as_string(object) + + def _return_as_string(self, object): + """Return a string given a returned object from a function.""" + result = "" + ignore = (float, complex, bool, int, str) + if object is not None and type(object) not in ignore: + # If object is not know, register it. + registry = self._registry + if object not in registry: + self.register(object) + result = registry.get(object).script_id + # Since this is returned it is known on the namespace. + known_ids = self._known_ids + if result not in known_ids: + known_ids.append(result) + return result + + def _import_class_string(self, cls): + """Import a class if needed.""" + cname = cls.__name__ + result = "" + if cname not in builtins.__dict__: + mod = cls.__module__ + typename = "%s.%s" % (mod, cname) + if typename not in self._known_types: + result = "from %s import %s" % (mod, cname) + self._known_types.append(typename) + return result
+
+ +
+
+
+
+
+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/5.0/_modules/apptools/scripting/recorder_with_ui.html b/5.0/_modules/apptools/scripting/recorder_with_ui.html new file mode 100644 index 000000000..8323559a9 --- /dev/null +++ b/5.0/_modules/apptools/scripting/recorder_with_ui.html @@ -0,0 +1,226 @@ + + + + + + + apptools.scripting.recorder_with_ui — Apptools Documentation + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +

Source code for apptools.scripting.recorder_with_ui

+# (C) Copyright 2005-2020 Enthought, Inc., Austin, TX
+# All rights reserved.
+#
+# This software is provided without warranty under the terms of the BSD
+# license included in LICENSE.txt and may be redistributed only under
+# the conditions described in the aforementioned license. The license
+# is also available online at http://www.enthought.com/licenses/BSD.txt
+#
+# Thanks for using Enthought open source!
+"""
+A Recorder subclass that presents a simple user interface.
+"""
+
+from traits.api import Code, Button, Int, on_trait_change, Any
+from traitsui.api import View, Item, Group, HGroup, CodeEditor, spring, Handler
+
+from .recorder import Recorder
+
+
+###############################################################################
+# `CloseHandler` class.
+###############################################################################
+
[docs]class CloseHandler(Handler): + """This class cleans up after the UI for the recorder is closed.""" + +
[docs] def close(self, info, is_ok): + """This method is invoked when the user closes the UI.""" + recorder = info.object + recorder.on_ui_close() + return True
+ + +############################################################################### +# `RecorderWithUI` class. +############################################################################### +
[docs]class RecorderWithUI(Recorder): + """ + This class represents a Recorder but with a simple user interface. + """ + + # The code to display + code = Code(editor=CodeEditor(line="current_line")) + + # Button to save script to file. + save_script = Button("Save Script") + + # The current line to show, used by the editor. + current_line = Int + + # The root object which is being recorded. + root = Any + + ######################################## + # Traits View. + view = View( + Group( + HGroup( + Item("recording", show_label=True), + spring, + Item("save_script", show_label=False), + ), + Group(Item("code", show_label=False)), + ), + width=600, + height=360, + id="apptools.scripting.recorder_with_ui", + buttons=["Cancel"], + resizable=True, + handler=CloseHandler(), + ) + + ###################################################################### + # RecorderWithUI interface. + ###################################################################### +
[docs] def on_ui_close(self): + """Called from the CloseHandler when the UI is closed. This + method basically stops the recording. + """ + from .util import stop_recording + from .package_globals import get_recorder + + if get_recorder() is self: + stop_recording(self.root, save=False) + else: + self.recording = False + self.unregister(self.root)
+ + ###################################################################### + # Non-public interface. + ###################################################################### + @on_trait_change("lines[]") + def _update_code(self): + self.code = self.get_code() + self.current_line = len(self.lines) + 1 + + def _save_script_fired(self): + self.ui_save()
+
+ +
+
+
+
+
+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/5.0/_modules/apptools/scripting/util.html b/5.0/_modules/apptools/scripting/util.html new file mode 100644 index 000000000..39a0ea9ef --- /dev/null +++ b/5.0/_modules/apptools/scripting/util.html @@ -0,0 +1,186 @@ + + + + + + + apptools.scripting.util — Apptools Documentation + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +

Source code for apptools.scripting.util

+# (C) Copyright 2005-2020 Enthought, Inc., Austin, TX
+# All rights reserved.
+#
+# This software is provided without warranty under the terms of the BSD
+# license included in LICENSE.txt and may be redistributed only under
+# the conditions described in the aforementioned license. The license
+# is also available online at http://www.enthought.com/licenses/BSD.txt
+#
+# Thanks for using Enthought open source!
+"""Simple utility functions provided by the scripting API.
+"""
+
+from .recorder import Recorder
+from .recorder_with_ui import RecorderWithUI
+from .package_globals import get_recorder, set_recorder
+
+
+###############################################################################
+# Utility functions.
+###############################################################################
+
[docs]def start_recording(object, ui=True, **kw): + """Convenience function to start recording. Returns the recorder. + + Parameters + ---------- + + object : object to record. + + ui : bool specifying if a UI is to be shown or not + + kw : Keyword arguments to pass to the register function of the + recorder. + """ + if ui: + r = RecorderWithUI(root=object) + r.edit_traits(kind="live") + else: + r = Recorder() + # Set the global recorder. + set_recorder(r) + r.recording = True + r.register(object, **kw) + return r
+ + +
[docs]def stop_recording(object, save=True): + """Stop recording the object. If `save` is `True`, this will pop up + a UI to ask where to save the script. + """ + recorder = get_recorder() + recorder.unregister(object) + recorder.recording = False + # Set the global recorder back to None + set_recorder(None) + # Save the script. + if save: + recorder.ui_save()
+
+ +
+
+
+
+
+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/5.0/_modules/apptools/selection/errors.html b/5.0/_modules/apptools/selection/errors.html new file mode 100644 index 000000000..441880612 --- /dev/null +++ b/5.0/_modules/apptools/selection/errors.html @@ -0,0 +1,172 @@ + + + + + + + apptools.selection.errors — Apptools Documentation + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +

Source code for apptools.selection.errors

+# (C) Copyright 2005-2020 Enthought, Inc., Austin, TX
+# All rights reserved.
+#
+# This software is provided without warranty under the terms of the BSD
+# license included in LICENSE.txt and may be redistributed only under
+# the conditions described in the aforementioned license. The license
+# is also available online at http://www.enthought.com/licenses/BSD.txt
+#
+# Thanks for using Enthought open source!
+
+
+
[docs]class ProviderNotRegisteredError(Exception): + """ Raised when a provider is requested by ID and not found. """ + + def __init__(self, provider_id): + self.provider_id = provider_id + + def __str__(self): + msg = "Selection provider with ID '{id}' not found." + return msg.format(id=self.provider_id)
+ + +
[docs]class IDConflictError(Exception): + """ Raised when a provider is added and its ID is already registered. """ + + def __init__(self, provider_id): + self.provider_id = provider_id + + def __str__(self): + msg = "A selection provider with ID '{id}' is already registered." + return msg.format(id=self.provider_id)
+ + +
[docs]class ListenerNotConnectedError(Exception): + """ Raised when a listener that was never connected is disconnected. """ + + def __init__(self, provider_id, listener): + self.provider_id = provider_id + self.listener = listener + + def __str__(self): + msg = "Selection listener {lr} is not connected to provider '{id}'." + return msg.format(lr=self.listener, id=self.provider_id)
+
+ +
+
+
+
+
+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/5.0/_modules/apptools/selection/i_selection.html b/5.0/_modules/apptools/selection/i_selection.html new file mode 100644 index 000000000..bcb99d64a --- /dev/null +++ b/5.0/_modules/apptools/selection/i_selection.html @@ -0,0 +1,159 @@ + + + + + + + apptools.selection.i_selection — Apptools Documentation + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +

Source code for apptools.selection.i_selection

+# (C) Copyright 2005-2020 Enthought, Inc., Austin, TX
+# All rights reserved.
+#
+# This software is provided without warranty under the terms of the BSD
+# license included in LICENSE.txt and may be redistributed only under
+# the conditions described in the aforementioned license. The license
+# is also available online at http://www.enthought.com/licenses/BSD.txt
+#
+# Thanks for using Enthought open source!
+from traits.api import Interface, List, Str
+
+
+
[docs]class ISelection(Interface): + """ Collection of selected items. """ + + #: ID of the selection provider that created this selection object. + provider_id = Str + +
[docs] def is_empty(self): + """ Is the selection empty? """
+ + +
[docs]class IListSelection(ISelection): + """ Selection for ordered sequences of items. """ + + #: Selected objects. + items = List + + #: Indices of the selected objects in the selection provider. + indices = List
+
+ +
+
+
+
+
+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/5.0/_modules/apptools/selection/i_selection_provider.html b/5.0/_modules/apptools/selection/i_selection_provider.html new file mode 100644 index 000000000..d2ffa29bc --- /dev/null +++ b/5.0/_modules/apptools/selection/i_selection_provider.html @@ -0,0 +1,176 @@ + + + + + + + apptools.selection.i_selection_provider — Apptools Documentation + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +

Source code for apptools.selection.i_selection_provider

+# (C) Copyright 2005-2020 Enthought, Inc., Austin, TX
+# All rights reserved.
+#
+# This software is provided without warranty under the terms of the BSD
+# license included in LICENSE.txt and may be redistributed only under
+# the conditions described in the aforementioned license. The license
+# is also available online at http://www.enthought.com/licenses/BSD.txt
+#
+# Thanks for using Enthought open source!
+from traits.api import Event, Interface, Str
+
+
+
[docs]class ISelectionProvider(Interface): + """ Source of selections. """ + + #: Unique ID identifying the provider. + provider_id = Str() + + #: Event triggered when the selection changes. + #: The content of the event is an :class:`~.ISelection` instance. + selection = Event + +
[docs] def get_selection(self): + """Return the current selection. + + Returns: + selection -- ISelection + Object representing the current selection. + """
+ +
[docs] def set_selection(self, items, ignore_missing=False): + """Set the current selection to the given items. + + If ``ignore_missing`` is ``True``, items that are not available in the + selection provider are silently ignored. If it is ``False`` (default), + an :class:`~.ValueError` should be raised. + + Arguments: + items -- list + List of items to be selected. + + ignore_missing -- bool + If ``False`` (default), the provider raises an exception if any + of the items in ``items`` is not available to be selected. + Otherwise, missing elements are silently ignored, and the rest + is selected. + """
+
+ +
+
+
+
+
+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/5.0/_modules/apptools/selection/list_selection.html b/5.0/_modules/apptools/selection/list_selection.html new file mode 100644 index 000000000..cd640f662 --- /dev/null +++ b/5.0/_modules/apptools/selection/list_selection.html @@ -0,0 +1,196 @@ + + + + + + + apptools.selection.list_selection — Apptools Documentation + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +

Source code for apptools.selection.list_selection

+# (C) Copyright 2005-2020 Enthought, Inc., Austin, TX
+# All rights reserved.
+#
+# This software is provided without warranty under the terms of the BSD
+# license included in LICENSE.txt and may be redistributed only under
+# the conditions described in the aforementioned license. The license
+# is also available online at http://www.enthought.com/licenses/BSD.txt
+#
+# Thanks for using Enthought open source!
+from traits.api import HasTraits, List, provides, Str
+
+from apptools.selection.i_selection import IListSelection
+
+
+
[docs]@provides(IListSelection) +class ListSelection(HasTraits): + """Selection for ordered sequences of items. + + This is the default implementation of the :class:`~.IListSelection` + interface. + """ + + #### 'ISelection' protocol ################################################ + + #: ID of the selection provider that created this selection object. + provider_id = Str + +
[docs] def is_empty(self): + """ Is the selection empty? """ + return len(self.items) == 0
+ + #### 'IListSelection' protocol ############################################ + + #: Selected objects. + items = List + + #: Indices of the selected objects in the selection provider. + indices = List + + #### 'ListSelection' class protocol ####################################### + +
[docs] @classmethod + def from_available_items(cls, provider_id, selected, all_items): + """Create a list selection given a list of all available items. + + Fills in the required information (in particular, the indices) based + on a list of selected items and a list of all available items. + + .. note:: + - The list of available items must not contain any duplicate items. + - It is expected that ``selected`` is populated by items in + ``all_items``. + + """ + number_of_items = len(all_items) + indices = [] + + for item in selected: + for index in range(number_of_items): + if all_items[index] is item: + indices.append(index) + break + else: + msg = "Selected item: {!r}, could not be found" + raise ValueError(msg.format(item)) + + return cls(provider_id=provider_id, items=selected, indices=indices)
+
+ +
+
+
+
+
+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/5.0/_modules/apptools/selection/selection_service.html b/5.0/_modules/apptools/selection/selection_service.html new file mode 100644 index 000000000..53ff56ffa --- /dev/null +++ b/5.0/_modules/apptools/selection/selection_service.html @@ -0,0 +1,325 @@ + + + + + + + apptools.selection.selection_service — Apptools Documentation + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +

Source code for apptools.selection.selection_service

+# (C) Copyright 2005-2020 Enthought, Inc., Austin, TX
+# All rights reserved.
+#
+# This software is provided without warranty under the terms of the BSD
+# license included in LICENSE.txt and may be redistributed only under
+# the conditions described in the aforementioned license. The license
+# is also available online at http://www.enthought.com/licenses/BSD.txt
+#
+# Thanks for using Enthought open source!
+from traits.api import Dict, HasTraits
+
+from apptools.selection.errors import (
+    ProviderNotRegisteredError,
+    IDConflictError,
+    ListenerNotConnectedError,
+)
+
+
+
[docs]class SelectionService(HasTraits): + """The selection service connects selection providers and listeners. + + The selection service is a register of selection providers, i.e., objects + that publish their current selection. + + Selections can be requested actively, by explicitly requesting the current + selection in a provider (:meth:`get_selection(id)`), or passively by + connecting selection listeners. + """ + + #### 'SelectionService' protocol ########################################## + +
[docs] def add_selection_provider(self, provider): + """Add a selection provider. + + The provider is identified by its ID. If a provider with the same + ID has been already registered, an :class:`~.IDConflictError` + is raised. + + Arguments: + provider -- ISelectionProvider + The selection provider added to the internal registry. + + """ + provider_id = provider.provider_id + if self.has_selection_provider(provider_id): + raise IDConflictError(provider_id=provider_id) + + self._providers[provider_id] = provider + + if provider_id in self._listeners: + self._connect_all_listeners(provider_id)
+ +
[docs] def has_selection_provider(self, provider_id): + """ Has a provider with the given ID been registered? """ + return provider_id in self._providers
+ +
[docs] def remove_selection_provider(self, provider): + """Remove a selection provider. + + If the provider has not been registered, a + :class:`~.ProviderNotRegisteredError` is raised. + + Arguments: + provider -- ISelectionProvider + The selection provider added to the internal registry. + """ + provider_id = provider.provider_id + self._raise_if_not_registered(provider_id) + + if provider_id in self._listeners: + self._disconnect_all_listeners(provider_id) + + del self._providers[provider_id]
+ +
[docs] def get_selection(self, provider_id): + """Return the current selection of the provider with the given ID. + + If a provider with that ID has not been registered, a + :class:`~.ProviderNotRegisteredError` is raised. + + Arguments: + provider_id -- str + The selection provider ID. + + Returns: + selection -- ISelection + The current selection of the provider. + """ + self._raise_if_not_registered(provider_id) + provider = self._providers[provider_id] + return provider.get_selection()
+ +
[docs] def set_selection(self, provider_id, items, ignore_missing=False): + """Set the current selection in a provider to the given items. + + If a provider with the given ID has not been registered, a + :class:`~.ProviderNotRegisteredError` is raised. + + If ``ignore_missing`` is ``True``, items that are not available in the + selection provider are silently ignored. If it is ``False`` (default), + a :class:`ValueError` should be raised. + + Arguments: + provider_id -- str + The selection provider ID. + + items -- list + List of items to be selected. + + ignore_missing -- bool + If ``False`` (default), the provider raises an exception if any + of the items in ``items`` is not available to be selected. + Otherwise, missing elements are silently ignored, and the rest + is selected. + """ + self._raise_if_not_registered(provider_id) + provider = self._providers[provider_id] + return provider.set_selection(items, ignore_missing=ignore_missing)
+ +
[docs] def connect_selection_listener(self, provider_id, func): + """Connect a listener to selection events from a specific provider. + + The signature if the listener callback is ``func(i_selection)``. + The listener is called: + + 1) When a provider with the given ID is registered, with its initial + selection as argument, or + + 2) whenever the provider fires a selection event. + + It is perfectly valid to connect a listener before a provider with the + given ID is registered. The listener will remain connected even if + the provider is repeatedly connected and disconnected. + + Arguments: + provider_id -- str + The selection provider ID. + func -- callable(i_selection) + A callable object that is notified when the selection changes. + """ + self._listeners.setdefault(provider_id, []) + self._listeners[provider_id].append(func) + + if self.has_selection_provider(provider_id): + self._toggle_listener(provider_id, func, remove=False)
+ +
[docs] def disconnect_selection_listener(self, provider_id, func): + """Disconnect a listener from a specific provider. + + Arguments: + provider_id -- str + The selection provider ID. + func -- callable(provider_id, i_selection) + A callable object that is notified when the selection changes. + """ + + if self.has_selection_provider(provider_id): + self._toggle_listener(provider_id, func, remove=True) + + try: + self._listeners[provider_id].remove(func) + except (ValueError, KeyError): + raise ListenerNotConnectedError( + provider_id=provider_id, listener=func + )
+ + #### Private protocol ##################################################### + + _listeners = Dict() + + _providers = Dict() + + def _toggle_listener(self, provider_id, func, remove): + provider = self._providers[provider_id] + provider.on_trait_change(func, "selection", remove=remove) + + def _connect_all_listeners(self, provider_id): + """Connect all listeners connected to a provider. + + As soon as they are connected, they receive the initial selection. + """ + provider = self._providers[provider_id] + selection = provider.get_selection() + for func in self._listeners[provider_id]: + self._toggle_listener(provider_id, func, remove=False) + # FIXME: make this robust to notifications that raise exceptions. + # Can we send the error to the traits exception hook? + func(selection) + + def _disconnect_all_listeners(self, provider_id): + for func in self._listeners[provider_id]: + self._toggle_listener(provider_id, func, remove=True) + + def _raise_if_not_registered(self, provider_id): + if not self.has_selection_provider(provider_id): + raise ProviderNotRegisteredError(provider_id=provider_id)
+
+ +
+
+
+
+
+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/5.0/_modules/apptools/type_registry/type_registry.html b/5.0/_modules/apptools/type_registry/type_registry.html new file mode 100644 index 000000000..6a0642e6b --- /dev/null +++ b/5.0/_modules/apptools/type_registry/type_registry.html @@ -0,0 +1,403 @@ + + + + + + + apptools.type_registry.type_registry — Apptools Documentation + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +

Source code for apptools.type_registry.type_registry

+# (C) Copyright 2005-2020 Enthought, Inc., Austin, TX
+# All rights reserved.
+#
+# This software is provided without warranty under the terms of the BSD
+# license included in LICENSE.txt and may be redistributed only under
+# the conditions described in the aforementioned license. The license
+# is also available online at http://www.enthought.com/licenses/BSD.txt
+#
+# Thanks for using Enthought open source!
+
+
+
[docs]def get_mro(obj_class): + """Get a reasonable method resolution order of a class and its + superclasses for both old-style and new-style classes. + """ + if not hasattr(obj_class, "__mro__"): + # Old-style class. Mix in object to make a fake new-style class. + try: + obj_class = type(obj_class.__name__, (obj_class, object), {}) + except TypeError: + # Old-style extension type that does not descend from object. + mro = [obj_class] + else: + mro = obj_class.__mro__[1:-1] + else: + mro = obj_class.__mro__ + return mro
+ + +def _mod_name_key(typ): + """Return a '__module__:__name__' key for a type.""" + module = getattr(typ, "__module__", None) + name = getattr(typ, "__name__", None) + key = "{0}:{1}".format(module, name) + return key + + +
[docs]class TypeRegistry(object): + """Register objects for types. + + Each type maintains a stack of registered objects that can be pushed and + popped. + """ + + def __init__(self): + # Map types to lists of registered objects. The last is the most + # current and will be the one that is returned on lookup. + self.type_map = {} + + # Map '__module__:__name__' strings to lists of registered objects. + self.name_map = {} + + # Map abstract base classes to lists of registered objects. + self.abc_map = {} + + #### TypeRegistry public interface ######################################## + +
[docs] def push(self, typ, obj): + """Push an object onto the stack for the given type. + + Parameters + ---------- + typ : type or '__module__:__name__' string for a type + obj : object + The object to register. + """ + if isinstance(typ, str): + # Check the cached types. + for cls in self.type_map: + if _mod_name_key(cls) == typ: + self.type_map[cls].append(obj) + break + else: + if typ not in self.name_map: + self.name_map[typ] = [] + self.name_map[typ].append(obj) + else: + if typ not in self.type_map: + self.type_map[typ] = [] + self.type_map[typ].append(obj)
+ +
[docs] def push_abc(self, typ, obj): + """Push an object onto the stack for the given ABC. + + Parameters + ---------- + typ : abc.ABCMeta + obj : object + """ + if typ not in self.abc_map: + self.abc_map[typ] = [] + self.abc_map[typ].append(obj)
+ +
[docs] def pop(self, typ): + """Pop a registered object for the given type. + + Parameters + ---------- + typ : type or '__module__:__name__' string for a type + + Returns + ------- + obj : object + The last registered object for the type. + + Raises + ------ + KeyError if the type is not registered. + """ + if isinstance(typ, str): + if typ not in self.name_map: + # We may have it cached in the type map. We will have to + # iterate over all of the types to check. + for cls in self.type_map: + if _mod_name_key(cls) == typ: + old = self._pop_value(self.type_map, cls) + break + else: + raise KeyError("No registered value for {0!r}".format(typ)) + else: + old = self._pop_value(self.name_map, typ) + else: + if typ in self.type_map: + old = self._pop_value(self.type_map, typ) + elif typ in self.abc_map: + old = self._pop_value(self.abc_map, typ) + else: + old = self._pop_value(self.name_map, _mod_name_key(typ)) + return old
+ +
[docs] def lookup(self, instance): + """Look up the registered object for the given instance. + + Parameters + ---------- + instance : object + An instance of a possibly registered type. + + Returns + ------- + obj : object + The registered object for the type of the instance, one of the + type's superclasses, or else one of the ABCs the type implements. + + Raises + ------ + KeyError if the instance's type has not been registered. + """ + return self.lookup_by_type(type(instance))
+ +
[docs] def lookup_by_type(self, typ): + """Look up the registered object for a type. + + Parameters + ---------- + typ : type + + Returns + ------- + obj : object + The registered object for the type, one of its superclasses, or + else one of the ABCs it implements. + + Raises + ------ + KeyError if the type has not been registered. + """ + return self.lookup_all_by_type(typ)[-1]
+ +
[docs] def lookup_all(self, instance): + """Look up all the registered objects for the given instance. + + Parameters + ---------- + instance : object + An instance of a possibly registered type. + + Returns + ------- + objs : list of objects + The list of registered objects for the instance. If the given + instance is not registered, its superclasses are searched. If none + of the superclasses are registered, search the possible ABCs. + + Raises + ------ + KeyError if the instance's type has not been registered. + """ + return self.lookup_all_by_type(type(instance))
+ +
[docs] def lookup_all_by_type(self, typ): + """Look up all the registered objects for a type. + + Parameters + ---------- + typ : type + + Returns + ------- + objs : list of objects + The list of registered objects for the type. If the given type is + not registered, its superclasses are searched. If none of the + superclasses are registered, search the possible ABCs. + + Raises + ------ + KeyError if the type has not been registered. + """ + # If a concrete superclass is registered use it. + for cls in get_mro(typ): + if cls in self.type_map or self._in_name_map(cls): + objs = self.type_map[cls] + if objs: + return objs + + # None of the concrete superclasses. Check the ABCs. + for abstract, objs in self.abc_map.items(): + if issubclass(typ, abstract) and objs: + return objs + + # If we have reached here, the lookup failed. + raise KeyError("No registered value for {0!r}".format(typ))
+ + #### Private implementation ############################################### + + def _pop_value(self, mapping, key): + """Pop a value from a keyed stack in a mapping, taking care to remove + the key if the stack is depleted. + """ + objs = mapping[key] + old = objs.pop() + if not objs: + del mapping[key] + return old + + def _in_name_map(self, typ): + """Check if the given type is specified in the name map. + + Parameters + ---------- + typ : type + + Returns + ------- + is_in_name_map : bool + If True, the registered value will be moved over to the type map + for future lookups. + """ + key = _mod_name_key(typ) + if key in self.name_map: + self.type_map[typ] = self.name_map.pop(key) + return True + else: + return False
+ + +
[docs]class LazyRegistry(TypeRegistry): + """A type registry that will lazily import the registered objects. + + Register '__module__:__name__' strings for the lazily imported objects. + These will only be imported when the matching type is looked up. The module + name must be a fully-qualified absolute name with all of the parent + packages specified. + """ + +
[docs] def lookup_by_type(self, typ): + """Look up the registered object for a type.""" + mod_name = TypeRegistry.lookup_by_type(self, typ) + return self._import_object(mod_name)
+ + def _import_object(self, mod_object): + module, name = mod_object.split(":") + mod = __import__(module, {}, {}, [name], 0) + return getattr(mod, name)
+
+ +
+
+
+
+
+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/5.0/_modules/apptools/undo/abstract_command.html b/5.0/_modules/apptools/undo/abstract_command.html new file mode 100644 index 000000000..48a26016b --- /dev/null +++ b/5.0/_modules/apptools/undo/abstract_command.html @@ -0,0 +1,205 @@ + + + + + + + apptools.undo.abstract_command — Apptools Documentation + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +

Source code for apptools.undo.abstract_command

+# ------------------------------------------------------------------------------
+# Copyright (c) 2007, Riverbank Computing Limited
+# All rights reserved.
+#
+# This software is provided without warranty under the terms of the BSD
+# license included in enthought/LICENSE.txt and may be redistributed only
+# under the conditions described in the aforementioned license.  The license
+# is also available online at http://www.enthought.com/licenses/BSD.txt
+# Thanks for using Enthought open source!
+#
+# Author: Riverbank Computing Limited
+# Description: <Enthought undo package component>
+# ------------------------------------------------------------------------------
+
+# Enthought library imports.
+from traits.api import Any, HasTraits, Str, provides
+
+# Local imports.
+from .i_command import ICommand
+
+
+
[docs]@provides(ICommand) +class AbstractCommand(HasTraits): + """The AbstractCommand class is an abstract base class that implements the + ICommand interface. + """ + + #### 'ICommand' interface ################################################# + + # This is the data on which the command operates. + data = Any + + # This is the name of the command as it will appear in any GUI element. It + # may include '&' which will be automatically removed whenever it is + # inappropriate. + name = Str + + ########################################################################### + # 'ICommand' interface. + ########################################################################### + +
[docs] def do(self): + """This is called by the command stack to do the command and to return + any value. The command must save any state necessary for the 'redo()' + and 'undo()' methods to work. The class's __init__() must also ensure + that deep copies of any arguments are made if appropriate. It is + guaranteed that this will only ever be called once and that it will be + called before any call to 'redo()' or 'undo()'. + """ + + raise NotImplementedError
+ +
[docs] def merge(self, other): + """This is called by the command stack to try and merge another + command with this one. True is returned if the commands were merged. + 'other' is the command that is about to be executed. If the commands + are merged then 'other' will discarded and not placed on the command + stack. A subsequent undo or redo of this modified command must have + the same effect as the two original commands. + """ + + # By default merges never happen. + return False
+ +
[docs] def redo(self): + """This is called by the command stack to redo the command. Any + returned value will replace the value that the command stack references + from the original call to 'do()' or previous call to 'redo()'. + """ + + raise NotImplementedError
+ +
[docs] def undo(self): + """ This is called by the command stack to undo the command. """ + + raise NotImplementedError
+
+ +
+
+
+
+
+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/5.0/_modules/apptools/undo/action/abstract_command_stack_action.html b/5.0/_modules/apptools/undo/action/abstract_command_stack_action.html new file mode 100644 index 000000000..eef451dd3 --- /dev/null +++ b/5.0/_modules/apptools/undo/action/abstract_command_stack_action.html @@ -0,0 +1,212 @@ + + + + + + + apptools.undo.action.abstract_command_stack_action — Apptools Documentation + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +

Source code for apptools.undo.action.abstract_command_stack_action

+# ------------------------------------------------------------------------------
+# Copyright (c) 2008, Riverbank Computing Limited
+# All rights reserved.
+#
+# This software is provided without warranty under the terms of the BSD
+# license included in enthought/LICENSE.txt and may be redistributed only
+# under the conditions described in the aforementioned license.  The license
+# is also available online at http://www.enthought.com/licenses/BSD.txt
+# Thanks for using Enthought open source!
+#
+# Author: Riverbank Computing Limited
+# Description: <Enthought undo package component>
+# ------------------------------------------------------------------------------
+
+# Enthought library imports.
+from pyface.action.api import Action
+from traits.api import Instance
+
+# Local library imports
+from ..i_undo_manager import IUndoManager
+
+
+
[docs]class AbstractCommandStackAction(Action): + """The abstract base class for all actions that operate on a command + stack. + """ + + #### 'AbstractCommandStackAction' interface ############################### + + # The undo manager. + undo_manager = Instance(IUndoManager) + + ########################################################################### + # 'object' interface. + ########################################################################### + + def __init__(self, **traits): + """ Initialise the instance. """ + + super(AbstractCommandStackAction, self).__init__(**traits) + + self.undo_manager.on_trait_event( + self._on_stack_updated, "stack_updated" + ) + + # Update the action to initialise it. + self._update_action() + + ########################################################################### + # 'Action' interface. + ########################################################################### + +
[docs] def destroy(self): + """Called when the action is no longer required. + + By default this method does nothing, but this would be a great place to + unhook trait listeners etc. + + """ + + self.undo_manager.on_trait_event( + self._on_stack_updated, "stack_updated", remove=True + )
+ + ########################################################################### + # Protected interface. + ########################################################################### + + def _update_action(self): + """ Update the state of the action. """ + + raise NotImplementedError + + ########################################################################### + # Private interface. + ########################################################################### + + def _on_stack_updated(self, stack): + """ Handle changes to the state of a command stack. """ + + # Ignore unless it is the active stack. + if stack is self.undo_manager.active_stack: + self._update_action()
+
+ +
+
+
+
+
+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/5.0/_modules/apptools/undo/action/command_action.html b/5.0/_modules/apptools/undo/action/command_action.html new file mode 100644 index 000000000..151e51aaa --- /dev/null +++ b/5.0/_modules/apptools/undo/action/command_action.html @@ -0,0 +1,187 @@ + + + + + + + apptools.undo.action.command_action — Apptools Documentation + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +

Source code for apptools.undo.action.command_action

+# ------------------------------------------------------------------------------
+# Copyright (c) 2007, Riverbank Computing Limited
+# All rights reserved.
+#
+# This software is provided without warranty under the terms of the BSD
+# license included in enthought/LICENSE.txt and may be redistributed only
+# under the conditions described in the aforementioned license.  The license
+# is also available online at http://www.enthought.com/licenses/BSD.txt
+# Thanks for using Enthought open source!
+#
+# Author: Riverbank Computing Limited
+# Description: <Enthought undo package component>
+# ------------------------------------------------------------------------------
+
+# Enthought library imports.
+from pyface.action.api import Action
+from traits.api import Any, Callable, Instance
+from ..i_command_stack import ICommandStack
+
+
+
[docs]class CommandAction(Action): + """The CommandAction class is an Action class that wraps undo/redo + commands. It is only useful for commands that do not take any arguments or + return any result. + """ + + #### 'CommandAction' interface ############################################ + + # The command to create when the action is performed. + command = Callable + + # The command stack onto which the command will be pushed when the action + # is performed. + command_stack = Instance(ICommandStack) + + # This is the data on which the command operates. + data = Any + + ########################################################################### + # 'Action' interface. + ########################################################################### + +
[docs] def perform(self, event): + """This is reimplemented to push a new command instance onto the + command stack. + """ + + self.command_stack.push(self.command(data=self.data))
+ + def _name_default(self): + """ This gets the action name from the command. """ + + if self.command: + name = self.command().name + else: + name = "" + + return name
+
+ +
+
+
+
+
+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/5.0/_modules/apptools/undo/action/redo_action.html b/5.0/_modules/apptools/undo/action/redo_action.html new file mode 100644 index 000000000..34960ff83 --- /dev/null +++ b/5.0/_modules/apptools/undo/action/redo_action.html @@ -0,0 +1,178 @@ + + + + + + + apptools.undo.action.redo_action — Apptools Documentation + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +

Source code for apptools.undo.action.redo_action

+# ------------------------------------------------------------------------------
+# Copyright (c) 2007, Riverbank Computing Limited
+# All rights reserved.
+#
+# This software is provided without warranty under the terms of the BSD
+# license included in enthought/LICENSE.txt and may be redistributed only
+# under the conditions described in the aforementioned license.  The license
+# is also available online at http://www.enthought.com/licenses/BSD.txt
+# Thanks for using Enthought open source!
+#
+# Author: Riverbank Computing Limited
+# Description: <Enthought undo package component>
+# ------------------------------------------------------------------------------
+
+# Local imports.
+from .abstract_command_stack_action import AbstractCommandStackAction
+
+
+
[docs]class RedoAction(AbstractCommandStackAction): + """An action that redos the last command undone of the active command + stack. + """ + + ########################################################################### + # 'Action' interface. + ########################################################################### + +
[docs] def perform(self, event): + """ Perform the action. """ + + self.undo_manager.redo()
+ + ########################################################################### + # 'AbstractUndoAction' interface. + ########################################################################### + + def _update_action(self): + """ Update the state of the action. """ + + name = self.undo_manager.redo_name + + if name: + name = "&Redo " + name + self.enabled = True + else: + name = "&Redo" + self.enabled = False + + self.name = name
+
+ +
+
+
+
+
+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/5.0/_modules/apptools/undo/action/undo_action.html b/5.0/_modules/apptools/undo/action/undo_action.html new file mode 100644 index 000000000..c5910362b --- /dev/null +++ b/5.0/_modules/apptools/undo/action/undo_action.html @@ -0,0 +1,176 @@ + + + + + + + apptools.undo.action.undo_action — Apptools Documentation + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +

Source code for apptools.undo.action.undo_action

+# ------------------------------------------------------------------------------
+# Copyright (c) 2007, Riverbank Computing Limited
+# All rights reserved.
+#
+# This software is provided without warranty under the terms of the BSD
+# license included in enthought/LICENSE.txt and may be redistributed only
+# under the conditions described in the aforementioned license.  The license
+# is also available online at http://www.enthought.com/licenses/BSD.txt
+# Thanks for using Enthought open source!
+#
+# Author: Riverbank Computing Limited
+# Description: <Enthought undo package component>
+# ------------------------------------------------------------------------------
+
+# Local imports.
+from .abstract_command_stack_action import AbstractCommandStackAction
+
+
+
[docs]class UndoAction(AbstractCommandStackAction): + """ An action that undos the last command of the active command stack. """ + + ########################################################################### + # 'Action' interface. + ########################################################################### + +
[docs] def perform(self, event): + """ Perform the action. """ + + self.undo_manager.undo()
+ + ########################################################################### + # 'AbstractUndoAction' interface. + ########################################################################### + + def _update_action(self): + """ Update the state of the action. """ + + name = self.undo_manager.undo_name + + if name: + name = "&Undo " + name + self.enabled = True + else: + name = "&Undo" + self.enabled = False + + self.name = name
+
+ +
+
+
+
+
+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/5.0/_modules/apptools/undo/command_stack.html b/5.0/_modules/apptools/undo/command_stack.html new file mode 100644 index 000000000..bba612ffb --- /dev/null +++ b/5.0/_modules/apptools/undo/command_stack.html @@ -0,0 +1,448 @@ + + + + + + + apptools.undo.command_stack — Apptools Documentation + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +

Source code for apptools.undo.command_stack

+# ------------------------------------------------------------------------------
+# Copyright (c) 2008, Riverbank Computing Limited
+# All rights reserved.
+#
+# This software is provided without warranty under the terms of the BSD
+# license included in enthought/LICENSE.txt and may be redistributed only
+# under the conditions described in the aforementioned license.  The license
+# is also available online at http://www.enthought.com/licenses/BSD.txt
+# Thanks for using Enthought open source!
+#
+# Author: Riverbank Computing Limited
+# Description: <Enthought undo package component>
+# ------------------------------------------------------------------------------
+
+# Enthought library imports.
+from traits.api import (
+    Bool,
+    HasTraits,
+    Instance,
+    Int,
+    List,
+    Property,
+    Str,
+    provides,
+)
+
+# Local imports.
+from .abstract_command import AbstractCommand
+from .i_command import ICommand
+from .i_command_stack import ICommandStack
+from .i_undo_manager import IUndoManager
+
+
+class _StackEntry(HasTraits):
+    """ The _StackEntry class is a single entry on a command stack. """
+
+    #### '_StackEntry' interface ##############################################
+
+    # Set if the entry corresponds to a clean point on the stack.
+    clean = Bool(False)
+
+    # The command instance.
+    command = Instance(ICommand)
+
+    # The sequence number of the entry.
+    sequence_nr = Int
+
+
+class _MacroCommand(AbstractCommand):
+    """ The _MacroCommand class is an internal command that handles macros. """
+
+    #### '_MacroCommand' interface ############################################
+
+    # The commands that make up this macro.
+    macro_commands = List(Instance(ICommand))
+
+    ###########################################################################
+    # 'ICommand' interface.
+    ###########################################################################
+
+    def do(self):
+        """ Invoke the command. """
+
+        # This is a dummy.
+        return None
+
+    def merge(self, other):
+        """ Try and merge a command. """
+
+        if len(self.macro_commands) == 0:
+            merged = False
+        else:
+            merged = self.macro_commands[-1].merge(other)
+
+        return merged
+
+    def redo(self):
+        """ Redo the sub-commands. """
+
+        for cmd in self.macro_commands:
+            cmd.redo()
+
+        # Macros cannot return values.
+        return None
+
+    def undo(self):
+        """ Undo the sub-commands. """
+
+        for cmd in self.macro_commands:
+            cmd.undo()
+
+
+
[docs]@provides(ICommandStack) +class CommandStack(HasTraits): + """The CommandStack class is the default implementation of the + ICommandStack interface. + """ + + #### 'ICommandStack' interface ############################################ + + # This is the clean state of the stack. Its value changes as commands are + # undone and redone. It can also be explicity set to mark the current + # stack position as being clean (when the data is saved to disk for + # example). + clean = Property(Bool) + + # This is the name of the command that can be redone. It will be empty if + # there is no command that can be redone. It is maintained by the undo + # stack. + redo_name = Property(Str) + + # This is the undo manager that manages this stack. + undo_manager = Instance(IUndoManager) + + # This is the name of the command that can be undone. It will be empty if + # there is no command that can be undone. It is maintained by the undo + # stack. + undo_name = Property(Str) + + #### Private interface #################################################### + + # The current index into the stack (ie. the last command that was done). + _index = Int(-1) + + # The current macro stack. + _macro_stack = List(Instance(_MacroCommand)) + + # The stack itself. + _stack = List(Instance(_StackEntry)) + + ########################################################################### + # 'ICommandStack' interface. + ########################################################################### + +
[docs] def begin_macro(self, name): + """This begins a macro by creating an empty command with the given + 'name'. All subsequent calls to 'push()' create commands that will be + children of the empty command until the next call to 'end_macro()'. + Macros may be nested. The stack is disabled (ie. nothing can be undone + or redone) while a macro is being created (ie. while there is an + outstanding 'end_macro()' call). + """ + + command = _MacroCommand(name=name) + self.push(command) + self._macro_stack.append(command)
+ +
[docs] def clear(self): + """This clears the stack, without undoing or redoing any commands, and + leaves the stack in a clean state. It is typically used when all + changes to the data have been abandoned. + """ + + self._index = -1 + self._stack = [] + self._macro_stack = [] + + self.undo_manager.stack_updated = self
+ +
[docs] def end_macro(self): + """ This ends a macro. """ + + try: + self._macro_stack.pop() + except IndexError: + pass
+ +
[docs] def push(self, command): + """This executes a command and saves it on the command stack so that + it can be subsequently undone and redone. 'command' is an instance + that implements the ICommand interface. Its 'do()' method is called + to execute the command. If any value is returned by 'do()' then it is + returned by 'push()'. + """ + + # See if the command can be merged with the previous one. + if len(self._macro_stack) == 0: + if self._index >= 0: + merged = self._stack[self._index].command.merge(command) + else: + merged = False + else: + merged = self._macro_stack[-1].merge(command) + + # Increment the global sequence number. + if not merged: + self.undo_manager.sequence_nr += 1 + + # Execute the command. + result = command.do() + + # Do nothing more if the command was merged. + if merged: + return result + + # Only update the command stack if there is no current macro. + if len(self._macro_stack) == 0: + # Remove everything on the stack after the last command that was + # done. + self._index += 1 + del self._stack[self._index:] + + # Create a new stack entry and add it to the stack. + entry = _StackEntry( + command=command, sequence_nr=self.undo_manager.sequence_nr + ) + + self._stack.append(entry) + self.undo_manager.stack_updated = self + else: + # Add the command to the parent macro command. + self._macro_stack[-1].macro_commands.append(command) + + return result
+ +
[docs] def redo(self, sequence_nr=0): + """If 'sequence_nr' is 0 then the last command that was undone is + redone and any result returned. Otherwise commands are redone up to + and including the given 'sequence_nr' and any result of the last of + these is returned. + """ + + # Make sure a redo is valid in the current context. + if self.redo_name == "": + return None + + if sequence_nr == 0: + result = self._redo_one() + else: + result = None + + while self._index + 1 < len(self._stack): + if self._stack[self._index + 1].sequence_nr > sequence_nr: + break + + result = self._redo_one() + + self.undo_manager.stack_updated = self + + return result
+ +
[docs] def undo(self, sequence_nr=0): + """If 'sequence_nr' is 0 then the last command is undone. Otherwise + commands are undone up to and including the given 'sequence_nr'. + """ + + # Make sure an undo is valid in the current context. + if self.undo_name == "": + return + + if sequence_nr == 0: + self._undo_one() + else: + while self._index >= 0: + if self._stack[self._index].sequence_nr <= sequence_nr: + break + + self._undo_one() + + self.undo_manager.stack_updated = self
+ + ########################################################################### + # Private interface. + ########################################################################### + + def _redo_one(self): + """ Redo the command at the current index and return the result. """ + + self._index += 1 + entry = self._stack[self._index] + + return entry.command.redo() + + def _undo_one(self): + """ Undo the command at the current index. """ + + entry = self._stack[self._index] + self._index -= 1 + + entry.command.undo() + + def _get_clean(self): + """ Get the clean state of the stack. """ + + if self._index >= 0: + clean = self._stack[self._index].clean + else: + clean = True + + return clean + + def _set_clean(self, clean): + """ Set the clean state of the stack. """ + + if self._index >= 0: + self._stack[self._index].clean = clean + + def _get_redo_name(self): + """ Get the name of the redo command, if any. """ + + redo_name = "" + + if len(self._macro_stack) == 0 and self._index + 1 < len(self._stack): + redo_name = self._stack[self._index + 1].command.name.replace( + "&", "" + ) + + return redo_name + + def _get_undo_name(self): + """ Get the name of the undo command, if any. """ + + undo_name = "" + + if len(self._macro_stack) == 0 and self._index >= 0: + command = self._stack[self._index].command + undo_name = command.name.replace("&", "") + + return undo_name
+
+ +
+
+
+
+
+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/5.0/_modules/apptools/undo/i_command.html b/5.0/_modules/apptools/undo/i_command.html new file mode 100644 index 000000000..2be484b01 --- /dev/null +++ b/5.0/_modules/apptools/undo/i_command.html @@ -0,0 +1,194 @@ + + + + + + + apptools.undo.i_command — Apptools Documentation + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +

Source code for apptools.undo.i_command

+# ------------------------------------------------------------------------------
+# Copyright (c) 2007, Riverbank Computing Limited
+# All rights reserved.
+#
+# This software is provided without warranty under the terms of the BSD
+# license included in enthought/LICENSE.txt and may be redistributed only
+# under the conditions described in the aforementioned license.  The license
+# is also available online at http://www.enthought.com/licenses/BSD.txt
+# Thanks for using Enthought open source!
+#
+# Author: Riverbank Computing Limited
+# Description: <Enthought undo package component>
+# ------------------------------------------------------------------------------
+
+
+# Enthought library imports.
+from traits.api import Any, Interface, Str
+
+
+
[docs]class ICommand(Interface): + """The command interface. The state of the data can be changed by passing + an instance that implements this interface to the 'push()' method of a + command stack along with any arguments. + """ + + #### 'ICommand' interface ################################################# + + # This is the data on which the command operates. + data = Any + + # This is the name of the command as it will appear in any GUI element. It + # may include '&' which will be automatically removed whenever it is + # inappropriate. + name = Str + + ########################################################################### + # 'ICommand' interface. + ########################################################################### + +
[docs] def do(self): + """This is called by the command stack to do the command and to return + any value. The command must save any state necessary for the 'redo()' + and 'undo()' methods to work. The class's __init__() must also ensure + that deep copies of any arguments are made if appropriate. It is + guaranteed that this will only ever be called once and that it will be + called before any call to 'redo()' or 'undo()'. + """
+ +
[docs] def merge(self, other): + """This is called by the command stack to try and merge another + command with this one. True is returned if the commands were merged. + 'other' is the command that is about to be executed. If the commands + are merged then 'other' will discarded and not placed on the command + stack. A subsequent undo or redo of this modified command must have + the same effect as the two original commands. + """
+ +
[docs] def redo(self): + """This is called by the command stack to redo the command. Any + returned value will replace the value that the command stack references + from the original call to 'do()' or previous call to 'redo()'. + """
+ +
[docs] def undo(self): + """ This is called by the command stack to undo the command. """
+
+ +
+
+
+
+
+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/5.0/_modules/apptools/undo/i_command_stack.html b/5.0/_modules/apptools/undo/i_command_stack.html new file mode 100644 index 000000000..38cfbb57b --- /dev/null +++ b/5.0/_modules/apptools/undo/i_command_stack.html @@ -0,0 +1,220 @@ + + + + + + + apptools.undo.i_command_stack — Apptools Documentation + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +

Source code for apptools.undo.i_command_stack

+# ------------------------------------------------------------------------------
+# Copyright (c) 2007, Riverbank Computing Limited
+# All rights reserved.
+#
+# This software is provided without warranty under the terms of the BSD
+# license included in enthought/LICENSE.txt and may be redistributed only
+# under the conditions described in the aforementioned license.  The license
+# is also available online at http://www.enthought.com/licenses/BSD.txt
+# Thanks for using Enthought open source!
+#
+# Author: Riverbank Computing Limited
+# Description: <Enthought undo package component>
+# ------------------------------------------------------------------------------
+
+# Enthought library imports.
+from traits.api import Bool, Instance, Interface, Str
+
+# Local imports.
+from .i_undo_manager import IUndoManager
+
+
+
[docs]class ICommandStack(Interface): + """The command stack interface. A command stack is responsible for + managing the changes to a data model and recording those changes so that + they can be undone or redone. + """ + + #### 'ICommandStack' interface ############################################ + + # This is the clean state of the stack. Its value changes as commands are + # undone and redone. It can also be explicity set to mark the current + # stack position as being clean (when the data is saved to disk for + # example). + clean = Bool + + # This is the name of the command that can be redone. It will be empty if + # there is no command that can be redone. It is maintained by the undo + # stack. + redo_name = Str + + # This is the undo manager that manages this stack. + undo_manager = Instance(IUndoManager) + + # This is the name of the command that can be undone. It will be empty if + # there is no command that can be undone. It is maintained by the undo + # stack. + undo_name = Str + + ########################################################################### + # 'ICommandStack' interface. + ########################################################################### + +
[docs] def begin_macro(self, name): + """This begins a macro by creating an empty command with the given + 'name'. The commands passed to all subsequent calls to 'push()' will + be contained in the macro until the next call to 'end_macro()'. Macros + may be nested. The stack is disabled (ie. nothing can be undone or + redone) while a macro is being created (ie. while there is an + outstanding 'end_macro()' call). + """
+ +
[docs] def clear(self): + """This clears the stack, without undoing or redoing any commands, and + leaves the stack in a clean state. It is typically used when all + changes to the data have been abandoned. + """
+ +
[docs] def end_macro(self): + """ This ends a macro. """
+ +
[docs] def push(self, command): + """This executes a command and saves it on the command stack so that + it can be subsequently undone and redone. 'command' is an instance + that implements the ICommand interface. Its 'do()' method is called + to execute the command. If any value is returned by 'do()' then it is + returned by 'push()'. The command stack will keep a reference to the + result so that it can recognise it as an argument to a subsequent + command (which allows a script to properly save a result needed later). + """
+ +
[docs] def redo(self, sequence_nr=0): + """If 'sequence_nr' is 0 then the last command that was undone is + redone and any result returned. Otherwise commands are redone up to + and including the given 'sequence_nr' and any result of the last of + these is returned. + """
+ +
[docs] def undo(self, sequence_nr=0): + """If 'sequence_nr' is 0 then the last command is undone. Otherwise + commands are undone up to and including the given 'sequence_nr'. + """
+
+ +
+
+
+
+
+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/5.0/_modules/apptools/undo/i_undo_manager.html b/5.0/_modules/apptools/undo/i_undo_manager.html new file mode 100644 index 000000000..cefd9792d --- /dev/null +++ b/5.0/_modules/apptools/undo/i_undo_manager.html @@ -0,0 +1,192 @@ + + + + + + + apptools.undo.i_undo_manager — Apptools Documentation + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +

Source code for apptools.undo.i_undo_manager

+# ------------------------------------------------------------------------------
+# Copyright (c) 2008, Riverbank Computing Limited
+# All rights reserved.
+#
+# This software is provided without warranty under the terms of the BSD
+# license included in enthought/LICENSE.txt and may be redistributed only
+# under the conditions described in the aforementioned license.  The license
+# is also available online at http://www.enthought.com/licenses/BSD.txt
+# Thanks for using Enthought open source!
+#
+# Author: Riverbank Computing Limited
+# Description: <Enthought undo package component>
+# ------------------------------------------------------------------------------
+
+# Enthought library imports.
+from traits.api import Bool, Event, Instance, Int, Interface, Str
+
+
+
[docs]class IUndoManager(Interface): + """The undo manager interface. An undo manager is responsible for one or + more command stacks. Typically an application would have a single undo + manager. + """ + + #### 'IUndoManager' interface ############################################# + + # This is the currently active command stack and may be None. Typically it + # is set when some sort of editor becomes active. + active_stack = Instance("apptools.undo.api.ICommandStack") + + # This reflects the clean state of the currently active command stack. It + # is intended to support a "document modified" indicator in the GUI. It is + # maintained by the undo manager. + active_stack_clean = Bool + + # This is the name of the command that can be redone. It will be empty if + # there is no command that can be redone. It is maintained by the undo + # manager. + redo_name = Str + + # This is the sequence number of the next command to be performed. It is + # incremented immediately before a command is invoked (by its 'do()' + # method). + sequence_nr = Int + + # This event is fired when the index of a command stack changes. Note that + # it may not be the active stack. + stack_updated = Event(Instance("apptools.undo.api.ICommandStack")) + + # This is the name of the command that can be undone. It will be empty if + # there is no command that can be undone. It is maintained by the undo + # manager. + undo_name = Str + + ########################################################################### + # 'IUndoManager' interface. + ########################################################################### + +
[docs] def redo(self): + """ Redo the last undone command of the active command stack. """
+ +
[docs] def undo(self): + """ Undo the last command of the active command stack. """
+
+ +
+
+
+
+
+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/5.0/_modules/apptools/undo/undo_manager.html b/5.0/_modules/apptools/undo/undo_manager.html new file mode 100644 index 000000000..0707f8edf --- /dev/null +++ b/5.0/_modules/apptools/undo/undo_manager.html @@ -0,0 +1,251 @@ + + + + + + + apptools.undo.undo_manager — Apptools Documentation + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +

Source code for apptools.undo.undo_manager

+# ------------------------------------------------------------------------------
+# Copyright (c) 2008, Riverbank Computing Limited
+# All rights reserved.
+#
+# This software is provided without warranty under the terms of the BSD
+# license included in enthought/LICENSE.txt and may be redistributed only
+# under the conditions described in the aforementioned license.  The license
+# is also available online at http://www.enthought.com/licenses/BSD.txt
+# Thanks for using Enthought open source!
+#
+# Author: Riverbank Computing Limited
+# Description: <Enthought undo package component>
+# ------------------------------------------------------------------------------
+
+# Enthought library imports.
+from traits.api import (
+    Bool,
+    Event,
+    HasTraits,
+    Instance,
+    Int,
+    Property,
+    Str,
+    provides,
+)
+
+# Local imports.
+from .i_undo_manager import IUndoManager
+
+
+
[docs]@provides(IUndoManager) +class UndoManager(HasTraits): + """The UndoManager class is the default implementation of the + IUndoManager interface. + """ + + #### 'IUndoManager' interface ############################################# + + # This is the currently active command stack and may be None. Typically it + # is set when some sort of editor becomes active. + active_stack = Instance("apptools.undo.api.ICommandStack") + + # This reflects the clean state of the currently active command stack. It + # is intended to support a "document modified" indicator in the GUI. It is + # maintained by the undo manager. + active_stack_clean = Property(Bool) + + # This is the name of the command that can be redone. It will be empty if + # there is no command that can be redone. It is maintained by the undo + # manager. + redo_name = Property(Str) + + # This is the sequence number of the next command to be performed. It is + # incremented immediately before a command is invoked (by its 'do()' + # method). + sequence_nr = Int + + # This event is fired when the index of a command stack changes. The value + # of the event is the stack that has changed. Note that it may not be the + # active stack. + stack_updated = Event + + # This is the name of the command that can be undone. It will be empty if + # there is no command that can be undone. It is maintained by the undo + # manager. + undo_name = Property(Str) + + ########################################################################### + # 'IUndoManager' interface. + ########################################################################### + +
[docs] def redo(self): + """ Redo the last undone command of the active command stack. """ + + if self.active_stack is not None: + self.active_stack.redo()
+ +
[docs] def undo(self): + """ Undo the last command of the active command stack. """ + + if self.active_stack is not None: + self.active_stack.undo()
+ + ########################################################################### + # Private interface. + ########################################################################### + + def _active_stack_changed(self, new): + """ Handle a different stack becoming active. """ + + # Pretend that the stack contents have changed. + self.stack_updated = new + + def _get_active_stack_clean(self): + """ Get the current clean state. """ + + if self.active_stack is None: + active_stack_clean = True + else: + active_stack_clean = self.active_stack.clean + + return active_stack_clean + + def _get_redo_name(self): + """ Get the current redo name. """ + + if self.active_stack is None: + redo_name = "" + else: + redo_name = self.active_stack.redo_name + + return redo_name + + def _get_undo_name(self): + """ Get the current undo name. """ + + if self.active_stack is None: + undo_name = "" + else: + undo_name = self.active_stack.undo_name + + return undo_name
+
+ +
+
+
+
+
+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/5.0/_modules/index.html b/5.0/_modules/index.html new file mode 100644 index 000000000..53b122600 --- /dev/null +++ b/5.0/_modules/index.html @@ -0,0 +1,215 @@ + + + + + + + Overview: module code — Apptools Documentation + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +

All modules for which code is available

+ + +
+
+
+
+
+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/5.0/_modules/traits/trait_types.html b/5.0/_modules/traits/trait_types.html new file mode 100644 index 000000000..aee7cb0dd --- /dev/null +++ b/5.0/_modules/traits/trait_types.html @@ -0,0 +1,4427 @@ + + + + + + + traits.trait_types — Apptools Documentation + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +

Source code for traits.trait_types

+# (C) Copyright 2005-2020 Enthought, Inc., Austin, TX
+# All rights reserved.
+#
+# This software is provided without warranty under the terms of the BSD
+# license included in LICENSE.txt and may be redistributed only under
+# the conditions described in the aforementioned license. The license
+# is also available online at http://www.enthought.com/licenses/BSD.txt
+#
+# Thanks for using Enthought open source!
+
+""" Core Trait definitions.
+"""
+
+import collections.abc
+import datetime
+from importlib import import_module
+import operator
+import re
+import sys
+try:
+    from os import fspath
+except ImportError:
+    fspath = None
+from os.path import isfile, isdir
+from types import FunctionType, MethodType, ModuleType
+import uuid
+
+from .constants import DefaultValue, TraitKind, ValidateTrait
+from .trait_base import (
+    strx,
+    get_module_name,
+    HandleWeakRef,
+    class_of,
+    RangeTypes,
+    safe_contains,
+    SequenceTypes,
+    TypeTypes,
+    Undefined,
+    TraitsCache,
+    xgetattr,
+)
+from .trait_converters import trait_from, trait_cast
+from .trait_dict_object import TraitDictEvent, TraitDictObject
+from .trait_errors import TraitError
+from .trait_list_object import TraitListEvent, TraitListObject
+from .trait_set_object import TraitSetEvent, TraitSetObject
+from .trait_type import TraitType, _infer_default_value_type
+from .traits import (
+    Trait,
+    _TraitMaker,
+    _InstanceArgs,
+)
+from .util.import_symbol import import_symbol
+
+# TraitsUI integration imports
+from .editor_factories import (
+    code_editor,
+    html_editor,
+    password_editor,
+    shell_editor,
+    date_editor,
+    datetime_editor,
+    time_editor,
+    list_editor,
+)
+
+
+# Constants
+
+SetTypes = SequenceTypes + (set,)
+
+# Numeric type fast validator definitions
+
+# A few words about the next block of code:
+
+# The coerce validator is a generic validator for possibly coercible types
+# (see validate_trait_coerce_type in ctraits.c).
+#
+# The tuples below are of the form
+# (ValidateTrait.coerce, type1, [type2, type3, ...],
+#     [None, ctype1, [ctype2, ...]])
+#
+# 'type1' corresponds to the main type for the trait
+# 'None' acts as the separator between 'types' and 'ctypes' (coercible types)
+#
+# The validation passes if:
+# 1) The trait value type is (a subtype of) one of 'type1', 'type2',  ...
+#    in which case the value is returned as-is
+# or
+# 2) The trait value type is (a subtype of) one of 'ctype1', 'ctype2', ...
+#    in which case the value is returned coerced to trait type using
+#    'return type1(value')
+
+try:
+    # The numpy enhanced definitions:
+    from numpy import integer, floating, complexfloating, bool_
+
+    int_fast_validate = (ValidateTrait.coerce, int, integer)
+    float_fast_validate = (
+        ValidateTrait.coerce,
+        float,
+        floating,
+        None,
+        int,
+        integer,
+    )
+    complex_fast_validate = (
+        ValidateTrait.coerce,
+        complex,
+        complexfloating,
+        None,
+        float,
+        floating,
+        int,
+        integer,
+    )
+    bool_fast_validate = (ValidateTrait.coerce, bool, None, bool_)
+    # Tuple or single type suitable for an isinstance check.
+    _BOOL_TYPES = (bool, bool_)
+except ImportError:
+    # The standard python definitions (without numpy):
+    int_fast_validate = (ValidateTrait.coerce, int)
+    float_fast_validate = (ValidateTrait.coerce, float, None, int)
+    complex_fast_validate = (ValidateTrait.coerce, complex, None, float, int)
+    bool_fast_validate = (ValidateTrait.coerce, bool)
+    # Tuple or single type suitable for an isinstance check.
+    _BOOL_TYPES = bool
+
+
+def default_text_editor(trait, type=None):
+    """ Return a default text editor for a trait.
+
+    Parameters
+    ----------
+    trait : TraitType
+        The trait we are constructing the editor for.
+    type : callable, optional
+        A callable (usually a Python type) to use to evaluate the text content
+        of the editor and return the correct type of value for the trait.
+
+    Returns
+    -------
+    TextEditor
+        A TraitsUI TextEditor instance for the trait.
+    """
+    auto_set = trait.auto_set
+    if auto_set is None:
+        auto_set = True
+
+    enter_set = trait.enter_set or False
+
+    from traitsui.api import TextEditor
+
+    if type is None:
+        return TextEditor(auto_set=auto_set, enter_set=enter_set)
+
+    return TextEditor(auto_set=auto_set, enter_set=enter_set, evaluate=type)
+
+
+# Generic validators
+
+def _validate_int(value):
+    """ Convert an integer-like Python object to an int, or raise TypeError.
+    """
+    if type(value) is int:
+        return value
+    else:
+        return int(operator.index(value))
+
+
+def _validate_float(value):
+    """ Convert an arbitrary Python object to a float, or raise TypeError.
+    """
+    if type(value) is float:  # fast path for common case
+        return value
+    try:
+        nb_float = type(value).__float__
+    except AttributeError:
+        raise TypeError(
+            "Object of type {!r} not convertible to float".format(type(value))
+        )
+    return nb_float(value)
+
+
+# Trait Types
+
+class Any(TraitType):
+    """ A trait type whose value can be anything.
+    """
+
+    #: The default value for the trait:
+    default_value = None
+
+    #: A description of the type of value this trait accepts:
+    info_text = "any value"
+
+
+class BaseInt(TraitType):
+    """ A trait type whose value must be an int.
+
+    Values which support the Python index protocol will validate and will be
+    converted to the corresponding int value.
+    """
+
+    #: The function to use for evaluating strings to this type:
+    evaluate = int
+
+    #: The default value for the trait:
+    default_value = 0
+
+    #: A description of the type of value this trait accepts:
+    info_text = "an integer"
+
+    def validate(self, object, name, value):
+        """ Validates that a specified value is valid for this trait.
+        """
+        try:
+            return _validate_int(value)
+        except TypeError:
+            self.error(object, name, value)
+
+    def create_editor(self):
+        """ Returns the default traits UI editor for this type of trait.
+        """
+        return default_text_editor(self, int)
+
+
+class Int(BaseInt):
+    """ A fast-validating trait type whose value must be an integer.
+
+    Values which support the Python index protocol will validate and will be
+    converted to the corresponding int value.
+    """
+
+    #: The C-level fast validator to use:
+    fast_validate = (ValidateTrait.int,)
+
+
+class BaseFloat(TraitType):
+    """ A trait type whose value must be a float.
+
+    Values which support automatic conversion to floats via the Python
+    __float__ method will validate and will be converted to the corresponding
+    float value.
+    """
+
+    #: The function to use for evaluating strings to this type:
+    evaluate = float
+
+    #: The default value for the trait:
+    default_value = 0.0
+
+    #: A description of the type of value this trait accepts:
+    info_text = "a float"
+
+    def validate(self, object, name, value):
+        """ Validates that a specified value is valid for this trait.
+
+        Note: The 'fast validator' version performs this check in C.
+        """
+        try:
+            return _validate_float(value)
+        except TypeError:
+            self.error(object, name, value)
+
+    def create_editor(self):
+        """ Returns the default traits UI editor for this type of trait.
+        """
+        return default_text_editor(self, float)
+
+
+class Float(BaseFloat):
+    """ A fast-validating trait type whose value must be a float.
+
+    Values which support automatic conversion to floats via the Python
+    __float__ method will validate and will be converted to the corresponding
+    float value.
+    """
+
+    #: The C-level fast validator to use:
+    fast_validate = (ValidateTrait.float,)
+
+
+class BaseComplex(TraitType):
+    """ A trait type whose value must be a complex number.
+
+    Integers and floating-point numbers will be converted to the
+    corresponding complex value.
+    """
+
+    #: The function to use for evaluating strings to this type:
+    evaluate = complex
+
+    #: The default value for the trait:
+    default_value = 0.0 + 0.0j
+
+    #: A description of the type of value this trait accepts:
+    info_text = "a complex number"
+
+    def validate(self, object, name, value):
+        """ Validates that a specified value is valid for this trait.
+
+        Note: The 'fast validator' version performs this check in C.
+        """
+        if isinstance(value, complex):
+            return value
+
+        if isinstance(value, (float, int)):
+            return complex(value)
+
+        self.error(object, name, value)
+
+    def create_editor(self):
+        """ Returns the default traits UI editor for this type of trait.
+        """
+        return default_text_editor(self, complex)
+
+
+class Complex(BaseComplex):
+    """ A fast-validating trait type whose value must be a complex number.
+
+    Integers and floating-point numbers will be converted to the
+    corresponding complex value.
+    """
+
+    #: The C-level fast validator to use:
+    fast_validate = complex_fast_validate
+
+
+class BaseStr(TraitType):
+    """ A trait type whose value must be a string.
+    """
+
+    #: The default value for the trait:
+    default_value = ""
+
+    #: A description of the type of value this trait accepts:
+    info_text = "a string"
+
+    def validate(self, object, name, value):
+        """ Validates that a specified value is valid for this trait.
+
+        Note: The 'fast validator' version performs this check in C.
+        """
+        if isinstance(value, str):
+            return value
+
+        self.error(object, name, value)
+
+    def create_editor(self):
+        """ Returns the default traits UI editor for this type of trait.
+        """
+        from .editor_factories import multi_line_text_editor
+
+        auto_set = self.auto_set
+        if auto_set is None:
+            auto_set = True
+        enter_set = self.enter_set or False
+
+        return multi_line_text_editor(auto_set, enter_set)
+
+
+class Str(BaseStr):
+    """ A fast-validating trait type whose value must be a complex number.
+    """
+
+    #: The C-level fast validator to use:
+    fast_validate = (ValidateTrait.coerce, str)
+
+
+class Title(Str):
+    """ A Str trait which by default uses a TraitsUI TitleEditor.
+    """
+
+    def create_editor(self):
+        """ Returns the default traits UI editor to use for a trait.
+        """
+        from traitsui.api import TitleEditor
+
+        if hasattr(self, "allow_selection"):
+            return TitleEditor(allow_selection=self.allow_selection)
+        else:
+            return TitleEditor()
+
+
+class BaseBytes(TraitType):
+    """ A trait type whose value must be a bytestring.
+    """
+
+    #: The default value for the trait:
+    default_value = b""
+
+    #: A description of the type of value this trait accepts:
+    info_text = "a bytes string"
+
+    #: An encoding to use with TraitsUI editors
+    encoding = None
+
+    def validate(self, object, name, value):
+        """ Validates that a specified value is valid for this trait.
+
+        Note: The 'fast validator' version performs this check in C.
+        """
+        if isinstance(value, bytes):
+            return value
+
+        self.error(object, name, value)
+
+    def create_editor(self):
+        """ Returns the default traits UI editor for this type of trait.
+        """
+        from .traits import bytes_editor
+
+        auto_set = self.auto_set
+        if auto_set is None:
+            auto_set = True
+        enter_set = self.enter_set or False
+
+        return bytes_editor(auto_set, enter_set, self.encoding)
+
+
+class Bytes(BaseBytes):
+    """ A fast-validating trait type whose value must be a bytestring.
+    """
+
+    #: The C-level fast validator to use:
+    fast_validate = (ValidateTrait.coerce, bytes)
+
+
+class BaseBool(TraitType):
+    """ A trait type whose value must be a bool.
+    """
+
+    #: The function to use for evaluating strings to this type:
+    evaluate = bool
+
+    #: The default value for the trait:
+    default_value = False
+
+    #: A description of the type of value this trait accepts:
+    info_text = "a boolean"
+
+    def validate(self, object, name, value):
+        """ Validates that a specified value is valid for this trait.
+
+        Note: The 'fast validator' version performs this check in C.
+        """
+        if isinstance(value, _BOOL_TYPES):
+            return bool(value)
+
+        self.error(object, name, value)
+
+    def create_editor(self):
+        """ Returns the default traits UI editor for this type of trait.
+        """
+        from traitsui.api import BooleanEditor
+
+        return BooleanEditor()
+
+
+class Bool(BaseBool):
+    """ A fast-validating trait type whose value must be a bool.
+    """
+
+    #: The C-level fast validator to use:
+    fast_validate = bool_fast_validate
+
+
+class BaseCInt(BaseInt):
+    """ A coercing trait type whose value is an integer.
+    """
+
+    #: The function to use for evaluating strings to this type:
+    evaluate = int
+
+    def validate(self, object, name, value):
+        """ Validates that a specified value is valid for this trait.
+
+        Note: The 'fast validator' version performs this check in C.
+        """
+        try:
+            return int(value)
+        except (ValueError, TypeError):
+            self.error(object, name, value)
+
+
+class CInt(BaseCInt):
+    """ A fast-validating, coercing trait type whose value is an int.
+    """
+
+    #: The C-level fast validator to use:
+    fast_validate = (ValidateTrait.cast, int)
+
+
+class BaseCFloat(BaseFloat):
+    """ A coercing trait type whose value is a float.
+    """
+
+    #: The function to use for evaluating strings to this type:
+    evaluate = float
+
+    def validate(self, object, name, value):
+        """ Validates that a specified value is valid for this trait.
+
+        Note: The 'fast validator' version performs this check in C.
+        """
+        try:
+            return float(value)
+        except (ValueError, TypeError):
+            self.error(object, name, value)
+
+
+class CFloat(BaseCFloat):
+    """ A fast-validating, coercing trait type whose value is a float.
+    """
+
+    #: The C-level fast validator to use:
+    fast_validate = (ValidateTrait.cast, float)
+
+
+class BaseCComplex(BaseComplex):
+    """ A coercing trait type whose value is a complex number.
+    """
+
+    #: The function to use for evaluating strings to this type:
+    evaluate = complex
+
+    def validate(self, object, name, value):
+        """ Validates that a specified value is valid for this trait.
+
+        Note: The 'fast validator' version performs this check in C.
+        """
+        try:
+            return complex(value)
+        except (ValueError, TypeError):
+            self.error(object, name, value)
+
+
+class CComplex(BaseCComplex):
+    """ A fast-validating, coercing trait type whose value is a complex number.
+    """
+
+    #: The C-level fast validator to use:
+    fast_validate = (ValidateTrait.cast, complex)
+
+
+class BaseCStr(BaseStr):
+    """ A coercing trait type whose value is a string.
+    """
+
+    def validate(self, object, name, value):
+        """ Validates that a specified value is valid for this trait.
+
+        Note: The 'fast validator' version performs this check in C.
+        """
+        try:
+            return str(value)
+        except:
+            self.error(object, name, value)
+
+
+class CStr(BaseCStr):
+    """ A fast-validating, coercing trait type whose value is a string.
+    """
+
+    #: The C-level fast validator to use:
+    fast_validate = (ValidateTrait.cast, str)
+
+
+class BaseCBytes(BaseBytes):
+    """ A coercing trait type whose value is a bytestring.
+    """
+
+    def validate(self, object, name, value):
+        """ Validates that a specified value is valid for this trait.
+
+        Note: The 'fast validator' version performs this check in C.
+        """
+        try:
+            return bytes(value)
+        except:
+            self.error(object, name, value)
+
+
+class CBytes(BaseCBytes):
+    """ A fast-validating, coercing trait type whose value is a bytestring.
+    """
+
+    #: The C-level fast validator to use:
+    fast_validate = (ValidateTrait.cast, bytes)
+
+
+class BaseCBool(BaseBool):
+    """ A coercing trait type whose value is a bool.
+    """
+
+    #: The function to use for evaluating strings to this type:
+    evaluate = bool
+
+    def validate(self, object, name, value):
+        """ Validates that a specified value is valid for this trait.
+
+        Note: The 'fast validator' version performs this check in C.
+        """
+        try:
+            return bool(value)
+        except:
+            self.error(object, name, value)
+
+
+class CBool(BaseCBool):
+    """ A fast-validating, coercing trait type whose value is a bool.
+    """
+
+    #: The C-level fast validator to use:
+    fast_validate = (ValidateTrait.cast, bool)
+
+
+class String(TraitType):
+    """ A trait type whose value must be a string with optional constraints.
+
+    The value is a string whose length is in a specified range, and which
+    optionally matches a specified regular expression.
+
+    Parameters
+    ----------
+    value : str
+        The default value for the string.
+    minlen : integer
+        The minimum length allowed for the string.
+    maxlen : integer
+        The maximum length allowed for the string.
+    regex : str
+        A Python regular expression that the string must match.
+    **metadata
+        The trait metadata for the trait.
+
+    Attributes
+    ----------
+    minlen : integer
+        The minimum length allowed for the string.
+    maxlen : integer
+        The maximum length allowed for the string.
+    regex : str
+        A Python regular expression that the string must match.
+    """
+
+    def __init__(
+        self, value="", minlen=0, maxlen=sys.maxsize, regex="", **metadata
+    ):
+        super(String, self).__init__(value, **metadata)
+        self.minlen = max(0, minlen)
+        self.maxlen = max(self.minlen, maxlen)
+        self.regex = regex
+        self._init()
+
+    def _init(self):
+        """ Completes initialization of the trait at construction or unpickling
+        time.
+        """
+        self._validate = "validate_all"
+        if self.regex != "":
+            self.match = re.compile(self.regex).match
+            if (self.minlen == 0) and (self.maxlen == sys.maxsize):
+                self._validate = "validate_regex"
+        elif (self.minlen == 0) and (self.maxlen == sys.maxsize):
+            self._validate = "validate_str"
+        else:
+            self._validate = "validate_len"
+
+    def validate(self, object, name, value):
+        """ Validates that the value is a valid string.
+        """
+        return getattr(self, self._validate)(object, name, value)
+
+    def validate_all(self, object, name, value):
+        """ Validates that the value is a valid string in the specified length
+            range which matches the specified regular expression.
+        """
+        try:
+            value = strx(value)
+            if (self.minlen <= len(value) <= self.maxlen) and (
+                self.match(value) is not None
+            ):
+                return value
+        except:
+            pass
+
+        self.error(object, name, value)
+
+    def validate_str(self, object, name, value):
+        """ Validates that the value is a valid string.
+        """
+        try:
+            return strx(value)
+        except:
+            pass
+
+        self.error(object, name, value)
+
+    def validate_len(self, object, name, value):
+        """ Validates that the value is a valid string in the specified length
+        range.
+        """
+        try:
+            value = strx(value)
+            if self.minlen <= len(value) <= self.maxlen:
+                return value
+        except:
+            pass
+
+        self.error(object, name, value)
+
+    def validate_regex(self, object, name, value):
+        """ Validates that the value is a valid string which matches the
+        specified regular expression.
+        """
+        try:
+            value = strx(value)
+            if self.match(value) is not None:
+                return value
+        except:
+            pass
+
+        self.error(object, name, value)
+
+    def info(self):
+        """ Returns a description of the trait.
+        """
+        msg = ""
+        if (self.minlen != 0) and (self.maxlen != sys.maxsize):
+            msg = " between %d and %d characters long" % (
+                self.minlen,
+                self.maxlen,
+            )
+        elif self.maxlen != sys.maxsize:
+            msg = " <= %d characters long" % self.maxlen
+        elif self.minlen != 0:
+            msg = " >= %d characters long" % self.minlen
+        if self.regex != "":
+            if msg != "":
+                msg += " and"
+            msg += " matching the pattern '%s'" % self.regex
+        return "a string" + msg
+
+    def create_editor(self):
+        """ Returns the default traits UI editor for this type of trait.
+        """
+        return default_text_editor(self)
+
+    def __getstate__(self):
+        """ Returns the current state of the trait.
+        """
+        result = self.__dict__.copy()
+        for name in ["validate", "match"]:
+            if name in result:
+                del result[name]
+
+        return result
+
+    def __setstate__(self, state):
+        """ Sets the current state of the trait.
+        """
+        self.__dict__.update(state)
+        self._init()
+
+
+class Regex(String):
+    """ A trait type whose value must match a regular expression.
+
+    Parameters
+    ----------
+    value : str
+        The default value of the trait.
+    regex : str
+        The regular expression that the trait value must match.
+    **metadata
+        Trait metadata.
+    """
+
+    def __init__(self, value="", regex=".*", **metadata):
+        super(Regex, self).__init__(value=value, regex=regex, **metadata)
+
+
+class Code(String):
+    """ A trait type whose value holds a string of source code.
+
+    Validation does not perform any sort of syntax checking. The default
+    TraitsUI editor is a CodeEditor.
+    """
+
+    #: The standard metadata for the trait:
+    metadata = {"editor": code_editor}
+
+
+class HTML(String):
+    """ A trait type whose value holds an HTML string.
+
+    The validation of the value does not enforce HTML syntax.  The default
+    TraitsUI editor is an HTMLEditor.
+    """
+
+    #: The standard metadata for the trait:
+    metadata = {"editor": html_editor}
+
+
+class Password(String):
+    """ A trait type whose value holds a password string.
+
+    The default TraitsUI editor is an PasswordEditor, which obscures text
+    entered by the user.
+    """
+
+    #: The standard metadata for the trait:
+    metadata = {"editor": password_editor}
+
+
+class BaseCallable(TraitType):
+    """ A trait type whose value must be a Python callable.
+    """
+
+    #: The standard metadata for the trait:
+    metadata = {"copy": "ref"}
+
+    #: The default value for the trait:
+    default_value = None
+
+    #: A description of the type of value this trait accepts:
+    info_text = "a callable value"
+
+    def validate(self, object, name, value):
+        """ Validates that the value is a Python callable.
+        """
+        if (value is None) or callable(value):
+            return value
+
+        self.error(object, name, value)
+
+
+class Callable(BaseCallable):
+    """ A fast-validating trait type whose value must be a Python callable.
+    """
+    def __init__(self, value=None, allow_none=True, **metadata):
+
+        self.fast_validate = (ValidateTrait.callable, allow_none)
+
+        default_value = metadata.pop("default_value", value)
+
+        super().__init__(default_value, **metadata)
+
+
+class BaseType(TraitType):
+    """ A trait type whose value must be an instance of a Python type.
+
+    This is an abstract class and should not be directly instantiated.
+    """
+
+    def validate(self, object, name, value):
+        """ Validates that the value is a Python callable.
+        """
+        if isinstance(value, self.fast_validate[1:]):
+            return value
+
+        self.error(object, name, value)
+
+
+class This(BaseType):
+    """ A trait type whose value must be an instance of the defining class.
+    """
+
+    #: The C-level fast validator to use:
+    fast_validate = (ValidateTrait.self_type,)
+
+    #: A description of the type of value this trait accepts:
+    info_text = "an instance of the same type as the receiver"
+
+    def __init__(self, value=None, allow_none=True, **metadata):
+        super(This, self).__init__(value, **metadata)
+
+        if allow_none:
+            self.fast_validate = (ValidateTrait.self_type, None)
+            self.validate = self.validate_none
+            self.info = self.info_none
+
+    def validate(self, object, name, value):
+        if isinstance(value, object.__class__):
+            return value
+
+        self.error(object, name, value)
+
+    def validate_none(self, object, name, value):
+        if isinstance(value, object.__class__) or (value is None):
+            return value
+
+        self.error(object, name, value)
+
+    def info(self):
+        return "an instance of the same type as the receiver"
+
+    def info_none(self):
+        return "an instance of the same type as the receiver or None"
+
+
+class self(This):
+    """ A trait type whose default value is the object containing the trait.
+
+    The trait can be assigned to, but any new value must be an instance of
+    the defining class.
+    """
+
+    #: The default value type to use (i.e. 'self'):
+    default_value_type = DefaultValue.object
+
+
+class Function(TraitType):
+    """ A trait type whose value must be a function.
+    """
+
+    #: The C-level fast validator to use:
+    fast_validate = (ValidateTrait.coerce, FunctionType)
+
+    #: A description of the type of value this trait accepts:
+    info_text = "a function"
+
+
+class Method(TraitType):
+    """ A trait type whose value must be a method.
+    """
+
+    #: The C-level fast validator to use:
+    fast_validate = (ValidateTrait.coerce, MethodType)
+
+    #: A description of the type of value this trait accepts:
+    info_text = "a method"
+
+
+class Module(TraitType):
+    """ A trait type whose value must be a module.
+    """
+
+    #: The C-level fast validator to use:
+    fast_validate = (ValidateTrait.coerce, ModuleType)
+
+    #: A description of the type of value this trait accepts:
+    info_text = "a module"
+
+
+class Python(TraitType):
+    """ A trait type that behaves as a standard Python attribute.
+
+    This trait type allows any value to be assigned, and raises an
+    ValueError if an attempt is made to get the value before one has been
+    assigned. It has no default value. This trait is most often used in
+    conjunction with wildcard naming. See the *Traits User Manual* for
+    details on wildcards.
+    """
+
+    #: The standard metadata for the trait:
+    metadata = {"type": "python"}
+
+    #: The default value for the trait:
+    default_value = Undefined
+
+
+class ReadOnly(TraitType):
+    """ A trait type that is write-once, and then read-only.
+
+    The initial value of the attribute is the special, singleton object
+    Undefined. The trait allows any value to be assigned to the attribute
+    if the current value is the Undefined object. Once any other value is
+    assigned, no further assignment is allowed. Normally, the initial
+    assignment to the attribute is performed in the class constructor,
+    based on information passed to the constructor. If the read-only value
+    is known in advance of run time, use Constant instead of ReadOnly to
+    define the trait.
+    """
+
+    # Defines the CTrait type to use for this trait:
+    ctrait_type = TraitKind.read_only
+
+    #: The default value for the trait:
+    default_value = Undefined
+
+
+# Create a singleton instance as the trait:
+ReadOnly = ReadOnly()
+
+
+class Disallow(TraitType):
+    """ A trait that prevents any value from being assigned or read.
+
+    Any attempt to get or set the value of the trait attribute raises an
+    exception. This trait is most often used in conjunction with wildcard
+    naming, for example, to catch spelling mistakes in attribute names.
+
+    See the *Traits User Manual* for details on wildcards.
+    """
+
+    #: Defines the CTrait type to use for this trait:
+    ctrait_type = TraitKind.disallow
+
+
+# Create a singleton instance as the trait:
+Disallow = Disallow()
+
+
+class Constant(TraitType):
+    """ A trait type whose value is a constant.
+
+    Traits of this type are very space efficient (and fast) because
+    *value* is not stored in each instance using the trait, but only in
+    the trait object itself.
+
+    Parameters
+    ----------
+    value : any
+        The constant value for the trait.
+    **metadata
+        Trait metadata for the trait.
+    """
+
+    #: Defines the CTrait type to use for this trait:
+    ctrait_type = TraitKind.constant
+
+    #: The standard metadata for the trait:
+    metadata = {"type": "constant", "transient": True}
+
+
+class Delegate(TraitType):
+    """ A trait type whose value is delegated to a trait on another object.
+
+    This is a base class that shouldn't be used directly, rather use one of
+    the subclasses DelegatesTo or PrototypesFrom, depending on desired
+    behaviour.
+
+    An object containing a delegator trait attribute must contain a
+    second attribute that references the object containing the delegate
+    trait attribute. The name of this second attribute is passed as the
+    *delegate* argument.
+
+    The following rules govern the application of the prefix parameter:
+
+    * If *prefix* is empty or omitted, the delegation is to an attribute
+      of the delegate object with the same name as the delegator
+      attribute.
+    * If *prefix* is a valid Python attribute name, then the delegation
+      is to an attribute whose name is the value of *prefix*.
+    * If *prefix* ends with an asterisk ('*') and is longer than one
+      character, then the delegation is to an attribute whose name is
+      the value of *prefix*, minus the trailing asterisk, prepended to
+      the delegator attribute name.
+    * If *prefix* is equal to a single asterisk, the delegation is to an
+      attribute whose name is the value of the delegator object's
+      __prefix__ attribute prepended to delegator attribute name.
+
+    Parameters
+    ----------
+    delegate : str
+        The name of the trait that holds the HasTraits instance that the
+        value is delegated to.
+    prefix : str
+        The name of the trait on the delegate that holds the delegated
+        value.  If empty, then the name of this trait will be used.
+    modify : bool
+        Whether modifications of this trait are applied to the delegated
+        object.  This differentiates the behaviour of DelegatesTo and
+        PrototypedFrom.
+    listenable : bool
+        Whether changes to the delegated trait will fire listeners to
+        this trait.
+
+    Attributes
+    ----------
+    delegate : str
+        The name of the trait that holds the HasTraits instance that the
+        value is delegated to.
+    prefix : str
+        The name of the trait on the delegate that holds the delegated
+        value.  If empty, then the name of this trait will be used.
+    prefix_type : int
+        An integer giving the type of prefix being used.
+    modify : bool
+        Whether modifications of this trait are applied to the delegated
+        object.  This differentiates the behaviour of DelegatesTo and
+        PrototypedFrom.
+    """
+
+    #: Defines the CTrait type to use for this trait:
+    ctrait_type = TraitKind.delegate
+
+    #: The standard metadata for the trait:
+    metadata = {"type": "delegate", "transient": False}
+
+    def __init__(
+        self, delegate, prefix="", modify=False, listenable=True, **metadata
+    ):
+        """ Creates a Delegate trait.
+        """
+        if prefix == "":
+            prefix_type = 0
+        elif prefix[-1:] != "*":
+            prefix_type = 1
+        else:
+            prefix = prefix[:-1]
+            if prefix != "":
+                prefix_type = 2
+            else:
+                prefix_type = 3
+
+        metadata["_delegate"] = delegate
+        metadata["_prefix"] = prefix
+        metadata["_listenable"] = listenable
+
+        super(Delegate, self).__init__(**metadata)
+
+        self.delegate = delegate
+        self.prefix = prefix
+        self.prefix_type = prefix_type
+        self.modify = modify
+
+    def as_ctrait(self):
+        """ Returns a CTrait corresponding to the trait defined by this class.
+        """
+        trait = super(Delegate, self).as_ctrait()
+        trait.delegate(
+            self.delegate, self.prefix, self.prefix_type, self.modify
+        )
+
+        return trait
+
+
+class DelegatesTo(Delegate):
+    """ A trait type that matches the 'delegate' design pattern.
+
+    This defines a trait whose value and definition is "delegated" to
+    another trait on a different object.
+
+    An object containing a delegator trait attribute must contain a
+    second attribute that references the object containing the delegate
+    trait attribute. The name of this second attribute is passed as the
+    *delegate* argument to the DelegatesTo() function.
+
+    The following rules govern the application of the prefix parameter:
+
+    * If *prefix* is empty or omitted, the delegation is to an attribute
+      of the delegate object with the same name as the delegator
+      attribute.
+    * If *prefix* is a valid Python attribute name, then the delegation
+      is to an attribute whose name is the value of *prefix*.
+    * If *prefix* ends with an asterisk ('*') and is longer than one
+      character, then the delegation is to an attribute whose name is
+      the value of *prefix*, minus the trailing asterisk, prepended to
+      the delegator attribute name.
+    * If *prefix* is equal to a single asterisk, the delegation is to an
+      attribute whose name is the value of the delegator object's
+      __prefix__ attribute prepended to delegator attribute name.
+
+    Note that any changes to the delegator attribute are actually
+    applied to the corresponding attribute on the delegate object. The
+    original object containing the delegator trait is not modified.
+
+    Parameters
+    ----------
+    delegate : str
+        Name of the attribute on the current object which references
+        the object that is the trait's delegate.
+    prefix : str
+        A prefix or substitution applied to the original attribute when
+        looking up the delegated attribute.
+    listenable : bool
+        Indicates whether a listener can be attached to this attribute
+        such that changes to the delegated attribute will trigger it.
+    **metadata
+        Trait metadata for the trait.
+    """
+
+    def __init__(self, delegate, prefix="", listenable=True, **metadata):
+        super(DelegatesTo, self).__init__(
+            delegate,
+            prefix=prefix,
+            modify=True,
+            listenable=listenable,
+            **metadata
+        )
+
+
+class PrototypedFrom(Delegate):
+    """ A trait type that matches the 'prototype' design pattern.
+
+    This defines a trait whose default value and definition is "prototyped"
+    from another trait on a different object.
+
+    An object containing a prototyped trait attribute must contain a
+    second attribute that references the object containing the prototype
+    trait attribute. The name of this second attribute is passed as the
+    *prototype* argument to the PrototypedFrom() function.
+
+    The following rules govern the application of the prefix parameter:
+
+    * If *prefix* is empty or omitted, the prototype delegation is to an
+      attribute of the prototype object with the same name as the
+      prototyped attribute.
+    * If *prefix* is a valid Python attribute name, then the prototype
+      delegation is to an attribute whose name is the value of *prefix*.
+    * If *prefix* ends with an asterisk ('*') and is longer than one
+      character, then the prototype delegation is to an attribute whose
+      name is the value of *prefix*, minus the trailing asterisk,
+      prepended to the prototyped attribute name.
+    * If *prefix* is equal to a single asterisk, the prototype
+      delegation is to an attribute whose name is the value of the
+      prototype object's __prefix__ attribute prepended to the
+      prototyped attribute name.
+
+    Note that any changes to the prototyped attribute are made to the
+    original object, not the prototype object. The prototype object is
+    only used to define to trait type and default value.
+
+    Parameters
+    ----------
+    prototype : str
+        Name of the attribute on the current object which references the
+        object that is the trait's prototype.
+    prefix : str
+        A prefix or substitution applied to the original attribute when
+        looking up the prototyped attribute.
+    listenable : bool
+        Indicates whether a listener can be attached to this attribute
+        such that changes to the corresponding attribute on the
+        prototype object will trigger it.
+    **metadata
+        Trait metadata for the trait.
+    """
+
+    def __init__(self, prototype, prefix="", listenable=True, **metadata):
+        super(PrototypedFrom, self).__init__(
+            prototype,
+            prefix=prefix,
+            modify=False,
+            listenable=listenable,
+            **metadata
+        )
+
+
+class Expression(TraitType):
+    """ A trait type whose value must be a valid Python expression.
+
+    The compiled form of a valid expression is stored as the mapped value of
+    the trait.
+    """
+
+    #: The default value for the trait:
+    default_value = "0"
+
+    #: A description of the type of value this trait accepts:
+    info_text = "a valid Python expression"
+
+    #: Indicate that this is a mapped trait:
+    is_mapped = True
+
+    def validate(self, object, name, value):
+        """ Validates that a specified value is valid for this trait.
+        """
+        try:
+            return compile(value, "<string>", "eval")
+        except:
+            self.error(object, name, value)
+
+    def post_setattr(self, object, name, value):
+        """ Performs additional post-assignment processing.
+        """
+        object.__dict__[name + "_"] = value
+
+    def mapped_value(self, value):
+        """ Returns the 'mapped' value for the specified **value**.
+        """
+        return compile(value, "<string>", "eval")
+
+    def as_ctrait(self):
+        """ Returns a CTrait corresponding to the trait defined by this class.
+        """
+        # Tell the C code that 'setattr' should store the original, unadapted
+        # value passed to it:
+        ctrait = super(Expression, self).as_ctrait()
+        ctrait.setattr_original_value = True
+        return ctrait
+
+
+class PythonValue(Any):
+    """ A trait type whose value can be of any type.
+
+    The default editor is a ShellEditor.
+    """
+
+    #: The standard metadata for the trait:
+    metadata = {"editor": shell_editor}
+
+
+class BaseFile(BaseStr):
+    """ A trait type whose value must be a file path string.
+
+    For Python 3.6 and later this will accept os.pathlib Path objects,
+    converting them to the corresponding string value.
+
+    Parameters
+    ----------
+    value : str
+        The default value for the trait.
+    filter : str
+        A wildcard string to filter filenames in the file dialog box used by
+        the attribute trait editor.
+    auto_set : bool
+        Indicates whether the file editor updates the trait value after
+        every key stroke.
+    entries : int
+        A hint to the TraitsUI editor about how many values to display in
+        the editor.
+    exists : bool
+        Indicates whether the trait value must be an existing file or
+        not.
+
+    Attributes
+    ----------
+    filter : str
+        A wildcard string to filter filenames in the file dialog box used by
+        the attribute trait editor.
+    auto_set : bool
+        Indicates whether the file editor updates the trait value after
+        every key stroke.
+    entries : int
+        A hint to the TraitsUI editor about how many values to display in
+        the editor.
+    exists : bool
+        Indicates whether the trait value must be an existing file or
+        not.
+    """
+
+    #: A description of the type of value this trait accepts:
+    info_text = "a filename or object implementing the os.PathLike interface"
+
+    def __init__(
+        self,
+        value="",
+        filter=None,
+        auto_set=False,
+        entries=0,
+        exists=False,
+        **metadata
+    ):
+        self.filter = filter
+        self.auto_set = auto_set
+        self.entries = entries
+        self.exists = exists
+
+        super(BaseFile, self).__init__(value, **metadata)
+
+    def validate(self, object, name, value):
+        """ Validates that a specified value is valid for this trait.
+
+            Note: The 'fast validator' version performs this check in C.
+        """
+        if fspath is not None:
+            # Python 3.5 does not implement __fspath__
+            try:
+                # If value is of type os.PathLike, get the path representation
+                # The path representation could be either a str or bytes type
+                # If fspath returns bytes, further validation will fail.
+                value = fspath(value)
+            except TypeError:
+                pass
+
+        validated_value = super(BaseFile, self).validate(object, name, value)
+        if not self.exists:
+            return validated_value
+        elif isfile(value):
+            return validated_value
+
+        self.error(object, name, value)
+
+    def create_editor(self):
+        from traitsui.editors.file_editor import FileEditor
+
+        editor = FileEditor(
+            filter=self.filter or [],
+            auto_set=self.auto_set,
+            entries=self.entries,
+            dialog_style="open" if self.exists else "save",
+        )
+        return editor
+
+
+class File(BaseFile):
+    """ A fast-validating trait type whose value must be a file path string.
+
+    For Python 3.6 and later this will accept os.pathlib Path objects,
+    converting them to the corresponding string value.
+
+    Parameters
+    ----------
+    value : str
+        The default value for the trait.
+    filter : str
+        A wildcard string to filter filenames in the file dialog box used by
+        the attribute trait editor.
+    auto_set : bool
+        Indicates whether the file editor updates the trait value after
+        every key stroke.
+    entries : int
+        A hint to the TraitsUI editor about how many values to display in
+        the editor.
+    exists : bool
+        Indicates whether the trait value must be an existing file or
+        not.
+
+    Attributes
+    ----------
+    filter : str
+        A wildcard string to filter filenames in the file dialog box used by
+        the attribute trait editor.
+    auto_set : bool
+        Indicates whether the file editor updates the trait value after
+        every key stroke.
+    entries : int
+        A hint to the TraitsUI editor about how many values to display in
+        the editor.
+    exists : bool
+        Indicates whether the trait value must be an existing file or
+        not.
+    """
+
+    def __init__(
+        self,
+        value="",
+        filter=None,
+        auto_set=False,
+        entries=0,
+        exists=False,
+        **metadata
+    ):
+        super(File, self).__init__(
+            value, filter, auto_set, entries, exists, **metadata
+        )
+
+
+class BaseDirectory(BaseStr):
+    """ A trait type whose value must be a directory path string.
+
+    For Python 3.6 and greater, it also accepts objects implementing
+    the :class:`os.PathLike` interface, converting them to the corresponding
+    string.
+
+    Parameters
+    ----------
+    value : str
+        The default value for the trait.
+    auto_set : bool
+        Indicates whether the directory editor updates the trait value
+        after every key stroke.
+    entries : int
+        A hint to the TraitsUI editor about how many values to display in
+        the editor.
+    exists : bool
+        Indicates whether the trait value must be an existing directory or
+        not.
+
+    Attributes
+    ----------
+    auto_set : bool
+        Indicates whether the directory editor updates the trait value
+        after every key stroke.
+    entries : int
+        A hint to the TraitsUI editor about how many values to display in
+        the editor.
+    exists : bool
+        Indicates whether the trait value must be an existing directory or
+        not.
+    """
+
+    #: A description of the type of value this trait accepts:
+    info_text = ("a directory name or an object implementing "
+                 "the os.PathLike interface")
+
+    def __init__(
+        self, value="", auto_set=False, entries=0, exists=False, **metadata
+    ):
+        self.entries = entries
+        self.auto_set = auto_set
+        self.exists = exists
+
+        super(BaseDirectory, self).__init__(value, **metadata)
+
+    def validate(self, object, name, value):
+        """ Validates that a specified value is valid for this trait.
+
+        Note: The 'fast validator' version performs this check in C.
+        """
+        if fspath is not None:
+            # Python 3.5 does not implement __fspath__
+            try:
+                value = fspath(value)
+            except TypeError:
+                pass
+
+        validated_value = super(BaseDirectory, self).validate(
+            object, name, value
+        )
+        if not self.exists:
+            return validated_value
+        elif isdir(value):
+            return validated_value
+
+        self.error(object, name, value)
+
+    def create_editor(self):
+        from traitsui.editors.directory_editor import DirectoryEditor
+
+        editor = DirectoryEditor(auto_set=self.auto_set, entries=self.entries)
+        return editor
+
+
+class Directory(BaseDirectory):
+    """ A fast-validating trait type whose value is a directory path string.
+
+    For Python 3.6 and greater, it also accepts objects implementing
+    the :class:`os.PathLike` interface, converting them to the corresponding
+    string.
+
+    Parameters
+    ----------
+    value : str
+        The default value for the trait.
+    auto_set : bool
+        Indicates whether the directory editor updates the trait value
+        after every key stroke.
+    entries : int
+        A hint to the TraitsUI editor about how many values to display in
+        the editor.
+    exists : bool
+        Indicates whether the trait value must be an existing directory or
+        not.
+
+    Attributes
+    ----------
+    auto_set : bool
+        Indicates whether the directory editor updates the trait value
+        after every key stroke.
+    entries : int
+        A hint to the TraitsUI editor about how many values to display in
+        the editor.
+    exists : bool
+        Indicates whether the trait value must be an existing directory or
+        not.
+    """
+
+    def __init__(
+        self, value="", auto_set=False, entries=0, exists=False, **metadata
+    ):
+        # Fast validation is disabled (Github issue #877).
+        super(Directory, self).__init__(
+            value, auto_set, entries, exists, **metadata
+        )
+
+
+class BaseRange(TraitType):
+    """ A trait type whose numeric value lies inside a range.
+
+    The value held will be either an integer or a float, which type is
+    determined by whether the *low*, *high* and *value* arguments are
+    integers or floats.
+
+    The *low*, *high*, and *value* arguments must be of the same type
+    (integer or float), except in the case where either *low* or *high* is
+    a string (i.e. extended trait name).
+
+    If *value* is None or omitted, the default value is *low*, unless *low*
+    is None or omitted, in which case the default value is *high*.
+
+    Parameters
+    ----------
+    low : integer, float or string (i.e. extended trait name)
+        The low end of the range.
+    high : integer, float or string (i.e. extended trait name)
+        The high end of the range.
+    value : integer, float or string (i.e. extended trait name)
+        The default value of the trait.
+    exclude_low : bool
+        Indicates whether the low end of the range is exclusive.
+    exclude_high : bool
+        Indicates whether the high end of the range is exclusive.
+    """
+
+    def __init__(
+        self,
+        low=None,
+        high=None,
+        value=None,
+        exclude_low=False,
+        exclude_high=False,
+        **metadata
+    ):
+        if value is None:
+            if low is not None:
+                value = low
+            else:
+                value = high
+
+        super(BaseRange, self).__init__(value, **metadata)
+
+        vtype = type(high)
+        if (low is not None) and (
+            not issubclass(vtype, (float, str))
+        ):
+            vtype = type(low)
+
+        is_static = not issubclass(vtype, str)
+        if is_static and (vtype not in RangeTypes):
+            raise TraitError(
+                "Range can only be use for int or float "
+                "values, but a value of type %s was specified." % vtype
+            )
+
+        self._low_name = self._high_name = ""
+        self._vtype = Undefined
+
+        kind = None
+
+        if vtype is float:
+            self._validate = "float_validate"
+            kind = ValidateTrait.float_range
+            self._type_desc = "a floating point number"
+            if low is not None:
+                low = float(low)
+
+            if high is not None:
+                high = float(high)
+
+        elif vtype is int:
+            self._validate = "int_validate"
+            self._type_desc = "an integer"
+            if low is not None:
+                low = int(low)
+
+            if high is not None:
+                high = int(high)
+        else:
+            self.get, self.set, self.validate = self._get, self._set, None
+            self._vtype = None
+            self._type_desc = "a number"
+
+            if isinstance(high, str):
+                self._high_name = high = "object." + high
+            else:
+                self._vtype = type(high)
+            high = compile(str(high), "<string>", "eval")
+
+            if isinstance(low, str):
+                self._low_name = low = "object." + low
+            else:
+                self._vtype = type(low)
+            low = compile(str(low), "<string>", "eval")
+
+            if isinstance(value, str):
+                value = "object." + value
+            self._value = compile(str(value), "<string>", "eval")
+
+            self.default_value_type = DefaultValue.callable
+            self.default_value = self._get_default_value
+
+        exclude_mask = 0
+        if exclude_low:
+            exclude_mask |= 1
+
+        if exclude_high:
+            exclude_mask |= 2
+
+        if is_static and kind is not None:
+            self.init_fast_validate(kind, low, high, exclude_mask)
+
+        #: Assign type-corrected arguments to handler attributes:
+        self._low = low
+        self._high = high
+        self._exclude_low = exclude_low
+        self._exclude_high = exclude_high
+
+    def init_fast_validate(self, *args):
+        """ Does nothing for the BaseRange class. Used in the Range class to
+        set up the fast validator.
+        """
+        pass
+
+    def validate(self, object, name, value):
+        """ Validate that the value is in the specified range.
+        """
+        return getattr(self, self._validate)(object, name, value)
+
+    def float_validate(self, object, name, value):
+        """ Validate that the value is a float value in the specified range.
+        """
+        # Convert to exact type float, re-raising a TypeError as a TraitError
+        # and letting other errors propagate. Keep original value for
+        # error-reporting purposes.
+        original_value = value
+        try:
+            value = _validate_float(value)
+        except TypeError:
+            self.error(object, name, original_value)
+
+        if (
+            (
+                (self._low is None)
+                or (self._exclude_low and (self._low < value))
+                or ((not self._exclude_low) and (self._low <= value))
+            )
+            and (
+                (self._high is None)
+                or (self._exclude_high and (self._high > value))
+                or ((not self._exclude_high) and (self._high >= value))
+            )
+        ):
+            return value
+
+        self.error(object, name, original_value)
+
+    def int_validate(self, object, name, value):
+        """ Validate that the value is an int value in the specified range.
+        """
+        # Convert to exact type float, re-raising a TypeError as a TraitError
+        # and letting other errors propagate. Keep original value for
+        # error-reporting purposes.
+        original_value = value
+        try:
+            value = _validate_int(value)
+        except TypeError:
+            self.error(object, name, original_value)
+
+        if (
+            (
+                (self._low is None)
+                or (self._exclude_low and (self._low < value))
+                or ((not self._exclude_low) and (self._low <= value))
+            )
+            and (
+                (self._high is None)
+                or (self._exclude_high and (self._high > value))
+                or ((not self._exclude_high) and (self._high >= value))
+            )
+        ):
+            return value
+
+        self.error(object, name, original_value)
+
+    def _get_default_value(self, object):
+        """ Returns the default value of the range.
+        """
+        return eval(self._value)
+
+    def _get(self, object, name, trait):
+        """ Returns the current value of a dynamic range trait.
+        """
+        cname = "_traits_cache_" + name
+        value = object.__dict__.get(cname, Undefined)
+        if value is Undefined:
+            object.__dict__[cname] = value = eval(self._value)
+
+        low = eval(self._low)
+        high = eval(self._high)
+        if (low is not None) and (value < low):
+            value = low
+        elif (high is not None) and (value > high):
+            value = high
+
+        return self._typed_value(value, low, high)
+
+    def _set(self, object, name, value):
+        """ Sets the current value of a dynamic range trait.
+        """
+        if not isinstance(value, str):
+            try:
+                low = eval(self._low)
+                high = eval(self._high)
+                if (low is None) and (high is None):
+                    if isinstance(value, RangeTypes):
+                        self._set_value(object, name, value)
+                        return
+                else:
+                    new_value = self._typed_value(value, low, high)
+                    if (
+                        (low is None)
+                        or (self._exclude_low and (low < new_value))
+                        or ((not self._exclude_low) and (low <= new_value))
+                    ) and (
+                        (high is None)
+                        or (self._exclude_high and (high > new_value))
+                        or ((not self._exclude_high) and (high >= new_value))
+                    ):
+                        self._set_value(object, name, new_value)
+                        return
+            except:
+                pass
+
+        self.error(object, name, value)
+
+    def _typed_value(self, value, low, high):
+        """ Returns the specified value with the correct type for the current
+            dynamic range.
+        """
+        vtype = self._vtype
+        if vtype is None:
+            if low is not None:
+                vtype = type(low)
+            elif high is not None:
+                vtype = type(high)
+            else:
+                vtype = lambda x: x
+
+        return vtype(value)
+
+    def _set_value(self, object, name, value):
+        """ Sets the specified value as the value of the dynamic range.
+        """
+        cname = "_traits_cache_" + name
+        old = object.__dict__.get(cname, Undefined)
+        if old is Undefined:
+            old = eval(self._value)
+        object.__dict__[cname] = value
+        if value != old:
+            object.trait_property_changed(name, old, value)
+
+    def full_info(self, object, name, value):
+        """ Returns a description of the trait.
+        """
+        if self._vtype is not Undefined:
+            low = eval(self._low)
+            high = eval(self._high)
+            low, high = (
+                self._typed_value(low, low, high),
+                self._typed_value(high, low, high),
+            )
+        else:
+            low = self._low
+            high = self._high
+
+        if low is None:
+            if high is None:
+                return self._type_desc
+
+            return "%s <%s %s" % (
+                self._type_desc,
+                "="[self._exclude_high:],
+                high,
+            )
+
+        elif high is None:
+            return "%s >%s %s" % (
+                self._type_desc,
+                "="[self._exclude_low:],
+                low,
+            )
+
+        return "%s <%s %s <%s %s" % (
+            low,
+            "="[self._exclude_low:],
+            self._type_desc,
+            "="[self._exclude_high:],
+            high,
+        )
+
+    def create_editor(self):
+        """ Returns the default UI editor for the trait.
+        """
+        # fixme: Needs to support a dynamic range editor.
+
+        auto_set = self.auto_set
+        if auto_set is None:
+            auto_set = True
+
+        from traitsui.api import RangeEditor
+
+        return RangeEditor(
+            self,
+            mode=self.mode or "auto",
+            cols=self.cols or 3,
+            auto_set=auto_set,
+            enter_set=self.enter_set or False,
+            low_label=self.low or "",
+            high_label=self.high or "",
+            low_name=self._low_name,
+            high_name=self._high_name,
+        )
+
+
+class Range(BaseRange):
+    """ A fast-validating trait type whose numeric value lies inside a range.
+    """
+
+    def init_fast_validate(self, *args):
+        """ Set up the C-level fast validator.
+        """
+        self.fast_validate = args
+
+
+class BaseEnum(TraitType):
+    """ A trait type whose value is an element of a finite collection.
+
+    This trait type can be either *static*, with the collection of valid values
+    specified directly in the constructor, or *dynamic*, with the collection
+    provided by the value of another trait attribute.
+
+    For both static and dynamic enumerations, a default value can be provided
+    as a positional argument. If no default is provided, the default is the
+    first item (in iteration order) of the underlying collection.
+
+    Notes
+    -----
+
+    1. If the enumeration is based on an unordered collection like a
+       ``set``, and no explicit default is given, the default used will
+       effectively be arbitrary (the first element of the set in iteration
+       order). It's recommended that a default be given explicitly in this
+       case.
+
+    2. Instances of ``str``, ``bytes`` and ``bytearray`` are not treated
+       as collections for the purposes of this trait type, both for pragmatic
+       reasons (it's more likely that a user wants to use a string as an
+       element in a collection than as a collection in its own right), and
+       because the behavior of the ``in`` operator for those types does not
+       express the usual membership semantics (for example, ``"bc" in "abc"``
+       is ``True``).
+
+    Parameters
+    ----------
+    *args
+        The enumeration of all valid values for the trait. For a static
+        enumeration trait (where the *values* keyword argument is not given)
+        the supported signatures for ``args`` are as follows:
+
+        (collection,)
+            A nonempty collection of valid values. The default is the first
+            element of the collection, in iteration order.
+        (default, collection)
+            The default value, followed by a nonempty collection of valid
+            values. The default should be an element of the collection, but
+            this is not checked.
+        (item1, item2, ..., itemn)
+            One or more items giving the valid values for the collection.
+            The default is *item1*.
+
+        For a dynamic enumeration trait, where the *values* keyword argument
+        is given, the supported signatures for ``args`` are:
+
+        ()
+            No arguments given. In this case the default is the first item
+            of the collection, in iteration order.
+        (default,)
+            The default value for the collection.
+
+        For the static case, the ambiguity in the signatures is resolved
+        as follows: if ``args`` has length ``1`` or ``2``, ``args[-1]`` can be
+        iterated over, and ``args[-1]`` is not an instance of ``str``,
+        ``bytes`` or ``bytearray``, then ``args[-1]`` is assumed to give the
+        collection of values. Otherwise, all elements of ``args`` are assumed
+        to be items in the collection. Thus the first two signatures are safe
+        from ambiguity, and it's recommended to use one of these two signatures
+        in preference to the third form.
+    values : str, optional
+        The name of a trait holding the valid values. If given, this is
+        a dynamic enumeration, otherwise it's a static numeration.
+    **metadata
+        Metadata for the trait.
+
+    Attributes
+    ----------
+    values : tuple or None
+        For a static enumeration, this is a tuple holding the valid values.
+        For a dynamic enumeration, this is None.
+    name : str or None
+        For a dynamic enumeration, this is the name of a trait holding
+        the collection of valid values. For a static enumeration, this is
+        None.
+    """
+
+    def __init__(self, *args, values=None, **metadata):
+        self.name = values
+
+        nargs = len(args)
+        if self.name is not None:
+            # Dynamic enumeration
+            self.values = None
+            self.get, self.set, self.validate = self._get, self._set, None
+            if nargs == 0:
+                super(BaseEnum, self).__init__(**metadata)
+            elif nargs == 1:
+                default_value = args[0]
+                super(BaseEnum, self).__init__(default_value, **metadata)
+            else:
+                raise TraitError(
+                    "Incorrect number of arguments specified "
+                    "when using the 'values' keyword"
+                )
+        else:
+            # Static enumeration
+            if nargs == 0:
+                raise TraitError("Enum trait requires at least 1 argument")
+
+            # If we have either 1 or 2 arguments and the last argument is a
+            # collection, then that collection provides the values of the
+            # enumeration. Otherwise, args itself is the collection.
+            have_collection_arg = (
+                nargs <= 2
+                and not isinstance(args[-1], (str, bytes, bytearray))
+                and isinstance(args[-1], collections.abc.Iterable)
+            )
+            self.values = tuple(args[-1]) if have_collection_arg else args
+            if not self.values:
+                raise TraitError("Enum collection should be nonempty")
+
+            # In the two-argument collection case, the first argument is
+            # the default. Otherwise, we take the first element of self.values.
+            if have_collection_arg and nargs == 2:
+                default_value = args[0]
+            else:
+                default_value = self.values[0]
+
+            self.init_fast_validate(ValidateTrait.enum, self.values)
+
+            super(BaseEnum, self).__init__(default_value, **metadata)
+
+    def init_fast_validate(self, *args):
+        """ Does nothing for the BaseEnum class. Used in the Enum class to set
+            up the fast validator.
+        """
+        pass
+
+    def validate(self, object, name, value):
+        """ Validates that the value is one of the enumerated set of valid
+        values.
+        """
+        if value in self.values:
+            return value
+
+        self.error(object, name, value)
+
+    def full_info(self, object, name, value):
+        """ Returns a description of the trait.
+        """
+        if self.name is None:
+            values = self.values
+        else:
+            values = xgetattr(object, self.name)
+
+        return " or ".join([repr(x) for x in values])
+
+    def create_editor(self):
+        """ Returns the default UI editor for the trait.
+        """
+        from traitsui.api import EnumEditor
+
+        if self.name is None:
+            values = self.values
+            name = ""
+        else:
+            values = None
+            name = self.name
+
+        editor = EnumEditor(
+            name=name,
+            cols=self.cols or 3,
+            evaluate=self.evaluate,
+            format_func=self.format_func,
+            mode=self.mode if self.mode else "radio",
+        )
+        # Workaround enthought/traitsui#782
+        if values is not None:
+            editor.values = values
+        return editor
+
+    def _get(self, object, name, trait):
+        """ Returns the current value of a dynamic enum trait.
+        """
+        value = self.get_value(object, name, trait)
+        values = xgetattr(object, self.name)
+        if not safe_contains(value, values):
+            value = next(iter(values), None)
+        return value
+
+    def _set(self, object, name, value):
+        """ Sets the current value of a dynamic range trait.
+        """
+        if safe_contains(value, xgetattr(object, self.name)):
+            self.set_value(object, name, value)
+        else:
+            self.error(object, name, value)
+
+
+class Enum(BaseEnum):
+    """ A fast-validating trait type whose value is an element of a finite
+    collection.
+
+    This trait type can be either *static*, with the collection of valid values
+    specified directly in the constructor, or *dynamic*, with the collection
+    provided by the value of another trait attribute.
+
+    For both static and dynamic enumerations, a default value can be provided
+    as a positional argument. If no default is provided, the default is the
+    first item (in iteration order) of the underlying collection.
+
+    Notes
+    -----
+
+    1. If the enumeration is based on an unordered collection like a
+       ``set``, and no explicit default is given, the default used will
+       effectively be arbitrary (the first element of the set in iteration
+       order). It's recommended that a default be given explicitly in this
+       case.
+
+    2. Instances of ``str``, ``bytes`` and ``bytearray`` are not treated
+       as collections for the purposes of this trait type, both for pragmatic
+       reasons (it's more likely that a user wants to use a string as an
+       element in a collection than as a collection in its own right), and
+       because the behavior of the ``in`` operator for those types does not
+       express the usual membership semantics (for example, ``"bc" in "abc"``
+       is ``True``).
+
+    Parameters
+    ----------
+    *args
+        The enumeration of all valid values for the trait. For a static
+        enumeration trait (where the *values* keyword argument is not given)
+        the supported signatures for ``args`` are as follows:
+
+        (collection,)
+            A nonempty collection of valid values. The default is the first
+            element of the collection, in iteration order.
+        (default, collection)
+            The default value, followed by a nonempty collection of valid
+            values. The default should be an element of the collection, but
+            this is not checked.
+        (item1, item2, ..., itemn)
+            One or more items giving the valid values for the collection.
+            The default is *item1*.
+
+        For a dynamic enumeration trait, where the *values* keyword argument
+        is given, the supported signatures for ``args`` are:
+
+        ()
+            No arguments given. In this case the default is the first item
+            of the collection, in iteration order.
+        (default,)
+            The default value for the collection.
+
+        For the static case, the ambiguity in the signatures is resolved
+        as follows: if ``args`` has length ``1`` or ``2``, ``args[-1]`` can be
+        iterated over, and ``args[-1]`` is not an instance of ``str``,
+        ``bytes`` or ``bytearray``, then ``args[-1]`` is assumed to give the
+        collection of values. Otherwise, all elements of ``args`` are assumed
+        to be items in the collection. Thus the first two signatures are safe
+        from ambiguity, and it's recommended to use one of these two signatures
+        in preference to the third form.
+    values : str, optional
+        The name of a trait holding the valid values. If given, this is
+        a dynamic enumeration, otherwise it's a static numeration.
+    **metadata
+        Metadata for the trait.
+
+    Attributes
+    ----------
+    values : tuple or None
+        For a static enumeration, this is a tuple holding the valid values.
+        For a dynamic enumeration, this is None.
+    name : str or None
+        For a dynamic enumeration, this is the name of a trait holding
+        the collection of valid values. For a static enumeration, this is
+        None.
+    """
+
+    def init_fast_validate(self, *args):
+        """ Set up C-level fast validation. """
+        self.fast_validate = args
+
+
+class BaseTuple(TraitType):
+    """ A trait type holding a tuple with typed elements.
+
+    The default value is determined as follows:
+
+    1.  If no arguments are specified, the default value is ().
+    2.  If a tuple is specified as the first argument, it is the default
+        value.
+    3.  If a tuple is not specified as the first argument, the default
+        value is a tuple whose length is the length of the argument list,
+        and whose values are the default values for the corresponding trait
+        types.
+
+    Example for case #2::
+
+        mytuple = Tuple(('Fred', 'Betty', 5))
+
+    The trait's value must be a 3-element tuple whose first and second
+    elements are strings, and whose third element is an integer. The
+    default value is ``('Fred', 'Betty', 5)``.
+
+    Example for case #3::
+
+        mytuple = Tuple('Fred', 'Betty', 5)
+
+    The trait's value must be a 3-element tuple whose first and second
+    elements are strings, and whose third element is an integer. The
+    default value is ``('','',0)``.
+
+    Parameters
+    ----------
+    *types
+        Definition of the default and allowed tuples. If the first item of
+        *types* is a tuple, it is used as the default value.
+        The remaining argument list is used to form a tuple that constrains
+        the  values assigned to the returned trait. The trait's value must
+        be a tuple of the same length as the remaining argument list, whose
+        elements must match the types specified by the corresponding items
+        of the remaining argument list.
+    **metadata
+        Trait metadata for the trait.
+
+    Attributes
+    ----------
+    types : tuple
+        The tuple of traits specifying the type of each element in order.
+    no_type_check : bool
+        Flag to indicate whether validation should check the type of each
+        element.
+    """
+
+    def __init__(self, *types, **metadata):
+        if len(types) == 0:
+            self.init_fast_validate(ValidateTrait.coerce, tuple, None, list)
+
+            super(BaseTuple, self).__init__((), **metadata)
+
+            return
+
+        default_value = None
+
+        if isinstance(types[0], tuple):
+            default_value, types = types[0], types[1:]
+            if len(types) == 0:
+                types = [Trait(element) for element in default_value]
+
+        self.types = tuple([trait_from(type) for type in types])
+        self.init_fast_validate(ValidateTrait.tuple, self.types)
+
+        if default_value is None:
+            default_value = tuple(
+                [type.default_value()[1] for type in self.types]
+            )
+
+        super(BaseTuple, self).__init__(default_value, **metadata)
+
+    def init_fast_validate(self, *args):
+        """ Saves the validation parameters.
+        """
+        self.no_type_check = args[0] == ValidateTrait.coerce
+
+    def validate(self, object, name, value):
+        """ Validates that the value is a valid tuple.
+        """
+        if self.no_type_check:
+            if isinstance(value, tuple):
+                return value
+
+            if isinstance(value, list):
+                return tuple(value)
+
+            self.error(object, name, value)
+
+        try:
+            if isinstance(value, list):
+                value = tuple(value)
+
+            if isinstance(value, tuple):
+                types = self.types
+                if len(value) == len(types):
+                    values = []
+                    for i, type in enumerate(types):
+                        values.append(type.validate(object, name, value[i]))
+
+                    return tuple(values)
+        except:
+            pass
+
+        self.error(object, name, value)
+
+    def full_info(self, object, name, value):
+        """ Returns a description of the trait.
+        """
+        if self.no_type_check:
+            return "a tuple"
+
+        return "a tuple of the form: (%s)" % (
+            ", ".join(
+                [type.full_info(object, name, value) for type in self.types]
+            )
+        )
+
+    def create_editor(self):
+        """ Returns the default UI editor for the trait.
+        """
+        from traitsui.api import TupleEditor
+
+        auto_set = self.auto_set
+        if auto_set is None:
+            auto_set = True
+        enter_set = self.enter_set or False
+
+        return TupleEditor(
+            types=self.types,
+            labels=self.labels or [],
+            cols=self.cols or 1,
+            auto_set=auto_set,
+            enter_set=enter_set,
+        )
+
+
+class Tuple(BaseTuple):
+    """ A fast-validating trait type holding a tuple with typed elements.
+    """
+
+    def init_fast_validate(self, *args):
+        """ Set up the C-level fast validator.
+        """
+        super(Tuple, self).init_fast_validate(*args)
+
+        self.fast_validate = args
+
+
+class ValidatedTuple(BaseTuple):
+    """ A trait type holding a tuple with customized validation.
+
+    Parameters
+    ----------
+    *types
+        Definition of the default and allowed tuples. (see
+        :class:`~.BaseTuple` for more details)
+    fvalidate : callable, optional
+        A callable to provide the additional custom validation for the
+        tuple. The callable will be passed the tuple value and should
+        return True or False.
+    fvalidate_info : string, optional
+        A string describing the custom validation to use for the error
+        messages.
+    **metadata
+        Trait metadata for the trait.
+
+    Example
+    -------
+    The definition::
+
+        value_range = ValidatedTuple(
+            Int(0), Int(1), fvalidate=lambda x: x[0] < x[1])
+
+    will accept only tuples ``(a, b)`` containing two integers that
+    satisfy ``a < b``.
+    """
+
+    def __init__(self, *types, **metadata):
+        metadata.setdefault("fvalidate", None)
+        metadata.setdefault("fvalidate_info", "")
+        super(ValidatedTuple, self).__init__(*types, **metadata)
+
+    def validate(self, object, name, value):
+        """ Validates that the value is a valid tuple.
+        """
+        values = super(ValidatedTuple, self).validate(object, name, value)
+        # Exceptions in the fvalidate function will not result in a TraitError
+        # but will be allowed to propagate up the frame stacks.
+        if self.fvalidate is None or self.fvalidate(values):
+            return values
+        else:
+            self.error(object, name, value)
+
+    def full_info(self, object, name, value):
+        """ Returns a description of the trait.
+        """
+        message = "a tuple of the form: ({0}) that passes custom validation{1}"
+        types_info = ", ".join(
+            [type_.full_info(object, name, value) for type_ in self.types]
+        )
+        if self.fvalidate_info is not None:
+            fvalidate_info = ": {0}".format(self.fvalidate_info)
+        else:
+            fvalidate_info = ""
+        return message.format(types_info, fvalidate_info)
+
+
+class List(TraitType):
+    """ A trait type for a list of values of the specified type.
+
+    The length of the list assigned to the trait must be such that::
+
+        minlen <= len(list) <= maxlen
+
+    Parameters
+    ----------
+    trait : a trait or value that can be converted using trait_from()
+        The type of item that the list contains. If not specified, the list
+        can contain items of any type.
+    value : list
+        Default value for the list.
+    minlen : integer
+        The minimum length of a list that can be assigned to the trait.
+    maxlen : integer
+        The maximum length of a list that can be assigned to the trait.
+    items : bool
+        Whether there is a corresponding `<name>_items` trait.
+    **metadata
+        Trait metadata for the trait.
+
+    Attributes
+    ----------
+    item_trait : trait
+        The type of item that the list contains.
+    minlen : integer
+        The minimum length of a list that can be assigned to the trait.
+    maxlen : integer
+        The maximum length of a list that can be assigned to the trait.
+    has_items : bool
+        Whether there is a corresponding `<name>_items` trait.
+    """
+
+    info_trait = None
+    default_value_type = DefaultValue.trait_list_object
+    _items_event = None
+
+    def __init__(
+        self,
+        trait=None,
+        value=None,
+        minlen=0,
+        maxlen=sys.maxsize,
+        items=True,
+        **metadata
+    ):
+        metadata.setdefault("copy", "deep")
+
+        if isinstance(trait, SequenceTypes):
+            trait, value = value, list(trait)
+
+        if value is None:
+            value = []
+
+        self.item_trait = trait_from(trait)
+        self.minlen = max(0, minlen)
+        self.maxlen = max(minlen, maxlen)
+        self.has_items = items
+
+        if self.item_trait.instance_handler == "_instance_changed_handler":
+            metadata.setdefault("instance_handler", "_list_changed_handler")
+
+        super(List, self).__init__(value, **metadata)
+
+    def validate(self, object, name, value):
+        """ Validates that the values is a valid list.
+
+        .. note::
+
+            `object` can be None when validating a default value (see e.g.
+            :meth:`~traits.trait_handlers.TraitType.clone`)
+
+        """
+        if isinstance(value, list) and (
+            self.minlen <= len(value) <= self.maxlen
+        ):
+            if object is None:
+                return value
+
+            return TraitListObject(self, object, name, value)
+
+        self.error(object, name, value)
+
+    def full_info(self, object, name, value):
+        """ Returns a description of the trait.
+        """
+        if self.minlen == 0:
+            if self.maxlen == sys.maxsize:
+                size = "items"
+            else:
+                size = "at most %d items" % self.maxlen
+        else:
+            if self.maxlen == sys.maxsize:
+                size = "at least %d items" % self.minlen
+            else:
+                size = "from %s to %s items" % (self.minlen, self.maxlen)
+
+        return "a list of %s which are %s" % (
+            size,
+            self.item_trait.full_info(object, name, value),
+        )
+
+    def create_editor(self):
+        """ Returns the default UI editor for the trait.
+        """
+        return list_editor(self, self)
+
+    def inner_traits(self):
+        """ Returns the *inner trait* (or traits) for this trait.
+        """
+        return (self.item_trait,)
+
+    # -- Private Methods ------------------------------------------------------
+
+    def items_event(self):
+        cls = self.__class__
+        if cls._items_event is None:
+            cls._items_event = Event(
+                TraitListEvent, is_base=False
+            ).as_ctrait()
+
+        return cls._items_event
+
+
+class CList(List):
+    """ A coercing trait type for a list of values of the specified type.
+    """
+
+    def validate(self, object, name, value):
+        """ Validates that the values is a valid list.
+        """
+        if not isinstance(value, list):
+            try:
+                # Should work for all iterables as well as strings (which do
+                # not define an __iter__ method)
+                value = list(value)
+            except (ValueError, TypeError):
+                value = [value]
+
+        return super(CList, self).validate(object, name, value)
+
+    def full_info(self, object, name, value):
+        """ Returns a description of the trait.
+        """
+        return "%s or %s" % (
+            self.item_trait.full_info(object, name, value),
+            super(CList, self).full_info(object, name, value),
+        )
+
+
+class PrefixList(TraitType):
+    r"""Ensures that a value assigned to the attribute is a member of a list of
+     specified string values, or is a unique prefix of one of those values.
+
+    The values that can be assigned to a trait attribute of type PrefixList
+    type is the set of all strings supplied to the PrefixList constructor,
+    as well as any unique prefix of those strings. That is, if the set of
+    strings supplied to the constructor is described by
+    [*s*\ :sub:`1`\ , *s*\ :sub:`2`\ , ..., *s*\ :sub:`n`\ ], then the
+    string *v* is a valid value for the trait if *v* == *s*\ :sub:`i[:j]`
+    for one and only one pair of values (i, j). If *v* is a valid value,
+    then the actual value assigned to the trait attribute is the
+    corresponding *s*\ :sub:`i` value that *v* matched.
+
+    The legal values can be provided as an iterable of values.
+
+    Example
+    -------
+    ::
+        class Person(HasTraits):
+            married = PrefixList(['yes', 'no'])
+
+    The Person class has a **married** trait that accepts any of the
+    strings 'y', 'ye', 'yes', 'n', or 'no' as valid values. However, the
+    actual values assigned as the value of the trait attribute are limited
+    to either 'yes' or 'no'. That is, if the value 'y' is assigned to the
+    **married** attribute, the actual value assigned will be 'yes'.
+
+    Note that the algorithm used by PrefixList in determining whether
+    a string is a valid value is fairly efficient in terms of both time and
+    space, and is not based on a brute force set of comparisons.
+
+    Parameters
+    ----------
+    values
+        A single iterable of legal string values.
+
+    Attributes
+    ----------
+    values : tuple of strings
+        Enumeration of all legal values for a trait.
+    """
+
+    #: The default value for the trait:
+    default_value = None
+
+    #: The default value type to use (i.e. 'constant'):
+    default_value_type = DefaultValue.constant
+
+    def __init__(self, values, **metadata):
+        if isinstance(values, (str, bytes, bytearray)):
+            raise TypeError(
+                "Legal values should be provided via an iterable of strings, "
+                "got {!r}.".format(values)
+            )
+        self.values = list(values)
+        self.values_ = values_ = {}
+        for key in values:
+            values_[key] = key
+
+        default = self.default_value
+        if 'default_value' in metadata:
+            default = metadata.pop('default_value')
+            default = self.value_for(default)
+        elif self.values:
+            default = self.values[0]
+
+        super().__init__(default, **metadata)
+
+    def value_for(self, value):
+        if not isinstance(value, str):
+            raise TraitError(
+                "The value of a {} trait must be {}, but a value of {!r} {!r} "
+                "was specified.".format(
+                    self.__class__.__name__, self.info(), value, type(value))
+            )
+
+        if value in self.values_:
+            return self.values_[value]
+
+        matches = [key for key in self.values if key.startswith(value)]
+        if len(matches) == 1:
+            self.values_[value] = match = matches[0]
+            return match
+
+        raise TraitError(
+            "The value of a {} trait must be {}, but a value of {!r} {!r} was "
+            "specified.".format(
+                self.__class__.__name__, self.info(), value, type(value))
+        )
+
+    def info(self):
+        return (
+            " or ".join([repr(x) for x in self.values])
+            + " (or any unique prefix)"
+        )
+
+
+class Set(TraitType):
+    """ A trait type for a set of values of the specified type.
+
+    Parameters
+    ----------
+    trait : a trait or value that can be converted to a trait using Trait()
+        The type of item that the list contains. If not specified, the list
+        can contain items of any type.
+    value : set
+        Default value for the set.
+    items : bool
+        Whether there is a corresponding `<name>_items` trait.
+    **metadata
+        Trait metadata for the trait.
+
+    Attributes
+    ----------
+    item_trait : a trait or value that can be converted to a trait
+        The type of item that the list contains. If not specified, the list
+        can contain items of any type.
+    has_items : bool
+        Whether there is a corresponding `<name>_items` trait.
+    """
+
+    info_trait = None
+    default_value_type = DefaultValue.trait_set_object
+    _items_event = None
+
+    def __init__(self, trait=None, value=None, items=True, **metadata):
+        metadata.setdefault("copy", "deep")
+
+        if isinstance(trait, SetTypes):
+            trait, value = value, set(trait)
+
+        if value is None:
+            value = set()
+
+        self.item_trait = trait_from(trait)
+        self.has_items = items
+
+        super(Set, self).__init__(value, **metadata)
+
+    def validate(self, object, name, value):
+        """ Validates that the values is a valid set.
+
+        .. note::
+
+            `object` can be None when validating a default value (see e.g.
+            :meth:`~traits.trait_handlers.TraitType.clone`)
+
+        """
+        if isinstance(value, set):
+            if object is None:
+                return value
+
+            return TraitSetObject(self, object, name, value)
+
+        self.error(object, name, value)
+
+    def full_info(self, object, name, value):
+        """ Returns a description of the trait.
+        """
+        return "a set of %s" % self.item_trait.full_info(object, name, value)
+
+    def create_editor(self):
+        """ Returns the default UI editor for the trait.
+        """
+        from traitsui.api import TextEditor
+
+        return TextEditor(evaluate=eval)
+
+    def inner_traits(self):
+        """ Returns the *inner trait* (or traits) for this trait.
+        """
+        return (self.item_trait,)
+
+    # -- Private Methods ------------------------------------------------------
+
+    def items_event(self):
+        if self.__class__._items_event is None:
+            self.__class__._items_event = Event(
+                TraitSetEvent, is_base=False
+            ).as_ctrait()
+
+        return self.__class__._items_event
+
+
+class CSet(Set):
+    """ A coercing trait type for a set of values of the specified type.
+    """
+
+    def validate(self, object, name, value):
+        """ Validates that the values is a valid list.
+        """
+        if not isinstance(value, set):
+            try:
+                # Should work for all iterables as well as strings (which do
+                # not define an __iter__ method)
+                value = set(value)
+            except (ValueError, TypeError):
+                value = set([value])
+
+        return super(CSet, self).validate(object, name, value)
+
+    def full_info(self, object, name, value):
+        """ Returns a description of the trait.
+        """
+        return "%s or %s" % (
+            self.item_trait.full_info(object, name, value),
+            super(CSet, self).full_info(object, name, value),
+        )
+
+
+class Dict(TraitType):
+    """ A trait type for a dictionary with specified key and value types.
+
+
+    Parameters
+    ----------
+    key_trait : a trait or value that can be converted using trait_from()
+        The trait type for keys in the dictionary; if not specified, any
+        values can be used as keys.
+    value_trait : a trait or value that can be converted using trait_from()
+        The trait type for values in the dictionary; if not specified, any
+        values can be used as dictionary values.
+    value : dict
+        The default value for the returned trait.
+    items : bool
+        Indicates whether the value contains items.
+
+    Attributes
+    ----------
+    key_trait : a trait
+        The trait type for keys in the dictionary; if not specified, any
+        values can be used as keys.
+    value_trait : a trait
+        The trait type for values in the dictionary; if not specified, any
+        values can be used as dictionary values.
+    value_trait_handler : TraitHandler
+        The TraitHandler for the value_trait.
+    has_items : bool
+        Indicates whether the value contains items.
+    """
+
+    info_trait = None
+    default_value_type = DefaultValue.trait_dict_object
+    _items_event = None
+
+    def __init__(
+        self,
+        key_trait=None,
+        value_trait=None,
+        value=None,
+        items=True,
+        **metadata
+    ):
+        if isinstance(key_trait, dict):
+            key_trait, value_trait, value = value_trait, value, key_trait
+
+        if value is None:
+            value = {}
+
+        self.key_trait = trait_from(key_trait)
+        self.value_trait = trait_from(value_trait)
+        self.has_items = items
+
+        handler = self.value_trait.handler
+        if (handler is not None) and handler.has_items:
+            handler = handler.clone()
+            handler.has_items = False
+        self.value_handler = handler
+
+        super(Dict, self).__init__(value, **metadata)
+
+    def validate(self, object, name, value):
+        """ Validates that the value is a valid dictionary.
+
+        Note
+        ----
+        `object` can be None when validating a default value (see e.g.
+        :meth:`~traits.trait_handlers.TraitType.clone`)
+        """
+        if isinstance(value, dict):
+            if object is None:
+                return value
+            return TraitDictObject(self, object, name, value)
+
+        self.error(object, name, value)
+
+    def full_info(self, object, name, value):
+        """ Returns a description of the trait.
+        """
+        return (
+            "a dictionary with keys which are %s and with values which "
+            "are %s"
+        ) % (
+            self.key_trait.full_info(object, name, value),
+            self.value_trait.full_info(object, name, value),
+        )
+
+    def create_editor(self):
+        """ Returns the default UI editor for the trait.
+        """
+        from traitsui.api import TextEditor
+
+        return TextEditor(evaluate=eval)
+
+    def inner_traits(self):
+        """ Returns the *inner trait* (or traits) for this trait.
+        """
+        return (self.key_trait, self.value_trait)
+
+    # -- Private Methods ------------------------------------------------------
+
+    def items_event(self):
+        cls = self.__class__
+        if cls._items_event is None:
+            cls._items_event = Event(TraitDictEvent, is_base=False).as_ctrait()
+
+        return cls._items_event
+
+
+#: Allowed values and mappings for the 'adapt' keyword.
+#:
+#: - 'no': Adaptation is not allowed.
+#: - 'yes': Adaptation is allowed. If adaptation fails, an
+#:   exception should be raised.
+#: - 'default': Adaptation is allowed. If adaptation fails, the
+#:   default value for the trait should be used.
+AdaptMap = {"no": 0, "yes": 1, "default": 2}
+
+
+class Map(TraitType):
+    """ Checks that the value assigned to a trait attribute is a key of a
+        specified dictionary, and also assigns the dictionary value
+        corresponding to that key to a *shadow* attribute.
+
+        A trait attribute of type Map is called a *mapped* trait
+        attribute. In practice, this means that the resulting object actually
+        contains two attributes: one whose value is a key of the Map
+        dictionary, and the other whose value is the corresponding value of the
+        Map dictionary. The name of the shadow attribute is simply the base
+        attribute name with an underscore ('_') appended. Mapped trait
+        attributes can be used to allow a variety of user-friendly input values
+        to be mapped to a set of internal, program-friendly values.
+
+        Example
+        -------
+
+        The following example defines a ``Person`` class::
+
+            >>> class Person(HasTraits):
+            ...     married = Map({'yes': 1, 'no': 0 }, default_value="yes")
+            ...
+            >>> bob = Person()
+            >>> print(bob.married)
+            yes
+            >>> print(bob.married_)
+            1
+
+        In this example, the default value of the ``married`` attribute of the
+        Person class is 'yes'. Because this attribute is defined using
+        Map, instances of Person have another attribute,
+        ``married_``, whose default value is 1, the dictionary value
+        corresponding to the key 'yes'.
+
+        Parameters
+        ----------
+        map : dict
+            A dictionary whose keys are valid values for the trait attribute,
+            and whose corresponding values are the values for the shadow
+            trait attribute.
+        default_value : object, optional
+            The default value for the trait. If given, this should be a key
+            from the mapping. If not given, the first key from the mapping (in
+            normal dictionary iteration order) will be used as the default.
+
+        Attributes
+        ----------
+        map : dict
+            A dictionary whose keys are valid values for the trait attribute,
+            and whose corresponding values are the values for the shadow
+            trait attribute.
+    """
+
+    is_mapped = True
+
+    def __init__(self, map, **metadata):
+
+        self.map = map
+        self.fast_validate = (ValidateTrait.map, map)
+
+        try:
+            default_value = metadata.pop("default_value")
+        except KeyError:
+            default_value = next(iter(self.map))
+
+        super().__init__(default_value, **metadata)
+
+    def validate(self, object, name, value):
+        try:
+            if value in self.map:
+                return value
+        except TypeError:
+            pass
+
+        self.error(object, name, value)
+
+    def mapped_value(self, value):
+        """ Get the mapped value for a value. """
+        return self.map[value]
+
+    def post_setattr(self, object, name, value):
+        setattr(object, name + "_", self.mapped_value(value))
+
+    def info(self):
+        keys = sorted(repr(x) for x in self.map.keys())
+        return " or ".join(keys)
+
+    def get_editor(self, trait):
+        from traitsui.api import EnumEditor
+
+        return EnumEditor(values=self, cols=trait.cols or 3)
+
+
+class PrefixMap(TraitType):
+    """ A cross between the PrefixList and Map classes.
+
+    Like Map, PrefixMap is created using a dictionary, but in this
+    case, the keys of the dictionary must be strings. Like PrefixList,
+    a string *v* is a valid value for the trait attribute if it is a prefix of
+    one and only one key *k* in the dictionary. The actual values assigned to
+    the trait attribute is *k*, and its corresponding mapped attribute is
+    *map*[*k*].
+
+    Example
+    -------
+    ::
+
+        mapping = {'true': 1, 'yes': 1, 'false': 0, 'no': 0 }
+        boolean_map = PrefixMap(mapping)
+
+    This example defines a Boolean trait that accepts any prefix of 'true',
+    'yes', 'false', or 'no', and maps them to 1 or 0.
+
+    Parameters
+    ----------
+    map : dict
+        A dictionary whose keys are strings that are valid values for the
+        trait attribute, and whose corresponding values are the values for
+        the shadow trait attribute.
+    default_value : object, optional
+        The default value for the trait. If given, this should be either a key
+        from the mapping or a unique prefix of a key from the mapping. If not
+        given, the first key from the mapping (in normal dictionary iteration
+        order) will be used as the default.
+
+    Attributes
+    ----------
+    map : dict
+        A dictionary whose keys are strings that are valid values for the
+        trait attribute, and whose corresponding values are the values for
+        the shadow trait attribute.
+    """
+    is_mapped = True
+
+    def __init__(self, map, **metadata):
+        self.map = map
+        self._map = {}
+        for key in map.keys():
+            self._map[key] = key
+
+        try:
+            default_value = metadata.pop("default_value")
+        except KeyError:
+            default_value = next(iter(self.map))
+        else:
+            default_value = self.value_for(default_value)
+
+        super().__init__(default_value, **metadata)
+
+    def value_for(self, value):
+        if not isinstance(value, str):
+            raise TraitError(
+                "Value must be {}, but a value {!r} was specified.".format(
+                    self.info(), value)
+            )
+
+        if value in self._map:
+            return self._map[value]
+
+        matches = [key for key in self.map if key.startswith(value)]
+        if len(matches) == 1:
+            self._map[value] = match = matches[0]
+            return match
+
+        raise TraitError(
+            "Value must be {}, but a value {!r} was specified.".format(
+                self.info(), value)
+        )
+
+    def mapped_value(self, value):
+        """ Get the mapped value for a value. """
+        return self.map[value]
+
+    def post_setattr(self, object, name, value):
+        setattr(object, name + "_", self.mapped_value(value))
+
+    def info(self):
+        keys = sorted(repr(x) for x in self.map.keys())
+        return " or ".join(keys) + " (or any unique prefix)"
+
+    def get_editor(self, trait):
+        from traitsui.api import EnumEditor
+
+        return EnumEditor(values=self, cols=trait.cols or 3)
+
+
+class BaseClass(TraitType):
+    """ A base trait type for trait types which have an associated class.
+
+    Traits sometimes need to be able to access classes which have not
+    yet been defined, or which are from a module that we want to defer
+    importing from.  To support this, classes can be determined
+    dynamically by specifying a string name for the class (e.g.
+    ``'package1.package2.module.class'``).  This base class provides the
+    machinery for this sort of deferred access to classes.
+
+    Any subclass must define instances with 'klass' and 'module' attributes
+    that contain the string name of the class (or actual class object) and
+    the module name that contained the original trait definition (used for
+    resolving local class names (e.g. 'LocalClass')).
+
+    This is an abstract class that only provides helper methods used to
+    resolve the class name into an actual class object.
+
+    Attributes
+    ----------
+    klass : type or str
+        The class object or a string that refers to it.
+    module : str
+        The name of the module that contains the class.
+    """
+
+    def resolve_class(self, object, name, value):
+        """ Resolve the class object as part of validation.
+
+        This is called when the ``klass`` attribute is a string and sets the
+        ``klass`` attribute to the actual klass object as a side-effect.  If
+        the class cannot be resolved, it will call validate_failed().
+        """
+        klass = self.validate_class(self.find_class(self.klass))
+        if klass is None:
+            self.validate_failed(object, name, value)
+
+        self.klass = klass
+
+    def validate_class(self, klass):
+        """ Validate a class object. """
+        return klass
+
+    def find_class(self, klass):
+        """ Given a string describing a class, get the class object.
+        """
+        module = self.module
+        col = klass.rfind(".")
+        if col >= 0:
+            module = klass[:col]
+            klass = klass[col + 1:]
+
+        theClass = getattr(sys.modules.get(module), klass, None)
+        if (theClass is None) and (col >= 0):
+            try:
+                mod = import_module(module)
+                theClass = getattr(mod, klass, None)
+            except Exception:
+                pass
+
+        return theClass
+
+    def validate_failed(self, object, name, value):
+        """ Raise a TraitError if the class could not be resolved. """
+        self.error(object, name, value)
+
+
+class BaseInstance(BaseClass):
+    """ A trait type whose value is an instance of a class or its subclasses.
+
+    The default value is **None** if *klass* is an instance or if it is a
+    class and *args* and *kw* are not specified. Otherwise, the default value
+    is the instance obtained by calling ``klass(*args, **kw)``. Note that the
+    constructor call is performed each time a default value is assigned, so
+    each default value assigned is a unique instance.
+
+    Parameters
+    ----------
+    klass : class, str or instance
+        The object that forms the basis for the trait; if it is an
+        instance, then trait values must be instances of the same class or
+        a subclass. This object is not the default value, even if it is an
+        instance.  If the provided value is a string, it is expected to be
+        a reference to a class that will be resolved at run-time.
+    factory : callable
+        A callable, typically a class, that when called with *args* and
+        *kw*, returns the default value for the trait. If not specified,
+        or *None*, *klass* is used as the factory.
+    args : tuple
+        Positional arguments for generating the default value.
+    kw : dictionary
+        Keyword arguments for generating the default value.
+    allow_none : bool
+        Indicates whether None is allowed as a value.
+    adapt : str
+        A string specifying how adaptation should be applied. The possible
+        values are:
+
+        - 'no': Adaptation is not allowed.
+        - 'yes': Adaptation is allowed. If adaptation fails, an
+          exception should be raised.
+        - 'default': Adaptation is allowed. If adaptation fails, the
+          default value for the trait should be used.
+
+    Attributes
+    ----------
+    factory : callable
+        A callable, typically a class, that when called with *args* and
+        *kw*, returns the default value for the trait. If not specified,
+        or *None*, *klass* is used as the factory.
+    args : tuple
+        Positional arguments for generating the default value.
+    kw : dictionary
+        Keyword arguments for generating the default value.
+    allow_none : bool
+        Indicates whether None is allowed as a value.
+    adapt : str
+        A string specifying how adaptation should be applied. The possible
+        values are:
+
+        - 'no': Adaptation is not allowed.
+        - 'yes': Adaptation is allowed. If adaptation fails, an
+          exception should be raised.
+        - 'default': Adaptation is allowed. If adaptation fails, the
+          default value for the trait should be used.
+    """
+
+    #: Default adaptation behavior.
+    adapt_default = "no"
+
+    def __init__(
+        self,
+        klass=None,
+        factory=None,
+        args=None,
+        kw=None,
+        allow_none=True,
+        adapt=None,
+        module=None,
+        **metadata
+    ):
+        if klass is None:
+            raise TraitError(
+                "A %s trait must have a class specified."
+                % self.__class__.__name__
+            )
+
+        metadata.setdefault("copy", "deep")
+        metadata.setdefault("instance_handler", "_instance_changed_handler")
+
+        adapt = adapt or self.adapt_default
+        if adapt not in AdaptMap:
+            raise TraitError("'adapt' must be 'yes', 'no' or 'default'.")
+
+        if isinstance(factory, tuple):
+            if args is None:
+                args, factory = factory, klass
+            elif isinstance(args, dict):
+                factory, args, kw = klass, factory, args
+
+        elif (kw is None) and isinstance(factory, dict):
+            kw, factory = factory, klass
+
+        elif ((args is not None) or (kw is not None)) and (factory is None):
+            factory = klass
+
+        self._allow_none = allow_none
+        self.adapt = AdaptMap[adapt]
+        self.module = module or get_module_name()
+
+        if isinstance(klass, str):
+            self.klass = klass
+        else:
+            if not isinstance(klass, type):
+                klass = klass.__class__
+
+            self.klass = klass
+            self.init_fast_validate()
+
+        value = factory
+        if factory is not None:
+            if args is None:
+                args = ()
+
+            if kw is None:
+                if isinstance(args, dict):
+                    kw = args
+                    args = ()
+                else:
+                    kw = {}
+            elif not isinstance(kw, dict):
+                raise TraitError("The 'kw' argument must be a dictionary.")
+
+            if (not callable(factory)) and (
+                not isinstance(factory, str)
+            ):
+                if (len(args) > 0) or (len(kw) > 0):
+                    raise TraitError("'factory' must be callable")
+            else:
+                value = _InstanceArgs(factory, args, kw)
+
+        self.default_value = value
+
+        super(BaseInstance, self).__init__(value, **metadata)
+
+    def validate(self, object, name, value):
+        """ Validates that the value is a valid object instance.
+        """
+        from traits.adaptation.api import adapt
+
+        if value is None:
+            if self._allow_none:
+                return value
+
+            self.validate_failed(object, name, value)
+
+        if isinstance(self.klass, str):
+            self.resolve_class(object, name, value)
+
+        # Adaptation mode 0: do a simple isinstance check.
+        if self.adapt == 0:
+            if isinstance(value, self.klass):
+                return value
+            else:
+                self.validate_failed(object, name, value)
+
+        # Try adaptation; return adapted value on success.
+        result = adapt(value, self.klass, None)
+        if result is not None:
+            return result
+
+        # Adaptation failed. Move on to an isinstance check.
+        if isinstance(value, self.klass):
+            return value
+
+        # Adaptation and isinstance both failed. In mode 1, fail.
+        # Otherwise, return the default.
+        if self.adapt == 1:
+            self.validate_failed(object, name, value)
+        else:
+            result = self.default_value
+            if isinstance(result, _InstanceArgs):
+                return result[0](*result[1], **result[2])
+            else:
+                return result
+
+    def info(self):
+        """ Returns a description of the trait.
+        """
+        klass = self.klass
+        if not isinstance(klass, str):
+            klass = klass.__name__
+
+        if self.adapt == 0:
+            result = class_of(klass)
+        else:
+            result = (
+                "an implementor of, or can be adapted to implement, %s" % klass
+            )
+
+        if self._allow_none:
+            return result + " or None"
+
+        return result
+
+    def get_default_value(self):
+        """ Returns a tuple of the form: ( default_value_type, default_value )
+            which describes the default value for this trait.
+        """
+        dv = self.default_value
+        dvt = self.default_value_type
+        if dvt < 0:
+            if not isinstance(dv, _InstanceArgs):
+                return super(BaseInstance, self).get_default_value()
+
+            self.default_value_type = dvt = DefaultValue.callable_and_args
+            self.default_value = dv = (
+                self.create_default_value,
+                dv.args,
+                dv.kw,
+            )
+
+        return (dvt, dv)
+
+    def create_editor(self):
+        """ Returns the default traits UI editor for this type of trait.
+        """
+        from traitsui.api import InstanceEditor
+
+        return InstanceEditor(
+            label=self.label or "",
+            view=self.view or "",
+            kind=self.kind or "live",
+        )
+
+    # -- Private Methods ------------------------------------------------------
+
+    def create_default_value(self, *args, **kw):
+        klass = args[0]
+        if isinstance(klass, str):
+            klass = self.validate_class(self.find_class(klass))
+            if klass is None:
+                raise TraitError("Unable to locate class: " + args[0])
+
+        return klass(*args[1:], **kw)
+
+    #: fixme: Do we still need this method using the new style?...
+    def allow_none(self):
+        self._allow_none = True
+        self.init_fast_validate()
+
+    def init_fast_validate(self):
+        """ Does nothing for the BaseInstance' class. Used by the 'Instance',
+            'Supports' and 'AdaptsTo' classes to set up the C-level fast
+            validator.
+        """
+        pass
+
+    def resolve_class(self, object, name, value):
+        super(BaseInstance, self).resolve_class(object, name, value)
+
+        # fixme: The following is quite ugly, because it wants to try and fix
+        # the trait referencing this handler to use the 'fast path' now that
+        # the actual class has been resolved. The problem is finding the trait,
+        # especially in the case of List(Instance('foo')), where the
+        # object.base_trait(...) value is the List trait, not the Instance
+        # trait, so we need to check for this and pull out the List
+        # 'item_trait'. Obviously this does not extend well to other traits
+        # containing nested trait references (Dict?)...
+        self.init_fast_validate()
+        trait = object.base_trait(name)
+        handler = trait.handler
+        if handler is not self:
+            set_validate = getattr(handler, "set_validate", None)
+            if set_validate is not None:
+                # The outer trait is a TraitCompound. Recompute its
+                # fast_validate table now that we have updated ours.
+                # FIXME: there are probably still issues if the TraitCompound
+                # is further nested.
+                set_validate()
+            else:
+                item_trait = getattr(handler, "item_trait", None)
+                if item_trait is not None and item_trait.handler is self:
+                    # The outer trait is a List trait.
+                    trait = item_trait
+                    handler = self
+                else:
+                    return
+        if handler.fast_validate is not None:
+            trait.set_validate(handler.fast_validate)
+
+
+class Instance(BaseInstance):
+    """ A fast-validated trait type whose value is an instance of a class.
+    """
+
+    def init_fast_validate(self):
+        """ Sets up the C-level fast validator. """
+
+        if self.adapt == 0:
+            fast_validate = [ValidateTrait.instance, self.klass]
+            if self._allow_none:
+                fast_validate = [ValidateTrait.instance, None, self.klass]
+            else:
+                fast_validate = [ValidateTrait.instance, self.klass]
+
+            if self.klass in TypeTypes:
+                fast_validate[0] = ValidateTrait.type
+
+            self.fast_validate = tuple(fast_validate)
+        else:
+            self.fast_validate = (
+                ValidateTrait.adapt, self.klass, self.adapt, self._allow_none)
+
+
+class Supports(Instance):
+    """ A trait type whose value is adapted to a specified protocol.
+
+    In other words, the value of the trait directly provide, or can be adapted
+    to, the given protocol (Interface or type).
+
+    The value of the trait after assignment is the possibly adapted value
+    (i.e., it is the original assigned value if that provides the protocol,
+    or is an adapter otherwise).
+
+    The original, unadapted value is stored in a "shadow" attribute with
+    the same name followed by an underscore (e.g., ``foo`` and ``foo_``).
+    """
+
+    adapt_default = "yes"
+
+    def post_setattr(self, object, name, value):
+        """ Performs additional post-assignment processing.
+        """
+        # Save the original, unadapted value in the mapped trait:
+        object.__dict__[name + "_"] = value
+
+    def as_ctrait(self):
+        """ Returns a CTrait corresponding to the trait defined by this class.
+        """
+        return self.modify_ctrait(super(Supports, self).as_ctrait())
+
+    def modify_ctrait(self, ctrait):
+
+        # Tell the C code that the 'post_setattr' method wants the original,
+        # unadapted value passed to 'setattr':
+        ctrait.post_setattr_original_value = True
+        return ctrait
+
+
+class AdaptsTo(Supports):
+    """ A trait type whose value must support a specified protocol.
+
+    In other words, the value of the trait directly provide, or can be adapted
+    to, the given protocol (Interface or type).
+
+    The value of the trait after assignment is the original, unadapted value.
+
+    A possibly adapted value is stored in a "shadow" attribute with
+    the same name followed by an underscore (e.g., ``foo`` and ``foo_``).
+    """
+
+    def modify_ctrait(self, ctrait):
+        # Tell the C code that 'setattr' should store the original, unadapted
+        # value passed to it:
+        ctrait.setattr_original_value = True
+        return ctrait
+
+
+class Type(BaseClass):
+    """ A trait type whose value must be a subclass of a specified class.
+
+    Parameters
+    ----------
+    value : class or None
+        The default value of the trait.
+    klass : class, str or None
+        The class that trait values must be subclasses of.  If None, then
+        the default value is used instead.  If both are None, then the
+        ``object`` type is used.  If it is a string, the first time that
+        the validate method is called, the class will be imported and
+        the value replaced with the class object.
+    allow_none : bool
+        Indicates whether None is allowed as an assignable value. Even if
+        **False**, the default *value* may be **None**.
+    **metadata
+        Trait metadata for the trait.
+
+    Attributes
+    ----------
+    klass : class or str
+        The class that trait values must be subclasses of.  If this is a
+        string, the first time that the validate method is called, the
+        class will be imported and the value replaced with the class object.
+    module : str
+        The name of the module where local class names (ie. class names
+        with no module components) are presumed to be importable from.
+        This is the caller's caller's module, as determined by the
+        ``get_module_method``.
+    """
+
+    def __init__(self, value=None, klass=None, allow_none=True, **metadata):
+        if value is None:
+            if klass is None:
+                klass = object
+
+        elif klass is None:
+            klass = value
+
+        if isinstance(klass, str):
+            self.validate = self.resolve
+
+        elif not isinstance(klass, type):
+            raise TraitError("A Type trait must specify a class.")
+
+        self.klass = klass
+        self._allow_none = allow_none
+        self.module = get_module_name()
+
+        super(Type, self).__init__(value, **metadata)
+
+    def validate(self, object, name, value):
+        """ Validates that the value is a valid object instance.
+        """
+        try:
+            if issubclass(value, self.klass):
+                return value
+        except:
+            if (value is None) and (self._allow_none):
+                return value
+
+        self.error(object, name, value)
+
+    def resolve(self, object, name, value):
+        """ Resolves a class originally specified as a string into an actual
+            class, then resets the trait so that future calls will be handled
+            by the normal validate method.
+        """
+        if isinstance(self.klass, str):
+            self.resolve_class(object, name, value)
+            del self.validate
+
+        return self.validate(object, name, value)
+
+    def info(self):
+        """ Returns a description of the trait.
+        """
+        klass = self.klass
+        if not isinstance(klass, str):
+            klass = klass.__name__
+
+        result = "a subclass of " + klass
+
+        if self._allow_none:
+            return result + " or None"
+
+        return result
+
+    def get_default_value(self):
+        """ Returns a tuple of the form: ( default_value_type, default_value )
+        which describes the default value for this trait.
+        """
+        if not isinstance(self.default_value, str):
+            return super(Type, self).get_default_value()
+
+        return (
+            DefaultValue.callable_and_args,
+            (self.resolve_default_value, (), None),
+        )
+
+    def resolve_default_value(self):
+        """ Resolves a class name into a class so that it can be used to
+            return the class as the default value of the trait.
+        """
+        if isinstance(self.klass, str):
+            try:
+                self.resolve_class(None, None, None)
+                del self.validate
+            except:
+                raise TraitError(
+                    "Could not resolve %s into a valid class" % self.klass
+                )
+
+        return self.klass
+
+
+#: An alias for the Type trait
+Subclass = Type
+
+
+class Event(TraitType):
+    """ A trait type that holds no value but can be set and listened to.
+
+    Event traits are write-only traits.  They do not hold any value, but
+    they can be assigned to, and listeners to the trait will be notified
+    of the assignment.  Since no value is held, trait change functions that
+    ask for the ``old`` value of the trait will be given the Undefined
+    special value.
+
+    Event traits can be given an optional trait type that is used to validate
+    values assigned to the trait.  If the assigned value does not validate,
+    then a TraitError will occur.
+
+    Parameters
+    ----------
+    trait : a trait
+        The type of value that can be assigned to the event.
+    """
+
+    def __init__(self, trait=None, **metadata):
+        metadata["type"] = "event"
+        metadata["transient"] = True
+
+        super(Event, self).__init__(**metadata)
+
+        self.trait = None
+        if trait is not None:
+            self.trait = trait_from(trait)
+            validate = self.trait.get_validate()
+            if validate is not None:
+                self.fast_validate = validate
+
+    def full_info(self, object, name, value):
+        """ Returns a description of the trait.
+        """
+        trait = self.trait
+        if trait is None:
+            return "any value"
+
+        return trait.full_info(object, name, value)
+
+
+class Button(Event):
+    """ An Event trait type whose UI editor is a button.
+
+    Parameters
+    ----------
+    label : str
+        The label for the button.
+    image : pyface.ImageResource
+        An image to display on the button.
+    style : 'button', 'radio', 'toolbar' or 'checkbox'
+        The style of button to display.
+    values_trait : str
+        For a "button" or "toolbar" style, the name of an enum
+        trait whose values will populate a drop-down menu on the button.
+        The selected value will replace the label on the button.
+    orientation : 'horizontal' or 'vertical'
+        The orientation of the label relative to the image.
+    width_padding : integer between 0 and 31
+        Extra padding (in pixels) added to the left and right sides of
+        the button.
+    height_padding : integer between 0 and 31
+        Extra padding (in pixels) added to the top and bottom of the
+        button.
+    view : traitsui View, optional
+        An optional View to display when the button is clicked.
+    **metadata
+        Trait metadata for the trait.
+
+    Attributes
+    ----------
+    label : str
+        The label for the button.
+    image : pyface.ImageResource
+        An image to display on the button.
+    style : 'button', 'radio', 'toolbar' or 'checkbox'
+        The style of button to display.
+    values_trait : str
+        For a "button" or "toolbar" style, the name of an enum
+        trait whose values will populate a drop-down menu on the button.
+        The selected value will replace the label on the button.
+    orientation : 'horizontal' or 'vertical'
+        The orientation of the label relative to the image.
+    width_padding : integer between 0 and 31
+        Extra padding (in pixels) added to the left and right sides of
+        the button.
+    height_padding : integer between 0 and 31
+        Extra padding (in pixels) added to the top and bottom of the
+        button.
+    view : traitsui View, optional
+        An optional View to display when the button is clicked.
+    """
+
+    def __init__(
+        self,
+        label="",
+        image=None,
+        values_trait=None,
+        style="button",
+        orientation="vertical",
+        width_padding=7,
+        height_padding=5,
+        view=None,
+        **metadata
+    ):
+        self.label = label
+        self.values_trait = values_trait
+        self.image = image
+        self.style = style
+        self.orientation = orientation
+        self.width_padding = width_padding
+        self.height_padding = height_padding
+        self.view = view
+        super(Button, self).__init__(**metadata)
+
+    def create_editor(self):
+        from traitsui.api import ButtonEditor
+
+        editor = ButtonEditor(
+            label=self.label,
+            values_trait=self.values_trait,
+            image=self.image,
+            style=self.style,
+            orientation=self.orientation,
+            width_padding=self.width_padding,
+            height_padding=self.height_padding,
+            view=self.view,
+        )
+        return editor
+
+
+class ToolbarButton(Button):
+    """ A Button trait type whose UI editor is a toolbar button.
+
+    This is just a Button trait with different defaults to style it like
+    a toolbar button.
+
+    Parameters
+    ----------
+    label : str
+        The label for the button.
+    image : pyface.ImageResource
+        An image to display on the button.
+    style : 'button', 'radio', 'toolbar' or 'checkbox'
+        The style of button to display.
+    orientation : 'horizontal' or 'vertical'
+        The orientation of the label relative to the image.
+    width_padding : integer between 0 and 31
+        Extra padding (in pixels) added to the left and right sides of
+        the button.
+    height_padding : integer between 0 and 31
+        Extra padding (in pixels) added to the top and bottom of the
+        button.
+    **metadata
+        Trait metadata for the trait.
+
+    Attributes
+    ----------
+    label : str
+        The label for the button.
+    image : pyface.ImageResource
+        An image to display on the button.
+    style : 'button', 'radio', 'toolbar' or 'checkbox'
+        The style of button to display.
+    values_trait : str
+        For a "button" or "toolbar" style, the name of an enum
+        trait whose values will populate a drop-down menu on the button.
+        The selected value will replace the label on the button.
+    orientation : 'horizontal' or 'vertical'
+        The orientation of the label relative to the image.
+    width_padding : integer between 0 and 31
+        Extra padding (in pixels) added to the left and right sides of
+        the button.
+    height_padding : integer between 0 and 31
+        Extra padding (in pixels) added to the top and bottom of the
+        button.
+    view : traitsui View, optional
+        An optional View to display when the button is clicked.
+    """
+
+    def __init__(
+        self,
+        label="",
+        image=None,
+        style="toolbar",
+        orientation="vertical",
+        width_padding=2,
+        height_padding=2,
+        **metadata
+    ):
+        super(ToolbarButton, self).__init__(
+            label,
+            image=image,
+            style=style,
+            orientation=orientation,
+            width_padding=width_padding,
+            height_padding=height_padding,
+            **metadata
+        )
+
+
+class Either(TraitType):
+    """ A trait type whose value can be any of of a specified list of traits.
+
+    Parameters
+    ----------
+    *traits
+        Arguments that define allowable trait values.
+    **metadata
+        Trait metadata for the trait.
+
+    Attributes
+    ----------
+    trait_maker : TraitHandler
+        A TraitHandler generated by _TraitMaker from the arguments.
+    """
+
+    def __init__(self, *traits, **metadata):
+        self.trait_maker = _TraitMaker(
+            metadata.pop("default", None), *traits, **metadata
+        )
+
+    def as_ctrait(self):
+        """ Returns a CTrait corresponding to the trait defined by this class.
+        """
+        return self.trait_maker.as_ctrait()
+
+
+class _NoneTrait(TraitType):
+    """ Defines a trait that only accepts the None value
+
+    This is primarily used for supporting ``Union``.
+    """
+
+    info_text = "None"
+
+    default_value = None
+
+    default_value_type = DefaultValue.constant
+
+    def __init__(self, **metadata):
+        default_value = metadata.pop("default_value", None)
+        if default_value is not None:
+            raise ValueError("Cannot set default value {} "
+                             "for _NoneTrait".format(default_value))
+        super(_NoneTrait, self).__init__(**metadata)
+
+    def validate(self, obj, name, value):
+        if value is None:
+            return value
+
+        self.error(obj, name, value)
+
+
+class Union(TraitType):
+    """ Defines a trait whose value can be any of of a specified list of
+    trait types or list of trait type instances or None
+
+    If the default value is not defined on Union, the default value from the
+    first trait will be used.
+    """
+
+    def __init__(self, *traits, **metadata):
+        self.list_ctrait_instances = []
+
+        if not traits:
+            traits = (_NoneTrait,)
+
+        for trait in traits:
+            if trait is None:
+                trait = _NoneTrait
+            ctrait_instance = trait_cast(trait)
+            if ctrait_instance is None:
+                raise ValueError("Union trait declaration expects a trait "
+                                 "type or an instance of trait type or None,"
+                                 " but got {!r} instead".format(trait))
+
+            self.list_ctrait_instances.append(ctrait_instance)
+
+        # ``Either`` uses 'default' for defining static default values.
+        # Raise if 'default' is found in order to help code migrate to Union
+        if "default" in metadata:
+            raise ValueError(
+                "Union default value should be set via 'default_value', not "
+                "'default'."
+            )
+
+        default_value = None
+        if 'default_value' in metadata:
+            default_value = metadata.pop("default_value")
+        elif self.list_ctrait_instances:
+            default_value = self.list_ctrait_instances[0].default
+
+        self.default_value_type = _infer_default_value_type(default_value)
+        super().__init__(default_value, **metadata)
+
+    def validate(self, obj, name, value):
+        """ Return the value by the first trait in the list that can
+        validate the assigned value, raise an error if none of them can.
+        """
+        for trait_type_instance in self.list_ctrait_instances:
+            try:
+                return trait_type_instance.validate(obj, name, value)
+            except TraitError:
+                pass
+
+        self.error(obj, name, value)
+
+    def info(self):
+        return " or ".join([ctrait.info() for ctrait in
+                            self.list_ctrait_instances])
+
+    def inner_traits(self):
+        return tuple(self.list_ctrait_instances)
+
+    def get_editor(self, trait):
+        from traitsui.api import TextEditor, CompoundEditor
+
+        the_editors = [x.get_editor() for x in self.list_ctrait_instances]
+        text_editor = TextEditor()
+        count = 0
+        editors = []
+        for editor in the_editors:
+            if isinstance(text_editor, editor.__class__):
+                count += 1
+                if count > 1:
+                    continue
+            editors.append(editor)
+
+        return CompoundEditor(editors=editors)
+
+
+# -------------------------------------------------------------------------------
+#  'Symbol' trait:
+# -------------------------------------------------------------------------------
+class Symbol(TraitType):
+    """ A property trait type that refers to a Python object by name.
+
+    The value set to the trait must be a value of the form
+    ``'[package.package...package.]module[:symbol[([arg1,...,argn])]]'``
+    which is imported and evaluated to get underlying value.
+
+    The value returned by the trait is the actual object that this string
+    refers to.  The value is cached, so any calls are only evaluated once.
+    """
+
+    #: A description of the type of value this trait accepts:
+    info_text = (
+        "an object or a string of the form "
+        "'[package.package...package.]module[:symbol[([arg1,...,argn])]]' "
+        "specifying where to locate the object"
+    )
+
+    def get(self, object, name):
+        value = object.__dict__.get(name, Undefined)
+        if value is Undefined:
+            cache = TraitsCache + name
+            ref = object.__dict__.get(cache)
+            if ref is None:
+                object.__dict__[cache] = ref = object.trait(
+                    name
+                ).default_value_for(object, name)
+
+            if isinstance(ref, str):
+                object.__dict__[name] = value = self._resolve(ref)
+
+        return value
+
+    def set(self, object, name, value):
+        dict = object.__dict__
+        old = dict.get(name, Undefined)
+        if isinstance(value, str):
+            dict.pop(name, None)
+            dict[TraitsCache + name] = value
+            object.trait_property_changed(name, old)
+        else:
+            dict[name] = value
+            object.trait_property_changed(name, old, value)
+
+    def _resolve(self, ref):
+        try:
+            elements = ref.split("(", 1)
+            symbol = import_symbol(elements[0])
+            if len(elements) == 1:
+                return symbol
+
+            args = eval("(" + elements[1])
+            if not isinstance(args, tuple):
+                args = (args,)
+
+            return symbol(*args)
+        except Exception:
+            raise TraitError(
+                "Could not resolve '%s' into a valid symbol." % ref
+            )
+
+
+class UUID(TraitType):
+    """ A read-only trait type whose value is a globally unique UUID (type 4).
+
+    Parameters
+    ----------
+    can_init : bool
+        Whether the value can be set during object instantiation.  Otherwise
+        the UUID is generated automatically.
+
+    Example
+    -------
+
+    Passing `can_init=True` allows the UUID value to be set during
+    object instantiation, e.g.::
+
+        class A(HasTraits):
+            id = UUID
+
+        class B(HasTraits):
+            id = UUID(can_init=True)
+
+        # TraitError!
+        A(id=uuid.uuid4())
+
+        # Okay!
+        B(id=uuid.uuid4())
+
+    Note however that in both cases, the UUID trait is set automatically
+    to a `uuid.UUID` instance (assuming none is provided during initialization
+    in the latter case).
+    """
+
+    #: A description of the type of value this trait accepts:
+    info_text = "a read-only UUID"
+
+    def __init__(self, can_init=False, **metadata):
+        super(UUID, self).__init__(None, **metadata)
+        self.can_init = can_init
+
+    def validate(self, object, name, value):
+        """ Raises an error, since no values can be assigned to the trait.
+        """
+        if not self.can_init:
+            raise TraitError(
+                "The '%s' trait of %s instance is a read-only "
+                "UUID." % (name, class_of(object))
+            )
+
+        if object.traits_inited():
+            msg = ("Initializable UUID trait is read-only "
+                   "after initialization")
+            raise TraitError(msg)
+
+        if isinstance(value, uuid.UUID):
+            return value
+
+        try:
+            # Construct the UUID from a string
+            return uuid.UUID(value)
+        except ValueError:
+            msg = ("The '{}' trait of '{}' expects an RFC 4122-compatible "
+                   "UUID value, but '{}' was given")
+            raise TraitError(msg.format(name, type(object).__name__, value))
+
+    def get_default_value(self):
+        """ Return a Traits default value tuple for the trait.
+
+        This uses the _create_uuid method to generate the defualt value.
+        """
+        return (
+            DefaultValue.callable_and_args,
+            (self._create_uuid, (), None),
+        )
+
+    # -- Private Methods ---------------------------------------------------
+
+    def _create_uuid(self):
+        return uuid.uuid4()
+
+
+class WeakRef(Instance):
+    """ A trait type holding a weak reference to an instance of a class.
+
+    Only a weak reference is maintained to any object assigned to a WeakRef
+    trait. If no other references exist to the assigned value, the value
+    may be garbage collected, in which case the value of the trait becomes
+    None. In all other cases, the value returned by the trait is the
+    original object.
+
+    Parameters
+    ----------
+    klass : class, str or instance
+        The object that forms the basis for the trait. If *klass* is
+        omitted, then values must be an instance of HasTraits.  If a string,
+        the value will be resolved to a class object at runtime.
+    allow_none : boolean
+        Indicates whether None can be _assigned_.  The trait attribute may
+        give a None value if the object referred to has been garbage collected
+        even if allow_none is False.
+    adapt : str
+        How to use the adaptation infrastructure when setting the value.
+    """
+
+    def __init__(
+        self,
+        klass="traits.has_traits.HasTraits",
+        allow_none=False,
+        adapt="yes",
+        **metadata
+    ):
+        metadata.setdefault("copy", "ref")
+
+        super(WeakRef, self).__init__(
+            klass,
+            allow_none=allow_none,
+            adapt=adapt,
+            module=get_module_name(),
+            **metadata
+        )
+
+    def get(self, object, name):
+        value = getattr(object, name + "_", None)
+        if value is not None:
+            return value.value()
+
+        return None
+
+    def set(self, object, name, value):
+        old = self.get(object, name)
+
+        if value is None:
+            object.__dict__[name + "_"] = None
+        else:
+            object.__dict__[name + "_"] = HandleWeakRef(object, name, value)
+
+        if value is not old:
+            object.trait_property_changed(name, old, value)
+
+    def resolve_class(self, object, name, value):
+        # fixme: We have to override this method to prevent the 'fast validate'
+        # from being set up, since the trait using this is a 'property' style
+        # trait which is not currently compatible with the 'fast_validate'
+        # style (causes internal Python SystemError messages).
+        klass = self.find_class(self.klass)
+        if klass is None:
+            self.validate_failed(object, name, value)
+
+        self.klass = klass
+
+
+#: A trait type for datetime.date instances.
+Date = BaseInstance(datetime.date, editor=date_editor)
+
+
+#: A trait type for datetime.datetime instances.
+Datetime = BaseInstance(datetime.datetime, editor=datetime_editor)
+
+
+#: A trait type for datetime.time instances.
+Time = BaseInstance(datetime.time, editor=time_editor)
+
+
+# Predefined, reusable trait instances
+
+# Everything from this point onwards is deprecated, and has a simple
+# drop-in replacement.
+
+#: A trait whose value must support a specified protocol. This is
+#: an alias for :class:`Supports`. Use ``Supports`` instead.
+AdaptedTo = Supports
+
+#: A trait whose value must be a (Unicode) string. This is an alias for
+#: :class:`BaseStr`. Use ``BaseStr`` instead.
+BaseUnicode = BaseStr
+
+#: A trait whose value must be a (Unicode) string, using a C-level
+#: fast validator. This is an alias for :class:`Str`. Use ``Str`` instead.
+Unicode = Str
+
+#: A trait whose value must be a (Unicode) string and which supports
+#: coercions of non-string values to string. This is
+#: an alias for :class:`BaseCStr`. Use ``BaseCStr`` instead.
+BaseCUnicode = BaseCStr
+
+#: A trait whose value must be a (Unicode) string and which supports
+#: coercions of non-string values to string, using a C-level fast validator.
+#: This is an alias for :class:`CStr`. Use ``CStr`` instead.
+CUnicode = CStr
+
+#: A trait whose value must be an integer. This is an alias for
+#: :class:`BaseInt`. Use ``BaseInt`` instead.
+BaseLong = BaseInt
+
+#: A trait whose value must be an integer, using a C-level fast validator.
+#: This is an alias for :class:`Int`. Use ``Int`` instead.
+Long = Int
+
+#: A trait whose value must be an integer and which supports coercions
+#: of non-integer values to integer. This is an alias for
+#: :class:`BaseCInt`. Use ``BaseCInt`` instead.
+BaseCLong = BaseCInt
+
+#: A trait whose value must be an integer and which supports coercions
+#: of non-integer values to integer, using a C-level fast validator.
+#: This is an alias for :class:`CInt`. Use ``CInt`` instead.
+CLong = CInt
+
+#: Synonym for Bool; default value is ``False``. This trait type is
+#: deprecated. Use ``Bool(False)`` or ``Bool()`` instead.
+false = Bool
+
+#: Boolean values only; default value is ``True``. This trait type is
+#: deprecated. Use ``Bool(True)`` instead.
+true = Bool(True)
+
+#: Allows any value to be assigned; no type-checking is performed.
+#: Default value is ``Undefined``. This trait type is deprecated. Use
+#: ``Any(Undefined)`` instead.
+undefined = Any(Undefined)
+
+# -- List Traits --------------------------------------------------------------
+
+#: List of integer values; default value is ``[]``. This trait type is
+#: deprecated. Use ``List(Int)`` instead.
+ListInt = List(int)
+
+#: List of float values; default value is ``[]``. This trait type is
+#: deprecated. Use ``List(Float)`` instead.
+ListFloat = List(float)
+
+#: List of string values; default value is ``[]``. This trait type is
+#: deprecated. Use ``List(Str)`` instead.
+ListStr = List(str)
+
+#: List of string values; default value is ``[]``. This trait type is
+#: deprecated. Use ``List(Str)`` instead.
+ListUnicode = List(str)
+
+#: List of complex values; default value is ``[]``. This trait type is
+#: deprecated. Use ``List(Complex)`` instead.
+ListComplex = List(complex)
+
+#: List of Boolean values; default value is ``[]``. This trait type is
+#: deprecated. Use ``List(Bool)`` instead.
+ListBool = List(bool)
+
+#: List of function values; default value is ``[]``. This trait type is
+#: deprecated. Use ``List(Instance(types.FunctionType, allow_none=False))``
+#: instead.
+ListFunction = List(FunctionType)
+
+#: List of method values; default value is ``[]``. This trait type is
+#: deprecated. Use ``List(Instance(types.MethodType, allow_none=False))``
+#: instead.
+ListMethod = List(MethodType)
+
+#: List of container type values; default value is ``[]``. This trait type is
+#: deprecated. Use ``List(This(allow_none=False))`` instead.
+ListThis = List(This(allow_none=False))
+
+# -- Dictionary Traits --------------------------------------------------------
+
+#: Only a dictionary with strings as keys can be assigned; only string keys
+#: can be inserted. The default value is {}. This trait type is deprecated. Use
+#: ``Dict(Str, Any)`` instead.
+DictStrAny = Dict(str, Any)
+
+#: Only a dictionary mapping strings to strings can be assigned; only string
+#: keys with string values can be inserted. The default value is {}. This trait
+#: type is deprecated. Use ``Dict(Str, Str)`` instead.
+DictStrStr = Dict(str, str)
+
+#: Only a dictionary mapping strings to integers can be assigned; only string
+#: keys with integer values can be inserted. The default value is {}. This
+#: trait type is deprecated. Use ``Dict(Str, Int)`` instead.
+DictStrInt = Dict(str, int)
+
+#: Only a dictionary mapping strings to floats can be assigned; only string
+#: keys with float values can be inserted. The default value is {}. This trait
+#: type is deprecated. Use ``Dict(Str, Float)`` instead.
+DictStrFloat = Dict(str, float)
+
+#: Only a dictionary mapping strings to booleans can be assigned; only string
+#: keys with boolean values can be inserted. The default value is {}. This
+#: trait type is deprecated. Use ``Dict(Str, Bool)`` instead.
+DictStrBool = Dict(str, bool)
+
+#: Only a dictionary mapping strings to lists can be assigned; only string keys
+#: with list values can be inserted. The default value is {}. This trait type
+#: is deprecated. Use ``Dict(Str, List)`` instead.
+DictStrList = Dict(str, list)
+
+ +
+
+
+
+
+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/5.0/_modules/traits/traits.html b/5.0/_modules/traits/traits.html new file mode 100644 index 000000000..4b1a7ea95 --- /dev/null +++ b/5.0/_modules/traits/traits.html @@ -0,0 +1,833 @@ + + + + + + + traits.traits — Apptools Documentation + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +

Source code for traits.traits

+# (C) Copyright 2005-2020 Enthought, Inc., Austin, TX
+# All rights reserved.
+#
+# This software is provided without warranty under the terms of the BSD
+# license included in LICENSE.txt and may be redistributed only under
+# the conditions described in the aforementioned license. The license
+# is also available online at http://www.enthought.com/licenses/BSD.txt
+#
+# Thanks for using Enthought open source!
+
+"""
+Defines the 'core' traits for the Traits package. A trait is a type definition
+that can be used for normal Python object attributes, giving the attributes
+some additional characteristics:
+
+Initialization:
+    Traits have predefined values that do not need to be explicitly
+    initialized in the class constructor or elsewhere.
+Validation:
+    Trait attributes have flexible, type-checked values.
+Delegation:
+    Trait attributes' values can be delegated to other objects.
+Notification:
+    Trait attributes can automatically notify interested parties when
+    their values change.
+Visualization:
+    Trait attributes can automatically construct (automatic or
+    programmer-defined) user interfaces that allow their values to be
+    edited or displayed)
+
+.. note:: 'trait' is a synonym for 'property', but is used instead of the
+    word 'property' to differentiate it from the Python language 'property'
+    feature.
+"""
+
+from types import FunctionType, MethodType
+import warnings
+
+from .constants import (
+    ComparisonMode,
+    DefaultValue,
+    TraitKind,
+)
+from .ctrait import CTrait
+from .trait_errors import TraitError
+from .trait_base import (
+    SequenceTypes,
+    TypeTypes,
+    add_article,
+)
+from .trait_converters import (
+    trait_cast,
+    check_trait as try_trait_cast,
+)
+
+from .trait_handler import TraitHandler
+from .trait_type import (
+    _infer_default_value_type,
+    _read_only,
+    _write_only,
+)
+from .trait_handlers import (
+    TraitInstance,
+    TraitFunction,
+    TraitCoerceType,
+    TraitCastType,
+    TraitEnum,
+    TraitCompound,
+    TraitMap,
+    _undefined_get,
+    _undefined_set,
+)
+from .trait_factory import (
+    TraitFactory,
+)
+from .util.deprecated import deprecated
+
+# Constants
+
+NoneType = type(None)  # Python 3's types does not include NoneType
+
+ConstantTypes = (NoneType, int, float, complex, str)
+
+PythonTypes = (
+    str,
+    int,
+    float,
+    complex,
+    list,
+    tuple,
+    dict,
+    FunctionType,
+    MethodType,
+    type,
+    NoneType,
+)
+
+CallableTypes = (FunctionType, MethodType)
+
+TraitTypes = (TraitHandler, CTrait)
+
+DefaultValues = {
+    str: "",
+    int: 0,
+    float: 0.0,
+    complex: 0j,
+    list: [],
+    tuple: (),
+    dict: {},
+    bool: False,
+}
+
+
+# This function is needed when unpickling historical pickles (pickles
+# created on versions of Traits prior to 6.0). It can be removed when
+# there's no longer any need to support pickles generated on older
+# versions of Traits.
+
+def __newobj__(cls, *args):
+    """ Unpickles new-style objects.
+    """
+    return cls.__new__(cls, *args)
+
+
+# --- 'instance' traits -------------------------------------------------------
+
+
+class _InstanceArgs(object):
+    def __init__(self, factory, args, kw):
+        self.args = (factory,) + args
+        self.kw = kw
+
+
+# --- 'creates a run-time default value' --------------------------------------
+
+
+class Default(object):
+    """ Generates a value the first time it is accessed.
+
+    A Default object can be used anywhere a default trait value would normally
+    be specified, to generate a default value dynamically.
+    """
+
+    def __init__(self, func=None, args=(), kw=None):
+        self.default_value = (func, args, kw)
+
+
+def Trait(*value_type, **metadata):
+    """ Creates a trait definition.
+
+    This function accepts a variety of forms of parameter lists:
+
+    +-------------------+---------------+-------------------------------------+
+    | Format            | Example       | Description                         |
+    +===================+===============+=====================================+
+    | Trait(*default*)  | Trait(150.0)  | The type of the trait is inferred   |
+    |                   |               | from the type of the default value, |
+    |                   |               | which must be in *ConstantTypes*.   |
+    +-------------------+---------------+-------------------------------------+
+    | Trait(*default*,  | Trait(None,   | The trait accepts any of the        |
+    | *other1*,         | 0, 1, 2,      | enumerated values, with the first   |
+    | *other2*, ...)    | 'many')       | value being the default value. The  |
+    |                   |               | values must be of types in          |
+    |                   |               | *ConstantTypes*, but they need not  |
+    |                   |               | be of the same type. The *default*  |
+    |                   |               | value is not valid for assignment   |
+    |                   |               | unless it is repeated later in the  |
+    |                   |               | list.                               |
+    +-------------------+---------------+-------------------------------------+
+    | Trait([*default*, | Trait([None,  | Similar to the previous format, but |
+    | *other1*,         | 0, 1, 2,      | takes an explicit list or a list    |
+    | *other2*, ...])   | 'many'])      | variable.                           |
+    +-------------------+---------------+-------------------------------------+
+    | Trait(*type*)     | Trait(Int)    | The *type* parameter must be a name |
+    |                   |               | of a Python type (see               |
+    |                   |               | *PythonTypes*). Assigned values     |
+    |                   |               | must be of exactly the specified    |
+    |                   |               | type; no casting or coercion is     |
+    |                   |               | performed. The default value is the |
+    |                   |               | appropriate form of zero, False,    |
+    |                   |               | or emtpy string, set or sequence.   |
+    +-------------------+---------------+-------------------------------------+
+    | Trait(*class*)    |::             | Values must be instances of *class* |
+    |                   |               | or of a subclass of *class*. The    |
+    |                   | class MyClass:| default value is None, but None     |
+    |                   |    pass       | cannot be assigned as a value.      |
+    |                   | foo = Trait(  |                                     |
+    |                   | MyClass)      |                                     |
+    +-------------------+---------------+-------------------------------------+
+    | Trait(None,       |::             | Similar to the previous format, but |
+    | *class*)          |               | None *can* be assigned as a value.  |
+    |                   | class MyClass:|                                     |
+    |                   |   pass        |                                     |
+    |                   | foo = Trait(  |                                     |
+    |                   | None, MyClass)|                                     |
+    +-------------------+---------------+-------------------------------------+
+    | Trait(*instance*) |::             | Values must be instances of the     |
+    |                   |               | same class as *instance*, or of a   |
+    |                   | class MyClass:| subclass of that class. The         |
+    |                   |    pass       | specified instance is the default   |
+    |                   | i = MyClass() | value.                              |
+    |                   | foo =         |                                     |
+    |                   |   Trait(i)    |                                     |
+    +-------------------+---------------+-------------------------------------+
+    | Trait(*handler*)  | Trait(        | Assignment to this trait is         |
+    |                   | TraitEnum )   | validated by an object derived from |
+    |                   |               | **traits.TraitHandler**.            |
+    +-------------------+---------------+-------------------------------------+
+    | Trait(*default*,  | Trait(0.0, 0.0| This is the most general form of    |
+    | { *type* |        | 'stuff',      | the function. The notation:         |
+    | *constant* |      | TupleType)    | ``{...|...|...}+`` means a list of  |
+    | *dict* | *class* ||               | one or more of any of the items     |
+    | *function* |      |               | listed between the braces. Thus, the|
+    | *handler* |       |               | most general form of the function   |
+    | *trait* }+ )      |               | consists of a default value,        |
+    |                   |               | followed by one or more of several  |
+    |                   |               | possible items. A trait defined by  |
+    |                   |               | multiple items is called a          |
+    |                   |               | "compound" trait.                   |
+    +-------------------+---------------+-------------------------------------+
+
+    All forms of the Trait function accept both predefined and arbitrary
+    keyword arguments. The value of each keyword argument becomes bound to the
+    resulting trait object as the value of an attribute having the same name
+    as the keyword. This feature lets you associate metadata with a trait.
+
+    The following predefined keywords are accepted:
+
+    desc : str
+        Describes the intended meaning of the trait. It is used in
+        exception messages and fly-over help in user interfaces.
+    label : str
+        Provides a human-readable name for the trait. It is used to label user
+        interface editors for traits.
+    editor : traits.api.Editor
+        Instance of a subclass Editor object to use when creating a user
+        interface editor for the trait. See the "Traits UI User Guide" for
+        more information on trait editors.
+    comparison_mode : int
+        Indicates when trait change notifications should be generated based
+        upon the result of comparing the old and new values of a trait
+        assignment. Possible values come from the ``ComparisonMode`` enum:
+
+        * 0 (none): The values are not compared and a trait change
+          notification is generated on each assignment.
+        * 1 (identity): A trait change notification is
+          generated if the old and new values are not the same object.
+        * 2 (equality): A trait change notification is generated if the
+          old and new values are not equal using Python's standard equality
+          testing. This is the default.
+
+    """
+    return _TraitMaker(*value_type, **metadata).as_ctrait()
+
+
+class _TraitMaker(object):
+
+    # Ctrait type map for special trait types:
+    type_map = {"event": TraitKind.event, "constant": TraitKind.constant}
+
+    def __init__(self, *value_type, **metadata):
+        metadata.setdefault("type", "trait")
+        self.define(*value_type, **metadata)
+
+    def define(self, *value_type, **metadata):
+        """ Define the trait. """
+        default_value_type = DefaultValue.unspecified
+        default_value = handler = clone = None
+
+        if len(value_type) > 0:
+            default_value = value_type[0]
+            value_type = value_type[1:]
+
+            if (len(value_type) == 0) and (
+                type(default_value) in SequenceTypes
+            ):
+                default_value, value_type = default_value[0], default_value
+
+            if len(value_type) == 0:
+                default_value = try_trait_cast(default_value)
+
+                if default_value in PythonTypes:
+                    handler = TraitCoerceType(default_value)
+                    default_value = DefaultValues.get(default_value)
+
+                elif isinstance(default_value, CTrait):
+                    clone = default_value
+                    default_value_type, default_value = clone.default_value()
+                    metadata["type"] = clone.type
+
+                elif isinstance(default_value, TraitHandler):
+                    handler = default_value
+                    default_value = None
+
+                else:
+                    typeValue = type(default_value)
+                    if typeValue in TypeTypes:
+                        handler = TraitCastType(typeValue)
+
+                    else:
+                        metadata.setdefault(
+                            "instance_handler", "_instance_changed_handler"
+                        )
+                        handler = TraitInstance(default_value)
+                        if default_value is handler.aClass:
+                            default_value = DefaultValues.get(default_value)
+            else:
+                enum = []
+                other = []
+                map = {}
+                self.do_list(value_type, enum, map, other)
+
+                if ((len(enum) == 1) and (enum[0] is None)) and (
+                    (len(other) == 1) and isinstance(other[0], TraitInstance)
+                ):
+                    enum = []
+                    other[0].allow_none()
+                    metadata.setdefault(
+                        "instance_handler", "_instance_changed_handler"
+                    )
+                if len(enum) > 0:
+                    if ((len(map) + len(other)) == 0) and (
+                        default_value not in enum
+                    ):
+                        enum.insert(0, default_value)
+
+                    other.append(TraitEnum(enum))
+
+                if len(map) > 0:
+                    other.append(TraitMap(map))
+
+                if len(other) == 0:
+                    handler = TraitHandler()
+
+                elif len(other) == 1:
+                    handler = other[0]
+                    if isinstance(handler, CTrait):
+                        clone, handler = handler, None
+                        metadata["type"] = clone.type
+
+                    elif isinstance(handler, TraitInstance):
+                        metadata.setdefault(
+                            "instance_handler", "_instance_changed_handler"
+                        )
+
+                        if default_value is None:
+                            handler.allow_none()
+
+                        elif isinstance(default_value, _InstanceArgs):
+                            default_value_type = (
+                                DefaultValue.callable_and_args
+                            )
+                            default_value = (
+                                handler.create_default_value,
+                                default_value.args,
+                                default_value.kw,
+                            )
+
+                        elif (len(enum) == 0) and (len(map) == 0):
+                            aClass = handler.aClass
+                            typeValue = type(default_value)
+
+                            if typeValue is dict:
+                                default_value_type = (
+                                    DefaultValue.callable_and_args
+                                )
+                                default_value = (aClass, (), default_value)
+                            elif not isinstance(default_value, aClass):
+                                if typeValue is not tuple:
+                                    default_value = (default_value,)
+                                default_value_type = (
+                                    DefaultValue.callable_and_args
+                                )
+                                default_value = (aClass, default_value, None)
+                else:
+                    for i, item in enumerate(other):
+                        if isinstance(item, CTrait):
+                            if item.type != "trait":
+                                raise TraitError(
+                                    "Cannot create a complex "
+                                    "trait containing %s trait."
+                                    % add_article(item.type)
+                                )
+                            handler = item.handler
+                            if handler is None:
+                                break
+                            other[i] = handler
+                    else:
+                        handler = TraitCompound(other)
+
+        # Save the results:
+        self.handler = handler
+        self.clone = clone
+
+        if default_value_type < 0:
+            if isinstance(default_value, Default):
+                default_value_type = DefaultValue.callable_and_args
+                default_value = default_value.default_value
+            else:
+                if (handler is None) and (clone is not None):
+                    handler = clone.handler
+
+                if handler is not None:
+                    default_value_type = handler.default_value_type
+                    if default_value_type < 0:
+                        try:
+                            default_value = handler.validate(
+                                None, "", default_value
+                            )
+                        except:
+                            pass
+
+                if default_value_type < 0:
+                    default_value_type = _infer_default_value_type(
+                        default_value
+                    )
+
+        self.default_value_type = default_value_type
+        self.default_value = default_value
+        self.metadata = metadata.copy()
+
+    def do_list(self, list, enum, map, other):
+        """ Determine the correct TraitHandler for each item in a list. """
+        for item in list:
+            if item in PythonTypes:
+                other.append(TraitCoerceType(item))
+            else:
+                item = try_trait_cast(item)
+                typeItem = type(item)
+
+                if typeItem in ConstantTypes:
+                    enum.append(item)
+
+                elif typeItem in SequenceTypes:
+                    self.do_list(item, enum, map, other)
+
+                elif typeItem is dict:
+                    map.update(item)
+
+                elif typeItem in CallableTypes:
+                    other.append(TraitFunction(item))
+
+                elif isinstance(item, TraitTypes):
+                    other.append(item)
+
+                else:
+                    other.append(TraitInstance(item))
+
+    def as_ctrait(self):
+        """ Return a properly initialized 'CTrait' instance. """
+        metadata = self.metadata
+        trait = CTrait(
+            self.type_map.get(metadata.get("type"), TraitKind.trait))
+        clone = self.clone
+        if clone is not None:
+            trait.clone(clone)
+            if clone.__dict__ is not None:
+                trait.__dict__ = clone.__dict__.copy()
+
+        trait.set_default_value(self.default_value_type, self.default_value)
+
+        handler = self.handler
+        if handler is not None:
+            trait.handler = handler
+            validate = getattr(handler, "fast_validate", None)
+            if validate is None:
+                validate = handler.validate
+            trait.set_validate(validate)
+
+            post_setattr = getattr(handler, "post_setattr", None)
+            if post_setattr is not None:
+                trait.post_setattr = post_setattr
+                trait.is_mapped = handler.is_mapped
+
+        rich_compare = metadata.get("rich_compare")
+        if rich_compare is not None:
+            # Ref: enthought/traits#602
+            warnings.warn(
+                "The 'rich_compare' metadata has been deprecated. Please "
+                "use the 'comparison_mode' metadata instead. In a future "
+                "release, rich_compare will have no effect.",
+                DeprecationWarning,
+                stacklevel=4,
+            )
+            if rich_compare:
+                trait.comparison_mode = ComparisonMode.equality
+            else:
+                trait.comparison_mode = ComparisonMode.identity
+
+        comparison_mode = metadata.pop("comparison_mode", None)
+        if comparison_mode is not None:
+            trait.comparison_mode = comparison_mode
+
+        if len(metadata) > 0:
+            if trait.__dict__ is None:
+                trait.__dict__ = metadata
+            else:
+                trait.__dict__.update(metadata)
+
+        return trait
+
+
+def Property(
+    fget=None,
+    fset=None,
+    fvalidate=None,
+    force=False,
+    handler=None,
+    trait=None,
+    **metadata
+):
+    """ Returns a trait whose value is a Python property.
+
+    If no getter, setter or validate functions are specified (and **force** is
+    not True), it is assumed that they are defined elsewhere on the class whose
+    attribute this trait is assigned to. For example::
+
+        class Bar(HasTraits):
+
+            # A float traits Property that should be always positive.
+            foo = Property(Float)
+
+            # Shadow trait attribute
+            _foo = Float
+
+            def _set_foo(self,x):
+                self._foo = x
+
+            def _validate_foo(self, x):
+                if x <= 0:
+                    raise TraitError(
+                        'foo property should be a positive number')
+                return x
+
+            def _get_foo(self):
+                return self._foo
+
+    You can use the **depends_on** metadata attribute to indicate that the
+    property depends on the value of another trait. The value of **depends_on**
+    is an extended name specifier for traits that the property depends on. The
+    property will a trait change notification if any of the traits specified
+    by **depends_on** change. For example::
+
+        class Wheel ( Part ):
+            axle     = Instanced( Axle )
+            position = Property( depends_on = 'axle.chassis.position' )
+
+    For details of the extended trait name syntax, refer to the
+    on_trait_change() method of the HasTraits class.
+
+    Parameters
+    ----------
+    fget : function
+        The "getter" function for the property.
+    fset : function
+        The "setter" function for the property.
+    fvalidate : function
+        The validation function for the property. The method should return the
+        value to set or raise TraitError if the new value is not valid.
+    force : bool
+        Indicates whether to use only the function definitions specified by
+        **fget** and **fset**, and not look elsewhere on the class.
+    handler : function
+        A trait handler function for the trait.
+    trait : Trait or value
+        A trait definition or a value that can be converted to a trait that
+        constrains the values of the property trait.
+    """
+    metadata["type"] = "property"
+
+    # If no parameters specified, must be a forward reference (if not forced):
+    if (not force) and (fset is None):
+        sum = (
+            (fget is not None) + (fvalidate is not None) + (trait is not None)
+        )
+        if sum <= 1:
+            if sum == 0:
+                return ForwardProperty(metadata)
+
+            handler = None
+            if fget is not None:
+                trait = fget
+
+            if trait is not None:
+                trait = trait_cast(trait)
+                if trait is not None:
+                    fvalidate = handler = trait.handler
+                    if fvalidate is not None:
+                        fvalidate = handler.validate
+
+            if (fvalidate is not None) or (trait is not None):
+                if "editor" not in metadata:
+                    if (trait is not None) and (trait.editor is not None):
+                        metadata["editor"] = trait.editor
+
+                return ForwardProperty(metadata, fvalidate, handler)
+
+    if fget is None:
+        metadata["transient"] = True
+        if fset is None:
+            fget = _undefined_get
+            fset = _undefined_set
+        else:
+            fget = _write_only
+
+    elif fset is None:
+        fset = _read_only
+        metadata["transient"] = True
+
+    if trait is not None:
+        trait = trait_cast(trait)
+        handler = trait.handler
+        if (fvalidate is None) and (handler is not None):
+            fvalidate = handler.validate
+
+        if ("editor" not in metadata) and (trait.editor is not None):
+            metadata["editor"] = trait.editor
+
+    metadata.setdefault("depends_on", getattr(fget, "depends_on", None))
+    if (metadata.get("depends_on") is not None) and getattr(
+        fget, "cached_property", False
+    ):
+        metadata.setdefault("cached", True)
+
+    trait = CTrait(TraitKind.property)
+    trait.__dict__ = metadata.copy()
+    trait.property_fields = (fget, fset, fvalidate)
+    trait.handler = handler
+
+    return trait
+
+
+Property = TraitFactory(Property)
+
+
+class ForwardProperty(object):
+    """ Used to implement Property traits where accessor functions are defined
+    implicitly on the class.
+    """
+
+    def __init__(self, metadata, validate=None, handler=None):
+        self.metadata = metadata.copy()
+        self.validate = validate
+        self.handler = handler
+
+
+# Predefined, reusable trait instances
+
+# Generic trait with 'object' behavior:
+generic_trait = CTrait(TraitKind.generic)
+
+
+# User interface related color and font traits
+
+@deprecated("'Color' in 'traits' package has been deprecated. "
+            "Use 'Color' from 'traitsui' package instead.")
+def Color(*args, **metadata):
+    """ Returns a trait whose value must be a GUI toolkit-specific color.
+
+    .. deprecated:: 6.1.0
+        ``Color`` trait in this package will be removed in the future. It is
+        replaced by ``Color`` trait in TraitsUI package.
+    """
+    from traitsui.toolkit_traits import ColorTrait
+
+    return ColorTrait(*args, **metadata)
+
+
+Color = TraitFactory(Color)
+
+
+@deprecated("'RGBColor' in 'traits' package has been deprecated. "
+            "Use 'RGBColor' from 'traitsui' package instead.")
+def RGBColor(*args, **metadata):
+    """ Returns a trait whose value must be a GUI toolkit-specific RGB-based
+    color.
+
+    .. deprecated:: 6.1.0
+        ``RGBColor`` trait in this package will be removed in the future. It is
+        replaced by ``RGBColor`` trait in TraitsUI package.
+    """
+    from traitsui.toolkit_traits import RGBColorTrait
+
+    return RGBColorTrait(*args, **metadata)
+
+
+RGBColor = TraitFactory(RGBColor)
+
+
+@deprecated("'Font' in 'traits' package has been deprecated. "
+            "Use 'Font' from 'traitsui' package instead.")
+def Font(*args, **metadata):
+    """ Returns a trait whose value must be a GUI toolkit-specific font.
+
+    .. deprecated:: 6.1.0
+        ``Font`` trait in this package will be removed in the future. It is
+        replaced by ``Font`` trait in TraitsUI package.
+    """
+    from traitsui.toolkit_traits import FontTrait
+
+    return FontTrait(*args, **metadata)
+
+
+Font = TraitFactory(Font)
+
+ +
+
+
+
+
+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/5.0/_modules/traitsui/editors/code_editor.html b/5.0/_modules/traitsui/editors/code_editor.html new file mode 100644 index 000000000..ae28fc000 --- /dev/null +++ b/5.0/_modules/traitsui/editors/code_editor.html @@ -0,0 +1,243 @@ + + + + + + + traitsui.editors.code_editor — Apptools Documentation + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +

Source code for traitsui.editors.code_editor

+# ------------------------------------------------------------------------------
+#
+#  Copyright (c) 2008, Enthought, Inc.
+#  All rights reserved.
+#
+#  This software is provided without warranty under the terms of the BSD
+#  license included in LICENSE.txt and may be redistributed only
+#  under the conditions described in the aforementioned license.  The license
+#  is also available online at http://www.enthought.com/licenses/BSD.txt
+#
+#  Thanks for using Enthought open source!
+#
+#  Author: David C. Morrill
+#  Date:   01/27/2006
+#
+# ------------------------------------------------------------------------------
+
+""" Defines the code editor factory for all traits toolkit backends,
+useful for tools such as debuggers.
+"""
+
+
+
+from traits.api import Instance, Str, Enum, Bool
+
+from ..editor_factory import EditorFactory
+from ..toolkit_traits import Color
+
+# -------------------------------------------------------------------------
+#  'ToolkitEditorFactory' class:
+# -------------------------------------------------------------------------
+
+
+class ToolkitEditorFactory(EditorFactory):
+    """ Editor factory for code editors.
+    """
+
+    # -------------------------------------------------------------------------
+    #  Trait definitions:
+    # -------------------------------------------------------------------------
+
+    #: Object trait containing list of line numbers to mark (optional)
+    mark_lines = Str()
+
+    #: Background color for marking lines
+    mark_color = Color(0xECE9D8)
+
+    #: Object trait containing the currently selected line (optional)
+    selected_line = Str()
+
+    #: Object trait containing the currently selected text (optional)
+    selected_text = Str()
+
+    #: Object trait containing the currently selected text start position
+    #: (optional)
+    selected_start_pos = Str()
+
+    #: Object trait containing the currently selected text end position
+    #: (optional)
+    selected_end_pos = Str()
+
+    #: Background color for selected lines
+    selected_color = Color(0xA4FFFF)
+
+    #: Where should the search toolbar be placed?
+    search = Enum("top", "bottom", "none")
+
+    #: Background color for lines that match the current search
+    search_color = Color(0xFFFF94)
+
+    #: Current line
+    line = Str()
+
+    #: Current column
+    column = Str()
+
+    #: Should code folding be enabled?
+    foldable = Bool(True)
+
+    #: Should line numbers be displayed in the margin?
+    show_line_numbers = Bool(True)
+
+    #: Is user input set on every change?
+    auto_set = Bool(True)
+
+    #: Should the editor auto-scroll when a new **selected_line** value is set?
+    auto_scroll = Bool(True)
+
+    #: Optional key bindings associated with the editor
+    key_bindings = Instance("traitsui.key_bindings.KeyBindings")
+
+    #: Calltip clicked event
+    calltip_clicked = Str()
+
+    #: The lexer to use. Default is 'python'; 'null' indicates no lexing.
+    lexer = Str("python")
+
+    #: Object trait containing the list of line numbers to dim (optional)
+    dim_lines = Str()
+
+    #: Object trait to dim lines to. Can be of form #rrggbb or a color spec. If
+    #: not specified, dark grey is used.
+    dim_color = Str()
+
+    #: Object trait containing the list of line numbers to put squiggles under
+    #: (optional)
+    squiggle_lines = Str()
+
+    #: Object trait for the color of squiggles. If not specified, red is used.
+    squiggle_color = Str()
+
+
+# Define the Code Editor class.
+CodeEditor = ToolkitEditorFactory
+
+ +
+
+
+
+
+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/5.0/_modules/traitsui/editors/tabular_editor.html b/5.0/_modules/traitsui/editors/tabular_editor.html new file mode 100644 index 000000000..a6db5e448 --- /dev/null +++ b/5.0/_modules/traitsui/editors/tabular_editor.html @@ -0,0 +1,290 @@ + + + + + + + traitsui.editors.tabular_editor — Apptools Documentation + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +

Source code for traitsui.editors.tabular_editor

+# -------------------------------------------------------------------------
+#
+#  Copyright (c) 2007, Enthought, Inc.
+#  All rights reserved.
+#
+#  This software is provided without warranty under the terms of the BSD
+#  license included in LICENSE.txt and may be redistributed only
+#  under the conditions described in the aforementioned license.  The license
+#  is also available online at http://www.enthought.com/licenses/BSD.txt
+#
+#  Thanks for using Enthought open source!
+#
+#  Author: David C. Morrill
+#  Date:   05/20/2007
+#
+# -------------------------------------------------------------------------
+
+""" A traits UI editor for editing tabular data (arrays, list of tuples, lists
+    of objects, etc).
+"""
+
+
+
+from pyface.ui_traits import Image
+from traits.api import Str, Bool, Property, List, Enum, Instance
+
+from ..basic_editor_factory import BasicEditorFactory
+
+from ..toolkit import toolkit_object
+
+
+class TabularEditor(BasicEditorFactory):
+    """ Editor factory for tabular editors.
+    """
+
+    # -- Trait Definitions ----------------------------------------------------
+
+    #: The editor class to be created:
+    klass = Property()
+
+    #: Should column headers (i.e. titles) be displayed?
+    show_titles = Bool(True)
+
+    #: Should row headers be displayed (Qt4 only)?
+    show_row_titles = Bool(False)
+
+    #: The optional extended name of the trait used to indicate that a complete
+    #: table update is needed:
+    update = Str()
+
+    #: The optional extended name of the trait used to indicate that the table
+    #: just needs to be repainted.
+    refresh = Str()
+
+    #: Should the table update automatically when the table item's contents
+    #: change? Note that in order for this feature to work correctly, the editor
+    #: trait should be a list of objects derived from HasTraits. Also,
+    #: performance can be affected when very long lists are used, since enabling
+    #: this feature adds and removed Traits listeners to each item in the list.
+    auto_update = Bool(False)
+
+    #: The optional extended name of the trait to synchronize the selection
+    #: values with:
+    selected = Str()
+
+    #: The optional extended name of the trait to synchronize the selection rows
+    #: with:
+    selected_row = Str()
+
+    #: Whether or not to allow selection.
+    selectable = Bool(True)
+
+    #: The optional extended name of the trait to synchronize the activated value
+    #: with:
+    activated = Str()
+
+    #: The optional extended name of the trait to synchronize the activated
+    #: value's row with:
+    activated_row = Str()
+
+    #: The optional extended name of the trait to synchronize left click data
+    #: with. The data is a TabularEditorEvent:
+    clicked = Str()
+
+    #: The optional extended name of the trait to synchronize left double click
+    #: data with. The data is a TabularEditorEvent:
+    dclicked = Str()
+
+    #: The optional extended name of the trait to synchronize right click data
+    #: with. The data is a TabularEditorEvent:
+    right_clicked = Str()
+
+    #: The optional extended name of the trait to synchronize right double
+    #: clicked data with. The data is a TabularEditorEvent:
+    right_dclicked = Str()
+
+    #: The optional extended name of the trait to synchronize column
+    #: clicked data with. The data is a TabularEditorEvent:
+    column_clicked = Str()
+
+    #: The optional extended name of the trait to synchronize column
+    #: right clicked data with. The data is a TabularEditorEvent:
+    column_right_clicked = Str()
+
+    #: The optional extended name of the Event trait that should be used to
+    #: trigger a scroll-to command. The data is an integer giving the row.
+    scroll_to_row = Str()
+
+    #: The optional extended name of the Event trait that should be used to
+    #: trigger a scroll-to command. The data is an integer giving the column.
+    scroll_to_column = Str()
+
+    #: Controls behavior of scroll to row
+    scroll_to_row_hint = Enum("center", "top", "bottom", "visible")
+
+    #: Can the user edit the values?
+    editable = Bool(True)
+
+    #: Can the user edit the labels (i.e. the first column)
+    editable_labels = Bool(False)
+
+    #: Are multiple selected items allowed?
+    multi_select = Bool(False)
+
+    #: Should horizontal lines be drawn between items?
+    horizontal_lines = Bool(True)
+
+    #: Should vertical lines be drawn between items?
+    vertical_lines = Bool(True)
+
+    #: Should the columns automatically resize? Don't allow this when the amount
+    #: of data is large.
+    auto_resize = Bool(False)
+
+    #: Should the rows automatically resize (Qt4 only)? Don't allow
+    #: this when the amount of data is large.
+    auto_resize_rows = Bool(False)
+
+    #: Whether to stretch the last column to fit the available space.
+    stretch_last_section = Bool(True)
+
+    #: The adapter from trait values to editor values:
+    adapter = Instance("traitsui.tabular_adapter.TabularAdapter", ())
+
+    #: What type of operations are allowed on the list:
+    operations = List(
+        Enum("delete", "insert", "append", "edit", "move"),
+        ["delete", "insert", "append", "edit", "move"],
+    )
+
+    #: Are 'drag_move' operations allowed (i.e. True), or should they always be
+    #: treated as 'drag_copy' operations (i.e. False):
+    drag_move = Bool(True)
+
+    #: The set of images that can be used:
+    images = List(Image)
+
+    def _get_klass(self):
+        """ Returns the toolkit-specific editor class to be instantiated.
+        """
+        return toolkit_object("tabular_editor:TabularEditor")
+
+ +
+
+
+
+
+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/5.0/_modules/traitsui/view.html b/5.0/_modules/traitsui/view.html new file mode 100644 index 000000000..9ef548fe1 --- /dev/null +++ b/5.0/_modules/traitsui/view.html @@ -0,0 +1,610 @@ + + + + + + + traitsui.view — Apptools Documentation + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +

Source code for traitsui.view

+# ------------------------------------------------------------------------------
+#
+#  Copyright (c) 2005, Enthought, Inc.
+#  All rights reserved.
+#
+#  This software is provided without warranty under the terms of the BSD
+#  license included in LICENSE.txt and may be redistributed only
+#  under the conditions described in the aforementioned license.  The license
+#  is also available online at http://www.enthought.com/licenses/BSD.txt
+#
+#  Thanks for using Enthought open source!
+#
+#  Author: David C. Morrill
+#  Date:   10/07/2004
+#
+# ------------------------------------------------------------------------------
+
+""" Defines the View class used to represent the structural content of a
+    Traits-based user interface.
+"""
+
+
+
+from pyface.ui_traits import Image
+from traits.api import (
+    Any,
+    Bool,
+    Callable,
+    Enum,
+    Event,
+    Float,
+    Instance,
+    List,
+    Str,
+    Trait,
+)
+
+from .view_element import ViewElement, ViewSubElement
+
+from .ui import UI
+
+from .ui_traits import (
+    AButton,
+    AnObject,
+    Buttons,
+    DockStyle,
+    EditorStyle,
+    ExportType,
+    HelpId,
+    Image,
+    SequenceTypes,
+    ViewStatus,
+)
+
+from .handler import Handler, default_handler
+
+from .group import Group
+
+from .item import Item
+
+from .include import Include
+
+from .helper import PrefixList
+
+# -------------------------------------------------------------------------
+#  Trait definitions:
+# -------------------------------------------------------------------------
+
+# Name of the view trait:
+AnId = Str(desc="the name of the view")
+
+# Contents of the view trait (i.e., a single Group object):
+Content = Instance(Group, desc="the content of the view")
+
+# An optional model/view factory for converting the model into a viewable
+# 'model_view' object
+AModelView = Callable(
+    desc="the factory function for converting a model "
+    "into a model/view object"
+)
+
+# Reference to a Handler object trait:
+AHandler = Any(desc="the handler for the view")
+
+# Dialog window title trait:
+ATitle = Str(desc="the window title for the view")
+
+# User interface 'kind' trait. The values have the following meanings:
+#
+# * 'panel': An embeddable panel. This type of window is intended to be used as
+#   part of a larger interface.
+# * 'subpanel': An embeddable panel that does not display command buttons,
+#   even if the View specifies them.
+# * 'modal': A modal dialog box that operates on a clone of the object until
+#   the user commits the change.
+# * 'nonmodal':  A nonmodal dialog box that operates on a clone of the object
+#   until the user commits the change
+# * 'live': A nonmodal dialog box that immediately updates the object.
+# * 'livemodal': A modal dialog box that immediately updates the object.
+# * 'popup': A temporary, frameless popup dialog that immediately updates the
+#   object and is active only while the mouse pointer is in the dialog.
+# * 'info': A temporary, frameless popup dialog that immediately updates the
+#   object and is active only while the dialog is still over the invoking
+#   control.
+# * 'wizard': A wizard modal dialog box. A wizard contains a sequence of
+#   pages, which can be accessed by clicking **Next** and **Back** buttons.
+#   Changes to attribute values are applied only when the user clicks the
+#   **Finish** button on the last page.
+AKind = PrefixList(
+    (
+        "panel",
+        "subpanel",
+        "modal",
+        "nonmodal",
+        "livemodal",
+        "live",
+        "popup",
+        "popover",
+        "info",
+        "wizard",
+    ),
+    default_value='live',
+    desc="the kind of view window to create",
+    cols=4,
+)
+
+# Apply changes handler:
+OnApply = Callable(
+    desc="the routine to call when modal changes are applied " "or reverted"
+)
+
+# Is the dialog window resizable?
+IsResizable = Bool(False, desc="whether dialog can be resized or not")
+
+# Is the view scrollable?
+IsScrollable = Bool(False, desc="whether view should be scrollable or not")
+
+# The valid categories of imported elements that can be dragged into the view:
+ImportTypes = List(
+    Str, desc="the categories of elements that can be " "dragged into the view"
+)
+
+# The view position and size traits:
+Width = Float(-1e6, desc="the width of the view window")
+Height = Float(-1e6, desc="the height of the view window")
+XCoordinate = Float(-1e6, desc="the x coordinate of the view window")
+YCoordinate = Float(-1e6, desc="the y coordinate of the view window")
+
+# The result that should be returned if the user clicks the window or dialog
+# close button or icon
+CloseResult = Enum(
+    None,
+    True,
+    False,
+    desc="the result to return when the user clicks the "
+    "window or dialog close button or icon",
+)
+
+# The KeyBindings trait:
+AKeyBindings = Instance(
+    "traitsui.key_bindings.KeyBindings",
+    desc="the global key bindings for the view",
+)
+
+
+class View(ViewElement):
+    """ A Traits-based user interface for one or more objects.
+
+        The attributes of the View object determine the contents and layout of
+        an attribute-editing window. A View object contains a set of Group,
+        Item, and Include objects. A View object can be an attribute of an
+        object derived from HasTraits, or it can be a standalone object.
+    """
+
+    # -------------------------------------------------------------------------
+    #  Trait definitions:
+    # -------------------------------------------------------------------------
+
+    #: A unique identifier for the view:
+    id = AnId
+
+    #: The top-level Group object for the view:
+    content = Content
+
+    #: The menu bar for the view. Usually requires a custom **handler**:
+    menubar = Any  # Instance( pyface.action.MenuBarManager )
+
+    #: The toolbar for the view. Usually requires a custom **handler**:
+    toolbar = Any  # Instance( pyface.action.ToolBarManager )
+
+    #: Status bar items to add to the view's status bar. The value can be:
+    #:
+    #:   - **None**: No status bar for the view (the default).
+    #:   - string: Same as [ StatusItem( name = string ) ].
+    #:   - StatusItem: Same as [ StatusItem ].
+    #:   - [ [StatusItem|string], ... ]: Create a status bar with one field for
+    #:     each StatusItem in the list (or tuple). The status bar fields are
+    #:     defined from left to right in the order specified. A string value is
+    #:     converted to: StatusItem( name = string ):
+    statusbar = ViewStatus
+
+    #: List of button actions to add to the view. The **traitsui.menu**
+    #: module defines standard buttons, such as **OKButton**, and standard sets
+    #: of buttons, such as **ModalButtons**, which can be used to define a value
+    #: for this attribute. This value can also be a list of button name strings,
+    #: such as ``['OK', 'Cancel', 'Help']``. If set to the empty list, the
+    #: view contains a default set of buttons (equivalent to **LiveButtons**:
+    #: Undo/Redo, Revert, OK, Cancel, Help). To suppress buttons in the view,
+    #: use the **NoButtons** variable, defined in **traitsui.menu**.
+    buttons = Buttons
+
+    #: The default button to activate when Enter is pressed. If not specified,
+    #: pressing Enter will not activate any button.
+    default_button = AButton
+
+    #: The set of global key bindings for the view. Each time a key is pressed
+    #: while the view has keyboard focus, the key is checked to see if it is one
+    #: of the keys recognized by the KeyBindings object. If it is, the matching
+    #: KeyBinding's method name is checked to see if it is defined on any of the
+    #: object's in the view's context. If it is, the method is invoked. If the
+    #: result of the method is **False**, then the search continues with the
+    #: next object in the context. If any invoked method returns a non-False
+    #: value, processing stops and the key is marked as having been handled. If
+    #: all invoked methods return **False**, or no matching KeyBinding object is
+    #: found, the key is processed normally. If the view has a non-empty *id*
+    #: trait, the contents of the **KeyBindings** object will be saved as part
+    #: of the view's persistent data:
+    key_bindings = AKeyBindings
+
+    #: The Handler object that provides GUI logic for handling events in the
+    #: window. Set this attribute only if you are using a custom Handler. If
+    #: not set, the default Traits UI Handler is used.
+    handler = AHandler
+
+    #: The factory function for converting a model into a model/view object:
+    model_view = AModelView
+
+    #: Title for the view, displayed in the title bar when the view appears as a
+    #: secondary window (i.e., dialog or wizard). If not specified, "Edit
+    #: properties" is used as the title.
+    title = ATitle
+
+    #: The name of the icon to display in the dialog window title bar:
+    icon = Image
+
+    #: The kind of user interface to create:
+    kind = AKind
+
+    #: The default object being edited:
+    object = AnObject
+
+    #: The default editor style of elements in the view:
+    style = EditorStyle
+
+    #: The default docking style to use for sub-groups of the view. The following
+    #: values are possible:
+    #:
+    #: * 'fixed': No rearrangement of sub-groups is allowed.
+    #: * 'horizontal': Moveable elements have a visual "handle" to the left by
+    #:   which the element can be dragged.
+    #: * 'vertical': Moveable elements have a visual "handle" above them by
+    #:   which the element can be dragged.
+    #: * 'tabbed': Moveable elements appear as tabbed pages, which can be
+    #:   arranged within the window or "stacked" so that only one appears at
+    #:   at a time.
+    dock = DockStyle
+
+    #: The image to display on notebook tabs:
+    image = Image
+
+    #: Called when modal changes are applied or reverted:
+    on_apply = OnApply
+
+    #: Can the user resize the window?
+    resizable = IsResizable
+
+    #: Can the user scroll the view? If set to True, window-level scroll bars
+    #: appear whenever the window is too small to show all of its contents at
+    #: one time. If set to False, the window does not scroll, but individual
+    #: widgets might still contain scroll bars.
+    scrollable = IsScrollable
+
+    #: The category of exported elements:
+    export = ExportType
+
+    #: The valid categories of imported elements:
+    imports = ImportTypes
+
+    #: External help context identifier, which can be used by a custom help
+    #: handler. This attribute is ignored by the default help handler.
+    help_id = HelpId
+
+    #: Requested x-coordinate (horizontal position) for the view window. This
+    #: attribute can be specified in the following ways:
+    #:
+    #: * A positive integer: indicates the number of pixels from the left edge
+    #:   of the screen to the left edge of the window.
+    #: * A negative integer: indicates the number of pixels from the right edge
+    #:   of the screen to the right edge of the window.
+    #: * A floating point value between 0 and 1: indicates the fraction of the
+    #:   total screen width between the left edge of the screen and the left edge
+    #:   of the window.
+    #: * A floating point value between -1 and 0: indicates the fraction of the
+    #:   total screen width between the right edge of the screen and the right
+    #:   edge of the window.
+    x = XCoordinate
+
+    #: Requested y-coordinate (vertical position) for the view window. This
+    #: attribute behaves exactly like the **x** attribute, except that its value
+    #: indicates the position of the top or bottom of the view window relative
+    #: to the top or bottom of the screen.
+    y = YCoordinate
+
+    #: Requested width for the view window, as an (integer) number of pixels, or
+    #: as a (floating point) fraction of the screen width.
+    width = Width
+
+    #: Requested height for the view window, as an (integer) number of pixels, or
+    #: as a (floating point) fraction of the screen height.
+    height = Height
+
+    #: Class of dropped objects that can be added:
+    drop_class = Any()
+
+    #: Event when the view has been updated:
+    updated = Event()
+
+    #: What result should be returned if the user clicks the window or dialog
+    #: close button or icon?
+    close_result = CloseResult
+
+    #: Note: Group objects delegate their 'object' and 'style' traits to the
+    #: View
+
+    # -- Deprecated Traits (DO NOT USE) ---------------------------------------
+
+    ok = Bool(False)
+    cancel = Bool(False)
+    undo = Bool(False)
+    redo = Bool(False)
+    apply = Bool(False)
+    revert = Bool(False)
+    help = Bool(False)
+
+    def __init__(self, *values, **traits):
+        """ Initializes the object.
+        """
+        ViewElement.__init__(self, **traits)
+        self.set_content(*values)
+
+    def set_content(self, *values):
+        """ Sets the content of a view.
+        """
+        content = []
+        accum = []
+        for value in values:
+            if isinstance(value, ViewSubElement):
+                content.append(value)
+            elif type(value) in SequenceTypes:
+                content.append(Group(*value))
+            elif (
+                isinstance(value, str)
+                and (value[:1] == "<")
+                and (value[-1:] == ">")
+            ):
+                # Convert string to an Include value:
+                content.append(Include(value[1:-1].strip()))
+            else:
+                content.append(Item(value))
+
+        # If there are any 'Item' objects in the content, wrap the content in a
+        # Group:
+        for item in content:
+            if isinstance(item, Item):
+                content = [Group(*content)]
+                break
+
+        # Wrap all of the content up into a Group and save it as our content:
+        self.content = Group(container=self, *content)
+
+    def ui(
+        self,
+        context,
+        parent=None,
+        kind=None,
+        view_elements=None,
+        handler=None,
+        id="",
+        scrollable=None,
+        args=None,
+    ):
+        """ Creates a **UI** object, which generates the actual GUI window or
+        panel from a set of view elements.
+
+        Parameters
+        ----------
+        context : object or dictionary
+            A single object or a dictionary of string/object pairs, whose trait
+            attributes are to be edited. If not specified, the current object is
+            used.
+        parent : window component
+            The window parent of the View object's window
+        kind : string
+            The kind of window to create. See the **AKind** trait for details.
+            If *kind* is unspecified or None, the **kind** attribute of the
+            View object is used.
+        view_elements : ViewElements object
+            The set of Group, Item, and Include objects contained in the view.
+            Do not use this parameter when calling this method directly.
+        handler : Handler object
+            A handler object used for event handling in the dialog box. If
+            None, the default handler for Traits UI is used.
+        id : string
+            A unique ID for persisting preferences about this user interface,
+            such as size and position. If not specified, no user preferences
+            are saved.
+        scrollable : Boolean
+            Indicates whether the dialog box should be scrollable. When set to
+            True, scroll bars appear on the dialog box if it is not large enough
+            to display all of the items in the view at one time.
+
+        """
+        handler = handler or self.handler or default_handler()
+        if not isinstance(handler, Handler):
+            handler = handler()
+
+        if args is not None:
+            handler.trait_set(**args)
+
+        if not isinstance(context, dict):
+            context = context.trait_context()
+
+        context.setdefault("handler", handler)
+        handler = context["handler"]
+
+        if self.model_view is not None:
+            context["object"] = self.model_view(context["object"])
+
+        self_id = self.id
+        if self_id != "":
+            if id != "":
+                id = "%s:%s" % (self_id, id)
+            else:
+                id = self_id
+
+        if scrollable is None:
+            scrollable = self.scrollable
+
+        ui = UI(
+            view=self,
+            context=context,
+            handler=handler,
+            view_elements=view_elements,
+            title=self.title,
+            id=id,
+            scrollable=scrollable,
+        )
+
+        if kind is None:
+            kind = self.kind
+
+        ui.ui(parent, kind)
+
+        return ui
+
+    def replace_include(self, view_elements):
+        """ Replaces any items that have an ID with an Include object with
+            the same ID, and puts the object with the ID into the specified
+            ViewElements object.
+        """
+        if self.content is not None:
+            self.content.replace_include(view_elements)
+
+    def __repr__(self):
+        """ Returns a "pretty print" version of the View.
+        """
+        if self.content is None:
+            return "()"
+        return "( %s )" % ", ".join(
+            [item.__repr__() for item in self.content.content]
+        )
+
+ +
+
+
+
+
+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/5.0/_sources/api.rst.txt b/5.0/_sources/api.rst.txt new file mode 100644 index 000000000..224ac6510 --- /dev/null +++ b/5.0/_sources/api.rst.txt @@ -0,0 +1,11 @@ +.. _api-documentation: + +API documentation +================= + +This section contains auto-generated API documentation for AppTools. + +.. toctree:: + :maxdepth: 2 + + api/modules diff --git a/5.0/_sources/api/apptools.io.h5.rst.txt b/5.0/_sources/api/apptools.io.h5.rst.txt new file mode 100644 index 000000000..dea85f58a --- /dev/null +++ b/5.0/_sources/api/apptools.io.h5.rst.txt @@ -0,0 +1,46 @@ +apptools.io.h5 package +====================== + +Submodules +---------- + +apptools.io.h5.dict\_node module +-------------------------------- + +.. automodule:: apptools.io.h5.dict_node + :members: + :undoc-members: + :show-inheritance: + +apptools.io.h5.file module +-------------------------- + +.. automodule:: apptools.io.h5.file + :members: + :undoc-members: + :show-inheritance: + +apptools.io.h5.table\_node module +--------------------------------- + +.. automodule:: apptools.io.h5.table_node + :members: + :undoc-members: + :show-inheritance: + +apptools.io.h5.utils module +--------------------------- + +.. automodule:: apptools.io.h5.utils + :members: + :undoc-members: + :show-inheritance: + + +Module contents +--------------- + +.. automodule:: apptools.io.h5 + :members: + :undoc-members: + :show-inheritance: diff --git a/5.0/_sources/api/apptools.io.rst.txt b/5.0/_sources/api/apptools.io.rst.txt new file mode 100644 index 000000000..0907ac23c --- /dev/null +++ b/5.0/_sources/api/apptools.io.rst.txt @@ -0,0 +1,37 @@ +apptools.io package +=================== + +Subpackages +----------- + +.. toctree:: + + apptools.io.h5 + +Submodules +---------- + +apptools.io.api module +---------------------- + +.. automodule:: apptools.io.api + :members: + :undoc-members: + :show-inheritance: + +apptools.io.file module +----------------------- + +.. automodule:: apptools.io.file + :members: + :undoc-members: + :show-inheritance: + + +Module contents +--------------- + +.. automodule:: apptools.io + :members: + :undoc-members: + :show-inheritance: diff --git a/5.0/_sources/api/apptools.logger.agent.rst.txt b/5.0/_sources/api/apptools.logger.agent.rst.txt new file mode 100644 index 000000000..c25c0dcfb --- /dev/null +++ b/5.0/_sources/api/apptools.logger.agent.rst.txt @@ -0,0 +1,38 @@ +apptools.logger.agent package +============================= + +Submodules +---------- + +apptools.logger.agent.attachments module +---------------------------------------- + +.. automodule:: apptools.logger.agent.attachments + :members: + :undoc-members: + :show-inheritance: + +apptools.logger.agent.quality\_agent\_mailer module +--------------------------------------------------- + +.. automodule:: apptools.logger.agent.quality_agent_mailer + :members: + :undoc-members: + :show-inheritance: + +apptools.logger.agent.quality\_agent\_view module +------------------------------------------------- + +.. automodule:: apptools.logger.agent.quality_agent_view + :members: + :undoc-members: + :show-inheritance: + + +Module contents +--------------- + +.. automodule:: apptools.logger.agent + :members: + :undoc-members: + :show-inheritance: diff --git a/5.0/_sources/api/apptools.logger.plugin.rst.txt b/5.0/_sources/api/apptools.logger.plugin.rst.txt new file mode 100644 index 000000000..b607fdd4e --- /dev/null +++ b/5.0/_sources/api/apptools.logger.plugin.rst.txt @@ -0,0 +1,45 @@ +apptools.logger.plugin package +============================== + +Subpackages +----------- + +.. toctree:: + + apptools.logger.plugin.view + +Submodules +---------- + +apptools.logger.plugin.logger\_plugin module +-------------------------------------------- + +.. automodule:: apptools.logger.plugin.logger_plugin + :members: + :undoc-members: + :show-inheritance: + +apptools.logger.plugin.logger\_preferences module +------------------------------------------------- + +.. automodule:: apptools.logger.plugin.logger_preferences + :members: + :undoc-members: + :show-inheritance: + +apptools.logger.plugin.logger\_service module +--------------------------------------------- + +.. automodule:: apptools.logger.plugin.logger_service + :members: + :undoc-members: + :show-inheritance: + + +Module contents +--------------- + +.. automodule:: apptools.logger.plugin + :members: + :undoc-members: + :show-inheritance: diff --git a/5.0/_sources/api/apptools.logger.plugin.view.rst.txt b/5.0/_sources/api/apptools.logger.plugin.view.rst.txt new file mode 100644 index 000000000..1d8dc0b3d --- /dev/null +++ b/5.0/_sources/api/apptools.logger.plugin.view.rst.txt @@ -0,0 +1,30 @@ +apptools.logger.plugin.view package +=================================== + +Submodules +---------- + +apptools.logger.plugin.view.logger\_preferences\_page module +------------------------------------------------------------ + +.. automodule:: apptools.logger.plugin.view.logger_preferences_page + :members: + :undoc-members: + :show-inheritance: + +apptools.logger.plugin.view.logger\_view module +----------------------------------------------- + +.. automodule:: apptools.logger.plugin.view.logger_view + :members: + :undoc-members: + :show-inheritance: + + +Module contents +--------------- + +.. automodule:: apptools.logger.plugin.view + :members: + :undoc-members: + :show-inheritance: diff --git a/5.0/_sources/api/apptools.logger.rst.txt b/5.0/_sources/api/apptools.logger.rst.txt new file mode 100644 index 000000000..c49196f26 --- /dev/null +++ b/5.0/_sources/api/apptools.logger.rst.txt @@ -0,0 +1,70 @@ +apptools.logger package +======================= + +Subpackages +----------- + +.. toctree:: + + apptools.logger.agent + apptools.logger.plugin + +Submodules +---------- + +apptools.logger.api module +-------------------------- + +.. automodule:: apptools.logger.api + :members: + :undoc-members: + :show-inheritance: + +apptools.logger.custom\_excepthook module +----------------------------------------- + +.. automodule:: apptools.logger.custom_excepthook + :members: + :undoc-members: + :show-inheritance: + +apptools.logger.log\_point module +--------------------------------- + +.. automodule:: apptools.logger.log_point + :members: + :undoc-members: + :show-inheritance: + +apptools.logger.log\_queue\_handler module +------------------------------------------ + +.. automodule:: apptools.logger.log_queue_handler + :members: + :undoc-members: + :show-inheritance: + +apptools.logger.logger module +----------------------------- + +.. automodule:: apptools.logger.logger + :members: + :undoc-members: + :show-inheritance: + +apptools.logger.ring\_buffer module +----------------------------------- + +.. automodule:: apptools.logger.ring_buffer + :members: + :undoc-members: + :show-inheritance: + + +Module contents +--------------- + +.. automodule:: apptools.logger + :members: + :undoc-members: + :show-inheritance: diff --git a/5.0/_sources/api/apptools.naming.rst.txt b/5.0/_sources/api/apptools.naming.rst.txt new file mode 100644 index 000000000..b4645f693 --- /dev/null +++ b/5.0/_sources/api/apptools.naming.rst.txt @@ -0,0 +1,221 @@ +apptools.naming package +======================= + +Subpackages +----------- + +.. toctree:: + + apptools.naming.trait_defs + +Submodules +---------- + +apptools.naming.address module +------------------------------ + +.. automodule:: apptools.naming.address + :members: + :undoc-members: + :show-inheritance: + +apptools.naming.api module +-------------------------- + +.. automodule:: apptools.naming.api + :members: + :undoc-members: + :show-inheritance: + +apptools.naming.binding module +------------------------------ + +.. automodule:: apptools.naming.binding + :members: + :undoc-members: + :show-inheritance: + +apptools.naming.context module +------------------------------ + +.. automodule:: apptools.naming.context + :members: + :undoc-members: + :show-inheritance: + +apptools.naming.dir\_context module +----------------------------------- + +.. automodule:: apptools.naming.dir_context + :members: + :undoc-members: + :show-inheritance: + +apptools.naming.dynamic\_context module +--------------------------------------- + +.. automodule:: apptools.naming.dynamic_context + :members: + :undoc-members: + :show-inheritance: + +apptools.naming.exception module +-------------------------------- + +.. automodule:: apptools.naming.exception + :members: + :undoc-members: + :show-inheritance: + +apptools.naming.initial\_context module +--------------------------------------- + +.. automodule:: apptools.naming.initial_context + :members: + :undoc-members: + :show-inheritance: + +apptools.naming.initial\_context\_factory module +------------------------------------------------ + +.. automodule:: apptools.naming.initial_context_factory + :members: + :undoc-members: + :show-inheritance: + +apptools.naming.naming\_event module +------------------------------------ + +.. automodule:: apptools.naming.naming_event + :members: + :undoc-members: + :show-inheritance: + +apptools.naming.naming\_manager module +-------------------------------------- + +.. automodule:: apptools.naming.naming_manager + :members: + :undoc-members: + :show-inheritance: + +apptools.naming.object\_factory module +-------------------------------------- + +.. automodule:: apptools.naming.object_factory + :members: + :undoc-members: + :show-inheritance: + +apptools.naming.object\_serializer module +----------------------------------------- + +.. automodule:: apptools.naming.object_serializer + :members: + :undoc-members: + :show-inheritance: + +apptools.naming.py\_context module +---------------------------------- + +.. automodule:: apptools.naming.py_context + :members: + :undoc-members: + :show-inheritance: + +apptools.naming.py\_object\_factory module +------------------------------------------ + +.. automodule:: apptools.naming.py_object_factory + :members: + :undoc-members: + :show-inheritance: + +apptools.naming.pyfs\_context module +------------------------------------ + +.. automodule:: apptools.naming.pyfs_context + :members: + :undoc-members: + :show-inheritance: + +apptools.naming.pyfs\_context\_factory module +--------------------------------------------- + +.. automodule:: apptools.naming.pyfs_context_factory + :members: + :undoc-members: + :show-inheritance: + +apptools.naming.pyfs\_initial\_context\_factory module +------------------------------------------------------ + +.. automodule:: apptools.naming.pyfs_initial_context_factory + :members: + :undoc-members: + :show-inheritance: + +apptools.naming.pyfs\_object\_factory module +-------------------------------------------- + +.. automodule:: apptools.naming.pyfs_object_factory + :members: + :undoc-members: + :show-inheritance: + +apptools.naming.pyfs\_state\_factory module +------------------------------------------- + +.. automodule:: apptools.naming.pyfs_state_factory + :members: + :undoc-members: + :show-inheritance: + +apptools.naming.reference module +-------------------------------- + +.. automodule:: apptools.naming.reference + :members: + :undoc-members: + :show-inheritance: + +apptools.naming.referenceable module +------------------------------------ + +.. automodule:: apptools.naming.referenceable + :members: + :undoc-members: + :show-inheritance: + +apptools.naming.referenceable\_state\_factory module +---------------------------------------------------- + +.. automodule:: apptools.naming.referenceable_state_factory + :members: + :undoc-members: + :show-inheritance: + +apptools.naming.state\_factory module +------------------------------------- + +.. automodule:: apptools.naming.state_factory + :members: + :undoc-members: + :show-inheritance: + +apptools.naming.unique\_name module +----------------------------------- + +.. automodule:: apptools.naming.unique_name + :members: + :undoc-members: + :show-inheritance: + + +Module contents +--------------- + +.. automodule:: apptools.naming + :members: + :undoc-members: + :show-inheritance: diff --git a/5.0/_sources/api/apptools.naming.trait_defs.rst.txt b/5.0/_sources/api/apptools.naming.trait_defs.rst.txt new file mode 100644 index 000000000..e2281ea3d --- /dev/null +++ b/5.0/_sources/api/apptools.naming.trait_defs.rst.txt @@ -0,0 +1,30 @@ +apptools.naming.trait\_defs package +=================================== + +Submodules +---------- + +apptools.naming.trait\_defs.api module +-------------------------------------- + +.. automodule:: apptools.naming.trait_defs.api + :members: + :undoc-members: + :show-inheritance: + +apptools.naming.trait\_defs.naming\_traits module +------------------------------------------------- + +.. automodule:: apptools.naming.trait_defs.naming_traits + :members: + :undoc-members: + :show-inheritance: + + +Module contents +--------------- + +.. automodule:: apptools.naming.trait_defs + :members: + :undoc-members: + :show-inheritance: diff --git a/5.0/_sources/api/apptools.persistence.rst.txt b/5.0/_sources/api/apptools.persistence.rst.txt new file mode 100644 index 000000000..4cda6c227 --- /dev/null +++ b/5.0/_sources/api/apptools.persistence.rst.txt @@ -0,0 +1,62 @@ +apptools.persistence package +============================ + +Submodules +---------- + +apptools.persistence.file\_path module +-------------------------------------- + +.. automodule:: apptools.persistence.file_path + :members: + :undoc-members: + :show-inheritance: + +apptools.persistence.project\_loader module +------------------------------------------- + +.. automodule:: apptools.persistence.project_loader + :members: + :undoc-members: + :show-inheritance: + +apptools.persistence.state\_pickler module +------------------------------------------ + +.. automodule:: apptools.persistence.state_pickler + :members: + :undoc-members: + :show-inheritance: + +apptools.persistence.updater module +----------------------------------- + +.. automodule:: apptools.persistence.updater + :members: + :undoc-members: + :show-inheritance: + +apptools.persistence.version\_registry module +--------------------------------------------- + +.. automodule:: apptools.persistence.version_registry + :members: + :undoc-members: + :show-inheritance: + +apptools.persistence.versioned\_unpickler module +------------------------------------------------ + +.. automodule:: apptools.persistence.versioned_unpickler + :members: + :undoc-members: + :show-inheritance: + + +Module contents +--------------- + +.. automodule:: apptools.persistence + :members: + :undoc-members: + :show-inheritance: diff --git a/5.0/_sources/api/apptools.preferences.rst.txt b/5.0/_sources/api/apptools.preferences.rst.txt new file mode 100644 index 000000000..cba31951c --- /dev/null +++ b/5.0/_sources/api/apptools.preferences.rst.txt @@ -0,0 +1,77 @@ +apptools.preferences package +============================ + +Subpackages +----------- + +.. toctree:: + + apptools.preferences.ui + +Submodules +---------- + +apptools.preferences.api module +------------------------------- + +.. automodule:: apptools.preferences.api + :members: + :undoc-members: + :show-inheritance: + +apptools.preferences.i\_preferences module +------------------------------------------ + +.. automodule:: apptools.preferences.i_preferences + :members: + :undoc-members: + :show-inheritance: + +apptools.preferences.package\_globals module +-------------------------------------------- + +.. automodule:: apptools.preferences.package_globals + :members: + :undoc-members: + :show-inheritance: + +apptools.preferences.preference\_binding module +----------------------------------------------- + +.. automodule:: apptools.preferences.preference_binding + :members: + :undoc-members: + :show-inheritance: + +apptools.preferences.preferences module +--------------------------------------- + +.. automodule:: apptools.preferences.preferences + :members: + :undoc-members: + :show-inheritance: + +apptools.preferences.preferences\_helper module +----------------------------------------------- + +.. automodule:: apptools.preferences.preferences_helper + :members: + :undoc-members: + :show-inheritance: + +apptools.preferences.scoped\_preferences module +----------------------------------------------- + +.. automodule:: apptools.preferences.scoped_preferences + :members: + :undoc-members: + :show-inheritance: + + +Module contents +--------------- + +.. automodule:: apptools.preferences + :members: + :undoc-members: + :show-inheritance: diff --git a/5.0/_sources/api/apptools.preferences.ui.rst.txt b/5.0/_sources/api/apptools.preferences.ui.rst.txt new file mode 100644 index 000000000..59a451f0a --- /dev/null +++ b/5.0/_sources/api/apptools.preferences.ui.rst.txt @@ -0,0 +1,70 @@ +apptools.preferences.ui package +=============================== + +Submodules +---------- + +apptools.preferences.ui.api module +---------------------------------- + +.. automodule:: apptools.preferences.ui.api + :members: + :undoc-members: + :show-inheritance: + +apptools.preferences.ui.i\_preferences\_page module +--------------------------------------------------- + +.. automodule:: apptools.preferences.ui.i_preferences_page + :members: + :undoc-members: + :show-inheritance: + +apptools.preferences.ui.preferences\_manager module +--------------------------------------------------- + +.. automodule:: apptools.preferences.ui.preferences_manager + :members: + :undoc-members: + :show-inheritance: + +apptools.preferences.ui.preferences\_node module +------------------------------------------------ + +.. automodule:: apptools.preferences.ui.preferences_node + :members: + :undoc-members: + :show-inheritance: + +apptools.preferences.ui.preferences\_page module +------------------------------------------------ + +.. automodule:: apptools.preferences.ui.preferences_page + :members: + :undoc-members: + :show-inheritance: + +apptools.preferences.ui.tree\_item module +----------------------------------------- + +.. automodule:: apptools.preferences.ui.tree_item + :members: + :undoc-members: + :show-inheritance: + +apptools.preferences.ui.widget\_editor module +--------------------------------------------- + +.. automodule:: apptools.preferences.ui.widget_editor + :members: + :undoc-members: + :show-inheritance: + + +Module contents +--------------- + +.. automodule:: apptools.preferences.ui + :members: + :undoc-members: + :show-inheritance: diff --git a/5.0/_sources/api/apptools.rst.txt b/5.0/_sources/api/apptools.rst.txt new file mode 100644 index 000000000..d1e57ded9 --- /dev/null +++ b/5.0/_sources/api/apptools.rst.txt @@ -0,0 +1,25 @@ +apptools package +================ + +Subpackages +----------- + +.. toctree:: + + apptools.io + apptools.logger + apptools.naming + apptools.persistence + apptools.preferences + apptools.scripting + apptools.selection + apptools.type_registry + apptools.undo + +Module contents +--------------- + +.. automodule:: apptools + :members: + :undoc-members: + :show-inheritance: diff --git a/5.0/_sources/api/apptools.scripting.rst.txt b/5.0/_sources/api/apptools.scripting.rst.txt new file mode 100644 index 000000000..4a47c7054 --- /dev/null +++ b/5.0/_sources/api/apptools.scripting.rst.txt @@ -0,0 +1,62 @@ +apptools.scripting package +========================== + +Submodules +---------- + +apptools.scripting.api module +----------------------------- + +.. automodule:: apptools.scripting.api + :members: + :undoc-members: + :show-inheritance: + +apptools.scripting.package\_globals module +------------------------------------------ + +.. automodule:: apptools.scripting.package_globals + :members: + :undoc-members: + :show-inheritance: + +apptools.scripting.recordable module +------------------------------------ + +.. automodule:: apptools.scripting.recordable + :members: + :undoc-members: + :show-inheritance: + +apptools.scripting.recorder module +---------------------------------- + +.. automodule:: apptools.scripting.recorder + :members: + :undoc-members: + :show-inheritance: + +apptools.scripting.recorder\_with\_ui module +-------------------------------------------- + +.. automodule:: apptools.scripting.recorder_with_ui + :members: + :undoc-members: + :show-inheritance: + +apptools.scripting.util module +------------------------------ + +.. automodule:: apptools.scripting.util + :members: + :undoc-members: + :show-inheritance: + + +Module contents +--------------- + +.. automodule:: apptools.scripting + :members: + :undoc-members: + :show-inheritance: diff --git a/5.0/_sources/api/apptools.selection.rst.txt b/5.0/_sources/api/apptools.selection.rst.txt new file mode 100644 index 000000000..d64022443 --- /dev/null +++ b/5.0/_sources/api/apptools.selection.rst.txt @@ -0,0 +1,62 @@ +apptools.selection package +========================== + +Submodules +---------- + +apptools.selection.api module +----------------------------- + +.. automodule:: apptools.selection.api + :members: + :undoc-members: + :show-inheritance: + +apptools.selection.errors module +-------------------------------- + +.. automodule:: apptools.selection.errors + :members: + :undoc-members: + :show-inheritance: + +apptools.selection.i\_selection module +-------------------------------------- + +.. automodule:: apptools.selection.i_selection + :members: + :undoc-members: + :show-inheritance: + +apptools.selection.i\_selection\_provider module +------------------------------------------------ + +.. automodule:: apptools.selection.i_selection_provider + :members: + :undoc-members: + :show-inheritance: + +apptools.selection.list\_selection module +----------------------------------------- + +.. automodule:: apptools.selection.list_selection + :members: + :undoc-members: + :show-inheritance: + +apptools.selection.selection\_service module +-------------------------------------------- + +.. automodule:: apptools.selection.selection_service + :members: + :undoc-members: + :show-inheritance: + + +Module contents +--------------- + +.. automodule:: apptools.selection + :members: + :undoc-members: + :show-inheritance: diff --git a/5.0/_sources/api/apptools.type_registry.rst.txt b/5.0/_sources/api/apptools.type_registry.rst.txt new file mode 100644 index 000000000..161af8365 --- /dev/null +++ b/5.0/_sources/api/apptools.type_registry.rst.txt @@ -0,0 +1,30 @@ +apptools.type\_registry package +=============================== + +Submodules +---------- + +apptools.type\_registry.api module +---------------------------------- + +.. automodule:: apptools.type_registry.api + :members: + :undoc-members: + :show-inheritance: + +apptools.type\_registry.type\_registry module +--------------------------------------------- + +.. automodule:: apptools.type_registry.type_registry + :members: + :undoc-members: + :show-inheritance: + + +Module contents +--------------- + +.. automodule:: apptools.type_registry + :members: + :undoc-members: + :show-inheritance: diff --git a/5.0/_sources/api/apptools.undo.action.rst.txt b/5.0/_sources/api/apptools.undo.action.rst.txt new file mode 100644 index 000000000..13985a67f --- /dev/null +++ b/5.0/_sources/api/apptools.undo.action.rst.txt @@ -0,0 +1,54 @@ +apptools.undo.action package +============================ + +Submodules +---------- + +apptools.undo.action.abstract\_command\_stack\_action module +------------------------------------------------------------ + +.. automodule:: apptools.undo.action.abstract_command_stack_action + :members: + :undoc-members: + :show-inheritance: + +apptools.undo.action.api module +------------------------------- + +.. automodule:: apptools.undo.action.api + :members: + :undoc-members: + :show-inheritance: + +apptools.undo.action.command\_action module +------------------------------------------- + +.. automodule:: apptools.undo.action.command_action + :members: + :undoc-members: + :show-inheritance: + +apptools.undo.action.redo\_action module +---------------------------------------- + +.. automodule:: apptools.undo.action.redo_action + :members: + :undoc-members: + :show-inheritance: + +apptools.undo.action.undo\_action module +---------------------------------------- + +.. automodule:: apptools.undo.action.undo_action + :members: + :undoc-members: + :show-inheritance: + + +Module contents +--------------- + +.. automodule:: apptools.undo.action + :members: + :undoc-members: + :show-inheritance: diff --git a/5.0/_sources/api/apptools.undo.rst.txt b/5.0/_sources/api/apptools.undo.rst.txt new file mode 100644 index 000000000..477e1bf52 --- /dev/null +++ b/5.0/_sources/api/apptools.undo.rst.txt @@ -0,0 +1,77 @@ +apptools.undo package +===================== + +Subpackages +----------- + +.. toctree:: + + apptools.undo.action + +Submodules +---------- + +apptools.undo.abstract\_command module +-------------------------------------- + +.. automodule:: apptools.undo.abstract_command + :members: + :undoc-members: + :show-inheritance: + +apptools.undo.api module +------------------------ + +.. automodule:: apptools.undo.api + :members: + :undoc-members: + :show-inheritance: + +apptools.undo.command\_stack module +----------------------------------- + +.. automodule:: apptools.undo.command_stack + :members: + :undoc-members: + :show-inheritance: + +apptools.undo.i\_command module +------------------------------- + +.. automodule:: apptools.undo.i_command + :members: + :undoc-members: + :show-inheritance: + +apptools.undo.i\_command\_stack module +-------------------------------------- + +.. automodule:: apptools.undo.i_command_stack + :members: + :undoc-members: + :show-inheritance: + +apptools.undo.i\_undo\_manager module +------------------------------------- + +.. automodule:: apptools.undo.i_undo_manager + :members: + :undoc-members: + :show-inheritance: + +apptools.undo.undo\_manager module +---------------------------------- + +.. automodule:: apptools.undo.undo_manager + :members: + :undoc-members: + :show-inheritance: + + +Module contents +--------------- + +.. automodule:: apptools.undo + :members: + :undoc-members: + :show-inheritance: diff --git a/5.0/_sources/api/modules.rst.txt b/5.0/_sources/api/modules.rst.txt new file mode 100644 index 000000000..f51f30d15 --- /dev/null +++ b/5.0/_sources/api/modules.rst.txt @@ -0,0 +1,7 @@ +apptools +======== + +.. toctree:: + :maxdepth: 4 + + apptools diff --git a/5.0/_sources/index.rst.txt b/5.0/_sources/index.rst.txt new file mode 100644 index 000000000..1891a5802 --- /dev/null +++ b/5.0/_sources/index.rst.txt @@ -0,0 +1,16 @@ +AppTools Documentation +============================================== + +.. toctree:: + :maxdepth: 2 + :glob: + + preferences/* + scripting/* + undo/* + selection/* + naming/* + io/* + api + +* :ref:`search` diff --git a/5.0/_sources/io/introduction.rst.txt b/5.0/_sources/io/introduction.rst.txt new file mode 100644 index 000000000..6bdd04ef5 --- /dev/null +++ b/5.0/_sources/io/introduction.rst.txt @@ -0,0 +1,28 @@ +File I/O +======== + +The :mod:`apptools.io` package provides a traited |File| object provides +properties and methods for common file path manipulation operations. Much of +this functionality was implemented before Python 3 `pathlib`_ standard library +became available to provide similar support. For new code we encourage users +to investigate if `pathlib`_ can satisfy their use cases before they turn to +the `apptools.io` |File| object + +HDF5 File Support +----------------- + +The :mod:`apptools.io.h5` sub-package provides a wrapper around `PyTables`_ +with a dictionary-style mapping. + + +.. + external links + +.. _pathlib: https://docs.python.org/3/library/pathlib.html +.. _PyTables: https://www.pytables.org/ + + +.. + # substitutions + +.. |File| replace:: :class:`~apptools.io.file.File` diff --git a/5.0/_sources/naming/Introduction.rst.txt b/5.0/_sources/naming/Introduction.rst.txt new file mode 100644 index 000000000..736f4b92a --- /dev/null +++ b/5.0/_sources/naming/Introduction.rst.txt @@ -0,0 +1,7 @@ +Naming +====== + +:mod:`apptools.naming` package is a Python implementation of the Naming portion of the `Java +Naming and Directory Interface `_, +including specific implementations for a heirarchy of Python objects. You can +also find the Java JNDI tutorial `here `_. diff --git a/5.0/_sources/preferences/Preferences.rst.txt b/5.0/_sources/preferences/Preferences.rst.txt new file mode 100644 index 000000000..51ee93fd8 --- /dev/null +++ b/5.0/_sources/preferences/Preferences.rst.txt @@ -0,0 +1,329 @@ +Preferences +=========== + +The preferences package provides a simple API for managing application +preferences. The classes in the package are implemented using a layered +approach where the lowest layer provides access to the raw preferences +mechanism and each layer on top providing more convenient ways to get and set +preference values. + +The Basic Preferences Mechanism +------------------------------- + +Lets start by taking a look at the lowest layer which consists of the +|IPreferences| interface and its default implementation in the |Preferences| +class. This layer implements the basic preferences system which is a +hierarchical arrangement of preferences 'nodes' (where each node is simply an +object that implements the |IPreferences| interface). Nodes in the hierarchy can +contain preference settings and/or child nodes. This layer also provides a +default way to read and write preferences from the filesystem using the +excellent `ConfigObj`_ package. + +This all sounds a bit complicated but, believe me, it isn't! To prove it +(hopefully) lets look at an example. Say I have the following preferences in +a file 'example.ini':: + + [acme.ui] + bgcolor = blue + width = 50 + ratio = 1.0 + visible = True + + [acme.ui.splash_screen] + image = splash + fgcolor = red + +I can create a preferences hierarchy from this file by:: + + >>> from apptools.preferences.api import Preferences + >>> preferences = Preferences(filename='example.ini') + >>> preferences.dump() + + Node() {} + Node(acme) {} + Node(ui) {'bgcolor': 'blue', 'width': '50', 'ratio': '1.0', 'visible': 'True'} + Node(splash_screen) {'image': 'splash', 'fgcolor': 'red'} + +The 'dump' method (useful for debugging etc) simply 'pretty prints' a +preferences hierarchy. The dictionary next to each node contains the node's +actual preferences. In this case, the root node (the node with no name) is the +preferences object that we created. This node now has one child node 'acme', +which contains no preferences. The 'acme' node has one child, 'ui', which +contains some preferences (e.g. 'bgcolor') and also a child node +'splash_screen' which also contains preferences (e.g. 'image'). + +To look up a preference we use:: + + >>> preferences.get('acme.ui.bgcolor') + 'blue' + +If no such preferences exists then, by default, None is returned:: + + >>> preferences.get('acme.ui.bogus') is None + True + +You can also specify an explicit default value:: + + >>> preferences.get('acme.ui.bogus', 'fred') + 'fred' + +To set a preference we use:: + + >>> preferences.set('acme.ui.bgcolor', 'red') + >>> preferences.get('acme.ui.bgcolor') + 'red' + +And to make sure the preferences are saved back to disk:: + + >>> preferences.flush() + +To add a new preference value we simply set it:: + + >>> preferences.set('acme.ui.fgcolor', 'black') + >>> preferences.get('acme.ui.fgcolor') + 'black' + +Any missing nodes in a call to 'set' are created automatically, hence:: + + >>> preferences.set('acme.ui.button.fgcolor', 'white') + >>> preferences.get('acme.ui.button.fgcolor') + 'white' + +Preferences can also be 'inherited'. e.g. Notice that the 'splash_screen' +node does not contain a 'bgcolor' preference, and hence:: + + >>> preferences.get('acme.ui.splash_screen.bgcolor') is None + True + +But if we allow the 'inheritance' of preference values then:: + + >>> preferences.get('acme.ui.splash_screen.bgcolor', inherit=True) + 'red' + +By using 'inheritance' here the preferences system will try the following +preferences:: + + 'acme.ui.splash_screen.bgcolor' + 'acme.ui.bgcolor' + 'acme.bgcolor' + 'bgcolor' + +Strings, Glorious Strings +~~~~~~~~~~~~~~~~~~~~~~~~~ + +At this point it is worth mentioning that preferences are *always* stored and +returned as strings. This is because of the limitations of the traditional +'.ini' file format i.e. they don't contain any type information! Now before you +start panicking, this doesn't mean that all of your preferences have to be +strings! Currently the preferences system allows, strings(!), booleans, ints, +longs, floats and complex numbers. When you store a non-string value it gets +converted to a string for you, but you *always* get a string back:: + + >>> preferences.get('acme.ui.width') + '50' + >>> preferences.set('acme.ui.width', 100) + >>> preferences.get('acme.ui.width') + '100' + + >>> preferences.get('acme.ui.visible') + 'True' + >>> preferences.set('acme.ui.visible', False) + >>> preferences.get('acme.ui.visible') + 'False' + +This is obviously not terribly convenient, and so the following section +discusses how we associate type information with our preferences to make +getting and setting them more natural. + +Preferences and Types +--------------------- + +As mentioned previously, we would like to be able to get and set non-string +preferences in a more convenient way. This is where the |PreferencesHelper| +class comes in. + +Let's take another look at 'example.ini':: + + [acme.ui] + bgcolor = blue + width = 50 + ratio = 1.0 + visible = True + + [acme.ui.splash_screen] + image = splash + fgcolor = red + +Say, I am interested in the preferences in the 'acme.ui' section. I can use a +preferences helper as follows:: + + from apptools.preferences.api import PreferencesHelper + + class SplashScreenPreferences(PreferencesHelper): + """ A preferences helper for the splash screen. """ + + preferences_path = 'acme.ui' + + bgcolor = Str + width = Int + ratio = Float + visible = Bool + + >>> preferences = Preferences(filename='example.ini') + >>> helper = SplashScreenPreferences(preferences=preferences) + >>> helper.bgcolor + 'blue' + >>> helper.width + 50 + >>> helper.ratio + 1.0 + >>> helper.visible + True + +And, obviously, I can set the value of the preferences via the helper too:: + + >>> helper.ratio = 0.5 + +And if you want to prove to yourself it really did set the preference:: + + >>> preferences.get('acme.ui.ratio') + '0.5' + +Using a preferences helper you also get notified via the usual trait +mechanism when the preferences are changed (either via the helper or via the +preferences node directly:: + + def listener(obj, trait_name, old, new): + print(trait_name, old, new) + + >>> helper.on_trait_change(listener) + >>> helper.ratio = 0.75 + ratio 0.5 0.75 + >>> preferences.set('acme.ui.ratio', 0.33) + ratio 0.75 0.33 + +Scoped Preferences +------------------ + +In many applications the idea of preferences scopes is useful. In a scoped +system, an actual preference value can be stored in any scope and when a call +is made to the 'get' method the scopes are searched in order of precedence. + +The default implementation (in the |ScopedPreferences| class) provides two +scopes by default: + +1) The application scope + +This scope stores itself in the 'ETSConfig.application_home' directory. This +scope is generally used when *setting* any user preferences. + +2) The default scope + +This scope is transient (i.e. it does not store itself anywhere). This scope +is generally used to load any predefined default values into the preferences +system. + +If you are happy with the default arrangement, then using the scoped +preferences is just like using the plain old non-scoped version:: + + >>> from apptools.preferences.api import ScopedPreferences + >>> preferences = ScopedPreferences(filename='example.ini') + >>> preferences.load('example.ini') + >>> preferences.dump() + + Node() {} + Node(application) {} + Node(acme) {} + Node(ui) {'bgcolor': 'blue', 'width': '50', 'ratio': '1.0', 'visible': 'True'} + Node(splash_screen) {'image': 'splash', 'fgcolor': 'red'} + Node(default) {} + +Here you can see that the root node now has a child node representing each +scope. + +When we are getting and setting preferences using scopes we generally want the +following behaviour: + +a) When we get a preference we want to look it up in each scope in order. The +first scope that contains a value 'wins'. + +b) When we set a preference, we want to set it in the first scope. By default +this means that when we set a preference it will be set in the application +scope. This is exactly what we want as the application scope is the scope that +is persistent. + +So usually, we just use the scoped preferences as before:: + + >>> preferences.get('acme.ui.bgcolor') + 'blue' + >>> preferences.set('acme.ui.bgcolor', 'red') + >>> preferences.dump() + + Node() {} + Node(application) {} + Node(acme) {} + Node(ui) {'bgcolor': 'red', 'width': '50', 'ratio': '1.0', 'visible': 'True'} + Node(splash_screen) {'image': 'splash', 'fgcolor': 'red'} + Node(default) {} + +And, conveniently, preference helpers work just the same with scoped +preferences too:: + + >>> helper = SplashScreenPreferences(preferences=preferences) + >>> helper.bgcolor + 'red' + >>> helper.width + 50 + >>> helper.ratio + 1.0 + >>> helper.visible + True + +Accessing a particular scope +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Should you care about getting or setting a preference in a particular scope +then you use the following syntax:: + + >>> preferences.set('default/acme.ui.bgcolor', 'red') + >>> preferences.get('default/acme.ui.bgcolor') + 'red' + >>> preferences.dump() + + Node() {} + Node(application) {} + Node(acme) {} + Node(ui) {'bgcolor': 'red', 'width': '50', 'ratio': '1.0', 'visible': 'True'} + Node(splash_screen) {'image': 'splash', 'fgcolor': 'red'} + Node(default) {} + Node(acme) {} + Node(ui) {'bgcolor': 'red'} + +You can also get hold of a scope via:: + + >>> default = preferences.get_scope('default') + +And then perform any of the usual operations on it. + +Further Reading +--------------- + +So that's a quick tour around the basic useage of the preferences API. For more +information about what is provided take a look at the :ref:`api-documentation`. + +If you are using Envisage to build your applications then you might also be +interested in the |Preferences in Envisage| section. + +.. + external links + +.. _ConfigObj: https://configobj.readthedocs.io/en/latest + +.. + # substitutions + +.. |ScopedPreferences| replace:: :class:`~apptools.preferences.scoped_preferences.ScopedPreferences` +.. |IPreferences| replace:: :class:`~apptools.preferences.i_preferences.IPreferences` +.. |Preferences| replace:: :class:`~apptools.preferences.preferences.Preferences` +.. |PreferencesHelper| replace:: :class:`~apptools.preferences.preferences_helper.PreferencesHelper` +.. |Preferences in Envisage| replace:: :ref:`preferences-in-envisage` diff --git a/5.0/_sources/preferences/PreferencesInEnvisage.rst.txt b/5.0/_sources/preferences/PreferencesInEnvisage.rst.txt new file mode 100644 index 000000000..931897eb6 --- /dev/null +++ b/5.0/_sources/preferences/PreferencesInEnvisage.rst.txt @@ -0,0 +1,52 @@ +.. _preferences-in-envisage: + +Preferences in Envisage +======================= + +This section discusses how an Envisage application uses the preferences +mechanism. Envisage tries not to dictate too much, and so this describes the +default behaviour, but you are free to override it as desired. + +Envisage uses the default implementation of the |ScopedPreferences| class which +is made available via the application's 'preferences' trait:: + + >>> application = Application(id='myapplication') + >>> application.preferences.set('acme.ui.bgcolor', 'yellow') + >>> application.preferences.get('acme.ui.bgcolor') + 'yellow' + +Hence, you use the Envisage preferences just like you would any other scoped +preferences. + +It also registers itself as the default preferences node used by the +|PreferencesHelper| class. Hence you don't need to provide a preferences node +explicitly to your helper:: + + >>> helper = SplashScreenPreferences() + >>> helper.bgcolor + 'blue' + >>> helper.width + 100 + >>> helper.ratio + 1.0 + >>> helper.visible + True + +The only extra thing that Envisage does for you is to provide an extension +point that allows you to contribute any number of '.ini' files that are +loaded into the default scope when the application is started. + +e.g. To contribute a preference file for my plugin I might use:: + + class MyPlugin(Plugin): + ... + + @contributes_to('envisage.preferences') + def get_preferences(self, application): + return ['pkgfile://mypackage:preferences.ini'] + +.. + # substitutions + +.. |PreferencesHelper| replace:: :class:`~apptools.preferences.preferences_helper.PreferencesHelper` +.. |ScopedPreferences| replace:: :class:`~apptools.preferences.scoped_preferences.ScopedPreferences` diff --git a/5.0/_sources/scripting/introduction.rst.txt b/5.0/_sources/scripting/introduction.rst.txt new file mode 100644 index 000000000..724a2767d --- /dev/null +++ b/5.0/_sources/scripting/introduction.rst.txt @@ -0,0 +1,198 @@ +.. _automatic-script-recording: + +Automatic script recording +=========================== + +This package provides a very handy and powerful Python script recording +facility. This can be used to: + + - record all actions performed on a traits based UI into a *human + readable*, Python script that should be able to recreate your UI + actions. + + - easily learn the scripting API of an application. + +This package is not just a toy framework and is powerful enough to +provide full script recording to the Mayavi_ application. Mayavi is a +powerful 3D visualization tool that is part of ETS_. + +.. _Mayavi: https://docs.enthought.com/mayavi/mayavi/ +.. _ETS: https://docs.enthought.com/ets/ + +.. _scripting-api: + + +The scripting API +------------------ + +The scripting API primarily allows you to record UI actions for objects +that have Traits. Technically the framework listens to all trait +changes so will work outside a UI. We do not document the full API +here, the best place to look for that is the +``apptools.scripting.recorder`` module which is reasonably well +documented. We provide a high level overview of the library. + +The quickest way to get started is to look at a small example. + + +.. _scripting-api-example: + +A tour by example +~~~~~~~~~~~~~~~~~~~ + +The following example is taken from the test suite. Consider a set of +simple objects organized in a hierarchy:: + + from traits.api import (HasTraits, Float, Instance, + Str, List, Bool, HasStrictTraits, Tuple, PrefixMap, Range, + Trait) + from apptools.scripting.api import (Recorder, recordable, + set_recorder) + + class Property(HasStrictTraits): + color = Tuple(Range(0.0, 1.0), Range(0.0, 1.0), Range(0.0, 1.0)) + opacity = Range(0.0, 1.0, 1.0) + representation = PrefixMap( + {"surface": 2, "wireframe": 1, "points": 0}, + default_value="surface" + ) + + class Toy(HasTraits): + color = Str + type = Str + # Note the use of the trait metadata to ignore this trait. + ignore = Bool(False, record=False) + + class Child(HasTraits): + name = Str('child') + age = Float(10.0) + # The recorder walks through sub-instances if they are marked + # with record=True + property = Instance(Property, (), record=True) + toy = Instance(Toy, record=True) + friends = List(Str) + + # The decorator records the method. + @recordable + def grow(self, x): + """Increase age by x years.""" + self.age += x + + class Parent(HasTraits): + children = List(Child, record=True) + recorder = Instance(Recorder, record=False) + +Using these simple classes we first create a simple object hierarchy as +follows:: + + p = Parent() + c = Child() + t = Toy() + c.toy = t + p.children.append(c) + +Given this hierarchy, we'd like to be able to record a script. To do +this we setup the recording infrastructure:: + + from mayavi.core.recorder import Recorder, set_recorder + # Create a recorder. + r = Recorder() + # Set the global recorder so the decorator works. + set_recorder(r) + r.register(p) + r.recording = True + +The key method here is the ``r.register(p)`` call above. It looks at +the traits of ``p`` and finds all traits and nested objects that specify +a ``record=True`` in their trait metadata (all methods starting and +ending with ``_`` are ignored). All sub-objects are in turn registered +with the recorder and so on. Callbacks are attached to traits changes +and these are wired up to produce readable and executable code. The +``set_recorder(r)`` call is also very important and sets the global +recorder so the framework listens to any functions that are decorated +with the ``recordable`` decorator. + +Now lets test this out like so:: + + # The following will be recorded. + c.name = 'Shiva' + c.property.representation = 'w' + c.property.opacity = 0.4 + c.grow(1) + +To see what's been recorded do this:: + + print(r.script) + +This prints:: + + child = parent.children[0] + child.name = 'Shiva' + child.property.representation = 'wireframe' + child.property.opacity = 0.40000000000000002 + child.grow(1) + +The recorder internally maintains a mapping between objects and unique +names for each object. It also stores the information about the +location of a particular object in the object hierarchy. For example, +the path to the ``Toy`` instance in the hierarchy above is +``parent.children[0].toy``. Since scripting with lists this way can be +tedious, the recorder first instantiates the ``child``:: + + child = parent.children[0] + +Subsequent lines use the ``child`` attribute. The recorder always tries +to instantiate the object referred to using its path information in this +manner. + +To record a function or method call one must simply decorate the +function/method with the ``recordable`` decorator. Nested recordable +functions are not recorded and trait changes are also not recorded if +done inside a recordable function. + +.. note:: + + 1. It is very important to note that the global recorder must be set + via the ``set_recorder`` method. The ``recordable`` decorator + relies on this being set to work. + + 2. The ``recordable`` decorator will work with plain Python classes + and with functions too. + +To stop recording do this:: + + r.unregister(p) + r.recording = False + +The ``r.unregister(p)`` reverses the ``r.register(p)`` call and +unregisters all nested objects as well. + + +.. _recorder-advanced-uses: + +Advanced use cases +~~~~~~~~~~~~~~~~~~~~ + +Here are a few advanced use cases. + + - The API also provides a ``RecorderWithUI`` class that provides a + simple user interface that prints the recorded script and allows the + user to save the script. + + - Sometimes it is not enough to just record trait changes, one may want + to pass an arbitrary string or command when recording is occurring. + To allow for this, if one defines a ``recorder`` trait on the object, + it is set to the current recorder. One can then use this recorder to + do whatever one wants. This is very convenient. + + - To ignore specific traits one must specify either a ``record=False`` + metadata to the trait definition or specify a list of strings to the + ``register`` method in the ``ignore`` keyword argument. + + - If you want to use a specific name for an object on the script you + can pass the ``script_id`` parameter to the register function. + + +For more details on the recorder itself we suggest reading the module +source code. It is fairly well documented and with the above background +should be enough to get you going. diff --git a/5.0/_sources/selection/selection.rst.txt b/5.0/_sources/selection/selection.rst.txt new file mode 100644 index 000000000..a57d9179e --- /dev/null +++ b/5.0/_sources/selection/selection.rst.txt @@ -0,0 +1,144 @@ +.. _selection_service: + +The selection service +===================== + +It is quite common in GUI applications to have a UI element displaying a +collection of items that a user can select ("selection providers"), while +other parts of the application must react to changes in the selection +("selection listeners"). + +Ideally, the listeners would not have a direct dependency on the UI object. +This is especially important in extensible `envisage`_ applications, where +a plugin might need to react to a selection change, but we do not want to +expose the internal organization of the application to external developers. + +This package defines a selection service that manages the communication +between providers and listener. + + +The :class:`~.SelectionService` object +-------------------------------------- + +The :class:`~.SelectionService` object is the central manager that handles +the communication between selection providers and listener. + +:ref:`Selection providers ` are components that wish to +publish information about their current selection for public consumption. +They register to a selection +service instance when they first have a selection available (e.g., when the +UI showing a list of selectable items is initialized), and un-register as soon +as the selection is not available anymore (e.g., the UI is destroyed when the +windows is closed). + +:ref:`Selection listeners ` can query the selection +service to get the current selection published by a provider, using the +provider unique ID. + +The service acts as a broker between providers and listeners, making sure that +they are notified when the +:attr:`~apptools.selection.i_selection_provider.ISelectionProvider.selection` +event is fired. + +.. _selection_providers: + +Selection providers +------------------- + +Any object can become a selection provider by implementing the +:class:`~apptools.selection.i_selection_provider.ISelectionProvider` +interface, and registering to the selection service. + +Selection providers must provide a unique ID +:attr:`~apptools.selection.i_selection_provider.ISelectionProvider.provider_id`, +which is used by listeners to request its current selection. + +Whenever its selection changes, providers fire a +:attr:`~apptools.selection.i_selection_provider.ISelectionProvider.selection` +event. The content of the event is an instance implementing +:class:`~.ISelection` that contains information about the selected items. +For example, a :class:`~.ListSelection` object contains a list of selected +items, and their indices. + +Selection providers can also be queried directly about their current selection +using the +:attr:`~apptools.selection.i_selection_provider.ISelectionProvider.get_selection` +method, and can be requested to change their selection to a new one with the +:attr:`~apptools.selection.i_selection_provider.ISelectionProvider.set_selection` +method. + +Registration +~~~~~~~~~~~~ + +Selection providers publish their selection by registering to the selection +service using the +:attr:`~apptools.selection.selection_service.SelectionService.add_selection_provider` +method. When the selection is no longer available, selection providers +should un-register through +:attr:`~apptools.selection.selection_service.SelectionService.remove_selection_provider`. + +Typically, selection providers are UI objects showing a list or tree of items, +they register as soon as the UI component is initialized, and un-register +when the UI component disappears (e.g., because their window has been closed). +In more complex applications, the registration could be done by a controller +object instead. + +.. _selection_listeners: + +Selection listeners +------------------- + +Selection listeners request information regarding the current selection +of a selection provider given their provider ID. The :class:`~.SelectionService` +supports two distinct use cases: + + 1) Passively listening to selection changes: listener connect to a specific + provider and are notified when the provider's selection changes. + + 2) Actively querying a provider for its current selection: the selection + service can be used to query a provider using its unique ID. + +Passive listening +~~~~~~~~~~~~~~~~~ + +Listeners connect to the selection events for a given provider using the +:attr:`~apptools.selection.selection_service.SelectionService.connect_selection_listener` +method. They need to provide the unique ID of the provider, and a function +(or callable) that is called to send the event. This callback function takes +one argument, an implementation of the :class:`~.ISelection` that represents +the selection. + +It is possible for a listener to connect to a provider ID before it is +registered. As soon as the provider is registered, the listener will receive +a notification containing the provider's initial selection. + +To disconnect a listener use the methods +:attr:`~apptools.selection.selection_service.SelectionService.disconnect_selection_listener`. + +Active querying +~~~~~~~~~~~~~~~ + +In other instances, an element of the application only needs the current +selection at a specific time. For example, a toolbar button could open dialog +representing a user action based on what is currently selected in the active +editor. + +The +:attr:`~apptools.selection.selection_service.SelectionService.get_selection` +method calls the corresponding method on the provider with the given ID and +returns an :class:`~.ISelection` instance. + +Setting a selection +~~~~~~~~~~~~~~~~~~~ + +Finally, it is possible to request a provider to set its selection to a given +set of objects with +:attr:`~apptools.selection.selection_service.SelectionService.set_selection`. +The main use case for this method is multiple views of the same list of +objects, which need to keep their selection synchronized. + +If the items specified in the arguments are not available in the provider, +a :class:`~apptools.selection.errors.ProviderNotRegisteredError` is raised, +unless the optional keyword argument :attr:`ignore_missing` is set to ``True``. + +.. _envisage: http://docs.enthought.com/envisage/ diff --git a/5.0/_sources/undo/Introduction.rst.txt b/5.0/_sources/undo/Introduction.rst.txt new file mode 100644 index 000000000..89dee28d6 --- /dev/null +++ b/5.0/_sources/undo/Introduction.rst.txt @@ -0,0 +1,275 @@ +Undo Framework +============== + +The Undo Framework is a component of the Enthought Tool Suite that provides +developers with an API that implements the standard pattern for do/undo/redo +commands. + +The framework is completely configurable. Alternate implementations of all +major components can be provided if necessary. + + +Framework Concepts +------------------ + +The following are the concepts supported by the framework. + +- Command + + A command is an application defined operation that can be done (i.e. + executed), undone (i.e. reverted) and redone (i.e. repeated). + + A command operates on some data and maintains sufficient state to allow it to + revert or repeat a change to the data. + + Commands may be merged so that potentially long sequences of similar + commands (e.g. to add a character to some text) can be collapsed into a + single command (e.g. to add a word to some text). + +- Macro + + A macro is a sequence of commands that is treated as a single command when + being undone or redone. + +- Command Stack + + A command is done by pushing it onto a command stack. The last command can + be undone and redone by calling appropriate command stack methods. It is + also possible to move the stack's position to any point and the command stack + will ensure that commands are undone or redone as required. + + A command stack maintains a *clean* state which is updated as commands are + done and undone. It may be explicitly set, for example when the data being + manipulated by the commands is saved to disk. + + Canned PyFace actions are provided as wrappers around command stack methods + to implement common menu items. + +- Undo Manager + + An undo manager is responsible for one or more command stacks and maintains + a reference to the currently active stack. It provides convenience undo and + redo methods that operate on the currently active stack. + + An undo manager ensures that each command execution is allocated a unique + sequence number, irrespective of which command stack it is pushed to. Using + this it is possible to synchronise multiple command stacks and restore them + to a particular point in time. + + An undo manager will generate an event whenever the clean state of the active + stack changes. This can be used to maintain some sort of GUI status + indicator to tell the user that their data has been modified since it was + last saved. + +Typically an application will have one undo manager and one undo stack for +each data type that can be edited. However this is not a requirement: how the +command stack's in particular are organised and linked (with the user +manager's sequence number) can need careful thought so as not to confuse the +user - particularly in a plugin based application that may have many editors. + +To support this typical usage the PyFace ``Workbench`` class has an +``undo_manager`` trait and the PyFace ``Editor`` class has a ``command_stack`` +trait. Both are lazy loaded so can be completely ignored if they are not used. + + +API Overview +------------ + +This section gives a brief overview of the various classes implemented in the +framework. The complete API_ documentation is available as endo generated +HTML. + +The example_ application demonstrates all the major features of the framework. + + +UndoManager +........... + +The ``UndoManager`` class is the default implementation of the ``IUndoManager`` +interface. + +``active_stack`` + This trait is a reference to the currently active command stack and may be + None. Typically it is set when some sort of editor becomes active. + +``active_stack_clean`` + This boolean trait reflects the clean state of the currently active + command stack. It is intended to support a "document modified" indicator + in the GUI. It is maintained by the undo manager. + +``stack_updated`` + This event is fired when the index of a command stack is changed. A + reference to the stack is passed as an argument to the event and may not + be the currently active stack. + +``undo_name`` + This Str trait is the name of the command that can be undone, and will + be empty if there is no such command. It is maintained by the undo + manager. + +``redo_name`` + This Str trait is the name of the command that can be redone, and will + be empty if there is no such command. It is maintained by the undo + manager. + +``sequence_nr`` + This integer trait is the sequence number of the next command to be + executed. It is incremented immediately before a command's ``do()`` + method is called. A particular sequence number identifies the state of + all command stacks handled by the undo manager and allows those stacks to + be set to the point they were at at a particular point in time. In other + words, the sequence number allows otherwise independent command stacks to + be synchronised. + +``undo()`` + This method calls the ``undo()`` method of the last command on the active + command stack. + +``redo()`` + This method calls the ``redo()`` method of the last undone command on the + active command stack. + + +CommandStack +............ + +The ``CommandStack`` class is the default implementation of the +``ICommandStack`` interface. + +``clean`` + This boolean traits reflects the clean state of the command stack. Its + value changes as commands are executed, undone and redone. It may also be + explicitly set to mark the current stack position as being clean (when + data is saved to disk for example). + +``undo_name`` + This Str trait is the name of the command that can be undone, and will + be empty if there is no such command. It is maintained by the command + stack. + +``redo_name`` + This Str trait is the name of the command that can be redone, and will + be empty if there is no such command. It is maintained by the command + stack. + +``undo_manager`` + This trait is a reference to the undo manager that manages the command + stack. + +``push(command)`` + This method executes the given command by calling its ``do()`` method. + Any value returned by ``do()`` is returned by ``push()``. If the command + couldn't be merged with the previous one then it is saved on the command + stack. + +``undo(sequence_nr=0)`` + This method undoes the last command. If a sequence number is given then + all commands are undone up to an including the sequence number. + +``redo(sequence_nr=0)`` + This method redoes the last command and returns any result. If a sequence + number is given then all commands are redone up to an including the + sequence number and any result of the last of these is returned. + +``clear()`` + This method clears the command stack, without undoing or redoing any + commands, and leaves the stack in a clean state. It is typically used + when all changes to the data have been abandoned. + +``begin_macro(name)`` + This method begins a macro by creating an empty command with the given + name. The commands passed to all subsequent calls to ``push()`` will be + contained in the macro until the next call to ``end_macro()``. Macros may + be nested. The command stack is disabled (ie. nothing can be undone or + redone) while a macro is being created (ie. while there is an outstanding + ``end_macro()`` call). + +``end_macro()`` + This method ends the current macro. + + +ICommand +........ + +The ``ICommand`` interface defines the interface that must be implemented by +any undoable/redoable command. + +``data`` + This optional trait is a reference to the data object that the command + operates on. It is not used by the framework itself. + +``name`` + This Str trait is the name of the command as it will appear in any GUI + element (e.g. in the text of an undo and redo menu entry). It may include + ``&`` to indicate a keyboard shortcut which will be automatically removed + whenever it is inappropriate. + +``__init__(*args)`` + If the command takes arguments then the command must ensure that deep + copies should be made if appropriate. + +``do()`` + This method is called by a command stack to execute the command and to + return any result. The command must save any state necessary for the + ``undo()`` and ``redo()`` methods to work. It is guaranteed that this + will only ever be called once and that it will be called before any call + to ``undo()`` or ``redo()``. + +``undo()`` + This method is called by a command stack to undo the command. + +``redo()`` + This method is called by a command stack to redo the command and to return + any result. + +``merge(other)`` + This method is called by the command stack to try and merge the ``other`` + command with this one. True should be returned if the commands were + merged. If the commands are merged then ``other`` will not be placed on + the command stack. A subsequent undo or redo of this modified command + must have the same effect as the two original commands. + + +AbstractCommand +............... + +``AbstractCommand`` is an abstract base class that implements the ``ICommand`` +interface. It provides a default implementation of the ``merge()`` method. + + +CommandAction +............. + +The ``CommandAction`` class is a sub-class of the PyFace ``Action`` class that +is used to wrap commands. + +``command`` + This callable trait must be set to a factory that will return an object + that implements ``ICommand``. It will be called when the action is invoked + and the object created pushed onto the command stack. + +``command_stack`` + This instance trait must be set to the command stack that commands invoked + by the action are pushed to. + +``data`` + This optional trait is a reference to the data object that will be passed + to the ``command`` factory when it is called. + + +UndoAction +.......... + +The ``UndoAction`` class is a canned PyFace action that undoes the last +command of the active command stack. + + +RedoAction +.......... + +The ``RedoAction`` class is a canned PyFace action that redoes the last +command undone of the active command stack. + + +.. _API: api/index.html +.. _example: https://svn.enthought.com/enthought/browser/AppTools/trunk/examples/undo/ diff --git a/5.0/_static/basic.css b/5.0/_static/basic.css new file mode 100644 index 000000000..b04360d69 --- /dev/null +++ b/5.0/_static/basic.css @@ -0,0 +1,768 @@ +/* + * basic.css + * ~~~~~~~~~ + * + * Sphinx stylesheet -- basic theme. + * + * :copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ + +/* -- main layout ----------------------------------------------------------- */ + +div.clearer { + clear: both; +} + +/* -- relbar ---------------------------------------------------------------- */ + +div.related { + width: 100%; + font-size: 90%; +} + +div.related h3 { + display: none; +} + +div.related ul { + margin: 0; + padding: 0 0 0 10px; + list-style: none; +} + +div.related li { + display: inline; +} + +div.related li.right { + float: right; + margin-right: 5px; +} + +/* -- sidebar --------------------------------------------------------------- */ + +div.sphinxsidebarwrapper { + padding: 10px 5px 0 10px; +} + +div.sphinxsidebar { + float: left; + width: 230px; + margin-left: -100%; + font-size: 90%; + word-wrap: break-word; + overflow-wrap : break-word; +} + +div.sphinxsidebar ul { + list-style: none; +} + +div.sphinxsidebar ul ul, +div.sphinxsidebar ul.want-points { + margin-left: 20px; + list-style: square; +} + +div.sphinxsidebar ul ul { + margin-top: 0; + margin-bottom: 0; +} + +div.sphinxsidebar form { + margin-top: 10px; +} + +div.sphinxsidebar input { + border: 1px solid #98dbcc; + font-family: sans-serif; + font-size: 1em; +} + +div.sphinxsidebar #searchbox form.search { + overflow: hidden; +} + +div.sphinxsidebar #searchbox input[type="text"] { + float: left; + width: 80%; + padding: 0.25em; + box-sizing: border-box; +} + +div.sphinxsidebar #searchbox input[type="submit"] { + float: left; + width: 20%; + border-left: none; + padding: 0.25em; + box-sizing: border-box; +} + + +img { + border: 0; + max-width: 100%; +} + +/* -- search page ----------------------------------------------------------- */ + +ul.search { + margin: 10px 0 0 20px; + padding: 0; +} + +ul.search li { + padding: 5px 0 5px 20px; + background-image: url(file.png); + background-repeat: no-repeat; + background-position: 0 7px; +} + +ul.search li a { + font-weight: bold; +} + +ul.search li div.context { + color: #888; + margin: 2px 0 0 30px; + text-align: left; +} + +ul.keywordmatches li.goodmatch a { + font-weight: bold; +} + +/* -- index page ------------------------------------------------------------ */ + +table.contentstable { + width: 90%; + margin-left: auto; + margin-right: auto; +} + +table.contentstable p.biglink { + line-height: 150%; +} + +a.biglink { + font-size: 1.3em; +} + +span.linkdescr { + font-style: italic; + padding-top: 5px; + font-size: 90%; +} + +/* -- general index --------------------------------------------------------- */ + +table.indextable { + width: 100%; +} + +table.indextable td { + text-align: left; + vertical-align: top; +} + +table.indextable ul { + margin-top: 0; + margin-bottom: 0; + list-style-type: none; +} + +table.indextable > tbody > tr > td > ul { + padding-left: 0em; +} + +table.indextable tr.pcap { + height: 10px; +} + +table.indextable tr.cap { + margin-top: 10px; + background-color: #f2f2f2; +} + +img.toggler { + margin-right: 3px; + margin-top: 3px; + cursor: pointer; +} + +div.modindex-jumpbox { + border-top: 1px solid #ddd; + border-bottom: 1px solid #ddd; + margin: 1em 0 1em 0; + padding: 0.4em; +} + +div.genindex-jumpbox { + border-top: 1px solid #ddd; + border-bottom: 1px solid #ddd; + margin: 1em 0 1em 0; + padding: 0.4em; +} + +/* -- domain module index --------------------------------------------------- */ + +table.modindextable td { + padding: 2px; + border-collapse: collapse; +} + +/* -- general body styles --------------------------------------------------- */ + +div.body { + min-width: 450px; + max-width: 800px; +} + +div.body p, div.body dd, div.body li, div.body blockquote { + -moz-hyphens: auto; + -ms-hyphens: auto; + -webkit-hyphens: auto; + hyphens: auto; +} + +a.headerlink { + visibility: hidden; +} + +a.brackets:before, +span.brackets > a:before{ + content: "["; +} + +a.brackets:after, +span.brackets > a:after { + content: "]"; +} + +h1:hover > a.headerlink, +h2:hover > a.headerlink, +h3:hover > a.headerlink, +h4:hover > a.headerlink, +h5:hover > a.headerlink, +h6:hover > a.headerlink, +dt:hover > a.headerlink, +caption:hover > a.headerlink, +p.caption:hover > a.headerlink, +div.code-block-caption:hover > a.headerlink { + visibility: visible; +} + +div.body p.caption { + text-align: inherit; +} + +div.body td { + text-align: left; +} + +.first { + margin-top: 0 !important; +} + +p.rubric { + margin-top: 30px; + font-weight: bold; +} + +img.align-left, .figure.align-left, object.align-left { + clear: left; + float: left; + margin-right: 1em; +} + +img.align-right, .figure.align-right, object.align-right { + clear: right; + float: right; + margin-left: 1em; +} + +img.align-center, .figure.align-center, object.align-center { + display: block; + margin-left: auto; + margin-right: auto; +} + +img.align-default, .figure.align-default { + display: block; + margin-left: auto; + margin-right: auto; +} + +.align-left { + text-align: left; +} + +.align-center { + text-align: center; +} + +.align-default { + text-align: center; +} + +.align-right { + text-align: right; +} + +/* -- sidebars -------------------------------------------------------------- */ + +div.sidebar { + margin: 0 0 0.5em 1em; + border: 1px solid #ddb; + padding: 7px 7px 0 7px; + background-color: #ffe; + width: 40%; + float: right; +} + +p.sidebar-title { + font-weight: bold; +} + +/* -- topics ---------------------------------------------------------------- */ + +div.topic { + border: 1px solid #ccc; + padding: 7px 7px 0 7px; + margin: 10px 0 10px 0; +} + +p.topic-title { + font-size: 1.1em; + font-weight: bold; + margin-top: 10px; +} + +/* -- admonitions ----------------------------------------------------------- */ + +div.admonition { + margin-top: 10px; + margin-bottom: 10px; + padding: 7px; +} + +div.admonition dt { + font-weight: bold; +} + +div.admonition dl { + margin-bottom: 0; +} + +p.admonition-title { + margin: 0px 10px 5px 0px; + font-weight: bold; +} + +div.body p.centered { + text-align: center; + margin-top: 25px; +} + +/* -- tables ---------------------------------------------------------------- */ + +table.docutils { + border: 0; + border-collapse: collapse; +} + +table.align-center { + margin-left: auto; + margin-right: auto; +} + +table.align-default { + margin-left: auto; + margin-right: auto; +} + +table caption span.caption-number { + font-style: italic; +} + +table caption span.caption-text { +} + +table.docutils td, table.docutils th { + padding: 1px 8px 1px 5px; + border-top: 0; + border-left: 0; + border-right: 0; + border-bottom: 1px solid #aaa; +} + +table.footnote td, table.footnote th { + border: 0 !important; +} + +th { + text-align: left; + padding-right: 5px; +} + +table.citation { + border-left: solid 1px gray; + margin-left: 1px; +} + +table.citation td { + border-bottom: none; +} + +th > p:first-child, +td > p:first-child { + margin-top: 0px; +} + +th > p:last-child, +td > p:last-child { + margin-bottom: 0px; +} + +/* -- figures --------------------------------------------------------------- */ + +div.figure { + margin: 0.5em; + padding: 0.5em; +} + +div.figure p.caption { + padding: 0.3em; +} + +div.figure p.caption span.caption-number { + font-style: italic; +} + +div.figure p.caption span.caption-text { +} + +/* -- field list styles ----------------------------------------------------- */ + +table.field-list td, table.field-list th { + border: 0 !important; +} + +.field-list ul { + margin: 0; + padding-left: 1em; +} + +.field-list p { + margin: 0; +} + +.field-name { + -moz-hyphens: manual; + -ms-hyphens: manual; + -webkit-hyphens: manual; + hyphens: manual; +} + +/* -- hlist styles ---------------------------------------------------------- */ + +table.hlist td { + vertical-align: top; +} + + +/* -- other body styles ----------------------------------------------------- */ + +ol.arabic { + list-style: decimal; +} + +ol.loweralpha { + list-style: lower-alpha; +} + +ol.upperalpha { + list-style: upper-alpha; +} + +ol.lowerroman { + list-style: lower-roman; +} + +ol.upperroman { + list-style: upper-roman; +} + +li > p:first-child { + margin-top: 0px; +} + +li > p:last-child { + margin-bottom: 0px; +} + +dl.footnote > dt, +dl.citation > dt { + float: left; +} + +dl.footnote > dd, +dl.citation > dd { + margin-bottom: 0em; +} + +dl.footnote > dd:after, +dl.citation > dd:after { + content: ""; + clear: both; +} + +dl.field-list { + display: grid; + grid-template-columns: fit-content(30%) auto; +} + +dl.field-list > dt { + font-weight: bold; + word-break: break-word; + padding-left: 0.5em; + padding-right: 5px; +} + +dl.field-list > dt:after { + content: ":"; +} + +dl.field-list > dd { + padding-left: 0.5em; + margin-top: 0em; + margin-left: 0em; + margin-bottom: 0em; +} + +dl { + margin-bottom: 15px; +} + +dd > p:first-child { + margin-top: 0px; +} + +dd ul, dd table { + margin-bottom: 10px; +} + +dd { + margin-top: 3px; + margin-bottom: 10px; + margin-left: 30px; +} + +dt:target, span.highlighted { + background-color: #fbe54e; +} + +rect.highlighted { + fill: #fbe54e; +} + +dl.glossary dt { + font-weight: bold; + font-size: 1.1em; +} + +.optional { + font-size: 1.3em; +} + +.sig-paren { + font-size: larger; +} + +.versionmodified { + font-style: italic; +} + +.system-message { + background-color: #fda; + padding: 5px; + border: 3px solid red; +} + +.footnote:target { + background-color: #ffa; +} + +.line-block { + display: block; + margin-top: 1em; + margin-bottom: 1em; +} + +.line-block .line-block { + margin-top: 0; + margin-bottom: 0; + margin-left: 1.5em; +} + +.guilabel, .menuselection { + font-family: sans-serif; +} + +.accelerator { + text-decoration: underline; +} + +.classifier { + font-style: oblique; +} + +.classifier:before { + font-style: normal; + margin: 0.5em; + content: ":"; +} + +abbr, acronym { + border-bottom: dotted 1px; + cursor: help; +} + +/* -- code displays --------------------------------------------------------- */ + +pre { + overflow: auto; + overflow-y: hidden; /* fixes display issues on Chrome browsers */ +} + +span.pre { + -moz-hyphens: none; + -ms-hyphens: none; + -webkit-hyphens: none; + hyphens: none; +} + +td.linenos pre { + padding: 5px 0px; + border: 0; + background-color: transparent; + color: #aaa; +} + +table.highlighttable { + margin-left: 0.5em; +} + +table.highlighttable td { + padding: 0 0.5em 0 0.5em; +} + +div.code-block-caption { + padding: 2px 5px; + font-size: small; +} + +div.code-block-caption code { + background-color: transparent; +} + +div.code-block-caption + div > div.highlight > pre { + margin-top: 0; +} + +div.doctest > div.highlight span.gp { /* gp: Generic.Prompt */ + user-select: none; +} + +div.code-block-caption span.caption-number { + padding: 0.1em 0.3em; + font-style: italic; +} + +div.code-block-caption span.caption-text { +} + +div.literal-block-wrapper { + padding: 1em 1em 0; +} + +div.literal-block-wrapper div.highlight { + margin: 0; +} + +code.descname { + background-color: transparent; + font-weight: bold; + font-size: 1.2em; +} + +code.descclassname { + background-color: transparent; +} + +code.xref, a code { + background-color: transparent; + font-weight: bold; +} + +h1 code, h2 code, h3 code, h4 code, h5 code, h6 code { + background-color: transparent; +} + +.viewcode-link { + float: right; +} + +.viewcode-back { + float: right; + font-family: sans-serif; +} + +div.viewcode-block:target { + margin: -1px -10px; + padding: 0 10px; +} + +/* -- math display ---------------------------------------------------------- */ + +img.math { + vertical-align: middle; +} + +div.body div.math p { + text-align: center; +} + +span.eqno { + float: right; +} + +span.eqno a.headerlink { + position: relative; + left: 0px; + z-index: 1; +} + +div.math:hover a.headerlink { + visibility: visible; +} + +/* -- printout stylesheet --------------------------------------------------- */ + +@media print { + div.document, + div.documentwrapper, + div.bodywrapper { + margin: 0 !important; + width: 100%; + } + + div.sphinxsidebar, + div.related, + div.footer, + #top-link { + display: none; + } +} \ No newline at end of file diff --git a/5.0/_static/css/pygments.css b/5.0/_static/css/pygments.css new file mode 100644 index 000000000..1c9c56a51 --- /dev/null +++ b/5.0/_static/css/pygments.css @@ -0,0 +1,87 @@ +/* Styling for the source code listings: (mostly from pygments)*/ + +.highlight pre{ + overflow: auto; + padding: 5px; + background-color: #ffffff; + color: #333333; + border: 1px solid #ac9; + border-left: none; + border-right: none; +} + +/* Styling for pre elements: from http://perishablepress.com/press/2009/11/09/perfect-pre-tags/ */ +/* no vertical scrollbars for IE 6 */ +* html pre { + padding-bottom:25px; + overflow-y:hidden; + overflow:visible; + overflow-x:auto +} +/* no vertical scrollbars for IE 7 */ +*:first-child+html pre { + padding-bottom:25px; + overflow-y:hidden; + overflow:visible; + overflow-x:auto +} + +div#spc-section-body td.linenos pre { + padding: 5px 0px; + border: 0; + background-color: transparent; + color: #aaa; +} +.highlight .hll { background-color: #ffffcc } +.highlight { background: #ffffff; } +.highlight .c { color: #008000 } /* Comment */ +.highlight .k { color: #000080; font-weight: bold } /* Keyword */ +.highlight .n { color: #000000 } /* Name */ +.highlight .o { color: #000000 } /* Operator */ +.highlight .cm { color: #008000 } /* Comment.Multiline */ +.highlight .cp { color: #008000 } /* Comment.Preproc */ +.highlight .c1 { color: #008000 } /* Comment.Single */ +.highlight .cs { color: #008000 } /* Comment.Special */ +.highlight .kc { color: #000080; font-weight: bold } /* Keyword.Constant */ +.highlight .kd { color: #000080; font-weight: bold } /* Keyword.Declaration */ +.highlight .kn { color: #000080; font-weight: bold } /* Keyword.Namespace */ +.highlight .kp { color: #000080; font-weight: bold } /* Keyword.Pseudo */ +.highlight .kr { color: #000080; font-weight: bold } /* Keyword.Reserved */ +.highlight .kt { color: #000080; font-weight: bold } /* Keyword.Type */ +.highlight .m { color: #008080 } /* Literal.Number */ +.highlight .s { color: #800080 } /* Literal.String */ +.highlight .na { color: #000000 } /* Name.Attribute */ +.highlight .nb { color: #407090 } /* Name.Builtin */ +.highlight .nc { color: #0000F0; font-weight: bold } /* Name.Class */ +.highlight .no { color: #000000 } /* Name.Constant */ +.highlight .nd { color: #000000 } /* Name.Decorator */ +.highlight .ni { color: #000000 } /* Name.Entity */ +.highlight .ne { color: #000000 } /* Name.Exception */ +.highlight .nf { color: #008080; font-weight: bold } /* Name.Function */ +.highlight .nl { color: #000000 } /* Name.Label */ +.highlight .nn { color: #000000 } /* Name.Namespace */ +.highlight .nx { color: #000000 } /* Name.Other */ +.highlight .py { color: #000000 } /* Name.Property */ +.highlight .nt { color: #000000 } /* Name.Tag */ +.highlight .nv { color: #000000 } /* Name.Variable */ +.highlight .ow { color: #AA22FF; font-weight: bold } /* Operator.Word */ +.highlight .mf { color: #008080 } /* Literal.Number.Float */ +.highlight .mh { color: #008080 } /* Literal.Number.Hex */ +.highlight .mi { color: #008080 } /* Literal.Number.Integer */ +.highlight .mo { color: #008080 } /* Literal.Number.Oct */ +.highlight .sb { color: #800080 } /* Literal.String.Backtick */ +.highlight .sc { color: #800080 } /* Literal.String.Char */ +.highlight .sd { color: #800000 } /* Literal.String.Doc */ +.highlight .s2 { color: #800080 } /* Literal.String.Double */ +.highlight .se { color: #800080 } /* Literal.String.Escape */ +.highlight .sh { color: #800080 } /* Literal.String.Heredoc */ +.highlight .si { color: #800080 } /* Literal.String.Interpol */ +.highlight .sx { color: #800080 } /* Literal.String.Other */ +.highlight .sr { color: #800080 } /* Literal.String.Regex */ +.highlight .s1 { color: #800080 } /* Literal.String.Single */ +.highlight .ss { color: #800080 } /* Literal.String.Symbol */ +.highlight .bp { color: #407090 } /* Name.Builtin.Pseudo */ +.highlight .vc { color: #000000 } /* Name.Variable.Class */ +.highlight .vg { color: #000000 } /* Name.Variable.Global */ +.highlight .vi { color: #000000 } /* Name.Variable.Instance */ +.highlight .il { color: #008080 } /* Literal.Number.Integer.Long */ diff --git a/5.0/_static/css/spc-bootstrap.css b/5.0/_static/css/spc-bootstrap.css new file mode 100644 index 000000000..9895e61fe --- /dev/null +++ b/5.0/_static/css/spc-bootstrap.css @@ -0,0 +1,6288 @@ +/*! + * Bootstrap v2.3.1 + * + * Copyright 2012 Twitter, Inc + * Licensed under the Apache License v2.0 + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Designed and built with all the love in the world @twitter by @mdo and @fat. + */ +.clearfix { + *zoom: 1; +} +.clearfix:before, +.clearfix:after { + display: table; + content: ""; + line-height: 0; +} +.clearfix:after { + clear: both; +} +.hide-text { + font: 0/0 a; + color: transparent; + text-shadow: none; + background-color: transparent; + border: 0; +} +.input-block-level { + display: block; + width: 100%; + min-height: 31px; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} +article, +aside, +details, +figcaption, +figure, +footer, +header, +hgroup, +nav, +section { + display: block; +} +audio, +canvas, +video { + display: inline-block; + *display: inline; + *zoom: 1; +} +audio:not([controls]) { + display: none; +} +html { + font-size: 100%; + -webkit-text-size-adjust: 100%; + -ms-text-size-adjust: 100%; +} +a:focus { + outline: thin dotted #333; + outline: 5px auto -webkit-focus-ring-color; + outline-offset: -2px; +} +a:hover, +a:active { + outline: 0; +} +sub, +sup { + position: relative; + font-size: 75%; + line-height: 0; + vertical-align: baseline; +} +sup { + top: -0.5em; +} +sub { + bottom: -0.25em; +} +img { + /* Responsive images (ensure images don't scale beyond their parents) */ + max-width: 100%; + /* Part 1: Set a maxium relative to the parent */ + width: auto\9; + /* IE7-8 need help adjusting responsive images */ + height: auto; + /* Part 2: Scale the height according to the width, otherwise you get stretching */ + vertical-align: middle; + border: 0; + -ms-interpolation-mode: bicubic; +} +#map_canvas img, +.google-maps img { + max-width: none; +} +button, +input, +select, +textarea { + margin: 0; + font-size: 100%; + vertical-align: middle; +} +button, +input { + *overflow: visible; + line-height: normal; +} +button::-moz-focus-inner, +input::-moz-focus-inner { + padding: 0; + border: 0; +} +button, +html input[type="button"], +input[type="reset"], +input[type="submit"] { + -webkit-appearance: button; + cursor: pointer; +} +label, +select, +button, +input[type="button"], +input[type="reset"], +input[type="submit"], +input[type="radio"], +input[type="checkbox"] { + cursor: pointer; +} +input[type="search"] { + -webkit-box-sizing: content-box; + -moz-box-sizing: content-box; + box-sizing: content-box; + -webkit-appearance: textfield; +} +input[type="search"]::-webkit-search-decoration, +input[type="search"]::-webkit-search-cancel-button { + -webkit-appearance: none; +} +textarea { + overflow: auto; + vertical-align: top; +} +@media print { + * { + text-shadow: none !important; + color: #000 !important; + background: transparent !important; + box-shadow: none !important; + } + a, + a:visited { + text-decoration: underline; + } + a[href]:after { + content: " (" attr(href) ")"; + } + abbr[title]:after { + content: " (" attr(title) ")"; + } + .ir a:after, + a[href^="javascript:"]:after, + a[href^="#"]:after { + content: ""; + } + pre, + blockquote { + border: 1px solid #999; + page-break-inside: avoid; + } + thead { + display: table-header-group; + } + tr, + img { + page-break-inside: avoid; + } + img { + max-width: 100% !important; + } + @page { + margin: 0.5cm; + } + p, + h2, + h3 { + orphans: 3; + widows: 3; + } + h2, + h3 { + page-break-after: avoid; + } +} +body { + margin: 0; + font-family: 'Source Sans Pro', sans-serif; + font-size: 16px; + line-height: 21px; + color: #333333; + background-color: #ffffff; +} +a { + color: #0088cc; + text-decoration: none; +} +a:hover, +a:focus { + color: #005580; + text-decoration: underline; +} +.img-rounded { + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; +} +.img-polaroid { + padding: 4px; + background-color: #fff; + border: 1px solid #ccc; + border: 1px solid rgba(0, 0, 0, 0.2); + -webkit-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); + -moz-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); + box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); +} +.img-circle { + -webkit-border-radius: 500px; + -moz-border-radius: 500px; + border-radius: 500px; +} +.row { + margin-left: -20px; + *zoom: 1; +} +.row:before, +.row:after { + display: table; + content: ""; + line-height: 0; +} +.row:after { + clear: both; +} +[class*="span"] { + float: left; + min-height: 1px; + margin-left: 20px; +} +.container, +.navbar-static-top .container, +.navbar-fixed-top .container, +.navbar-fixed-bottom .container { + width: 940px; +} +.span12 { + width: 940px; +} +.span11 { + width: 860px; +} +.span10 { + width: 780px; +} +.span9 { + width: 700px; +} +.span8 { + width: 620px; +} +.span7 { + width: 540px; +} +.span6 { + width: 460px; +} +.span5 { + width: 380px; +} +.span4 { + width: 300px; +} +.span3 { + width: 220px; +} +.span2 { + width: 140px; +} +.span1 { + width: 60px; +} +.offset12 { + margin-left: 980px; +} +.offset11 { + margin-left: 900px; +} +.offset10 { + margin-left: 820px; +} +.offset9 { + margin-left: 740px; +} +.offset8 { + margin-left: 660px; +} +.offset7 { + margin-left: 580px; +} +.offset6 { + margin-left: 500px; +} +.offset5 { + margin-left: 420px; +} +.offset4 { + margin-left: 340px; +} +.offset3 { + margin-left: 260px; +} +.offset2 { + margin-left: 180px; +} +.offset1 { + margin-left: 100px; +} +.row-fluid { + width: 100%; + *zoom: 1; +} +.row-fluid:before, +.row-fluid:after { + display: table; + content: ""; + line-height: 0; +} +.row-fluid:after { + clear: both; +} +.row-fluid [class*="span"] { + display: block; + width: 100%; + min-height: 31px; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + float: left; + margin-left: 2.12765957%; + *margin-left: 2.07446809%; +} +.row-fluid [class*="span"]:first-child { + margin-left: 0; +} +.row-fluid .controls-row [class*="span"] + [class*="span"] { + margin-left: 2.12765957%; +} +.row-fluid .span12 { + width: 100%; + *width: 99.94680851%; +} +.row-fluid .span11 { + width: 91.4893617%; + *width: 91.43617021%; +} +.row-fluid .span10 { + width: 82.9787234%; + *width: 82.92553191%; +} +.row-fluid .span9 { + width: 74.46808511%; + *width: 74.41489362%; +} +.row-fluid .span8 { + width: 65.95744681%; + *width: 65.90425532%; +} +.row-fluid .span7 { + width: 57.44680851%; + *width: 57.39361702%; +} +.row-fluid .span6 { + width: 48.93617021%; + *width: 48.88297872%; +} +.row-fluid .span5 { + width: 40.42553191%; + *width: 40.37234043%; +} +.row-fluid .span4 { + width: 31.91489362%; + *width: 31.86170213%; +} +.row-fluid .span3 { + width: 23.40425532%; + *width: 23.35106383%; +} +.row-fluid .span2 { + width: 14.89361702%; + *width: 14.84042553%; +} +.row-fluid .span1 { + width: 6.38297872%; + *width: 6.32978723%; +} +.row-fluid .offset12 { + margin-left: 104.25531915%; + *margin-left: 104.14893617%; +} +.row-fluid .offset12:first-child { + margin-left: 102.12765957%; + *margin-left: 102.0212766%; +} +.row-fluid .offset11 { + margin-left: 95.74468085%; + *margin-left: 95.63829787%; +} +.row-fluid .offset11:first-child { + margin-left: 93.61702128%; + *margin-left: 93.5106383%; +} +.row-fluid .offset10 { + margin-left: 87.23404255%; + *margin-left: 87.12765957%; +} +.row-fluid .offset10:first-child { + margin-left: 85.10638298%; + *margin-left: 85%; +} +.row-fluid .offset9 { + margin-left: 78.72340426%; + *margin-left: 78.61702128%; +} +.row-fluid .offset9:first-child { + margin-left: 76.59574468%; + *margin-left: 76.4893617%; +} +.row-fluid .offset8 { + margin-left: 70.21276596%; + *margin-left: 70.10638298%; +} +.row-fluid .offset8:first-child { + margin-left: 68.08510638%; + *margin-left: 67.9787234%; +} +.row-fluid .offset7 { + margin-left: 61.70212766%; + *margin-left: 61.59574468%; +} +.row-fluid .offset7:first-child { + margin-left: 59.57446809%; + *margin-left: 59.46808511%; +} +.row-fluid .offset6 { + margin-left: 53.19148936%; + *margin-left: 53.08510638%; +} +.row-fluid .offset6:first-child { + margin-left: 51.06382979%; + *margin-left: 50.95744681%; +} +.row-fluid .offset5 { + margin-left: 44.68085106%; + *margin-left: 44.57446809%; +} +.row-fluid .offset5:first-child { + margin-left: 42.55319149%; + *margin-left: 42.44680851%; +} +.row-fluid .offset4 { + margin-left: 36.17021277%; + *margin-left: 36.06382979%; +} +.row-fluid .offset4:first-child { + margin-left: 34.04255319%; + *margin-left: 33.93617021%; +} +.row-fluid .offset3 { + margin-left: 27.65957447%; + *margin-left: 27.55319149%; +} +.row-fluid .offset3:first-child { + margin-left: 25.53191489%; + *margin-left: 25.42553191%; +} +.row-fluid .offset2 { + margin-left: 19.14893617%; + *margin-left: 19.04255319%; +} +.row-fluid .offset2:first-child { + margin-left: 17.0212766%; + *margin-left: 16.91489362%; +} +.row-fluid .offset1 { + margin-left: 10.63829787%; + *margin-left: 10.53191489%; +} +.row-fluid .offset1:first-child { + margin-left: 8.5106383%; + *margin-left: 8.40425532%; +} +[class*="span"].hide, +.row-fluid [class*="span"].hide { + display: none; +} +[class*="span"].pull-right, +.row-fluid [class*="span"].pull-right { + float: right; +} +.container { + margin-right: auto; + margin-left: auto; + *zoom: 1; +} +.container:before, +.container:after { + display: table; + content: ""; + line-height: 0; +} +.container:after { + clear: both; +} +.container-fluid { + padding-right: 20px; + padding-left: 20px; + *zoom: 1; +} +.container-fluid:before, +.container-fluid:after { + display: table; + content: ""; + line-height: 0; +} +.container-fluid:after { + clear: both; +} +p { + margin: 0 0 10.5px; +} +.lead { + margin-bottom: 21px; + font-size: 24px; + font-weight: 200; + line-height: 31.5px; +} +small { + font-size: 85%; +} +strong { + font-weight: bold; +} +em { + font-style: italic; +} +cite { + font-style: normal; +} +.muted { + color: #999999; +} +a.muted:hover, +a.muted:focus { + color: #808080; +} +.text-warning { + color: #c09853; +} +a.text-warning:hover, +a.text-warning:focus { + color: #a47e3c; +} +.text-error { + color: #b94a48; +} +a.text-error:hover, +a.text-error:focus { + color: #953b39; +} +.text-info { + color: #3a87ad; +} +a.text-info:hover, +a.text-info:focus { + color: #2d6987; +} +.text-success { + color: #468847; +} +a.text-success:hover, +a.text-success:focus { + color: #356635; +} +.text-left { + text-align: left; +} +.text-right { + text-align: right; +} +.text-center { + text-align: center; +} +h1, +h2, +h3, +h4, +h5, +h6 { + margin: 10.5px 0; + font-family: inherit; + font-weight: bold; + line-height: 21px; + color: inherit; + text-rendering: optimizelegibility; +} +h1 small, +h2 small, +h3 small, +h4 small, +h5 small, +h6 small { + font-weight: normal; + line-height: 1; + color: #999999; +} +h1, +h2, +h3 { + line-height: 42px; +} +h1 { + font-size: 44px; +} +h2 { + font-size: 36px; +} +h3 { + font-size: 28px; +} +h4 { + font-size: 20px; +} +h5 { + font-size: 16px; +} +h6 { + font-size: 13.6px; +} +h1 small { + font-size: 28px; +} +h2 small { + font-size: 20px; +} +h3 small { + font-size: 16px; +} +h4 small { + font-size: 16px; +} +.page-header { + padding-bottom: 9.5px; + margin: 21px 0 31.5px; + border-bottom: 1px solid #eeeeee; +} +ul, +ol { + padding: 0; + margin: 0 0 10.5px 25px; +} +ul ul, +ul ol, +ol ol, +ol ul { + margin-bottom: 0; +} +li { + line-height: 21px; +} +ul.unstyled, +ol.unstyled { + margin-left: 0; + list-style: none; +} +ul.inline, +ol.inline { + margin-left: 0; + list-style: none; +} +ul.inline > li, +ol.inline > li { + display: inline-block; + *display: inline; + /* IE7 inline-block hack */ + *zoom: 1; + padding-left: 5px; + padding-right: 5px; +} +dl { + margin-bottom: 21px; +} +dt, +dd { + line-height: 21px; +} +dt { + font-weight: bold; +} +dd { + margin-left: 10.5px; +} +.dl-horizontal { + *zoom: 1; +} +.dl-horizontal:before, +.dl-horizontal:after { + display: table; + content: ""; + line-height: 0; +} +.dl-horizontal:after { + clear: both; +} +.dl-horizontal dt { + float: left; + width: 160px; + clear: left; + text-align: right; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} +.dl-horizontal dd { + margin-left: 180px; +} +hr { + margin: 21px 0; + border: 0; + border-top: 1px solid #eeeeee; + border-bottom: 1px solid #ffffff; +} +abbr[title], +abbr[data-original-title] { + cursor: help; + border-bottom: 1px dotted #999999; +} +abbr.initialism { + font-size: 90%; + text-transform: uppercase; +} +blockquote { + padding: 0 0 0 15px; + margin: 0 0 21px; + border-left: 5px solid #eeeeee; +} +blockquote p { + margin-bottom: 0; + font-size: 20px; + font-weight: 300; + line-height: 1.25; +} +blockquote small { + display: block; + line-height: 21px; + color: #999999; +} +blockquote small:before { + content: '\2014 \00A0'; +} +blockquote.pull-right { + float: right; + padding-right: 15px; + padding-left: 0; + border-right: 5px solid #eeeeee; + border-left: 0; +} +blockquote.pull-right p, +blockquote.pull-right small { + text-align: right; +} +blockquote.pull-right small:before { + content: ''; +} +blockquote.pull-right small:after { + content: '\00A0 \2014'; +} +q:before, +q:after, +blockquote:before, +blockquote:after { + content: ""; +} +address { + display: block; + margin-bottom: 21px; + font-style: normal; + line-height: 21px; +} +code, +pre { + padding: 0 3px 2px; + font-family: 'Source Code Pro', monospace; + font-size: 14px; + color: #333333; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; +} +code { + padding: 2px 4px; + color: #d14; + background-color: #f7f7f9; + border: 1px solid #e1e1e8; + white-space: nowrap; +} +pre { + display: block; + padding: 10px; + margin: 0 0 10.5px; + font-size: 15px; + line-height: 21px; + word-break: break-all; + word-wrap: break-word; + white-space: pre; + white-space: pre-wrap; + background-color: #f5f5f5; + border: 1px solid #ccc; + border: 1px solid rgba(0, 0, 0, 0.15); + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; +} +pre.prettyprint { + margin-bottom: 21px; +} +pre code { + padding: 0; + color: inherit; + white-space: pre; + white-space: pre-wrap; + background-color: transparent; + border: 0; +} +.pre-scrollable { + max-height: 340px; + overflow-y: scroll; +} +form { + margin: 0 0 21px; +} +fieldset { + padding: 0; + margin: 0; + border: 0; +} +legend { + display: block; + width: 100%; + padding: 0; + margin-bottom: 21px; + font-size: 24px; + line-height: 42px; + color: #333333; + border: 0; + border-bottom: 1px solid #e5e5e5; +} +legend small { + font-size: 15.75px; + color: #999999; +} +label, +input, +button, +select, +textarea { + font-size: 16px; + font-weight: normal; + line-height: 21px; +} +input, +button, +select, +textarea { + font-family: 'Source Sans Pro', sans-serif; +} +label { + display: block; + margin-bottom: 5px; +} +select, +textarea, +input[type="text"], +input[type="password"], +input[type="datetime"], +input[type="datetime-local"], +input[type="date"], +input[type="month"], +input[type="time"], +input[type="week"], +input[type="number"], +input[type="email"], +input[type="url"], +input[type="search"], +input[type="tel"], +input[type="color"], +.uneditable-input { + display: inline-block; + height: 21px; + padding: 4px 6px; + margin-bottom: 10.5px; + font-size: 16px; + line-height: 21px; + color: #555555; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; + vertical-align: middle; +} +input, +textarea, +.uneditable-input { + width: 206px; +} +textarea { + height: auto; +} +textarea, +input[type="text"], +input[type="password"], +input[type="datetime"], +input[type="datetime-local"], +input[type="date"], +input[type="month"], +input[type="time"], +input[type="week"], +input[type="number"], +input[type="email"], +input[type="url"], +input[type="search"], +input[type="tel"], +input[type="color"], +.uneditable-input { + background-color: #ffffff; + border: 1px solid #cccccc; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + -webkit-transition: border linear .2s, box-shadow linear .2s; + -moz-transition: border linear .2s, box-shadow linear .2s; + -o-transition: border linear .2s, box-shadow linear .2s; + transition: border linear .2s, box-shadow linear .2s; +} +textarea:focus, +input[type="text"]:focus, +input[type="password"]:focus, +input[type="datetime"]:focus, +input[type="datetime-local"]:focus, +input[type="date"]:focus, +input[type="month"]:focus, +input[type="time"]:focus, +input[type="week"]:focus, +input[type="number"]:focus, +input[type="email"]:focus, +input[type="url"]:focus, +input[type="search"]:focus, +input[type="tel"]:focus, +input[type="color"]:focus, +.uneditable-input:focus { + border-color: rgba(82, 168, 236, 0.8); + outline: 0; + outline: thin dotted \9; + /* IE6-9 */ + -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(82,168,236,.6); + -moz-box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(82,168,236,.6); + box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(82,168,236,.6); +} +input[type="radio"], +input[type="checkbox"] { + margin: 4px 0 0; + *margin-top: 0; + /* IE7 */ + margin-top: 1px \9; + /* IE8-9 */ + line-height: normal; +} +input[type="file"], +input[type="image"], +input[type="submit"], +input[type="reset"], +input[type="button"], +input[type="radio"], +input[type="checkbox"] { + width: auto; +} +select, +input[type="file"] { + height: 31px; + /* In IE7, the height of the select element cannot be changed by height, only font-size */ + *margin-top: 4px; + /* For IE7, add top margin to align select with labels */ + line-height: 31px; +} +select { + width: 220px; + border: 1px solid #cccccc; + background-color: #ffffff; +} +select[multiple], +select[size] { + height: auto; +} +select:focus, +input[type="file"]:focus, +input[type="radio"]:focus, +input[type="checkbox"]:focus { + outline: thin dotted #333; + outline: 5px auto -webkit-focus-ring-color; + outline-offset: -2px; +} +.uneditable-input, +.uneditable-textarea { + color: #999999; + background-color: #fcfcfc; + border-color: #cccccc; + -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.025); + -moz-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.025); + box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.025); + cursor: not-allowed; +} +.uneditable-input { + overflow: hidden; + white-space: nowrap; +} +.uneditable-textarea { + width: auto; + height: auto; +} +input:-moz-placeholder, +textarea:-moz-placeholder { + color: #999999; +} +input:-ms-input-placeholder, +textarea:-ms-input-placeholder { + color: #999999; +} +input::-webkit-input-placeholder, +textarea::-webkit-input-placeholder { + color: #999999; +} +.radio, +.checkbox { + min-height: 21px; + padding-left: 20px; +} +.radio input[type="radio"], +.checkbox input[type="checkbox"] { + float: left; + margin-left: -20px; +} +.controls > .radio:first-child, +.controls > .checkbox:first-child { + padding-top: 5px; +} +.radio.inline, +.checkbox.inline { + display: inline-block; + padding-top: 5px; + margin-bottom: 0; + vertical-align: middle; +} +.radio.inline + .radio.inline, +.checkbox.inline + .checkbox.inline { + margin-left: 10px; +} +.input-mini { + width: 60px; +} +.input-small { + width: 90px; +} +.input-medium { + width: 150px; +} +.input-large { + width: 210px; +} +.input-xlarge { + width: 270px; +} +.input-xxlarge { + width: 530px; +} +input[class*="span"], +select[class*="span"], +textarea[class*="span"], +.uneditable-input[class*="span"], +.row-fluid input[class*="span"], +.row-fluid select[class*="span"], +.row-fluid textarea[class*="span"], +.row-fluid .uneditable-input[class*="span"] { + float: none; + margin-left: 0; +} +.input-append input[class*="span"], +.input-append .uneditable-input[class*="span"], +.input-prepend input[class*="span"], +.input-prepend .uneditable-input[class*="span"], +.row-fluid input[class*="span"], +.row-fluid select[class*="span"], +.row-fluid textarea[class*="span"], +.row-fluid .uneditable-input[class*="span"], +.row-fluid .input-prepend [class*="span"], +.row-fluid .input-append [class*="span"] { + display: inline-block; +} +input, +textarea, +.uneditable-input { + margin-left: 0; +} +.controls-row [class*="span"] + [class*="span"] { + margin-left: 20px; +} +input.span12, +textarea.span12, +.uneditable-input.span12 { + width: 926px; +} +input.span11, +textarea.span11, +.uneditable-input.span11 { + width: 846px; +} +input.span10, +textarea.span10, +.uneditable-input.span10 { + width: 766px; +} +input.span9, +textarea.span9, +.uneditable-input.span9 { + width: 686px; +} +input.span8, +textarea.span8, +.uneditable-input.span8 { + width: 606px; +} +input.span7, +textarea.span7, +.uneditable-input.span7 { + width: 526px; +} +input.span6, +textarea.span6, +.uneditable-input.span6 { + width: 446px; +} +input.span5, +textarea.span5, +.uneditable-input.span5 { + width: 366px; +} +input.span4, +textarea.span4, +.uneditable-input.span4 { + width: 286px; +} +input.span3, +textarea.span3, +.uneditable-input.span3 { + width: 206px; +} +input.span2, +textarea.span2, +.uneditable-input.span2 { + width: 126px; +} +input.span1, +textarea.span1, +.uneditable-input.span1 { + width: 46px; +} +.controls-row { + *zoom: 1; +} +.controls-row:before, +.controls-row:after { + display: table; + content: ""; + line-height: 0; +} +.controls-row:after { + clear: both; +} +.controls-row [class*="span"], +.row-fluid .controls-row [class*="span"] { + float: left; +} +.controls-row .checkbox[class*="span"], +.controls-row .radio[class*="span"] { + padding-top: 5px; +} +input[disabled], +select[disabled], +textarea[disabled], +input[readonly], +select[readonly], +textarea[readonly] { + cursor: not-allowed; + background-color: #eeeeee; +} +input[type="radio"][disabled], +input[type="checkbox"][disabled], +input[type="radio"][readonly], +input[type="checkbox"][readonly] { + background-color: transparent; +} +.control-group.warning .control-label, +.control-group.warning .help-block, +.control-group.warning .help-inline { + color: #c09853; +} +.control-group.warning .checkbox, +.control-group.warning .radio, +.control-group.warning input, +.control-group.warning select, +.control-group.warning textarea { + color: #c09853; +} +.control-group.warning input, +.control-group.warning select, +.control-group.warning textarea { + border-color: #c09853; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); +} +.control-group.warning input:focus, +.control-group.warning select:focus, +.control-group.warning textarea:focus { + border-color: #a47e3c; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #dbc59e; + -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #dbc59e; + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #dbc59e; +} +.control-group.warning .input-prepend .add-on, +.control-group.warning .input-append .add-on { + color: #c09853; + background-color: #fcf8e3; + border-color: #c09853; +} +.control-group.error .control-label, +.control-group.error .help-block, +.control-group.error .help-inline { + color: #b94a48; +} +.control-group.error .checkbox, +.control-group.error .radio, +.control-group.error input, +.control-group.error select, +.control-group.error textarea { + color: #b94a48; +} +.control-group.error input, +.control-group.error select, +.control-group.error textarea { + border-color: #b94a48; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); +} +.control-group.error input:focus, +.control-group.error select:focus, +.control-group.error textarea:focus { + border-color: #953b39; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #d59392; + -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #d59392; + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #d59392; +} +.control-group.error .input-prepend .add-on, +.control-group.error .input-append .add-on { + color: #b94a48; + background-color: #f2dede; + border-color: #b94a48; +} +.control-group.success .control-label, +.control-group.success .help-block, +.control-group.success .help-inline { + color: #468847; +} +.control-group.success .checkbox, +.control-group.success .radio, +.control-group.success input, +.control-group.success select, +.control-group.success textarea { + color: #468847; +} +.control-group.success input, +.control-group.success select, +.control-group.success textarea { + border-color: #468847; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); +} +.control-group.success input:focus, +.control-group.success select:focus, +.control-group.success textarea:focus { + border-color: #356635; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #7aba7b; + -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #7aba7b; + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #7aba7b; +} +.control-group.success .input-prepend .add-on, +.control-group.success .input-append .add-on { + color: #468847; + background-color: #dff0d8; + border-color: #468847; +} +.control-group.info .control-label, +.control-group.info .help-block, +.control-group.info .help-inline { + color: #3a87ad; +} +.control-group.info .checkbox, +.control-group.info .radio, +.control-group.info input, +.control-group.info select, +.control-group.info textarea { + color: #3a87ad; +} +.control-group.info input, +.control-group.info select, +.control-group.info textarea { + border-color: #3a87ad; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); +} +.control-group.info input:focus, +.control-group.info select:focus, +.control-group.info textarea:focus { + border-color: #2d6987; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #7ab5d3; + -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #7ab5d3; + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #7ab5d3; +} +.control-group.info .input-prepend .add-on, +.control-group.info .input-append .add-on { + color: #3a87ad; + background-color: #d9edf7; + border-color: #3a87ad; +} +input:focus:invalid, +textarea:focus:invalid, +select:focus:invalid { + color: #b94a48; + border-color: #ee5f5b; +} +input:focus:invalid:focus, +textarea:focus:invalid:focus, +select:focus:invalid:focus { + border-color: #e9322d; + -webkit-box-shadow: 0 0 6px #f8b9b7; + -moz-box-shadow: 0 0 6px #f8b9b7; + box-shadow: 0 0 6px #f8b9b7; +} +.form-actions { + padding: 20px 20px 21px; + margin-top: 21px; + margin-bottom: 21px; + background-color: #f5f5f5; + border-top: 1px solid #e5e5e5; + *zoom: 1; +} +.form-actions:before, +.form-actions:after { + display: table; + content: ""; + line-height: 0; +} +.form-actions:after { + clear: both; +} +.help-block, +.help-inline { + color: #595959; +} +.help-block { + display: block; + margin-bottom: 10.5px; +} +.help-inline { + display: inline-block; + *display: inline; + /* IE7 inline-block hack */ + *zoom: 1; + vertical-align: middle; + padding-left: 5px; +} +.input-append, +.input-prepend { + display: inline-block; + margin-bottom: 10.5px; + vertical-align: middle; + font-size: 0; + white-space: nowrap; +} +.input-append input, +.input-prepend input, +.input-append select, +.input-prepend select, +.input-append .uneditable-input, +.input-prepend .uneditable-input, +.input-append .dropdown-menu, +.input-prepend .dropdown-menu, +.input-append .popover, +.input-prepend .popover { + font-size: 16px; +} +.input-append input, +.input-prepend input, +.input-append select, +.input-prepend select, +.input-append .uneditable-input, +.input-prepend .uneditable-input { + position: relative; + margin-bottom: 0; + *margin-left: 0; + vertical-align: top; + -webkit-border-radius: 0 4px 4px 0; + -moz-border-radius: 0 4px 4px 0; + border-radius: 0 4px 4px 0; +} +.input-append input:focus, +.input-prepend input:focus, +.input-append select:focus, +.input-prepend select:focus, +.input-append .uneditable-input:focus, +.input-prepend .uneditable-input:focus { + z-index: 2; +} +.input-append .add-on, +.input-prepend .add-on { + display: inline-block; + width: auto; + height: 21px; + min-width: 16px; + padding: 4px 5px; + font-size: 16px; + font-weight: normal; + line-height: 21px; + text-align: center; + text-shadow: 0 1px 0 #ffffff; + background-color: #eeeeee; + border: 1px solid #ccc; +} +.input-append .add-on, +.input-prepend .add-on, +.input-append .btn, +.input-prepend .btn, +.input-append .btn-group > .dropdown-toggle, +.input-prepend .btn-group > .dropdown-toggle { + vertical-align: top; + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; +} +.input-append .active, +.input-prepend .active { + background-color: #a9dba9; + border-color: #46a546; +} +.input-prepend .add-on, +.input-prepend .btn { + margin-right: -1px; +} +.input-prepend .add-on:first-child, +.input-prepend .btn:first-child { + -webkit-border-radius: 4px 0 0 4px; + -moz-border-radius: 4px 0 0 4px; + border-radius: 4px 0 0 4px; +} +.input-append input, +.input-append select, +.input-append .uneditable-input { + -webkit-border-radius: 4px 0 0 4px; + -moz-border-radius: 4px 0 0 4px; + border-radius: 4px 0 0 4px; +} +.input-append input + .btn-group .btn:last-child, +.input-append select + .btn-group .btn:last-child, +.input-append .uneditable-input + .btn-group .btn:last-child { + -webkit-border-radius: 0 4px 4px 0; + -moz-border-radius: 0 4px 4px 0; + border-radius: 0 4px 4px 0; +} +.input-append .add-on, +.input-append .btn, +.input-append .btn-group { + margin-left: -1px; +} +.input-append .add-on:last-child, +.input-append .btn:last-child, +.input-append .btn-group:last-child > .dropdown-toggle { + -webkit-border-radius: 0 4px 4px 0; + -moz-border-radius: 0 4px 4px 0; + border-radius: 0 4px 4px 0; +} +.input-prepend.input-append input, +.input-prepend.input-append select, +.input-prepend.input-append .uneditable-input { + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; +} +.input-prepend.input-append input + .btn-group .btn, +.input-prepend.input-append select + .btn-group .btn, +.input-prepend.input-append .uneditable-input + .btn-group .btn { + -webkit-border-radius: 0 4px 4px 0; + -moz-border-radius: 0 4px 4px 0; + border-radius: 0 4px 4px 0; +} +.input-prepend.input-append .add-on:first-child, +.input-prepend.input-append .btn:first-child { + margin-right: -1px; + -webkit-border-radius: 4px 0 0 4px; + -moz-border-radius: 4px 0 0 4px; + border-radius: 4px 0 0 4px; +} +.input-prepend.input-append .add-on:last-child, +.input-prepend.input-append .btn:last-child { + margin-left: -1px; + -webkit-border-radius: 0 4px 4px 0; + -moz-border-radius: 0 4px 4px 0; + border-radius: 0 4px 4px 0; +} +.input-prepend.input-append .btn-group:first-child { + margin-left: 0; +} +input.search-query { + padding-right: 14px; + padding-right: 4px \9; + padding-left: 14px; + padding-left: 4px \9; + /* IE7-8 doesn't have border-radius, so don't indent the padding */ + margin-bottom: 0; + -webkit-border-radius: 15px; + -moz-border-radius: 15px; + border-radius: 15px; +} +/* Allow for input prepend/append in search forms */ +.form-search .input-append .search-query, +.form-search .input-prepend .search-query { + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; +} +.form-search .input-append .search-query { + -webkit-border-radius: 14px 0 0 14px; + -moz-border-radius: 14px 0 0 14px; + border-radius: 14px 0 0 14px; +} +.form-search .input-append .btn { + -webkit-border-radius: 0 14px 14px 0; + -moz-border-radius: 0 14px 14px 0; + border-radius: 0 14px 14px 0; +} +.form-search .input-prepend .search-query { + -webkit-border-radius: 0 14px 14px 0; + -moz-border-radius: 0 14px 14px 0; + border-radius: 0 14px 14px 0; +} +.form-search .input-prepend .btn { + -webkit-border-radius: 14px 0 0 14px; + -moz-border-radius: 14px 0 0 14px; + border-radius: 14px 0 0 14px; +} +.form-search input, +.form-inline input, +.form-horizontal input, +.form-search textarea, +.form-inline textarea, +.form-horizontal textarea, +.form-search select, +.form-inline select, +.form-horizontal select, +.form-search .help-inline, +.form-inline .help-inline, +.form-horizontal .help-inline, +.form-search .uneditable-input, +.form-inline .uneditable-input, +.form-horizontal .uneditable-input, +.form-search .input-prepend, +.form-inline .input-prepend, +.form-horizontal .input-prepend, +.form-search .input-append, +.form-inline .input-append, +.form-horizontal .input-append { + display: inline-block; + *display: inline; + /* IE7 inline-block hack */ + *zoom: 1; + margin-bottom: 0; + vertical-align: middle; +} +.form-search .hide, +.form-inline .hide, +.form-horizontal .hide { + display: none; +} +.form-search label, +.form-inline label, +.form-search .btn-group, +.form-inline .btn-group { + display: inline-block; +} +.form-search .input-append, +.form-inline .input-append, +.form-search .input-prepend, +.form-inline .input-prepend { + margin-bottom: 0; +} +.form-search .radio, +.form-search .checkbox, +.form-inline .radio, +.form-inline .checkbox { + padding-left: 0; + margin-bottom: 0; + vertical-align: middle; +} +.form-search .radio input[type="radio"], +.form-search .checkbox input[type="checkbox"], +.form-inline .radio input[type="radio"], +.form-inline .checkbox input[type="checkbox"] { + float: left; + margin-right: 3px; + margin-left: 0; +} +.control-group { + margin-bottom: 10.5px; +} +legend + .control-group { + margin-top: 21px; + -webkit-margin-top-collapse: separate; +} +.form-horizontal .control-group { + margin-bottom: 21px; + *zoom: 1; +} +.form-horizontal .control-group:before, +.form-horizontal .control-group:after { + display: table; + content: ""; + line-height: 0; +} +.form-horizontal .control-group:after { + clear: both; +} +.form-horizontal .control-label { + float: left; + width: 160px; + padding-top: 5px; + text-align: right; +} +.form-horizontal .controls { + *display: inline-block; + *padding-left: 20px; + margin-left: 180px; + *margin-left: 0; +} +.form-horizontal .controls:first-child { + *padding-left: 180px; +} +.form-horizontal .help-block { + margin-bottom: 0; +} +.form-horizontal input + .help-block, +.form-horizontal select + .help-block, +.form-horizontal textarea + .help-block, +.form-horizontal .uneditable-input + .help-block, +.form-horizontal .input-prepend + .help-block, +.form-horizontal .input-append + .help-block { + margin-top: 10.5px; +} +.form-horizontal .form-actions { + padding-left: 180px; +} +table { + max-width: 100%; + background-color: transparent; + border-collapse: collapse; + border-spacing: 0; +} +.table { + width: 100%; + margin-bottom: 21px; +} +.table th, +.table td { + padding: 8px; + line-height: 21px; + text-align: left; + vertical-align: top; + border-top: 1px solid #dddddd; +} +.table th { + font-weight: bold; +} +.table thead th { + vertical-align: bottom; +} +.table caption + thead tr:first-child th, +.table caption + thead tr:first-child td, +.table colgroup + thead tr:first-child th, +.table colgroup + thead tr:first-child td, +.table thead:first-child tr:first-child th, +.table thead:first-child tr:first-child td { + border-top: 0; +} +.table tbody + tbody { + border-top: 2px solid #dddddd; +} +.table .table { + background-color: #ffffff; +} +.table-condensed th, +.table-condensed td { + padding: 4px 5px; +} +.table-bordered { + border: 1px solid #dddddd; + border-collapse: separate; + *border-collapse: collapse; + border-left: 0; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; +} +.table-bordered th, +.table-bordered td { + border-left: 1px solid #dddddd; +} +.table-bordered caption + thead tr:first-child th, +.table-bordered caption + tbody tr:first-child th, +.table-bordered caption + tbody tr:first-child td, +.table-bordered colgroup + thead tr:first-child th, +.table-bordered colgroup + tbody tr:first-child th, +.table-bordered colgroup + tbody tr:first-child td, +.table-bordered thead:first-child tr:first-child th, +.table-bordered tbody:first-child tr:first-child th, +.table-bordered tbody:first-child tr:first-child td { + border-top: 0; +} +.table-bordered thead:first-child tr:first-child > th:first-child, +.table-bordered tbody:first-child tr:first-child > td:first-child, +.table-bordered tbody:first-child tr:first-child > th:first-child { + -webkit-border-top-left-radius: 4px; + -moz-border-radius-topleft: 4px; + border-top-left-radius: 4px; +} +.table-bordered thead:first-child tr:first-child > th:last-child, +.table-bordered tbody:first-child tr:first-child > td:last-child, +.table-bordered tbody:first-child tr:first-child > th:last-child { + -webkit-border-top-right-radius: 4px; + -moz-border-radius-topright: 4px; + border-top-right-radius: 4px; +} +.table-bordered thead:last-child tr:last-child > th:first-child, +.table-bordered tbody:last-child tr:last-child > td:first-child, +.table-bordered tbody:last-child tr:last-child > th:first-child, +.table-bordered tfoot:last-child tr:last-child > td:first-child, +.table-bordered tfoot:last-child tr:last-child > th:first-child { + -webkit-border-bottom-left-radius: 4px; + -moz-border-radius-bottomleft: 4px; + border-bottom-left-radius: 4px; +} +.table-bordered thead:last-child tr:last-child > th:last-child, +.table-bordered tbody:last-child tr:last-child > td:last-child, +.table-bordered tbody:last-child tr:last-child > th:last-child, +.table-bordered tfoot:last-child tr:last-child > td:last-child, +.table-bordered tfoot:last-child tr:last-child > th:last-child { + -webkit-border-bottom-right-radius: 4px; + -moz-border-radius-bottomright: 4px; + border-bottom-right-radius: 4px; +} +.table-bordered tfoot + tbody:last-child tr:last-child td:first-child { + -webkit-border-bottom-left-radius: 0; + -moz-border-radius-bottomleft: 0; + border-bottom-left-radius: 0; +} +.table-bordered tfoot + tbody:last-child tr:last-child td:last-child { + -webkit-border-bottom-right-radius: 0; + -moz-border-radius-bottomright: 0; + border-bottom-right-radius: 0; +} +.table-bordered caption + thead tr:first-child th:first-child, +.table-bordered caption + tbody tr:first-child td:first-child, +.table-bordered colgroup + thead tr:first-child th:first-child, +.table-bordered colgroup + tbody tr:first-child td:first-child { + -webkit-border-top-left-radius: 4px; + -moz-border-radius-topleft: 4px; + border-top-left-radius: 4px; +} +.table-bordered caption + thead tr:first-child th:last-child, +.table-bordered caption + tbody tr:first-child td:last-child, +.table-bordered colgroup + thead tr:first-child th:last-child, +.table-bordered colgroup + tbody tr:first-child td:last-child { + -webkit-border-top-right-radius: 4px; + -moz-border-radius-topright: 4px; + border-top-right-radius: 4px; +} +.table-striped tbody > tr:nth-child(odd) > td, +.table-striped tbody > tr:nth-child(odd) > th { + background-color: #f9f9f9; +} +.table-hover tbody tr:hover > td, +.table-hover tbody tr:hover > th { + background-color: #f5f5f5; +} +table td[class*="span"], +table th[class*="span"], +.row-fluid table td[class*="span"], +.row-fluid table th[class*="span"] { + display: table-cell; + float: none; + margin-left: 0; +} +.table td.span1, +.table th.span1 { + float: none; + width: 44px; + margin-left: 0; +} +.table td.span2, +.table th.span2 { + float: none; + width: 124px; + margin-left: 0; +} +.table td.span3, +.table th.span3 { + float: none; + width: 204px; + margin-left: 0; +} +.table td.span4, +.table th.span4 { + float: none; + width: 284px; + margin-left: 0; +} +.table td.span5, +.table th.span5 { + float: none; + width: 364px; + margin-left: 0; +} +.table td.span6, +.table th.span6 { + float: none; + width: 444px; + margin-left: 0; +} +.table td.span7, +.table th.span7 { + float: none; + width: 524px; + margin-left: 0; +} +.table td.span8, +.table th.span8 { + float: none; + width: 604px; + margin-left: 0; +} +.table td.span9, +.table th.span9 { + float: none; + width: 684px; + margin-left: 0; +} +.table td.span10, +.table th.span10 { + float: none; + width: 764px; + margin-left: 0; +} +.table td.span11, +.table th.span11 { + float: none; + width: 844px; + margin-left: 0; +} +.table td.span12, +.table th.span12 { + float: none; + width: 924px; + margin-left: 0; +} +.table tbody tr.success > td { + background-color: #dff0d8; +} +.table tbody tr.error > td { + background-color: #f2dede; +} +.table tbody tr.warning > td { + background-color: #fcf8e3; +} +.table tbody tr.info > td { + background-color: #d9edf7; +} +.table-hover tbody tr.success:hover > td { + background-color: #d0e9c6; +} +.table-hover tbody tr.error:hover > td { + background-color: #ebcccc; +} +.table-hover tbody tr.warning:hover > td { + background-color: #faf2cc; +} +.table-hover tbody tr.info:hover > td { + background-color: #c4e3f3; +} +[class^="icon-"], +[class*=" icon-"] { + display: inline-block; + width: 14px; + height: 14px; + *margin-right: .3em; + line-height: 14px; + vertical-align: text-top; + background-image: url("../../img/glyphicons-halflings.png"); + background-position: 14px 14px; + background-repeat: no-repeat; + margin-top: 1px; +} +/* White icons with optional class, or on hover/focus/active states of certain elements */ +.icon-white, +.nav-pills > .active > a > [class^="icon-"], +.nav-pills > .active > a > [class*=" icon-"], +.nav-list > .active > a > [class^="icon-"], +.nav-list > .active > a > [class*=" icon-"], +.navbar-inverse .nav > .active > a > [class^="icon-"], +.navbar-inverse .nav > .active > a > [class*=" icon-"], +.dropdown-menu > li > a:hover > [class^="icon-"], +.dropdown-menu > li > a:focus > [class^="icon-"], +.dropdown-menu > li > a:hover > [class*=" icon-"], +.dropdown-menu > li > a:focus > [class*=" icon-"], +.dropdown-menu > .active > a > [class^="icon-"], +.dropdown-menu > .active > a > [class*=" icon-"], +.dropdown-submenu:hover > a > [class^="icon-"], +.dropdown-submenu:focus > a > [class^="icon-"], +.dropdown-submenu:hover > a > [class*=" icon-"], +.dropdown-submenu:focus > a > [class*=" icon-"] { + background-image: url("../../img/glyphicons-halflings-white.png"); +} +.icon-glass { + background-position: 0 0; +} +.icon-music { + background-position: -24px 0; +} +.icon-search { + background-position: -48px 0; +} +.icon-envelope { + background-position: -72px 0; +} +.icon-heart { + background-position: -96px 0; +} +.icon-star { + background-position: -120px 0; +} +.icon-star-empty { + background-position: -144px 0; +} +.icon-user { + background-position: -168px 0; +} +.icon-film { + background-position: -192px 0; +} +.icon-th-large { + background-position: -216px 0; +} +.icon-th { + background-position: -240px 0; +} +.icon-th-list { + background-position: -264px 0; +} +.icon-ok { + background-position: -288px 0; +} +.icon-remove { + background-position: -312px 0; +} +.icon-zoom-in { + background-position: -336px 0; +} +.icon-zoom-out { + background-position: -360px 0; +} +.icon-off { + background-position: -384px 0; +} +.icon-signal { + background-position: -408px 0; +} +.icon-cog { + background-position: -432px 0; +} +.icon-trash { + background-position: -456px 0; +} +.icon-home { + background-position: 0 -24px; +} +.icon-file { + background-position: -24px -24px; +} +.icon-time { + background-position: -48px -24px; +} +.icon-road { + background-position: -72px -24px; +} +.icon-download-alt { + background-position: -96px -24px; +} +.icon-download { + background-position: -120px -24px; +} +.icon-upload { + background-position: -144px -24px; +} +.icon-inbox { + background-position: -168px -24px; +} +.icon-play-circle { + background-position: -192px -24px; +} +.icon-repeat { + background-position: -216px -24px; +} +.icon-refresh { + background-position: -240px -24px; +} +.icon-list-alt { + background-position: -264px -24px; +} +.icon-lock { + background-position: -287px -24px; +} +.icon-flag { + background-position: -312px -24px; +} +.icon-headphones { + background-position: -336px -24px; +} +.icon-volume-off { + background-position: -360px -24px; +} +.icon-volume-down { + background-position: -384px -24px; +} +.icon-volume-up { + background-position: -408px -24px; +} +.icon-qrcode { + background-position: -432px -24px; +} +.icon-barcode { + background-position: -456px -24px; +} +.icon-tag { + background-position: 0 -48px; +} +.icon-tags { + background-position: -25px -48px; +} +.icon-book { + background-position: -48px -48px; +} +.icon-bookmark { + background-position: -72px -48px; +} +.icon-print { + background-position: -96px -48px; +} +.icon-camera { + background-position: -120px -48px; +} +.icon-font { + background-position: -144px -48px; +} +.icon-bold { + background-position: -167px -48px; +} +.icon-italic { + background-position: -192px -48px; +} +.icon-text-height { + background-position: -216px -48px; +} +.icon-text-width { + background-position: -240px -48px; +} +.icon-align-left { + background-position: -264px -48px; +} +.icon-align-center { + background-position: -288px -48px; +} +.icon-align-right { + background-position: -312px -48px; +} +.icon-align-justify { + background-position: -336px -48px; +} +.icon-list { + background-position: -360px -48px; +} +.icon-indent-left { + background-position: -384px -48px; +} +.icon-indent-right { + background-position: -408px -48px; +} +.icon-facetime-video { + background-position: -432px -48px; +} +.icon-picture { + background-position: -456px -48px; +} +.icon-pencil { + background-position: 0 -72px; +} +.icon-map-marker { + background-position: -24px -72px; +} +.icon-adjust { + background-position: -48px -72px; +} +.icon-tint { + background-position: -72px -72px; +} +.icon-edit { + background-position: -96px -72px; +} +.icon-share { + background-position: -120px -72px; +} +.icon-check { + background-position: -144px -72px; +} +.icon-move { + background-position: -168px -72px; +} +.icon-step-backward { + background-position: -192px -72px; +} +.icon-fast-backward { + background-position: -216px -72px; +} +.icon-backward { + background-position: -240px -72px; +} +.icon-play { + background-position: -264px -72px; +} +.icon-pause { + background-position: -288px -72px; +} +.icon-stop { + background-position: -312px -72px; +} +.icon-forward { + background-position: -336px -72px; +} +.icon-fast-forward { + background-position: -360px -72px; +} +.icon-step-forward { + background-position: -384px -72px; +} +.icon-eject { + background-position: -408px -72px; +} +.icon-chevron-left { + background-position: -432px -72px; +} +.icon-chevron-right { + background-position: -456px -72px; +} +.icon-plus-sign { + background-position: 0 -96px; +} +.icon-minus-sign { + background-position: -24px -96px; +} +.icon-remove-sign { + background-position: -48px -96px; +} +.icon-ok-sign { + background-position: -72px -96px; +} +.icon-question-sign { + background-position: -96px -96px; +} +.icon-info-sign { + background-position: -120px -96px; +} +.icon-screenshot { + background-position: -144px -96px; +} +.icon-remove-circle { + background-position: -168px -96px; +} +.icon-ok-circle { + background-position: -192px -96px; +} +.icon-ban-circle { + background-position: -216px -96px; +} +.icon-arrow-left { + background-position: -240px -96px; +} +.icon-arrow-right { + background-position: -264px -96px; +} +.icon-arrow-up { + background-position: -289px -96px; +} +.icon-arrow-down { + background-position: -312px -96px; +} +.icon-share-alt { + background-position: -336px -96px; +} +.icon-resize-full { + background-position: -360px -96px; +} +.icon-resize-small { + background-position: -384px -96px; +} +.icon-plus { + background-position: -408px -96px; +} +.icon-minus { + background-position: -433px -96px; +} +.icon-asterisk { + background-position: -456px -96px; +} +.icon-exclamation-sign { + background-position: 0 -120px; +} +.icon-gift { + background-position: -24px -120px; +} +.icon-leaf { + background-position: -48px -120px; +} +.icon-fire { + background-position: -72px -120px; +} +.icon-eye-open { + background-position: -96px -120px; +} +.icon-eye-close { + background-position: -120px -120px; +} +.icon-warning-sign { + background-position: -144px -120px; +} +.icon-plane { + background-position: -168px -120px; +} +.icon-calendar { + background-position: -192px -120px; +} +.icon-random { + background-position: -216px -120px; + width: 16px; +} +.icon-comment { + background-position: -240px -120px; +} +.icon-magnet { + background-position: -264px -120px; +} +.icon-chevron-up { + background-position: -288px -120px; +} +.icon-chevron-down { + background-position: -313px -119px; +} +.icon-retweet { + background-position: -336px -120px; +} +.icon-shopping-cart { + background-position: -360px -120px; +} +.icon-folder-close { + background-position: -384px -120px; + width: 16px; +} +.icon-folder-open { + background-position: -408px -120px; + width: 16px; +} +.icon-resize-vertical { + background-position: -432px -119px; +} +.icon-resize-horizontal { + background-position: -456px -118px; +} +.icon-hdd { + background-position: 0 -144px; +} +.icon-bullhorn { + background-position: -24px -144px; +} +.icon-bell { + background-position: -48px -144px; +} +.icon-certificate { + background-position: -72px -144px; +} +.icon-thumbs-up { + background-position: -96px -144px; +} +.icon-thumbs-down { + background-position: -120px -144px; +} +.icon-hand-right { + background-position: -144px -144px; +} +.icon-hand-left { + background-position: -168px -144px; +} +.icon-hand-up { + background-position: -192px -144px; +} +.icon-hand-down { + background-position: -216px -144px; +} +.icon-circle-arrow-right { + background-position: -240px -144px; +} +.icon-circle-arrow-left { + background-position: -264px -144px; +} +.icon-circle-arrow-up { + background-position: -288px -144px; +} +.icon-circle-arrow-down { + background-position: -312px -144px; +} +.icon-globe { + background-position: -336px -144px; +} +.icon-wrench { + background-position: -360px -144px; +} +.icon-tasks { + background-position: -384px -144px; +} +.icon-filter { + background-position: -408px -144px; +} +.icon-briefcase { + background-position: -432px -144px; +} +.icon-fullscreen { + background-position: -456px -144px; +} +.dropup, +.dropdown { + position: relative; +} +.dropdown-toggle { + *margin-bottom: -3px; +} +.dropdown-toggle:active, +.open .dropdown-toggle { + outline: 0; +} +.caret { + display: inline-block; + width: 0; + height: 0; + vertical-align: top; + border-top: 4px solid #000000; + border-right: 4px solid transparent; + border-left: 4px solid transparent; + content: ""; +} +.dropdown .caret { + margin-top: 8px; + margin-left: 2px; +} +.dropdown-menu { + position: absolute; + top: 100%; + left: 0; + z-index: 1000; + display: none; + float: left; + min-width: 160px; + padding: 5px 0; + margin: 2px 0 0; + list-style: none; + background-color: #ffffff; + border: 1px solid #ccc; + border: 1px solid rgba(0, 0, 0, 0.2); + *border-right-width: 2px; + *border-bottom-width: 2px; + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; + -webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); + -moz-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); + box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); + -webkit-background-clip: padding-box; + -moz-background-clip: padding; + background-clip: padding-box; +} +.dropdown-menu.pull-right { + right: 0; + left: auto; +} +.dropdown-menu .divider { + *width: 100%; + height: 1px; + margin: 9.5px 1px; + *margin: -5px 0 5px; + overflow: hidden; + background-color: #e5e5e5; + border-bottom: 1px solid #ffffff; +} +.dropdown-menu > li > a { + display: block; + padding: 3px 20px; + clear: both; + font-weight: normal; + line-height: 21px; + color: #333333; + white-space: nowrap; +} +.dropdown-menu > li > a:hover, +.dropdown-menu > li > a:focus, +.dropdown-submenu:hover > a, +.dropdown-submenu:focus > a { + text-decoration: none; + color: #ffffff; + background-color: #0081c2; + background-image: -moz-linear-gradient(top, #0088cc, #0077b3); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#0088cc), to(#0077b3)); + background-image: -webkit-linear-gradient(top, #0088cc, #0077b3); + background-image: -o-linear-gradient(top, #0088cc, #0077b3); + background-image: linear-gradient(to bottom, #0088cc, #0077b3); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc', endColorstr='#ff0077b3', GradientType=0); +} +.dropdown-menu > .active > a, +.dropdown-menu > .active > a:hover, +.dropdown-menu > .active > a:focus { + color: #ffffff; + text-decoration: none; + outline: 0; + background-color: #0081c2; + background-image: -moz-linear-gradient(top, #0088cc, #0077b3); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#0088cc), to(#0077b3)); + background-image: -webkit-linear-gradient(top, #0088cc, #0077b3); + background-image: -o-linear-gradient(top, #0088cc, #0077b3); + background-image: linear-gradient(to bottom, #0088cc, #0077b3); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc', endColorstr='#ff0077b3', GradientType=0); +} +.dropdown-menu > .disabled > a, +.dropdown-menu > .disabled > a:hover, +.dropdown-menu > .disabled > a:focus { + color: #999999; +} +.dropdown-menu > .disabled > a:hover, +.dropdown-menu > .disabled > a:focus { + text-decoration: none; + background-color: transparent; + background-image: none; + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); + cursor: default; +} +.open { + *z-index: 1000; +} +.open > .dropdown-menu { + display: block; +} +.pull-right > .dropdown-menu { + right: 0; + left: auto; +} +.dropup .caret, +.navbar-fixed-bottom .dropdown .caret { + border-top: 0; + border-bottom: 4px solid #000000; + content: ""; +} +.dropup .dropdown-menu, +.navbar-fixed-bottom .dropdown .dropdown-menu { + top: auto; + bottom: 100%; + margin-bottom: 1px; +} +.dropdown-submenu { + position: relative; +} +.dropdown-submenu > .dropdown-menu { + top: 0; + left: 100%; + margin-top: -6px; + margin-left: -1px; + -webkit-border-radius: 0 6px 6px 6px; + -moz-border-radius: 0 6px 6px 6px; + border-radius: 0 6px 6px 6px; +} +.dropdown-submenu:hover > .dropdown-menu { + display: block; +} +.dropup .dropdown-submenu > .dropdown-menu { + top: auto; + bottom: 0; + margin-top: 0; + margin-bottom: -2px; + -webkit-border-radius: 5px 5px 5px 0; + -moz-border-radius: 5px 5px 5px 0; + border-radius: 5px 5px 5px 0; +} +.dropdown-submenu > a:after { + display: block; + content: " "; + float: right; + width: 0; + height: 0; + border-color: transparent; + border-style: solid; + border-width: 5px 0 5px 5px; + border-left-color: #cccccc; + margin-top: 5px; + margin-right: -10px; +} +.dropdown-submenu:hover > a:after { + border-left-color: #ffffff; +} +.dropdown-submenu.pull-left { + float: none; +} +.dropdown-submenu.pull-left > .dropdown-menu { + left: -100%; + margin-left: 10px; + -webkit-border-radius: 6px 0 6px 6px; + -moz-border-radius: 6px 0 6px 6px; + border-radius: 6px 0 6px 6px; +} +.dropdown .dropdown-menu .nav-header { + padding-left: 20px; + padding-right: 20px; +} +.typeahead { + z-index: 1051; + margin-top: 2px; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; +} +.well { + min-height: 20px; + padding: 19px; + margin-bottom: 20px; + background-color: #f5f5f5; + border: 1px solid #e3e3e3; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05); + -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05); +} +.well blockquote { + border-color: #ddd; + border-color: rgba(0, 0, 0, 0.15); +} +.well-large { + padding: 24px; + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; +} +.well-small { + padding: 9px; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; +} +.fade { + opacity: 0; + -webkit-transition: opacity 0.15s linear; + -moz-transition: opacity 0.15s linear; + -o-transition: opacity 0.15s linear; + transition: opacity 0.15s linear; +} +.fade.in { + opacity: 1; +} +.collapse { + position: relative; + height: 0; + overflow: hidden; + -webkit-transition: height 0.35s ease; + -moz-transition: height 0.35s ease; + -o-transition: height 0.35s ease; + transition: height 0.35s ease; +} +.collapse.in { + height: auto; +} +.close { + float: right; + font-size: 20px; + font-weight: bold; + line-height: 21px; + color: #000000; + text-shadow: 0 1px 0 #ffffff; + opacity: 0.2; + filter: alpha(opacity=20); +} +.close:hover, +.close:focus { + color: #000000; + text-decoration: none; + cursor: pointer; + opacity: 0.4; + filter: alpha(opacity=40); +} +button.close { + padding: 0; + cursor: pointer; + background: transparent; + border: 0; + -webkit-appearance: none; +} +.btn { + display: inline-block; + *display: inline; + /* IE7 inline-block hack */ + *zoom: 1; + padding: 4px 12px; + margin-bottom: 0; + font-size: 16px; + line-height: 21px; + text-align: center; + vertical-align: middle; + cursor: pointer; + color: #333333; + text-shadow: 0 1px 1px rgba(255, 255, 255, 0.75); + background-color: #f5f5f5; + background-image: -moz-linear-gradient(top, #ffffff, #e6e6e6); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#ffffff), to(#e6e6e6)); + background-image: -webkit-linear-gradient(top, #ffffff, #e6e6e6); + background-image: -o-linear-gradient(top, #ffffff, #e6e6e6); + background-image: linear-gradient(to bottom, #ffffff, #e6e6e6); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffe6e6e6', GradientType=0); + border-color: #e6e6e6 #e6e6e6 #bfbfbf; + border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); + *background-color: #e6e6e6; + /* Darken IE7 buttons by default so they stand out more given they won't have borders */ + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); + border: 1px solid #cccccc; + *border: 0; + border-bottom-color: #b3b3b3; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; + *margin-left: .3em; + -webkit-box-shadow: inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05); + -moz-box-shadow: inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05); + box-shadow: inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05); +} +.btn:hover, +.btn:focus, +.btn:active, +.btn.active, +.btn.disabled, +.btn[disabled] { + color: #333333; + background-color: #e6e6e6; + *background-color: #d9d9d9; +} +.btn:active, +.btn.active { + background-color: #cccccc \9; +} +.btn:first-child { + *margin-left: 0; +} +.btn:hover, +.btn:focus { + color: #333333; + text-decoration: none; + background-position: 0 -15px; + -webkit-transition: background-position 0.1s linear; + -moz-transition: background-position 0.1s linear; + -o-transition: background-position 0.1s linear; + transition: background-position 0.1s linear; +} +.btn:focus { + outline: thin dotted #333; + outline: 5px auto -webkit-focus-ring-color; + outline-offset: -2px; +} +.btn.active, +.btn:active { + background-image: none; + outline: 0; + -webkit-box-shadow: inset 0 2px 4px rgba(0,0,0,.15), 0 1px 2px rgba(0,0,0,.05); + -moz-box-shadow: inset 0 2px 4px rgba(0,0,0,.15), 0 1px 2px rgba(0,0,0,.05); + box-shadow: inset 0 2px 4px rgba(0,0,0,.15), 0 1px 2px rgba(0,0,0,.05); +} +.btn.disabled, +.btn[disabled] { + cursor: default; + background-image: none; + opacity: 0.65; + filter: alpha(opacity=65); + -webkit-box-shadow: none; + -moz-box-shadow: none; + box-shadow: none; +} +.btn-large { + padding: 11px 19px; + font-size: 20px; + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; +} +.btn-large [class^="icon-"], +.btn-large [class*=" icon-"] { + margin-top: 4px; +} +.btn-small { + padding: 2px 10px; + font-size: 13.6px; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; +} +.btn-small [class^="icon-"], +.btn-small [class*=" icon-"] { + margin-top: 0; +} +.btn-mini [class^="icon-"], +.btn-mini [class*=" icon-"] { + margin-top: -1px; +} +.btn-mini { + padding: 0 6px; + font-size: 12px; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; +} +.btn-block { + display: block; + width: 100%; + padding-left: 0; + padding-right: 0; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} +.btn-block + .btn-block { + margin-top: 5px; +} +input[type="submit"].btn-block, +input[type="reset"].btn-block, +input[type="button"].btn-block { + width: 100%; +} +.btn-primary.active, +.btn-warning.active, +.btn-danger.active, +.btn-success.active, +.btn-info.active, +.btn-inverse.active { + color: rgba(255, 255, 255, 0.75); +} +.btn-primary { + color: #ffffff; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); + background-color: #006dcc; + background-image: -moz-linear-gradient(top, #0088cc, #0044cc); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#0088cc), to(#0044cc)); + background-image: -webkit-linear-gradient(top, #0088cc, #0044cc); + background-image: -o-linear-gradient(top, #0088cc, #0044cc); + background-image: linear-gradient(to bottom, #0088cc, #0044cc); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc', endColorstr='#ff0044cc', GradientType=0); + border-color: #0044cc #0044cc #002a80; + border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); + *background-color: #0044cc; + /* Darken IE7 buttons by default so they stand out more given they won't have borders */ + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); +} +.btn-primary:hover, +.btn-primary:focus, +.btn-primary:active, +.btn-primary.active, +.btn-primary.disabled, +.btn-primary[disabled] { + color: #ffffff; + background-color: #0044cc; + *background-color: #003bb3; +} +.btn-primary:active, +.btn-primary.active { + background-color: #003399 \9; +} +.btn-warning { + color: #ffffff; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); + background-color: #faa732; + background-image: -moz-linear-gradient(top, #fbb450, #f89406); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#fbb450), to(#f89406)); + background-image: -webkit-linear-gradient(top, #fbb450, #f89406); + background-image: -o-linear-gradient(top, #fbb450, #f89406); + background-image: linear-gradient(to bottom, #fbb450, #f89406); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffbb450', endColorstr='#fff89406', GradientType=0); + border-color: #f89406 #f89406 #ad6704; + border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); + *background-color: #f89406; + /* Darken IE7 buttons by default so they stand out more given they won't have borders */ + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); +} +.btn-warning:hover, +.btn-warning:focus, +.btn-warning:active, +.btn-warning.active, +.btn-warning.disabled, +.btn-warning[disabled] { + color: #ffffff; + background-color: #f89406; + *background-color: #df8505; +} +.btn-warning:active, +.btn-warning.active { + background-color: #c67605 \9; +} +.btn-danger { + color: #ffffff; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); + background-color: #da4f49; + background-image: -moz-linear-gradient(top, #ee5f5b, #bd362f); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#ee5f5b), to(#bd362f)); + background-image: -webkit-linear-gradient(top, #ee5f5b, #bd362f); + background-image: -o-linear-gradient(top, #ee5f5b, #bd362f); + background-image: linear-gradient(to bottom, #ee5f5b, #bd362f); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffee5f5b', endColorstr='#ffbd362f', GradientType=0); + border-color: #bd362f #bd362f #802420; + border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); + *background-color: #bd362f; + /* Darken IE7 buttons by default so they stand out more given they won't have borders */ + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); +} +.btn-danger:hover, +.btn-danger:focus, +.btn-danger:active, +.btn-danger.active, +.btn-danger.disabled, +.btn-danger[disabled] { + color: #ffffff; + background-color: #bd362f; + *background-color: #a9302a; +} +.btn-danger:active, +.btn-danger.active { + background-color: #942a25 \9; +} +.btn-success { + color: #ffffff; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); + background-color: #5bb75b; + background-image: -moz-linear-gradient(top, #62c462, #51a351); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#62c462), to(#51a351)); + background-image: -webkit-linear-gradient(top, #62c462, #51a351); + background-image: -o-linear-gradient(top, #62c462, #51a351); + background-image: linear-gradient(to bottom, #62c462, #51a351); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff62c462', endColorstr='#ff51a351', GradientType=0); + border-color: #51a351 #51a351 #387038; + border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); + *background-color: #51a351; + /* Darken IE7 buttons by default so they stand out more given they won't have borders */ + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); +} +.btn-success:hover, +.btn-success:focus, +.btn-success:active, +.btn-success.active, +.btn-success.disabled, +.btn-success[disabled] { + color: #ffffff; + background-color: #51a351; + *background-color: #499249; +} +.btn-success:active, +.btn-success.active { + background-color: #408140 \9; +} +.btn-info { + color: #ffffff; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); + background-color: #49afcd; + background-image: -moz-linear-gradient(top, #5bc0de, #2f96b4); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#5bc0de), to(#2f96b4)); + background-image: -webkit-linear-gradient(top, #5bc0de, #2f96b4); + background-image: -o-linear-gradient(top, #5bc0de, #2f96b4); + background-image: linear-gradient(to bottom, #5bc0de, #2f96b4); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff2f96b4', GradientType=0); + border-color: #2f96b4 #2f96b4 #1f6377; + border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); + *background-color: #2f96b4; + /* Darken IE7 buttons by default so they stand out more given they won't have borders */ + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); +} +.btn-info:hover, +.btn-info:focus, +.btn-info:active, +.btn-info.active, +.btn-info.disabled, +.btn-info[disabled] { + color: #ffffff; + background-color: #2f96b4; + *background-color: #2a85a0; +} +.btn-info:active, +.btn-info.active { + background-color: #24748c \9; +} +.btn-inverse { + color: #ffffff; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); + background-color: #363636; + background-image: -moz-linear-gradient(top, #444444, #222222); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#444444), to(#222222)); + background-image: -webkit-linear-gradient(top, #444444, #222222); + background-image: -o-linear-gradient(top, #444444, #222222); + background-image: linear-gradient(to bottom, #444444, #222222); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff444444', endColorstr='#ff222222', GradientType=0); + border-color: #222222 #222222 #000000; + border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); + *background-color: #222222; + /* Darken IE7 buttons by default so they stand out more given they won't have borders */ + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); +} +.btn-inverse:hover, +.btn-inverse:focus, +.btn-inverse:active, +.btn-inverse.active, +.btn-inverse.disabled, +.btn-inverse[disabled] { + color: #ffffff; + background-color: #222222; + *background-color: #151515; +} +.btn-inverse:active, +.btn-inverse.active { + background-color: #080808 \9; +} +button.btn, +input[type="submit"].btn { + *padding-top: 3px; + *padding-bottom: 3px; +} +button.btn::-moz-focus-inner, +input[type="submit"].btn::-moz-focus-inner { + padding: 0; + border: 0; +} +button.btn.btn-large, +input[type="submit"].btn.btn-large { + *padding-top: 7px; + *padding-bottom: 7px; +} +button.btn.btn-small, +input[type="submit"].btn.btn-small { + *padding-top: 3px; + *padding-bottom: 3px; +} +button.btn.btn-mini, +input[type="submit"].btn.btn-mini { + *padding-top: 1px; + *padding-bottom: 1px; +} +.btn-link, +.btn-link:active, +.btn-link[disabled] { + background-color: transparent; + background-image: none; + -webkit-box-shadow: none; + -moz-box-shadow: none; + box-shadow: none; +} +.btn-link { + border-color: transparent; + cursor: pointer; + color: #0088cc; + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; +} +.btn-link:hover, +.btn-link:focus { + color: #005580; + text-decoration: underline; + background-color: transparent; +} +.btn-link[disabled]:hover, +.btn-link[disabled]:focus { + color: #333333; + text-decoration: none; +} +.btn-group { + position: relative; + display: inline-block; + *display: inline; + /* IE7 inline-block hack */ + *zoom: 1; + font-size: 0; + vertical-align: middle; + white-space: nowrap; + *margin-left: .3em; +} +.btn-group:first-child { + *margin-left: 0; +} +.btn-group + .btn-group { + margin-left: 5px; +} +.btn-toolbar { + font-size: 0; + margin-top: 10.5px; + margin-bottom: 10.5px; +} +.btn-toolbar > .btn + .btn, +.btn-toolbar > .btn-group + .btn, +.btn-toolbar > .btn + .btn-group { + margin-left: 5px; +} +.btn-group > .btn { + position: relative; + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; +} +.btn-group > .btn + .btn { + margin-left: -1px; +} +.btn-group > .btn, +.btn-group > .dropdown-menu, +.btn-group > .popover { + font-size: 16px; +} +.btn-group > .btn-mini { + font-size: 12px; +} +.btn-group > .btn-small { + font-size: 13.6px; +} +.btn-group > .btn-large { + font-size: 20px; +} +.btn-group > .btn:first-child { + margin-left: 0; + -webkit-border-top-left-radius: 4px; + -moz-border-radius-topleft: 4px; + border-top-left-radius: 4px; + -webkit-border-bottom-left-radius: 4px; + -moz-border-radius-bottomleft: 4px; + border-bottom-left-radius: 4px; +} +.btn-group > .btn:last-child, +.btn-group > .dropdown-toggle { + -webkit-border-top-right-radius: 4px; + -moz-border-radius-topright: 4px; + border-top-right-radius: 4px; + -webkit-border-bottom-right-radius: 4px; + -moz-border-radius-bottomright: 4px; + border-bottom-right-radius: 4px; +} +.btn-group > .btn.large:first-child { + margin-left: 0; + -webkit-border-top-left-radius: 6px; + -moz-border-radius-topleft: 6px; + border-top-left-radius: 6px; + -webkit-border-bottom-left-radius: 6px; + -moz-border-radius-bottomleft: 6px; + border-bottom-left-radius: 6px; +} +.btn-group > .btn.large:last-child, +.btn-group > .large.dropdown-toggle { + -webkit-border-top-right-radius: 6px; + -moz-border-radius-topright: 6px; + border-top-right-radius: 6px; + -webkit-border-bottom-right-radius: 6px; + -moz-border-radius-bottomright: 6px; + border-bottom-right-radius: 6px; +} +.btn-group > .btn:hover, +.btn-group > .btn:focus, +.btn-group > .btn:active, +.btn-group > .btn.active { + z-index: 2; +} +.btn-group .dropdown-toggle:active, +.btn-group.open .dropdown-toggle { + outline: 0; +} +.btn-group > .btn + .dropdown-toggle { + padding-left: 8px; + padding-right: 8px; + -webkit-box-shadow: inset 1px 0 0 rgba(255,255,255,.125), inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05); + -moz-box-shadow: inset 1px 0 0 rgba(255,255,255,.125), inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05); + box-shadow: inset 1px 0 0 rgba(255,255,255,.125), inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05); + *padding-top: 5px; + *padding-bottom: 5px; +} +.btn-group > .btn-mini + .dropdown-toggle { + padding-left: 5px; + padding-right: 5px; + *padding-top: 2px; + *padding-bottom: 2px; +} +.btn-group > .btn-small + .dropdown-toggle { + *padding-top: 5px; + *padding-bottom: 4px; +} +.btn-group > .btn-large + .dropdown-toggle { + padding-left: 12px; + padding-right: 12px; + *padding-top: 7px; + *padding-bottom: 7px; +} +.btn-group.open .dropdown-toggle { + background-image: none; + -webkit-box-shadow: inset 0 2px 4px rgba(0,0,0,.15), 0 1px 2px rgba(0,0,0,.05); + -moz-box-shadow: inset 0 2px 4px rgba(0,0,0,.15), 0 1px 2px rgba(0,0,0,.05); + box-shadow: inset 0 2px 4px rgba(0,0,0,.15), 0 1px 2px rgba(0,0,0,.05); +} +.btn-group.open .btn.dropdown-toggle { + background-color: #e6e6e6; +} +.btn-group.open .btn-primary.dropdown-toggle { + background-color: #0044cc; +} +.btn-group.open .btn-warning.dropdown-toggle { + background-color: #f89406; +} +.btn-group.open .btn-danger.dropdown-toggle { + background-color: #bd362f; +} +.btn-group.open .btn-success.dropdown-toggle { + background-color: #51a351; +} +.btn-group.open .btn-info.dropdown-toggle { + background-color: #2f96b4; +} +.btn-group.open .btn-inverse.dropdown-toggle { + background-color: #222222; +} +.btn .caret { + margin-top: 8px; + margin-left: 0; +} +.btn-large .caret { + margin-top: 6px; +} +.btn-large .caret { + border-left-width: 5px; + border-right-width: 5px; + border-top-width: 5px; +} +.btn-mini .caret, +.btn-small .caret { + margin-top: 8px; +} +.dropup .btn-large .caret { + border-bottom-width: 5px; +} +.btn-primary .caret, +.btn-warning .caret, +.btn-danger .caret, +.btn-info .caret, +.btn-success .caret, +.btn-inverse .caret { + border-top-color: #ffffff; + border-bottom-color: #ffffff; +} +.btn-group-vertical { + display: inline-block; + *display: inline; + /* IE7 inline-block hack */ + *zoom: 1; +} +.btn-group-vertical > .btn { + display: block; + float: none; + max-width: 100%; + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; +} +.btn-group-vertical > .btn + .btn { + margin-left: 0; + margin-top: -1px; +} +.btn-group-vertical > .btn:first-child { + -webkit-border-radius: 4px 4px 0 0; + -moz-border-radius: 4px 4px 0 0; + border-radius: 4px 4px 0 0; +} +.btn-group-vertical > .btn:last-child { + -webkit-border-radius: 0 0 4px 4px; + -moz-border-radius: 0 0 4px 4px; + border-radius: 0 0 4px 4px; +} +.btn-group-vertical > .btn-large:first-child { + -webkit-border-radius: 6px 6px 0 0; + -moz-border-radius: 6px 6px 0 0; + border-radius: 6px 6px 0 0; +} +.btn-group-vertical > .btn-large:last-child { + -webkit-border-radius: 0 0 6px 6px; + -moz-border-radius: 0 0 6px 6px; + border-radius: 0 0 6px 6px; +} +.alert { + padding: 8px 35px 8px 14px; + margin-bottom: 21px; + text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5); + background-color: #fcf8e3; + border: 1px solid #fbeed5; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; +} +.alert, +.alert h4 { + color: #c09853; +} +.alert h4 { + margin: 0; +} +.alert .close { + position: relative; + top: -2px; + right: -21px; + line-height: 21px; +} +.alert-success { + background-color: #dff0d8; + border-color: #d6e9c6; + color: #468847; +} +.alert-success h4 { + color: #468847; +} +.alert-danger, +.alert-error { + background-color: #f2dede; + border-color: #eed3d7; + color: #b94a48; +} +.alert-danger h4, +.alert-error h4 { + color: #b94a48; +} +.alert-info { + background-color: #d9edf7; + border-color: #bce8f1; + color: #3a87ad; +} +.alert-info h4 { + color: #3a87ad; +} +.alert-block { + padding-top: 14px; + padding-bottom: 14px; +} +.alert-block > p, +.alert-block > ul { + margin-bottom: 0; +} +.alert-block p + p { + margin-top: 5px; +} +.nav { + margin-left: 0; + margin-bottom: 21px; + list-style: none; +} +.nav > li > a { + display: block; +} +.nav > li > a:hover, +.nav > li > a:focus { + text-decoration: none; + background-color: #eeeeee; +} +.nav > li > a > img { + max-width: none; +} +.nav > .pull-right { + float: right; +} +.nav-header { + display: block; + padding: 3px 15px; + font-size: 11px; + font-weight: bold; + line-height: 21px; + color: #999999; + text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5); + text-transform: uppercase; +} +.nav li + .nav-header { + margin-top: 9px; +} +.nav-list { + padding-left: 15px; + padding-right: 15px; + margin-bottom: 0; +} +.nav-list > li > a, +.nav-list .nav-header { + margin-left: -15px; + margin-right: -15px; + text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5); +} +.nav-list > li > a { + padding: 3px 15px; +} +.nav-list > .active > a, +.nav-list > .active > a:hover, +.nav-list > .active > a:focus { + color: #ffffff; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.2); + background-color: #0088cc; +} +.nav-list [class^="icon-"], +.nav-list [class*=" icon-"] { + margin-right: 2px; +} +.nav-list .divider { + *width: 100%; + height: 1px; + margin: 9.5px 1px; + *margin: -5px 0 5px; + overflow: hidden; + background-color: #e5e5e5; + border-bottom: 1px solid #ffffff; +} +.nav-tabs, +.nav-pills { + *zoom: 1; +} +.nav-tabs:before, +.nav-pills:before, +.nav-tabs:after, +.nav-pills:after { + display: table; + content: ""; + line-height: 0; +} +.nav-tabs:after, +.nav-pills:after { + clear: both; +} +.nav-tabs > li, +.nav-pills > li { + float: left; +} +.nav-tabs > li > a, +.nav-pills > li > a { + padding-right: 12px; + padding-left: 12px; + margin-right: 2px; + line-height: 14px; +} +.nav-tabs { + border-bottom: 1px solid #ddd; +} +.nav-tabs > li { + margin-bottom: -1px; +} +.nav-tabs > li > a { + padding-top: 8px; + padding-bottom: 8px; + line-height: 21px; + border: 1px solid transparent; + -webkit-border-radius: 4px 4px 0 0; + -moz-border-radius: 4px 4px 0 0; + border-radius: 4px 4px 0 0; +} +.nav-tabs > li > a:hover, +.nav-tabs > li > a:focus { + border-color: #eeeeee #eeeeee #dddddd; +} +.nav-tabs > .active > a, +.nav-tabs > .active > a:hover, +.nav-tabs > .active > a:focus { + color: #555555; + background-color: #ffffff; + border: 1px solid #ddd; + border-bottom-color: transparent; + cursor: default; +} +.nav-pills > li > a { + padding-top: 8px; + padding-bottom: 8px; + margin-top: 2px; + margin-bottom: 2px; + -webkit-border-radius: 5px; + -moz-border-radius: 5px; + border-radius: 5px; +} +.nav-pills > .active > a, +.nav-pills > .active > a:hover, +.nav-pills > .active > a:focus { + color: #ffffff; + background-color: #0088cc; +} +.nav-stacked > li { + float: none; +} +.nav-stacked > li > a { + margin-right: 0; +} +.nav-tabs.nav-stacked { + border-bottom: 0; +} +.nav-tabs.nav-stacked > li > a { + border: 1px solid #ddd; + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; +} +.nav-tabs.nav-stacked > li:first-child > a { + -webkit-border-top-right-radius: 4px; + -moz-border-radius-topright: 4px; + border-top-right-radius: 4px; + -webkit-border-top-left-radius: 4px; + -moz-border-radius-topleft: 4px; + border-top-left-radius: 4px; +} +.nav-tabs.nav-stacked > li:last-child > a { + -webkit-border-bottom-right-radius: 4px; + -moz-border-radius-bottomright: 4px; + border-bottom-right-radius: 4px; + -webkit-border-bottom-left-radius: 4px; + -moz-border-radius-bottomleft: 4px; + border-bottom-left-radius: 4px; +} +.nav-tabs.nav-stacked > li > a:hover, +.nav-tabs.nav-stacked > li > a:focus { + border-color: #ddd; + z-index: 2; +} +.nav-pills.nav-stacked > li > a { + margin-bottom: 3px; +} +.nav-pills.nav-stacked > li:last-child > a { + margin-bottom: 1px; +} +.nav-tabs .dropdown-menu { + -webkit-border-radius: 0 0 6px 6px; + -moz-border-radius: 0 0 6px 6px; + border-radius: 0 0 6px 6px; +} +.nav-pills .dropdown-menu { + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; +} +.nav .dropdown-toggle .caret { + border-top-color: #0088cc; + border-bottom-color: #0088cc; + margin-top: 6px; +} +.nav .dropdown-toggle:hover .caret, +.nav .dropdown-toggle:focus .caret { + border-top-color: #005580; + border-bottom-color: #005580; +} +/* move down carets for tabs */ +.nav-tabs .dropdown-toggle .caret { + margin-top: 8px; +} +.nav .active .dropdown-toggle .caret { + border-top-color: #fff; + border-bottom-color: #fff; +} +.nav-tabs .active .dropdown-toggle .caret { + border-top-color: #555555; + border-bottom-color: #555555; +} +.nav > .dropdown.active > a:hover, +.nav > .dropdown.active > a:focus { + cursor: pointer; +} +.nav-tabs .open .dropdown-toggle, +.nav-pills .open .dropdown-toggle, +.nav > li.dropdown.open.active > a:hover, +.nav > li.dropdown.open.active > a:focus { + color: #ffffff; + background-color: #999999; + border-color: #999999; +} +.nav li.dropdown.open .caret, +.nav li.dropdown.open.active .caret, +.nav li.dropdown.open a:hover .caret, +.nav li.dropdown.open a:focus .caret { + border-top-color: #ffffff; + border-bottom-color: #ffffff; + opacity: 1; + filter: alpha(opacity=100); +} +.tabs-stacked .open > a:hover, +.tabs-stacked .open > a:focus { + border-color: #999999; +} +.tabbable { + *zoom: 1; +} +.tabbable:before, +.tabbable:after { + display: table; + content: ""; + line-height: 0; +} +.tabbable:after { + clear: both; +} +.tab-content { + overflow: auto; +} +.tabs-below > .nav-tabs, +.tabs-right > .nav-tabs, +.tabs-left > .nav-tabs { + border-bottom: 0; +} +.tab-content > .tab-pane, +.pill-content > .pill-pane { + display: none; +} +.tab-content > .active, +.pill-content > .active { + display: block; +} +.tabs-below > .nav-tabs { + border-top: 1px solid #ddd; +} +.tabs-below > .nav-tabs > li { + margin-top: -1px; + margin-bottom: 0; +} +.tabs-below > .nav-tabs > li > a { + -webkit-border-radius: 0 0 4px 4px; + -moz-border-radius: 0 0 4px 4px; + border-radius: 0 0 4px 4px; +} +.tabs-below > .nav-tabs > li > a:hover, +.tabs-below > .nav-tabs > li > a:focus { + border-bottom-color: transparent; + border-top-color: #ddd; +} +.tabs-below > .nav-tabs > .active > a, +.tabs-below > .nav-tabs > .active > a:hover, +.tabs-below > .nav-tabs > .active > a:focus { + border-color: transparent #ddd #ddd #ddd; +} +.tabs-left > .nav-tabs > li, +.tabs-right > .nav-tabs > li { + float: none; +} +.tabs-left > .nav-tabs > li > a, +.tabs-right > .nav-tabs > li > a { + min-width: 74px; + margin-right: 0; + margin-bottom: 3px; +} +.tabs-left > .nav-tabs { + float: left; + margin-right: 19px; + border-right: 1px solid #ddd; +} +.tabs-left > .nav-tabs > li > a { + margin-right: -1px; + -webkit-border-radius: 4px 0 0 4px; + -moz-border-radius: 4px 0 0 4px; + border-radius: 4px 0 0 4px; +} +.tabs-left > .nav-tabs > li > a:hover, +.tabs-left > .nav-tabs > li > a:focus { + border-color: #eeeeee #dddddd #eeeeee #eeeeee; +} +.tabs-left > .nav-tabs .active > a, +.tabs-left > .nav-tabs .active > a:hover, +.tabs-left > .nav-tabs .active > a:focus { + border-color: #ddd transparent #ddd #ddd; + *border-right-color: #ffffff; +} +.tabs-right > .nav-tabs { + float: right; + margin-left: 19px; + border-left: 1px solid #ddd; +} +.tabs-right > .nav-tabs > li > a { + margin-left: -1px; + -webkit-border-radius: 0 4px 4px 0; + -moz-border-radius: 0 4px 4px 0; + border-radius: 0 4px 4px 0; +} +.tabs-right > .nav-tabs > li > a:hover, +.tabs-right > .nav-tabs > li > a:focus { + border-color: #eeeeee #eeeeee #eeeeee #dddddd; +} +.tabs-right > .nav-tabs .active > a, +.tabs-right > .nav-tabs .active > a:hover, +.tabs-right > .nav-tabs .active > a:focus { + border-color: #ddd #ddd #ddd transparent; + *border-left-color: #ffffff; +} +.nav > .disabled > a { + color: #999999; +} +.nav > .disabled > a:hover, +.nav > .disabled > a:focus { + text-decoration: none; + background-color: transparent; + cursor: default; +} +.navbar { + overflow: visible; + margin-bottom: 21px; + *position: relative; + *z-index: 2; +} +.navbar-inner { + min-height: 40px; + padding-left: 20px; + padding-right: 20px; + background-color: #fafafa; + background-image: -moz-linear-gradient(top, #ffffff, #f2f2f2); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#ffffff), to(#f2f2f2)); + background-image: -webkit-linear-gradient(top, #ffffff, #f2f2f2); + background-image: -o-linear-gradient(top, #ffffff, #f2f2f2); + background-image: linear-gradient(to bottom, #ffffff, #f2f2f2); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#fff2f2f2', GradientType=0); + border: 1px solid #d4d4d4; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; + -webkit-box-shadow: 0 1px 4px rgba(0, 0, 0, 0.065); + -moz-box-shadow: 0 1px 4px rgba(0, 0, 0, 0.065); + box-shadow: 0 1px 4px rgba(0, 0, 0, 0.065); + *zoom: 1; +} +.navbar-inner:before, +.navbar-inner:after { + display: table; + content: ""; + line-height: 0; +} +.navbar-inner:after { + clear: both; +} +.navbar .container { + width: auto; +} +.nav-collapse.collapse { + height: auto; + overflow: visible; +} +.navbar .brand { + float: left; + display: block; + padding: 9.5px 20px 9.5px; + margin-left: -20px; + font-size: 20px; + font-weight: 200; + color: #777777; + text-shadow: 0 1px 0 #ffffff; +} +.navbar .brand:hover, +.navbar .brand:focus { + text-decoration: none; +} +.navbar-text { + margin-bottom: 0; + line-height: 40px; + color: #777777; +} +.navbar-link { + color: #777777; +} +.navbar-link:hover, +.navbar-link:focus { + color: #333333; +} +.navbar .divider-vertical { + height: 40px; + margin: 0 9px; + border-left: 1px solid #f2f2f2; + border-right: 1px solid #ffffff; +} +.navbar .btn, +.navbar .btn-group { + margin-top: 5px; +} +.navbar .btn-group .btn, +.navbar .input-prepend .btn, +.navbar .input-append .btn, +.navbar .input-prepend .btn-group, +.navbar .input-append .btn-group { + margin-top: 0; +} +.navbar-form { + margin-bottom: 0; + *zoom: 1; +} +.navbar-form:before, +.navbar-form:after { + display: table; + content: ""; + line-height: 0; +} +.navbar-form:after { + clear: both; +} +.navbar-form input, +.navbar-form select, +.navbar-form .radio, +.navbar-form .checkbox { + margin-top: 5px; +} +.navbar-form input, +.navbar-form select, +.navbar-form .btn { + display: inline-block; + margin-bottom: 0; +} +.navbar-form input[type="image"], +.navbar-form input[type="checkbox"], +.navbar-form input[type="radio"] { + margin-top: 3px; +} +.navbar-form .input-append, +.navbar-form .input-prepend { + margin-top: 5px; + white-space: nowrap; +} +.navbar-form .input-append input, +.navbar-form .input-prepend input { + margin-top: 0; +} +.navbar-search { + position: relative; + float: left; + margin-top: 5px; + margin-bottom: 0; +} +.navbar-search .search-query { + margin-bottom: 0; + padding: 4px 14px; + font-family: 'Source Sans Pro', sans-serif; + font-size: 13px; + font-weight: normal; + line-height: 1; + -webkit-border-radius: 15px; + -moz-border-radius: 15px; + border-radius: 15px; +} +.navbar-static-top { + position: static; + margin-bottom: 0; +} +.navbar-static-top .navbar-inner { + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; +} +.navbar-fixed-top, +.navbar-fixed-bottom { + position: fixed; + right: 0; + left: 0; + z-index: 1030; + margin-bottom: 0; +} +.navbar-fixed-top .navbar-inner, +.navbar-static-top .navbar-inner { + border-width: 0 0 1px; +} +.navbar-fixed-bottom .navbar-inner { + border-width: 1px 0 0; +} +.navbar-fixed-top .navbar-inner, +.navbar-fixed-bottom .navbar-inner { + padding-left: 0; + padding-right: 0; + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; +} +.navbar-static-top .container, +.navbar-fixed-top .container, +.navbar-fixed-bottom .container { + width: 940px; +} +.navbar-fixed-top { + top: 0; +} +.navbar-fixed-top .navbar-inner, +.navbar-static-top .navbar-inner { + -webkit-box-shadow: 0 1px 10px rgba(0,0,0,.1); + -moz-box-shadow: 0 1px 10px rgba(0,0,0,.1); + box-shadow: 0 1px 10px rgba(0,0,0,.1); +} +.navbar-fixed-bottom { + bottom: 0; +} +.navbar-fixed-bottom .navbar-inner { + -webkit-box-shadow: 0 -1px 10px rgba(0,0,0,.1); + -moz-box-shadow: 0 -1px 10px rgba(0,0,0,.1); + box-shadow: 0 -1px 10px rgba(0,0,0,.1); +} +.navbar .nav { + position: relative; + left: 0; + display: block; + float: left; + margin: 0 10px 0 0; +} +.navbar .nav.pull-right { + float: right; + margin-right: 0; +} +.navbar .nav > li { + float: left; +} +.navbar .nav > li > a { + float: none; + padding: 9.5px 15px 9.5px; + color: #777777; + text-decoration: none; + text-shadow: 0 1px 0 #ffffff; +} +.navbar .nav .dropdown-toggle .caret { + margin-top: 8px; +} +.navbar .nav > li > a:focus, +.navbar .nav > li > a:hover { + background-color: transparent; + color: #333333; + text-decoration: none; +} +.navbar .nav > .active > a, +.navbar .nav > .active > a:hover, +.navbar .nav > .active > a:focus { + color: #555555; + text-decoration: none; + background-color: #e5e5e5; + -webkit-box-shadow: inset 0 3px 8px rgba(0, 0, 0, 0.125); + -moz-box-shadow: inset 0 3px 8px rgba(0, 0, 0, 0.125); + box-shadow: inset 0 3px 8px rgba(0, 0, 0, 0.125); +} +.navbar .btn-navbar { + display: none; + float: right; + padding: 7px 10px; + margin-left: 5px; + margin-right: 5px; + color: #ffffff; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); + background-color: #ededed; + background-image: -moz-linear-gradient(top, #f2f2f2, #e5e5e5); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#f2f2f2), to(#e5e5e5)); + background-image: -webkit-linear-gradient(top, #f2f2f2, #e5e5e5); + background-image: -o-linear-gradient(top, #f2f2f2, #e5e5e5); + background-image: linear-gradient(to bottom, #f2f2f2, #e5e5e5); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2f2f2', endColorstr='#ffe5e5e5', GradientType=0); + border-color: #e5e5e5 #e5e5e5 #bfbfbf; + border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); + *background-color: #e5e5e5; + /* Darken IE7 buttons by default so they stand out more given they won't have borders */ + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); + -webkit-box-shadow: inset 0 1px 0 rgba(255,255,255,.1), 0 1px 0 rgba(255,255,255,.075); + -moz-box-shadow: inset 0 1px 0 rgba(255,255,255,.1), 0 1px 0 rgba(255,255,255,.075); + box-shadow: inset 0 1px 0 rgba(255,255,255,.1), 0 1px 0 rgba(255,255,255,.075); +} +.navbar .btn-navbar:hover, +.navbar .btn-navbar:focus, +.navbar .btn-navbar:active, +.navbar .btn-navbar.active, +.navbar .btn-navbar.disabled, +.navbar .btn-navbar[disabled] { + color: #ffffff; + background-color: #e5e5e5; + *background-color: #d9d9d9; +} +.navbar .btn-navbar:active, +.navbar .btn-navbar.active { + background-color: #cccccc \9; +} +.navbar .btn-navbar .icon-bar { + display: block; + width: 18px; + height: 2px; + background-color: #f5f5f5; + -webkit-border-radius: 1px; + -moz-border-radius: 1px; + border-radius: 1px; + -webkit-box-shadow: 0 1px 0 rgba(0, 0, 0, 0.25); + -moz-box-shadow: 0 1px 0 rgba(0, 0, 0, 0.25); + box-shadow: 0 1px 0 rgba(0, 0, 0, 0.25); +} +.btn-navbar .icon-bar + .icon-bar { + margin-top: 3px; +} +.navbar .nav > li > .dropdown-menu:before { + content: ''; + display: inline-block; + border-left: 7px solid transparent; + border-right: 7px solid transparent; + border-bottom: 7px solid #ccc; + border-bottom-color: rgba(0, 0, 0, 0.2); + position: absolute; + top: -7px; + left: 9px; +} +.navbar .nav > li > .dropdown-menu:after { + content: ''; + display: inline-block; + border-left: 6px solid transparent; + border-right: 6px solid transparent; + border-bottom: 6px solid #ffffff; + position: absolute; + top: -6px; + left: 10px; +} +.navbar-fixed-bottom .nav > li > .dropdown-menu:before { + border-top: 7px solid #ccc; + border-top-color: rgba(0, 0, 0, 0.2); + border-bottom: 0; + bottom: -7px; + top: auto; +} +.navbar-fixed-bottom .nav > li > .dropdown-menu:after { + border-top: 6px solid #ffffff; + border-bottom: 0; + bottom: -6px; + top: auto; +} +.navbar .nav li.dropdown > a:hover .caret, +.navbar .nav li.dropdown > a:focus .caret { + border-top-color: #333333; + border-bottom-color: #333333; +} +.navbar .nav li.dropdown.open > .dropdown-toggle, +.navbar .nav li.dropdown.active > .dropdown-toggle, +.navbar .nav li.dropdown.open.active > .dropdown-toggle { + background-color: #e5e5e5; + color: #555555; +} +.navbar .nav li.dropdown > .dropdown-toggle .caret { + border-top-color: #777777; + border-bottom-color: #777777; +} +.navbar .nav li.dropdown.open > .dropdown-toggle .caret, +.navbar .nav li.dropdown.active > .dropdown-toggle .caret, +.navbar .nav li.dropdown.open.active > .dropdown-toggle .caret { + border-top-color: #555555; + border-bottom-color: #555555; +} +.navbar .pull-right > li > .dropdown-menu, +.navbar .nav > li > .dropdown-menu.pull-right { + left: auto; + right: 0; +} +.navbar .pull-right > li > .dropdown-menu:before, +.navbar .nav > li > .dropdown-menu.pull-right:before { + left: auto; + right: 12px; +} +.navbar .pull-right > li > .dropdown-menu:after, +.navbar .nav > li > .dropdown-menu.pull-right:after { + left: auto; + right: 13px; +} +.navbar .pull-right > li > .dropdown-menu .dropdown-menu, +.navbar .nav > li > .dropdown-menu.pull-right .dropdown-menu { + left: auto; + right: 100%; + margin-left: 0; + margin-right: -1px; + -webkit-border-radius: 6px 0 6px 6px; + -moz-border-radius: 6px 0 6px 6px; + border-radius: 6px 0 6px 6px; +} +.navbar-inverse .navbar-inner { + background-color: #1b1b1b; + background-image: -moz-linear-gradient(top, #222222, #111111); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#222222), to(#111111)); + background-image: -webkit-linear-gradient(top, #222222, #111111); + background-image: -o-linear-gradient(top, #222222, #111111); + background-image: linear-gradient(to bottom, #222222, #111111); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff222222', endColorstr='#ff111111', GradientType=0); + border-color: #252525; +} +.navbar-inverse .brand, +.navbar-inverse .nav > li > a { + color: #999999; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); +} +.navbar-inverse .brand:hover, +.navbar-inverse .nav > li > a:hover, +.navbar-inverse .brand:focus, +.navbar-inverse .nav > li > a:focus { + color: #ffffff; +} +.navbar-inverse .brand { + color: #999999; +} +.navbar-inverse .navbar-text { + color: #999999; +} +.navbar-inverse .nav > li > a:focus, +.navbar-inverse .nav > li > a:hover { + background-color: transparent; + color: #ffffff; +} +.navbar-inverse .nav .active > a, +.navbar-inverse .nav .active > a:hover, +.navbar-inverse .nav .active > a:focus { + color: #ffffff; + background-color: #111111; +} +.navbar-inverse .navbar-link { + color: #999999; +} +.navbar-inverse .navbar-link:hover, +.navbar-inverse .navbar-link:focus { + color: #ffffff; +} +.navbar-inverse .divider-vertical { + border-left-color: #111111; + border-right-color: #222222; +} +.navbar-inverse .nav li.dropdown.open > .dropdown-toggle, +.navbar-inverse .nav li.dropdown.active > .dropdown-toggle, +.navbar-inverse .nav li.dropdown.open.active > .dropdown-toggle { + background-color: #111111; + color: #ffffff; +} +.navbar-inverse .nav li.dropdown > a:hover .caret, +.navbar-inverse .nav li.dropdown > a:focus .caret { + border-top-color: #ffffff; + border-bottom-color: #ffffff; +} +.navbar-inverse .nav li.dropdown > .dropdown-toggle .caret { + border-top-color: #999999; + border-bottom-color: #999999; +} +.navbar-inverse .nav li.dropdown.open > .dropdown-toggle .caret, +.navbar-inverse .nav li.dropdown.active > .dropdown-toggle .caret, +.navbar-inverse .nav li.dropdown.open.active > .dropdown-toggle .caret { + border-top-color: #ffffff; + border-bottom-color: #ffffff; +} +.navbar-inverse .navbar-search .search-query { + color: #ffffff; + background-color: #515151; + border-color: #111111; + -webkit-box-shadow: inset 0 1px 2px rgba(0,0,0,.1), 0 1px 0 rgba(255,255,255,.15); + -moz-box-shadow: inset 0 1px 2px rgba(0,0,0,.1), 0 1px 0 rgba(255,255,255,.15); + box-shadow: inset 0 1px 2px rgba(0,0,0,.1), 0 1px 0 rgba(255,255,255,.15); + -webkit-transition: none; + -moz-transition: none; + -o-transition: none; + transition: none; +} +.navbar-inverse .navbar-search .search-query:-moz-placeholder { + color: #cccccc; +} +.navbar-inverse .navbar-search .search-query:-ms-input-placeholder { + color: #cccccc; +} +.navbar-inverse .navbar-search .search-query::-webkit-input-placeholder { + color: #cccccc; +} +.navbar-inverse .navbar-search .search-query:focus, +.navbar-inverse .navbar-search .search-query.focused { + padding: 5px 15px; + color: #333333; + text-shadow: 0 1px 0 #ffffff; + background-color: #ffffff; + border: 0; + -webkit-box-shadow: 0 0 3px rgba(0, 0, 0, 0.15); + -moz-box-shadow: 0 0 3px rgba(0, 0, 0, 0.15); + box-shadow: 0 0 3px rgba(0, 0, 0, 0.15); + outline: 0; +} +.navbar-inverse .btn-navbar { + color: #ffffff; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); + background-color: #0e0e0e; + background-image: -moz-linear-gradient(top, #151515, #040404); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#151515), to(#040404)); + background-image: -webkit-linear-gradient(top, #151515, #040404); + background-image: -o-linear-gradient(top, #151515, #040404); + background-image: linear-gradient(to bottom, #151515, #040404); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff151515', endColorstr='#ff040404', GradientType=0); + border-color: #040404 #040404 #000000; + border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); + *background-color: #040404; + /* Darken IE7 buttons by default so they stand out more given they won't have borders */ + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); +} +.navbar-inverse .btn-navbar:hover, +.navbar-inverse .btn-navbar:focus, +.navbar-inverse .btn-navbar:active, +.navbar-inverse .btn-navbar.active, +.navbar-inverse .btn-navbar.disabled, +.navbar-inverse .btn-navbar[disabled] { + color: #ffffff; + background-color: #040404; + *background-color: #000000; +} +.navbar-inverse .btn-navbar:active, +.navbar-inverse .btn-navbar.active { + background-color: #000000 \9; +} +.breadcrumb { + padding: 8px 15px; + margin: 0 0 21px; + list-style: none; + background-color: #f5f5f5; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; +} +.breadcrumb > li { + display: inline-block; + *display: inline; + /* IE7 inline-block hack */ + *zoom: 1; + text-shadow: 0 1px 0 #ffffff; +} +.breadcrumb > li > .divider { + padding: 0 5px; + color: #ccc; +} +.breadcrumb > .active { + color: #999999; +} +.pagination { + margin: 21px 0; +} +.pagination ul { + display: inline-block; + *display: inline; + /* IE7 inline-block hack */ + *zoom: 1; + margin-left: 0; + margin-bottom: 0; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; + -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05); + -moz-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05); + box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05); +} +.pagination ul > li { + display: inline; +} +.pagination ul > li > a, +.pagination ul > li > span { + float: left; + padding: 4px 12px; + line-height: 21px; + text-decoration: none; + background-color: #ffffff; + border: 1px solid #dddddd; + border-left-width: 0; +} +.pagination ul > li > a:hover, +.pagination ul > li > a:focus, +.pagination ul > .active > a, +.pagination ul > .active > span { + background-color: #f5f5f5; +} +.pagination ul > .active > a, +.pagination ul > .active > span { + color: #999999; + cursor: default; +} +.pagination ul > .disabled > span, +.pagination ul > .disabled > a, +.pagination ul > .disabled > a:hover, +.pagination ul > .disabled > a:focus { + color: #999999; + background-color: transparent; + cursor: default; +} +.pagination ul > li:first-child > a, +.pagination ul > li:first-child > span { + border-left-width: 1px; + -webkit-border-top-left-radius: 4px; + -moz-border-radius-topleft: 4px; + border-top-left-radius: 4px; + -webkit-border-bottom-left-radius: 4px; + -moz-border-radius-bottomleft: 4px; + border-bottom-left-radius: 4px; +} +.pagination ul > li:last-child > a, +.pagination ul > li:last-child > span { + -webkit-border-top-right-radius: 4px; + -moz-border-radius-topright: 4px; + border-top-right-radius: 4px; + -webkit-border-bottom-right-radius: 4px; + -moz-border-radius-bottomright: 4px; + border-bottom-right-radius: 4px; +} +.pagination-centered { + text-align: center; +} +.pagination-right { + text-align: right; +} +.pagination-large ul > li > a, +.pagination-large ul > li > span { + padding: 11px 19px; + font-size: 20px; +} +.pagination-large ul > li:first-child > a, +.pagination-large ul > li:first-child > span { + -webkit-border-top-left-radius: 6px; + -moz-border-radius-topleft: 6px; + border-top-left-radius: 6px; + -webkit-border-bottom-left-radius: 6px; + -moz-border-radius-bottomleft: 6px; + border-bottom-left-radius: 6px; +} +.pagination-large ul > li:last-child > a, +.pagination-large ul > li:last-child > span { + -webkit-border-top-right-radius: 6px; + -moz-border-radius-topright: 6px; + border-top-right-radius: 6px; + -webkit-border-bottom-right-radius: 6px; + -moz-border-radius-bottomright: 6px; + border-bottom-right-radius: 6px; +} +.pagination-mini ul > li:first-child > a, +.pagination-small ul > li:first-child > a, +.pagination-mini ul > li:first-child > span, +.pagination-small ul > li:first-child > span { + -webkit-border-top-left-radius: 3px; + -moz-border-radius-topleft: 3px; + border-top-left-radius: 3px; + -webkit-border-bottom-left-radius: 3px; + -moz-border-radius-bottomleft: 3px; + border-bottom-left-radius: 3px; +} +.pagination-mini ul > li:last-child > a, +.pagination-small ul > li:last-child > a, +.pagination-mini ul > li:last-child > span, +.pagination-small ul > li:last-child > span { + -webkit-border-top-right-radius: 3px; + -moz-border-radius-topright: 3px; + border-top-right-radius: 3px; + -webkit-border-bottom-right-radius: 3px; + -moz-border-radius-bottomright: 3px; + border-bottom-right-radius: 3px; +} +.pagination-small ul > li > a, +.pagination-small ul > li > span { + padding: 2px 10px; + font-size: 13.6px; +} +.pagination-mini ul > li > a, +.pagination-mini ul > li > span { + padding: 0 6px; + font-size: 12px; +} +.pager { + margin: 21px 0; + list-style: none; + text-align: center; + *zoom: 1; +} +.pager:before, +.pager:after { + display: table; + content: ""; + line-height: 0; +} +.pager:after { + clear: both; +} +.pager li { + display: inline; +} +.pager li > a, +.pager li > span { + display: inline-block; + padding: 5px 14px; + background-color: #fff; + border: 1px solid #ddd; + -webkit-border-radius: 15px; + -moz-border-radius: 15px; + border-radius: 15px; +} +.pager li > a:hover, +.pager li > a:focus { + text-decoration: none; + background-color: #f5f5f5; +} +.pager .next > a, +.pager .next > span { + float: right; +} +.pager .previous > a, +.pager .previous > span { + float: left; +} +.pager .disabled > a, +.pager .disabled > a:hover, +.pager .disabled > a:focus, +.pager .disabled > span { + color: #999999; + background-color: #fff; + cursor: default; +} +.modal-backdrop { + position: fixed; + top: 0; + right: 0; + bottom: 0; + left: 0; + z-index: 1040; + background-color: #000000; +} +.modal-backdrop.fade { + opacity: 0; +} +.modal-backdrop, +.modal-backdrop.fade.in { + opacity: 0.8; + filter: alpha(opacity=80); +} +.modal { + position: fixed; + top: 10%; + left: 50%; + z-index: 1050; + width: 560px; + margin-left: -280px; + background-color: #ffffff; + border: 1px solid #999; + border: 1px solid rgba(0, 0, 0, 0.3); + *border: 1px solid #999; + /* IE6-7 */ + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; + -webkit-box-shadow: 0 3px 7px rgba(0, 0, 0, 0.3); + -moz-box-shadow: 0 3px 7px rgba(0, 0, 0, 0.3); + box-shadow: 0 3px 7px rgba(0, 0, 0, 0.3); + -webkit-background-clip: padding-box; + -moz-background-clip: padding-box; + background-clip: padding-box; + outline: none; +} +.modal.fade { + -webkit-transition: opacity .3s linear, top .3s ease-out; + -moz-transition: opacity .3s linear, top .3s ease-out; + -o-transition: opacity .3s linear, top .3s ease-out; + transition: opacity .3s linear, top .3s ease-out; + top: -25%; +} +.modal.fade.in { + top: 10%; +} +.modal-header { + padding: 9px 15px; + border-bottom: 1px solid #eee; +} +.modal-header .close { + margin-top: 2px; +} +.modal-header h3 { + margin: 0; + line-height: 30px; +} +.modal-body { + position: relative; + overflow-y: auto; + max-height: 400px; + padding: 15px; +} +.modal-form { + margin-bottom: 0; +} +.modal-footer { + padding: 14px 15px 15px; + margin-bottom: 0; + text-align: right; + background-color: #f5f5f5; + border-top: 1px solid #ddd; + -webkit-border-radius: 0 0 6px 6px; + -moz-border-radius: 0 0 6px 6px; + border-radius: 0 0 6px 6px; + -webkit-box-shadow: inset 0 1px 0 #ffffff; + -moz-box-shadow: inset 0 1px 0 #ffffff; + box-shadow: inset 0 1px 0 #ffffff; + *zoom: 1; +} +.modal-footer:before, +.modal-footer:after { + display: table; + content: ""; + line-height: 0; +} +.modal-footer:after { + clear: both; +} +.modal-footer .btn + .btn { + margin-left: 5px; + margin-bottom: 0; +} +.modal-footer .btn-group .btn + .btn { + margin-left: -1px; +} +.modal-footer .btn-block + .btn-block { + margin-left: 0; +} +.tooltip { + position: absolute; + z-index: 1030; + display: block; + visibility: visible; + font-size: 11px; + line-height: 1.4; + opacity: 0; + filter: alpha(opacity=0); +} +.tooltip.in { + opacity: 0.8; + filter: alpha(opacity=80); +} +.tooltip.top { + margin-top: -3px; + padding: 5px 0; +} +.tooltip.right { + margin-left: 3px; + padding: 0 5px; +} +.tooltip.bottom { + margin-top: 3px; + padding: 5px 0; +} +.tooltip.left { + margin-left: -3px; + padding: 0 5px; +} +.tooltip-inner { + max-width: 200px; + padding: 8px; + color: #ffffff; + text-align: center; + text-decoration: none; + background-color: #000000; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; +} +.tooltip-arrow { + position: absolute; + width: 0; + height: 0; + border-color: transparent; + border-style: solid; +} +.tooltip.top .tooltip-arrow { + bottom: 0; + left: 50%; + margin-left: -5px; + border-width: 5px 5px 0; + border-top-color: #000000; +} +.tooltip.right .tooltip-arrow { + top: 50%; + left: 0; + margin-top: -5px; + border-width: 5px 5px 5px 0; + border-right-color: #000000; +} +.tooltip.left .tooltip-arrow { + top: 50%; + right: 0; + margin-top: -5px; + border-width: 5px 0 5px 5px; + border-left-color: #000000; +} +.tooltip.bottom .tooltip-arrow { + top: 0; + left: 50%; + margin-left: -5px; + border-width: 0 5px 5px; + border-bottom-color: #000000; +} +.popover { + position: absolute; + top: 0; + left: 0; + z-index: 1010; + display: none; + max-width: 276px; + padding: 1px; + text-align: left; + background-color: #ffffff; + -webkit-background-clip: padding-box; + -moz-background-clip: padding; + background-clip: padding-box; + border: 1px solid #ccc; + border: 1px solid rgba(0, 0, 0, 0.2); + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; + -webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); + -moz-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); + box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); + white-space: normal; +} +.popover.top { + margin-top: -10px; +} +.popover.right { + margin-left: 10px; +} +.popover.bottom { + margin-top: 10px; +} +.popover.left { + margin-left: -10px; +} +.popover-title { + margin: 0; + padding: 8px 14px; + font-size: 14px; + font-weight: normal; + line-height: 18px; + background-color: #f7f7f7; + border-bottom: 1px solid #ebebeb; + -webkit-border-radius: 5px 5px 0 0; + -moz-border-radius: 5px 5px 0 0; + border-radius: 5px 5px 0 0; +} +.popover-title:empty { + display: none; +} +.popover-content { + padding: 9px 14px; +} +.popover .arrow, +.popover .arrow:after { + position: absolute; + display: block; + width: 0; + height: 0; + border-color: transparent; + border-style: solid; +} +.popover .arrow { + border-width: 11px; +} +.popover .arrow:after { + border-width: 10px; + content: ""; +} +.popover.top .arrow { + left: 50%; + margin-left: -11px; + border-bottom-width: 0; + border-top-color: #999; + border-top-color: rgba(0, 0, 0, 0.25); + bottom: -11px; +} +.popover.top .arrow:after { + bottom: 1px; + margin-left: -10px; + border-bottom-width: 0; + border-top-color: #ffffff; +} +.popover.right .arrow { + top: 50%; + left: -11px; + margin-top: -11px; + border-left-width: 0; + border-right-color: #999; + border-right-color: rgba(0, 0, 0, 0.25); +} +.popover.right .arrow:after { + left: 1px; + bottom: -10px; + border-left-width: 0; + border-right-color: #ffffff; +} +.popover.bottom .arrow { + left: 50%; + margin-left: -11px; + border-top-width: 0; + border-bottom-color: #999; + border-bottom-color: rgba(0, 0, 0, 0.25); + top: -11px; +} +.popover.bottom .arrow:after { + top: 1px; + margin-left: -10px; + border-top-width: 0; + border-bottom-color: #ffffff; +} +.popover.left .arrow { + top: 50%; + right: -11px; + margin-top: -11px; + border-right-width: 0; + border-left-color: #999; + border-left-color: rgba(0, 0, 0, 0.25); +} +.popover.left .arrow:after { + right: 1px; + border-right-width: 0; + border-left-color: #ffffff; + bottom: -10px; +} +.thumbnails { + margin-left: -20px; + list-style: none; + *zoom: 1; +} +.thumbnails:before, +.thumbnails:after { + display: table; + content: ""; + line-height: 0; +} +.thumbnails:after { + clear: both; +} +.row-fluid .thumbnails { + margin-left: 0; +} +.thumbnails > li { + float: left; + margin-bottom: 21px; + margin-left: 20px; +} +.thumbnail { + display: block; + padding: 4px; + line-height: 21px; + border: 1px solid #ddd; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; + -webkit-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.055); + -moz-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.055); + box-shadow: 0 1px 3px rgba(0, 0, 0, 0.055); + -webkit-transition: all 0.2s ease-in-out; + -moz-transition: all 0.2s ease-in-out; + -o-transition: all 0.2s ease-in-out; + transition: all 0.2s ease-in-out; +} +a.thumbnail:hover, +a.thumbnail:focus { + border-color: #0088cc; + -webkit-box-shadow: 0 1px 4px rgba(0, 105, 214, 0.25); + -moz-box-shadow: 0 1px 4px rgba(0, 105, 214, 0.25); + box-shadow: 0 1px 4px rgba(0, 105, 214, 0.25); +} +.thumbnail > img { + display: block; + max-width: 100%; + margin-left: auto; + margin-right: auto; +} +.thumbnail .caption { + padding: 9px; + color: #555555; +} +.media, +.media-body { + overflow: hidden; + *overflow: visible; + zoom: 1; +} +.media, +.media .media { + margin-top: 15px; +} +.media:first-child { + margin-top: 0; +} +.media-object { + display: block; +} +.media-heading { + margin: 0 0 5px; +} +.media > .pull-left { + margin-right: 10px; +} +.media > .pull-right { + margin-left: 10px; +} +.media-list { + margin-left: 0; + list-style: none; +} +.label, +.badge { + display: inline-block; + padding: 2px 4px; + font-size: 13.536px; + font-weight: bold; + line-height: 14px; + color: #ffffff; + vertical-align: baseline; + white-space: nowrap; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); + background-color: #999999; +} +.label { + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; +} +.badge { + padding-left: 9px; + padding-right: 9px; + -webkit-border-radius: 9px; + -moz-border-radius: 9px; + border-radius: 9px; +} +.label:empty, +.badge:empty { + display: none; +} +a.label:hover, +a.label:focus, +a.badge:hover, +a.badge:focus { + color: #ffffff; + text-decoration: none; + cursor: pointer; +} +.label-important, +.badge-important { + background-color: #b94a48; +} +.label-important[href], +.badge-important[href] { + background-color: #953b39; +} +.label-warning, +.badge-warning { + background-color: #f89406; +} +.label-warning[href], +.badge-warning[href] { + background-color: #c67605; +} +.label-success, +.badge-success { + background-color: #468847; +} +.label-success[href], +.badge-success[href] { + background-color: #356635; +} +.label-info, +.badge-info { + background-color: #3a87ad; +} +.label-info[href], +.badge-info[href] { + background-color: #2d6987; +} +.label-inverse, +.badge-inverse { + background-color: #333333; +} +.label-inverse[href], +.badge-inverse[href] { + background-color: #1a1a1a; +} +.btn .label, +.btn .badge { + position: relative; + top: -1px; +} +.btn-mini .label, +.btn-mini .badge { + top: 0; +} +@-webkit-keyframes progress-bar-stripes { + from { + background-position: 40px 0; + } + to { + background-position: 0 0; + } +} +@-moz-keyframes progress-bar-stripes { + from { + background-position: 40px 0; + } + to { + background-position: 0 0; + } +} +@-ms-keyframes progress-bar-stripes { + from { + background-position: 40px 0; + } + to { + background-position: 0 0; + } +} +@-o-keyframes progress-bar-stripes { + from { + background-position: 0 0; + } + to { + background-position: 40px 0; + } +} +@keyframes progress-bar-stripes { + from { + background-position: 40px 0; + } + to { + background-position: 0 0; + } +} +.progress { + overflow: hidden; + height: 21px; + margin-bottom: 21px; + background-color: #f7f7f7; + background-image: -moz-linear-gradient(top, #f5f5f5, #f9f9f9); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#f5f5f5), to(#f9f9f9)); + background-image: -webkit-linear-gradient(top, #f5f5f5, #f9f9f9); + background-image: -o-linear-gradient(top, #f5f5f5, #f9f9f9); + background-image: linear-gradient(to bottom, #f5f5f5, #f9f9f9); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#fff9f9f9', GradientType=0); + -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1); + -moz-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1); + box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1); + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; +} +.progress .bar { + width: 0%; + height: 100%; + color: #ffffff; + float: left; + font-size: 12px; + text-align: center; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); + background-color: #0e90d2; + background-image: -moz-linear-gradient(top, #149bdf, #0480be); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#149bdf), to(#0480be)); + background-image: -webkit-linear-gradient(top, #149bdf, #0480be); + background-image: -o-linear-gradient(top, #149bdf, #0480be); + background-image: linear-gradient(to bottom, #149bdf, #0480be); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff149bdf', endColorstr='#ff0480be', GradientType=0); + -webkit-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15); + -moz-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15); + box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15); + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + -webkit-transition: width 0.6s ease; + -moz-transition: width 0.6s ease; + -o-transition: width 0.6s ease; + transition: width 0.6s ease; +} +.progress .bar + .bar { + -webkit-box-shadow: inset 1px 0 0 rgba(0,0,0,.15), inset 0 -1px 0 rgba(0,0,0,.15); + -moz-box-shadow: inset 1px 0 0 rgba(0,0,0,.15), inset 0 -1px 0 rgba(0,0,0,.15); + box-shadow: inset 1px 0 0 rgba(0,0,0,.15), inset 0 -1px 0 rgba(0,0,0,.15); +} +.progress-striped .bar { + background-color: #149bdf; + background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent)); + background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -moz-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + -webkit-background-size: 40px 40px; + -moz-background-size: 40px 40px; + -o-background-size: 40px 40px; + background-size: 40px 40px; +} +.progress.active .bar { + -webkit-animation: progress-bar-stripes 2s linear infinite; + -moz-animation: progress-bar-stripes 2s linear infinite; + -ms-animation: progress-bar-stripes 2s linear infinite; + -o-animation: progress-bar-stripes 2s linear infinite; + animation: progress-bar-stripes 2s linear infinite; +} +.progress-danger .bar, +.progress .bar-danger { + background-color: #dd514c; + background-image: -moz-linear-gradient(top, #ee5f5b, #c43c35); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#ee5f5b), to(#c43c35)); + background-image: -webkit-linear-gradient(top, #ee5f5b, #c43c35); + background-image: -o-linear-gradient(top, #ee5f5b, #c43c35); + background-image: linear-gradient(to bottom, #ee5f5b, #c43c35); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffee5f5b', endColorstr='#ffc43c35', GradientType=0); +} +.progress-danger.progress-striped .bar, +.progress-striped .bar-danger { + background-color: #ee5f5b; + background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent)); + background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -moz-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); +} +.progress-success .bar, +.progress .bar-success { + background-color: #5eb95e; + background-image: -moz-linear-gradient(top, #62c462, #57a957); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#62c462), to(#57a957)); + background-image: -webkit-linear-gradient(top, #62c462, #57a957); + background-image: -o-linear-gradient(top, #62c462, #57a957); + background-image: linear-gradient(to bottom, #62c462, #57a957); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff62c462', endColorstr='#ff57a957', GradientType=0); +} +.progress-success.progress-striped .bar, +.progress-striped .bar-success { + background-color: #62c462; + background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent)); + background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -moz-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); +} +.progress-info .bar, +.progress .bar-info { + background-color: #4bb1cf; + background-image: -moz-linear-gradient(top, #5bc0de, #339bb9); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#5bc0de), to(#339bb9)); + background-image: -webkit-linear-gradient(top, #5bc0de, #339bb9); + background-image: -o-linear-gradient(top, #5bc0de, #339bb9); + background-image: linear-gradient(to bottom, #5bc0de, #339bb9); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff339bb9', GradientType=0); +} +.progress-info.progress-striped .bar, +.progress-striped .bar-info { + background-color: #5bc0de; + background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent)); + background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -moz-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); +} +.progress-warning .bar, +.progress .bar-warning { + background-color: #faa732; + background-image: -moz-linear-gradient(top, #fbb450, #f89406); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#fbb450), to(#f89406)); + background-image: -webkit-linear-gradient(top, #fbb450, #f89406); + background-image: -o-linear-gradient(top, #fbb450, #f89406); + background-image: linear-gradient(to bottom, #fbb450, #f89406); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffbb450', endColorstr='#fff89406', GradientType=0); +} +.progress-warning.progress-striped .bar, +.progress-striped .bar-warning { + background-color: #fbb450; + background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent)); + background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -moz-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); +} +.accordion { + margin-bottom: 21px; +} +.accordion-group { + margin-bottom: 2px; + border: 1px solid #e5e5e5; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; +} +.accordion-heading { + border-bottom: 0; +} +.accordion-heading .accordion-toggle { + display: block; + padding: 8px 15px; +} +.accordion-toggle { + cursor: pointer; +} +.accordion-inner { + padding: 9px 15px; + border-top: 1px solid #e5e5e5; +} +.carousel { + position: relative; + margin-bottom: 21px; + line-height: 1; +} +.carousel-inner { + overflow: hidden; + width: 100%; + position: relative; +} +.carousel-inner > .item { + display: none; + position: relative; + -webkit-transition: 0.6s ease-in-out left; + -moz-transition: 0.6s ease-in-out left; + -o-transition: 0.6s ease-in-out left; + transition: 0.6s ease-in-out left; +} +.carousel-inner > .item > img, +.carousel-inner > .item > a > img { + display: block; + line-height: 1; +} +.carousel-inner > .active, +.carousel-inner > .next, +.carousel-inner > .prev { + display: block; +} +.carousel-inner > .active { + left: 0; +} +.carousel-inner > .next, +.carousel-inner > .prev { + position: absolute; + top: 0; + width: 100%; +} +.carousel-inner > .next { + left: 100%; +} +.carousel-inner > .prev { + left: -100%; +} +.carousel-inner > .next.left, +.carousel-inner > .prev.right { + left: 0; +} +.carousel-inner > .active.left { + left: -100%; +} +.carousel-inner > .active.right { + left: 100%; +} +.carousel-control { + position: absolute; + top: 40%; + left: 15px; + width: 40px; + height: 40px; + margin-top: -20px; + font-size: 60px; + font-weight: 100; + line-height: 30px; + color: #ffffff; + text-align: center; + background: #222222; + border: 3px solid #ffffff; + -webkit-border-radius: 23px; + -moz-border-radius: 23px; + border-radius: 23px; + opacity: 0.5; + filter: alpha(opacity=50); +} +.carousel-control.right { + left: auto; + right: 15px; +} +.carousel-control:hover, +.carousel-control:focus { + color: #ffffff; + text-decoration: none; + opacity: 0.9; + filter: alpha(opacity=90); +} +.carousel-indicators { + position: absolute; + top: 15px; + right: 15px; + z-index: 5; + margin: 0; + list-style: none; +} +.carousel-indicators li { + display: block; + float: left; + width: 10px; + height: 10px; + margin-left: 5px; + text-indent: -999px; + background-color: #ccc; + background-color: rgba(255, 255, 255, 0.25); + border-radius: 5px; +} +.carousel-indicators .active { + background-color: #fff; +} +.carousel-caption { + position: absolute; + left: 0; + right: 0; + bottom: 0; + padding: 15px; + background: #333333; + background: rgba(0, 0, 0, 0.75); +} +.carousel-caption h4, +.carousel-caption p { + color: #ffffff; + line-height: 21px; +} +.carousel-caption h4 { + margin: 0 0 5px; +} +.carousel-caption p { + margin-bottom: 0; +} +.hero-unit { + padding: 60px; + margin-bottom: 30px; + font-size: 18px; + font-weight: 200; + line-height: 31.5px; + color: inherit; + background-color: #eeeeee; + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; +} +.hero-unit h1 { + margin-bottom: 0; + font-size: 60px; + line-height: 1; + color: inherit; + letter-spacing: -1px; +} +.hero-unit li { + line-height: 31.5px; +} +.pull-right { + float: right; +} +.pull-left { + float: left; +} +.hide { + display: none; +} +.show { + display: block; +} +.invisible { + visibility: hidden; +} +.affix { + position: fixed; +} +/*! + * Bootstrap Responsive v2.3.1 + * + * Copyright 2012 Twitter, Inc + * Licensed under the Apache License v2.0 + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Designed and built with all the love in the world @twitter by @mdo and @fat. + */ +@-ms-viewport { + width: device-width; +} +.hidden { + display: none; + visibility: hidden; +} +.visible-phone { + display: none !important; +} +.visible-tablet { + display: none !important; +} +.hidden-desktop { + display: none !important; +} +.visible-desktop { + display: inherit !important; +} +@media (min-width: 768px) and (max-width: 979px) { + .hidden-desktop { + display: inherit !important; + } + .visible-desktop { + display: none !important ; + } + .visible-tablet { + display: inherit !important; + } + .hidden-tablet { + display: none !important; + } +} +@media (max-width: 767px) { + .hidden-desktop { + display: inherit !important; + } + .visible-desktop { + display: none !important; + } + .visible-phone { + display: inherit !important; + } + .hidden-phone { + display: none !important; + } +} +.visible-print { + display: none !important; +} +@media print { + .visible-print { + display: inherit !important; + } + .hidden-print { + display: none !important; + } +} +@media (min-width: 1200px) { + .row { + margin-left: -30px; + *zoom: 1; + } + .row:before, + .row:after { + display: table; + content: ""; + line-height: 0; + } + .row:after { + clear: both; + } + [class*="span"] { + float: left; + min-height: 1px; + margin-left: 30px; + } + .container, + .navbar-static-top .container, + .navbar-fixed-top .container, + .navbar-fixed-bottom .container { + width: 1170px; + } + .span12 { + width: 1170px; + } + .span11 { + width: 1070px; + } + .span10 { + width: 970px; + } + .span9 { + width: 870px; + } + .span8 { + width: 770px; + } + .span7 { + width: 670px; + } + .span6 { + width: 570px; + } + .span5 { + width: 470px; + } + .span4 { + width: 370px; + } + .span3 { + width: 270px; + } + .span2 { + width: 170px; + } + .span1 { + width: 70px; + } + .offset12 { + margin-left: 1230px; + } + .offset11 { + margin-left: 1130px; + } + .offset10 { + margin-left: 1030px; + } + .offset9 { + margin-left: 930px; + } + .offset8 { + margin-left: 830px; + } + .offset7 { + margin-left: 730px; + } + .offset6 { + margin-left: 630px; + } + .offset5 { + margin-left: 530px; + } + .offset4 { + margin-left: 430px; + } + .offset3 { + margin-left: 330px; + } + .offset2 { + margin-left: 230px; + } + .offset1 { + margin-left: 130px; + } + .row-fluid { + width: 100%; + *zoom: 1; + } + .row-fluid:before, + .row-fluid:after { + display: table; + content: ""; + line-height: 0; + } + .row-fluid:after { + clear: both; + } + .row-fluid [class*="span"] { + display: block; + width: 100%; + min-height: 31px; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + float: left; + margin-left: 2.56410256%; + *margin-left: 2.51091107%; + } + .row-fluid [class*="span"]:first-child { + margin-left: 0; + } + .row-fluid .controls-row [class*="span"] + [class*="span"] { + margin-left: 2.56410256%; + } + .row-fluid .span12 { + width: 100%; + *width: 99.94680851%; + } + .row-fluid .span11 { + width: 91.45299145%; + *width: 91.39979996%; + } + .row-fluid .span10 { + width: 82.90598291%; + *width: 82.85279142%; + } + .row-fluid .span9 { + width: 74.35897436%; + *width: 74.30578287%; + } + .row-fluid .span8 { + width: 65.81196581%; + *width: 65.75877432%; + } + .row-fluid .span7 { + width: 57.26495726%; + *width: 57.21176578%; + } + .row-fluid .span6 { + width: 48.71794872%; + *width: 48.66475723%; + } + .row-fluid .span5 { + width: 40.17094017%; + *width: 40.11774868%; + } + .row-fluid .span4 { + width: 31.62393162%; + *width: 31.57074013%; + } + .row-fluid .span3 { + width: 23.07692308%; + *width: 23.02373159%; + } + .row-fluid .span2 { + width: 14.52991453%; + *width: 14.47672304%; + } + .row-fluid .span1 { + width: 5.98290598%; + *width: 5.92971449%; + } + .row-fluid .offset12 { + margin-left: 105.12820513%; + *margin-left: 105.02182215%; + } + .row-fluid .offset12:first-child { + margin-left: 102.56410256%; + *margin-left: 102.45771959%; + } + .row-fluid .offset11 { + margin-left: 96.58119658%; + *margin-left: 96.4748136%; + } + .row-fluid .offset11:first-child { + margin-left: 94.01709402%; + *margin-left: 93.91071104%; + } + .row-fluid .offset10 { + margin-left: 88.03418803%; + *margin-left: 87.92780506%; + } + .row-fluid .offset10:first-child { + margin-left: 85.47008547%; + *margin-left: 85.36370249%; + } + .row-fluid .offset9 { + margin-left: 79.48717949%; + *margin-left: 79.38079651%; + } + .row-fluid .offset9:first-child { + margin-left: 76.92307692%; + *margin-left: 76.81669394%; + } + .row-fluid .offset8 { + margin-left: 70.94017094%; + *margin-left: 70.83378796%; + } + .row-fluid .offset8:first-child { + margin-left: 68.37606838%; + *margin-left: 68.2696854%; + } + .row-fluid .offset7 { + margin-left: 62.39316239%; + *margin-left: 62.28677941%; + } + .row-fluid .offset7:first-child { + margin-left: 59.82905983%; + *margin-left: 59.72267685%; + } + .row-fluid .offset6 { + margin-left: 53.84615385%; + *margin-left: 53.73977087%; + } + .row-fluid .offset6:first-child { + margin-left: 51.28205128%; + *margin-left: 51.1756683%; + } + .row-fluid .offset5 { + margin-left: 45.2991453%; + *margin-left: 45.19276232%; + } + .row-fluid .offset5:first-child { + margin-left: 42.73504274%; + *margin-left: 42.62865976%; + } + .row-fluid .offset4 { + margin-left: 36.75213675%; + *margin-left: 36.64575377%; + } + .row-fluid .offset4:first-child { + margin-left: 34.18803419%; + *margin-left: 34.08165121%; + } + .row-fluid .offset3 { + margin-left: 28.20512821%; + *margin-left: 28.09874523%; + } + .row-fluid .offset3:first-child { + margin-left: 25.64102564%; + *margin-left: 25.53464266%; + } + .row-fluid .offset2 { + margin-left: 19.65811966%; + *margin-left: 19.55173668%; + } + .row-fluid .offset2:first-child { + margin-left: 17.09401709%; + *margin-left: 16.98763412%; + } + .row-fluid .offset1 { + margin-left: 11.11111111%; + *margin-left: 11.00472813%; + } + .row-fluid .offset1:first-child { + margin-left: 8.54700855%; + *margin-left: 8.44062557%; + } + input, + textarea, + .uneditable-input { + margin-left: 0; + } + .controls-row [class*="span"] + [class*="span"] { + margin-left: 30px; + } + input.span12, + textarea.span12, + .uneditable-input.span12 { + width: 1156px; + } + input.span11, + textarea.span11, + .uneditable-input.span11 { + width: 1056px; + } + input.span10, + textarea.span10, + .uneditable-input.span10 { + width: 956px; + } + input.span9, + textarea.span9, + .uneditable-input.span9 { + width: 856px; + } + input.span8, + textarea.span8, + .uneditable-input.span8 { + width: 756px; + } + input.span7, + textarea.span7, + .uneditable-input.span7 { + width: 656px; + } + input.span6, + textarea.span6, + .uneditable-input.span6 { + width: 556px; + } + input.span5, + textarea.span5, + .uneditable-input.span5 { + width: 456px; + } + input.span4, + textarea.span4, + .uneditable-input.span4 { + width: 356px; + } + input.span3, + textarea.span3, + .uneditable-input.span3 { + width: 256px; + } + input.span2, + textarea.span2, + .uneditable-input.span2 { + width: 156px; + } + input.span1, + textarea.span1, + .uneditable-input.span1 { + width: 56px; + } + .thumbnails { + margin-left: -30px; + } + .thumbnails > li { + margin-left: 30px; + } + .row-fluid .thumbnails { + margin-left: 0; + } +} +@media (min-width: 768px) and (max-width: 979px) { + .row { + margin-left: -20px; + *zoom: 1; + } + .row:before, + .row:after { + display: table; + content: ""; + line-height: 0; + } + .row:after { + clear: both; + } + [class*="span"] { + float: left; + min-height: 1px; + margin-left: 20px; + } + .container, + .navbar-static-top .container, + .navbar-fixed-top .container, + .navbar-fixed-bottom .container { + width: 724px; + } + .span12 { + width: 724px; + } + .span11 { + width: 662px; + } + .span10 { + width: 600px; + } + .span9 { + width: 538px; + } + .span8 { + width: 476px; + } + .span7 { + width: 414px; + } + .span6 { + width: 352px; + } + .span5 { + width: 290px; + } + .span4 { + width: 228px; + } + .span3 { + width: 166px; + } + .span2 { + width: 104px; + } + .span1 { + width: 42px; + } + .offset12 { + margin-left: 764px; + } + .offset11 { + margin-left: 702px; + } + .offset10 { + margin-left: 640px; + } + .offset9 { + margin-left: 578px; + } + .offset8 { + margin-left: 516px; + } + .offset7 { + margin-left: 454px; + } + .offset6 { + margin-left: 392px; + } + .offset5 { + margin-left: 330px; + } + .offset4 { + margin-left: 268px; + } + .offset3 { + margin-left: 206px; + } + .offset2 { + margin-left: 144px; + } + .offset1 { + margin-left: 82px; + } + .row-fluid { + width: 100%; + *zoom: 1; + } + .row-fluid:before, + .row-fluid:after { + display: table; + content: ""; + line-height: 0; + } + .row-fluid:after { + clear: both; + } + .row-fluid [class*="span"] { + display: block; + width: 100%; + min-height: 31px; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + float: left; + margin-left: 2.76243094%; + *margin-left: 2.70923945%; + } + .row-fluid [class*="span"]:first-child { + margin-left: 0; + } + .row-fluid .controls-row [class*="span"] + [class*="span"] { + margin-left: 2.76243094%; + } + .row-fluid .span12 { + width: 100%; + *width: 99.94680851%; + } + .row-fluid .span11 { + width: 91.43646409%; + *width: 91.3832726%; + } + .row-fluid .span10 { + width: 82.87292818%; + *width: 82.81973669%; + } + .row-fluid .span9 { + width: 74.30939227%; + *width: 74.25620078%; + } + .row-fluid .span8 { + width: 65.74585635%; + *width: 65.69266486%; + } + .row-fluid .span7 { + width: 57.18232044%; + *width: 57.12912895%; + } + .row-fluid .span6 { + width: 48.61878453%; + *width: 48.56559304%; + } + .row-fluid .span5 { + width: 40.05524862%; + *width: 40.00205713%; + } + .row-fluid .span4 { + width: 31.49171271%; + *width: 31.43852122%; + } + .row-fluid .span3 { + width: 22.9281768%; + *width: 22.87498531%; + } + .row-fluid .span2 { + width: 14.36464088%; + *width: 14.31144939%; + } + .row-fluid .span1 { + width: 5.80110497%; + *width: 5.74791348%; + } + .row-fluid .offset12 { + margin-left: 105.52486188%; + *margin-left: 105.4184789%; + } + .row-fluid .offset12:first-child { + margin-left: 102.76243094%; + *margin-left: 102.65604796%; + } + .row-fluid .offset11 { + margin-left: 96.96132597%; + *margin-left: 96.85494299%; + } + .row-fluid .offset11:first-child { + margin-left: 94.19889503%; + *margin-left: 94.09251205%; + } + .row-fluid .offset10 { + margin-left: 88.39779006%; + *margin-left: 88.29140708%; + } + .row-fluid .offset10:first-child { + margin-left: 85.63535912%; + *margin-left: 85.52897614%; + } + .row-fluid .offset9 { + margin-left: 79.83425414%; + *margin-left: 79.72787116%; + } + .row-fluid .offset9:first-child { + margin-left: 77.0718232%; + *margin-left: 76.96544023%; + } + .row-fluid .offset8 { + margin-left: 71.27071823%; + *margin-left: 71.16433525%; + } + .row-fluid .offset8:first-child { + margin-left: 68.50828729%; + *margin-left: 68.40190431%; + } + .row-fluid .offset7 { + margin-left: 62.70718232%; + *margin-left: 62.60079934%; + } + .row-fluid .offset7:first-child { + margin-left: 59.94475138%; + *margin-left: 59.8383684%; + } + .row-fluid .offset6 { + margin-left: 54.14364641%; + *margin-left: 54.03726343%; + } + .row-fluid .offset6:first-child { + margin-left: 51.38121547%; + *margin-left: 51.27483249%; + } + .row-fluid .offset5 { + margin-left: 45.5801105%; + *margin-left: 45.47372752%; + } + .row-fluid .offset5:first-child { + margin-left: 42.81767956%; + *margin-left: 42.71129658%; + } + .row-fluid .offset4 { + margin-left: 37.01657459%; + *margin-left: 36.91019161%; + } + .row-fluid .offset4:first-child { + margin-left: 34.25414365%; + *margin-left: 34.14776067%; + } + .row-fluid .offset3 { + margin-left: 28.45303867%; + *margin-left: 28.3466557%; + } + .row-fluid .offset3:first-child { + margin-left: 25.69060773%; + *margin-left: 25.58422476%; + } + .row-fluid .offset2 { + margin-left: 19.88950276%; + *margin-left: 19.78311978%; + } + .row-fluid .offset2:first-child { + margin-left: 17.12707182%; + *margin-left: 17.02068884%; + } + .row-fluid .offset1 { + margin-left: 11.32596685%; + *margin-left: 11.21958387%; + } + .row-fluid .offset1:first-child { + margin-left: 8.56353591%; + *margin-left: 8.45715293%; + } + input, + textarea, + .uneditable-input { + margin-left: 0; + } + .controls-row [class*="span"] + [class*="span"] { + margin-left: 20px; + } + input.span12, + textarea.span12, + .uneditable-input.span12 { + width: 710px; + } + input.span11, + textarea.span11, + .uneditable-input.span11 { + width: 648px; + } + input.span10, + textarea.span10, + .uneditable-input.span10 { + width: 586px; + } + input.span9, + textarea.span9, + .uneditable-input.span9 { + width: 524px; + } + input.span8, + textarea.span8, + .uneditable-input.span8 { + width: 462px; + } + input.span7, + textarea.span7, + .uneditable-input.span7 { + width: 400px; + } + input.span6, + textarea.span6, + .uneditable-input.span6 { + width: 338px; + } + input.span5, + textarea.span5, + .uneditable-input.span5 { + width: 276px; + } + input.span4, + textarea.span4, + .uneditable-input.span4 { + width: 214px; + } + input.span3, + textarea.span3, + .uneditable-input.span3 { + width: 152px; + } + input.span2, + textarea.span2, + .uneditable-input.span2 { + width: 90px; + } + input.span1, + textarea.span1, + .uneditable-input.span1 { + width: 28px; + } +} +@media (max-width: 767px) { + body { + padding-left: 20px; + padding-right: 20px; + } + .navbar-fixed-top, + .navbar-fixed-bottom, + .navbar-static-top { + margin-left: -20px; + margin-right: -20px; + } + .container-fluid { + padding: 0; + } + .dl-horizontal dt { + float: none; + clear: none; + width: auto; + text-align: left; + } + .dl-horizontal dd { + margin-left: 0; + } + .container { + width: auto; + } + .row-fluid { + width: 100%; + } + .row, + .thumbnails { + margin-left: 0; + } + .thumbnails > li { + float: none; + margin-left: 0; + } + [class*="span"], + .uneditable-input[class*="span"], + .row-fluid [class*="span"] { + float: none; + display: block; + width: 100%; + margin-left: 0; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + } + .span12, + .row-fluid .span12 { + width: 100%; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + } + .row-fluid [class*="offset"]:first-child { + margin-left: 0; + } + .input-large, + .input-xlarge, + .input-xxlarge, + input[class*="span"], + select[class*="span"], + textarea[class*="span"], + .uneditable-input { + display: block; + width: 100%; + min-height: 31px; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + } + .input-prepend input, + .input-append input, + .input-prepend input[class*="span"], + .input-append input[class*="span"] { + display: inline-block; + width: auto; + } + .controls-row [class*="span"] + [class*="span"] { + margin-left: 0; + } + .modal { + position: fixed; + top: 20px; + left: 20px; + right: 20px; + width: auto; + margin: 0; + } + .modal.fade { + top: -100px; + } + .modal.fade.in { + top: 20px; + } +} +@media (max-width: 480px) { + .nav-collapse { + -webkit-transform: translate3d(0, 0, 0); + } + .page-header h1 small { + display: block; + line-height: 21px; + } + input[type="checkbox"], + input[type="radio"] { + border: 1px solid #ccc; + } + .form-horizontal .control-label { + float: none; + width: auto; + padding-top: 0; + text-align: left; + } + .form-horizontal .controls { + margin-left: 0; + } + .form-horizontal .control-list { + padding-top: 0; + } + .form-horizontal .form-actions { + padding-left: 10px; + padding-right: 10px; + } + .media .pull-left, + .media .pull-right { + float: none; + display: block; + margin-bottom: 10px; + } + .media-object { + margin-right: 0; + margin-left: 0; + } + .modal { + top: 10px; + left: 10px; + right: 10px; + } + .modal-header .close { + padding: 10px; + margin: -10px; + } + .carousel-caption { + position: static; + } +} +@media (max-width: 979px) { + body { + padding-top: 0; + } + .navbar-fixed-top, + .navbar-fixed-bottom { + position: static; + } + .navbar-fixed-top { + margin-bottom: 21px; + } + .navbar-fixed-bottom { + margin-top: 21px; + } + .navbar-fixed-top .navbar-inner, + .navbar-fixed-bottom .navbar-inner { + padding: 5px; + } + .navbar .container { + width: auto; + padding: 0; + } + .navbar .brand { + padding-left: 10px; + padding-right: 10px; + margin: 0 0 0 -5px; + } + .nav-collapse { + clear: both; + } + .nav-collapse .nav { + float: none; + margin: 0 0 10.5px; + } + .nav-collapse .nav > li { + float: none; + } + .nav-collapse .nav > li > a { + margin-bottom: 2px; + } + .nav-collapse .nav > .divider-vertical { + display: none; + } + .nav-collapse .nav .nav-header { + color: #777777; + text-shadow: none; + } + .nav-collapse .nav > li > a, + .nav-collapse .dropdown-menu a { + padding: 9px 15px; + font-weight: bold; + color: #777777; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; + } + .nav-collapse .btn { + padding: 4px 10px 4px; + font-weight: normal; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; + } + .nav-collapse .dropdown-menu li + li a { + margin-bottom: 2px; + } + .nav-collapse .nav > li > a:hover, + .nav-collapse .nav > li > a:focus, + .nav-collapse .dropdown-menu a:hover, + .nav-collapse .dropdown-menu a:focus { + background-color: #f2f2f2; + } + .navbar-inverse .nav-collapse .nav > li > a, + .navbar-inverse .nav-collapse .dropdown-menu a { + color: #999999; + } + .navbar-inverse .nav-collapse .nav > li > a:hover, + .navbar-inverse .nav-collapse .nav > li > a:focus, + .navbar-inverse .nav-collapse .dropdown-menu a:hover, + .navbar-inverse .nav-collapse .dropdown-menu a:focus { + background-color: #111111; + } + .nav-collapse.in .btn-group { + margin-top: 5px; + padding: 0; + } + .nav-collapse .dropdown-menu { + position: static; + top: auto; + left: auto; + float: none; + display: none; + max-width: none; + margin: 0 15px; + padding: 0; + background-color: transparent; + border: none; + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; + -webkit-box-shadow: none; + -moz-box-shadow: none; + box-shadow: none; + } + .nav-collapse .open > .dropdown-menu { + display: block; + } + .nav-collapse .dropdown-menu:before, + .nav-collapse .dropdown-menu:after { + display: none; + } + .nav-collapse .dropdown-menu .divider { + display: none; + } + .nav-collapse .nav > li > .dropdown-menu:before, + .nav-collapse .nav > li > .dropdown-menu:after { + display: none; + } + .nav-collapse .navbar-form, + .nav-collapse .navbar-search { + float: none; + padding: 10.5px 15px; + margin: 10.5px 0; + border-top: 1px solid #f2f2f2; + border-bottom: 1px solid #f2f2f2; + -webkit-box-shadow: inset 0 1px 0 rgba(255,255,255,.1), 0 1px 0 rgba(255,255,255,.1); + -moz-box-shadow: inset 0 1px 0 rgba(255,255,255,.1), 0 1px 0 rgba(255,255,255,.1); + box-shadow: inset 0 1px 0 rgba(255,255,255,.1), 0 1px 0 rgba(255,255,255,.1); + } + .navbar-inverse .nav-collapse .navbar-form, + .navbar-inverse .nav-collapse .navbar-search { + border-top-color: #111111; + border-bottom-color: #111111; + } + .navbar .nav-collapse .nav.pull-right { + float: none; + margin-left: 0; + } + .nav-collapse, + .nav-collapse.collapse { + overflow: hidden; + height: 0; + } + .navbar .btn-navbar { + display: block; + } + .navbar-static .navbar-inner { + padding-left: 10px; + padding-right: 10px; + } +} +@media (min-width: 979px + 1) { + .nav-collapse.collapse { + height: auto !important; + overflow: visible !important; + } +} diff --git a/5.0/_static/css/spc-extend.css b/5.0/_static/css/spc-extend.css new file mode 100644 index 000000000..264a62bfb --- /dev/null +++ b/5.0/_static/css/spc-extend.css @@ -0,0 +1,92 @@ +body { + background-color: white; +} +.container { + width: 90%; +} +.underline { + border-bottom: 1.5px solid #eeeeee; +} +.header { + margin-top: 15px; + margin-bottom: 15px; + margin-left: 0px; + margin-right: 0px; +} +.spc-navbar { + margin-top: 15px; + margin-bottom: 5px; + margin-left: 0px; + margin-right: 0px; +} +.spc-navbar .nav-pills { + margin-bottom: 0px; + font-size: 12px; +} +.spc-navbar .nav-pills > li > a { + padding-top: 2.5px; + padding-bottom: 2.5px; +} +.spc-page-title h1, +.spc-page-title h2, +.spc-page-title h3, +.spc-page-title h4 { + font-weight: normal; + border-bottom: 1.5px solid #eeeeee; +} +.tags .btn { + border: none; + font-size: 9.5px; + font-weight: bold; +} +.spc-search-result-title h1, +.spc-search-result-title h2, +.spc-search-result-title h3, +.spc-search-result-title h4 { + font-weight: normal; +} +.spc-snippet-header { + margin-bottom: 5px; +} +.spc-snippet-info { + padding-top: 10px; +} +.spc-snippet-info .dl-horizontal { + margin: 5px; +} +.spc-snippet-info .dl-horizontal dt { + font-weight: normal; +} +.spc-snippet-body { + padding: 10px; +} +.spc-snippet-body .accordion-group { + border: none; +} +.spc-snippet-body .accordion-heading { + text-transform: uppercase; + font-size: 14px; + border-bottom: 1px solid #e5e5e5; +} +.spc-snippet-body .accordion-heading .accordion-toggle { + padding-top: 10px; + padding-bottom: 5px; +} +.spc-rightsidebar { + color: #555555; +} +.spc-rightsidebar .navigation { + padding: 2px 10px; + font-size: 11.9px; +} +.spc-rightsidebar .navigation .nav-title { + font-weight: bold; + text-transform: uppercase; +} +.spc-rightsidebar .navigation li { + margin: 5px; +} +.footer { + padding: 5px; + font-size: small; +} diff --git a/5.0/_static/doctools.js b/5.0/_static/doctools.js new file mode 100644 index 000000000..b33f87fcb --- /dev/null +++ b/5.0/_static/doctools.js @@ -0,0 +1,314 @@ +/* + * doctools.js + * ~~~~~~~~~~~ + * + * Sphinx JavaScript utilities for all documentation. + * + * :copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ + +/** + * select a different prefix for underscore + */ +$u = _.noConflict(); + +/** + * make the code below compatible with browsers without + * an installed firebug like debugger +if (!window.console || !console.firebug) { + var names = ["log", "debug", "info", "warn", "error", "assert", "dir", + "dirxml", "group", "groupEnd", "time", "timeEnd", "count", "trace", + "profile", "profileEnd"]; + window.console = {}; + for (var i = 0; i < names.length; ++i) + window.console[names[i]] = function() {}; +} + */ + +/** + * small helper function to urldecode strings + */ +jQuery.urldecode = function(x) { + return decodeURIComponent(x).replace(/\+/g, ' '); +}; + +/** + * small helper function to urlencode strings + */ +jQuery.urlencode = encodeURIComponent; + +/** + * This function returns the parsed url parameters of the + * current request. Multiple values per key are supported, + * it will always return arrays of strings for the value parts. + */ +jQuery.getQueryParameters = function(s) { + if (typeof s === 'undefined') + s = document.location.search; + var parts = s.substr(s.indexOf('?') + 1).split('&'); + var result = {}; + for (var i = 0; i < parts.length; i++) { + var tmp = parts[i].split('=', 2); + var key = jQuery.urldecode(tmp[0]); + var value = jQuery.urldecode(tmp[1]); + if (key in result) + result[key].push(value); + else + result[key] = [value]; + } + return result; +}; + +/** + * highlight a given string on a jquery object by wrapping it in + * span elements with the given class name. + */ +jQuery.fn.highlightText = function(text, className) { + function highlight(node, addItems) { + if (node.nodeType === 3) { + var val = node.nodeValue; + var pos = val.toLowerCase().indexOf(text); + if (pos >= 0 && + !jQuery(node.parentNode).hasClass(className) && + !jQuery(node.parentNode).hasClass("nohighlight")) { + var span; + var isInSVG = jQuery(node).closest("body, svg, foreignObject").is("svg"); + if (isInSVG) { + span = document.createElementNS("http://www.w3.org/2000/svg", "tspan"); + } else { + span = document.createElement("span"); + span.className = className; + } + span.appendChild(document.createTextNode(val.substr(pos, text.length))); + node.parentNode.insertBefore(span, node.parentNode.insertBefore( + document.createTextNode(val.substr(pos + text.length)), + node.nextSibling)); + node.nodeValue = val.substr(0, pos); + if (isInSVG) { + var rect = document.createElementNS("http://www.w3.org/2000/svg", "rect"); + var bbox = node.parentElement.getBBox(); + rect.x.baseVal.value = bbox.x; + rect.y.baseVal.value = bbox.y; + rect.width.baseVal.value = bbox.width; + rect.height.baseVal.value = bbox.height; + rect.setAttribute('class', className); + addItems.push({ + "parent": node.parentNode, + "target": rect}); + } + } + } + else if (!jQuery(node).is("button, select, textarea")) { + jQuery.each(node.childNodes, function() { + highlight(this, addItems); + }); + } + } + var addItems = []; + var result = this.each(function() { + highlight(this, addItems); + }); + for (var i = 0; i < addItems.length; ++i) { + jQuery(addItems[i].parent).before(addItems[i].target); + } + return result; +}; + +/* + * backward compatibility for jQuery.browser + * This will be supported until firefox bug is fixed. + */ +if (!jQuery.browser) { + jQuery.uaMatch = function(ua) { + ua = ua.toLowerCase(); + + var match = /(chrome)[ \/]([\w.]+)/.exec(ua) || + /(webkit)[ \/]([\w.]+)/.exec(ua) || + /(opera)(?:.*version|)[ \/]([\w.]+)/.exec(ua) || + /(msie) ([\w.]+)/.exec(ua) || + ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec(ua) || + []; + + return { + browser: match[ 1 ] || "", + version: match[ 2 ] || "0" + }; + }; + jQuery.browser = {}; + jQuery.browser[jQuery.uaMatch(navigator.userAgent).browser] = true; +} + +/** + * Small JavaScript module for the documentation. + */ +var Documentation = { + + init : function() { + this.fixFirefoxAnchorBug(); + this.highlightSearchWords(); + this.initIndexTable(); + if (DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS) { + this.initOnKeyListeners(); + } + }, + + /** + * i18n support + */ + TRANSLATIONS : {}, + PLURAL_EXPR : function(n) { return n === 1 ? 0 : 1; }, + LOCALE : 'unknown', + + // gettext and ngettext don't access this so that the functions + // can safely bound to a different name (_ = Documentation.gettext) + gettext : function(string) { + var translated = Documentation.TRANSLATIONS[string]; + if (typeof translated === 'undefined') + return string; + return (typeof translated === 'string') ? translated : translated[0]; + }, + + ngettext : function(singular, plural, n) { + var translated = Documentation.TRANSLATIONS[singular]; + if (typeof translated === 'undefined') + return (n == 1) ? singular : plural; + return translated[Documentation.PLURALEXPR(n)]; + }, + + addTranslations : function(catalog) { + for (var key in catalog.messages) + this.TRANSLATIONS[key] = catalog.messages[key]; + this.PLURAL_EXPR = new Function('n', 'return +(' + catalog.plural_expr + ')'); + this.LOCALE = catalog.locale; + }, + + /** + * add context elements like header anchor links + */ + addContextElements : function() { + $('div[id] > :header:first').each(function() { + $('\u00B6'). + attr('href', '#' + this.id). + attr('title', _('Permalink to this headline')). + appendTo(this); + }); + $('dt[id]').each(function() { + $('\u00B6'). + attr('href', '#' + this.id). + attr('title', _('Permalink to this definition')). + appendTo(this); + }); + }, + + /** + * workaround a firefox stupidity + * see: https://bugzilla.mozilla.org/show_bug.cgi?id=645075 + */ + fixFirefoxAnchorBug : function() { + if (document.location.hash && $.browser.mozilla) + window.setTimeout(function() { + document.location.href += ''; + }, 10); + }, + + /** + * highlight the search words provided in the url in the text + */ + highlightSearchWords : function() { + var params = $.getQueryParameters(); + var terms = (params.highlight) ? params.highlight[0].split(/\s+/) : []; + if (terms.length) { + var body = $('div.body'); + if (!body.length) { + body = $('body'); + } + window.setTimeout(function() { + $.each(terms, function() { + body.highlightText(this.toLowerCase(), 'highlighted'); + }); + }, 10); + $('') + .appendTo($('#searchbox')); + } + }, + + /** + * init the domain index toggle buttons + */ + initIndexTable : function() { + var togglers = $('img.toggler').click(function() { + var src = $(this).attr('src'); + var idnum = $(this).attr('id').substr(7); + $('tr.cg-' + idnum).toggle(); + if (src.substr(-9) === 'minus.png') + $(this).attr('src', src.substr(0, src.length-9) + 'plus.png'); + else + $(this).attr('src', src.substr(0, src.length-8) + 'minus.png'); + }).css('display', ''); + if (DOCUMENTATION_OPTIONS.COLLAPSE_INDEX) { + togglers.click(); + } + }, + + /** + * helper function to hide the search marks again + */ + hideSearchWords : function() { + $('#searchbox .highlight-link').fadeOut(300); + $('span.highlighted').removeClass('highlighted'); + }, + + /** + * make the url absolute + */ + makeURL : function(relativeURL) { + return DOCUMENTATION_OPTIONS.URL_ROOT + '/' + relativeURL; + }, + + /** + * get the current relative url + */ + getCurrentURL : function() { + var path = document.location.pathname; + var parts = path.split(/\//); + $.each(DOCUMENTATION_OPTIONS.URL_ROOT.split(/\//), function() { + if (this === '..') + parts.pop(); + }); + var url = parts.join('/'); + return path.substring(url.lastIndexOf('/') + 1, path.length - 1); + }, + + initOnKeyListeners: function() { + $(document).keyup(function(event) { + var activeElementType = document.activeElement.tagName; + // don't navigate when in search box or textarea + if (activeElementType !== 'TEXTAREA' && activeElementType !== 'INPUT' && activeElementType !== 'SELECT') { + switch (event.keyCode) { + case 37: // left + var prevHref = $('link[rel="prev"]').prop('href'); + if (prevHref) { + window.location.href = prevHref; + return false; + } + case 39: // right + var nextHref = $('link[rel="next"]').prop('href'); + if (nextHref) { + window.location.href = nextHref; + return false; + } + } + } + }); + } +}; + +// quick alias for translations +_ = Documentation.gettext; + +$(document).ready(function() { + Documentation.init(); +}); diff --git a/5.0/_static/documentation_options.js b/5.0/_static/documentation_options.js new file mode 100644 index 000000000..3ceefbbee --- /dev/null +++ b/5.0/_static/documentation_options.js @@ -0,0 +1,11 @@ +var DOCUMENTATION_OPTIONS = { + URL_ROOT: document.getElementById("documentation_options").getAttribute('data-url_root'), + VERSION: 'unknown', + LANGUAGE: 'None', + COLLAPSE_INDEX: false, + BUILDER: 'html', + FILE_SUFFIX: '.html', + HAS_SOURCE: true, + SOURCELINK_SUFFIX: '.txt', + NAVIGATION_WITH_KEYS: false +}; \ No newline at end of file diff --git a/5.0/_static/enthought.css b/5.0/_static/enthought.css new file mode 100644 index 000000000..32ddcacb7 --- /dev/null +++ b/5.0/_static/enthought.css @@ -0,0 +1,412 @@ +/* -*- css -*- + * + * sphinxdoc.css_t + * ~~~~~~~~~~~~~~~ + * + * Sphinx stylesheet -- sphinxdoc theme. Originally created by + * Armin Ronacher for Werkzeug. + * + * :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ + +@import url("basic.css"); + +/* @import url("css/scipy-central.css"); */ + +@font-face { + font-family: 'Source Code Pro'; + font-weight: 400; + font-style: normal; + font-stretch: normal; + src: local('Source Code Pro'), local('SourceCodePro-Regular'), url('fonts/SourceCodePro-Regular.otf.woff') format('woff'); +} + +@font-face { + font-family: 'Source Code Pro'; + font-weight: 600; + font-style: normal; + font-stretch: normal; + src: local('Source Code Pro Semibold'), local('SourceCodePro-Semibold'), url('fonts/SourceCodePro-Semibold.otf.woff') format('woff'); +} + +@font-face{ + font-family: 'Source Sans Pro'; + font-weight: 400; + font-style: normal; + font-stretch: normal; + src: local('Source Sans Pro'), local('SourceSansPro-Regular'), url('fonts/SourceSansPro-Regular.otf.woff') format('woff'); +} + +@font-face{ + font-family: 'Source Sans Pro'; + font-weight: 600; + font-style: normal; + font-stretch: normal; + src: local('Source Sans Pro Semibold'), local('SourceSansPro-Semibold'), url('fonts/SourceSansPro-Semibold.otf.woff') format('woff'); +} + +@font-face{ + font-family: 'Source Sans Pro'; + font-weight: 400; + font-style: italic; + font-stretch: normal; + src: local('Source Sans Pro Italic'), local('SourceSansPro-It'), url('fonts/SourceSansPro-It.otf.woff') format('woff'); +} + +@font-face{ + font-family: 'Source Sans Pro'; + font-weight: 600; + font-style: italic; + font-stretch: normal; + src: local('Source Sans Pro Semibold Italic'), local('SourceSansPro-SemiboldIt'), url('fonts/SourceSansPro-SemiboldIt.otf.woff') format('woff'); +} + +/* + * General tweaks + */ + +div.container-navbar-bottom { + margin-top: 0; +} + +div.container-navbar-bottom div.spc-navbar { + margin-top: 0; +} + +div.spc-navbar { + margin: 0; +} + +tt { + color: inherit; + font: inherit; +} + +tt.literal { + font-family: 'Source Code Pro', monospace; + padding-left: 2px; + background-color: rgb(242, 242, 242); +} + +a tt.literal { + border-bottom: none; + background-color: inherit; +} + +tt.xref { + border-bottom: none; + background-color: inherit; + font-weight: inherit; + padding-left: 0px; +} + +tt.descclassname { + font-family: 'Source Code Pro', monospace; +} + +tt.descname { + font-family: 'Source Code Pro', monospace; + font-size: 20px; +} + +code { + color: inherit; + font: inherit; + padding: 2px 0px; + border: inherit; +} + +code.literal { + font-family: monospace; + padding-left: 2px; + background-color: rgb(242, 242, 242); +} + +a code.literal { + border: none; + background-color: inherit; +} + +code.xref { + font-family: inherit; + border-bottom: none; + background-color: inherit; + padding-left: 0px; +} + +code.descname { + font-size: 16px; +} + +dl.class, +dl.function, +dl.data +{ + border-top: 2px solid #888; + padding-top: 1px; +} + +dl.attribute, +dl.classmethod, +dl.staticmethod, +dl.method +{ + border-top: 1px solid #aaa; + padding-top: 1px; +} + +dl.attribute > dt > tt.descname, +dl.classmethod > dt > tt.descname, +dl.staticmethod > dt > tt.descname, +dl.method > dt > tt.descname +{ + font-size: inherit; +} + +dl.class > dt, +dl.attribute > dt, +dl.data > dt, +dl.function > dt, +dl.exception > dt, +dl.classmethod > dt, +dl.staticmethod > dt, +dl.method > dt +{ + font-weight: normal; + /* Fake a hanging indent. If the text has to linewrap, it will indent more + * than the following
. + */ + text-indent: -60px; + padding-left: 60px; +} + +pre { + border-radius: 0; + border: none; + font-family: 'Source Code Pro', monospace; +} + +.nav-pills > .active > a, +.nav-pills > .active > a:hover, +.nav-pills > .active > a:focus { + color: #ffffff; + background-color: #253370; +} + +.nav-pills.pull-right > li { + float: right; +} + +a { + color: #253370; + text-decoration: none; +} + +/* + * Field lists + */ + +table.field-list { + border-collapse: collapse; + border-spacing: 5px; + margin-left: 1px; + border-left: 5px solid #DFDFDF !important; +} + +table.field-list th.field-name { + display: block; + text-align: left; + padding: 1px 8px 1px 5px; + white-space: nowrap; + background-color: #DFDFDF; +} + +table.field-list td.field-body { + display: block; + border-left: none !important; + padding-left: 1em; +} + +table.field-list td.field-body > ul { + padding-left: 1em; +} + +table.field-list td.field-body > p, +table.field-list td.field-body > ul > li > p +{ + display: inline; +} + +table.field-list td.field-body > p > strong { + font-style: normal; +} + +td.field-body blockquote { + border-left: none; + margin: 0; + padding-left: 30px; +} + +td.field-body blockquote p, +dl.class blockquote p, +dl.function blockquote p, +dl.classmethod blockquote p, +dl.staticmethod blockquote p, +dl.method blockquote p +{ + font-family: inherit; + font-size: inherit; + font-weight: inherit; + line-height: inherit; +} + + +/* + * Sidebars and top logo + */ + +div.sphinxsidebarwrapper { + overflow: hidden; +} + +div.sphinxsidebarwrapper p.logo { + text-align: center; +} + +div.spc-rightsidebar h3 { + font-size: 120%; + line-height: inherit; + border-bottom: 1px solid #656565; +} + +div.spc-rightsidebar h4 { + font-size: 110%; + line-height: inherit; + border-bottom: 1px solid #656565; +} + +form.search > input[type="text"] { + width: auto; +} + +/* + * Headers + */ + +h1 a { color: #333333; } +h2 a { color: #333333; } +h3 a { color: #333333; } +h4 a { color: #333333; } +h5 a { color: #333333; } +h6 a { color: #333333; } + +h1 tt { font: inherit; border-bottom: none; } +h2 tt { font: inherit; border-bottom: none; } +h3 tt { font: inherit; border-bottom: none; } +h4 tt { font: inherit; border-bottom: none; } +h5 tt { font: inherit; border-bottom: none; } +h6 tt { font: inherit; border-bottom: none; } + +div#spc-section-body h1, h2, h3, h4, h5, h6{ + color: #444444; + font-weight: normal; + border-bottom: 0px solid #656565; + margin-bottom: 0.5em; +} +div#spc-section-body h1 { font-size: 200%; font-weight: bold; color: #333333; } +div#spc-section-body h2 { font-size: 160%; font-weight: bold; } +div#spc-section-body h3 { font-size: 140%; } +div#spc-section-body h4 { font-size: 120%; border-bottom: none; } +div#spc-section-body h5 { font-size: 110%; border-bottom: none; } +div#spc-section-body h6 { font-size: 100%; border-bottom: none; } + +/* Styling for hyperlinks */ +div#spc-section-body a{ + text-decoration: none; +} +div#spc-section-body a:hover{ + text-decoration: underline; +} + +/* Styling for images and figures: images are inline, figures are centered */ +div#spc-section-body .align-center{ + text-align: center; +} + +p.rubric { + color: #333333; + font-size: 120%; + font-weight: normal; + border-bottom: 1px solid #DDDDDD; +} + +.highlight-python pre { + border-top: 1px solid #656565; + border-bottom: 1px solid #656565; +} + +/* Docutils uses this tag for footnote backrefs. By coincidence, Bootstrap also + * uses this class and assigns an obnoxious color to it. Use a less obnoxious + * color. + */ +td.label { + background-color: rgb(242, 242, 242); +} + +/* + * Tables + */ + +table.citation { + border: none; +} + +table.docutils td, table.docutils th { + border: none; +} + +table.docutils { + margin-bottom: 9.5px; +} + + +/* + * Admonitions + */ + +p.admonition-title { + display: inline; +} + +p.admonition-title:after { + content: ":"; +} + +div.seealso { + background-color: #ffc; + border: 1px solid #ff6; +} + +div.seealso dt { + float: left; + clear: left; + min-width: 4em; + padding-right: 1em; +} + +div.seealso dd { + margin-top: 0; + margin-bottom: 0; +} + +div.warning { + background-color: #ffe4e4; + border: 1px solid #f66; +} + +div.note { + background-color: #eee; + border: 1px solid #ccc; +} \ No newline at end of file diff --git a/5.0/_static/file.png b/5.0/_static/file.png new file mode 100644 index 000000000..a858a410e Binary files /dev/null and b/5.0/_static/file.png differ diff --git a/5.0/_static/fonts/SourceCodePro-Regular.otf.woff b/5.0/_static/fonts/SourceCodePro-Regular.otf.woff new file mode 100644 index 000000000..46e7bd058 Binary files /dev/null and b/5.0/_static/fonts/SourceCodePro-Regular.otf.woff differ diff --git a/5.0/_static/fonts/SourceCodePro-Semibold.otf.woff b/5.0/_static/fonts/SourceCodePro-Semibold.otf.woff new file mode 100644 index 000000000..d0f6f758f Binary files /dev/null and b/5.0/_static/fonts/SourceCodePro-Semibold.otf.woff differ diff --git a/5.0/_static/fonts/SourceSansPro-It.otf.woff b/5.0/_static/fonts/SourceSansPro-It.otf.woff new file mode 100644 index 000000000..9cae9b4b9 Binary files /dev/null and b/5.0/_static/fonts/SourceSansPro-It.otf.woff differ diff --git a/5.0/_static/fonts/SourceSansPro-Regular.otf.woff b/5.0/_static/fonts/SourceSansPro-Regular.otf.woff new file mode 100644 index 000000000..6bc912b76 Binary files /dev/null and b/5.0/_static/fonts/SourceSansPro-Regular.otf.woff differ diff --git a/5.0/_static/fonts/SourceSansPro-Semibold.otf.woff b/5.0/_static/fonts/SourceSansPro-Semibold.otf.woff new file mode 100644 index 000000000..475c49971 Binary files /dev/null and b/5.0/_static/fonts/SourceSansPro-Semibold.otf.woff differ diff --git a/5.0/_static/fonts/SourceSansPro-SemiboldIt.otf.woff b/5.0/_static/fonts/SourceSansPro-SemiboldIt.otf.woff new file mode 100644 index 000000000..62c2997d3 Binary files /dev/null and b/5.0/_static/fonts/SourceSansPro-SemiboldIt.otf.woff differ diff --git a/5.0/_static/img/contents.png b/5.0/_static/img/contents.png new file mode 100644 index 000000000..7fb82154a Binary files /dev/null and b/5.0/_static/img/contents.png differ diff --git a/5.0/_static/img/e-logo.png b/5.0/_static/img/e-logo.png new file mode 100644 index 000000000..3874ef07a Binary files /dev/null and b/5.0/_static/img/e-logo.png differ diff --git a/5.0/_static/img/favicon.ico b/5.0/_static/img/favicon.ico new file mode 100644 index 000000000..6ff4b1d2f Binary files /dev/null and b/5.0/_static/img/favicon.ico differ diff --git a/5.0/_static/img/glyphicons-halflings-white.png b/5.0/_static/img/glyphicons-halflings-white.png new file mode 100644 index 000000000..3bf6484a2 Binary files /dev/null and b/5.0/_static/img/glyphicons-halflings-white.png differ diff --git a/5.0/_static/img/glyphicons-halflings.png b/5.0/_static/img/glyphicons-halflings.png new file mode 100644 index 000000000..a99699932 Binary files /dev/null and b/5.0/_static/img/glyphicons-halflings.png differ diff --git a/5.0/_static/img/navigation.png b/5.0/_static/img/navigation.png new file mode 100644 index 000000000..1081dc143 Binary files /dev/null and b/5.0/_static/img/navigation.png differ diff --git a/5.0/_static/img/transparent-pixel.gif b/5.0/_static/img/transparent-pixel.gif new file mode 100644 index 000000000..e4994d9ef Binary files /dev/null and b/5.0/_static/img/transparent-pixel.gif differ diff --git a/5.0/_static/img/ui-anim_basic_16x16.gif b/5.0/_static/img/ui-anim_basic_16x16.gif new file mode 100644 index 000000000..084ecb879 Binary files /dev/null and b/5.0/_static/img/ui-anim_basic_16x16.gif differ diff --git a/5.0/_static/jquery-3.4.1.js b/5.0/_static/jquery-3.4.1.js new file mode 100644 index 000000000..773ad95c5 --- /dev/null +++ b/5.0/_static/jquery-3.4.1.js @@ -0,0 +1,10598 @@ +/*! + * jQuery JavaScript Library v3.4.1 + * https://jquery.com/ + * + * Includes Sizzle.js + * https://sizzlejs.com/ + * + * Copyright JS Foundation and other contributors + * Released under the MIT license + * https://jquery.org/license + * + * Date: 2019-05-01T21:04Z + */ +( function( global, factory ) { + + "use strict"; + + if ( typeof module === "object" && typeof module.exports === "object" ) { + + // For CommonJS and CommonJS-like environments where a proper `window` + // is present, execute the factory and get jQuery. + // For environments that do not have a `window` with a `document` + // (such as Node.js), expose a factory as module.exports. + // This accentuates the need for the creation of a real `window`. + // e.g. var jQuery = require("jquery")(window); + // See ticket #14549 for more info. + module.exports = global.document ? + factory( global, true ) : + function( w ) { + if ( !w.document ) { + throw new Error( "jQuery requires a window with a document" ); + } + return factory( w ); + }; + } else { + factory( global ); + } + +// Pass this if window is not defined yet +} )( typeof window !== "undefined" ? window : this, function( window, noGlobal ) { + +// Edge <= 12 - 13+, Firefox <=18 - 45+, IE 10 - 11, Safari 5.1 - 9+, iOS 6 - 9.1 +// throw exceptions when non-strict code (e.g., ASP.NET 4.5) accesses strict mode +// arguments.callee.caller (trac-13335). But as of jQuery 3.0 (2016), strict mode should be common +// enough that all such attempts are guarded in a try block. +"use strict"; + +var arr = []; + +var document = window.document; + +var getProto = Object.getPrototypeOf; + +var slice = arr.slice; + +var concat = arr.concat; + +var push = arr.push; + +var indexOf = arr.indexOf; + +var class2type = {}; + +var toString = class2type.toString; + +var hasOwn = class2type.hasOwnProperty; + +var fnToString = hasOwn.toString; + +var ObjectFunctionString = fnToString.call( Object ); + +var support = {}; + +var isFunction = function isFunction( obj ) { + + // Support: Chrome <=57, Firefox <=52 + // In some browsers, typeof returns "function" for HTML elements + // (i.e., `typeof document.createElement( "object" ) === "function"`). + // We don't want to classify *any* DOM node as a function. + return typeof obj === "function" && typeof obj.nodeType !== "number"; + }; + + +var isWindow = function isWindow( obj ) { + return obj != null && obj === obj.window; + }; + + + + + var preservedScriptAttributes = { + type: true, + src: true, + nonce: true, + noModule: true + }; + + function DOMEval( code, node, doc ) { + doc = doc || document; + + var i, val, + script = doc.createElement( "script" ); + + script.text = code; + if ( node ) { + for ( i in preservedScriptAttributes ) { + + // Support: Firefox 64+, Edge 18+ + // Some browsers don't support the "nonce" property on scripts. + // On the other hand, just using `getAttribute` is not enough as + // the `nonce` attribute is reset to an empty string whenever it + // becomes browsing-context connected. + // See https://github.com/whatwg/html/issues/2369 + // See https://html.spec.whatwg.org/#nonce-attributes + // The `node.getAttribute` check was added for the sake of + // `jQuery.globalEval` so that it can fake a nonce-containing node + // via an object. + val = node[ i ] || node.getAttribute && node.getAttribute( i ); + if ( val ) { + script.setAttribute( i, val ); + } + } + } + doc.head.appendChild( script ).parentNode.removeChild( script ); + } + + +function toType( obj ) { + if ( obj == null ) { + return obj + ""; + } + + // Support: Android <=2.3 only (functionish RegExp) + return typeof obj === "object" || typeof obj === "function" ? + class2type[ toString.call( obj ) ] || "object" : + typeof obj; +} +/* global Symbol */ +// Defining this global in .eslintrc.json would create a danger of using the global +// unguarded in another place, it seems safer to define global only for this module + + + +var + version = "3.4.1", + + // Define a local copy of jQuery + jQuery = function( selector, context ) { + + // The jQuery object is actually just the init constructor 'enhanced' + // Need init if jQuery is called (just allow error to be thrown if not included) + return new jQuery.fn.init( selector, context ); + }, + + // Support: Android <=4.0 only + // Make sure we trim BOM and NBSP + rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g; + +jQuery.fn = jQuery.prototype = { + + // The current version of jQuery being used + jquery: version, + + constructor: jQuery, + + // The default length of a jQuery object is 0 + length: 0, + + toArray: function() { + return slice.call( this ); + }, + + // Get the Nth element in the matched element set OR + // Get the whole matched element set as a clean array + get: function( num ) { + + // Return all the elements in a clean array + if ( num == null ) { + return slice.call( this ); + } + + // Return just the one element from the set + return num < 0 ? this[ num + this.length ] : this[ num ]; + }, + + // Take an array of elements and push it onto the stack + // (returning the new matched element set) + pushStack: function( elems ) { + + // Build a new jQuery matched element set + var ret = jQuery.merge( this.constructor(), elems ); + + // Add the old object onto the stack (as a reference) + ret.prevObject = this; + + // Return the newly-formed element set + return ret; + }, + + // Execute a callback for every element in the matched set. + each: function( callback ) { + return jQuery.each( this, callback ); + }, + + map: function( callback ) { + return this.pushStack( jQuery.map( this, function( elem, i ) { + return callback.call( elem, i, elem ); + } ) ); + }, + + slice: function() { + return this.pushStack( slice.apply( this, arguments ) ); + }, + + first: function() { + return this.eq( 0 ); + }, + + last: function() { + return this.eq( -1 ); + }, + + eq: function( i ) { + var len = this.length, + j = +i + ( i < 0 ? len : 0 ); + return this.pushStack( j >= 0 && j < len ? [ this[ j ] ] : [] ); + }, + + end: function() { + return this.prevObject || this.constructor(); + }, + + // For internal use only. + // Behaves like an Array's method, not like a jQuery method. + push: push, + sort: arr.sort, + splice: arr.splice +}; + +jQuery.extend = jQuery.fn.extend = function() { + var options, name, src, copy, copyIsArray, clone, + target = arguments[ 0 ] || {}, + i = 1, + length = arguments.length, + deep = false; + + // Handle a deep copy situation + if ( typeof target === "boolean" ) { + deep = target; + + // Skip the boolean and the target + target = arguments[ i ] || {}; + i++; + } + + // Handle case when target is a string or something (possible in deep copy) + if ( typeof target !== "object" && !isFunction( target ) ) { + target = {}; + } + + // Extend jQuery itself if only one argument is passed + if ( i === length ) { + target = this; + i--; + } + + for ( ; i < length; i++ ) { + + // Only deal with non-null/undefined values + if ( ( options = arguments[ i ] ) != null ) { + + // Extend the base object + for ( name in options ) { + copy = options[ name ]; + + // Prevent Object.prototype pollution + // Prevent never-ending loop + if ( name === "__proto__" || target === copy ) { + continue; + } + + // Recurse if we're merging plain objects or arrays + if ( deep && copy && ( jQuery.isPlainObject( copy ) || + ( copyIsArray = Array.isArray( copy ) ) ) ) { + src = target[ name ]; + + // Ensure proper type for the source value + if ( copyIsArray && !Array.isArray( src ) ) { + clone = []; + } else if ( !copyIsArray && !jQuery.isPlainObject( src ) ) { + clone = {}; + } else { + clone = src; + } + copyIsArray = false; + + // Never move original objects, clone them + target[ name ] = jQuery.extend( deep, clone, copy ); + + // Don't bring in undefined values + } else if ( copy !== undefined ) { + target[ name ] = copy; + } + } + } + } + + // Return the modified object + return target; +}; + +jQuery.extend( { + + // Unique for each copy of jQuery on the page + expando: "jQuery" + ( version + Math.random() ).replace( /\D/g, "" ), + + // Assume jQuery is ready without the ready module + isReady: true, + + error: function( msg ) { + throw new Error( msg ); + }, + + noop: function() {}, + + isPlainObject: function( obj ) { + var proto, Ctor; + + // Detect obvious negatives + // Use toString instead of jQuery.type to catch host objects + if ( !obj || toString.call( obj ) !== "[object Object]" ) { + return false; + } + + proto = getProto( obj ); + + // Objects with no prototype (e.g., `Object.create( null )`) are plain + if ( !proto ) { + return true; + } + + // Objects with prototype are plain iff they were constructed by a global Object function + Ctor = hasOwn.call( proto, "constructor" ) && proto.constructor; + return typeof Ctor === "function" && fnToString.call( Ctor ) === ObjectFunctionString; + }, + + isEmptyObject: function( obj ) { + var name; + + for ( name in obj ) { + return false; + } + return true; + }, + + // Evaluates a script in a global context + globalEval: function( code, options ) { + DOMEval( code, { nonce: options && options.nonce } ); + }, + + each: function( obj, callback ) { + var length, i = 0; + + if ( isArrayLike( obj ) ) { + length = obj.length; + for ( ; i < length; i++ ) { + if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) { + break; + } + } + } else { + for ( i in obj ) { + if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) { + break; + } + } + } + + return obj; + }, + + // Support: Android <=4.0 only + trim: function( text ) { + return text == null ? + "" : + ( text + "" ).replace( rtrim, "" ); + }, + + // results is for internal usage only + makeArray: function( arr, results ) { + var ret = results || []; + + if ( arr != null ) { + if ( isArrayLike( Object( arr ) ) ) { + jQuery.merge( ret, + typeof arr === "string" ? + [ arr ] : arr + ); + } else { + push.call( ret, arr ); + } + } + + return ret; + }, + + inArray: function( elem, arr, i ) { + return arr == null ? -1 : indexOf.call( arr, elem, i ); + }, + + // Support: Android <=4.0 only, PhantomJS 1 only + // push.apply(_, arraylike) throws on ancient WebKit + merge: function( first, second ) { + var len = +second.length, + j = 0, + i = first.length; + + for ( ; j < len; j++ ) { + first[ i++ ] = second[ j ]; + } + + first.length = i; + + return first; + }, + + grep: function( elems, callback, invert ) { + var callbackInverse, + matches = [], + i = 0, + length = elems.length, + callbackExpect = !invert; + + // Go through the array, only saving the items + // that pass the validator function + for ( ; i < length; i++ ) { + callbackInverse = !callback( elems[ i ], i ); + if ( callbackInverse !== callbackExpect ) { + matches.push( elems[ i ] ); + } + } + + return matches; + }, + + // arg is for internal usage only + map: function( elems, callback, arg ) { + var length, value, + i = 0, + ret = []; + + // Go through the array, translating each of the items to their new values + if ( isArrayLike( elems ) ) { + length = elems.length; + for ( ; i < length; i++ ) { + value = callback( elems[ i ], i, arg ); + + if ( value != null ) { + ret.push( value ); + } + } + + // Go through every key on the object, + } else { + for ( i in elems ) { + value = callback( elems[ i ], i, arg ); + + if ( value != null ) { + ret.push( value ); + } + } + } + + // Flatten any nested arrays + return concat.apply( [], ret ); + }, + + // A global GUID counter for objects + guid: 1, + + // jQuery.support is not used in Core but other projects attach their + // properties to it so it needs to exist. + support: support +} ); + +if ( typeof Symbol === "function" ) { + jQuery.fn[ Symbol.iterator ] = arr[ Symbol.iterator ]; +} + +// Populate the class2type map +jQuery.each( "Boolean Number String Function Array Date RegExp Object Error Symbol".split( " " ), +function( i, name ) { + class2type[ "[object " + name + "]" ] = name.toLowerCase(); +} ); + +function isArrayLike( obj ) { + + // Support: real iOS 8.2 only (not reproducible in simulator) + // `in` check used to prevent JIT error (gh-2145) + // hasOwn isn't used here due to false negatives + // regarding Nodelist length in IE + var length = !!obj && "length" in obj && obj.length, + type = toType( obj ); + + if ( isFunction( obj ) || isWindow( obj ) ) { + return false; + } + + return type === "array" || length === 0 || + typeof length === "number" && length > 0 && ( length - 1 ) in obj; +} +var Sizzle = +/*! + * Sizzle CSS Selector Engine v2.3.4 + * https://sizzlejs.com/ + * + * Copyright JS Foundation and other contributors + * Released under the MIT license + * https://js.foundation/ + * + * Date: 2019-04-08 + */ +(function( window ) { + +var i, + support, + Expr, + getText, + isXML, + tokenize, + compile, + select, + outermostContext, + sortInput, + hasDuplicate, + + // Local document vars + setDocument, + document, + docElem, + documentIsHTML, + rbuggyQSA, + rbuggyMatches, + matches, + contains, + + // Instance-specific data + expando = "sizzle" + 1 * new Date(), + preferredDoc = window.document, + dirruns = 0, + done = 0, + classCache = createCache(), + tokenCache = createCache(), + compilerCache = createCache(), + nonnativeSelectorCache = createCache(), + sortOrder = function( a, b ) { + if ( a === b ) { + hasDuplicate = true; + } + return 0; + }, + + // Instance methods + hasOwn = ({}).hasOwnProperty, + arr = [], + pop = arr.pop, + push_native = arr.push, + push = arr.push, + slice = arr.slice, + // Use a stripped-down indexOf as it's faster than native + // https://jsperf.com/thor-indexof-vs-for/5 + indexOf = function( list, elem ) { + var i = 0, + len = list.length; + for ( ; i < len; i++ ) { + if ( list[i] === elem ) { + return i; + } + } + return -1; + }, + + booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped", + + // Regular expressions + + // http://www.w3.org/TR/css3-selectors/#whitespace + whitespace = "[\\x20\\t\\r\\n\\f]", + + // http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier + identifier = "(?:\\\\.|[\\w-]|[^\0-\\xa0])+", + + // Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors + attributes = "\\[" + whitespace + "*(" + identifier + ")(?:" + whitespace + + // Operator (capture 2) + "*([*^$|!~]?=)" + whitespace + + // "Attribute values must be CSS identifiers [capture 5] or strings [capture 3 or capture 4]" + "*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" + whitespace + + "*\\]", + + pseudos = ":(" + identifier + ")(?:\\((" + + // To reduce the number of selectors needing tokenize in the preFilter, prefer arguments: + // 1. quoted (capture 3; capture 4 or capture 5) + "('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" + + // 2. simple (capture 6) + "((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" + + // 3. anything else (capture 2) + ".*" + + ")\\)|)", + + // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter + rwhitespace = new RegExp( whitespace + "+", "g" ), + rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ), + + rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ), + rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + "*" ), + rdescend = new RegExp( whitespace + "|>" ), + + rpseudo = new RegExp( pseudos ), + ridentifier = new RegExp( "^" + identifier + "$" ), + + matchExpr = { + "ID": new RegExp( "^#(" + identifier + ")" ), + "CLASS": new RegExp( "^\\.(" + identifier + ")" ), + "TAG": new RegExp( "^(" + identifier + "|[*])" ), + "ATTR": new RegExp( "^" + attributes ), + "PSEUDO": new RegExp( "^" + pseudos ), + "CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + whitespace + + "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace + + "*(\\d+)|))" + whitespace + "*\\)|)", "i" ), + "bool": new RegExp( "^(?:" + booleans + ")$", "i" ), + // For use in libraries implementing .is() + // We use this for POS matching in `select` + "needsContext": new RegExp( "^" + whitespace + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" + + whitespace + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" ) + }, + + rhtml = /HTML$/i, + rinputs = /^(?:input|select|textarea|button)$/i, + rheader = /^h\d$/i, + + rnative = /^[^{]+\{\s*\[native \w/, + + // Easily-parseable/retrievable ID or TAG or CLASS selectors + rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/, + + rsibling = /[+~]/, + + // CSS escapes + // http://www.w3.org/TR/CSS21/syndata.html#escaped-characters + runescape = new RegExp( "\\\\([\\da-f]{1,6}" + whitespace + "?|(" + whitespace + ")|.)", "ig" ), + funescape = function( _, escaped, escapedWhitespace ) { + var high = "0x" + escaped - 0x10000; + // NaN means non-codepoint + // Support: Firefox<24 + // Workaround erroneous numeric interpretation of +"0x" + return high !== high || escapedWhitespace ? + escaped : + high < 0 ? + // BMP codepoint + String.fromCharCode( high + 0x10000 ) : + // Supplemental Plane codepoint (surrogate pair) + String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 ); + }, + + // CSS string/identifier serialization + // https://drafts.csswg.org/cssom/#common-serializing-idioms + rcssescape = /([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g, + fcssescape = function( ch, asCodePoint ) { + if ( asCodePoint ) { + + // U+0000 NULL becomes U+FFFD REPLACEMENT CHARACTER + if ( ch === "\0" ) { + return "\uFFFD"; + } + + // Control characters and (dependent upon position) numbers get escaped as code points + return ch.slice( 0, -1 ) + "\\" + ch.charCodeAt( ch.length - 1 ).toString( 16 ) + " "; + } + + // Other potentially-special ASCII characters get backslash-escaped + return "\\" + ch; + }, + + // Used for iframes + // See setDocument() + // Removing the function wrapper causes a "Permission Denied" + // error in IE + unloadHandler = function() { + setDocument(); + }, + + inDisabledFieldset = addCombinator( + function( elem ) { + return elem.disabled === true && elem.nodeName.toLowerCase() === "fieldset"; + }, + { dir: "parentNode", next: "legend" } + ); + +// Optimize for push.apply( _, NodeList ) +try { + push.apply( + (arr = slice.call( preferredDoc.childNodes )), + preferredDoc.childNodes + ); + // Support: Android<4.0 + // Detect silently failing push.apply + arr[ preferredDoc.childNodes.length ].nodeType; +} catch ( e ) { + push = { apply: arr.length ? + + // Leverage slice if possible + function( target, els ) { + push_native.apply( target, slice.call(els) ); + } : + + // Support: IE<9 + // Otherwise append directly + function( target, els ) { + var j = target.length, + i = 0; + // Can't trust NodeList.length + while ( (target[j++] = els[i++]) ) {} + target.length = j - 1; + } + }; +} + +function Sizzle( selector, context, results, seed ) { + var m, i, elem, nid, match, groups, newSelector, + newContext = context && context.ownerDocument, + + // nodeType defaults to 9, since context defaults to document + nodeType = context ? context.nodeType : 9; + + results = results || []; + + // Return early from calls with invalid selector or context + if ( typeof selector !== "string" || !selector || + nodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) { + + return results; + } + + // Try to shortcut find operations (as opposed to filters) in HTML documents + if ( !seed ) { + + if ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) { + setDocument( context ); + } + context = context || document; + + if ( documentIsHTML ) { + + // If the selector is sufficiently simple, try using a "get*By*" DOM method + // (excepting DocumentFragment context, where the methods don't exist) + if ( nodeType !== 11 && (match = rquickExpr.exec( selector )) ) { + + // ID selector + if ( (m = match[1]) ) { + + // Document context + if ( nodeType === 9 ) { + if ( (elem = context.getElementById( m )) ) { + + // Support: IE, Opera, Webkit + // TODO: identify versions + // getElementById can match elements by name instead of ID + if ( elem.id === m ) { + results.push( elem ); + return results; + } + } else { + return results; + } + + // Element context + } else { + + // Support: IE, Opera, Webkit + // TODO: identify versions + // getElementById can match elements by name instead of ID + if ( newContext && (elem = newContext.getElementById( m )) && + contains( context, elem ) && + elem.id === m ) { + + results.push( elem ); + return results; + } + } + + // Type selector + } else if ( match[2] ) { + push.apply( results, context.getElementsByTagName( selector ) ); + return results; + + // Class selector + } else if ( (m = match[3]) && support.getElementsByClassName && + context.getElementsByClassName ) { + + push.apply( results, context.getElementsByClassName( m ) ); + return results; + } + } + + // Take advantage of querySelectorAll + if ( support.qsa && + !nonnativeSelectorCache[ selector + " " ] && + (!rbuggyQSA || !rbuggyQSA.test( selector )) && + + // Support: IE 8 only + // Exclude object elements + (nodeType !== 1 || context.nodeName.toLowerCase() !== "object") ) { + + newSelector = selector; + newContext = context; + + // qSA considers elements outside a scoping root when evaluating child or + // descendant combinators, which is not what we want. + // In such cases, we work around the behavior by prefixing every selector in the + // list with an ID selector referencing the scope context. + // Thanks to Andrew Dupont for this technique. + if ( nodeType === 1 && rdescend.test( selector ) ) { + + // Capture the context ID, setting it first if necessary + if ( (nid = context.getAttribute( "id" )) ) { + nid = nid.replace( rcssescape, fcssescape ); + } else { + context.setAttribute( "id", (nid = expando) ); + } + + // Prefix every selector in the list + groups = tokenize( selector ); + i = groups.length; + while ( i-- ) { + groups[i] = "#" + nid + " " + toSelector( groups[i] ); + } + newSelector = groups.join( "," ); + + // Expand context for sibling selectors + newContext = rsibling.test( selector ) && testContext( context.parentNode ) || + context; + } + + try { + push.apply( results, + newContext.querySelectorAll( newSelector ) + ); + return results; + } catch ( qsaError ) { + nonnativeSelectorCache( selector, true ); + } finally { + if ( nid === expando ) { + context.removeAttribute( "id" ); + } + } + } + } + } + + // All others + return select( selector.replace( rtrim, "$1" ), context, results, seed ); +} + +/** + * Create key-value caches of limited size + * @returns {function(string, object)} Returns the Object data after storing it on itself with + * property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength) + * deleting the oldest entry + */ +function createCache() { + var keys = []; + + function cache( key, value ) { + // Use (key + " ") to avoid collision with native prototype properties (see Issue #157) + if ( keys.push( key + " " ) > Expr.cacheLength ) { + // Only keep the most recent entries + delete cache[ keys.shift() ]; + } + return (cache[ key + " " ] = value); + } + return cache; +} + +/** + * Mark a function for special use by Sizzle + * @param {Function} fn The function to mark + */ +function markFunction( fn ) { + fn[ expando ] = true; + return fn; +} + +/** + * Support testing using an element + * @param {Function} fn Passed the created element and returns a boolean result + */ +function assert( fn ) { + var el = document.createElement("fieldset"); + + try { + return !!fn( el ); + } catch (e) { + return false; + } finally { + // Remove from its parent by default + if ( el.parentNode ) { + el.parentNode.removeChild( el ); + } + // release memory in IE + el = null; + } +} + +/** + * Adds the same handler for all of the specified attrs + * @param {String} attrs Pipe-separated list of attributes + * @param {Function} handler The method that will be applied + */ +function addHandle( attrs, handler ) { + var arr = attrs.split("|"), + i = arr.length; + + while ( i-- ) { + Expr.attrHandle[ arr[i] ] = handler; + } +} + +/** + * Checks document order of two siblings + * @param {Element} a + * @param {Element} b + * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b + */ +function siblingCheck( a, b ) { + var cur = b && a, + diff = cur && a.nodeType === 1 && b.nodeType === 1 && + a.sourceIndex - b.sourceIndex; + + // Use IE sourceIndex if available on both nodes + if ( diff ) { + return diff; + } + + // Check if b follows a + if ( cur ) { + while ( (cur = cur.nextSibling) ) { + if ( cur === b ) { + return -1; + } + } + } + + return a ? 1 : -1; +} + +/** + * Returns a function to use in pseudos for input types + * @param {String} type + */ +function createInputPseudo( type ) { + return function( elem ) { + var name = elem.nodeName.toLowerCase(); + return name === "input" && elem.type === type; + }; +} + +/** + * Returns a function to use in pseudos for buttons + * @param {String} type + */ +function createButtonPseudo( type ) { + return function( elem ) { + var name = elem.nodeName.toLowerCase(); + return (name === "input" || name === "button") && elem.type === type; + }; +} + +/** + * Returns a function to use in pseudos for :enabled/:disabled + * @param {Boolean} disabled true for :disabled; false for :enabled + */ +function createDisabledPseudo( disabled ) { + + // Known :disabled false positives: fieldset[disabled] > legend:nth-of-type(n+2) :can-disable + return function( elem ) { + + // Only certain elements can match :enabled or :disabled + // https://html.spec.whatwg.org/multipage/scripting.html#selector-enabled + // https://html.spec.whatwg.org/multipage/scripting.html#selector-disabled + if ( "form" in elem ) { + + // Check for inherited disabledness on relevant non-disabled elements: + // * listed form-associated elements in a disabled fieldset + // https://html.spec.whatwg.org/multipage/forms.html#category-listed + // https://html.spec.whatwg.org/multipage/forms.html#concept-fe-disabled + // * option elements in a disabled optgroup + // https://html.spec.whatwg.org/multipage/forms.html#concept-option-disabled + // All such elements have a "form" property. + if ( elem.parentNode && elem.disabled === false ) { + + // Option elements defer to a parent optgroup if present + if ( "label" in elem ) { + if ( "label" in elem.parentNode ) { + return elem.parentNode.disabled === disabled; + } else { + return elem.disabled === disabled; + } + } + + // Support: IE 6 - 11 + // Use the isDisabled shortcut property to check for disabled fieldset ancestors + return elem.isDisabled === disabled || + + // Where there is no isDisabled, check manually + /* jshint -W018 */ + elem.isDisabled !== !disabled && + inDisabledFieldset( elem ) === disabled; + } + + return elem.disabled === disabled; + + // Try to winnow out elements that can't be disabled before trusting the disabled property. + // Some victims get caught in our net (label, legend, menu, track), but it shouldn't + // even exist on them, let alone have a boolean value. + } else if ( "label" in elem ) { + return elem.disabled === disabled; + } + + // Remaining elements are neither :enabled nor :disabled + return false; + }; +} + +/** + * Returns a function to use in pseudos for positionals + * @param {Function} fn + */ +function createPositionalPseudo( fn ) { + return markFunction(function( argument ) { + argument = +argument; + return markFunction(function( seed, matches ) { + var j, + matchIndexes = fn( [], seed.length, argument ), + i = matchIndexes.length; + + // Match elements found at the specified indexes + while ( i-- ) { + if ( seed[ (j = matchIndexes[i]) ] ) { + seed[j] = !(matches[j] = seed[j]); + } + } + }); + }); +} + +/** + * Checks a node for validity as a Sizzle context + * @param {Element|Object=} context + * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value + */ +function testContext( context ) { + return context && typeof context.getElementsByTagName !== "undefined" && context; +} + +// Expose support vars for convenience +support = Sizzle.support = {}; + +/** + * Detects XML nodes + * @param {Element|Object} elem An element or a document + * @returns {Boolean} True iff elem is a non-HTML XML node + */ +isXML = Sizzle.isXML = function( elem ) { + var namespace = elem.namespaceURI, + docElem = (elem.ownerDocument || elem).documentElement; + + // Support: IE <=8 + // Assume HTML when documentElement doesn't yet exist, such as inside loading iframes + // https://bugs.jquery.com/ticket/4833 + return !rhtml.test( namespace || docElem && docElem.nodeName || "HTML" ); +}; + +/** + * Sets document-related variables once based on the current document + * @param {Element|Object} [doc] An element or document object to use to set the document + * @returns {Object} Returns the current document + */ +setDocument = Sizzle.setDocument = function( node ) { + var hasCompare, subWindow, + doc = node ? node.ownerDocument || node : preferredDoc; + + // Return early if doc is invalid or already selected + if ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) { + return document; + } + + // Update global variables + document = doc; + docElem = document.documentElement; + documentIsHTML = !isXML( document ); + + // Support: IE 9-11, Edge + // Accessing iframe documents after unload throws "permission denied" errors (jQuery #13936) + if ( preferredDoc !== document && + (subWindow = document.defaultView) && subWindow.top !== subWindow ) { + + // Support: IE 11, Edge + if ( subWindow.addEventListener ) { + subWindow.addEventListener( "unload", unloadHandler, false ); + + // Support: IE 9 - 10 only + } else if ( subWindow.attachEvent ) { + subWindow.attachEvent( "onunload", unloadHandler ); + } + } + + /* Attributes + ---------------------------------------------------------------------- */ + + // Support: IE<8 + // Verify that getAttribute really returns attributes and not properties + // (excepting IE8 booleans) + support.attributes = assert(function( el ) { + el.className = "i"; + return !el.getAttribute("className"); + }); + + /* getElement(s)By* + ---------------------------------------------------------------------- */ + + // Check if getElementsByTagName("*") returns only elements + support.getElementsByTagName = assert(function( el ) { + el.appendChild( document.createComment("") ); + return !el.getElementsByTagName("*").length; + }); + + // Support: IE<9 + support.getElementsByClassName = rnative.test( document.getElementsByClassName ); + + // Support: IE<10 + // Check if getElementById returns elements by name + // The broken getElementById methods don't pick up programmatically-set names, + // so use a roundabout getElementsByName test + support.getById = assert(function( el ) { + docElem.appendChild( el ).id = expando; + return !document.getElementsByName || !document.getElementsByName( expando ).length; + }); + + // ID filter and find + if ( support.getById ) { + Expr.filter["ID"] = function( id ) { + var attrId = id.replace( runescape, funescape ); + return function( elem ) { + return elem.getAttribute("id") === attrId; + }; + }; + Expr.find["ID"] = function( id, context ) { + if ( typeof context.getElementById !== "undefined" && documentIsHTML ) { + var elem = context.getElementById( id ); + return elem ? [ elem ] : []; + } + }; + } else { + Expr.filter["ID"] = function( id ) { + var attrId = id.replace( runescape, funescape ); + return function( elem ) { + var node = typeof elem.getAttributeNode !== "undefined" && + elem.getAttributeNode("id"); + return node && node.value === attrId; + }; + }; + + // Support: IE 6 - 7 only + // getElementById is not reliable as a find shortcut + Expr.find["ID"] = function( id, context ) { + if ( typeof context.getElementById !== "undefined" && documentIsHTML ) { + var node, i, elems, + elem = context.getElementById( id ); + + if ( elem ) { + + // Verify the id attribute + node = elem.getAttributeNode("id"); + if ( node && node.value === id ) { + return [ elem ]; + } + + // Fall back on getElementsByName + elems = context.getElementsByName( id ); + i = 0; + while ( (elem = elems[i++]) ) { + node = elem.getAttributeNode("id"); + if ( node && node.value === id ) { + return [ elem ]; + } + } + } + + return []; + } + }; + } + + // Tag + Expr.find["TAG"] = support.getElementsByTagName ? + function( tag, context ) { + if ( typeof context.getElementsByTagName !== "undefined" ) { + return context.getElementsByTagName( tag ); + + // DocumentFragment nodes don't have gEBTN + } else if ( support.qsa ) { + return context.querySelectorAll( tag ); + } + } : + + function( tag, context ) { + var elem, + tmp = [], + i = 0, + // By happy coincidence, a (broken) gEBTN appears on DocumentFragment nodes too + results = context.getElementsByTagName( tag ); + + // Filter out possible comments + if ( tag === "*" ) { + while ( (elem = results[i++]) ) { + if ( elem.nodeType === 1 ) { + tmp.push( elem ); + } + } + + return tmp; + } + return results; + }; + + // Class + Expr.find["CLASS"] = support.getElementsByClassName && function( className, context ) { + if ( typeof context.getElementsByClassName !== "undefined" && documentIsHTML ) { + return context.getElementsByClassName( className ); + } + }; + + /* QSA/matchesSelector + ---------------------------------------------------------------------- */ + + // QSA and matchesSelector support + + // matchesSelector(:active) reports false when true (IE9/Opera 11.5) + rbuggyMatches = []; + + // qSa(:focus) reports false when true (Chrome 21) + // We allow this because of a bug in IE8/9 that throws an error + // whenever `document.activeElement` is accessed on an iframe + // So, we allow :focus to pass through QSA all the time to avoid the IE error + // See https://bugs.jquery.com/ticket/13378 + rbuggyQSA = []; + + if ( (support.qsa = rnative.test( document.querySelectorAll )) ) { + // Build QSA regex + // Regex strategy adopted from Diego Perini + assert(function( el ) { + // Select is set to empty string on purpose + // This is to test IE's treatment of not explicitly + // setting a boolean content attribute, + // since its presence should be enough + // https://bugs.jquery.com/ticket/12359 + docElem.appendChild( el ).innerHTML = "" + + ""; + + // Support: IE8, Opera 11-12.16 + // Nothing should be selected when empty strings follow ^= or $= or *= + // The test attribute must be unknown in Opera but "safe" for WinRT + // https://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section + if ( el.querySelectorAll("[msallowcapture^='']").length ) { + rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" ); + } + + // Support: IE8 + // Boolean attributes and "value" are not treated correctly + if ( !el.querySelectorAll("[selected]").length ) { + rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" ); + } + + // Support: Chrome<29, Android<4.4, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.8+ + if ( !el.querySelectorAll( "[id~=" + expando + "-]" ).length ) { + rbuggyQSA.push("~="); + } + + // Webkit/Opera - :checked should return selected option elements + // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked + // IE8 throws error here and will not see later tests + if ( !el.querySelectorAll(":checked").length ) { + rbuggyQSA.push(":checked"); + } + + // Support: Safari 8+, iOS 8+ + // https://bugs.webkit.org/show_bug.cgi?id=136851 + // In-page `selector#id sibling-combinator selector` fails + if ( !el.querySelectorAll( "a#" + expando + "+*" ).length ) { + rbuggyQSA.push(".#.+[+~]"); + } + }); + + assert(function( el ) { + el.innerHTML = "" + + ""; + + // Support: Windows 8 Native Apps + // The type and name attributes are restricted during .innerHTML assignment + var input = document.createElement("input"); + input.setAttribute( "type", "hidden" ); + el.appendChild( input ).setAttribute( "name", "D" ); + + // Support: IE8 + // Enforce case-sensitivity of name attribute + if ( el.querySelectorAll("[name=d]").length ) { + rbuggyQSA.push( "name" + whitespace + "*[*^$|!~]?=" ); + } + + // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled) + // IE8 throws error here and will not see later tests + if ( el.querySelectorAll(":enabled").length !== 2 ) { + rbuggyQSA.push( ":enabled", ":disabled" ); + } + + // Support: IE9-11+ + // IE's :disabled selector does not pick up the children of disabled fieldsets + docElem.appendChild( el ).disabled = true; + if ( el.querySelectorAll(":disabled").length !== 2 ) { + rbuggyQSA.push( ":enabled", ":disabled" ); + } + + // Opera 10-11 does not throw on post-comma invalid pseudos + el.querySelectorAll("*,:x"); + rbuggyQSA.push(",.*:"); + }); + } + + if ( (support.matchesSelector = rnative.test( (matches = docElem.matches || + docElem.webkitMatchesSelector || + docElem.mozMatchesSelector || + docElem.oMatchesSelector || + docElem.msMatchesSelector) )) ) { + + assert(function( el ) { + // Check to see if it's possible to do matchesSelector + // on a disconnected node (IE 9) + support.disconnectedMatch = matches.call( el, "*" ); + + // This should fail with an exception + // Gecko does not error, returns false instead + matches.call( el, "[s!='']:x" ); + rbuggyMatches.push( "!=", pseudos ); + }); + } + + rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join("|") ); + rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join("|") ); + + /* Contains + ---------------------------------------------------------------------- */ + hasCompare = rnative.test( docElem.compareDocumentPosition ); + + // Element contains another + // Purposefully self-exclusive + // As in, an element does not contain itself + contains = hasCompare || rnative.test( docElem.contains ) ? + function( a, b ) { + var adown = a.nodeType === 9 ? a.documentElement : a, + bup = b && b.parentNode; + return a === bup || !!( bup && bup.nodeType === 1 && ( + adown.contains ? + adown.contains( bup ) : + a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16 + )); + } : + function( a, b ) { + if ( b ) { + while ( (b = b.parentNode) ) { + if ( b === a ) { + return true; + } + } + } + return false; + }; + + /* Sorting + ---------------------------------------------------------------------- */ + + // Document order sorting + sortOrder = hasCompare ? + function( a, b ) { + + // Flag for duplicate removal + if ( a === b ) { + hasDuplicate = true; + return 0; + } + + // Sort on method existence if only one input has compareDocumentPosition + var compare = !a.compareDocumentPosition - !b.compareDocumentPosition; + if ( compare ) { + return compare; + } + + // Calculate position if both inputs belong to the same document + compare = ( a.ownerDocument || a ) === ( b.ownerDocument || b ) ? + a.compareDocumentPosition( b ) : + + // Otherwise we know they are disconnected + 1; + + // Disconnected nodes + if ( compare & 1 || + (!support.sortDetached && b.compareDocumentPosition( a ) === compare) ) { + + // Choose the first element that is related to our preferred document + if ( a === document || a.ownerDocument === preferredDoc && contains(preferredDoc, a) ) { + return -1; + } + if ( b === document || b.ownerDocument === preferredDoc && contains(preferredDoc, b) ) { + return 1; + } + + // Maintain original order + return sortInput ? + ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) : + 0; + } + + return compare & 4 ? -1 : 1; + } : + function( a, b ) { + // Exit early if the nodes are identical + if ( a === b ) { + hasDuplicate = true; + return 0; + } + + var cur, + i = 0, + aup = a.parentNode, + bup = b.parentNode, + ap = [ a ], + bp = [ b ]; + + // Parentless nodes are either documents or disconnected + if ( !aup || !bup ) { + return a === document ? -1 : + b === document ? 1 : + aup ? -1 : + bup ? 1 : + sortInput ? + ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) : + 0; + + // If the nodes are siblings, we can do a quick check + } else if ( aup === bup ) { + return siblingCheck( a, b ); + } + + // Otherwise we need full lists of their ancestors for comparison + cur = a; + while ( (cur = cur.parentNode) ) { + ap.unshift( cur ); + } + cur = b; + while ( (cur = cur.parentNode) ) { + bp.unshift( cur ); + } + + // Walk down the tree looking for a discrepancy + while ( ap[i] === bp[i] ) { + i++; + } + + return i ? + // Do a sibling check if the nodes have a common ancestor + siblingCheck( ap[i], bp[i] ) : + + // Otherwise nodes in our document sort first + ap[i] === preferredDoc ? -1 : + bp[i] === preferredDoc ? 1 : + 0; + }; + + return document; +}; + +Sizzle.matches = function( expr, elements ) { + return Sizzle( expr, null, null, elements ); +}; + +Sizzle.matchesSelector = function( elem, expr ) { + // Set document vars if needed + if ( ( elem.ownerDocument || elem ) !== document ) { + setDocument( elem ); + } + + if ( support.matchesSelector && documentIsHTML && + !nonnativeSelectorCache[ expr + " " ] && + ( !rbuggyMatches || !rbuggyMatches.test( expr ) ) && + ( !rbuggyQSA || !rbuggyQSA.test( expr ) ) ) { + + try { + var ret = matches.call( elem, expr ); + + // IE 9's matchesSelector returns false on disconnected nodes + if ( ret || support.disconnectedMatch || + // As well, disconnected nodes are said to be in a document + // fragment in IE 9 + elem.document && elem.document.nodeType !== 11 ) { + return ret; + } + } catch (e) { + nonnativeSelectorCache( expr, true ); + } + } + + return Sizzle( expr, document, null, [ elem ] ).length > 0; +}; + +Sizzle.contains = function( context, elem ) { + // Set document vars if needed + if ( ( context.ownerDocument || context ) !== document ) { + setDocument( context ); + } + return contains( context, elem ); +}; + +Sizzle.attr = function( elem, name ) { + // Set document vars if needed + if ( ( elem.ownerDocument || elem ) !== document ) { + setDocument( elem ); + } + + var fn = Expr.attrHandle[ name.toLowerCase() ], + // Don't get fooled by Object.prototype properties (jQuery #13807) + val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ? + fn( elem, name, !documentIsHTML ) : + undefined; + + return val !== undefined ? + val : + support.attributes || !documentIsHTML ? + elem.getAttribute( name ) : + (val = elem.getAttributeNode(name)) && val.specified ? + val.value : + null; +}; + +Sizzle.escape = function( sel ) { + return (sel + "").replace( rcssescape, fcssescape ); +}; + +Sizzle.error = function( msg ) { + throw new Error( "Syntax error, unrecognized expression: " + msg ); +}; + +/** + * Document sorting and removing duplicates + * @param {ArrayLike} results + */ +Sizzle.uniqueSort = function( results ) { + var elem, + duplicates = [], + j = 0, + i = 0; + + // Unless we *know* we can detect duplicates, assume their presence + hasDuplicate = !support.detectDuplicates; + sortInput = !support.sortStable && results.slice( 0 ); + results.sort( sortOrder ); + + if ( hasDuplicate ) { + while ( (elem = results[i++]) ) { + if ( elem === results[ i ] ) { + j = duplicates.push( i ); + } + } + while ( j-- ) { + results.splice( duplicates[ j ], 1 ); + } + } + + // Clear input after sorting to release objects + // See https://github.com/jquery/sizzle/pull/225 + sortInput = null; + + return results; +}; + +/** + * Utility function for retrieving the text value of an array of DOM nodes + * @param {Array|Element} elem + */ +getText = Sizzle.getText = function( elem ) { + var node, + ret = "", + i = 0, + nodeType = elem.nodeType; + + if ( !nodeType ) { + // If no nodeType, this is expected to be an array + while ( (node = elem[i++]) ) { + // Do not traverse comment nodes + ret += getText( node ); + } + } else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) { + // Use textContent for elements + // innerText usage removed for consistency of new lines (jQuery #11153) + if ( typeof elem.textContent === "string" ) { + return elem.textContent; + } else { + // Traverse its children + for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { + ret += getText( elem ); + } + } + } else if ( nodeType === 3 || nodeType === 4 ) { + return elem.nodeValue; + } + // Do not include comment or processing instruction nodes + + return ret; +}; + +Expr = Sizzle.selectors = { + + // Can be adjusted by the user + cacheLength: 50, + + createPseudo: markFunction, + + match: matchExpr, + + attrHandle: {}, + + find: {}, + + relative: { + ">": { dir: "parentNode", first: true }, + " ": { dir: "parentNode" }, + "+": { dir: "previousSibling", first: true }, + "~": { dir: "previousSibling" } + }, + + preFilter: { + "ATTR": function( match ) { + match[1] = match[1].replace( runescape, funescape ); + + // Move the given value to match[3] whether quoted or unquoted + match[3] = ( match[3] || match[4] || match[5] || "" ).replace( runescape, funescape ); + + if ( match[2] === "~=" ) { + match[3] = " " + match[3] + " "; + } + + return match.slice( 0, 4 ); + }, + + "CHILD": function( match ) { + /* matches from matchExpr["CHILD"] + 1 type (only|nth|...) + 2 what (child|of-type) + 3 argument (even|odd|\d*|\d*n([+-]\d+)?|...) + 4 xn-component of xn+y argument ([+-]?\d*n|) + 5 sign of xn-component + 6 x of xn-component + 7 sign of y-component + 8 y of y-component + */ + match[1] = match[1].toLowerCase(); + + if ( match[1].slice( 0, 3 ) === "nth" ) { + // nth-* requires argument + if ( !match[3] ) { + Sizzle.error( match[0] ); + } + + // numeric x and y parameters for Expr.filter.CHILD + // remember that false/true cast respectively to 0/1 + match[4] = +( match[4] ? match[5] + (match[6] || 1) : 2 * ( match[3] === "even" || match[3] === "odd" ) ); + match[5] = +( ( match[7] + match[8] ) || match[3] === "odd" ); + + // other types prohibit arguments + } else if ( match[3] ) { + Sizzle.error( match[0] ); + } + + return match; + }, + + "PSEUDO": function( match ) { + var excess, + unquoted = !match[6] && match[2]; + + if ( matchExpr["CHILD"].test( match[0] ) ) { + return null; + } + + // Accept quoted arguments as-is + if ( match[3] ) { + match[2] = match[4] || match[5] || ""; + + // Strip excess characters from unquoted arguments + } else if ( unquoted && rpseudo.test( unquoted ) && + // Get excess from tokenize (recursively) + (excess = tokenize( unquoted, true )) && + // advance to the next closing parenthesis + (excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length) ) { + + // excess is a negative index + match[0] = match[0].slice( 0, excess ); + match[2] = unquoted.slice( 0, excess ); + } + + // Return only captures needed by the pseudo filter method (type and argument) + return match.slice( 0, 3 ); + } + }, + + filter: { + + "TAG": function( nodeNameSelector ) { + var nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase(); + return nodeNameSelector === "*" ? + function() { return true; } : + function( elem ) { + return elem.nodeName && elem.nodeName.toLowerCase() === nodeName; + }; + }, + + "CLASS": function( className ) { + var pattern = classCache[ className + " " ]; + + return pattern || + (pattern = new RegExp( "(^|" + whitespace + ")" + className + "(" + whitespace + "|$)" )) && + classCache( className, function( elem ) { + return pattern.test( typeof elem.className === "string" && elem.className || typeof elem.getAttribute !== "undefined" && elem.getAttribute("class") || "" ); + }); + }, + + "ATTR": function( name, operator, check ) { + return function( elem ) { + var result = Sizzle.attr( elem, name ); + + if ( result == null ) { + return operator === "!="; + } + if ( !operator ) { + return true; + } + + result += ""; + + return operator === "=" ? result === check : + operator === "!=" ? result !== check : + operator === "^=" ? check && result.indexOf( check ) === 0 : + operator === "*=" ? check && result.indexOf( check ) > -1 : + operator === "$=" ? check && result.slice( -check.length ) === check : + operator === "~=" ? ( " " + result.replace( rwhitespace, " " ) + " " ).indexOf( check ) > -1 : + operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" : + false; + }; + }, + + "CHILD": function( type, what, argument, first, last ) { + var simple = type.slice( 0, 3 ) !== "nth", + forward = type.slice( -4 ) !== "last", + ofType = what === "of-type"; + + return first === 1 && last === 0 ? + + // Shortcut for :nth-*(n) + function( elem ) { + return !!elem.parentNode; + } : + + function( elem, context, xml ) { + var cache, uniqueCache, outerCache, node, nodeIndex, start, + dir = simple !== forward ? "nextSibling" : "previousSibling", + parent = elem.parentNode, + name = ofType && elem.nodeName.toLowerCase(), + useCache = !xml && !ofType, + diff = false; + + if ( parent ) { + + // :(first|last|only)-(child|of-type) + if ( simple ) { + while ( dir ) { + node = elem; + while ( (node = node[ dir ]) ) { + if ( ofType ? + node.nodeName.toLowerCase() === name : + node.nodeType === 1 ) { + + return false; + } + } + // Reverse direction for :only-* (if we haven't yet done so) + start = dir = type === "only" && !start && "nextSibling"; + } + return true; + } + + start = [ forward ? parent.firstChild : parent.lastChild ]; + + // non-xml :nth-child(...) stores cache data on `parent` + if ( forward && useCache ) { + + // Seek `elem` from a previously-cached index + + // ...in a gzip-friendly way + node = parent; + outerCache = node[ expando ] || (node[ expando ] = {}); + + // Support: IE <9 only + // Defend against cloned attroperties (jQuery gh-1709) + uniqueCache = outerCache[ node.uniqueID ] || + (outerCache[ node.uniqueID ] = {}); + + cache = uniqueCache[ type ] || []; + nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ]; + diff = nodeIndex && cache[ 2 ]; + node = nodeIndex && parent.childNodes[ nodeIndex ]; + + while ( (node = ++nodeIndex && node && node[ dir ] || + + // Fallback to seeking `elem` from the start + (diff = nodeIndex = 0) || start.pop()) ) { + + // When found, cache indexes on `parent` and break + if ( node.nodeType === 1 && ++diff && node === elem ) { + uniqueCache[ type ] = [ dirruns, nodeIndex, diff ]; + break; + } + } + + } else { + // Use previously-cached element index if available + if ( useCache ) { + // ...in a gzip-friendly way + node = elem; + outerCache = node[ expando ] || (node[ expando ] = {}); + + // Support: IE <9 only + // Defend against cloned attroperties (jQuery gh-1709) + uniqueCache = outerCache[ node.uniqueID ] || + (outerCache[ node.uniqueID ] = {}); + + cache = uniqueCache[ type ] || []; + nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ]; + diff = nodeIndex; + } + + // xml :nth-child(...) + // or :nth-last-child(...) or :nth(-last)?-of-type(...) + if ( diff === false ) { + // Use the same loop as above to seek `elem` from the start + while ( (node = ++nodeIndex && node && node[ dir ] || + (diff = nodeIndex = 0) || start.pop()) ) { + + if ( ( ofType ? + node.nodeName.toLowerCase() === name : + node.nodeType === 1 ) && + ++diff ) { + + // Cache the index of each encountered element + if ( useCache ) { + outerCache = node[ expando ] || (node[ expando ] = {}); + + // Support: IE <9 only + // Defend against cloned attroperties (jQuery gh-1709) + uniqueCache = outerCache[ node.uniqueID ] || + (outerCache[ node.uniqueID ] = {}); + + uniqueCache[ type ] = [ dirruns, diff ]; + } + + if ( node === elem ) { + break; + } + } + } + } + } + + // Incorporate the offset, then check against cycle size + diff -= last; + return diff === first || ( diff % first === 0 && diff / first >= 0 ); + } + }; + }, + + "PSEUDO": function( pseudo, argument ) { + // pseudo-class names are case-insensitive + // http://www.w3.org/TR/selectors/#pseudo-classes + // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters + // Remember that setFilters inherits from pseudos + var args, + fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] || + Sizzle.error( "unsupported pseudo: " + pseudo ); + + // The user may use createPseudo to indicate that + // arguments are needed to create the filter function + // just as Sizzle does + if ( fn[ expando ] ) { + return fn( argument ); + } + + // But maintain support for old signatures + if ( fn.length > 1 ) { + args = [ pseudo, pseudo, "", argument ]; + return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ? + markFunction(function( seed, matches ) { + var idx, + matched = fn( seed, argument ), + i = matched.length; + while ( i-- ) { + idx = indexOf( seed, matched[i] ); + seed[ idx ] = !( matches[ idx ] = matched[i] ); + } + }) : + function( elem ) { + return fn( elem, 0, args ); + }; + } + + return fn; + } + }, + + pseudos: { + // Potentially complex pseudos + "not": markFunction(function( selector ) { + // Trim the selector passed to compile + // to avoid treating leading and trailing + // spaces as combinators + var input = [], + results = [], + matcher = compile( selector.replace( rtrim, "$1" ) ); + + return matcher[ expando ] ? + markFunction(function( seed, matches, context, xml ) { + var elem, + unmatched = matcher( seed, null, xml, [] ), + i = seed.length; + + // Match elements unmatched by `matcher` + while ( i-- ) { + if ( (elem = unmatched[i]) ) { + seed[i] = !(matches[i] = elem); + } + } + }) : + function( elem, context, xml ) { + input[0] = elem; + matcher( input, null, xml, results ); + // Don't keep the element (issue #299) + input[0] = null; + return !results.pop(); + }; + }), + + "has": markFunction(function( selector ) { + return function( elem ) { + return Sizzle( selector, elem ).length > 0; + }; + }), + + "contains": markFunction(function( text ) { + text = text.replace( runescape, funescape ); + return function( elem ) { + return ( elem.textContent || getText( elem ) ).indexOf( text ) > -1; + }; + }), + + // "Whether an element is represented by a :lang() selector + // is based solely on the element's language value + // being equal to the identifier C, + // or beginning with the identifier C immediately followed by "-". + // The matching of C against the element's language value is performed case-insensitively. + // The identifier C does not have to be a valid language name." + // http://www.w3.org/TR/selectors/#lang-pseudo + "lang": markFunction( function( lang ) { + // lang value must be a valid identifier + if ( !ridentifier.test(lang || "") ) { + Sizzle.error( "unsupported lang: " + lang ); + } + lang = lang.replace( runescape, funescape ).toLowerCase(); + return function( elem ) { + var elemLang; + do { + if ( (elemLang = documentIsHTML ? + elem.lang : + elem.getAttribute("xml:lang") || elem.getAttribute("lang")) ) { + + elemLang = elemLang.toLowerCase(); + return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0; + } + } while ( (elem = elem.parentNode) && elem.nodeType === 1 ); + return false; + }; + }), + + // Miscellaneous + "target": function( elem ) { + var hash = window.location && window.location.hash; + return hash && hash.slice( 1 ) === elem.id; + }, + + "root": function( elem ) { + return elem === docElem; + }, + + "focus": function( elem ) { + return elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex); + }, + + // Boolean properties + "enabled": createDisabledPseudo( false ), + "disabled": createDisabledPseudo( true ), + + "checked": function( elem ) { + // In CSS3, :checked should return both checked and selected elements + // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked + var nodeName = elem.nodeName.toLowerCase(); + return (nodeName === "input" && !!elem.checked) || (nodeName === "option" && !!elem.selected); + }, + + "selected": function( elem ) { + // Accessing this property makes selected-by-default + // options in Safari work properly + if ( elem.parentNode ) { + elem.parentNode.selectedIndex; + } + + return elem.selected === true; + }, + + // Contents + "empty": function( elem ) { + // http://www.w3.org/TR/selectors/#empty-pseudo + // :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5), + // but not by others (comment: 8; processing instruction: 7; etc.) + // nodeType < 6 works because attributes (2) do not appear as children + for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { + if ( elem.nodeType < 6 ) { + return false; + } + } + return true; + }, + + "parent": function( elem ) { + return !Expr.pseudos["empty"]( elem ); + }, + + // Element/input types + "header": function( elem ) { + return rheader.test( elem.nodeName ); + }, + + "input": function( elem ) { + return rinputs.test( elem.nodeName ); + }, + + "button": function( elem ) { + var name = elem.nodeName.toLowerCase(); + return name === "input" && elem.type === "button" || name === "button"; + }, + + "text": function( elem ) { + var attr; + return elem.nodeName.toLowerCase() === "input" && + elem.type === "text" && + + // Support: IE<8 + // New HTML5 attribute values (e.g., "search") appear with elem.type === "text" + ( (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === "text" ); + }, + + // Position-in-collection + "first": createPositionalPseudo(function() { + return [ 0 ]; + }), + + "last": createPositionalPseudo(function( matchIndexes, length ) { + return [ length - 1 ]; + }), + + "eq": createPositionalPseudo(function( matchIndexes, length, argument ) { + return [ argument < 0 ? argument + length : argument ]; + }), + + "even": createPositionalPseudo(function( matchIndexes, length ) { + var i = 0; + for ( ; i < length; i += 2 ) { + matchIndexes.push( i ); + } + return matchIndexes; + }), + + "odd": createPositionalPseudo(function( matchIndexes, length ) { + var i = 1; + for ( ; i < length; i += 2 ) { + matchIndexes.push( i ); + } + return matchIndexes; + }), + + "lt": createPositionalPseudo(function( matchIndexes, length, argument ) { + var i = argument < 0 ? + argument + length : + argument > length ? + length : + argument; + for ( ; --i >= 0; ) { + matchIndexes.push( i ); + } + return matchIndexes; + }), + + "gt": createPositionalPseudo(function( matchIndexes, length, argument ) { + var i = argument < 0 ? argument + length : argument; + for ( ; ++i < length; ) { + matchIndexes.push( i ); + } + return matchIndexes; + }) + } +}; + +Expr.pseudos["nth"] = Expr.pseudos["eq"]; + +// Add button/input type pseudos +for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) { + Expr.pseudos[ i ] = createInputPseudo( i ); +} +for ( i in { submit: true, reset: true } ) { + Expr.pseudos[ i ] = createButtonPseudo( i ); +} + +// Easy API for creating new setFilters +function setFilters() {} +setFilters.prototype = Expr.filters = Expr.pseudos; +Expr.setFilters = new setFilters(); + +tokenize = Sizzle.tokenize = function( selector, parseOnly ) { + var matched, match, tokens, type, + soFar, groups, preFilters, + cached = tokenCache[ selector + " " ]; + + if ( cached ) { + return parseOnly ? 0 : cached.slice( 0 ); + } + + soFar = selector; + groups = []; + preFilters = Expr.preFilter; + + while ( soFar ) { + + // Comma and first run + if ( !matched || (match = rcomma.exec( soFar )) ) { + if ( match ) { + // Don't consume trailing commas as valid + soFar = soFar.slice( match[0].length ) || soFar; + } + groups.push( (tokens = []) ); + } + + matched = false; + + // Combinators + if ( (match = rcombinators.exec( soFar )) ) { + matched = match.shift(); + tokens.push({ + value: matched, + // Cast descendant combinators to space + type: match[0].replace( rtrim, " " ) + }); + soFar = soFar.slice( matched.length ); + } + + // Filters + for ( type in Expr.filter ) { + if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] || + (match = preFilters[ type ]( match ))) ) { + matched = match.shift(); + tokens.push({ + value: matched, + type: type, + matches: match + }); + soFar = soFar.slice( matched.length ); + } + } + + if ( !matched ) { + break; + } + } + + // Return the length of the invalid excess + // if we're just parsing + // Otherwise, throw an error or return tokens + return parseOnly ? + soFar.length : + soFar ? + Sizzle.error( selector ) : + // Cache the tokens + tokenCache( selector, groups ).slice( 0 ); +}; + +function toSelector( tokens ) { + var i = 0, + len = tokens.length, + selector = ""; + for ( ; i < len; i++ ) { + selector += tokens[i].value; + } + return selector; +} + +function addCombinator( matcher, combinator, base ) { + var dir = combinator.dir, + skip = combinator.next, + key = skip || dir, + checkNonElements = base && key === "parentNode", + doneName = done++; + + return combinator.first ? + // Check against closest ancestor/preceding element + function( elem, context, xml ) { + while ( (elem = elem[ dir ]) ) { + if ( elem.nodeType === 1 || checkNonElements ) { + return matcher( elem, context, xml ); + } + } + return false; + } : + + // Check against all ancestor/preceding elements + function( elem, context, xml ) { + var oldCache, uniqueCache, outerCache, + newCache = [ dirruns, doneName ]; + + // We can't set arbitrary data on XML nodes, so they don't benefit from combinator caching + if ( xml ) { + while ( (elem = elem[ dir ]) ) { + if ( elem.nodeType === 1 || checkNonElements ) { + if ( matcher( elem, context, xml ) ) { + return true; + } + } + } + } else { + while ( (elem = elem[ dir ]) ) { + if ( elem.nodeType === 1 || checkNonElements ) { + outerCache = elem[ expando ] || (elem[ expando ] = {}); + + // Support: IE <9 only + // Defend against cloned attroperties (jQuery gh-1709) + uniqueCache = outerCache[ elem.uniqueID ] || (outerCache[ elem.uniqueID ] = {}); + + if ( skip && skip === elem.nodeName.toLowerCase() ) { + elem = elem[ dir ] || elem; + } else if ( (oldCache = uniqueCache[ key ]) && + oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) { + + // Assign to newCache so results back-propagate to previous elements + return (newCache[ 2 ] = oldCache[ 2 ]); + } else { + // Reuse newcache so results back-propagate to previous elements + uniqueCache[ key ] = newCache; + + // A match means we're done; a fail means we have to keep checking + if ( (newCache[ 2 ] = matcher( elem, context, xml )) ) { + return true; + } + } + } + } + } + return false; + }; +} + +function elementMatcher( matchers ) { + return matchers.length > 1 ? + function( elem, context, xml ) { + var i = matchers.length; + while ( i-- ) { + if ( !matchers[i]( elem, context, xml ) ) { + return false; + } + } + return true; + } : + matchers[0]; +} + +function multipleContexts( selector, contexts, results ) { + var i = 0, + len = contexts.length; + for ( ; i < len; i++ ) { + Sizzle( selector, contexts[i], results ); + } + return results; +} + +function condense( unmatched, map, filter, context, xml ) { + var elem, + newUnmatched = [], + i = 0, + len = unmatched.length, + mapped = map != null; + + for ( ; i < len; i++ ) { + if ( (elem = unmatched[i]) ) { + if ( !filter || filter( elem, context, xml ) ) { + newUnmatched.push( elem ); + if ( mapped ) { + map.push( i ); + } + } + } + } + + return newUnmatched; +} + +function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) { + if ( postFilter && !postFilter[ expando ] ) { + postFilter = setMatcher( postFilter ); + } + if ( postFinder && !postFinder[ expando ] ) { + postFinder = setMatcher( postFinder, postSelector ); + } + return markFunction(function( seed, results, context, xml ) { + var temp, i, elem, + preMap = [], + postMap = [], + preexisting = results.length, + + // Get initial elements from seed or context + elems = seed || multipleContexts( selector || "*", context.nodeType ? [ context ] : context, [] ), + + // Prefilter to get matcher input, preserving a map for seed-results synchronization + matcherIn = preFilter && ( seed || !selector ) ? + condense( elems, preMap, preFilter, context, xml ) : + elems, + + matcherOut = matcher ? + // If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results, + postFinder || ( seed ? preFilter : preexisting || postFilter ) ? + + // ...intermediate processing is necessary + [] : + + // ...otherwise use results directly + results : + matcherIn; + + // Find primary matches + if ( matcher ) { + matcher( matcherIn, matcherOut, context, xml ); + } + + // Apply postFilter + if ( postFilter ) { + temp = condense( matcherOut, postMap ); + postFilter( temp, [], context, xml ); + + // Un-match failing elements by moving them back to matcherIn + i = temp.length; + while ( i-- ) { + if ( (elem = temp[i]) ) { + matcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem); + } + } + } + + if ( seed ) { + if ( postFinder || preFilter ) { + if ( postFinder ) { + // Get the final matcherOut by condensing this intermediate into postFinder contexts + temp = []; + i = matcherOut.length; + while ( i-- ) { + if ( (elem = matcherOut[i]) ) { + // Restore matcherIn since elem is not yet a final match + temp.push( (matcherIn[i] = elem) ); + } + } + postFinder( null, (matcherOut = []), temp, xml ); + } + + // Move matched elements from seed to results to keep them synchronized + i = matcherOut.length; + while ( i-- ) { + if ( (elem = matcherOut[i]) && + (temp = postFinder ? indexOf( seed, elem ) : preMap[i]) > -1 ) { + + seed[temp] = !(results[temp] = elem); + } + } + } + + // Add elements to results, through postFinder if defined + } else { + matcherOut = condense( + matcherOut === results ? + matcherOut.splice( preexisting, matcherOut.length ) : + matcherOut + ); + if ( postFinder ) { + postFinder( null, results, matcherOut, xml ); + } else { + push.apply( results, matcherOut ); + } + } + }); +} + +function matcherFromTokens( tokens ) { + var checkContext, matcher, j, + len = tokens.length, + leadingRelative = Expr.relative[ tokens[0].type ], + implicitRelative = leadingRelative || Expr.relative[" "], + i = leadingRelative ? 1 : 0, + + // The foundational matcher ensures that elements are reachable from top-level context(s) + matchContext = addCombinator( function( elem ) { + return elem === checkContext; + }, implicitRelative, true ), + matchAnyContext = addCombinator( function( elem ) { + return indexOf( checkContext, elem ) > -1; + }, implicitRelative, true ), + matchers = [ function( elem, context, xml ) { + var ret = ( !leadingRelative && ( xml || context !== outermostContext ) ) || ( + (checkContext = context).nodeType ? + matchContext( elem, context, xml ) : + matchAnyContext( elem, context, xml ) ); + // Avoid hanging onto element (issue #299) + checkContext = null; + return ret; + } ]; + + for ( ; i < len; i++ ) { + if ( (matcher = Expr.relative[ tokens[i].type ]) ) { + matchers = [ addCombinator(elementMatcher( matchers ), matcher) ]; + } else { + matcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches ); + + // Return special upon seeing a positional matcher + if ( matcher[ expando ] ) { + // Find the next relative operator (if any) for proper handling + j = ++i; + for ( ; j < len; j++ ) { + if ( Expr.relative[ tokens[j].type ] ) { + break; + } + } + return setMatcher( + i > 1 && elementMatcher( matchers ), + i > 1 && toSelector( + // If the preceding token was a descendant combinator, insert an implicit any-element `*` + tokens.slice( 0, i - 1 ).concat({ value: tokens[ i - 2 ].type === " " ? "*" : "" }) + ).replace( rtrim, "$1" ), + matcher, + i < j && matcherFromTokens( tokens.slice( i, j ) ), + j < len && matcherFromTokens( (tokens = tokens.slice( j )) ), + j < len && toSelector( tokens ) + ); + } + matchers.push( matcher ); + } + } + + return elementMatcher( matchers ); +} + +function matcherFromGroupMatchers( elementMatchers, setMatchers ) { + var bySet = setMatchers.length > 0, + byElement = elementMatchers.length > 0, + superMatcher = function( seed, context, xml, results, outermost ) { + var elem, j, matcher, + matchedCount = 0, + i = "0", + unmatched = seed && [], + setMatched = [], + contextBackup = outermostContext, + // We must always have either seed elements or outermost context + elems = seed || byElement && Expr.find["TAG"]( "*", outermost ), + // Use integer dirruns iff this is the outermost matcher + dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1), + len = elems.length; + + if ( outermost ) { + outermostContext = context === document || context || outermost; + } + + // Add elements passing elementMatchers directly to results + // Support: IE<9, Safari + // Tolerate NodeList properties (IE: "length"; Safari: ) matching elements by id + for ( ; i !== len && (elem = elems[i]) != null; i++ ) { + if ( byElement && elem ) { + j = 0; + if ( !context && elem.ownerDocument !== document ) { + setDocument( elem ); + xml = !documentIsHTML; + } + while ( (matcher = elementMatchers[j++]) ) { + if ( matcher( elem, context || document, xml) ) { + results.push( elem ); + break; + } + } + if ( outermost ) { + dirruns = dirrunsUnique; + } + } + + // Track unmatched elements for set filters + if ( bySet ) { + // They will have gone through all possible matchers + if ( (elem = !matcher && elem) ) { + matchedCount--; + } + + // Lengthen the array for every element, matched or not + if ( seed ) { + unmatched.push( elem ); + } + } + } + + // `i` is now the count of elements visited above, and adding it to `matchedCount` + // makes the latter nonnegative. + matchedCount += i; + + // Apply set filters to unmatched elements + // NOTE: This can be skipped if there are no unmatched elements (i.e., `matchedCount` + // equals `i`), unless we didn't visit _any_ elements in the above loop because we have + // no element matchers and no seed. + // Incrementing an initially-string "0" `i` allows `i` to remain a string only in that + // case, which will result in a "00" `matchedCount` that differs from `i` but is also + // numerically zero. + if ( bySet && i !== matchedCount ) { + j = 0; + while ( (matcher = setMatchers[j++]) ) { + matcher( unmatched, setMatched, context, xml ); + } + + if ( seed ) { + // Reintegrate element matches to eliminate the need for sorting + if ( matchedCount > 0 ) { + while ( i-- ) { + if ( !(unmatched[i] || setMatched[i]) ) { + setMatched[i] = pop.call( results ); + } + } + } + + // Discard index placeholder values to get only actual matches + setMatched = condense( setMatched ); + } + + // Add matches to results + push.apply( results, setMatched ); + + // Seedless set matches succeeding multiple successful matchers stipulate sorting + if ( outermost && !seed && setMatched.length > 0 && + ( matchedCount + setMatchers.length ) > 1 ) { + + Sizzle.uniqueSort( results ); + } + } + + // Override manipulation of globals by nested matchers + if ( outermost ) { + dirruns = dirrunsUnique; + outermostContext = contextBackup; + } + + return unmatched; + }; + + return bySet ? + markFunction( superMatcher ) : + superMatcher; +} + +compile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) { + var i, + setMatchers = [], + elementMatchers = [], + cached = compilerCache[ selector + " " ]; + + if ( !cached ) { + // Generate a function of recursive functions that can be used to check each element + if ( !match ) { + match = tokenize( selector ); + } + i = match.length; + while ( i-- ) { + cached = matcherFromTokens( match[i] ); + if ( cached[ expando ] ) { + setMatchers.push( cached ); + } else { + elementMatchers.push( cached ); + } + } + + // Cache the compiled function + cached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) ); + + // Save selector and tokenization + cached.selector = selector; + } + return cached; +}; + +/** + * A low-level selection function that works with Sizzle's compiled + * selector functions + * @param {String|Function} selector A selector or a pre-compiled + * selector function built with Sizzle.compile + * @param {Element} context + * @param {Array} [results] + * @param {Array} [seed] A set of elements to match against + */ +select = Sizzle.select = function( selector, context, results, seed ) { + var i, tokens, token, type, find, + compiled = typeof selector === "function" && selector, + match = !seed && tokenize( (selector = compiled.selector || selector) ); + + results = results || []; + + // Try to minimize operations if there is only one selector in the list and no seed + // (the latter of which guarantees us context) + if ( match.length === 1 ) { + + // Reduce context if the leading compound selector is an ID + tokens = match[0] = match[0].slice( 0 ); + if ( tokens.length > 2 && (token = tokens[0]).type === "ID" && + context.nodeType === 9 && documentIsHTML && Expr.relative[ tokens[1].type ] ) { + + context = ( Expr.find["ID"]( token.matches[0].replace(runescape, funescape), context ) || [] )[0]; + if ( !context ) { + return results; + + // Precompiled matchers will still verify ancestry, so step up a level + } else if ( compiled ) { + context = context.parentNode; + } + + selector = selector.slice( tokens.shift().value.length ); + } + + // Fetch a seed set for right-to-left matching + i = matchExpr["needsContext"].test( selector ) ? 0 : tokens.length; + while ( i-- ) { + token = tokens[i]; + + // Abort if we hit a combinator + if ( Expr.relative[ (type = token.type) ] ) { + break; + } + if ( (find = Expr.find[ type ]) ) { + // Search, expanding context for leading sibling combinators + if ( (seed = find( + token.matches[0].replace( runescape, funescape ), + rsibling.test( tokens[0].type ) && testContext( context.parentNode ) || context + )) ) { + + // If seed is empty or no tokens remain, we can return early + tokens.splice( i, 1 ); + selector = seed.length && toSelector( tokens ); + if ( !selector ) { + push.apply( results, seed ); + return results; + } + + break; + } + } + } + } + + // Compile and execute a filtering function if one is not provided + // Provide `match` to avoid retokenization if we modified the selector above + ( compiled || compile( selector, match ) )( + seed, + context, + !documentIsHTML, + results, + !context || rsibling.test( selector ) && testContext( context.parentNode ) || context + ); + return results; +}; + +// One-time assignments + +// Sort stability +support.sortStable = expando.split("").sort( sortOrder ).join("") === expando; + +// Support: Chrome 14-35+ +// Always assume duplicates if they aren't passed to the comparison function +support.detectDuplicates = !!hasDuplicate; + +// Initialize against the default document +setDocument(); + +// Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27) +// Detached nodes confoundingly follow *each other* +support.sortDetached = assert(function( el ) { + // Should return 1, but returns 4 (following) + return el.compareDocumentPosition( document.createElement("fieldset") ) & 1; +}); + +// Support: IE<8 +// Prevent attribute/property "interpolation" +// https://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx +if ( !assert(function( el ) { + el.innerHTML = ""; + return el.firstChild.getAttribute("href") === "#" ; +}) ) { + addHandle( "type|href|height|width", function( elem, name, isXML ) { + if ( !isXML ) { + return elem.getAttribute( name, name.toLowerCase() === "type" ? 1 : 2 ); + } + }); +} + +// Support: IE<9 +// Use defaultValue in place of getAttribute("value") +if ( !support.attributes || !assert(function( el ) { + el.innerHTML = ""; + el.firstChild.setAttribute( "value", "" ); + return el.firstChild.getAttribute( "value" ) === ""; +}) ) { + addHandle( "value", function( elem, name, isXML ) { + if ( !isXML && elem.nodeName.toLowerCase() === "input" ) { + return elem.defaultValue; + } + }); +} + +// Support: IE<9 +// Use getAttributeNode to fetch booleans when getAttribute lies +if ( !assert(function( el ) { + return el.getAttribute("disabled") == null; +}) ) { + addHandle( booleans, function( elem, name, isXML ) { + var val; + if ( !isXML ) { + return elem[ name ] === true ? name.toLowerCase() : + (val = elem.getAttributeNode( name )) && val.specified ? + val.value : + null; + } + }); +} + +return Sizzle; + +})( window ); + + + +jQuery.find = Sizzle; +jQuery.expr = Sizzle.selectors; + +// Deprecated +jQuery.expr[ ":" ] = jQuery.expr.pseudos; +jQuery.uniqueSort = jQuery.unique = Sizzle.uniqueSort; +jQuery.text = Sizzle.getText; +jQuery.isXMLDoc = Sizzle.isXML; +jQuery.contains = Sizzle.contains; +jQuery.escapeSelector = Sizzle.escape; + + + + +var dir = function( elem, dir, until ) { + var matched = [], + truncate = until !== undefined; + + while ( ( elem = elem[ dir ] ) && elem.nodeType !== 9 ) { + if ( elem.nodeType === 1 ) { + if ( truncate && jQuery( elem ).is( until ) ) { + break; + } + matched.push( elem ); + } + } + return matched; +}; + + +var siblings = function( n, elem ) { + var matched = []; + + for ( ; n; n = n.nextSibling ) { + if ( n.nodeType === 1 && n !== elem ) { + matched.push( n ); + } + } + + return matched; +}; + + +var rneedsContext = jQuery.expr.match.needsContext; + + + +function nodeName( elem, name ) { + + return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase(); + +}; +var rsingleTag = ( /^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i ); + + + +// Implement the identical functionality for filter and not +function winnow( elements, qualifier, not ) { + if ( isFunction( qualifier ) ) { + return jQuery.grep( elements, function( elem, i ) { + return !!qualifier.call( elem, i, elem ) !== not; + } ); + } + + // Single element + if ( qualifier.nodeType ) { + return jQuery.grep( elements, function( elem ) { + return ( elem === qualifier ) !== not; + } ); + } + + // Arraylike of elements (jQuery, arguments, Array) + if ( typeof qualifier !== "string" ) { + return jQuery.grep( elements, function( elem ) { + return ( indexOf.call( qualifier, elem ) > -1 ) !== not; + } ); + } + + // Filtered directly for both simple and complex selectors + return jQuery.filter( qualifier, elements, not ); +} + +jQuery.filter = function( expr, elems, not ) { + var elem = elems[ 0 ]; + + if ( not ) { + expr = ":not(" + expr + ")"; + } + + if ( elems.length === 1 && elem.nodeType === 1 ) { + return jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : []; + } + + return jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) { + return elem.nodeType === 1; + } ) ); +}; + +jQuery.fn.extend( { + find: function( selector ) { + var i, ret, + len = this.length, + self = this; + + if ( typeof selector !== "string" ) { + return this.pushStack( jQuery( selector ).filter( function() { + for ( i = 0; i < len; i++ ) { + if ( jQuery.contains( self[ i ], this ) ) { + return true; + } + } + } ) ); + } + + ret = this.pushStack( [] ); + + for ( i = 0; i < len; i++ ) { + jQuery.find( selector, self[ i ], ret ); + } + + return len > 1 ? jQuery.uniqueSort( ret ) : ret; + }, + filter: function( selector ) { + return this.pushStack( winnow( this, selector || [], false ) ); + }, + not: function( selector ) { + return this.pushStack( winnow( this, selector || [], true ) ); + }, + is: function( selector ) { + return !!winnow( + this, + + // If this is a positional/relative selector, check membership in the returned set + // so $("p:first").is("p:last") won't return true for a doc with two "p". + typeof selector === "string" && rneedsContext.test( selector ) ? + jQuery( selector ) : + selector || [], + false + ).length; + } +} ); + + +// Initialize a jQuery object + + +// A central reference to the root jQuery(document) +var rootjQuery, + + // A simple way to check for HTML strings + // Prioritize #id over to avoid XSS via location.hash (#9521) + // Strict HTML recognition (#11290: must start with <) + // Shortcut simple #id case for speed + rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/, + + init = jQuery.fn.init = function( selector, context, root ) { + var match, elem; + + // HANDLE: $(""), $(null), $(undefined), $(false) + if ( !selector ) { + return this; + } + + // Method init() accepts an alternate rootjQuery + // so migrate can support jQuery.sub (gh-2101) + root = root || rootjQuery; + + // Handle HTML strings + if ( typeof selector === "string" ) { + if ( selector[ 0 ] === "<" && + selector[ selector.length - 1 ] === ">" && + selector.length >= 3 ) { + + // Assume that strings that start and end with <> are HTML and skip the regex check + match = [ null, selector, null ]; + + } else { + match = rquickExpr.exec( selector ); + } + + // Match html or make sure no context is specified for #id + if ( match && ( match[ 1 ] || !context ) ) { + + // HANDLE: $(html) -> $(array) + if ( match[ 1 ] ) { + context = context instanceof jQuery ? context[ 0 ] : context; + + // Option to run scripts is true for back-compat + // Intentionally let the error be thrown if parseHTML is not present + jQuery.merge( this, jQuery.parseHTML( + match[ 1 ], + context && context.nodeType ? context.ownerDocument || context : document, + true + ) ); + + // HANDLE: $(html, props) + if ( rsingleTag.test( match[ 1 ] ) && jQuery.isPlainObject( context ) ) { + for ( match in context ) { + + // Properties of context are called as methods if possible + if ( isFunction( this[ match ] ) ) { + this[ match ]( context[ match ] ); + + // ...and otherwise set as attributes + } else { + this.attr( match, context[ match ] ); + } + } + } + + return this; + + // HANDLE: $(#id) + } else { + elem = document.getElementById( match[ 2 ] ); + + if ( elem ) { + + // Inject the element directly into the jQuery object + this[ 0 ] = elem; + this.length = 1; + } + return this; + } + + // HANDLE: $(expr, $(...)) + } else if ( !context || context.jquery ) { + return ( context || root ).find( selector ); + + // HANDLE: $(expr, context) + // (which is just equivalent to: $(context).find(expr) + } else { + return this.constructor( context ).find( selector ); + } + + // HANDLE: $(DOMElement) + } else if ( selector.nodeType ) { + this[ 0 ] = selector; + this.length = 1; + return this; + + // HANDLE: $(function) + // Shortcut for document ready + } else if ( isFunction( selector ) ) { + return root.ready !== undefined ? + root.ready( selector ) : + + // Execute immediately if ready is not present + selector( jQuery ); + } + + return jQuery.makeArray( selector, this ); + }; + +// Give the init function the jQuery prototype for later instantiation +init.prototype = jQuery.fn; + +// Initialize central reference +rootjQuery = jQuery( document ); + + +var rparentsprev = /^(?:parents|prev(?:Until|All))/, + + // Methods guaranteed to produce a unique set when starting from a unique set + guaranteedUnique = { + children: true, + contents: true, + next: true, + prev: true + }; + +jQuery.fn.extend( { + has: function( target ) { + var targets = jQuery( target, this ), + l = targets.length; + + return this.filter( function() { + var i = 0; + for ( ; i < l; i++ ) { + if ( jQuery.contains( this, targets[ i ] ) ) { + return true; + } + } + } ); + }, + + closest: function( selectors, context ) { + var cur, + i = 0, + l = this.length, + matched = [], + targets = typeof selectors !== "string" && jQuery( selectors ); + + // Positional selectors never match, since there's no _selection_ context + if ( !rneedsContext.test( selectors ) ) { + for ( ; i < l; i++ ) { + for ( cur = this[ i ]; cur && cur !== context; cur = cur.parentNode ) { + + // Always skip document fragments + if ( cur.nodeType < 11 && ( targets ? + targets.index( cur ) > -1 : + + // Don't pass non-elements to Sizzle + cur.nodeType === 1 && + jQuery.find.matchesSelector( cur, selectors ) ) ) { + + matched.push( cur ); + break; + } + } + } + } + + return this.pushStack( matched.length > 1 ? jQuery.uniqueSort( matched ) : matched ); + }, + + // Determine the position of an element within the set + index: function( elem ) { + + // No argument, return index in parent + if ( !elem ) { + return ( this[ 0 ] && this[ 0 ].parentNode ) ? this.first().prevAll().length : -1; + } + + // Index in selector + if ( typeof elem === "string" ) { + return indexOf.call( jQuery( elem ), this[ 0 ] ); + } + + // Locate the position of the desired element + return indexOf.call( this, + + // If it receives a jQuery object, the first element is used + elem.jquery ? elem[ 0 ] : elem + ); + }, + + add: function( selector, context ) { + return this.pushStack( + jQuery.uniqueSort( + jQuery.merge( this.get(), jQuery( selector, context ) ) + ) + ); + }, + + addBack: function( selector ) { + return this.add( selector == null ? + this.prevObject : this.prevObject.filter( selector ) + ); + } +} ); + +function sibling( cur, dir ) { + while ( ( cur = cur[ dir ] ) && cur.nodeType !== 1 ) {} + return cur; +} + +jQuery.each( { + parent: function( elem ) { + var parent = elem.parentNode; + return parent && parent.nodeType !== 11 ? parent : null; + }, + parents: function( elem ) { + return dir( elem, "parentNode" ); + }, + parentsUntil: function( elem, i, until ) { + return dir( elem, "parentNode", until ); + }, + next: function( elem ) { + return sibling( elem, "nextSibling" ); + }, + prev: function( elem ) { + return sibling( elem, "previousSibling" ); + }, + nextAll: function( elem ) { + return dir( elem, "nextSibling" ); + }, + prevAll: function( elem ) { + return dir( elem, "previousSibling" ); + }, + nextUntil: function( elem, i, until ) { + return dir( elem, "nextSibling", until ); + }, + prevUntil: function( elem, i, until ) { + return dir( elem, "previousSibling", until ); + }, + siblings: function( elem ) { + return siblings( ( elem.parentNode || {} ).firstChild, elem ); + }, + children: function( elem ) { + return siblings( elem.firstChild ); + }, + contents: function( elem ) { + if ( typeof elem.contentDocument !== "undefined" ) { + return elem.contentDocument; + } + + // Support: IE 9 - 11 only, iOS 7 only, Android Browser <=4.3 only + // Treat the template element as a regular one in browsers that + // don't support it. + if ( nodeName( elem, "template" ) ) { + elem = elem.content || elem; + } + + return jQuery.merge( [], elem.childNodes ); + } +}, function( name, fn ) { + jQuery.fn[ name ] = function( until, selector ) { + var matched = jQuery.map( this, fn, until ); + + if ( name.slice( -5 ) !== "Until" ) { + selector = until; + } + + if ( selector && typeof selector === "string" ) { + matched = jQuery.filter( selector, matched ); + } + + if ( this.length > 1 ) { + + // Remove duplicates + if ( !guaranteedUnique[ name ] ) { + jQuery.uniqueSort( matched ); + } + + // Reverse order for parents* and prev-derivatives + if ( rparentsprev.test( name ) ) { + matched.reverse(); + } + } + + return this.pushStack( matched ); + }; +} ); +var rnothtmlwhite = ( /[^\x20\t\r\n\f]+/g ); + + + +// Convert String-formatted options into Object-formatted ones +function createOptions( options ) { + var object = {}; + jQuery.each( options.match( rnothtmlwhite ) || [], function( _, flag ) { + object[ flag ] = true; + } ); + return object; +} + +/* + * Create a callback list using the following parameters: + * + * options: an optional list of space-separated options that will change how + * the callback list behaves or a more traditional option object + * + * By default a callback list will act like an event callback list and can be + * "fired" multiple times. + * + * Possible options: + * + * once: will ensure the callback list can only be fired once (like a Deferred) + * + * memory: will keep track of previous values and will call any callback added + * after the list has been fired right away with the latest "memorized" + * values (like a Deferred) + * + * unique: will ensure a callback can only be added once (no duplicate in the list) + * + * stopOnFalse: interrupt callings when a callback returns false + * + */ +jQuery.Callbacks = function( options ) { + + // Convert options from String-formatted to Object-formatted if needed + // (we check in cache first) + options = typeof options === "string" ? + createOptions( options ) : + jQuery.extend( {}, options ); + + var // Flag to know if list is currently firing + firing, + + // Last fire value for non-forgettable lists + memory, + + // Flag to know if list was already fired + fired, + + // Flag to prevent firing + locked, + + // Actual callback list + list = [], + + // Queue of execution data for repeatable lists + queue = [], + + // Index of currently firing callback (modified by add/remove as needed) + firingIndex = -1, + + // Fire callbacks + fire = function() { + + // Enforce single-firing + locked = locked || options.once; + + // Execute callbacks for all pending executions, + // respecting firingIndex overrides and runtime changes + fired = firing = true; + for ( ; queue.length; firingIndex = -1 ) { + memory = queue.shift(); + while ( ++firingIndex < list.length ) { + + // Run callback and check for early termination + if ( list[ firingIndex ].apply( memory[ 0 ], memory[ 1 ] ) === false && + options.stopOnFalse ) { + + // Jump to end and forget the data so .add doesn't re-fire + firingIndex = list.length; + memory = false; + } + } + } + + // Forget the data if we're done with it + if ( !options.memory ) { + memory = false; + } + + firing = false; + + // Clean up if we're done firing for good + if ( locked ) { + + // Keep an empty list if we have data for future add calls + if ( memory ) { + list = []; + + // Otherwise, this object is spent + } else { + list = ""; + } + } + }, + + // Actual Callbacks object + self = { + + // Add a callback or a collection of callbacks to the list + add: function() { + if ( list ) { + + // If we have memory from a past run, we should fire after adding + if ( memory && !firing ) { + firingIndex = list.length - 1; + queue.push( memory ); + } + + ( function add( args ) { + jQuery.each( args, function( _, arg ) { + if ( isFunction( arg ) ) { + if ( !options.unique || !self.has( arg ) ) { + list.push( arg ); + } + } else if ( arg && arg.length && toType( arg ) !== "string" ) { + + // Inspect recursively + add( arg ); + } + } ); + } )( arguments ); + + if ( memory && !firing ) { + fire(); + } + } + return this; + }, + + // Remove a callback from the list + remove: function() { + jQuery.each( arguments, function( _, arg ) { + var index; + while ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) { + list.splice( index, 1 ); + + // Handle firing indexes + if ( index <= firingIndex ) { + firingIndex--; + } + } + } ); + return this; + }, + + // Check if a given callback is in the list. + // If no argument is given, return whether or not list has callbacks attached. + has: function( fn ) { + return fn ? + jQuery.inArray( fn, list ) > -1 : + list.length > 0; + }, + + // Remove all callbacks from the list + empty: function() { + if ( list ) { + list = []; + } + return this; + }, + + // Disable .fire and .add + // Abort any current/pending executions + // Clear all callbacks and values + disable: function() { + locked = queue = []; + list = memory = ""; + return this; + }, + disabled: function() { + return !list; + }, + + // Disable .fire + // Also disable .add unless we have memory (since it would have no effect) + // Abort any pending executions + lock: function() { + locked = queue = []; + if ( !memory && !firing ) { + list = memory = ""; + } + return this; + }, + locked: function() { + return !!locked; + }, + + // Call all callbacks with the given context and arguments + fireWith: function( context, args ) { + if ( !locked ) { + args = args || []; + args = [ context, args.slice ? args.slice() : args ]; + queue.push( args ); + if ( !firing ) { + fire(); + } + } + return this; + }, + + // Call all the callbacks with the given arguments + fire: function() { + self.fireWith( this, arguments ); + return this; + }, + + // To know if the callbacks have already been called at least once + fired: function() { + return !!fired; + } + }; + + return self; +}; + + +function Identity( v ) { + return v; +} +function Thrower( ex ) { + throw ex; +} + +function adoptValue( value, resolve, reject, noValue ) { + var method; + + try { + + // Check for promise aspect first to privilege synchronous behavior + if ( value && isFunction( ( method = value.promise ) ) ) { + method.call( value ).done( resolve ).fail( reject ); + + // Other thenables + } else if ( value && isFunction( ( method = value.then ) ) ) { + method.call( value, resolve, reject ); + + // Other non-thenables + } else { + + // Control `resolve` arguments by letting Array#slice cast boolean `noValue` to integer: + // * false: [ value ].slice( 0 ) => resolve( value ) + // * true: [ value ].slice( 1 ) => resolve() + resolve.apply( undefined, [ value ].slice( noValue ) ); + } + + // For Promises/A+, convert exceptions into rejections + // Since jQuery.when doesn't unwrap thenables, we can skip the extra checks appearing in + // Deferred#then to conditionally suppress rejection. + } catch ( value ) { + + // Support: Android 4.0 only + // Strict mode functions invoked without .call/.apply get global-object context + reject.apply( undefined, [ value ] ); + } +} + +jQuery.extend( { + + Deferred: function( func ) { + var tuples = [ + + // action, add listener, callbacks, + // ... .then handlers, argument index, [final state] + [ "notify", "progress", jQuery.Callbacks( "memory" ), + jQuery.Callbacks( "memory" ), 2 ], + [ "resolve", "done", jQuery.Callbacks( "once memory" ), + jQuery.Callbacks( "once memory" ), 0, "resolved" ], + [ "reject", "fail", jQuery.Callbacks( "once memory" ), + jQuery.Callbacks( "once memory" ), 1, "rejected" ] + ], + state = "pending", + promise = { + state: function() { + return state; + }, + always: function() { + deferred.done( arguments ).fail( arguments ); + return this; + }, + "catch": function( fn ) { + return promise.then( null, fn ); + }, + + // Keep pipe for back-compat + pipe: function( /* fnDone, fnFail, fnProgress */ ) { + var fns = arguments; + + return jQuery.Deferred( function( newDefer ) { + jQuery.each( tuples, function( i, tuple ) { + + // Map tuples (progress, done, fail) to arguments (done, fail, progress) + var fn = isFunction( fns[ tuple[ 4 ] ] ) && fns[ tuple[ 4 ] ]; + + // deferred.progress(function() { bind to newDefer or newDefer.notify }) + // deferred.done(function() { bind to newDefer or newDefer.resolve }) + // deferred.fail(function() { bind to newDefer or newDefer.reject }) + deferred[ tuple[ 1 ] ]( function() { + var returned = fn && fn.apply( this, arguments ); + if ( returned && isFunction( returned.promise ) ) { + returned.promise() + .progress( newDefer.notify ) + .done( newDefer.resolve ) + .fail( newDefer.reject ); + } else { + newDefer[ tuple[ 0 ] + "With" ]( + this, + fn ? [ returned ] : arguments + ); + } + } ); + } ); + fns = null; + } ).promise(); + }, + then: function( onFulfilled, onRejected, onProgress ) { + var maxDepth = 0; + function resolve( depth, deferred, handler, special ) { + return function() { + var that = this, + args = arguments, + mightThrow = function() { + var returned, then; + + // Support: Promises/A+ section 2.3.3.3.3 + // https://promisesaplus.com/#point-59 + // Ignore double-resolution attempts + if ( depth < maxDepth ) { + return; + } + + returned = handler.apply( that, args ); + + // Support: Promises/A+ section 2.3.1 + // https://promisesaplus.com/#point-48 + if ( returned === deferred.promise() ) { + throw new TypeError( "Thenable self-resolution" ); + } + + // Support: Promises/A+ sections 2.3.3.1, 3.5 + // https://promisesaplus.com/#point-54 + // https://promisesaplus.com/#point-75 + // Retrieve `then` only once + then = returned && + + // Support: Promises/A+ section 2.3.4 + // https://promisesaplus.com/#point-64 + // Only check objects and functions for thenability + ( typeof returned === "object" || + typeof returned === "function" ) && + returned.then; + + // Handle a returned thenable + if ( isFunction( then ) ) { + + // Special processors (notify) just wait for resolution + if ( special ) { + then.call( + returned, + resolve( maxDepth, deferred, Identity, special ), + resolve( maxDepth, deferred, Thrower, special ) + ); + + // Normal processors (resolve) also hook into progress + } else { + + // ...and disregard older resolution values + maxDepth++; + + then.call( + returned, + resolve( maxDepth, deferred, Identity, special ), + resolve( maxDepth, deferred, Thrower, special ), + resolve( maxDepth, deferred, Identity, + deferred.notifyWith ) + ); + } + + // Handle all other returned values + } else { + + // Only substitute handlers pass on context + // and multiple values (non-spec behavior) + if ( handler !== Identity ) { + that = undefined; + args = [ returned ]; + } + + // Process the value(s) + // Default process is resolve + ( special || deferred.resolveWith )( that, args ); + } + }, + + // Only normal processors (resolve) catch and reject exceptions + process = special ? + mightThrow : + function() { + try { + mightThrow(); + } catch ( e ) { + + if ( jQuery.Deferred.exceptionHook ) { + jQuery.Deferred.exceptionHook( e, + process.stackTrace ); + } + + // Support: Promises/A+ section 2.3.3.3.4.1 + // https://promisesaplus.com/#point-61 + // Ignore post-resolution exceptions + if ( depth + 1 >= maxDepth ) { + + // Only substitute handlers pass on context + // and multiple values (non-spec behavior) + if ( handler !== Thrower ) { + that = undefined; + args = [ e ]; + } + + deferred.rejectWith( that, args ); + } + } + }; + + // Support: Promises/A+ section 2.3.3.3.1 + // https://promisesaplus.com/#point-57 + // Re-resolve promises immediately to dodge false rejection from + // subsequent errors + if ( depth ) { + process(); + } else { + + // Call an optional hook to record the stack, in case of exception + // since it's otherwise lost when execution goes async + if ( jQuery.Deferred.getStackHook ) { + process.stackTrace = jQuery.Deferred.getStackHook(); + } + window.setTimeout( process ); + } + }; + } + + return jQuery.Deferred( function( newDefer ) { + + // progress_handlers.add( ... ) + tuples[ 0 ][ 3 ].add( + resolve( + 0, + newDefer, + isFunction( onProgress ) ? + onProgress : + Identity, + newDefer.notifyWith + ) + ); + + // fulfilled_handlers.add( ... ) + tuples[ 1 ][ 3 ].add( + resolve( + 0, + newDefer, + isFunction( onFulfilled ) ? + onFulfilled : + Identity + ) + ); + + // rejected_handlers.add( ... ) + tuples[ 2 ][ 3 ].add( + resolve( + 0, + newDefer, + isFunction( onRejected ) ? + onRejected : + Thrower + ) + ); + } ).promise(); + }, + + // Get a promise for this deferred + // If obj is provided, the promise aspect is added to the object + promise: function( obj ) { + return obj != null ? jQuery.extend( obj, promise ) : promise; + } + }, + deferred = {}; + + // Add list-specific methods + jQuery.each( tuples, function( i, tuple ) { + var list = tuple[ 2 ], + stateString = tuple[ 5 ]; + + // promise.progress = list.add + // promise.done = list.add + // promise.fail = list.add + promise[ tuple[ 1 ] ] = list.add; + + // Handle state + if ( stateString ) { + list.add( + function() { + + // state = "resolved" (i.e., fulfilled) + // state = "rejected" + state = stateString; + }, + + // rejected_callbacks.disable + // fulfilled_callbacks.disable + tuples[ 3 - i ][ 2 ].disable, + + // rejected_handlers.disable + // fulfilled_handlers.disable + tuples[ 3 - i ][ 3 ].disable, + + // progress_callbacks.lock + tuples[ 0 ][ 2 ].lock, + + // progress_handlers.lock + tuples[ 0 ][ 3 ].lock + ); + } + + // progress_handlers.fire + // fulfilled_handlers.fire + // rejected_handlers.fire + list.add( tuple[ 3 ].fire ); + + // deferred.notify = function() { deferred.notifyWith(...) } + // deferred.resolve = function() { deferred.resolveWith(...) } + // deferred.reject = function() { deferred.rejectWith(...) } + deferred[ tuple[ 0 ] ] = function() { + deferred[ tuple[ 0 ] + "With" ]( this === deferred ? undefined : this, arguments ); + return this; + }; + + // deferred.notifyWith = list.fireWith + // deferred.resolveWith = list.fireWith + // deferred.rejectWith = list.fireWith + deferred[ tuple[ 0 ] + "With" ] = list.fireWith; + } ); + + // Make the deferred a promise + promise.promise( deferred ); + + // Call given func if any + if ( func ) { + func.call( deferred, deferred ); + } + + // All done! + return deferred; + }, + + // Deferred helper + when: function( singleValue ) { + var + + // count of uncompleted subordinates + remaining = arguments.length, + + // count of unprocessed arguments + i = remaining, + + // subordinate fulfillment data + resolveContexts = Array( i ), + resolveValues = slice.call( arguments ), + + // the master Deferred + master = jQuery.Deferred(), + + // subordinate callback factory + updateFunc = function( i ) { + return function( value ) { + resolveContexts[ i ] = this; + resolveValues[ i ] = arguments.length > 1 ? slice.call( arguments ) : value; + if ( !( --remaining ) ) { + master.resolveWith( resolveContexts, resolveValues ); + } + }; + }; + + // Single- and empty arguments are adopted like Promise.resolve + if ( remaining <= 1 ) { + adoptValue( singleValue, master.done( updateFunc( i ) ).resolve, master.reject, + !remaining ); + + // Use .then() to unwrap secondary thenables (cf. gh-3000) + if ( master.state() === "pending" || + isFunction( resolveValues[ i ] && resolveValues[ i ].then ) ) { + + return master.then(); + } + } + + // Multiple arguments are aggregated like Promise.all array elements + while ( i-- ) { + adoptValue( resolveValues[ i ], updateFunc( i ), master.reject ); + } + + return master.promise(); + } +} ); + + +// These usually indicate a programmer mistake during development, +// warn about them ASAP rather than swallowing them by default. +var rerrorNames = /^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/; + +jQuery.Deferred.exceptionHook = function( error, stack ) { + + // Support: IE 8 - 9 only + // Console exists when dev tools are open, which can happen at any time + if ( window.console && window.console.warn && error && rerrorNames.test( error.name ) ) { + window.console.warn( "jQuery.Deferred exception: " + error.message, error.stack, stack ); + } +}; + + + + +jQuery.readyException = function( error ) { + window.setTimeout( function() { + throw error; + } ); +}; + + + + +// The deferred used on DOM ready +var readyList = jQuery.Deferred(); + +jQuery.fn.ready = function( fn ) { + + readyList + .then( fn ) + + // Wrap jQuery.readyException in a function so that the lookup + // happens at the time of error handling instead of callback + // registration. + .catch( function( error ) { + jQuery.readyException( error ); + } ); + + return this; +}; + +jQuery.extend( { + + // Is the DOM ready to be used? Set to true once it occurs. + isReady: false, + + // A counter to track how many items to wait for before + // the ready event fires. See #6781 + readyWait: 1, + + // Handle when the DOM is ready + ready: function( wait ) { + + // Abort if there are pending holds or we're already ready + if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) { + return; + } + + // Remember that the DOM is ready + jQuery.isReady = true; + + // If a normal DOM Ready event fired, decrement, and wait if need be + if ( wait !== true && --jQuery.readyWait > 0 ) { + return; + } + + // If there are functions bound, to execute + readyList.resolveWith( document, [ jQuery ] ); + } +} ); + +jQuery.ready.then = readyList.then; + +// The ready event handler and self cleanup method +function completed() { + document.removeEventListener( "DOMContentLoaded", completed ); + window.removeEventListener( "load", completed ); + jQuery.ready(); +} + +// Catch cases where $(document).ready() is called +// after the browser event has already occurred. +// Support: IE <=9 - 10 only +// Older IE sometimes signals "interactive" too soon +if ( document.readyState === "complete" || + ( document.readyState !== "loading" && !document.documentElement.doScroll ) ) { + + // Handle it asynchronously to allow scripts the opportunity to delay ready + window.setTimeout( jQuery.ready ); + +} else { + + // Use the handy event callback + document.addEventListener( "DOMContentLoaded", completed ); + + // A fallback to window.onload, that will always work + window.addEventListener( "load", completed ); +} + + + + +// Multifunctional method to get and set values of a collection +// The value/s can optionally be executed if it's a function +var access = function( elems, fn, key, value, chainable, emptyGet, raw ) { + var i = 0, + len = elems.length, + bulk = key == null; + + // Sets many values + if ( toType( key ) === "object" ) { + chainable = true; + for ( i in key ) { + access( elems, fn, i, key[ i ], true, emptyGet, raw ); + } + + // Sets one value + } else if ( value !== undefined ) { + chainable = true; + + if ( !isFunction( value ) ) { + raw = true; + } + + if ( bulk ) { + + // Bulk operations run against the entire set + if ( raw ) { + fn.call( elems, value ); + fn = null; + + // ...except when executing function values + } else { + bulk = fn; + fn = function( elem, key, value ) { + return bulk.call( jQuery( elem ), value ); + }; + } + } + + if ( fn ) { + for ( ; i < len; i++ ) { + fn( + elems[ i ], key, raw ? + value : + value.call( elems[ i ], i, fn( elems[ i ], key ) ) + ); + } + } + } + + if ( chainable ) { + return elems; + } + + // Gets + if ( bulk ) { + return fn.call( elems ); + } + + return len ? fn( elems[ 0 ], key ) : emptyGet; +}; + + +// Matches dashed string for camelizing +var rmsPrefix = /^-ms-/, + rdashAlpha = /-([a-z])/g; + +// Used by camelCase as callback to replace() +function fcamelCase( all, letter ) { + return letter.toUpperCase(); +} + +// Convert dashed to camelCase; used by the css and data modules +// Support: IE <=9 - 11, Edge 12 - 15 +// Microsoft forgot to hump their vendor prefix (#9572) +function camelCase( string ) { + return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase ); +} +var acceptData = function( owner ) { + + // Accepts only: + // - Node + // - Node.ELEMENT_NODE + // - Node.DOCUMENT_NODE + // - Object + // - Any + return owner.nodeType === 1 || owner.nodeType === 9 || !( +owner.nodeType ); +}; + + + + +function Data() { + this.expando = jQuery.expando + Data.uid++; +} + +Data.uid = 1; + +Data.prototype = { + + cache: function( owner ) { + + // Check if the owner object already has a cache + var value = owner[ this.expando ]; + + // If not, create one + if ( !value ) { + value = {}; + + // We can accept data for non-element nodes in modern browsers, + // but we should not, see #8335. + // Always return an empty object. + if ( acceptData( owner ) ) { + + // If it is a node unlikely to be stringify-ed or looped over + // use plain assignment + if ( owner.nodeType ) { + owner[ this.expando ] = value; + + // Otherwise secure it in a non-enumerable property + // configurable must be true to allow the property to be + // deleted when data is removed + } else { + Object.defineProperty( owner, this.expando, { + value: value, + configurable: true + } ); + } + } + } + + return value; + }, + set: function( owner, data, value ) { + var prop, + cache = this.cache( owner ); + + // Handle: [ owner, key, value ] args + // Always use camelCase key (gh-2257) + if ( typeof data === "string" ) { + cache[ camelCase( data ) ] = value; + + // Handle: [ owner, { properties } ] args + } else { + + // Copy the properties one-by-one to the cache object + for ( prop in data ) { + cache[ camelCase( prop ) ] = data[ prop ]; + } + } + return cache; + }, + get: function( owner, key ) { + return key === undefined ? + this.cache( owner ) : + + // Always use camelCase key (gh-2257) + owner[ this.expando ] && owner[ this.expando ][ camelCase( key ) ]; + }, + access: function( owner, key, value ) { + + // In cases where either: + // + // 1. No key was specified + // 2. A string key was specified, but no value provided + // + // Take the "read" path and allow the get method to determine + // which value to return, respectively either: + // + // 1. The entire cache object + // 2. The data stored at the key + // + if ( key === undefined || + ( ( key && typeof key === "string" ) && value === undefined ) ) { + + return this.get( owner, key ); + } + + // When the key is not a string, or both a key and value + // are specified, set or extend (existing objects) with either: + // + // 1. An object of properties + // 2. A key and value + // + this.set( owner, key, value ); + + // Since the "set" path can have two possible entry points + // return the expected data based on which path was taken[*] + return value !== undefined ? value : key; + }, + remove: function( owner, key ) { + var i, + cache = owner[ this.expando ]; + + if ( cache === undefined ) { + return; + } + + if ( key !== undefined ) { + + // Support array or space separated string of keys + if ( Array.isArray( key ) ) { + + // If key is an array of keys... + // We always set camelCase keys, so remove that. + key = key.map( camelCase ); + } else { + key = camelCase( key ); + + // If a key with the spaces exists, use it. + // Otherwise, create an array by matching non-whitespace + key = key in cache ? + [ key ] : + ( key.match( rnothtmlwhite ) || [] ); + } + + i = key.length; + + while ( i-- ) { + delete cache[ key[ i ] ]; + } + } + + // Remove the expando if there's no more data + if ( key === undefined || jQuery.isEmptyObject( cache ) ) { + + // Support: Chrome <=35 - 45 + // Webkit & Blink performance suffers when deleting properties + // from DOM nodes, so set to undefined instead + // https://bugs.chromium.org/p/chromium/issues/detail?id=378607 (bug restricted) + if ( owner.nodeType ) { + owner[ this.expando ] = undefined; + } else { + delete owner[ this.expando ]; + } + } + }, + hasData: function( owner ) { + var cache = owner[ this.expando ]; + return cache !== undefined && !jQuery.isEmptyObject( cache ); + } +}; +var dataPriv = new Data(); + +var dataUser = new Data(); + + + +// Implementation Summary +// +// 1. Enforce API surface and semantic compatibility with 1.9.x branch +// 2. Improve the module's maintainability by reducing the storage +// paths to a single mechanism. +// 3. Use the same single mechanism to support "private" and "user" data. +// 4. _Never_ expose "private" data to user code (TODO: Drop _data, _removeData) +// 5. Avoid exposing implementation details on user objects (eg. expando properties) +// 6. Provide a clear path for implementation upgrade to WeakMap in 2014 + +var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/, + rmultiDash = /[A-Z]/g; + +function getData( data ) { + if ( data === "true" ) { + return true; + } + + if ( data === "false" ) { + return false; + } + + if ( data === "null" ) { + return null; + } + + // Only convert to a number if it doesn't change the string + if ( data === +data + "" ) { + return +data; + } + + if ( rbrace.test( data ) ) { + return JSON.parse( data ); + } + + return data; +} + +function dataAttr( elem, key, data ) { + var name; + + // If nothing was found internally, try to fetch any + // data from the HTML5 data-* attribute + if ( data === undefined && elem.nodeType === 1 ) { + name = "data-" + key.replace( rmultiDash, "-$&" ).toLowerCase(); + data = elem.getAttribute( name ); + + if ( typeof data === "string" ) { + try { + data = getData( data ); + } catch ( e ) {} + + // Make sure we set the data so it isn't changed later + dataUser.set( elem, key, data ); + } else { + data = undefined; + } + } + return data; +} + +jQuery.extend( { + hasData: function( elem ) { + return dataUser.hasData( elem ) || dataPriv.hasData( elem ); + }, + + data: function( elem, name, data ) { + return dataUser.access( elem, name, data ); + }, + + removeData: function( elem, name ) { + dataUser.remove( elem, name ); + }, + + // TODO: Now that all calls to _data and _removeData have been replaced + // with direct calls to dataPriv methods, these can be deprecated. + _data: function( elem, name, data ) { + return dataPriv.access( elem, name, data ); + }, + + _removeData: function( elem, name ) { + dataPriv.remove( elem, name ); + } +} ); + +jQuery.fn.extend( { + data: function( key, value ) { + var i, name, data, + elem = this[ 0 ], + attrs = elem && elem.attributes; + + // Gets all values + if ( key === undefined ) { + if ( this.length ) { + data = dataUser.get( elem ); + + if ( elem.nodeType === 1 && !dataPriv.get( elem, "hasDataAttrs" ) ) { + i = attrs.length; + while ( i-- ) { + + // Support: IE 11 only + // The attrs elements can be null (#14894) + if ( attrs[ i ] ) { + name = attrs[ i ].name; + if ( name.indexOf( "data-" ) === 0 ) { + name = camelCase( name.slice( 5 ) ); + dataAttr( elem, name, data[ name ] ); + } + } + } + dataPriv.set( elem, "hasDataAttrs", true ); + } + } + + return data; + } + + // Sets multiple values + if ( typeof key === "object" ) { + return this.each( function() { + dataUser.set( this, key ); + } ); + } + + return access( this, function( value ) { + var data; + + // The calling jQuery object (element matches) is not empty + // (and therefore has an element appears at this[ 0 ]) and the + // `value` parameter was not undefined. An empty jQuery object + // will result in `undefined` for elem = this[ 0 ] which will + // throw an exception if an attempt to read a data cache is made. + if ( elem && value === undefined ) { + + // Attempt to get data from the cache + // The key will always be camelCased in Data + data = dataUser.get( elem, key ); + if ( data !== undefined ) { + return data; + } + + // Attempt to "discover" the data in + // HTML5 custom data-* attrs + data = dataAttr( elem, key ); + if ( data !== undefined ) { + return data; + } + + // We tried really hard, but the data doesn't exist. + return; + } + + // Set the data... + this.each( function() { + + // We always store the camelCased key + dataUser.set( this, key, value ); + } ); + }, null, value, arguments.length > 1, null, true ); + }, + + removeData: function( key ) { + return this.each( function() { + dataUser.remove( this, key ); + } ); + } +} ); + + +jQuery.extend( { + queue: function( elem, type, data ) { + var queue; + + if ( elem ) { + type = ( type || "fx" ) + "queue"; + queue = dataPriv.get( elem, type ); + + // Speed up dequeue by getting out quickly if this is just a lookup + if ( data ) { + if ( !queue || Array.isArray( data ) ) { + queue = dataPriv.access( elem, type, jQuery.makeArray( data ) ); + } else { + queue.push( data ); + } + } + return queue || []; + } + }, + + dequeue: function( elem, type ) { + type = type || "fx"; + + var queue = jQuery.queue( elem, type ), + startLength = queue.length, + fn = queue.shift(), + hooks = jQuery._queueHooks( elem, type ), + next = function() { + jQuery.dequeue( elem, type ); + }; + + // If the fx queue is dequeued, always remove the progress sentinel + if ( fn === "inprogress" ) { + fn = queue.shift(); + startLength--; + } + + if ( fn ) { + + // Add a progress sentinel to prevent the fx queue from being + // automatically dequeued + if ( type === "fx" ) { + queue.unshift( "inprogress" ); + } + + // Clear up the last queue stop function + delete hooks.stop; + fn.call( elem, next, hooks ); + } + + if ( !startLength && hooks ) { + hooks.empty.fire(); + } + }, + + // Not public - generate a queueHooks object, or return the current one + _queueHooks: function( elem, type ) { + var key = type + "queueHooks"; + return dataPriv.get( elem, key ) || dataPriv.access( elem, key, { + empty: jQuery.Callbacks( "once memory" ).add( function() { + dataPriv.remove( elem, [ type + "queue", key ] ); + } ) + } ); + } +} ); + +jQuery.fn.extend( { + queue: function( type, data ) { + var setter = 2; + + if ( typeof type !== "string" ) { + data = type; + type = "fx"; + setter--; + } + + if ( arguments.length < setter ) { + return jQuery.queue( this[ 0 ], type ); + } + + return data === undefined ? + this : + this.each( function() { + var queue = jQuery.queue( this, type, data ); + + // Ensure a hooks for this queue + jQuery._queueHooks( this, type ); + + if ( type === "fx" && queue[ 0 ] !== "inprogress" ) { + jQuery.dequeue( this, type ); + } + } ); + }, + dequeue: function( type ) { + return this.each( function() { + jQuery.dequeue( this, type ); + } ); + }, + clearQueue: function( type ) { + return this.queue( type || "fx", [] ); + }, + + // Get a promise resolved when queues of a certain type + // are emptied (fx is the type by default) + promise: function( type, obj ) { + var tmp, + count = 1, + defer = jQuery.Deferred(), + elements = this, + i = this.length, + resolve = function() { + if ( !( --count ) ) { + defer.resolveWith( elements, [ elements ] ); + } + }; + + if ( typeof type !== "string" ) { + obj = type; + type = undefined; + } + type = type || "fx"; + + while ( i-- ) { + tmp = dataPriv.get( elements[ i ], type + "queueHooks" ); + if ( tmp && tmp.empty ) { + count++; + tmp.empty.add( resolve ); + } + } + resolve(); + return defer.promise( obj ); + } +} ); +var pnum = ( /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/ ).source; + +var rcssNum = new RegExp( "^(?:([+-])=|)(" + pnum + ")([a-z%]*)$", "i" ); + + +var cssExpand = [ "Top", "Right", "Bottom", "Left" ]; + +var documentElement = document.documentElement; + + + + var isAttached = function( elem ) { + return jQuery.contains( elem.ownerDocument, elem ); + }, + composed = { composed: true }; + + // Support: IE 9 - 11+, Edge 12 - 18+, iOS 10.0 - 10.2 only + // Check attachment across shadow DOM boundaries when possible (gh-3504) + // Support: iOS 10.0-10.2 only + // Early iOS 10 versions support `attachShadow` but not `getRootNode`, + // leading to errors. We need to check for `getRootNode`. + if ( documentElement.getRootNode ) { + isAttached = function( elem ) { + return jQuery.contains( elem.ownerDocument, elem ) || + elem.getRootNode( composed ) === elem.ownerDocument; + }; + } +var isHiddenWithinTree = function( elem, el ) { + + // isHiddenWithinTree might be called from jQuery#filter function; + // in that case, element will be second argument + elem = el || elem; + + // Inline style trumps all + return elem.style.display === "none" || + elem.style.display === "" && + + // Otherwise, check computed style + // Support: Firefox <=43 - 45 + // Disconnected elements can have computed display: none, so first confirm that elem is + // in the document. + isAttached( elem ) && + + jQuery.css( elem, "display" ) === "none"; + }; + +var swap = function( elem, options, callback, args ) { + var ret, name, + old = {}; + + // Remember the old values, and insert the new ones + for ( name in options ) { + old[ name ] = elem.style[ name ]; + elem.style[ name ] = options[ name ]; + } + + ret = callback.apply( elem, args || [] ); + + // Revert the old values + for ( name in options ) { + elem.style[ name ] = old[ name ]; + } + + return ret; +}; + + + + +function adjustCSS( elem, prop, valueParts, tween ) { + var adjusted, scale, + maxIterations = 20, + currentValue = tween ? + function() { + return tween.cur(); + } : + function() { + return jQuery.css( elem, prop, "" ); + }, + initial = currentValue(), + unit = valueParts && valueParts[ 3 ] || ( jQuery.cssNumber[ prop ] ? "" : "px" ), + + // Starting value computation is required for potential unit mismatches + initialInUnit = elem.nodeType && + ( jQuery.cssNumber[ prop ] || unit !== "px" && +initial ) && + rcssNum.exec( jQuery.css( elem, prop ) ); + + if ( initialInUnit && initialInUnit[ 3 ] !== unit ) { + + // Support: Firefox <=54 + // Halve the iteration target value to prevent interference from CSS upper bounds (gh-2144) + initial = initial / 2; + + // Trust units reported by jQuery.css + unit = unit || initialInUnit[ 3 ]; + + // Iteratively approximate from a nonzero starting point + initialInUnit = +initial || 1; + + while ( maxIterations-- ) { + + // Evaluate and update our best guess (doubling guesses that zero out). + // Finish if the scale equals or crosses 1 (making the old*new product non-positive). + jQuery.style( elem, prop, initialInUnit + unit ); + if ( ( 1 - scale ) * ( 1 - ( scale = currentValue() / initial || 0.5 ) ) <= 0 ) { + maxIterations = 0; + } + initialInUnit = initialInUnit / scale; + + } + + initialInUnit = initialInUnit * 2; + jQuery.style( elem, prop, initialInUnit + unit ); + + // Make sure we update the tween properties later on + valueParts = valueParts || []; + } + + if ( valueParts ) { + initialInUnit = +initialInUnit || +initial || 0; + + // Apply relative offset (+=/-=) if specified + adjusted = valueParts[ 1 ] ? + initialInUnit + ( valueParts[ 1 ] + 1 ) * valueParts[ 2 ] : + +valueParts[ 2 ]; + if ( tween ) { + tween.unit = unit; + tween.start = initialInUnit; + tween.end = adjusted; + } + } + return adjusted; +} + + +var defaultDisplayMap = {}; + +function getDefaultDisplay( elem ) { + var temp, + doc = elem.ownerDocument, + nodeName = elem.nodeName, + display = defaultDisplayMap[ nodeName ]; + + if ( display ) { + return display; + } + + temp = doc.body.appendChild( doc.createElement( nodeName ) ); + display = jQuery.css( temp, "display" ); + + temp.parentNode.removeChild( temp ); + + if ( display === "none" ) { + display = "block"; + } + defaultDisplayMap[ nodeName ] = display; + + return display; +} + +function showHide( elements, show ) { + var display, elem, + values = [], + index = 0, + length = elements.length; + + // Determine new display value for elements that need to change + for ( ; index < length; index++ ) { + elem = elements[ index ]; + if ( !elem.style ) { + continue; + } + + display = elem.style.display; + if ( show ) { + + // Since we force visibility upon cascade-hidden elements, an immediate (and slow) + // check is required in this first loop unless we have a nonempty display value (either + // inline or about-to-be-restored) + if ( display === "none" ) { + values[ index ] = dataPriv.get( elem, "display" ) || null; + if ( !values[ index ] ) { + elem.style.display = ""; + } + } + if ( elem.style.display === "" && isHiddenWithinTree( elem ) ) { + values[ index ] = getDefaultDisplay( elem ); + } + } else { + if ( display !== "none" ) { + values[ index ] = "none"; + + // Remember what we're overwriting + dataPriv.set( elem, "display", display ); + } + } + } + + // Set the display of the elements in a second loop to avoid constant reflow + for ( index = 0; index < length; index++ ) { + if ( values[ index ] != null ) { + elements[ index ].style.display = values[ index ]; + } + } + + return elements; +} + +jQuery.fn.extend( { + show: function() { + return showHide( this, true ); + }, + hide: function() { + return showHide( this ); + }, + toggle: function( state ) { + if ( typeof state === "boolean" ) { + return state ? this.show() : this.hide(); + } + + return this.each( function() { + if ( isHiddenWithinTree( this ) ) { + jQuery( this ).show(); + } else { + jQuery( this ).hide(); + } + } ); + } +} ); +var rcheckableType = ( /^(?:checkbox|radio)$/i ); + +var rtagName = ( /<([a-z][^\/\0>\x20\t\r\n\f]*)/i ); + +var rscriptType = ( /^$|^module$|\/(?:java|ecma)script/i ); + + + +// We have to close these tags to support XHTML (#13200) +var wrapMap = { + + // Support: IE <=9 only + option: [ 1, "" ], + + // XHTML parsers do not magically insert elements in the + // same way that tag soup parsers do. So we cannot shorten + // this by omitting or other required elements. + thead: [ 1, "", "
" ], + col: [ 2, "", "
" ], + tr: [ 2, "", "
" ], + td: [ 3, "", "
" ], + + _default: [ 0, "", "" ] +}; + +// Support: IE <=9 only +wrapMap.optgroup = wrapMap.option; + +wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead; +wrapMap.th = wrapMap.td; + + +function getAll( context, tag ) { + + // Support: IE <=9 - 11 only + // Use typeof to avoid zero-argument method invocation on host objects (#15151) + var ret; + + if ( typeof context.getElementsByTagName !== "undefined" ) { + ret = context.getElementsByTagName( tag || "*" ); + + } else if ( typeof context.querySelectorAll !== "undefined" ) { + ret = context.querySelectorAll( tag || "*" ); + + } else { + ret = []; + } + + if ( tag === undefined || tag && nodeName( context, tag ) ) { + return jQuery.merge( [ context ], ret ); + } + + return ret; +} + + +// Mark scripts as having already been evaluated +function setGlobalEval( elems, refElements ) { + var i = 0, + l = elems.length; + + for ( ; i < l; i++ ) { + dataPriv.set( + elems[ i ], + "globalEval", + !refElements || dataPriv.get( refElements[ i ], "globalEval" ) + ); + } +} + + +var rhtml = /<|&#?\w+;/; + +function buildFragment( elems, context, scripts, selection, ignored ) { + var elem, tmp, tag, wrap, attached, j, + fragment = context.createDocumentFragment(), + nodes = [], + i = 0, + l = elems.length; + + for ( ; i < l; i++ ) { + elem = elems[ i ]; + + if ( elem || elem === 0 ) { + + // Add nodes directly + if ( toType( elem ) === "object" ) { + + // Support: Android <=4.0 only, PhantomJS 1 only + // push.apply(_, arraylike) throws on ancient WebKit + jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem ); + + // Convert non-html into a text node + } else if ( !rhtml.test( elem ) ) { + nodes.push( context.createTextNode( elem ) ); + + // Convert html into DOM nodes + } else { + tmp = tmp || fragment.appendChild( context.createElement( "div" ) ); + + // Deserialize a standard representation + tag = ( rtagName.exec( elem ) || [ "", "" ] )[ 1 ].toLowerCase(); + wrap = wrapMap[ tag ] || wrapMap._default; + tmp.innerHTML = wrap[ 1 ] + jQuery.htmlPrefilter( elem ) + wrap[ 2 ]; + + // Descend through wrappers to the right content + j = wrap[ 0 ]; + while ( j-- ) { + tmp = tmp.lastChild; + } + + // Support: Android <=4.0 only, PhantomJS 1 only + // push.apply(_, arraylike) throws on ancient WebKit + jQuery.merge( nodes, tmp.childNodes ); + + // Remember the top-level container + tmp = fragment.firstChild; + + // Ensure the created nodes are orphaned (#12392) + tmp.textContent = ""; + } + } + } + + // Remove wrapper from fragment + fragment.textContent = ""; + + i = 0; + while ( ( elem = nodes[ i++ ] ) ) { + + // Skip elements already in the context collection (trac-4087) + if ( selection && jQuery.inArray( elem, selection ) > -1 ) { + if ( ignored ) { + ignored.push( elem ); + } + continue; + } + + attached = isAttached( elem ); + + // Append to fragment + tmp = getAll( fragment.appendChild( elem ), "script" ); + + // Preserve script evaluation history + if ( attached ) { + setGlobalEval( tmp ); + } + + // Capture executables + if ( scripts ) { + j = 0; + while ( ( elem = tmp[ j++ ] ) ) { + if ( rscriptType.test( elem.type || "" ) ) { + scripts.push( elem ); + } + } + } + } + + return fragment; +} + + +( function() { + var fragment = document.createDocumentFragment(), + div = fragment.appendChild( document.createElement( "div" ) ), + input = document.createElement( "input" ); + + // Support: Android 4.0 - 4.3 only + // Check state lost if the name is set (#11217) + // Support: Windows Web Apps (WWA) + // `name` and `type` must use .setAttribute for WWA (#14901) + input.setAttribute( "type", "radio" ); + input.setAttribute( "checked", "checked" ); + input.setAttribute( "name", "t" ); + + div.appendChild( input ); + + // Support: Android <=4.1 only + // Older WebKit doesn't clone checked state correctly in fragments + support.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked; + + // Support: IE <=11 only + // Make sure textarea (and checkbox) defaultValue is properly cloned + div.innerHTML = ""; + support.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue; +} )(); + + +var + rkeyEvent = /^key/, + rmouseEvent = /^(?:mouse|pointer|contextmenu|drag|drop)|click/, + rtypenamespace = /^([^.]*)(?:\.(.+)|)/; + +function returnTrue() { + return true; +} + +function returnFalse() { + return false; +} + +// Support: IE <=9 - 11+ +// focus() and blur() are asynchronous, except when they are no-op. +// So expect focus to be synchronous when the element is already active, +// and blur to be synchronous when the element is not already active. +// (focus and blur are always synchronous in other supported browsers, +// this just defines when we can count on it). +function expectSync( elem, type ) { + return ( elem === safeActiveElement() ) === ( type === "focus" ); +} + +// Support: IE <=9 only +// Accessing document.activeElement can throw unexpectedly +// https://bugs.jquery.com/ticket/13393 +function safeActiveElement() { + try { + return document.activeElement; + } catch ( err ) { } +} + +function on( elem, types, selector, data, fn, one ) { + var origFn, type; + + // Types can be a map of types/handlers + if ( typeof types === "object" ) { + + // ( types-Object, selector, data ) + if ( typeof selector !== "string" ) { + + // ( types-Object, data ) + data = data || selector; + selector = undefined; + } + for ( type in types ) { + on( elem, type, selector, data, types[ type ], one ); + } + return elem; + } + + if ( data == null && fn == null ) { + + // ( types, fn ) + fn = selector; + data = selector = undefined; + } else if ( fn == null ) { + if ( typeof selector === "string" ) { + + // ( types, selector, fn ) + fn = data; + data = undefined; + } else { + + // ( types, data, fn ) + fn = data; + data = selector; + selector = undefined; + } + } + if ( fn === false ) { + fn = returnFalse; + } else if ( !fn ) { + return elem; + } + + if ( one === 1 ) { + origFn = fn; + fn = function( event ) { + + // Can use an empty set, since event contains the info + jQuery().off( event ); + return origFn.apply( this, arguments ); + }; + + // Use same guid so caller can remove using origFn + fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ ); + } + return elem.each( function() { + jQuery.event.add( this, types, fn, data, selector ); + } ); +} + +/* + * Helper functions for managing events -- not part of the public interface. + * Props to Dean Edwards' addEvent library for many of the ideas. + */ +jQuery.event = { + + global: {}, + + add: function( elem, types, handler, data, selector ) { + + var handleObjIn, eventHandle, tmp, + events, t, handleObj, + special, handlers, type, namespaces, origType, + elemData = dataPriv.get( elem ); + + // Don't attach events to noData or text/comment nodes (but allow plain objects) + if ( !elemData ) { + return; + } + + // Caller can pass in an object of custom data in lieu of the handler + if ( handler.handler ) { + handleObjIn = handler; + handler = handleObjIn.handler; + selector = handleObjIn.selector; + } + + // Ensure that invalid selectors throw exceptions at attach time + // Evaluate against documentElement in case elem is a non-element node (e.g., document) + if ( selector ) { + jQuery.find.matchesSelector( documentElement, selector ); + } + + // Make sure that the handler has a unique ID, used to find/remove it later + if ( !handler.guid ) { + handler.guid = jQuery.guid++; + } + + // Init the element's event structure and main handler, if this is the first + if ( !( events = elemData.events ) ) { + events = elemData.events = {}; + } + if ( !( eventHandle = elemData.handle ) ) { + eventHandle = elemData.handle = function( e ) { + + // Discard the second event of a jQuery.event.trigger() and + // when an event is called after a page has unloaded + return typeof jQuery !== "undefined" && jQuery.event.triggered !== e.type ? + jQuery.event.dispatch.apply( elem, arguments ) : undefined; + }; + } + + // Handle multiple events separated by a space + types = ( types || "" ).match( rnothtmlwhite ) || [ "" ]; + t = types.length; + while ( t-- ) { + tmp = rtypenamespace.exec( types[ t ] ) || []; + type = origType = tmp[ 1 ]; + namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort(); + + // There *must* be a type, no attaching namespace-only handlers + if ( !type ) { + continue; + } + + // If event changes its type, use the special event handlers for the changed type + special = jQuery.event.special[ type ] || {}; + + // If selector defined, determine special event api type, otherwise given type + type = ( selector ? special.delegateType : special.bindType ) || type; + + // Update special based on newly reset type + special = jQuery.event.special[ type ] || {}; + + // handleObj is passed to all event handlers + handleObj = jQuery.extend( { + type: type, + origType: origType, + data: data, + handler: handler, + guid: handler.guid, + selector: selector, + needsContext: selector && jQuery.expr.match.needsContext.test( selector ), + namespace: namespaces.join( "." ) + }, handleObjIn ); + + // Init the event handler queue if we're the first + if ( !( handlers = events[ type ] ) ) { + handlers = events[ type ] = []; + handlers.delegateCount = 0; + + // Only use addEventListener if the special events handler returns false + if ( !special.setup || + special.setup.call( elem, data, namespaces, eventHandle ) === false ) { + + if ( elem.addEventListener ) { + elem.addEventListener( type, eventHandle ); + } + } + } + + if ( special.add ) { + special.add.call( elem, handleObj ); + + if ( !handleObj.handler.guid ) { + handleObj.handler.guid = handler.guid; + } + } + + // Add to the element's handler list, delegates in front + if ( selector ) { + handlers.splice( handlers.delegateCount++, 0, handleObj ); + } else { + handlers.push( handleObj ); + } + + // Keep track of which events have ever been used, for event optimization + jQuery.event.global[ type ] = true; + } + + }, + + // Detach an event or set of events from an element + remove: function( elem, types, handler, selector, mappedTypes ) { + + var j, origCount, tmp, + events, t, handleObj, + special, handlers, type, namespaces, origType, + elemData = dataPriv.hasData( elem ) && dataPriv.get( elem ); + + if ( !elemData || !( events = elemData.events ) ) { + return; + } + + // Once for each type.namespace in types; type may be omitted + types = ( types || "" ).match( rnothtmlwhite ) || [ "" ]; + t = types.length; + while ( t-- ) { + tmp = rtypenamespace.exec( types[ t ] ) || []; + type = origType = tmp[ 1 ]; + namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort(); + + // Unbind all events (on this namespace, if provided) for the element + if ( !type ) { + for ( type in events ) { + jQuery.event.remove( elem, type + types[ t ], handler, selector, true ); + } + continue; + } + + special = jQuery.event.special[ type ] || {}; + type = ( selector ? special.delegateType : special.bindType ) || type; + handlers = events[ type ] || []; + tmp = tmp[ 2 ] && + new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" ); + + // Remove matching events + origCount = j = handlers.length; + while ( j-- ) { + handleObj = handlers[ j ]; + + if ( ( mappedTypes || origType === handleObj.origType ) && + ( !handler || handler.guid === handleObj.guid ) && + ( !tmp || tmp.test( handleObj.namespace ) ) && + ( !selector || selector === handleObj.selector || + selector === "**" && handleObj.selector ) ) { + handlers.splice( j, 1 ); + + if ( handleObj.selector ) { + handlers.delegateCount--; + } + if ( special.remove ) { + special.remove.call( elem, handleObj ); + } + } + } + + // Remove generic event handler if we removed something and no more handlers exist + // (avoids potential for endless recursion during removal of special event handlers) + if ( origCount && !handlers.length ) { + if ( !special.teardown || + special.teardown.call( elem, namespaces, elemData.handle ) === false ) { + + jQuery.removeEvent( elem, type, elemData.handle ); + } + + delete events[ type ]; + } + } + + // Remove data and the expando if it's no longer used + if ( jQuery.isEmptyObject( events ) ) { + dataPriv.remove( elem, "handle events" ); + } + }, + + dispatch: function( nativeEvent ) { + + // Make a writable jQuery.Event from the native event object + var event = jQuery.event.fix( nativeEvent ); + + var i, j, ret, matched, handleObj, handlerQueue, + args = new Array( arguments.length ), + handlers = ( dataPriv.get( this, "events" ) || {} )[ event.type ] || [], + special = jQuery.event.special[ event.type ] || {}; + + // Use the fix-ed jQuery.Event rather than the (read-only) native event + args[ 0 ] = event; + + for ( i = 1; i < arguments.length; i++ ) { + args[ i ] = arguments[ i ]; + } + + event.delegateTarget = this; + + // Call the preDispatch hook for the mapped type, and let it bail if desired + if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) { + return; + } + + // Determine handlers + handlerQueue = jQuery.event.handlers.call( this, event, handlers ); + + // Run delegates first; they may want to stop propagation beneath us + i = 0; + while ( ( matched = handlerQueue[ i++ ] ) && !event.isPropagationStopped() ) { + event.currentTarget = matched.elem; + + j = 0; + while ( ( handleObj = matched.handlers[ j++ ] ) && + !event.isImmediatePropagationStopped() ) { + + // If the event is namespaced, then each handler is only invoked if it is + // specially universal or its namespaces are a superset of the event's. + if ( !event.rnamespace || handleObj.namespace === false || + event.rnamespace.test( handleObj.namespace ) ) { + + event.handleObj = handleObj; + event.data = handleObj.data; + + ret = ( ( jQuery.event.special[ handleObj.origType ] || {} ).handle || + handleObj.handler ).apply( matched.elem, args ); + + if ( ret !== undefined ) { + if ( ( event.result = ret ) === false ) { + event.preventDefault(); + event.stopPropagation(); + } + } + } + } + } + + // Call the postDispatch hook for the mapped type + if ( special.postDispatch ) { + special.postDispatch.call( this, event ); + } + + return event.result; + }, + + handlers: function( event, handlers ) { + var i, handleObj, sel, matchedHandlers, matchedSelectors, + handlerQueue = [], + delegateCount = handlers.delegateCount, + cur = event.target; + + // Find delegate handlers + if ( delegateCount && + + // Support: IE <=9 + // Black-hole SVG instance trees (trac-13180) + cur.nodeType && + + // Support: Firefox <=42 + // Suppress spec-violating clicks indicating a non-primary pointer button (trac-3861) + // https://www.w3.org/TR/DOM-Level-3-Events/#event-type-click + // Support: IE 11 only + // ...but not arrow key "clicks" of radio inputs, which can have `button` -1 (gh-2343) + !( event.type === "click" && event.button >= 1 ) ) { + + for ( ; cur !== this; cur = cur.parentNode || this ) { + + // Don't check non-elements (#13208) + // Don't process clicks on disabled elements (#6911, #8165, #11382, #11764) + if ( cur.nodeType === 1 && !( event.type === "click" && cur.disabled === true ) ) { + matchedHandlers = []; + matchedSelectors = {}; + for ( i = 0; i < delegateCount; i++ ) { + handleObj = handlers[ i ]; + + // Don't conflict with Object.prototype properties (#13203) + sel = handleObj.selector + " "; + + if ( matchedSelectors[ sel ] === undefined ) { + matchedSelectors[ sel ] = handleObj.needsContext ? + jQuery( sel, this ).index( cur ) > -1 : + jQuery.find( sel, this, null, [ cur ] ).length; + } + if ( matchedSelectors[ sel ] ) { + matchedHandlers.push( handleObj ); + } + } + if ( matchedHandlers.length ) { + handlerQueue.push( { elem: cur, handlers: matchedHandlers } ); + } + } + } + } + + // Add the remaining (directly-bound) handlers + cur = this; + if ( delegateCount < handlers.length ) { + handlerQueue.push( { elem: cur, handlers: handlers.slice( delegateCount ) } ); + } + + return handlerQueue; + }, + + addProp: function( name, hook ) { + Object.defineProperty( jQuery.Event.prototype, name, { + enumerable: true, + configurable: true, + + get: isFunction( hook ) ? + function() { + if ( this.originalEvent ) { + return hook( this.originalEvent ); + } + } : + function() { + if ( this.originalEvent ) { + return this.originalEvent[ name ]; + } + }, + + set: function( value ) { + Object.defineProperty( this, name, { + enumerable: true, + configurable: true, + writable: true, + value: value + } ); + } + } ); + }, + + fix: function( originalEvent ) { + return originalEvent[ jQuery.expando ] ? + originalEvent : + new jQuery.Event( originalEvent ); + }, + + special: { + load: { + + // Prevent triggered image.load events from bubbling to window.load + noBubble: true + }, + click: { + + // Utilize native event to ensure correct state for checkable inputs + setup: function( data ) { + + // For mutual compressibility with _default, replace `this` access with a local var. + // `|| data` is dead code meant only to preserve the variable through minification. + var el = this || data; + + // Claim the first handler + if ( rcheckableType.test( el.type ) && + el.click && nodeName( el, "input" ) ) { + + // dataPriv.set( el, "click", ... ) + leverageNative( el, "click", returnTrue ); + } + + // Return false to allow normal processing in the caller + return false; + }, + trigger: function( data ) { + + // For mutual compressibility with _default, replace `this` access with a local var. + // `|| data` is dead code meant only to preserve the variable through minification. + var el = this || data; + + // Force setup before triggering a click + if ( rcheckableType.test( el.type ) && + el.click && nodeName( el, "input" ) ) { + + leverageNative( el, "click" ); + } + + // Return non-false to allow normal event-path propagation + return true; + }, + + // For cross-browser consistency, suppress native .click() on links + // Also prevent it if we're currently inside a leveraged native-event stack + _default: function( event ) { + var target = event.target; + return rcheckableType.test( target.type ) && + target.click && nodeName( target, "input" ) && + dataPriv.get( target, "click" ) || + nodeName( target, "a" ); + } + }, + + beforeunload: { + postDispatch: function( event ) { + + // Support: Firefox 20+ + // Firefox doesn't alert if the returnValue field is not set. + if ( event.result !== undefined && event.originalEvent ) { + event.originalEvent.returnValue = event.result; + } + } + } + } +}; + +// Ensure the presence of an event listener that handles manually-triggered +// synthetic events by interrupting progress until reinvoked in response to +// *native* events that it fires directly, ensuring that state changes have +// already occurred before other listeners are invoked. +function leverageNative( el, type, expectSync ) { + + // Missing expectSync indicates a trigger call, which must force setup through jQuery.event.add + if ( !expectSync ) { + if ( dataPriv.get( el, type ) === undefined ) { + jQuery.event.add( el, type, returnTrue ); + } + return; + } + + // Register the controller as a special universal handler for all event namespaces + dataPriv.set( el, type, false ); + jQuery.event.add( el, type, { + namespace: false, + handler: function( event ) { + var notAsync, result, + saved = dataPriv.get( this, type ); + + if ( ( event.isTrigger & 1 ) && this[ type ] ) { + + // Interrupt processing of the outer synthetic .trigger()ed event + // Saved data should be false in such cases, but might be a leftover capture object + // from an async native handler (gh-4350) + if ( !saved.length ) { + + // Store arguments for use when handling the inner native event + // There will always be at least one argument (an event object), so this array + // will not be confused with a leftover capture object. + saved = slice.call( arguments ); + dataPriv.set( this, type, saved ); + + // Trigger the native event and capture its result + // Support: IE <=9 - 11+ + // focus() and blur() are asynchronous + notAsync = expectSync( this, type ); + this[ type ](); + result = dataPriv.get( this, type ); + if ( saved !== result || notAsync ) { + dataPriv.set( this, type, false ); + } else { + result = {}; + } + if ( saved !== result ) { + + // Cancel the outer synthetic event + event.stopImmediatePropagation(); + event.preventDefault(); + return result.value; + } + + // If this is an inner synthetic event for an event with a bubbling surrogate + // (focus or blur), assume that the surrogate already propagated from triggering the + // native event and prevent that from happening again here. + // This technically gets the ordering wrong w.r.t. to `.trigger()` (in which the + // bubbling surrogate propagates *after* the non-bubbling base), but that seems + // less bad than duplication. + } else if ( ( jQuery.event.special[ type ] || {} ).delegateType ) { + event.stopPropagation(); + } + + // If this is a native event triggered above, everything is now in order + // Fire an inner synthetic event with the original arguments + } else if ( saved.length ) { + + // ...and capture the result + dataPriv.set( this, type, { + value: jQuery.event.trigger( + + // Support: IE <=9 - 11+ + // Extend with the prototype to reset the above stopImmediatePropagation() + jQuery.extend( saved[ 0 ], jQuery.Event.prototype ), + saved.slice( 1 ), + this + ) + } ); + + // Abort handling of the native event + event.stopImmediatePropagation(); + } + } + } ); +} + +jQuery.removeEvent = function( elem, type, handle ) { + + // This "if" is needed for plain objects + if ( elem.removeEventListener ) { + elem.removeEventListener( type, handle ); + } +}; + +jQuery.Event = function( src, props ) { + + // Allow instantiation without the 'new' keyword + if ( !( this instanceof jQuery.Event ) ) { + return new jQuery.Event( src, props ); + } + + // Event object + if ( src && src.type ) { + this.originalEvent = src; + this.type = src.type; + + // Events bubbling up the document may have been marked as prevented + // by a handler lower down the tree; reflect the correct value. + this.isDefaultPrevented = src.defaultPrevented || + src.defaultPrevented === undefined && + + // Support: Android <=2.3 only + src.returnValue === false ? + returnTrue : + returnFalse; + + // Create target properties + // Support: Safari <=6 - 7 only + // Target should not be a text node (#504, #13143) + this.target = ( src.target && src.target.nodeType === 3 ) ? + src.target.parentNode : + src.target; + + this.currentTarget = src.currentTarget; + this.relatedTarget = src.relatedTarget; + + // Event type + } else { + this.type = src; + } + + // Put explicitly provided properties onto the event object + if ( props ) { + jQuery.extend( this, props ); + } + + // Create a timestamp if incoming event doesn't have one + this.timeStamp = src && src.timeStamp || Date.now(); + + // Mark it as fixed + this[ jQuery.expando ] = true; +}; + +// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding +// https://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html +jQuery.Event.prototype = { + constructor: jQuery.Event, + isDefaultPrevented: returnFalse, + isPropagationStopped: returnFalse, + isImmediatePropagationStopped: returnFalse, + isSimulated: false, + + preventDefault: function() { + var e = this.originalEvent; + + this.isDefaultPrevented = returnTrue; + + if ( e && !this.isSimulated ) { + e.preventDefault(); + } + }, + stopPropagation: function() { + var e = this.originalEvent; + + this.isPropagationStopped = returnTrue; + + if ( e && !this.isSimulated ) { + e.stopPropagation(); + } + }, + stopImmediatePropagation: function() { + var e = this.originalEvent; + + this.isImmediatePropagationStopped = returnTrue; + + if ( e && !this.isSimulated ) { + e.stopImmediatePropagation(); + } + + this.stopPropagation(); + } +}; + +// Includes all common event props including KeyEvent and MouseEvent specific props +jQuery.each( { + altKey: true, + bubbles: true, + cancelable: true, + changedTouches: true, + ctrlKey: true, + detail: true, + eventPhase: true, + metaKey: true, + pageX: true, + pageY: true, + shiftKey: true, + view: true, + "char": true, + code: true, + charCode: true, + key: true, + keyCode: true, + button: true, + buttons: true, + clientX: true, + clientY: true, + offsetX: true, + offsetY: true, + pointerId: true, + pointerType: true, + screenX: true, + screenY: true, + targetTouches: true, + toElement: true, + touches: true, + + which: function( event ) { + var button = event.button; + + // Add which for key events + if ( event.which == null && rkeyEvent.test( event.type ) ) { + return event.charCode != null ? event.charCode : event.keyCode; + } + + // Add which for click: 1 === left; 2 === middle; 3 === right + if ( !event.which && button !== undefined && rmouseEvent.test( event.type ) ) { + if ( button & 1 ) { + return 1; + } + + if ( button & 2 ) { + return 3; + } + + if ( button & 4 ) { + return 2; + } + + return 0; + } + + return event.which; + } +}, jQuery.event.addProp ); + +jQuery.each( { focus: "focusin", blur: "focusout" }, function( type, delegateType ) { + jQuery.event.special[ type ] = { + + // Utilize native event if possible so blur/focus sequence is correct + setup: function() { + + // Claim the first handler + // dataPriv.set( this, "focus", ... ) + // dataPriv.set( this, "blur", ... ) + leverageNative( this, type, expectSync ); + + // Return false to allow normal processing in the caller + return false; + }, + trigger: function() { + + // Force setup before trigger + leverageNative( this, type ); + + // Return non-false to allow normal event-path propagation + return true; + }, + + delegateType: delegateType + }; +} ); + +// Create mouseenter/leave events using mouseover/out and event-time checks +// so that event delegation works in jQuery. +// Do the same for pointerenter/pointerleave and pointerover/pointerout +// +// Support: Safari 7 only +// Safari sends mouseenter too often; see: +// https://bugs.chromium.org/p/chromium/issues/detail?id=470258 +// for the description of the bug (it existed in older Chrome versions as well). +jQuery.each( { + mouseenter: "mouseover", + mouseleave: "mouseout", + pointerenter: "pointerover", + pointerleave: "pointerout" +}, function( orig, fix ) { + jQuery.event.special[ orig ] = { + delegateType: fix, + bindType: fix, + + handle: function( event ) { + var ret, + target = this, + related = event.relatedTarget, + handleObj = event.handleObj; + + // For mouseenter/leave call the handler if related is outside the target. + // NB: No relatedTarget if the mouse left/entered the browser window + if ( !related || ( related !== target && !jQuery.contains( target, related ) ) ) { + event.type = handleObj.origType; + ret = handleObj.handler.apply( this, arguments ); + event.type = fix; + } + return ret; + } + }; +} ); + +jQuery.fn.extend( { + + on: function( types, selector, data, fn ) { + return on( this, types, selector, data, fn ); + }, + one: function( types, selector, data, fn ) { + return on( this, types, selector, data, fn, 1 ); + }, + off: function( types, selector, fn ) { + var handleObj, type; + if ( types && types.preventDefault && types.handleObj ) { + + // ( event ) dispatched jQuery.Event + handleObj = types.handleObj; + jQuery( types.delegateTarget ).off( + handleObj.namespace ? + handleObj.origType + "." + handleObj.namespace : + handleObj.origType, + handleObj.selector, + handleObj.handler + ); + return this; + } + if ( typeof types === "object" ) { + + // ( types-object [, selector] ) + for ( type in types ) { + this.off( type, selector, types[ type ] ); + } + return this; + } + if ( selector === false || typeof selector === "function" ) { + + // ( types [, fn] ) + fn = selector; + selector = undefined; + } + if ( fn === false ) { + fn = returnFalse; + } + return this.each( function() { + jQuery.event.remove( this, types, fn, selector ); + } ); + } +} ); + + +var + + /* eslint-disable max-len */ + + // See https://github.com/eslint/eslint/issues/3229 + rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([a-z][^\/\0>\x20\t\r\n\f]*)[^>]*)\/>/gi, + + /* eslint-enable */ + + // Support: IE <=10 - 11, Edge 12 - 13 only + // In IE/Edge using regex groups here causes severe slowdowns. + // See https://connect.microsoft.com/IE/feedback/details/1736512/ + rnoInnerhtml = /\s*$/g; + +// Prefer a tbody over its parent table for containing new rows +function manipulationTarget( elem, content ) { + if ( nodeName( elem, "table" ) && + nodeName( content.nodeType !== 11 ? content : content.firstChild, "tr" ) ) { + + return jQuery( elem ).children( "tbody" )[ 0 ] || elem; + } + + return elem; +} + +// Replace/restore the type attribute of script elements for safe DOM manipulation +function disableScript( elem ) { + elem.type = ( elem.getAttribute( "type" ) !== null ) + "/" + elem.type; + return elem; +} +function restoreScript( elem ) { + if ( ( elem.type || "" ).slice( 0, 5 ) === "true/" ) { + elem.type = elem.type.slice( 5 ); + } else { + elem.removeAttribute( "type" ); + } + + return elem; +} + +function cloneCopyEvent( src, dest ) { + var i, l, type, pdataOld, pdataCur, udataOld, udataCur, events; + + if ( dest.nodeType !== 1 ) { + return; + } + + // 1. Copy private data: events, handlers, etc. + if ( dataPriv.hasData( src ) ) { + pdataOld = dataPriv.access( src ); + pdataCur = dataPriv.set( dest, pdataOld ); + events = pdataOld.events; + + if ( events ) { + delete pdataCur.handle; + pdataCur.events = {}; + + for ( type in events ) { + for ( i = 0, l = events[ type ].length; i < l; i++ ) { + jQuery.event.add( dest, type, events[ type ][ i ] ); + } + } + } + } + + // 2. Copy user data + if ( dataUser.hasData( src ) ) { + udataOld = dataUser.access( src ); + udataCur = jQuery.extend( {}, udataOld ); + + dataUser.set( dest, udataCur ); + } +} + +// Fix IE bugs, see support tests +function fixInput( src, dest ) { + var nodeName = dest.nodeName.toLowerCase(); + + // Fails to persist the checked state of a cloned checkbox or radio button. + if ( nodeName === "input" && rcheckableType.test( src.type ) ) { + dest.checked = src.checked; + + // Fails to return the selected option to the default selected state when cloning options + } else if ( nodeName === "input" || nodeName === "textarea" ) { + dest.defaultValue = src.defaultValue; + } +} + +function domManip( collection, args, callback, ignored ) { + + // Flatten any nested arrays + args = concat.apply( [], args ); + + var fragment, first, scripts, hasScripts, node, doc, + i = 0, + l = collection.length, + iNoClone = l - 1, + value = args[ 0 ], + valueIsFunction = isFunction( value ); + + // We can't cloneNode fragments that contain checked, in WebKit + if ( valueIsFunction || + ( l > 1 && typeof value === "string" && + !support.checkClone && rchecked.test( value ) ) ) { + return collection.each( function( index ) { + var self = collection.eq( index ); + if ( valueIsFunction ) { + args[ 0 ] = value.call( this, index, self.html() ); + } + domManip( self, args, callback, ignored ); + } ); + } + + if ( l ) { + fragment = buildFragment( args, collection[ 0 ].ownerDocument, false, collection, ignored ); + first = fragment.firstChild; + + if ( fragment.childNodes.length === 1 ) { + fragment = first; + } + + // Require either new content or an interest in ignored elements to invoke the callback + if ( first || ignored ) { + scripts = jQuery.map( getAll( fragment, "script" ), disableScript ); + hasScripts = scripts.length; + + // Use the original fragment for the last item + // instead of the first because it can end up + // being emptied incorrectly in certain situations (#8070). + for ( ; i < l; i++ ) { + node = fragment; + + if ( i !== iNoClone ) { + node = jQuery.clone( node, true, true ); + + // Keep references to cloned scripts for later restoration + if ( hasScripts ) { + + // Support: Android <=4.0 only, PhantomJS 1 only + // push.apply(_, arraylike) throws on ancient WebKit + jQuery.merge( scripts, getAll( node, "script" ) ); + } + } + + callback.call( collection[ i ], node, i ); + } + + if ( hasScripts ) { + doc = scripts[ scripts.length - 1 ].ownerDocument; + + // Reenable scripts + jQuery.map( scripts, restoreScript ); + + // Evaluate executable scripts on first document insertion + for ( i = 0; i < hasScripts; i++ ) { + node = scripts[ i ]; + if ( rscriptType.test( node.type || "" ) && + !dataPriv.access( node, "globalEval" ) && + jQuery.contains( doc, node ) ) { + + if ( node.src && ( node.type || "" ).toLowerCase() !== "module" ) { + + // Optional AJAX dependency, but won't run scripts if not present + if ( jQuery._evalUrl && !node.noModule ) { + jQuery._evalUrl( node.src, { + nonce: node.nonce || node.getAttribute( "nonce" ) + } ); + } + } else { + DOMEval( node.textContent.replace( rcleanScript, "" ), node, doc ); + } + } + } + } + } + } + + return collection; +} + +function remove( elem, selector, keepData ) { + var node, + nodes = selector ? jQuery.filter( selector, elem ) : elem, + i = 0; + + for ( ; ( node = nodes[ i ] ) != null; i++ ) { + if ( !keepData && node.nodeType === 1 ) { + jQuery.cleanData( getAll( node ) ); + } + + if ( node.parentNode ) { + if ( keepData && isAttached( node ) ) { + setGlobalEval( getAll( node, "script" ) ); + } + node.parentNode.removeChild( node ); + } + } + + return elem; +} + +jQuery.extend( { + htmlPrefilter: function( html ) { + return html.replace( rxhtmlTag, "<$1>" ); + }, + + clone: function( elem, dataAndEvents, deepDataAndEvents ) { + var i, l, srcElements, destElements, + clone = elem.cloneNode( true ), + inPage = isAttached( elem ); + + // Fix IE cloning issues + if ( !support.noCloneChecked && ( elem.nodeType === 1 || elem.nodeType === 11 ) && + !jQuery.isXMLDoc( elem ) ) { + + // We eschew Sizzle here for performance reasons: https://jsperf.com/getall-vs-sizzle/2 + destElements = getAll( clone ); + srcElements = getAll( elem ); + + for ( i = 0, l = srcElements.length; i < l; i++ ) { + fixInput( srcElements[ i ], destElements[ i ] ); + } + } + + // Copy the events from the original to the clone + if ( dataAndEvents ) { + if ( deepDataAndEvents ) { + srcElements = srcElements || getAll( elem ); + destElements = destElements || getAll( clone ); + + for ( i = 0, l = srcElements.length; i < l; i++ ) { + cloneCopyEvent( srcElements[ i ], destElements[ i ] ); + } + } else { + cloneCopyEvent( elem, clone ); + } + } + + // Preserve script evaluation history + destElements = getAll( clone, "script" ); + if ( destElements.length > 0 ) { + setGlobalEval( destElements, !inPage && getAll( elem, "script" ) ); + } + + // Return the cloned set + return clone; + }, + + cleanData: function( elems ) { + var data, elem, type, + special = jQuery.event.special, + i = 0; + + for ( ; ( elem = elems[ i ] ) !== undefined; i++ ) { + if ( acceptData( elem ) ) { + if ( ( data = elem[ dataPriv.expando ] ) ) { + if ( data.events ) { + for ( type in data.events ) { + if ( special[ type ] ) { + jQuery.event.remove( elem, type ); + + // This is a shortcut to avoid jQuery.event.remove's overhead + } else { + jQuery.removeEvent( elem, type, data.handle ); + } + } + } + + // Support: Chrome <=35 - 45+ + // Assign undefined instead of using delete, see Data#remove + elem[ dataPriv.expando ] = undefined; + } + if ( elem[ dataUser.expando ] ) { + + // Support: Chrome <=35 - 45+ + // Assign undefined instead of using delete, see Data#remove + elem[ dataUser.expando ] = undefined; + } + } + } + } +} ); + +jQuery.fn.extend( { + detach: function( selector ) { + return remove( this, selector, true ); + }, + + remove: function( selector ) { + return remove( this, selector ); + }, + + text: function( value ) { + return access( this, function( value ) { + return value === undefined ? + jQuery.text( this ) : + this.empty().each( function() { + if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { + this.textContent = value; + } + } ); + }, null, value, arguments.length ); + }, + + append: function() { + return domManip( this, arguments, function( elem ) { + if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { + var target = manipulationTarget( this, elem ); + target.appendChild( elem ); + } + } ); + }, + + prepend: function() { + return domManip( this, arguments, function( elem ) { + if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { + var target = manipulationTarget( this, elem ); + target.insertBefore( elem, target.firstChild ); + } + } ); + }, + + before: function() { + return domManip( this, arguments, function( elem ) { + if ( this.parentNode ) { + this.parentNode.insertBefore( elem, this ); + } + } ); + }, + + after: function() { + return domManip( this, arguments, function( elem ) { + if ( this.parentNode ) { + this.parentNode.insertBefore( elem, this.nextSibling ); + } + } ); + }, + + empty: function() { + var elem, + i = 0; + + for ( ; ( elem = this[ i ] ) != null; i++ ) { + if ( elem.nodeType === 1 ) { + + // Prevent memory leaks + jQuery.cleanData( getAll( elem, false ) ); + + // Remove any remaining nodes + elem.textContent = ""; + } + } + + return this; + }, + + clone: function( dataAndEvents, deepDataAndEvents ) { + dataAndEvents = dataAndEvents == null ? false : dataAndEvents; + deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents; + + return this.map( function() { + return jQuery.clone( this, dataAndEvents, deepDataAndEvents ); + } ); + }, + + html: function( value ) { + return access( this, function( value ) { + var elem = this[ 0 ] || {}, + i = 0, + l = this.length; + + if ( value === undefined && elem.nodeType === 1 ) { + return elem.innerHTML; + } + + // See if we can take a shortcut and just use innerHTML + if ( typeof value === "string" && !rnoInnerhtml.test( value ) && + !wrapMap[ ( rtagName.exec( value ) || [ "", "" ] )[ 1 ].toLowerCase() ] ) { + + value = jQuery.htmlPrefilter( value ); + + try { + for ( ; i < l; i++ ) { + elem = this[ i ] || {}; + + // Remove element nodes and prevent memory leaks + if ( elem.nodeType === 1 ) { + jQuery.cleanData( getAll( elem, false ) ); + elem.innerHTML = value; + } + } + + elem = 0; + + // If using innerHTML throws an exception, use the fallback method + } catch ( e ) {} + } + + if ( elem ) { + this.empty().append( value ); + } + }, null, value, arguments.length ); + }, + + replaceWith: function() { + var ignored = []; + + // Make the changes, replacing each non-ignored context element with the new content + return domManip( this, arguments, function( elem ) { + var parent = this.parentNode; + + if ( jQuery.inArray( this, ignored ) < 0 ) { + jQuery.cleanData( getAll( this ) ); + if ( parent ) { + parent.replaceChild( elem, this ); + } + } + + // Force callback invocation + }, ignored ); + } +} ); + +jQuery.each( { + appendTo: "append", + prependTo: "prepend", + insertBefore: "before", + insertAfter: "after", + replaceAll: "replaceWith" +}, function( name, original ) { + jQuery.fn[ name ] = function( selector ) { + var elems, + ret = [], + insert = jQuery( selector ), + last = insert.length - 1, + i = 0; + + for ( ; i <= last; i++ ) { + elems = i === last ? this : this.clone( true ); + jQuery( insert[ i ] )[ original ]( elems ); + + // Support: Android <=4.0 only, PhantomJS 1 only + // .get() because push.apply(_, arraylike) throws on ancient WebKit + push.apply( ret, elems.get() ); + } + + return this.pushStack( ret ); + }; +} ); +var rnumnonpx = new RegExp( "^(" + pnum + ")(?!px)[a-z%]+$", "i" ); + +var getStyles = function( elem ) { + + // Support: IE <=11 only, Firefox <=30 (#15098, #14150) + // IE throws on elements created in popups + // FF meanwhile throws on frame elements through "defaultView.getComputedStyle" + var view = elem.ownerDocument.defaultView; + + if ( !view || !view.opener ) { + view = window; + } + + return view.getComputedStyle( elem ); + }; + +var rboxStyle = new RegExp( cssExpand.join( "|" ), "i" ); + + + +( function() { + + // Executing both pixelPosition & boxSizingReliable tests require only one layout + // so they're executed at the same time to save the second computation. + function computeStyleTests() { + + // This is a singleton, we need to execute it only once + if ( !div ) { + return; + } + + container.style.cssText = "position:absolute;left:-11111px;width:60px;" + + "margin-top:1px;padding:0;border:0"; + div.style.cssText = + "position:relative;display:block;box-sizing:border-box;overflow:scroll;" + + "margin:auto;border:1px;padding:1px;" + + "width:60%;top:1%"; + documentElement.appendChild( container ).appendChild( div ); + + var divStyle = window.getComputedStyle( div ); + pixelPositionVal = divStyle.top !== "1%"; + + // Support: Android 4.0 - 4.3 only, Firefox <=3 - 44 + reliableMarginLeftVal = roundPixelMeasures( divStyle.marginLeft ) === 12; + + // Support: Android 4.0 - 4.3 only, Safari <=9.1 - 10.1, iOS <=7.0 - 9.3 + // Some styles come back with percentage values, even though they shouldn't + div.style.right = "60%"; + pixelBoxStylesVal = roundPixelMeasures( divStyle.right ) === 36; + + // Support: IE 9 - 11 only + // Detect misreporting of content dimensions for box-sizing:border-box elements + boxSizingReliableVal = roundPixelMeasures( divStyle.width ) === 36; + + // Support: IE 9 only + // Detect overflow:scroll screwiness (gh-3699) + // Support: Chrome <=64 + // Don't get tricked when zoom affects offsetWidth (gh-4029) + div.style.position = "absolute"; + scrollboxSizeVal = roundPixelMeasures( div.offsetWidth / 3 ) === 12; + + documentElement.removeChild( container ); + + // Nullify the div so it wouldn't be stored in the memory and + // it will also be a sign that checks already performed + div = null; + } + + function roundPixelMeasures( measure ) { + return Math.round( parseFloat( measure ) ); + } + + var pixelPositionVal, boxSizingReliableVal, scrollboxSizeVal, pixelBoxStylesVal, + reliableMarginLeftVal, + container = document.createElement( "div" ), + div = document.createElement( "div" ); + + // Finish early in limited (non-browser) environments + if ( !div.style ) { + return; + } + + // Support: IE <=9 - 11 only + // Style of cloned element affects source element cloned (#8908) + div.style.backgroundClip = "content-box"; + div.cloneNode( true ).style.backgroundClip = ""; + support.clearCloneStyle = div.style.backgroundClip === "content-box"; + + jQuery.extend( support, { + boxSizingReliable: function() { + computeStyleTests(); + return boxSizingReliableVal; + }, + pixelBoxStyles: function() { + computeStyleTests(); + return pixelBoxStylesVal; + }, + pixelPosition: function() { + computeStyleTests(); + return pixelPositionVal; + }, + reliableMarginLeft: function() { + computeStyleTests(); + return reliableMarginLeftVal; + }, + scrollboxSize: function() { + computeStyleTests(); + return scrollboxSizeVal; + } + } ); +} )(); + + +function curCSS( elem, name, computed ) { + var width, minWidth, maxWidth, ret, + + // Support: Firefox 51+ + // Retrieving style before computed somehow + // fixes an issue with getting wrong values + // on detached elements + style = elem.style; + + computed = computed || getStyles( elem ); + + // getPropertyValue is needed for: + // .css('filter') (IE 9 only, #12537) + // .css('--customProperty) (#3144) + if ( computed ) { + ret = computed.getPropertyValue( name ) || computed[ name ]; + + if ( ret === "" && !isAttached( elem ) ) { + ret = jQuery.style( elem, name ); + } + + // A tribute to the "awesome hack by Dean Edwards" + // Android Browser returns percentage for some values, + // but width seems to be reliably pixels. + // This is against the CSSOM draft spec: + // https://drafts.csswg.org/cssom/#resolved-values + if ( !support.pixelBoxStyles() && rnumnonpx.test( ret ) && rboxStyle.test( name ) ) { + + // Remember the original values + width = style.width; + minWidth = style.minWidth; + maxWidth = style.maxWidth; + + // Put in the new values to get a computed value out + style.minWidth = style.maxWidth = style.width = ret; + ret = computed.width; + + // Revert the changed values + style.width = width; + style.minWidth = minWidth; + style.maxWidth = maxWidth; + } + } + + return ret !== undefined ? + + // Support: IE <=9 - 11 only + // IE returns zIndex value as an integer. + ret + "" : + ret; +} + + +function addGetHookIf( conditionFn, hookFn ) { + + // Define the hook, we'll check on the first run if it's really needed. + return { + get: function() { + if ( conditionFn() ) { + + // Hook not needed (or it's not possible to use it due + // to missing dependency), remove it. + delete this.get; + return; + } + + // Hook needed; redefine it so that the support test is not executed again. + return ( this.get = hookFn ).apply( this, arguments ); + } + }; +} + + +var cssPrefixes = [ "Webkit", "Moz", "ms" ], + emptyStyle = document.createElement( "div" ).style, + vendorProps = {}; + +// Return a vendor-prefixed property or undefined +function vendorPropName( name ) { + + // Check for vendor prefixed names + var capName = name[ 0 ].toUpperCase() + name.slice( 1 ), + i = cssPrefixes.length; + + while ( i-- ) { + name = cssPrefixes[ i ] + capName; + if ( name in emptyStyle ) { + return name; + } + } +} + +// Return a potentially-mapped jQuery.cssProps or vendor prefixed property +function finalPropName( name ) { + var final = jQuery.cssProps[ name ] || vendorProps[ name ]; + + if ( final ) { + return final; + } + if ( name in emptyStyle ) { + return name; + } + return vendorProps[ name ] = vendorPropName( name ) || name; +} + + +var + + // Swappable if display is none or starts with table + // except "table", "table-cell", or "table-caption" + // See here for display values: https://developer.mozilla.org/en-US/docs/CSS/display + rdisplayswap = /^(none|table(?!-c[ea]).+)/, + rcustomProp = /^--/, + cssShow = { position: "absolute", visibility: "hidden", display: "block" }, + cssNormalTransform = { + letterSpacing: "0", + fontWeight: "400" + }; + +function setPositiveNumber( elem, value, subtract ) { + + // Any relative (+/-) values have already been + // normalized at this point + var matches = rcssNum.exec( value ); + return matches ? + + // Guard against undefined "subtract", e.g., when used as in cssHooks + Math.max( 0, matches[ 2 ] - ( subtract || 0 ) ) + ( matches[ 3 ] || "px" ) : + value; +} + +function boxModelAdjustment( elem, dimension, box, isBorderBox, styles, computedVal ) { + var i = dimension === "width" ? 1 : 0, + extra = 0, + delta = 0; + + // Adjustment may not be necessary + if ( box === ( isBorderBox ? "border" : "content" ) ) { + return 0; + } + + for ( ; i < 4; i += 2 ) { + + // Both box models exclude margin + if ( box === "margin" ) { + delta += jQuery.css( elem, box + cssExpand[ i ], true, styles ); + } + + // If we get here with a content-box, we're seeking "padding" or "border" or "margin" + if ( !isBorderBox ) { + + // Add padding + delta += jQuery.css( elem, "padding" + cssExpand[ i ], true, styles ); + + // For "border" or "margin", add border + if ( box !== "padding" ) { + delta += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); + + // But still keep track of it otherwise + } else { + extra += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); + } + + // If we get here with a border-box (content + padding + border), we're seeking "content" or + // "padding" or "margin" + } else { + + // For "content", subtract padding + if ( box === "content" ) { + delta -= jQuery.css( elem, "padding" + cssExpand[ i ], true, styles ); + } + + // For "content" or "padding", subtract border + if ( box !== "margin" ) { + delta -= jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); + } + } + } + + // Account for positive content-box scroll gutter when requested by providing computedVal + if ( !isBorderBox && computedVal >= 0 ) { + + // offsetWidth/offsetHeight is a rounded sum of content, padding, scroll gutter, and border + // Assuming integer scroll gutter, subtract the rest and round down + delta += Math.max( 0, Math.ceil( + elem[ "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ] - + computedVal - + delta - + extra - + 0.5 + + // If offsetWidth/offsetHeight is unknown, then we can't determine content-box scroll gutter + // Use an explicit zero to avoid NaN (gh-3964) + ) ) || 0; + } + + return delta; +} + +function getWidthOrHeight( elem, dimension, extra ) { + + // Start with computed style + var styles = getStyles( elem ), + + // To avoid forcing a reflow, only fetch boxSizing if we need it (gh-4322). + // Fake content-box until we know it's needed to know the true value. + boxSizingNeeded = !support.boxSizingReliable() || extra, + isBorderBox = boxSizingNeeded && + jQuery.css( elem, "boxSizing", false, styles ) === "border-box", + valueIsBorderBox = isBorderBox, + + val = curCSS( elem, dimension, styles ), + offsetProp = "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ); + + // Support: Firefox <=54 + // Return a confounding non-pixel value or feign ignorance, as appropriate. + if ( rnumnonpx.test( val ) ) { + if ( !extra ) { + return val; + } + val = "auto"; + } + + + // Fall back to offsetWidth/offsetHeight when value is "auto" + // This happens for inline elements with no explicit setting (gh-3571) + // Support: Android <=4.1 - 4.3 only + // Also use offsetWidth/offsetHeight for misreported inline dimensions (gh-3602) + // Support: IE 9-11 only + // Also use offsetWidth/offsetHeight for when box sizing is unreliable + // We use getClientRects() to check for hidden/disconnected. + // In those cases, the computed value can be trusted to be border-box + if ( ( !support.boxSizingReliable() && isBorderBox || + val === "auto" || + !parseFloat( val ) && jQuery.css( elem, "display", false, styles ) === "inline" ) && + elem.getClientRects().length ) { + + isBorderBox = jQuery.css( elem, "boxSizing", false, styles ) === "border-box"; + + // Where available, offsetWidth/offsetHeight approximate border box dimensions. + // Where not available (e.g., SVG), assume unreliable box-sizing and interpret the + // retrieved value as a content box dimension. + valueIsBorderBox = offsetProp in elem; + if ( valueIsBorderBox ) { + val = elem[ offsetProp ]; + } + } + + // Normalize "" and auto + val = parseFloat( val ) || 0; + + // Adjust for the element's box model + return ( val + + boxModelAdjustment( + elem, + dimension, + extra || ( isBorderBox ? "border" : "content" ), + valueIsBorderBox, + styles, + + // Provide the current computed size to request scroll gutter calculation (gh-3589) + val + ) + ) + "px"; +} + +jQuery.extend( { + + // Add in style property hooks for overriding the default + // behavior of getting and setting a style property + cssHooks: { + opacity: { + get: function( elem, computed ) { + if ( computed ) { + + // We should always get a number back from opacity + var ret = curCSS( elem, "opacity" ); + return ret === "" ? "1" : ret; + } + } + } + }, + + // Don't automatically add "px" to these possibly-unitless properties + cssNumber: { + "animationIterationCount": true, + "columnCount": true, + "fillOpacity": true, + "flexGrow": true, + "flexShrink": true, + "fontWeight": true, + "gridArea": true, + "gridColumn": true, + "gridColumnEnd": true, + "gridColumnStart": true, + "gridRow": true, + "gridRowEnd": true, + "gridRowStart": true, + "lineHeight": true, + "opacity": true, + "order": true, + "orphans": true, + "widows": true, + "zIndex": true, + "zoom": true + }, + + // Add in properties whose names you wish to fix before + // setting or getting the value + cssProps: {}, + + // Get and set the style property on a DOM Node + style: function( elem, name, value, extra ) { + + // Don't set styles on text and comment nodes + if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) { + return; + } + + // Make sure that we're working with the right name + var ret, type, hooks, + origName = camelCase( name ), + isCustomProp = rcustomProp.test( name ), + style = elem.style; + + // Make sure that we're working with the right name. We don't + // want to query the value if it is a CSS custom property + // since they are user-defined. + if ( !isCustomProp ) { + name = finalPropName( origName ); + } + + // Gets hook for the prefixed version, then unprefixed version + hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; + + // Check if we're setting a value + if ( value !== undefined ) { + type = typeof value; + + // Convert "+=" or "-=" to relative numbers (#7345) + if ( type === "string" && ( ret = rcssNum.exec( value ) ) && ret[ 1 ] ) { + value = adjustCSS( elem, name, ret ); + + // Fixes bug #9237 + type = "number"; + } + + // Make sure that null and NaN values aren't set (#7116) + if ( value == null || value !== value ) { + return; + } + + // If a number was passed in, add the unit (except for certain CSS properties) + // The isCustomProp check can be removed in jQuery 4.0 when we only auto-append + // "px" to a few hardcoded values. + if ( type === "number" && !isCustomProp ) { + value += ret && ret[ 3 ] || ( jQuery.cssNumber[ origName ] ? "" : "px" ); + } + + // background-* props affect original clone's values + if ( !support.clearCloneStyle && value === "" && name.indexOf( "background" ) === 0 ) { + style[ name ] = "inherit"; + } + + // If a hook was provided, use that value, otherwise just set the specified value + if ( !hooks || !( "set" in hooks ) || + ( value = hooks.set( elem, value, extra ) ) !== undefined ) { + + if ( isCustomProp ) { + style.setProperty( name, value ); + } else { + style[ name ] = value; + } + } + + } else { + + // If a hook was provided get the non-computed value from there + if ( hooks && "get" in hooks && + ( ret = hooks.get( elem, false, extra ) ) !== undefined ) { + + return ret; + } + + // Otherwise just get the value from the style object + return style[ name ]; + } + }, + + css: function( elem, name, extra, styles ) { + var val, num, hooks, + origName = camelCase( name ), + isCustomProp = rcustomProp.test( name ); + + // Make sure that we're working with the right name. We don't + // want to modify the value if it is a CSS custom property + // since they are user-defined. + if ( !isCustomProp ) { + name = finalPropName( origName ); + } + + // Try prefixed name followed by the unprefixed name + hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; + + // If a hook was provided get the computed value from there + if ( hooks && "get" in hooks ) { + val = hooks.get( elem, true, extra ); + } + + // Otherwise, if a way to get the computed value exists, use that + if ( val === undefined ) { + val = curCSS( elem, name, styles ); + } + + // Convert "normal" to computed value + if ( val === "normal" && name in cssNormalTransform ) { + val = cssNormalTransform[ name ]; + } + + // Make numeric if forced or a qualifier was provided and val looks numeric + if ( extra === "" || extra ) { + num = parseFloat( val ); + return extra === true || isFinite( num ) ? num || 0 : val; + } + + return val; + } +} ); + +jQuery.each( [ "height", "width" ], function( i, dimension ) { + jQuery.cssHooks[ dimension ] = { + get: function( elem, computed, extra ) { + if ( computed ) { + + // Certain elements can have dimension info if we invisibly show them + // but it must have a current display style that would benefit + return rdisplayswap.test( jQuery.css( elem, "display" ) ) && + + // Support: Safari 8+ + // Table columns in Safari have non-zero offsetWidth & zero + // getBoundingClientRect().width unless display is changed. + // Support: IE <=11 only + // Running getBoundingClientRect on a disconnected node + // in IE throws an error. + ( !elem.getClientRects().length || !elem.getBoundingClientRect().width ) ? + swap( elem, cssShow, function() { + return getWidthOrHeight( elem, dimension, extra ); + } ) : + getWidthOrHeight( elem, dimension, extra ); + } + }, + + set: function( elem, value, extra ) { + var matches, + styles = getStyles( elem ), + + // Only read styles.position if the test has a chance to fail + // to avoid forcing a reflow. + scrollboxSizeBuggy = !support.scrollboxSize() && + styles.position === "absolute", + + // To avoid forcing a reflow, only fetch boxSizing if we need it (gh-3991) + boxSizingNeeded = scrollboxSizeBuggy || extra, + isBorderBox = boxSizingNeeded && + jQuery.css( elem, "boxSizing", false, styles ) === "border-box", + subtract = extra ? + boxModelAdjustment( + elem, + dimension, + extra, + isBorderBox, + styles + ) : + 0; + + // Account for unreliable border-box dimensions by comparing offset* to computed and + // faking a content-box to get border and padding (gh-3699) + if ( isBorderBox && scrollboxSizeBuggy ) { + subtract -= Math.ceil( + elem[ "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ] - + parseFloat( styles[ dimension ] ) - + boxModelAdjustment( elem, dimension, "border", false, styles ) - + 0.5 + ); + } + + // Convert to pixels if value adjustment is needed + if ( subtract && ( matches = rcssNum.exec( value ) ) && + ( matches[ 3 ] || "px" ) !== "px" ) { + + elem.style[ dimension ] = value; + value = jQuery.css( elem, dimension ); + } + + return setPositiveNumber( elem, value, subtract ); + } + }; +} ); + +jQuery.cssHooks.marginLeft = addGetHookIf( support.reliableMarginLeft, + function( elem, computed ) { + if ( computed ) { + return ( parseFloat( curCSS( elem, "marginLeft" ) ) || + elem.getBoundingClientRect().left - + swap( elem, { marginLeft: 0 }, function() { + return elem.getBoundingClientRect().left; + } ) + ) + "px"; + } + } +); + +// These hooks are used by animate to expand properties +jQuery.each( { + margin: "", + padding: "", + border: "Width" +}, function( prefix, suffix ) { + jQuery.cssHooks[ prefix + suffix ] = { + expand: function( value ) { + var i = 0, + expanded = {}, + + // Assumes a single number if not a string + parts = typeof value === "string" ? value.split( " " ) : [ value ]; + + for ( ; i < 4; i++ ) { + expanded[ prefix + cssExpand[ i ] + suffix ] = + parts[ i ] || parts[ i - 2 ] || parts[ 0 ]; + } + + return expanded; + } + }; + + if ( prefix !== "margin" ) { + jQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber; + } +} ); + +jQuery.fn.extend( { + css: function( name, value ) { + return access( this, function( elem, name, value ) { + var styles, len, + map = {}, + i = 0; + + if ( Array.isArray( name ) ) { + styles = getStyles( elem ); + len = name.length; + + for ( ; i < len; i++ ) { + map[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles ); + } + + return map; + } + + return value !== undefined ? + jQuery.style( elem, name, value ) : + jQuery.css( elem, name ); + }, name, value, arguments.length > 1 ); + } +} ); + + +function Tween( elem, options, prop, end, easing ) { + return new Tween.prototype.init( elem, options, prop, end, easing ); +} +jQuery.Tween = Tween; + +Tween.prototype = { + constructor: Tween, + init: function( elem, options, prop, end, easing, unit ) { + this.elem = elem; + this.prop = prop; + this.easing = easing || jQuery.easing._default; + this.options = options; + this.start = this.now = this.cur(); + this.end = end; + this.unit = unit || ( jQuery.cssNumber[ prop ] ? "" : "px" ); + }, + cur: function() { + var hooks = Tween.propHooks[ this.prop ]; + + return hooks && hooks.get ? + hooks.get( this ) : + Tween.propHooks._default.get( this ); + }, + run: function( percent ) { + var eased, + hooks = Tween.propHooks[ this.prop ]; + + if ( this.options.duration ) { + this.pos = eased = jQuery.easing[ this.easing ]( + percent, this.options.duration * percent, 0, 1, this.options.duration + ); + } else { + this.pos = eased = percent; + } + this.now = ( this.end - this.start ) * eased + this.start; + + if ( this.options.step ) { + this.options.step.call( this.elem, this.now, this ); + } + + if ( hooks && hooks.set ) { + hooks.set( this ); + } else { + Tween.propHooks._default.set( this ); + } + return this; + } +}; + +Tween.prototype.init.prototype = Tween.prototype; + +Tween.propHooks = { + _default: { + get: function( tween ) { + var result; + + // Use a property on the element directly when it is not a DOM element, + // or when there is no matching style property that exists. + if ( tween.elem.nodeType !== 1 || + tween.elem[ tween.prop ] != null && tween.elem.style[ tween.prop ] == null ) { + return tween.elem[ tween.prop ]; + } + + // Passing an empty string as a 3rd parameter to .css will automatically + // attempt a parseFloat and fallback to a string if the parse fails. + // Simple values such as "10px" are parsed to Float; + // complex values such as "rotate(1rad)" are returned as-is. + result = jQuery.css( tween.elem, tween.prop, "" ); + + // Empty strings, null, undefined and "auto" are converted to 0. + return !result || result === "auto" ? 0 : result; + }, + set: function( tween ) { + + // Use step hook for back compat. + // Use cssHook if its there. + // Use .style if available and use plain properties where available. + if ( jQuery.fx.step[ tween.prop ] ) { + jQuery.fx.step[ tween.prop ]( tween ); + } else if ( tween.elem.nodeType === 1 && ( + jQuery.cssHooks[ tween.prop ] || + tween.elem.style[ finalPropName( tween.prop ) ] != null ) ) { + jQuery.style( tween.elem, tween.prop, tween.now + tween.unit ); + } else { + tween.elem[ tween.prop ] = tween.now; + } + } + } +}; + +// Support: IE <=9 only +// Panic based approach to setting things on disconnected nodes +Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = { + set: function( tween ) { + if ( tween.elem.nodeType && tween.elem.parentNode ) { + tween.elem[ tween.prop ] = tween.now; + } + } +}; + +jQuery.easing = { + linear: function( p ) { + return p; + }, + swing: function( p ) { + return 0.5 - Math.cos( p * Math.PI ) / 2; + }, + _default: "swing" +}; + +jQuery.fx = Tween.prototype.init; + +// Back compat <1.8 extension point +jQuery.fx.step = {}; + + + + +var + fxNow, inProgress, + rfxtypes = /^(?:toggle|show|hide)$/, + rrun = /queueHooks$/; + +function schedule() { + if ( inProgress ) { + if ( document.hidden === false && window.requestAnimationFrame ) { + window.requestAnimationFrame( schedule ); + } else { + window.setTimeout( schedule, jQuery.fx.interval ); + } + + jQuery.fx.tick(); + } +} + +// Animations created synchronously will run synchronously +function createFxNow() { + window.setTimeout( function() { + fxNow = undefined; + } ); + return ( fxNow = Date.now() ); +} + +// Generate parameters to create a standard animation +function genFx( type, includeWidth ) { + var which, + i = 0, + attrs = { height: type }; + + // If we include width, step value is 1 to do all cssExpand values, + // otherwise step value is 2 to skip over Left and Right + includeWidth = includeWidth ? 1 : 0; + for ( ; i < 4; i += 2 - includeWidth ) { + which = cssExpand[ i ]; + attrs[ "margin" + which ] = attrs[ "padding" + which ] = type; + } + + if ( includeWidth ) { + attrs.opacity = attrs.width = type; + } + + return attrs; +} + +function createTween( value, prop, animation ) { + var tween, + collection = ( Animation.tweeners[ prop ] || [] ).concat( Animation.tweeners[ "*" ] ), + index = 0, + length = collection.length; + for ( ; index < length; index++ ) { + if ( ( tween = collection[ index ].call( animation, prop, value ) ) ) { + + // We're done with this property + return tween; + } + } +} + +function defaultPrefilter( elem, props, opts ) { + var prop, value, toggle, hooks, oldfire, propTween, restoreDisplay, display, + isBox = "width" in props || "height" in props, + anim = this, + orig = {}, + style = elem.style, + hidden = elem.nodeType && isHiddenWithinTree( elem ), + dataShow = dataPriv.get( elem, "fxshow" ); + + // Queue-skipping animations hijack the fx hooks + if ( !opts.queue ) { + hooks = jQuery._queueHooks( elem, "fx" ); + if ( hooks.unqueued == null ) { + hooks.unqueued = 0; + oldfire = hooks.empty.fire; + hooks.empty.fire = function() { + if ( !hooks.unqueued ) { + oldfire(); + } + }; + } + hooks.unqueued++; + + anim.always( function() { + + // Ensure the complete handler is called before this completes + anim.always( function() { + hooks.unqueued--; + if ( !jQuery.queue( elem, "fx" ).length ) { + hooks.empty.fire(); + } + } ); + } ); + } + + // Detect show/hide animations + for ( prop in props ) { + value = props[ prop ]; + if ( rfxtypes.test( value ) ) { + delete props[ prop ]; + toggle = toggle || value === "toggle"; + if ( value === ( hidden ? "hide" : "show" ) ) { + + // Pretend to be hidden if this is a "show" and + // there is still data from a stopped show/hide + if ( value === "show" && dataShow && dataShow[ prop ] !== undefined ) { + hidden = true; + + // Ignore all other no-op show/hide data + } else { + continue; + } + } + orig[ prop ] = dataShow && dataShow[ prop ] || jQuery.style( elem, prop ); + } + } + + // Bail out if this is a no-op like .hide().hide() + propTween = !jQuery.isEmptyObject( props ); + if ( !propTween && jQuery.isEmptyObject( orig ) ) { + return; + } + + // Restrict "overflow" and "display" styles during box animations + if ( isBox && elem.nodeType === 1 ) { + + // Support: IE <=9 - 11, Edge 12 - 15 + // Record all 3 overflow attributes because IE does not infer the shorthand + // from identically-valued overflowX and overflowY and Edge just mirrors + // the overflowX value there. + opts.overflow = [ style.overflow, style.overflowX, style.overflowY ]; + + // Identify a display type, preferring old show/hide data over the CSS cascade + restoreDisplay = dataShow && dataShow.display; + if ( restoreDisplay == null ) { + restoreDisplay = dataPriv.get( elem, "display" ); + } + display = jQuery.css( elem, "display" ); + if ( display === "none" ) { + if ( restoreDisplay ) { + display = restoreDisplay; + } else { + + // Get nonempty value(s) by temporarily forcing visibility + showHide( [ elem ], true ); + restoreDisplay = elem.style.display || restoreDisplay; + display = jQuery.css( elem, "display" ); + showHide( [ elem ] ); + } + } + + // Animate inline elements as inline-block + if ( display === "inline" || display === "inline-block" && restoreDisplay != null ) { + if ( jQuery.css( elem, "float" ) === "none" ) { + + // Restore the original display value at the end of pure show/hide animations + if ( !propTween ) { + anim.done( function() { + style.display = restoreDisplay; + } ); + if ( restoreDisplay == null ) { + display = style.display; + restoreDisplay = display === "none" ? "" : display; + } + } + style.display = "inline-block"; + } + } + } + + if ( opts.overflow ) { + style.overflow = "hidden"; + anim.always( function() { + style.overflow = opts.overflow[ 0 ]; + style.overflowX = opts.overflow[ 1 ]; + style.overflowY = opts.overflow[ 2 ]; + } ); + } + + // Implement show/hide animations + propTween = false; + for ( prop in orig ) { + + // General show/hide setup for this element animation + if ( !propTween ) { + if ( dataShow ) { + if ( "hidden" in dataShow ) { + hidden = dataShow.hidden; + } + } else { + dataShow = dataPriv.access( elem, "fxshow", { display: restoreDisplay } ); + } + + // Store hidden/visible for toggle so `.stop().toggle()` "reverses" + if ( toggle ) { + dataShow.hidden = !hidden; + } + + // Show elements before animating them + if ( hidden ) { + showHide( [ elem ], true ); + } + + /* eslint-disable no-loop-func */ + + anim.done( function() { + + /* eslint-enable no-loop-func */ + + // The final step of a "hide" animation is actually hiding the element + if ( !hidden ) { + showHide( [ elem ] ); + } + dataPriv.remove( elem, "fxshow" ); + for ( prop in orig ) { + jQuery.style( elem, prop, orig[ prop ] ); + } + } ); + } + + // Per-property setup + propTween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim ); + if ( !( prop in dataShow ) ) { + dataShow[ prop ] = propTween.start; + if ( hidden ) { + propTween.end = propTween.start; + propTween.start = 0; + } + } + } +} + +function propFilter( props, specialEasing ) { + var index, name, easing, value, hooks; + + // camelCase, specialEasing and expand cssHook pass + for ( index in props ) { + name = camelCase( index ); + easing = specialEasing[ name ]; + value = props[ index ]; + if ( Array.isArray( value ) ) { + easing = value[ 1 ]; + value = props[ index ] = value[ 0 ]; + } + + if ( index !== name ) { + props[ name ] = value; + delete props[ index ]; + } + + hooks = jQuery.cssHooks[ name ]; + if ( hooks && "expand" in hooks ) { + value = hooks.expand( value ); + delete props[ name ]; + + // Not quite $.extend, this won't overwrite existing keys. + // Reusing 'index' because we have the correct "name" + for ( index in value ) { + if ( !( index in props ) ) { + props[ index ] = value[ index ]; + specialEasing[ index ] = easing; + } + } + } else { + specialEasing[ name ] = easing; + } + } +} + +function Animation( elem, properties, options ) { + var result, + stopped, + index = 0, + length = Animation.prefilters.length, + deferred = jQuery.Deferred().always( function() { + + // Don't match elem in the :animated selector + delete tick.elem; + } ), + tick = function() { + if ( stopped ) { + return false; + } + var currentTime = fxNow || createFxNow(), + remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ), + + // Support: Android 2.3 only + // Archaic crash bug won't allow us to use `1 - ( 0.5 || 0 )` (#12497) + temp = remaining / animation.duration || 0, + percent = 1 - temp, + index = 0, + length = animation.tweens.length; + + for ( ; index < length; index++ ) { + animation.tweens[ index ].run( percent ); + } + + deferred.notifyWith( elem, [ animation, percent, remaining ] ); + + // If there's more to do, yield + if ( percent < 1 && length ) { + return remaining; + } + + // If this was an empty animation, synthesize a final progress notification + if ( !length ) { + deferred.notifyWith( elem, [ animation, 1, 0 ] ); + } + + // Resolve the animation and report its conclusion + deferred.resolveWith( elem, [ animation ] ); + return false; + }, + animation = deferred.promise( { + elem: elem, + props: jQuery.extend( {}, properties ), + opts: jQuery.extend( true, { + specialEasing: {}, + easing: jQuery.easing._default + }, options ), + originalProperties: properties, + originalOptions: options, + startTime: fxNow || createFxNow(), + duration: options.duration, + tweens: [], + createTween: function( prop, end ) { + var tween = jQuery.Tween( elem, animation.opts, prop, end, + animation.opts.specialEasing[ prop ] || animation.opts.easing ); + animation.tweens.push( tween ); + return tween; + }, + stop: function( gotoEnd ) { + var index = 0, + + // If we are going to the end, we want to run all the tweens + // otherwise we skip this part + length = gotoEnd ? animation.tweens.length : 0; + if ( stopped ) { + return this; + } + stopped = true; + for ( ; index < length; index++ ) { + animation.tweens[ index ].run( 1 ); + } + + // Resolve when we played the last frame; otherwise, reject + if ( gotoEnd ) { + deferred.notifyWith( elem, [ animation, 1, 0 ] ); + deferred.resolveWith( elem, [ animation, gotoEnd ] ); + } else { + deferred.rejectWith( elem, [ animation, gotoEnd ] ); + } + return this; + } + } ), + props = animation.props; + + propFilter( props, animation.opts.specialEasing ); + + for ( ; index < length; index++ ) { + result = Animation.prefilters[ index ].call( animation, elem, props, animation.opts ); + if ( result ) { + if ( isFunction( result.stop ) ) { + jQuery._queueHooks( animation.elem, animation.opts.queue ).stop = + result.stop.bind( result ); + } + return result; + } + } + + jQuery.map( props, createTween, animation ); + + if ( isFunction( animation.opts.start ) ) { + animation.opts.start.call( elem, animation ); + } + + // Attach callbacks from options + animation + .progress( animation.opts.progress ) + .done( animation.opts.done, animation.opts.complete ) + .fail( animation.opts.fail ) + .always( animation.opts.always ); + + jQuery.fx.timer( + jQuery.extend( tick, { + elem: elem, + anim: animation, + queue: animation.opts.queue + } ) + ); + + return animation; +} + +jQuery.Animation = jQuery.extend( Animation, { + + tweeners: { + "*": [ function( prop, value ) { + var tween = this.createTween( prop, value ); + adjustCSS( tween.elem, prop, rcssNum.exec( value ), tween ); + return tween; + } ] + }, + + tweener: function( props, callback ) { + if ( isFunction( props ) ) { + callback = props; + props = [ "*" ]; + } else { + props = props.match( rnothtmlwhite ); + } + + var prop, + index = 0, + length = props.length; + + for ( ; index < length; index++ ) { + prop = props[ index ]; + Animation.tweeners[ prop ] = Animation.tweeners[ prop ] || []; + Animation.tweeners[ prop ].unshift( callback ); + } + }, + + prefilters: [ defaultPrefilter ], + + prefilter: function( callback, prepend ) { + if ( prepend ) { + Animation.prefilters.unshift( callback ); + } else { + Animation.prefilters.push( callback ); + } + } +} ); + +jQuery.speed = function( speed, easing, fn ) { + var opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed ) : { + complete: fn || !fn && easing || + isFunction( speed ) && speed, + duration: speed, + easing: fn && easing || easing && !isFunction( easing ) && easing + }; + + // Go to the end state if fx are off + if ( jQuery.fx.off ) { + opt.duration = 0; + + } else { + if ( typeof opt.duration !== "number" ) { + if ( opt.duration in jQuery.fx.speeds ) { + opt.duration = jQuery.fx.speeds[ opt.duration ]; + + } else { + opt.duration = jQuery.fx.speeds._default; + } + } + } + + // Normalize opt.queue - true/undefined/null -> "fx" + if ( opt.queue == null || opt.queue === true ) { + opt.queue = "fx"; + } + + // Queueing + opt.old = opt.complete; + + opt.complete = function() { + if ( isFunction( opt.old ) ) { + opt.old.call( this ); + } + + if ( opt.queue ) { + jQuery.dequeue( this, opt.queue ); + } + }; + + return opt; +}; + +jQuery.fn.extend( { + fadeTo: function( speed, to, easing, callback ) { + + // Show any hidden elements after setting opacity to 0 + return this.filter( isHiddenWithinTree ).css( "opacity", 0 ).show() + + // Animate to the value specified + .end().animate( { opacity: to }, speed, easing, callback ); + }, + animate: function( prop, speed, easing, callback ) { + var empty = jQuery.isEmptyObject( prop ), + optall = jQuery.speed( speed, easing, callback ), + doAnimation = function() { + + // Operate on a copy of prop so per-property easing won't be lost + var anim = Animation( this, jQuery.extend( {}, prop ), optall ); + + // Empty animations, or finishing resolves immediately + if ( empty || dataPriv.get( this, "finish" ) ) { + anim.stop( true ); + } + }; + doAnimation.finish = doAnimation; + + return empty || optall.queue === false ? + this.each( doAnimation ) : + this.queue( optall.queue, doAnimation ); + }, + stop: function( type, clearQueue, gotoEnd ) { + var stopQueue = function( hooks ) { + var stop = hooks.stop; + delete hooks.stop; + stop( gotoEnd ); + }; + + if ( typeof type !== "string" ) { + gotoEnd = clearQueue; + clearQueue = type; + type = undefined; + } + if ( clearQueue && type !== false ) { + this.queue( type || "fx", [] ); + } + + return this.each( function() { + var dequeue = true, + index = type != null && type + "queueHooks", + timers = jQuery.timers, + data = dataPriv.get( this ); + + if ( index ) { + if ( data[ index ] && data[ index ].stop ) { + stopQueue( data[ index ] ); + } + } else { + for ( index in data ) { + if ( data[ index ] && data[ index ].stop && rrun.test( index ) ) { + stopQueue( data[ index ] ); + } + } + } + + for ( index = timers.length; index--; ) { + if ( timers[ index ].elem === this && + ( type == null || timers[ index ].queue === type ) ) { + + timers[ index ].anim.stop( gotoEnd ); + dequeue = false; + timers.splice( index, 1 ); + } + } + + // Start the next in the queue if the last step wasn't forced. + // Timers currently will call their complete callbacks, which + // will dequeue but only if they were gotoEnd. + if ( dequeue || !gotoEnd ) { + jQuery.dequeue( this, type ); + } + } ); + }, + finish: function( type ) { + if ( type !== false ) { + type = type || "fx"; + } + return this.each( function() { + var index, + data = dataPriv.get( this ), + queue = data[ type + "queue" ], + hooks = data[ type + "queueHooks" ], + timers = jQuery.timers, + length = queue ? queue.length : 0; + + // Enable finishing flag on private data + data.finish = true; + + // Empty the queue first + jQuery.queue( this, type, [] ); + + if ( hooks && hooks.stop ) { + hooks.stop.call( this, true ); + } + + // Look for any active animations, and finish them + for ( index = timers.length; index--; ) { + if ( timers[ index ].elem === this && timers[ index ].queue === type ) { + timers[ index ].anim.stop( true ); + timers.splice( index, 1 ); + } + } + + // Look for any animations in the old queue and finish them + for ( index = 0; index < length; index++ ) { + if ( queue[ index ] && queue[ index ].finish ) { + queue[ index ].finish.call( this ); + } + } + + // Turn off finishing flag + delete data.finish; + } ); + } +} ); + +jQuery.each( [ "toggle", "show", "hide" ], function( i, name ) { + var cssFn = jQuery.fn[ name ]; + jQuery.fn[ name ] = function( speed, easing, callback ) { + return speed == null || typeof speed === "boolean" ? + cssFn.apply( this, arguments ) : + this.animate( genFx( name, true ), speed, easing, callback ); + }; +} ); + +// Generate shortcuts for custom animations +jQuery.each( { + slideDown: genFx( "show" ), + slideUp: genFx( "hide" ), + slideToggle: genFx( "toggle" ), + fadeIn: { opacity: "show" }, + fadeOut: { opacity: "hide" }, + fadeToggle: { opacity: "toggle" } +}, function( name, props ) { + jQuery.fn[ name ] = function( speed, easing, callback ) { + return this.animate( props, speed, easing, callback ); + }; +} ); + +jQuery.timers = []; +jQuery.fx.tick = function() { + var timer, + i = 0, + timers = jQuery.timers; + + fxNow = Date.now(); + + for ( ; i < timers.length; i++ ) { + timer = timers[ i ]; + + // Run the timer and safely remove it when done (allowing for external removal) + if ( !timer() && timers[ i ] === timer ) { + timers.splice( i--, 1 ); + } + } + + if ( !timers.length ) { + jQuery.fx.stop(); + } + fxNow = undefined; +}; + +jQuery.fx.timer = function( timer ) { + jQuery.timers.push( timer ); + jQuery.fx.start(); +}; + +jQuery.fx.interval = 13; +jQuery.fx.start = function() { + if ( inProgress ) { + return; + } + + inProgress = true; + schedule(); +}; + +jQuery.fx.stop = function() { + inProgress = null; +}; + +jQuery.fx.speeds = { + slow: 600, + fast: 200, + + // Default speed + _default: 400 +}; + + +// Based off of the plugin by Clint Helfers, with permission. +// https://web.archive.org/web/20100324014747/http://blindsignals.com/index.php/2009/07/jquery-delay/ +jQuery.fn.delay = function( time, type ) { + time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time; + type = type || "fx"; + + return this.queue( type, function( next, hooks ) { + var timeout = window.setTimeout( next, time ); + hooks.stop = function() { + window.clearTimeout( timeout ); + }; + } ); +}; + + +( function() { + var input = document.createElement( "input" ), + select = document.createElement( "select" ), + opt = select.appendChild( document.createElement( "option" ) ); + + input.type = "checkbox"; + + // Support: Android <=4.3 only + // Default value for a checkbox should be "on" + support.checkOn = input.value !== ""; + + // Support: IE <=11 only + // Must access selectedIndex to make default options select + support.optSelected = opt.selected; + + // Support: IE <=11 only + // An input loses its value after becoming a radio + input = document.createElement( "input" ); + input.value = "t"; + input.type = "radio"; + support.radioValue = input.value === "t"; +} )(); + + +var boolHook, + attrHandle = jQuery.expr.attrHandle; + +jQuery.fn.extend( { + attr: function( name, value ) { + return access( this, jQuery.attr, name, value, arguments.length > 1 ); + }, + + removeAttr: function( name ) { + return this.each( function() { + jQuery.removeAttr( this, name ); + } ); + } +} ); + +jQuery.extend( { + attr: function( elem, name, value ) { + var ret, hooks, + nType = elem.nodeType; + + // Don't get/set attributes on text, comment and attribute nodes + if ( nType === 3 || nType === 8 || nType === 2 ) { + return; + } + + // Fallback to prop when attributes are not supported + if ( typeof elem.getAttribute === "undefined" ) { + return jQuery.prop( elem, name, value ); + } + + // Attribute hooks are determined by the lowercase version + // Grab necessary hook if one is defined + if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) { + hooks = jQuery.attrHooks[ name.toLowerCase() ] || + ( jQuery.expr.match.bool.test( name ) ? boolHook : undefined ); + } + + if ( value !== undefined ) { + if ( value === null ) { + jQuery.removeAttr( elem, name ); + return; + } + + if ( hooks && "set" in hooks && + ( ret = hooks.set( elem, value, name ) ) !== undefined ) { + return ret; + } + + elem.setAttribute( name, value + "" ); + return value; + } + + if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) { + return ret; + } + + ret = jQuery.find.attr( elem, name ); + + // Non-existent attributes return null, we normalize to undefined + return ret == null ? undefined : ret; + }, + + attrHooks: { + type: { + set: function( elem, value ) { + if ( !support.radioValue && value === "radio" && + nodeName( elem, "input" ) ) { + var val = elem.value; + elem.setAttribute( "type", value ); + if ( val ) { + elem.value = val; + } + return value; + } + } + } + }, + + removeAttr: function( elem, value ) { + var name, + i = 0, + + // Attribute names can contain non-HTML whitespace characters + // https://html.spec.whatwg.org/multipage/syntax.html#attributes-2 + attrNames = value && value.match( rnothtmlwhite ); + + if ( attrNames && elem.nodeType === 1 ) { + while ( ( name = attrNames[ i++ ] ) ) { + elem.removeAttribute( name ); + } + } + } +} ); + +// Hooks for boolean attributes +boolHook = { + set: function( elem, value, name ) { + if ( value === false ) { + + // Remove boolean attributes when set to false + jQuery.removeAttr( elem, name ); + } else { + elem.setAttribute( name, name ); + } + return name; + } +}; + +jQuery.each( jQuery.expr.match.bool.source.match( /\w+/g ), function( i, name ) { + var getter = attrHandle[ name ] || jQuery.find.attr; + + attrHandle[ name ] = function( elem, name, isXML ) { + var ret, handle, + lowercaseName = name.toLowerCase(); + + if ( !isXML ) { + + // Avoid an infinite loop by temporarily removing this function from the getter + handle = attrHandle[ lowercaseName ]; + attrHandle[ lowercaseName ] = ret; + ret = getter( elem, name, isXML ) != null ? + lowercaseName : + null; + attrHandle[ lowercaseName ] = handle; + } + return ret; + }; +} ); + + + + +var rfocusable = /^(?:input|select|textarea|button)$/i, + rclickable = /^(?:a|area)$/i; + +jQuery.fn.extend( { + prop: function( name, value ) { + return access( this, jQuery.prop, name, value, arguments.length > 1 ); + }, + + removeProp: function( name ) { + return this.each( function() { + delete this[ jQuery.propFix[ name ] || name ]; + } ); + } +} ); + +jQuery.extend( { + prop: function( elem, name, value ) { + var ret, hooks, + nType = elem.nodeType; + + // Don't get/set properties on text, comment and attribute nodes + if ( nType === 3 || nType === 8 || nType === 2 ) { + return; + } + + if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) { + + // Fix name and attach hooks + name = jQuery.propFix[ name ] || name; + hooks = jQuery.propHooks[ name ]; + } + + if ( value !== undefined ) { + if ( hooks && "set" in hooks && + ( ret = hooks.set( elem, value, name ) ) !== undefined ) { + return ret; + } + + return ( elem[ name ] = value ); + } + + if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) { + return ret; + } + + return elem[ name ]; + }, + + propHooks: { + tabIndex: { + get: function( elem ) { + + // Support: IE <=9 - 11 only + // elem.tabIndex doesn't always return the + // correct value when it hasn't been explicitly set + // https://web.archive.org/web/20141116233347/http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/ + // Use proper attribute retrieval(#12072) + var tabindex = jQuery.find.attr( elem, "tabindex" ); + + if ( tabindex ) { + return parseInt( tabindex, 10 ); + } + + if ( + rfocusable.test( elem.nodeName ) || + rclickable.test( elem.nodeName ) && + elem.href + ) { + return 0; + } + + return -1; + } + } + }, + + propFix: { + "for": "htmlFor", + "class": "className" + } +} ); + +// Support: IE <=11 only +// Accessing the selectedIndex property +// forces the browser to respect setting selected +// on the option +// The getter ensures a default option is selected +// when in an optgroup +// eslint rule "no-unused-expressions" is disabled for this code +// since it considers such accessions noop +if ( !support.optSelected ) { + jQuery.propHooks.selected = { + get: function( elem ) { + + /* eslint no-unused-expressions: "off" */ + + var parent = elem.parentNode; + if ( parent && parent.parentNode ) { + parent.parentNode.selectedIndex; + } + return null; + }, + set: function( elem ) { + + /* eslint no-unused-expressions: "off" */ + + var parent = elem.parentNode; + if ( parent ) { + parent.selectedIndex; + + if ( parent.parentNode ) { + parent.parentNode.selectedIndex; + } + } + } + }; +} + +jQuery.each( [ + "tabIndex", + "readOnly", + "maxLength", + "cellSpacing", + "cellPadding", + "rowSpan", + "colSpan", + "useMap", + "frameBorder", + "contentEditable" +], function() { + jQuery.propFix[ this.toLowerCase() ] = this; +} ); + + + + + // Strip and collapse whitespace according to HTML spec + // https://infra.spec.whatwg.org/#strip-and-collapse-ascii-whitespace + function stripAndCollapse( value ) { + var tokens = value.match( rnothtmlwhite ) || []; + return tokens.join( " " ); + } + + +function getClass( elem ) { + return elem.getAttribute && elem.getAttribute( "class" ) || ""; +} + +function classesToArray( value ) { + if ( Array.isArray( value ) ) { + return value; + } + if ( typeof value === "string" ) { + return value.match( rnothtmlwhite ) || []; + } + return []; +} + +jQuery.fn.extend( { + addClass: function( value ) { + var classes, elem, cur, curValue, clazz, j, finalValue, + i = 0; + + if ( isFunction( value ) ) { + return this.each( function( j ) { + jQuery( this ).addClass( value.call( this, j, getClass( this ) ) ); + } ); + } + + classes = classesToArray( value ); + + if ( classes.length ) { + while ( ( elem = this[ i++ ] ) ) { + curValue = getClass( elem ); + cur = elem.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " ); + + if ( cur ) { + j = 0; + while ( ( clazz = classes[ j++ ] ) ) { + if ( cur.indexOf( " " + clazz + " " ) < 0 ) { + cur += clazz + " "; + } + } + + // Only assign if different to avoid unneeded rendering. + finalValue = stripAndCollapse( cur ); + if ( curValue !== finalValue ) { + elem.setAttribute( "class", finalValue ); + } + } + } + } + + return this; + }, + + removeClass: function( value ) { + var classes, elem, cur, curValue, clazz, j, finalValue, + i = 0; + + if ( isFunction( value ) ) { + return this.each( function( j ) { + jQuery( this ).removeClass( value.call( this, j, getClass( this ) ) ); + } ); + } + + if ( !arguments.length ) { + return this.attr( "class", "" ); + } + + classes = classesToArray( value ); + + if ( classes.length ) { + while ( ( elem = this[ i++ ] ) ) { + curValue = getClass( elem ); + + // This expression is here for better compressibility (see addClass) + cur = elem.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " ); + + if ( cur ) { + j = 0; + while ( ( clazz = classes[ j++ ] ) ) { + + // Remove *all* instances + while ( cur.indexOf( " " + clazz + " " ) > -1 ) { + cur = cur.replace( " " + clazz + " ", " " ); + } + } + + // Only assign if different to avoid unneeded rendering. + finalValue = stripAndCollapse( cur ); + if ( curValue !== finalValue ) { + elem.setAttribute( "class", finalValue ); + } + } + } + } + + return this; + }, + + toggleClass: function( value, stateVal ) { + var type = typeof value, + isValidValue = type === "string" || Array.isArray( value ); + + if ( typeof stateVal === "boolean" && isValidValue ) { + return stateVal ? this.addClass( value ) : this.removeClass( value ); + } + + if ( isFunction( value ) ) { + return this.each( function( i ) { + jQuery( this ).toggleClass( + value.call( this, i, getClass( this ), stateVal ), + stateVal + ); + } ); + } + + return this.each( function() { + var className, i, self, classNames; + + if ( isValidValue ) { + + // Toggle individual class names + i = 0; + self = jQuery( this ); + classNames = classesToArray( value ); + + while ( ( className = classNames[ i++ ] ) ) { + + // Check each className given, space separated list + if ( self.hasClass( className ) ) { + self.removeClass( className ); + } else { + self.addClass( className ); + } + } + + // Toggle whole class name + } else if ( value === undefined || type === "boolean" ) { + className = getClass( this ); + if ( className ) { + + // Store className if set + dataPriv.set( this, "__className__", className ); + } + + // If the element has a class name or if we're passed `false`, + // then remove the whole classname (if there was one, the above saved it). + // Otherwise bring back whatever was previously saved (if anything), + // falling back to the empty string if nothing was stored. + if ( this.setAttribute ) { + this.setAttribute( "class", + className || value === false ? + "" : + dataPriv.get( this, "__className__" ) || "" + ); + } + } + } ); + }, + + hasClass: function( selector ) { + var className, elem, + i = 0; + + className = " " + selector + " "; + while ( ( elem = this[ i++ ] ) ) { + if ( elem.nodeType === 1 && + ( " " + stripAndCollapse( getClass( elem ) ) + " " ).indexOf( className ) > -1 ) { + return true; + } + } + + return false; + } +} ); + + + + +var rreturn = /\r/g; + +jQuery.fn.extend( { + val: function( value ) { + var hooks, ret, valueIsFunction, + elem = this[ 0 ]; + + if ( !arguments.length ) { + if ( elem ) { + hooks = jQuery.valHooks[ elem.type ] || + jQuery.valHooks[ elem.nodeName.toLowerCase() ]; + + if ( hooks && + "get" in hooks && + ( ret = hooks.get( elem, "value" ) ) !== undefined + ) { + return ret; + } + + ret = elem.value; + + // Handle most common string cases + if ( typeof ret === "string" ) { + return ret.replace( rreturn, "" ); + } + + // Handle cases where value is null/undef or number + return ret == null ? "" : ret; + } + + return; + } + + valueIsFunction = isFunction( value ); + + return this.each( function( i ) { + var val; + + if ( this.nodeType !== 1 ) { + return; + } + + if ( valueIsFunction ) { + val = value.call( this, i, jQuery( this ).val() ); + } else { + val = value; + } + + // Treat null/undefined as ""; convert numbers to string + if ( val == null ) { + val = ""; + + } else if ( typeof val === "number" ) { + val += ""; + + } else if ( Array.isArray( val ) ) { + val = jQuery.map( val, function( value ) { + return value == null ? "" : value + ""; + } ); + } + + hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ]; + + // If set returns undefined, fall back to normal setting + if ( !hooks || !( "set" in hooks ) || hooks.set( this, val, "value" ) === undefined ) { + this.value = val; + } + } ); + } +} ); + +jQuery.extend( { + valHooks: { + option: { + get: function( elem ) { + + var val = jQuery.find.attr( elem, "value" ); + return val != null ? + val : + + // Support: IE <=10 - 11 only + // option.text throws exceptions (#14686, #14858) + // Strip and collapse whitespace + // https://html.spec.whatwg.org/#strip-and-collapse-whitespace + stripAndCollapse( jQuery.text( elem ) ); + } + }, + select: { + get: function( elem ) { + var value, option, i, + options = elem.options, + index = elem.selectedIndex, + one = elem.type === "select-one", + values = one ? null : [], + max = one ? index + 1 : options.length; + + if ( index < 0 ) { + i = max; + + } else { + i = one ? index : 0; + } + + // Loop through all the selected options + for ( ; i < max; i++ ) { + option = options[ i ]; + + // Support: IE <=9 only + // IE8-9 doesn't update selected after form reset (#2551) + if ( ( option.selected || i === index ) && + + // Don't return options that are disabled or in a disabled optgroup + !option.disabled && + ( !option.parentNode.disabled || + !nodeName( option.parentNode, "optgroup" ) ) ) { + + // Get the specific value for the option + value = jQuery( option ).val(); + + // We don't need an array for one selects + if ( one ) { + return value; + } + + // Multi-Selects return an array + values.push( value ); + } + } + + return values; + }, + + set: function( elem, value ) { + var optionSet, option, + options = elem.options, + values = jQuery.makeArray( value ), + i = options.length; + + while ( i-- ) { + option = options[ i ]; + + /* eslint-disable no-cond-assign */ + + if ( option.selected = + jQuery.inArray( jQuery.valHooks.option.get( option ), values ) > -1 + ) { + optionSet = true; + } + + /* eslint-enable no-cond-assign */ + } + + // Force browsers to behave consistently when non-matching value is set + if ( !optionSet ) { + elem.selectedIndex = -1; + } + return values; + } + } + } +} ); + +// Radios and checkboxes getter/setter +jQuery.each( [ "radio", "checkbox" ], function() { + jQuery.valHooks[ this ] = { + set: function( elem, value ) { + if ( Array.isArray( value ) ) { + return ( elem.checked = jQuery.inArray( jQuery( elem ).val(), value ) > -1 ); + } + } + }; + if ( !support.checkOn ) { + jQuery.valHooks[ this ].get = function( elem ) { + return elem.getAttribute( "value" ) === null ? "on" : elem.value; + }; + } +} ); + + + + +// Return jQuery for attributes-only inclusion + + +support.focusin = "onfocusin" in window; + + +var rfocusMorph = /^(?:focusinfocus|focusoutblur)$/, + stopPropagationCallback = function( e ) { + e.stopPropagation(); + }; + +jQuery.extend( jQuery.event, { + + trigger: function( event, data, elem, onlyHandlers ) { + + var i, cur, tmp, bubbleType, ontype, handle, special, lastElement, + eventPath = [ elem || document ], + type = hasOwn.call( event, "type" ) ? event.type : event, + namespaces = hasOwn.call( event, "namespace" ) ? event.namespace.split( "." ) : []; + + cur = lastElement = tmp = elem = elem || document; + + // Don't do events on text and comment nodes + if ( elem.nodeType === 3 || elem.nodeType === 8 ) { + return; + } + + // focus/blur morphs to focusin/out; ensure we're not firing them right now + if ( rfocusMorph.test( type + jQuery.event.triggered ) ) { + return; + } + + if ( type.indexOf( "." ) > -1 ) { + + // Namespaced trigger; create a regexp to match event type in handle() + namespaces = type.split( "." ); + type = namespaces.shift(); + namespaces.sort(); + } + ontype = type.indexOf( ":" ) < 0 && "on" + type; + + // Caller can pass in a jQuery.Event object, Object, or just an event type string + event = event[ jQuery.expando ] ? + event : + new jQuery.Event( type, typeof event === "object" && event ); + + // Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true) + event.isTrigger = onlyHandlers ? 2 : 3; + event.namespace = namespaces.join( "." ); + event.rnamespace = event.namespace ? + new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" ) : + null; + + // Clean up the event in case it is being reused + event.result = undefined; + if ( !event.target ) { + event.target = elem; + } + + // Clone any incoming data and prepend the event, creating the handler arg list + data = data == null ? + [ event ] : + jQuery.makeArray( data, [ event ] ); + + // Allow special events to draw outside the lines + special = jQuery.event.special[ type ] || {}; + if ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) { + return; + } + + // Determine event propagation path in advance, per W3C events spec (#9951) + // Bubble up to document, then to window; watch for a global ownerDocument var (#9724) + if ( !onlyHandlers && !special.noBubble && !isWindow( elem ) ) { + + bubbleType = special.delegateType || type; + if ( !rfocusMorph.test( bubbleType + type ) ) { + cur = cur.parentNode; + } + for ( ; cur; cur = cur.parentNode ) { + eventPath.push( cur ); + tmp = cur; + } + + // Only add window if we got to document (e.g., not plain obj or detached DOM) + if ( tmp === ( elem.ownerDocument || document ) ) { + eventPath.push( tmp.defaultView || tmp.parentWindow || window ); + } + } + + // Fire handlers on the event path + i = 0; + while ( ( cur = eventPath[ i++ ] ) && !event.isPropagationStopped() ) { + lastElement = cur; + event.type = i > 1 ? + bubbleType : + special.bindType || type; + + // jQuery handler + handle = ( dataPriv.get( cur, "events" ) || {} )[ event.type ] && + dataPriv.get( cur, "handle" ); + if ( handle ) { + handle.apply( cur, data ); + } + + // Native handler + handle = ontype && cur[ ontype ]; + if ( handle && handle.apply && acceptData( cur ) ) { + event.result = handle.apply( cur, data ); + if ( event.result === false ) { + event.preventDefault(); + } + } + } + event.type = type; + + // If nobody prevented the default action, do it now + if ( !onlyHandlers && !event.isDefaultPrevented() ) { + + if ( ( !special._default || + special._default.apply( eventPath.pop(), data ) === false ) && + acceptData( elem ) ) { + + // Call a native DOM method on the target with the same name as the event. + // Don't do default actions on window, that's where global variables be (#6170) + if ( ontype && isFunction( elem[ type ] ) && !isWindow( elem ) ) { + + // Don't re-trigger an onFOO event when we call its FOO() method + tmp = elem[ ontype ]; + + if ( tmp ) { + elem[ ontype ] = null; + } + + // Prevent re-triggering of the same event, since we already bubbled it above + jQuery.event.triggered = type; + + if ( event.isPropagationStopped() ) { + lastElement.addEventListener( type, stopPropagationCallback ); + } + + elem[ type ](); + + if ( event.isPropagationStopped() ) { + lastElement.removeEventListener( type, stopPropagationCallback ); + } + + jQuery.event.triggered = undefined; + + if ( tmp ) { + elem[ ontype ] = tmp; + } + } + } + } + + return event.result; + }, + + // Piggyback on a donor event to simulate a different one + // Used only for `focus(in | out)` events + simulate: function( type, elem, event ) { + var e = jQuery.extend( + new jQuery.Event(), + event, + { + type: type, + isSimulated: true + } + ); + + jQuery.event.trigger( e, null, elem ); + } + +} ); + +jQuery.fn.extend( { + + trigger: function( type, data ) { + return this.each( function() { + jQuery.event.trigger( type, data, this ); + } ); + }, + triggerHandler: function( type, data ) { + var elem = this[ 0 ]; + if ( elem ) { + return jQuery.event.trigger( type, data, elem, true ); + } + } +} ); + + +// Support: Firefox <=44 +// Firefox doesn't have focus(in | out) events +// Related ticket - https://bugzilla.mozilla.org/show_bug.cgi?id=687787 +// +// Support: Chrome <=48 - 49, Safari <=9.0 - 9.1 +// focus(in | out) events fire after focus & blur events, +// which is spec violation - http://www.w3.org/TR/DOM-Level-3-Events/#events-focusevent-event-order +// Related ticket - https://bugs.chromium.org/p/chromium/issues/detail?id=449857 +if ( !support.focusin ) { + jQuery.each( { focus: "focusin", blur: "focusout" }, function( orig, fix ) { + + // Attach a single capturing handler on the document while someone wants focusin/focusout + var handler = function( event ) { + jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ) ); + }; + + jQuery.event.special[ fix ] = { + setup: function() { + var doc = this.ownerDocument || this, + attaches = dataPriv.access( doc, fix ); + + if ( !attaches ) { + doc.addEventListener( orig, handler, true ); + } + dataPriv.access( doc, fix, ( attaches || 0 ) + 1 ); + }, + teardown: function() { + var doc = this.ownerDocument || this, + attaches = dataPriv.access( doc, fix ) - 1; + + if ( !attaches ) { + doc.removeEventListener( orig, handler, true ); + dataPriv.remove( doc, fix ); + + } else { + dataPriv.access( doc, fix, attaches ); + } + } + }; + } ); +} +var location = window.location; + +var nonce = Date.now(); + +var rquery = ( /\?/ ); + + + +// Cross-browser xml parsing +jQuery.parseXML = function( data ) { + var xml; + if ( !data || typeof data !== "string" ) { + return null; + } + + // Support: IE 9 - 11 only + // IE throws on parseFromString with invalid input. + try { + xml = ( new window.DOMParser() ).parseFromString( data, "text/xml" ); + } catch ( e ) { + xml = undefined; + } + + if ( !xml || xml.getElementsByTagName( "parsererror" ).length ) { + jQuery.error( "Invalid XML: " + data ); + } + return xml; +}; + + +var + rbracket = /\[\]$/, + rCRLF = /\r?\n/g, + rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i, + rsubmittable = /^(?:input|select|textarea|keygen)/i; + +function buildParams( prefix, obj, traditional, add ) { + var name; + + if ( Array.isArray( obj ) ) { + + // Serialize array item. + jQuery.each( obj, function( i, v ) { + if ( traditional || rbracket.test( prefix ) ) { + + // Treat each array item as a scalar. + add( prefix, v ); + + } else { + + // Item is non-scalar (array or object), encode its numeric index. + buildParams( + prefix + "[" + ( typeof v === "object" && v != null ? i : "" ) + "]", + v, + traditional, + add + ); + } + } ); + + } else if ( !traditional && toType( obj ) === "object" ) { + + // Serialize object item. + for ( name in obj ) { + buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add ); + } + + } else { + + // Serialize scalar item. + add( prefix, obj ); + } +} + +// Serialize an array of form elements or a set of +// key/values into a query string +jQuery.param = function( a, traditional ) { + var prefix, + s = [], + add = function( key, valueOrFunction ) { + + // If value is a function, invoke it and use its return value + var value = isFunction( valueOrFunction ) ? + valueOrFunction() : + valueOrFunction; + + s[ s.length ] = encodeURIComponent( key ) + "=" + + encodeURIComponent( value == null ? "" : value ); + }; + + if ( a == null ) { + return ""; + } + + // If an array was passed in, assume that it is an array of form elements. + if ( Array.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) { + + // Serialize the form elements + jQuery.each( a, function() { + add( this.name, this.value ); + } ); + + } else { + + // If traditional, encode the "old" way (the way 1.3.2 or older + // did it), otherwise encode params recursively. + for ( prefix in a ) { + buildParams( prefix, a[ prefix ], traditional, add ); + } + } + + // Return the resulting serialization + return s.join( "&" ); +}; + +jQuery.fn.extend( { + serialize: function() { + return jQuery.param( this.serializeArray() ); + }, + serializeArray: function() { + return this.map( function() { + + // Can add propHook for "elements" to filter or add form elements + var elements = jQuery.prop( this, "elements" ); + return elements ? jQuery.makeArray( elements ) : this; + } ) + .filter( function() { + var type = this.type; + + // Use .is( ":disabled" ) so that fieldset[disabled] works + return this.name && !jQuery( this ).is( ":disabled" ) && + rsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) && + ( this.checked || !rcheckableType.test( type ) ); + } ) + .map( function( i, elem ) { + var val = jQuery( this ).val(); + + if ( val == null ) { + return null; + } + + if ( Array.isArray( val ) ) { + return jQuery.map( val, function( val ) { + return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) }; + } ); + } + + return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) }; + } ).get(); + } +} ); + + +var + r20 = /%20/g, + rhash = /#.*$/, + rantiCache = /([?&])_=[^&]*/, + rheaders = /^(.*?):[ \t]*([^\r\n]*)$/mg, + + // #7653, #8125, #8152: local protocol detection + rlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/, + rnoContent = /^(?:GET|HEAD)$/, + rprotocol = /^\/\//, + + /* Prefilters + * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example) + * 2) These are called: + * - BEFORE asking for a transport + * - AFTER param serialization (s.data is a string if s.processData is true) + * 3) key is the dataType + * 4) the catchall symbol "*" can be used + * 5) execution will start with transport dataType and THEN continue down to "*" if needed + */ + prefilters = {}, + + /* Transports bindings + * 1) key is the dataType + * 2) the catchall symbol "*" can be used + * 3) selection will start with transport dataType and THEN go to "*" if needed + */ + transports = {}, + + // Avoid comment-prolog char sequence (#10098); must appease lint and evade compression + allTypes = "*/".concat( "*" ), + + // Anchor tag for parsing the document origin + originAnchor = document.createElement( "a" ); + originAnchor.href = location.href; + +// Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport +function addToPrefiltersOrTransports( structure ) { + + // dataTypeExpression is optional and defaults to "*" + return function( dataTypeExpression, func ) { + + if ( typeof dataTypeExpression !== "string" ) { + func = dataTypeExpression; + dataTypeExpression = "*"; + } + + var dataType, + i = 0, + dataTypes = dataTypeExpression.toLowerCase().match( rnothtmlwhite ) || []; + + if ( isFunction( func ) ) { + + // For each dataType in the dataTypeExpression + while ( ( dataType = dataTypes[ i++ ] ) ) { + + // Prepend if requested + if ( dataType[ 0 ] === "+" ) { + dataType = dataType.slice( 1 ) || "*"; + ( structure[ dataType ] = structure[ dataType ] || [] ).unshift( func ); + + // Otherwise append + } else { + ( structure[ dataType ] = structure[ dataType ] || [] ).push( func ); + } + } + } + }; +} + +// Base inspection function for prefilters and transports +function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR ) { + + var inspected = {}, + seekingTransport = ( structure === transports ); + + function inspect( dataType ) { + var selected; + inspected[ dataType ] = true; + jQuery.each( structure[ dataType ] || [], function( _, prefilterOrFactory ) { + var dataTypeOrTransport = prefilterOrFactory( options, originalOptions, jqXHR ); + if ( typeof dataTypeOrTransport === "string" && + !seekingTransport && !inspected[ dataTypeOrTransport ] ) { + + options.dataTypes.unshift( dataTypeOrTransport ); + inspect( dataTypeOrTransport ); + return false; + } else if ( seekingTransport ) { + return !( selected = dataTypeOrTransport ); + } + } ); + return selected; + } + + return inspect( options.dataTypes[ 0 ] ) || !inspected[ "*" ] && inspect( "*" ); +} + +// A special extend for ajax options +// that takes "flat" options (not to be deep extended) +// Fixes #9887 +function ajaxExtend( target, src ) { + var key, deep, + flatOptions = jQuery.ajaxSettings.flatOptions || {}; + + for ( key in src ) { + if ( src[ key ] !== undefined ) { + ( flatOptions[ key ] ? target : ( deep || ( deep = {} ) ) )[ key ] = src[ key ]; + } + } + if ( deep ) { + jQuery.extend( true, target, deep ); + } + + return target; +} + +/* Handles responses to an ajax request: + * - finds the right dataType (mediates between content-type and expected dataType) + * - returns the corresponding response + */ +function ajaxHandleResponses( s, jqXHR, responses ) { + + var ct, type, finalDataType, firstDataType, + contents = s.contents, + dataTypes = s.dataTypes; + + // Remove auto dataType and get content-type in the process + while ( dataTypes[ 0 ] === "*" ) { + dataTypes.shift(); + if ( ct === undefined ) { + ct = s.mimeType || jqXHR.getResponseHeader( "Content-Type" ); + } + } + + // Check if we're dealing with a known content-type + if ( ct ) { + for ( type in contents ) { + if ( contents[ type ] && contents[ type ].test( ct ) ) { + dataTypes.unshift( type ); + break; + } + } + } + + // Check to see if we have a response for the expected dataType + if ( dataTypes[ 0 ] in responses ) { + finalDataType = dataTypes[ 0 ]; + } else { + + // Try convertible dataTypes + for ( type in responses ) { + if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[ 0 ] ] ) { + finalDataType = type; + break; + } + if ( !firstDataType ) { + firstDataType = type; + } + } + + // Or just use first one + finalDataType = finalDataType || firstDataType; + } + + // If we found a dataType + // We add the dataType to the list if needed + // and return the corresponding response + if ( finalDataType ) { + if ( finalDataType !== dataTypes[ 0 ] ) { + dataTypes.unshift( finalDataType ); + } + return responses[ finalDataType ]; + } +} + +/* Chain conversions given the request and the original response + * Also sets the responseXXX fields on the jqXHR instance + */ +function ajaxConvert( s, response, jqXHR, isSuccess ) { + var conv2, current, conv, tmp, prev, + converters = {}, + + // Work with a copy of dataTypes in case we need to modify it for conversion + dataTypes = s.dataTypes.slice(); + + // Create converters map with lowercased keys + if ( dataTypes[ 1 ] ) { + for ( conv in s.converters ) { + converters[ conv.toLowerCase() ] = s.converters[ conv ]; + } + } + + current = dataTypes.shift(); + + // Convert to each sequential dataType + while ( current ) { + + if ( s.responseFields[ current ] ) { + jqXHR[ s.responseFields[ current ] ] = response; + } + + // Apply the dataFilter if provided + if ( !prev && isSuccess && s.dataFilter ) { + response = s.dataFilter( response, s.dataType ); + } + + prev = current; + current = dataTypes.shift(); + + if ( current ) { + + // There's only work to do if current dataType is non-auto + if ( current === "*" ) { + + current = prev; + + // Convert response if prev dataType is non-auto and differs from current + } else if ( prev !== "*" && prev !== current ) { + + // Seek a direct converter + conv = converters[ prev + " " + current ] || converters[ "* " + current ]; + + // If none found, seek a pair + if ( !conv ) { + for ( conv2 in converters ) { + + // If conv2 outputs current + tmp = conv2.split( " " ); + if ( tmp[ 1 ] === current ) { + + // If prev can be converted to accepted input + conv = converters[ prev + " " + tmp[ 0 ] ] || + converters[ "* " + tmp[ 0 ] ]; + if ( conv ) { + + // Condense equivalence converters + if ( conv === true ) { + conv = converters[ conv2 ]; + + // Otherwise, insert the intermediate dataType + } else if ( converters[ conv2 ] !== true ) { + current = tmp[ 0 ]; + dataTypes.unshift( tmp[ 1 ] ); + } + break; + } + } + } + } + + // Apply converter (if not an equivalence) + if ( conv !== true ) { + + // Unless errors are allowed to bubble, catch and return them + if ( conv && s.throws ) { + response = conv( response ); + } else { + try { + response = conv( response ); + } catch ( e ) { + return { + state: "parsererror", + error: conv ? e : "No conversion from " + prev + " to " + current + }; + } + } + } + } + } + } + + return { state: "success", data: response }; +} + +jQuery.extend( { + + // Counter for holding the number of active queries + active: 0, + + // Last-Modified header cache for next request + lastModified: {}, + etag: {}, + + ajaxSettings: { + url: location.href, + type: "GET", + isLocal: rlocalProtocol.test( location.protocol ), + global: true, + processData: true, + async: true, + contentType: "application/x-www-form-urlencoded; charset=UTF-8", + + /* + timeout: 0, + data: null, + dataType: null, + username: null, + password: null, + cache: null, + throws: false, + traditional: false, + headers: {}, + */ + + accepts: { + "*": allTypes, + text: "text/plain", + html: "text/html", + xml: "application/xml, text/xml", + json: "application/json, text/javascript" + }, + + contents: { + xml: /\bxml\b/, + html: /\bhtml/, + json: /\bjson\b/ + }, + + responseFields: { + xml: "responseXML", + text: "responseText", + json: "responseJSON" + }, + + // Data converters + // Keys separate source (or catchall "*") and destination types with a single space + converters: { + + // Convert anything to text + "* text": String, + + // Text to html (true = no transformation) + "text html": true, + + // Evaluate text as a json expression + "text json": JSON.parse, + + // Parse text as xml + "text xml": jQuery.parseXML + }, + + // For options that shouldn't be deep extended: + // you can add your own custom options here if + // and when you create one that shouldn't be + // deep extended (see ajaxExtend) + flatOptions: { + url: true, + context: true + } + }, + + // Creates a full fledged settings object into target + // with both ajaxSettings and settings fields. + // If target is omitted, writes into ajaxSettings. + ajaxSetup: function( target, settings ) { + return settings ? + + // Building a settings object + ajaxExtend( ajaxExtend( target, jQuery.ajaxSettings ), settings ) : + + // Extending ajaxSettings + ajaxExtend( jQuery.ajaxSettings, target ); + }, + + ajaxPrefilter: addToPrefiltersOrTransports( prefilters ), + ajaxTransport: addToPrefiltersOrTransports( transports ), + + // Main method + ajax: function( url, options ) { + + // If url is an object, simulate pre-1.5 signature + if ( typeof url === "object" ) { + options = url; + url = undefined; + } + + // Force options to be an object + options = options || {}; + + var transport, + + // URL without anti-cache param + cacheURL, + + // Response headers + responseHeadersString, + responseHeaders, + + // timeout handle + timeoutTimer, + + // Url cleanup var + urlAnchor, + + // Request state (becomes false upon send and true upon completion) + completed, + + // To know if global events are to be dispatched + fireGlobals, + + // Loop variable + i, + + // uncached part of the url + uncached, + + // Create the final options object + s = jQuery.ajaxSetup( {}, options ), + + // Callbacks context + callbackContext = s.context || s, + + // Context for global events is callbackContext if it is a DOM node or jQuery collection + globalEventContext = s.context && + ( callbackContext.nodeType || callbackContext.jquery ) ? + jQuery( callbackContext ) : + jQuery.event, + + // Deferreds + deferred = jQuery.Deferred(), + completeDeferred = jQuery.Callbacks( "once memory" ), + + // Status-dependent callbacks + statusCode = s.statusCode || {}, + + // Headers (they are sent all at once) + requestHeaders = {}, + requestHeadersNames = {}, + + // Default abort message + strAbort = "canceled", + + // Fake xhr + jqXHR = { + readyState: 0, + + // Builds headers hashtable if needed + getResponseHeader: function( key ) { + var match; + if ( completed ) { + if ( !responseHeaders ) { + responseHeaders = {}; + while ( ( match = rheaders.exec( responseHeadersString ) ) ) { + responseHeaders[ match[ 1 ].toLowerCase() + " " ] = + ( responseHeaders[ match[ 1 ].toLowerCase() + " " ] || [] ) + .concat( match[ 2 ] ); + } + } + match = responseHeaders[ key.toLowerCase() + " " ]; + } + return match == null ? null : match.join( ", " ); + }, + + // Raw string + getAllResponseHeaders: function() { + return completed ? responseHeadersString : null; + }, + + // Caches the header + setRequestHeader: function( name, value ) { + if ( completed == null ) { + name = requestHeadersNames[ name.toLowerCase() ] = + requestHeadersNames[ name.toLowerCase() ] || name; + requestHeaders[ name ] = value; + } + return this; + }, + + // Overrides response content-type header + overrideMimeType: function( type ) { + if ( completed == null ) { + s.mimeType = type; + } + return this; + }, + + // Status-dependent callbacks + statusCode: function( map ) { + var code; + if ( map ) { + if ( completed ) { + + // Execute the appropriate callbacks + jqXHR.always( map[ jqXHR.status ] ); + } else { + + // Lazy-add the new callbacks in a way that preserves old ones + for ( code in map ) { + statusCode[ code ] = [ statusCode[ code ], map[ code ] ]; + } + } + } + return this; + }, + + // Cancel the request + abort: function( statusText ) { + var finalText = statusText || strAbort; + if ( transport ) { + transport.abort( finalText ); + } + done( 0, finalText ); + return this; + } + }; + + // Attach deferreds + deferred.promise( jqXHR ); + + // Add protocol if not provided (prefilters might expect it) + // Handle falsy url in the settings object (#10093: consistency with old signature) + // We also use the url parameter if available + s.url = ( ( url || s.url || location.href ) + "" ) + .replace( rprotocol, location.protocol + "//" ); + + // Alias method option to type as per ticket #12004 + s.type = options.method || options.type || s.method || s.type; + + // Extract dataTypes list + s.dataTypes = ( s.dataType || "*" ).toLowerCase().match( rnothtmlwhite ) || [ "" ]; + + // A cross-domain request is in order when the origin doesn't match the current origin. + if ( s.crossDomain == null ) { + urlAnchor = document.createElement( "a" ); + + // Support: IE <=8 - 11, Edge 12 - 15 + // IE throws exception on accessing the href property if url is malformed, + // e.g. http://example.com:80x/ + try { + urlAnchor.href = s.url; + + // Support: IE <=8 - 11 only + // Anchor's host property isn't correctly set when s.url is relative + urlAnchor.href = urlAnchor.href; + s.crossDomain = originAnchor.protocol + "//" + originAnchor.host !== + urlAnchor.protocol + "//" + urlAnchor.host; + } catch ( e ) { + + // If there is an error parsing the URL, assume it is crossDomain, + // it can be rejected by the transport if it is invalid + s.crossDomain = true; + } + } + + // Convert data if not already a string + if ( s.data && s.processData && typeof s.data !== "string" ) { + s.data = jQuery.param( s.data, s.traditional ); + } + + // Apply prefilters + inspectPrefiltersOrTransports( prefilters, s, options, jqXHR ); + + // If request was aborted inside a prefilter, stop there + if ( completed ) { + return jqXHR; + } + + // We can fire global events as of now if asked to + // Don't fire events if jQuery.event is undefined in an AMD-usage scenario (#15118) + fireGlobals = jQuery.event && s.global; + + // Watch for a new set of requests + if ( fireGlobals && jQuery.active++ === 0 ) { + jQuery.event.trigger( "ajaxStart" ); + } + + // Uppercase the type + s.type = s.type.toUpperCase(); + + // Determine if request has content + s.hasContent = !rnoContent.test( s.type ); + + // Save the URL in case we're toying with the If-Modified-Since + // and/or If-None-Match header later on + // Remove hash to simplify url manipulation + cacheURL = s.url.replace( rhash, "" ); + + // More options handling for requests with no content + if ( !s.hasContent ) { + + // Remember the hash so we can put it back + uncached = s.url.slice( cacheURL.length ); + + // If data is available and should be processed, append data to url + if ( s.data && ( s.processData || typeof s.data === "string" ) ) { + cacheURL += ( rquery.test( cacheURL ) ? "&" : "?" ) + s.data; + + // #9682: remove data so that it's not used in an eventual retry + delete s.data; + } + + // Add or update anti-cache param if needed + if ( s.cache === false ) { + cacheURL = cacheURL.replace( rantiCache, "$1" ); + uncached = ( rquery.test( cacheURL ) ? "&" : "?" ) + "_=" + ( nonce++ ) + uncached; + } + + // Put hash and anti-cache on the URL that will be requested (gh-1732) + s.url = cacheURL + uncached; + + // Change '%20' to '+' if this is encoded form body content (gh-2658) + } else if ( s.data && s.processData && + ( s.contentType || "" ).indexOf( "application/x-www-form-urlencoded" ) === 0 ) { + s.data = s.data.replace( r20, "+" ); + } + + // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. + if ( s.ifModified ) { + if ( jQuery.lastModified[ cacheURL ] ) { + jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ cacheURL ] ); + } + if ( jQuery.etag[ cacheURL ] ) { + jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ cacheURL ] ); + } + } + + // Set the correct header, if data is being sent + if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) { + jqXHR.setRequestHeader( "Content-Type", s.contentType ); + } + + // Set the Accepts header for the server, depending on the dataType + jqXHR.setRequestHeader( + "Accept", + s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[ 0 ] ] ? + s.accepts[ s.dataTypes[ 0 ] ] + + ( s.dataTypes[ 0 ] !== "*" ? ", " + allTypes + "; q=0.01" : "" ) : + s.accepts[ "*" ] + ); + + // Check for headers option + for ( i in s.headers ) { + jqXHR.setRequestHeader( i, s.headers[ i ] ); + } + + // Allow custom headers/mimetypes and early abort + if ( s.beforeSend && + ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || completed ) ) { + + // Abort if not done already and return + return jqXHR.abort(); + } + + // Aborting is no longer a cancellation + strAbort = "abort"; + + // Install callbacks on deferreds + completeDeferred.add( s.complete ); + jqXHR.done( s.success ); + jqXHR.fail( s.error ); + + // Get transport + transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR ); + + // If no transport, we auto-abort + if ( !transport ) { + done( -1, "No Transport" ); + } else { + jqXHR.readyState = 1; + + // Send global event + if ( fireGlobals ) { + globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] ); + } + + // If request was aborted inside ajaxSend, stop there + if ( completed ) { + return jqXHR; + } + + // Timeout + if ( s.async && s.timeout > 0 ) { + timeoutTimer = window.setTimeout( function() { + jqXHR.abort( "timeout" ); + }, s.timeout ); + } + + try { + completed = false; + transport.send( requestHeaders, done ); + } catch ( e ) { + + // Rethrow post-completion exceptions + if ( completed ) { + throw e; + } + + // Propagate others as results + done( -1, e ); + } + } + + // Callback for when everything is done + function done( status, nativeStatusText, responses, headers ) { + var isSuccess, success, error, response, modified, + statusText = nativeStatusText; + + // Ignore repeat invocations + if ( completed ) { + return; + } + + completed = true; + + // Clear timeout if it exists + if ( timeoutTimer ) { + window.clearTimeout( timeoutTimer ); + } + + // Dereference transport for early garbage collection + // (no matter how long the jqXHR object will be used) + transport = undefined; + + // Cache response headers + responseHeadersString = headers || ""; + + // Set readyState + jqXHR.readyState = status > 0 ? 4 : 0; + + // Determine if successful + isSuccess = status >= 200 && status < 300 || status === 304; + + // Get response data + if ( responses ) { + response = ajaxHandleResponses( s, jqXHR, responses ); + } + + // Convert no matter what (that way responseXXX fields are always set) + response = ajaxConvert( s, response, jqXHR, isSuccess ); + + // If successful, handle type chaining + if ( isSuccess ) { + + // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. + if ( s.ifModified ) { + modified = jqXHR.getResponseHeader( "Last-Modified" ); + if ( modified ) { + jQuery.lastModified[ cacheURL ] = modified; + } + modified = jqXHR.getResponseHeader( "etag" ); + if ( modified ) { + jQuery.etag[ cacheURL ] = modified; + } + } + + // if no content + if ( status === 204 || s.type === "HEAD" ) { + statusText = "nocontent"; + + // if not modified + } else if ( status === 304 ) { + statusText = "notmodified"; + + // If we have data, let's convert it + } else { + statusText = response.state; + success = response.data; + error = response.error; + isSuccess = !error; + } + } else { + + // Extract error from statusText and normalize for non-aborts + error = statusText; + if ( status || !statusText ) { + statusText = "error"; + if ( status < 0 ) { + status = 0; + } + } + } + + // Set data for the fake xhr object + jqXHR.status = status; + jqXHR.statusText = ( nativeStatusText || statusText ) + ""; + + // Success/Error + if ( isSuccess ) { + deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] ); + } else { + deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] ); + } + + // Status-dependent callbacks + jqXHR.statusCode( statusCode ); + statusCode = undefined; + + if ( fireGlobals ) { + globalEventContext.trigger( isSuccess ? "ajaxSuccess" : "ajaxError", + [ jqXHR, s, isSuccess ? success : error ] ); + } + + // Complete + completeDeferred.fireWith( callbackContext, [ jqXHR, statusText ] ); + + if ( fireGlobals ) { + globalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] ); + + // Handle the global AJAX counter + if ( !( --jQuery.active ) ) { + jQuery.event.trigger( "ajaxStop" ); + } + } + } + + return jqXHR; + }, + + getJSON: function( url, data, callback ) { + return jQuery.get( url, data, callback, "json" ); + }, + + getScript: function( url, callback ) { + return jQuery.get( url, undefined, callback, "script" ); + } +} ); + +jQuery.each( [ "get", "post" ], function( i, method ) { + jQuery[ method ] = function( url, data, callback, type ) { + + // Shift arguments if data argument was omitted + if ( isFunction( data ) ) { + type = type || callback; + callback = data; + data = undefined; + } + + // The url can be an options object (which then must have .url) + return jQuery.ajax( jQuery.extend( { + url: url, + type: method, + dataType: type, + data: data, + success: callback + }, jQuery.isPlainObject( url ) && url ) ); + }; +} ); + + +jQuery._evalUrl = function( url, options ) { + return jQuery.ajax( { + url: url, + + // Make this explicit, since user can override this through ajaxSetup (#11264) + type: "GET", + dataType: "script", + cache: true, + async: false, + global: false, + + // Only evaluate the response if it is successful (gh-4126) + // dataFilter is not invoked for failure responses, so using it instead + // of the default converter is kludgy but it works. + converters: { + "text script": function() {} + }, + dataFilter: function( response ) { + jQuery.globalEval( response, options ); + } + } ); +}; + + +jQuery.fn.extend( { + wrapAll: function( html ) { + var wrap; + + if ( this[ 0 ] ) { + if ( isFunction( html ) ) { + html = html.call( this[ 0 ] ); + } + + // The elements to wrap the target around + wrap = jQuery( html, this[ 0 ].ownerDocument ).eq( 0 ).clone( true ); + + if ( this[ 0 ].parentNode ) { + wrap.insertBefore( this[ 0 ] ); + } + + wrap.map( function() { + var elem = this; + + while ( elem.firstElementChild ) { + elem = elem.firstElementChild; + } + + return elem; + } ).append( this ); + } + + return this; + }, + + wrapInner: function( html ) { + if ( isFunction( html ) ) { + return this.each( function( i ) { + jQuery( this ).wrapInner( html.call( this, i ) ); + } ); + } + + return this.each( function() { + var self = jQuery( this ), + contents = self.contents(); + + if ( contents.length ) { + contents.wrapAll( html ); + + } else { + self.append( html ); + } + } ); + }, + + wrap: function( html ) { + var htmlIsFunction = isFunction( html ); + + return this.each( function( i ) { + jQuery( this ).wrapAll( htmlIsFunction ? html.call( this, i ) : html ); + } ); + }, + + unwrap: function( selector ) { + this.parent( selector ).not( "body" ).each( function() { + jQuery( this ).replaceWith( this.childNodes ); + } ); + return this; + } +} ); + + +jQuery.expr.pseudos.hidden = function( elem ) { + return !jQuery.expr.pseudos.visible( elem ); +}; +jQuery.expr.pseudos.visible = function( elem ) { + return !!( elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length ); +}; + + + + +jQuery.ajaxSettings.xhr = function() { + try { + return new window.XMLHttpRequest(); + } catch ( e ) {} +}; + +var xhrSuccessStatus = { + + // File protocol always yields status code 0, assume 200 + 0: 200, + + // Support: IE <=9 only + // #1450: sometimes IE returns 1223 when it should be 204 + 1223: 204 + }, + xhrSupported = jQuery.ajaxSettings.xhr(); + +support.cors = !!xhrSupported && ( "withCredentials" in xhrSupported ); +support.ajax = xhrSupported = !!xhrSupported; + +jQuery.ajaxTransport( function( options ) { + var callback, errorCallback; + + // Cross domain only allowed if supported through XMLHttpRequest + if ( support.cors || xhrSupported && !options.crossDomain ) { + return { + send: function( headers, complete ) { + var i, + xhr = options.xhr(); + + xhr.open( + options.type, + options.url, + options.async, + options.username, + options.password + ); + + // Apply custom fields if provided + if ( options.xhrFields ) { + for ( i in options.xhrFields ) { + xhr[ i ] = options.xhrFields[ i ]; + } + } + + // Override mime type if needed + if ( options.mimeType && xhr.overrideMimeType ) { + xhr.overrideMimeType( options.mimeType ); + } + + // X-Requested-With header + // For cross-domain requests, seeing as conditions for a preflight are + // akin to a jigsaw puzzle, we simply never set it to be sure. + // (it can always be set on a per-request basis or even using ajaxSetup) + // For same-domain requests, won't change header if already provided. + if ( !options.crossDomain && !headers[ "X-Requested-With" ] ) { + headers[ "X-Requested-With" ] = "XMLHttpRequest"; + } + + // Set headers + for ( i in headers ) { + xhr.setRequestHeader( i, headers[ i ] ); + } + + // Callback + callback = function( type ) { + return function() { + if ( callback ) { + callback = errorCallback = xhr.onload = + xhr.onerror = xhr.onabort = xhr.ontimeout = + xhr.onreadystatechange = null; + + if ( type === "abort" ) { + xhr.abort(); + } else if ( type === "error" ) { + + // Support: IE <=9 only + // On a manual native abort, IE9 throws + // errors on any property access that is not readyState + if ( typeof xhr.status !== "number" ) { + complete( 0, "error" ); + } else { + complete( + + // File: protocol always yields status 0; see #8605, #14207 + xhr.status, + xhr.statusText + ); + } + } else { + complete( + xhrSuccessStatus[ xhr.status ] || xhr.status, + xhr.statusText, + + // Support: IE <=9 only + // IE9 has no XHR2 but throws on binary (trac-11426) + // For XHR2 non-text, let the caller handle it (gh-2498) + ( xhr.responseType || "text" ) !== "text" || + typeof xhr.responseText !== "string" ? + { binary: xhr.response } : + { text: xhr.responseText }, + xhr.getAllResponseHeaders() + ); + } + } + }; + }; + + // Listen to events + xhr.onload = callback(); + errorCallback = xhr.onerror = xhr.ontimeout = callback( "error" ); + + // Support: IE 9 only + // Use onreadystatechange to replace onabort + // to handle uncaught aborts + if ( xhr.onabort !== undefined ) { + xhr.onabort = errorCallback; + } else { + xhr.onreadystatechange = function() { + + // Check readyState before timeout as it changes + if ( xhr.readyState === 4 ) { + + // Allow onerror to be called first, + // but that will not handle a native abort + // Also, save errorCallback to a variable + // as xhr.onerror cannot be accessed + window.setTimeout( function() { + if ( callback ) { + errorCallback(); + } + } ); + } + }; + } + + // Create the abort callback + callback = callback( "abort" ); + + try { + + // Do send the request (this may raise an exception) + xhr.send( options.hasContent && options.data || null ); + } catch ( e ) { + + // #14683: Only rethrow if this hasn't been notified as an error yet + if ( callback ) { + throw e; + } + } + }, + + abort: function() { + if ( callback ) { + callback(); + } + } + }; + } +} ); + + + + +// Prevent auto-execution of scripts when no explicit dataType was provided (See gh-2432) +jQuery.ajaxPrefilter( function( s ) { + if ( s.crossDomain ) { + s.contents.script = false; + } +} ); + +// Install script dataType +jQuery.ajaxSetup( { + accepts: { + script: "text/javascript, application/javascript, " + + "application/ecmascript, application/x-ecmascript" + }, + contents: { + script: /\b(?:java|ecma)script\b/ + }, + converters: { + "text script": function( text ) { + jQuery.globalEval( text ); + return text; + } + } +} ); + +// Handle cache's special case and crossDomain +jQuery.ajaxPrefilter( "script", function( s ) { + if ( s.cache === undefined ) { + s.cache = false; + } + if ( s.crossDomain ) { + s.type = "GET"; + } +} ); + +// Bind script tag hack transport +jQuery.ajaxTransport( "script", function( s ) { + + // This transport only deals with cross domain or forced-by-attrs requests + if ( s.crossDomain || s.scriptAttrs ) { + var script, callback; + return { + send: function( _, complete ) { + script = jQuery( " + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +
+

API documentation

+

This section contains auto-generated API documentation for AppTools.

+ +
+ + +
+
+
+
+
+ +

Previous topic

+

File I/O

+

Next topic

+

apptools

+

This Page

+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/5.0/api/apptools.html b/5.0/api/apptools.html new file mode 100644 index 000000000..1bf597fd6 --- /dev/null +++ b/5.0/api/apptools.html @@ -0,0 +1,367 @@ + + + + + + + apptools package — Apptools Documentation + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +
+

apptools package

+
+

Subpackages

+
+ +
+
+
+

Module contents

+
+
+ + +
+
+
+
+
+ +

Table of Contents

+ + +

Previous topic

+

apptools

+

Next topic

+

apptools.io package

+

This Page

+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/5.0/api/apptools.io.h5.html b/5.0/api/apptools.io.h5.html new file mode 100644 index 000000000..4a6f98d18 --- /dev/null +++ b/5.0/api/apptools.io.h5.html @@ -0,0 +1,705 @@ + + + + + + + apptools.io.h5 package — Apptools Documentation + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+ +
+ + +
+
+ +
+
+ +
+

apptools.io.h5 package

+
+

Submodules

+
+
+

apptools.io.h5.dict_node module

+
+
+apptools.io.h5.dict_node.ARRAY_PROXY_KEY = '__array__'
+

The key name which identifies array objects in the JSON dict.

+
+ +
+
+class apptools.io.h5.dict_node.H5DictNode(h5_group, auto_flush=True)[source]
+

Bases: object

+

Dictionary-like node interface.

+

Data for the dict is stored as a JSON file in a PyTables FileNode. This +allows easy storage of Python objects, such as dictionaries and lists of +different data types.

+

Note that this is implemented using a group-node assuming that arrays are +valid inputs and will be stored as H5 array nodes.

+
+
Parameters
+
    +
  • h5_group (H5Group instance) – Group node which will be used as a dictionary store.

  • +
  • auto_flush (bool) – If True, write data to disk whenever the dict data is altered. +Otherwise, call flush() explicitly to write data to disk.

  • +
+
+
+
+
+classmethod add_to_h5file(h5, node_path, data=None, **kwargs)[source]
+

Add dict node to an H5 file at the specified path.

+
+
Parameters
+
    +
  • h5 (H5File) – The H5 file where the dictionary data will be stored.

  • +
  • node_path (str) – Path to node where data is stored (e.g. ‘/path/to/my_dict’)

  • +
  • data (dict) – Data for initialization, if desired.

  • +
+
+
+
+ +
+
+property data
+
+ +
+
+flush()[source]
+

Write buffered data to disk.

+
+ +
+
+classmethod is_dict_node(pytables_node)[source]
+

Return True if PyTables node looks like an H5DictNode.

+

NOTE: That this returns False if the node is an H5DictNode instance, +since the input node should be a normal PyTables Group node.

+
+ +
+
+keys()[source]
+
+ +
+ +
+
+

apptools.io.h5.file module

+
+
+class apptools.io.h5.file.H5Attrs(node_attrs)[source]
+

Bases: collections.abc.MutableMapping

+

An attributes dictionary for an h5 node.

+

This intercepts __setitem__ so that python sequences can be converted to +numpy arrays. This helps preserve the readability of our HDF5 files by +other (non-python) programs.

+
+
+get(k[, d]) → D[k] if k in D, else d. d defaults to None.[source]
+
+ +
+
+items() → a set-like object providing a view on D's items[source]
+
+ +
+
+keys() → a set-like object providing a view on D's keys[source]
+
+ +
+
+values() → an object providing a view on D's values[source]
+
+ +
+ +
+
+class apptools.io.h5.file.H5File(filename, mode='r+', delete_existing=False, auto_groups=True, auto_open=True, h5filters=None)[source]
+

Bases: collections.abc.Mapping

+

File object for HDF5 files.

+

This class wraps PyTables to provide a cleaner, but only implements an +interface for accessing arrays.

+
+
Parameters
+
    +
  • filename (str or a tables.File instance) – Filename for an HDF5 file, or a PyTables File object.

  • +
  • mode (str) –

    Mode to open the file:

    +
    +

    ’r’ : Read-only +‘w’ : Write; create new file (an existing file would be deleted). +‘a’ : Read and write to file; create if not existing +‘r+’: Read and write to file; must already exist

    +
    +

  • +
  • delete_existing (bool) – If True, an existing node will be deleted when a create_* method is +called. Otherwise, a ValueError will be raise.

  • +
  • auto_groups (bool) – If True, create_array will automatically create parent groups.

  • +
  • auto_open (bool) – If True, open the file automatically on initialization. Otherwise, +you can call H5File.open() explicitly after initialization.

  • +
  • chunked (bool) – If True, the default behavior of create_array will be a chunked +array (see PyTables create_carray).

  • +
+
+
+
+
+close()[source]
+
+ +
+
+create_array(node_path, array_or_shape, dtype=None, chunked=False, extendable=False, **kwargs)[source]
+

Create node to store an array.

+
+
Parameters
+
    +
  • node_path (str) – PyTable node path; e.g. ‘/path/to/node’.

  • +
  • array_or_shape (array or shape tuple) – Array or shape tuple for an array. If given a shape tuple, the +dtype parameter must also specified.

  • +
  • dtype (str or numpy.dtype) – Data type of array. Only necessary if array_or_shape is a shape.

  • +
  • chunked (bool) – Controls whether the array is chunked.

  • +
  • extendable ({None | bool}) – Controls whether the array is extendable.

  • +
  • kwargs (key/value pairs) – Keyword args passed to PyTables File.create_(c|e)array.

  • +
+
+
+
+ +
+
+create_dict(node_path, data=None, **kwargs)[source]
+

Create dict node at the specified path.

+
+
Parameters
+
    +
  • node_path (str) – Path to node where data is stored (e.g. ‘/path/to/my_dict’)

  • +
  • data (dict) – Data for initialization, if desired.

  • +
+
+
+
+ +
+
+create_group(group_path, **kwargs)[source]
+

Create group.

+
+
Parameters
+
    +
  • group_path (str) – PyTable group path; e.g. ‘/path/to/group’.

  • +
  • kwargs (key/value pairs) – Keyword args passed to PyTables File.create_group.

  • +
+
+
+
+ +
+
+create_table(node_path, description, **kwargs)[source]
+

Create table node at the specified path.

+
+
Parameters
+
    +
  • node_path (str) – Path to node where data is stored (e.g. ‘/path/to/my_dict’)

  • +
  • description (dict or numpy dtype object) – The description of the columns in the table. This is either a dict +of column name -> dtype items or a numpy record array dtype. For +more information, see the documentation for Table in pytables.

  • +
+
+
+
+ +
+
+exists_error = "'{}' exists in '{}'; set `delete_existing` attribute to True to overwrite existing calculations."
+
+ +
+
+property is_open
+
+ +
+
+iteritems(path='/')[source]
+

Iterate over node paths and nodes of the h5 file.

+
+ +
+
+classmethod join_path(*args)[source]
+

Join parts of an h5 path.

+

For example, the 3 argmuments ‘path’, ‘to’, ‘node’ will return +‘/path/to/node’.

+
+
Parameters
+

args (str) – Parts of path to be joined.

+
+
+
+ +
+
+open()[source]
+
+ +
+
+remove_group(group_path, **kwargs)[source]
+

Remove group

+
+
Parameters
+

group_path (str) – PyTable group path; e.g. ‘/path/to/group’.

+
+
+
+ +
+
+remove_node(node_path)[source]
+

Remove node

+
+
Parameters
+

node_path (str) – PyTable node path; e.g. ‘/path/to/node’.

+
+
+
+ +
+
+property root
+
+ +
+
+classmethod split_path(node_path)[source]
+

Split node path returning the base path and node name.

+

For example: ‘/path/to/node’ will return ‘/path/to’ and ‘node’

+
+
Parameters
+

node_path (str) – PyTable node path; e.g. ‘/path/to/node’.

+
+
+
+ +
+ +
+
+class apptools.io.h5.file.H5Group(pytables_group)[source]
+

Bases: collections.abc.Mapping

+

A group node in an H5File.

+

This is a thin wrapper around PyTables’ Group object to expose attributes +and maintain the dict interface of H5File.

+
+
+property children_names
+
+ +
+
+create_array(node_subpath, array_or_shape, dtype=None, chunked=False, extendable=False, **kwargs)[source]
+

** H5Group wrapper for H5File.create_array: ** +Note that the first argument is a nodepath relative to the group, rather than +an absolute path. Below is the original docstring:

+

Create node to store an array.

+
+
Parameters
+
    +
  • node_path (str) – PyTable node path; e.g. ‘/path/to/node’.

  • +
  • array_or_shape (array or shape tuple) – Array or shape tuple for an array. If given a shape tuple, the +dtype parameter must also specified.

  • +
  • dtype (str or numpy.dtype) – Data type of array. Only necessary if array_or_shape is a shape.

  • +
  • chunked (bool) – Controls whether the array is chunked.

  • +
  • extendable ({None | bool}) – Controls whether the array is extendable.

  • +
  • kwargs (key/value pairs) – Keyword args passed to PyTables File.create_(c|e)array.

  • +
+
+
+
+ +
+
+create_dict(node_subpath, data=None, **kwargs)[source]
+

** H5Group wrapper for H5File.create_dict: ** +Note that the first argument is a nodepath relative to the group, rather than +an absolute path. Below is the original docstring:

+

Create dict node at the specified path.

+
+
Parameters
+
    +
  • node_path (str) – Path to node where data is stored (e.g. ‘/path/to/my_dict’)

  • +
  • data (dict) – Data for initialization, if desired.

  • +
+
+
+
+ +
+
+create_group(group_subpath, delete_existing=False, **kwargs)[source]
+

** H5Group wrapper for H5File.create_group: ** +Note that the first argument is a nodepath relative to the group, rather than +an absolute path. Below is the original docstring:

+

Create group.

+
+
Parameters
+
    +
  • group_path (str) – PyTable group path; e.g. ‘/path/to/group’.

  • +
  • kwargs (key/value pairs) – Keyword args passed to PyTables File.create_group.

  • +
+
+
+
+ +
+
+create_table(node_subpath, description, *args, **kwargs)[source]
+

** H5Group wrapper for H5File.create_table: ** +Note that the first argument is a nodepath relative to the group, rather than +an absolute path. Below is the original docstring:

+

Create table node at the specified path.

+
+
Parameters
+
    +
  • node_path (str) – Path to node where data is stored (e.g. ‘/path/to/my_dict’)

  • +
  • description (dict or numpy dtype object) – The description of the columns in the table. This is either a dict +of column name -> dtype items or a numpy record array dtype. For +more information, see the documentation for Table in pytables.

  • +
+
+
+
+ +
+
+property filename
+
+ +
+
+iter_groups()[source]
+

Iterate over H5Group nodes that are children of this group.

+
+ +
+
+property name
+
+ +
+
+property pathname
+
+ +
+
+remove_group(group_subpath, **kwargs)[source]
+

** H5Group wrapper for H5File.remove_group: ** +Note that the first argument is a nodepath relative to the group, rather than +an absolute path. Below is the original docstring:

+

Remove group

+
+
Parameters
+

group_path (str) – PyTable group path; e.g. ‘/path/to/group’.

+
+
+
+ +
+
+remove_node(node_subpath, **kwargs)[source]
+

** H5Group wrapper for H5File.remove_node: ** +Note that the first argument is a nodepath relative to the group, rather than +an absolute path. Below is the original docstring:

+

Remove node

+
+
Parameters
+

node_path (str) – PyTable node path; e.g. ‘/path/to/node’.

+
+
+
+ +
+
+property root
+
+ +
+
+property subgroup_names
+
+ +
+ +
+
+apptools.io.h5.file.get_atom(dtype)[source]
+

Return a PyTables Atom for the given dtype or dtype string.

+
+ +
+
+apptools.io.h5.file.h5_group_wrapper(original)[source]
+
+ +
+
+apptools.io.h5.file.iterator_length(iterator)[source]
+
+ +
+
+

apptools.io.h5.table_node module

+
+
+class apptools.io.h5.table_node.H5TableNode(node)[source]
+

Bases: object

+

A wrapper for PyTables Table nodes.

+
+
Parameters
+

node (tables.Table instance) – An H5 node which is a pytables.Table or H5TableNode instance

+
+
+
+
+classmethod add_to_h5file(h5, node_path, description, **kwargs)[source]
+

Add table node to an H5 file at the specified path.

+
+
Parameters
+
    +
  • h5 (H5File) – The H5 file where the table node will be stored.

  • +
  • node_path (str) – Path to node where data is stored (e.g. ‘/path/to/my_table’)

  • +
  • description (list of tuples or numpy dtype object) – The description of the columns in the table. This is either a list +of (column name, dtype, [, shape or itemsize]) tuples or a numpy +record array dtype. For more information, see the documentation for +Table in PyTables.

  • +
  • **kwargs (dict) – Additional keyword arguments to pass to pytables.File.create_table

  • +
+
+
+
+ +
+
+append(data)[source]
+

Add some data to the table.

+
+
Parameters
+

data (dict) – A dictionary of column name -> values items

+
+
+
+ +
+
+classmethod is_table_node(pytables_node)[source]
+

Return True if pytables_node is a pytables.Table or a H5TableNode.

+
+ +
+
+property ix
+

Return an object which provides access to row data.

+
+ +
+
+keys()[source]
+
+ +
+
+to_dataframe()[source]
+

Return table data as a pandas DataFrame.

+

XXX: This does not work if the table contains a multidimensional column

+

This method requires pandas to have been installed in the environment.

+
+ +
+ +
+
+

apptools.io.h5.utils module

+
+
+apptools.io.h5.utils.open_h5file(filename, mode='r+', **kwargs)[source]
+

Context manager for reading an HDF5 file as an H5File object.

+
+
Parameters
+
    +
  • filename (str) – HDF5 file name.

  • +
  • mode (str) –

    Mode to open the file:

    +

    ’r’ : Read-only +‘w’ : Write; create new file (an existing file would be deleted). +‘a’ : Read and write to file; create if not existing +‘r+’: Read and write to file; must already exist

    +

  • +
  • H5File for additional keyword arguments. (See) –

  • +
+
+
+
+ +
+
+

Module contents

+
+
+ + +
+
+
+ +
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/5.0/api/apptools.io.html b/5.0/api/apptools.io.html new file mode 100644 index 000000000..fa1514e92 --- /dev/null +++ b/5.0/api/apptools.io.html @@ -0,0 +1,256 @@ + + + + + + + apptools.io package — Apptools Documentation + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +
+

apptools.io package

+ +
+

Submodules

+
+
+

apptools.io.api module

+
+
+

apptools.io.file module

+

A representation of files and folders in a file system.

+
+
+class apptools.io.file.File(path, **traits)[source]
+

Bases: traits.has_traits.HasPrivateTraits

+

A representation of files and folders in a file system.

+
+
+copy(destination)[source]
+

Copies this file/folder.

+
+ +
+
+create_file(contents='')[source]
+

Creates a file at this path.

+
+ +
+
+create_folder()[source]
+

Creates a folder at this path.

+

All intermediate folders MUST already exist.

+
+ +
+
+create_folders()[source]
+

Creates a folder at this path.

+

This will attempt to create any missing intermediate folders.

+
+ +
+
+create_package()[source]
+

Creates a package at this path.

+

All intermediate folders/packages MUST already exist.

+
+ +
+
+delete()[source]
+

Deletes this file/folder.

+

Does nothing if the file/folder does not exist.

+
+ +
+
+make_writeable()[source]
+

Attempt to make the file/folder writeable.

+
+ +
+
+move(destination)[source]
+

Moves this file/folder.

+
+ +
+ +
+
+

Module contents

+

Provides an abstraction for files and folders in a file system. +Part of the AppTools project of the Enthought Tool Suite.

+
+
+ + +
+
+
+
+
+ +

Table of Contents

+ + +

Previous topic

+

apptools package

+

Next topic

+

apptools.io.h5 package

+

This Page

+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/5.0/api/apptools.logger.agent.html b/5.0/api/apptools.logger.agent.html new file mode 100644 index 000000000..109f12f4f --- /dev/null +++ b/5.0/api/apptools.logger.agent.html @@ -0,0 +1,286 @@ + + + + + + + apptools.logger.agent package — Apptools Documentation + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+ +
+ + +
+
+ +
+
+ +
+

apptools.logger.agent package

+
+

Submodules

+
+
+

apptools.logger.agent.attachments module

+

Attach relevant project files.

+

FIXME: there are no public project plugins for Envisage 3, yet. In any case, +this stuff should not be hard-coded, but extensible via extension points. The +code remains here because we can reuse the zip utility code in that extensible +rewrite.

+
+
+class apptools.logger.agent.attachments.Attachments(message, **traits)[source]
+

Bases: traits.has_traits.HasTraits

+
+
+package_any_relevant_files()[source]
+
+ +
+
+package_single_project()[source]
+
+ +
+
+package_workspace()[source]
+
+ +
+ +
+
+

apptools.logger.agent.quality_agent_mailer module

+
+
+apptools.logger.agent.quality_agent_mailer.create_email_message(fromaddr, toaddrs, ccaddrs, subject, priority, include_project=False, stack_trace='', comments='')[source]
+
+ +
+
+

apptools.logger.agent.quality_agent_view module

+
+
+class apptools.logger.agent.quality_agent_view.QualityAgentView(*args, **kwargs)[source]
+

Bases: pyface.base_toolkit.Unimplemented

+
+
+cc_address = <traits.trait_types.Str object>
+
+ +
+
+comments = <traits.trait_types.Str object>
+
+ +
+
+from_address = <traits.trait_types.Str object>
+
+ +
+
+help_id = 'enlib|HID_Quality_Agent_Dlg'
+
+ +
+
+include_userdata
+

alias of traits.trait_types.Any

+
+ +
+
+msg = <traits.trait_types.Str object>
+
+ +
+
+priority = <traits.trait_types.Str object>
+
+ +
+
+service = <traits.trait_types.Any object>
+
+ +
+
+size = <traits.trait_types.Tuple object>
+
+ +
+
+smtp_server = <traits.trait_types.Str object>
+
+ +
+
+subject = <traits.trait_types.Str object>
+
+ +
+
+title = <traits.trait_types.Str object>
+
+ +
+
+to_address = <traits.trait_types.Str object>
+
+ +
+ +
+
+

Module contents

+

lib.apptools.logger.agent

+
+
+ + +
+
+
+ +
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/5.0/api/apptools.logger.html b/5.0/api/apptools.logger.html new file mode 100644 index 000000000..454905560 --- /dev/null +++ b/5.0/api/apptools.logger.html @@ -0,0 +1,323 @@ + + + + + + + apptools.logger package — Apptools Documentation + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +
+

apptools.logger package

+ +
+

Submodules

+
+
+

apptools.logger.api module

+
+
+

apptools.logger.custom_excepthook module

+
+
+apptools.logger.custom_excepthook.custom_excepthook(type, value, traceback)[source]
+

Pass on the exception to the logging system.

+
+ +
+
+

apptools.logger.log_point module

+

Prints a stack trace every time it is called but does not halt execution +of the application.

+

Copied from Uche Ogbuji’s blog

+
+
+apptools.logger.log_point.log_point(msg='\n')[source]
+
+ +
+
+

apptools.logger.log_queue_handler module

+
+
+class apptools.logger.log_queue_handler.LogQueueHandler(size=1000)[source]
+

Bases: logging.Handler

+

Buffers up the log messages so that we can display them later. +This is important on startup when log messages are generated before +the ui has started. By putting them in this queue we can display +them once the ui is ready.

+
+
+emit(record)[source]
+

Actually this is more like an enqueue than an emit().

+
+ +
+
+get()[source]
+
+ +
+
+has_new_records()[source]
+
+ +
+
+reset()[source]
+
+ +
+ +
+
+

apptools.logger.logger module

+

Convenience functions for creating logging handlers etc.

+
+
+class apptools.logger.logger.LogFileHandler(path, maxBytes=1000000, backupCount=3, level=None, formatter=None)[source]
+

Bases: logging.handlers.RotatingFileHandler

+

The default log file handler.

+
+ +
+
+apptools.logger.logger.add_log_queue_handler(logger, level=None, formatter=None)[source]
+

Adds a queueing log handler to a logger.

+
+ +
+
+

apptools.logger.ring_buffer module

+

Copied from Python Cookbook.

+
+
+class apptools.logger.ring_buffer.RingBuffer(size_max)[source]
+

Bases: object

+
+
+append(x)[source]
+

append an element at the end of the buffer

+
+ +
+
+get()[source]
+

return a list of elements from the oldest to the newest

+
+ +
+ +
+
+class apptools.logger.ring_buffer.RingBufferFull(n)[source]
+

Bases: object

+
+
+append(x)[source]
+
+ +
+
+get()[source]
+
+ +
+ +
+
+

Module contents

+

Convenience functions for creating logging handlers. +Part of the EnthoughtBase project.

+
+
+ + +
+
+
+ +
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/5.0/api/apptools.logger.plugin.html b/5.0/api/apptools.logger.plugin.html new file mode 100644 index 000000000..0f53db074 --- /dev/null +++ b/5.0/api/apptools.logger.plugin.html @@ -0,0 +1,305 @@ + + + + + + + apptools.logger.plugin package — Apptools Documentation + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+ +
+ + +
+
+ +
+
+ +
+

apptools.logger.plugin package

+ +
+

Submodules

+
+
+

apptools.logger.plugin.logger_plugin module

+

Logger plugin.

+
+
+class apptools.logger.plugin.logger_plugin.LoggerPlugin(*args, **kwargs)[source]
+

Bases: envisage.api.Plugin

+

Logger plugin.

+
+
+MAIL_FILES = 'apptools.logger.plugin.mail_files'
+
+ +
+
+PREFERENCES = 'envisage.preferences'
+
+ +
+
+PREFERENCES_PAGES = 'envisage.ui.workbench.preferences_pages'
+
+ +
+
+VIEWS = 'envisage.ui.workbench.views'
+
+ +
+
+id = 'apptools.logger'
+
+ +
+
+mail_files
+
+ +
+
+name = 'Logger plugin'
+
+ +
+
+preferences = <traits.trait_types.List object>
+
+ +
+
+preferences_pages = <traits.trait_types.List object>
+
+ +
+
+start()[source]
+

Starts the plugin.

+
+ +
+
+stop()[source]
+

Stops the plugin.

+
+ +
+
+views = <traits.trait_types.List object>
+
+ +
+ +
+
+

apptools.logger.plugin.logger_preferences module

+
+
+class apptools.logger.plugin.logger_preferences.LoggerPreferences(**traits)[source]
+

Bases: apptools.preferences.preferences_helper.PreferencesHelper

+

The persistent service exposing the Logger plugin’s API.

+
+ +
+
+

apptools.logger.plugin.logger_service module

+
+
+class apptools.logger.plugin.logger_service.LoggerService[source]
+

Bases: traits.has_traits.HasTraits

+

The persistent service exposing the Logger plugin’s API.

+
+
+create_email_message(fromaddr, toaddrs, ccaddrs, subject, priority, include_userdata=False, stack_trace='', comments='', include_environment=True)[source]
+

Format a bug report email from the log files.

+
+ +
+
+save_preferences()[source]
+

Save the preferences.

+
+ +
+
+send_bug_report(smtp_server, fromaddr, toaddrs, ccaddrs, message)[source]
+

Send a bug report email.

+
+ +
+
+whole_log_text()[source]
+

Return all of the logged data as formatted text.

+
+ +
+ +
+
+

Module contents

+
+
+ + +
+
+
+ +
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/5.0/api/apptools.logger.plugin.view.html b/5.0/api/apptools.logger.plugin.view.html new file mode 100644 index 000000000..6cc16d720 --- /dev/null +++ b/5.0/api/apptools.logger.plugin.view.html @@ -0,0 +1,303 @@ + + + + + + + apptools.logger.plugin.view package — Apptools Documentation + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ + + + +
+
+ +
+
+ +
+

apptools.logger.plugin.view package

+
+

Submodules

+
+
+

apptools.logger.plugin.view.logger_preferences_page module

+
+
+class apptools.logger.plugin.view.logger_preferences_page.LoggerPreferencesPage(**traits)[source]
+

Bases: apptools.preferences.ui.preferences_page.PreferencesPage

+

A preference page for the logger plugin.

+
+ +
+
+

apptools.logger.plugin.view.logger_view module

+
+
+class apptools.logger.plugin.view.logger_view.LogRecordAdapter[source]
+

Bases: traitsui.tabular_adapter.TabularAdapter

+

A TabularEditor adapter for logging.LogRecord objects.

+
+
+column_widths = [80, 100, 120, -1]
+
+ +
+
+get_width(object, trait, column)[source]
+

Returns the width to use for a specified column.

+

If the value is <= 0, the column will have a default width, which is +the same as specifying a width of 0.1.

+

If the value is > 1.0, it is converted to an integer and the result is +the width of the column in pixels. This is referred to as a +fixed width column.

+

If the value is a float such that 0.0 < value <= 1.0, it is treated as +the unnormalized fraction of the available space that is to be +assigned to the column. What this means requires a little explanation.

+

To arrive at the size in pixels of the column at any given time, the +editor adds together all of the unnormalized fraction values +returned for all columns in the table to arrive at a total value. Each +unnormalized fraction is then divided by the total to create a +normalized fraction. Each column is then assigned an amount of space +in pixels equal to the maximum of 30 or its normalized fraction +multiplied by the available space. The available space is defined +as the actual width of the table minus the width of all fixed width +columns. Note that this calculation is performed each time the table is +resized in the user interface, thus allowing columns of this type to +increase or decrease their width dynamically, while leaving fixed +width columns unchanged.

+
+ +
+ +
+
+class apptools.logger.plugin.view.logger_view.LoggerView(*args, **kwargs)[source]
+

Bases: pyface.workbench.traits_ui_view.TraitsUIView

+

The Workbench View showing the list of log items.

+
+
+activated = <traits.trait_types.Instance object>
+
+ +
+
+activated_text = <traits.traits.ForwardProperty object>
+
+ +
+
+code_editor = <traitsui.editors.code_editor.ToolkitEditorFactory object>
+
+ +
+
+copy_button = <traits.trait_types.Button object>
+
+ +
+
+formatted_records = <traits.traits.ForwardProperty object>
+
+ +
+
+id = <traits.trait_types.Str object>
+
+ +
+
+log_records = <traits.trait_types.List object>
+
+ +
+
+log_records_editor = <traitsui.editors.tabular_editor.TabularEditor object>
+
+ +
+
+name = <traits.trait_types.Str object>
+
+ +
+
+reset_button = <traits.trait_types.Button object>
+
+ +
+
+service = <traits.trait_types.Instance object>
+
+ +
+
+show_button = <traits.trait_types.Button object>
+
+ +
+
+trait_view = ( Group( Item( 'log_records' object = 'object', style = 'simple', show_label = False ), Group( Item( 'reset_button' object = 'object', style = 'simple', show_label = False ), Item( 'trait_modified' object = 'object', style = 'simple' ), Item( 'show_button' object = 'object', style = 'simple', show_label = False ), Item( 'copy_button' object = 'object', style = 'simple', show_label = False ), orientation = 'horizontal', show_labels = False, object = 'object', style = 'simple' ), show_labels = False, object = 'object', style = 'simple' ) )
+
+ +
+
+update(force=False)[source]
+

Update ‘log_records’ if our handler has new records or ‘force’ is +set.

+
+ +
+ +
+
+

Module contents

+
+
+ + +
+
+
+ +
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/5.0/api/apptools.naming.html b/5.0/api/apptools.naming.html new file mode 100644 index 000000000..8879ceee8 --- /dev/null +++ b/5.0/api/apptools.naming.html @@ -0,0 +1,840 @@ + + + + + + + apptools.naming package — Apptools Documentation + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +
+

apptools.naming package

+ +
+

Submodules

+
+
+

apptools.naming.address module

+

The address of a commuications endpoint.

+
+
+class apptools.naming.address.Address[source]
+

Bases: traits.has_traits.HasTraits

+

The address of a communications end-point.

+

It contains a type that describes the communication mechanism, and the +actual address content.

+
+ +
+
+

apptools.naming.api module

+
+
+

apptools.naming.binding module

+

The representation of a name-to-object binding in a context.

+
+
+class apptools.naming.binding.Binding[source]
+

Bases: traits.has_traits.HasTraits

+

The representation of a name-to-object binding in a context.

+
+ +
+
+

apptools.naming.context module

+

The base class for all naming contexts.

+
+
+class apptools.naming.context.Context[source]
+

Bases: traits.has_traits.HasTraits

+

The base class for all naming contexts.

+
+
+INITIAL_CONTEXT_FACTORY = 'apptools.naming.factory.initial'
+
+ +
+
+OBJECT_FACTORIES = 'apptools.naming.factory.object'
+
+ +
+
+STATE_FACTORIES = 'apptools.naming.factory.state'
+
+ +
+
+bind(name, obj, make_contexts=False)[source]
+

Binds a name to an object.

+

If ‘make_contexts’ is True then any missing intermediate contexts are +created automatically.

+
+ +
+
+create_subcontext(name)[source]
+

Creates a sub-context.

+
+ +
+
+destroy_subcontext(name)[source]
+

Destroys a sub-context.

+
+ +
+
+get_unique_name(prefix)[source]
+

Returns a name that is unique within the context.

+

The name returned will start with the specified prefix.

+
+ +
+
+is_context(name)[source]
+

Returns True if the name is bound to a context.

+
+ +
+
+list_bindings(name='')[source]
+

Lists the bindings in a context.

+
+ +
+
+list_names(name='')[source]
+

Lists the names bound in a context.

+
+ +
+
+lookup(name)[source]
+

Resolves a name relative to this context.

+
+ +
+
+lookup_binding(name)[source]
+

Looks up the binding for a name relative to this context.

+
+ +
+
+lookup_context(name)[source]
+

Resolves a name relative to this context.

+

The name MUST resolve to a context.

+
+ +
+
+rebind(name, obj, make_contexts=False)[source]
+

Binds an object to a name that may already be bound.

+

If ‘make_contexts’ is True then any missing intermediate contexts are +created automatically.

+

The object may be a different object but may also be the same object +that is already bound to the specified name. The name may or may not be +already used. Think of this as a safer version of ‘bind’ since this +one will never raise an exception regarding a name being used.

+
+ +
+
+rename(old_name, new_name)[source]
+

Binds a new name to an object.

+
+ +
+
+search(obj)[source]
+

Returns a list of namespace names that are bound to obj.

+
+ +
+
+unbind(name)[source]
+

Unbinds a name.

+
+ +
+ +
+
+

apptools.naming.dir_context module

+

The base class for all directory contexts.

+
+
+class apptools.naming.dir_context.DirContext[source]
+

Bases: apptools.naming.context.Context

+

The base class for all directory contexts.

+
+
+find_bindings(visitor)[source]
+

Find bindings with attributes matching criteria in visitor.

+

Visitor is a function that is passed the bindings for each level of the +heirarchy and the attribute dictionary for those bindings. The visitor +examines the bindings and dictionary and returns the bindings it is +interested in.

+
+ +
+
+get_attributes(name)[source]
+

Returns the attributes associated with a named object.

+
+ +
+
+set_attributes(name, attributes)[source]
+

Sets the attributes associated with a named object.

+
+ +
+ +
+
+

apptools.naming.dynamic_context module

+

Provider of a framework that dynamically determines the contents of a +context at the time of interaction with the contents rather than at the +time a class is written.

+

This capability is particularly useful when the object acting as a context +is part of a plug-in application – such as Envisage. In general, this +capability allows the context to be:

+
    +
  • Extendable by contributions from somewhere other than the original +code writer

  • +
  • Dynamic in that the elements it is composed of can change each time +someone interacts with the contents of the context.

  • +
+

It should be noted that this capability is explicitly different from +contexts that look at another container to determine their contents, such +as a file system context!

+

Users of this framework contribute items to a dynamic context by adding +traits to the dynamic context instance. (This addition can happen +statically through the use of a Traits Category.) The trait value is the +context item’s value and the trait definition’s metadata determines how the +item is treated within the context. The support metadata is:

+
+
context_name: A non-empty string

Represents the name of the item within this context. This must be +present for the trait to show up as a context item though the value +may change over time as the item gets bound to different names.

+
+
context_order: A float value

Indicates the position for the item within this context. All +dynamically contributed context items are sorted by ascending order +of this value using the standard list sort function.

+
+
is_context: A boolean value

True if the item is itself a context.

+
+
+
+
+class apptools.naming.dynamic_context.DynamicContext[source]
+

Bases: apptools.naming.context.Context

+

A framework that dynamically determines the contents of a context at +the time of interaction with the contents rather than at the time a +context class is written.

+

It should be noted that this capability is explicitly different from +contexts that look at another container to determine their contents, +such as a file system context!

+
+ +
+
+

apptools.naming.exception module

+

Naming exceptions.

+
+
+exception apptools.naming.exception.InvalidNameError[source]
+

Bases: apptools.naming.exception.NamingError

+

Invalid name.

+

This exception is thrown when the name passed to a naming operation does +not conform to the syntax of the naming system (or is empty etc).

+
+ +
+
+exception apptools.naming.exception.NameAlreadyBoundError[source]
+

Bases: apptools.naming.exception.NamingError

+

Name already bound.

+

This exception is thrown when an attempt is made to bind a name that is +already bound in the current context.

+
+ +
+
+exception apptools.naming.exception.NameNotFoundError[source]
+

Bases: apptools.naming.exception.NamingError

+

Name not found.

+

This exception is thrown when a component of a name cannot be resolved +because it is not bound in the current context.

+
+ +
+
+exception apptools.naming.exception.NamingError[source]
+

Bases: Exception

+

Base class for all naming exceptions.

+
+ +
+
+exception apptools.naming.exception.NotContextError[source]
+

Bases: apptools.naming.exception.NamingError

+

Not a context.

+

This exception is thrown when a naming operation has reached a point where +a context is required to continue the operation, but the resolved object +is not a context.

+
+ +
+
+exception apptools.naming.exception.OperationNotSupportedError[source]
+

Bases: apptools.naming.exception.NamingError

+

The context does support the requested operation.

+
+ +
+
+

apptools.naming.initial_context module

+

The starting point for performing naming operations.

+
+
+apptools.naming.initial_context.InitialContext(environment)[source]
+

Creates an initial context for beginning name resolution.

+
+ +
+
+

apptools.naming.initial_context_factory module

+

The base class for all initial context factories.

+
+
+class apptools.naming.initial_context_factory.InitialContextFactory[source]
+

Bases: traits.has_traits.HasTraits

+

The base class for all initial context factories.

+
+
+get_initial_context(environment)[source]
+

Creates an initial context for beginning name resolution.

+
+ +
+ +
+
+

apptools.naming.naming_event module

+

The event fired by the tree model when it changes.

+
+
+class apptools.naming.naming_event.NamingEvent[source]
+

Bases: traits.has_traits.HasTraits

+

Information about tree model changes.

+
+ +
+
+

apptools.naming.naming_manager module

+

The naming manager.

+
+
+class apptools.naming.naming_manager.NamingManager[source]
+

Bases: traits.has_traits.HasTraits

+

The naming manager.

+
+
+get_object_instance(info, name, context)[source]
+

Creates an object using the specified state information.

+

The naming manager asks the context for its list of OBJECT factories +and calls them one by one until it gets a non-None result, indicating +that the factory recognised the information and created an object.

+

If none of the factories recognize the state information (or if the +context has no factories) then the state information itself is +returned.

+
+ +
+
+get_state_to_bind(obj, name, context)[source]
+

Returns the state of an object for binding.

+

The naming manager asks the context for its list of STATE factories +and then calls them one by one until it gets a non-None result +indicating that the factory recognised the object and created state +information for it.

+

If none of the factories recognize the object (or if the context +has no factories) then the object itself is returned.

+
+ +
+ +
+
+

apptools.naming.object_factory module

+

The base class for all object factories.

+
+
+class apptools.naming.object_factory.ObjectFactory[source]
+

Bases: traits.has_traits.HasTraits

+

The base class for all object factories.

+

An object factory accepts some information about how to create an object +(such as a reference) and returns an instance of that object.

+
+
+get_object_instance(state, name, context)[source]
+

Creates an object using the specified state information.

+

Returns None if the factory cannot create the object (ie. it does not +recognise the state passed to it).

+
+ +
+ +
+
+

apptools.naming.object_serializer module

+

The base class for all object serializers.

+
+
+class apptools.naming.object_serializer.ObjectSerializer[source]
+

Bases: traits.has_traits.HasTraits

+

The base class for all object serializers.

+
+
+can_load(path)[source]
+

Returns True if the serializer can load a file.

+
+ +
+
+can_save(obj)[source]
+

Returns True if the serializer can save an object.

+
+ +
+
+load(path)[source]
+

Loads an object from a file.

+
+ +
+
+save(path, obj)[source]
+

Saves an object to a file.

+
+ +
+ +
+
+

apptools.naming.py_context module

+

A naming context for a Python namespace.

+
+
+class apptools.naming.py_context.PyContext(**traits)[source]
+

Bases: apptools.naming.context.Context, apptools.naming.referenceable.Referenceable

+

A naming context for a Python namespace.

+
+ +
+
+

apptools.naming.py_object_factory module

+

Object factory for Python namespace contexts.

+
+
+class apptools.naming.py_object_factory.PyObjectFactory[source]
+

Bases: apptools.naming.object_factory.ObjectFactory

+

Object factory for Python namespace contexts.

+
+
+get_object_instance(state, name, context)[source]
+

Creates an object using the specified state information.

+
+ +
+ +
+
+

apptools.naming.pyfs_context module

+

A Python File System context.

+
+
+class apptools.naming.pyfs_context.PyFSContext(**traits)[source]
+

Bases: apptools.naming.dir_context.DirContext, apptools.naming.referenceable.Referenceable

+

A Python File System context.

+

This context represents a directory on a local file system.

+
+
+ATTRIBUTES_FILE = '__attributes__'
+
+ +
+
+FILTERS = 'apptools.naming.pyfs.filters'
+
+ +
+
+OBJECT_SERIALIZERS = 'apptools.naming.pyfs.object.serializers'
+
+ +
+
+get_unique_name(name)[source]
+

Returns a name that is unique within the context.

+

The name returned will start with the specified prefix.

+
+ +
+
+refresh()[source]
+

Refresh the context to reflect changes in the file system.

+
+ +
+ +
+
+

apptools.naming.pyfs_context_factory module

+

Object factory for Python File System contexts.

+
+
+class apptools.naming.pyfs_context_factory.PyFSContextFactory[source]
+

Bases: apptools.naming.object_factory.ObjectFactory

+

Object factory for Python File System contexts.

+
+
+get_object_instance(state, name, context)[source]
+

Creates an object using the specified state information.

+
+ +
+ +
+
+

apptools.naming.pyfs_initial_context_factory module

+

The initial context factory for Python file system contexts.

+
+
+class apptools.naming.pyfs_initial_context_factory.PyFSInitialContextFactory[source]
+

Bases: apptools.naming.initial_context_factory.InitialContextFactory

+

The initial context factory for Python file system contexts.

+
+
+get_initial_context(environment)[source]
+

Creates an initial context for beginning name resolution.

+
+ +
+ +
+
+

apptools.naming.pyfs_object_factory module

+

Object factory for Python File System contexts.

+
+
+class apptools.naming.pyfs_object_factory.PyFSObjectFactory[source]
+

Bases: apptools.naming.object_factory.ObjectFactory

+

Object factory for Python File System contexts.

+
+
+get_object_instance(state, name, context)[source]
+

Creates an object using the specified state information.

+
+ +
+ +
+
+

apptools.naming.pyfs_state_factory module

+

State factory for Python File System contexts.

+
+
+class apptools.naming.pyfs_state_factory.PyFSStateFactory[source]
+

Bases: apptools.naming.state_factory.StateFactory

+

State factory for Python File System contexts.

+
+
+get_state_to_bind(obj, name, context)[source]
+

Returns the state of an object for binding.

+
+ +
+ +
+
+

apptools.naming.reference module

+

A reference to an object that lives outside of the naming system.

+
+
+class apptools.naming.reference.Reference[source]
+

Bases: traits.has_traits.HasPrivateTraits

+

A reference to an object that lives outside of the naming system.

+

References provide a way to store the address(s) of objects that live +outside of the naming system. A reference consists of a list of +addresses that represent a communications endpoint for the object being +referenced.

+

A reference also contains information to assist in the creation of an +instance of the object to which it refers. It contains the name of +the class that will be created and the class name and location of a +factory that will be used to do the actual instance creation.

+
+ +
+
+

apptools.naming.referenceable module

+

Base class for classes that can produce a reference to themselves.

+
+
+class apptools.naming.referenceable.Referenceable[source]
+

Bases: traits.has_traits.HasPrivateTraits

+

Base class for classes that can produce a reference to themselves.

+
+ +
+
+

apptools.naming.referenceable_state_factory module

+

State factory for referenceable objects.

+
+
+class apptools.naming.referenceable_state_factory.ReferenceableStateFactory[source]
+

Bases: apptools.naming.state_factory.StateFactory

+

State factory for referenceable objects.

+
+
+get_state_to_bind(obj, name, context)[source]
+

Returns the state of an object for binding.

+
+ +
+ +
+
+

apptools.naming.state_factory module

+

The base class for all state factories.

+
+
+class apptools.naming.state_factory.StateFactory[source]
+

Bases: traits.has_traits.HasPrivateTraits

+

The base class for all state factories.

+

A state factory accepts an object and returns some data representing the +object that is suitable for storing in a particular context.

+
+
+get_state_to_bind(obj, name, context)[source]
+

Returns the state of an object for binding.

+

Returns None if the factory cannot create the state (ie. it does not +recognise the object passed to it).

+
+ +
+ +
+
+

apptools.naming.unique_name module

+

A re-usable method for calculating a unique name given a list of existing +names.

+
+
+apptools.naming.unique_name.make_unique_name(base, existing=[], format='%s_%s')[source]
+

Return a name, unique within a context, based on the specified name.

+

base: the desired base name of the generated unique name. +existing: a sequence of the existing names to avoid returning. +format: a formatting specification for how the name is made unique.

+
+ +
+
+

Module contents

+

Manages naming contexts. Supports non-string data types and scoped +preferences. Part of the AppTools project of the Enthought Tool Suite.

+
+
+ + +
+
+
+ +
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/5.0/api/apptools.naming.trait_defs.html b/5.0/api/apptools.naming.trait_defs.html new file mode 100644 index 000000000..6938f18d2 --- /dev/null +++ b/5.0/api/apptools.naming.trait_defs.html @@ -0,0 +1,271 @@ + + + + + + + apptools.naming.trait_defs package — Apptools Documentation + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+ +
+ + +
+
+ +
+
+ +
+

apptools.naming.trait_defs package

+
+

Submodules

+
+
+

apptools.naming.trait_defs.api module

+
+
+

apptools.naming.trait_defs.naming_traits module

+
+
+class apptools.naming.trait_defs.naming_traits.NamingTraitHandler(aClass, or_none, module)[source]
+

Bases: traits.trait_handler.TraitHandler

+
+
+find_class()[source]
+
+ +
+
+get_editor(trait)[source]
+

Returns a trait editor that allows the user to modify the trait +trait. +This method only needs to be specified if traits defined using this +trait handler require a non-default trait editor in trait user +interfaces. The default implementation of this method returns a trait +editor that allows the user to type an arbitrary string as the value.

+

For more information on trait user interfaces, refer to the Traits UI +User Guide.

+
+
Parameters
+

trait (Trait) – The trait to be edited.

+
+
+
+ +
+
+info()[source]
+

Must return a string describing the type of value accepted by the +trait handler.

+

The string should be a phrase describing the type defined by the +TraitHandler subclass, rather than a complete sentence. For example, +use the phrase, “a square sprocket” instead of the sentence, “The value +must be a square sprocket.” The value returned by info() is combined +with other information whenever an error occurs and therefore makes +more sense to the user if the result is a phrase. The info() method is +similar in purpose and use to the info attribute of a validator +function.

+

Note that the result can include information specific to the particular +trait handler instance. If the info() method is not overridden, the +default method returns the value of the ‘info_text’ attribute.

+
+ +
+
+post_setattr(object, name, value)[source]
+
+ +
+
+resolve_class(object, name, value)[source]
+
+ +
+
+validate(object, name, value)[source]
+

Verifies whether a new value assigned to a trait attribute is +valid.

+

This method must be implemented by subclasses of TraitHandler. It is +called whenever a new value is assigned to a trait attribute defined +using this trait handler.

+

If the value received by validate() is not valid for the trait +attribute, the method must called the predefined error() method to +raise a TraitError exception

+
+
Parameters
+
    +
  • object (HasTraits instance) – The object whose attribute is being assigned.

  • +
  • name (str) – The name of the attribute being assigned.

  • +
  • value (any) – The proposed new value for the attribute.

  • +
+
+
Returns
+

If the new value is valid, this method must return either the +original value passed to it, or an alternate value to be assigned +in place of the original value. Whatever value this method returns +is the actual value assigned to object.name.

+
+
Return type
+

any

+
+
+
+ +
+
+validate_failed(object, name, value)[source]
+
+ +
+ +
+
+

Module contents

+
+
+ + +
+
+
+ +
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/5.0/api/apptools.persistence.html b/5.0/api/apptools.persistence.html new file mode 100644 index 000000000..8640a7d0b --- /dev/null +++ b/5.0/api/apptools.persistence.html @@ -0,0 +1,794 @@ + + + + + + + apptools.persistence package — Apptools Documentation + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +
+

apptools.persistence package

+
+

Submodules

+
+
+

apptools.persistence.file_path module

+

Simple class to support file path objects that work well in the +context of persistent storage with the state_pickler.

+
+
+class apptools.persistence.file_path.FilePath(value='')[source]
+

Bases: object

+

This class stores two paths to the file. A relative path and +an absolute one. The absolute path is used by the end user. When +this object is pickled the state_pickler sets the relative path +relative to the file that is being generated. When unpickled, the +stored relative path is used to set the absolute path correctly +based on the path of the saved file.

+
+
+get()[source]
+

Get the path.

+
+ +
+
+set(value)[source]
+

Sets the value of the path.

+
+ +
+
+set_absolute(base_f_name)[source]
+

Sets the absolute file name for the current relative file +name with respect to the given base_f_name.

+
+ +
+
+set_relative(base_f_name)[source]
+

Sets the path relative to base_f_name. Note that +base_f_name and self.rel_pth should be valid file names +correct on the current os. The set name is a file name that +has a POSIX path.

+
+ +
+ +
+
+

apptools.persistence.project_loader module

+
+
+apptools.persistence.project_loader.load_project(pickle_filename, updater_path, application_version, protocol, max_pass=-1)[source]
+

Reads a project from a pickle file and if necessary will update it to +the latest version of the application.

+
+ +
+
+apptools.persistence.project_loader.upgrade_project(pickle_filename, updater_path, project_version, application_version, protocol, max_pass=-1)[source]
+

Repeatedly read and write the project to disk updating it one version +at a time.

+

Example the p5.project is at version 0 +The application is at version 3

+

p5.project — Update1 —> p5.project.v1 +p5.project.v1 — Update2 —> p5.project.v2 +p5.project.v2 — Update3 —> p5.project.v3 +p5.project.v3 —> loaded into app

+

The user then has the option to save the updated project as p5.project

+
+ +
+
+

apptools.persistence.state_pickler module

+

This module provides code that allows one to pickle the state of a +Python object to a dictionary.

+

The motivation for this is simple. The standard Python +pickler/unpickler is best used to pickle simple objects and does not +work too well for complex code. Specifically, there are two major +problems (1) the pickle file format is not easy to edit with a text +editor and (2) when a pickle is unpickled, it creates all the +necessary objects and sets the state of these objects.

+

Issue (2) might not appear to be a problem. However, often, the +determination of the entire ‘state’ of an application requires the +knowledge of the state of many objects that are not really in the +users concern. The user would ideally like to pickle just what he +thinks is relevant. Now, given that the user is not going to save the +entire state of the application, the use of pickle is insufficient +since the state is no longer completely known (or worth knowing). The +default Unpickler recreates the objects and the typical +implementation of __setstate__ is usually to simply update the +object’s __dict__ attribute. This is inadequate because the pickled +information is taken out of the real context when it was saved.

+

The StatePickler basically pickles the ‘state’ of an object into a +large dictionary. This pickled data may be easily unpickled and +modified on the interpreter or edited with a text editor +(pprint.saferepr is a friend). The second problem is also +eliminated. When this state is unpickled using StateUnpickler, what +you get is a special dictionary (a State instance). This allows one +to navigate the state just like the original object. Its up to the +user to create any new objects and set their states using this +information. This allows for a lot of flexibility while allowing one +to save and set the state of (almost) any Python object.

+

The StateSetter class helps set the state of a known instance. When +setting the state of an instance it checks to see if there is a +__set_pure_state__ method that in turn calls StateSetter.set +appropriately.

+

Additionally, there is support for versioning. The class’ version is +obtain from the __version__ class attribute. This version along +with the versions of the bases of a class is embedded into the +metadata of the state and stored. By using version_registry.py a +user may register a handler for a particular class and module. When +the state of an object is set using StateSetter.set_state, then +these handlers are called in reverse order of their MRO. This gives +the handler an opportunity to upgrade the state depending on its +version. Builtin classes are not scanned for versions. If a class +has no version, then by default it is assumed to be -1.

+

Example:

+
>>> class A:
+...    def __init__(self):
+...        self.a = 'a'
+...
+>>> a = A()
+>>> a.a = 100
+>>> import state_pickler
+>>> s = state_pickler.dumps(a)               # Dump the state of `a`.
+>>> state = state_pickler.loads_state(s)     # Get the state back.
+>>> b = state_pickler.create_instance(state) # Create the object.
+>>> state_pickler.set_state(b, state)        # Set the object's state.
+>>> assert b.a == 100
+
+
+
+

Features

+
+
    +
  • The output is a plain old dictionary so is easy to parse, edit etc.

  • +
  • Handles references to avoid duplication.

  • +
  • Gzips Numeric arrays when dumping them.

  • +
  • Support for versioning.

  • +
+
+
+
+

Caveats

+
+
    +
  • Does not pickle a whole bunch of stuff including code objects and +functions.

  • +
  • The output is a pure dictionary and does not contain instances. So +using this as it is in __setstate__ will not work. Instead +define a __set_pure_state__ and use the StateSetter class or +the set_state function provided by this module.

  • +
+
+

Notes

+

Browsing the code from XMarshaL and pickle.py proved useful for +ideas. None of the code is taken from there though.

+
+
+class apptools.persistence.state_pickler.State(**kw)[source]
+

Bases: dict

+

Used to encapsulate the state of an instance in a very +convenient form. The ‘__metadata__’ attribute/key is a dictionary +that has class specific details like the class name, module name +etc.

+
+ +
+
+class apptools.persistence.state_pickler.StateDict(**kw)[source]
+

Bases: dict

+

Used to encapsulate a dictionary stored in a State instance. +The has_instance attribute specifies if the dict has an instance +embedded in it.

+
+ +
+
+class apptools.persistence.state_pickler.StateList(seq=None)[source]
+

Bases: list

+

Used to encapsulate a list stored in a State instance. The +has_instance attribute specifies if the list has an instance +embedded in it.

+
+ +
+
+class apptools.persistence.state_pickler.StatePickler[source]
+

Bases: object

+

Pickles the state of an object into a dictionary. The +dictionary is itself either saved as a pickled file (dump) or +pickled string (dumps). Alternatively, the dump_state method +will return the dictionary that is pickled.

+

The format of the state dict is quite strightfoward. Basic types +(bool, int, long, float, complex, None, string) are +represented as they are. Everything else is stored as a +dictionary containing metadata information on the object’s type +etc. and also the actual object in the ‘data’ key. For example:

+
>>> p = StatePickler()
+>>> p.dump_state(1)
+1
+>>> l = [1,2.0, None, [1,2,3]]
+>>> p.dump_state(l)
+{'data': [1, 2.0, None, {'data': [1, 2, 3], 'type': 'list', 'id': 1}],
+ 'id': 0,
+ 'type': 'list'}
+
+
+

Classes are also represented similarly. The state in this case is +obtained from the __getstate__ method or from the __dict__. +Here is an example:

+
>>> class A:
+...     __version__ = 1  # State version
+...     def __init__(self):
+...         self.attribute = 1
+...
+>>> a = A()
+>>> p = StatePickler()
+>>> p.dump_state(a)
+{'class_name': 'A',
+ 'data': {'data': {'attribute': 1}, 'type': 'dict', 'id': 2},
+ 'id': 0,
+ 'initargs': {'data': (), 'type': 'tuple', 'id': 1},
+ 'module': '__main__',
+ 'type': 'instance',
+ 'version': [(('A', '__main__'), 1)]}
+
+
+

When pickling data, references are taken care of. Numeric arrays +can be pickled and are stored as a gzipped base64 encoded string.

+
+
+dump(value, file)[source]
+

Pickles the state of the object (value) into the passed +file.

+
+ +
+
+dump_state(value)[source]
+

Returns a dictionary or a basic type representing the +complete state of the object (value).

+

This value is pickled by the dump and dumps methods.

+
+ +
+
+dumps(value)[source]
+

Pickles the state of the object (value) and returns a +string.

+
+ +
+ +
+
+exception apptools.persistence.state_pickler.StatePicklerError[source]
+

Bases: Exception

+
+ +
+
+class apptools.persistence.state_pickler.StateSetter[source]
+

Bases: object

+

This is a convenience class that helps a user set the +attributes of an object given its saved state. For instances it +checks to see if a __set_pure_state__ method exists and calls +that when it sets the state.

+
+
+set(obj, state, ignore=None, first=None, last=None)[source]
+

Sets the state of the object.

+

This is to be used as a means to simplify loading the state of +an object from its __setstate__ method using the dictionary +describing its state. Note that before the state is set, the +registered handlers for the particular class are called in +order to upgrade the version of the state to the latest +version.

+
+
Parameters
+
    +
  • obj (-) – The object whose state is to be set. If this is None +(default) then the object is created.

  • +
  • state (-) – The dictionary representing the state of the object.

  • +
  • ignore (-) – The list of attributes specified in this list are ignored +and the state of these attributes are not set (this excludes +the ones specified in first and last). If one specifies +a ‘*’ then all attributes are ignored except the ones +specified in first and last.

  • +
  • first (-) – The list of attributes specified in this list are set first (in +order), before any other attributes are set.

  • +
  • last (-) – The list of attributes specified in this list are set last (in +order), after all other attributes are set.

  • +
+
+
+
+ +
+ +
+
+exception apptools.persistence.state_pickler.StateSetterError[source]
+

Bases: Exception

+
+ +
+
+class apptools.persistence.state_pickler.StateTuple[source]
+

Bases: tuple

+

Used to encapsulate a tuple stored in a State instance. The +has_instance attribute specifies if the tuple has an instance +embedded in it.

+
+ +
+
+class apptools.persistence.state_pickler.StateUnpickler[source]
+

Bases: object

+

Unpickles the state of an object saved using StatePickler.

+

Please note that unlike the standard Unpickler, no instances of +any user class are created. The data for the state is obtained +from the file or string, reference objects are setup to refer to +the same state value and this state is returned in the form +usually in the form of a dictionary. For example:

+
>>> class A:
+...     def __init__(self):
+...         self.attribute = 1
+...
+>>> a = A()
+>>> p = StatePickler()
+>>> s = p.dumps(a)
+>>> up = StateUnpickler()
+>>> state = up.loads_state(s)
+>>> state.__class__.__name__
+'State'
+>>> state.attribute
+1
+>>> state.__metadata__
+{'class_name': 'A',
+ 'has_instance': True,
+ 'id': 0,
+ 'initargs': (),
+ 'module': '__main__',
+ 'type': 'instance',
+ 'version': [(('A', '__main__'), -1)]}
+
+
+

Note that the state is actually a State instance and is +navigable just like the original object. The details of the +instance are stored in the __metadata__ attribute. This is +highly convenient since it is possible for someone to view and +modify the state very easily.

+
+
+load_state(file)[source]
+

Returns the state of an object loaded from the pickled data +in the given file.

+
+ +
+
+loads_state(string)[source]
+

Returns the state of an object loaded from the pickled data +in the given string.

+
+ +
+ +
+
+exception apptools.persistence.state_pickler.StateUnpicklerError[source]
+

Bases: Exception

+
+ +
+
+apptools.persistence.state_pickler.create_instance(state)[source]
+

Create an instance from the state if possible.

+
+ +
+
+apptools.persistence.state_pickler.dump(value, file)[source]
+

Pickles the state of the object (value) into the passed file +(or file name).

+
+ +
+
+apptools.persistence.state_pickler.dumps(value)[source]
+

Pickles the state of the object (value) and returns a string.

+
+ +
+
+apptools.persistence.state_pickler.get_state(obj)[source]
+

Returns the state of the object (usually as a dictionary). The +returned state may be used directy to set the state of the object +via set_state.

+
+ +
+
+apptools.persistence.state_pickler.gunzip_string(data)[source]
+

Given a gzipped string (data) this unzips the string and +returns it.

+
+ +
+
+apptools.persistence.state_pickler.gzip_string(data)[source]
+

Given a string (data) this gzips the string and returns it.

+
+ +
+
+apptools.persistence.state_pickler.load_state(file)[source]
+

Returns the state of an object loaded from the pickled data in +the given file (or file name).

+
+ +
+
+apptools.persistence.state_pickler.loads_state(string)[source]
+

Returns the state of an object loaded from the pickled data +in the given string.

+
+ +
+
+apptools.persistence.state_pickler.set_state(obj, state, ignore=None, first=None, last=None)[source]
+

Sets the state of the object.

+

This is to be used as a means to simplify loading the state of +an object from its __setstate__ method using the dictionary +describing its state. Note that before the state is set, the +registered handlers for the particular class are called in +order to upgrade the version of the state to the latest +version.

+
+
Parameters
+
    +
  • obj (-) – The object whose state is to be set. If this is None +(default) then the object is created.

  • +
  • state (-) – The dictionary representing the state of the object.

  • +
  • ignore (-) – The list of attributes specified in this list are ignored +and the state of these attributes are not set (this excludes +the ones specified in first and last). If one specifies +a ‘*’ then all attributes are ignored except the ones +specified in first and last.

  • +
  • first (-) – The list of attributes specified in this list are set first (in +order), before any other attributes are set.

  • +
  • last (-) – The list of attributes specified in this list are set last (in +order), after all other attributes are set.

  • +
+
+
+
+ +
+
+apptools.persistence.state_pickler.update_state(state)[source]
+

Given the state of an object, this updates the state to the +latest version using the handlers given in the version registry. +The state is modified in-place.

+
+ +
+
+
+

apptools.persistence.updater module

+
+
+class apptools.persistence.updater.Updater[source]
+

Bases: object

+

An abstract class to provide functionality common to the updaters.

+
+
+get_latest(module, name)[source]
+

The refactorings dictionary contains mappings between old and new +module names. Since we only bump the version number one increment +there is only one possible answer.

+
+ +
+
+strip(string)[source]
+
+ +
+ +
+
+

apptools.persistence.version_registry module

+

A version registry that manages handlers for different state +versions.

+
+
+class apptools.persistence.version_registry.HandlerRegistry[source]
+

Bases: object

+

A simple version conversion handler registry. Classes register +handlers in order to convert the state version to the latest +version. When an object’s state is about to be set, the update +method of the registy is called. This in turn calls any handlers +registered for the class/module and this handler is then called +with the state and the version of the state. The state is +modified in-place by the handlers.

+
+
+register(class_name, module, handler)[source]
+

Register handler that handles versioning for class having +class name (class_name) and module name (module). The +handler function will be passed the state and its version to fix.

+
+ +
+
+unregister(class_name, module)[source]
+

Unregisters any handlers for a class and module.

+
+ +
+
+update(state)[source]
+

Updates the given state using the handlers. Note that the +state is modified in-place.

+
+ +
+ +
+
+apptools.persistence.version_registry.get_version(obj)[source]
+

Walks the class hierarchy and obtains the versions of the +various classes and returns a list of tuples of the form +((class_name, module), version) in reverse order of the MRO.

+
+ +
+
+

apptools.persistence.versioned_unpickler module

+
+
+class apptools.persistence.versioned_unpickler.NewUnpickler(file, *, fix_imports=True, encoding='ASCII', errors='strict')[source]
+

Bases: pickle._Unpickler

+

An unpickler that implements a two-stage pickling process to make it +possible to unpickle complicated Python object hierarchies where the +unserialized state of an object depends on the state of other objects in +the same pickle.

+
+
+initialize(max_pass)[source]
+
+ +
+
+load(max_pass=-1)[source]
+

Read a pickled object representation from the open file.

+

Return the reconstituted object hierarchy specified in the file.

+
+ +
+
+classmethod load_build(obj)[source]
+
+ +
+ +
+
+class apptools.persistence.versioned_unpickler.VersionedUnpickler(file, updater=None)[source]
+

Bases: apptools.persistence.versioned_unpickler.NewUnpickler

+

This class reads in a pickled file created at revision version ‘n’ +and then applies the transforms specified in the updater class to +generate a new set of objects which are at revision version ‘n+1’.

+

I decided to keep the loading of the updater out of this generic class +because we will want updaters to be generated for each plugin’s type +of project.

+

This ensures that the VersionedUnpickler can remain ignorant about the +actual version numbers - all it needs to do is upgrade one release.

+
+
+add_updater(module, name, klass)[source]
+

If there is an updater defined for this class we will add it to the +class as the __setstate__ method.

+
+ +
+
+backup_setstate(module, klass)[source]
+

If the class has a user defined __setstate__ we back it up.

+
+ +
+
+find_class(module, name)[source]
+

Overridden method from Unpickler.

+

NB __setstate__ is not called until later.

+
+ +
+
+import_name(module, name)[source]
+

If the class is needed for the latest version of the application then +it should presumably exist.

+

If the class no longer exists then we should perhaps return +a proxy of the class.

+

If the persisted file is at v1 say and the application is at v3 then +objects that are required for v1 and v2 do not have to exist they only +need to be placeholders for the state during an upgrade.

+
+ +
+ +
+
+

Module contents

+

Supports flexible pickling and unpickling of the state of a Python object +to a dictionary. Part of the AppTools project of the Enthought Tool Suite.

+
+
+ + +
+
+
+ +
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/5.0/api/apptools.preferences.html b/5.0/api/apptools.preferences.html new file mode 100644 index 000000000..e7f3cde28 --- /dev/null +++ b/5.0/api/apptools.preferences.html @@ -0,0 +1,653 @@ + + + + + + + apptools.preferences package — Apptools Documentation + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +
+

apptools.preferences package

+ +
+

Submodules

+
+
+

apptools.preferences.api module

+
+
+

apptools.preferences.i_preferences module

+

The interface for a node in a preferences hierarchy.

+
+
+class apptools.preferences.i_preferences.IPreferences[source]
+

Bases: traits.has_traits.Interface

+

The interface for a node in a preferences hierarchy.

+
+
+clear(path='')[source]
+

Remove all preference from the node at the specified path.

+

If the path is the empty string (the default) then remove the +preferences in this node.

+

This does not affect any of the node’s children.

+

e.g. To clear the preferences out of a node directly:

+
preferences.clear()
+
+
+

Or to clear the preferences of a node at a given path:

+
preferences.clear('acme.ui')
+
+
+
+ +
+
+flush()[source]
+

Force any changes in the node to the backing store.

+

This includes any changes to the node’s descendants.

+
+ +
+
+get(path, default=None, inherit=False)[source]
+

Get the value of the preference at the specified path.

+

If no value exists for the path (or any part of the path does not +exist) then return the default value.

+

Preference values are always returned as strings.

+

e.g:

+
preferences.set('acme.ui.bgcolor', 'blue')
+preferences.get('acme.ui.bgcolor') -> 'blue'
+
+preferences.set('acme.ui.width', 100)
+preferences.get('acme.ui.width') -> '100'
+
+preferences.set('acme.ui.visible', True)
+preferences.get('acme.ui.visible') -> 'True'
+
+
+

If ‘inherit’ is True then we allow ‘inherited’ preference values.

+

e.g. If we are looking up:

+
'acme.ui.widget.bgcolor'
+
+
+

and it does not exist then we will also try:

+
'acme.ui.bgcolor'
+'acme.bgcolor'
+'bgcolor'
+
+
+

Raise a ‘ValueError’ exception if the path is the empty string.

+
+ +
+
+keys(path='')[source]
+

Return the preference keys of the node at the specified path.

+

If the path is the empty string (the default) then return the +preference keys of this node.

+

e.g:

+
keys = preferences.keys('acme.ui')
+
+
+
+ +
+
+node(path='')[source]
+

Return the node at the specified path.

+

If the path is the empty string (the default) then return this node.

+

Any missing nodes are created automatically.

+

e.g:

+
node = preferences.node('acme.ui')
+bgcolor = node.get('bgcolor')
+
+
+
+ +
+
+node_exists(path='')[source]
+

Return True if the node at the specified path exists

+

If the path is the empty string (the default) then return True.

+

e.g:

+
exists = preferences.exists('acme.ui')
+
+
+
+ +
+
+node_names(path='')[source]
+

Return the names of the children of the node at the specified path.

+

If the path is the empty string (the default) then return the names of +the children of this node.

+

e.g:

+
names = preferences.node_names('acme.ui')
+
+
+
+ +
+
+remove(path)[source]
+

Remove the preference at the specified path.

+

Does nothing if no value exists for the path (or any part of the path +does not exist.

+

Raise a ‘ValueError’ exception if the path is the empty string.

+

e.g.:

+
preferences.remove('acme.ui.bgcolor')
+
+
+
+ +
+
+set(path, value)[source]
+

Set the value of the preference at the specified path.

+

Any missing nodes are created automatically.

+

Primitive Python types can be set, but preferences are always +stored and returned as strings.

+

e.g:

+
preferences.set('acme.ui.bgcolor', 'blue')
+preferences.get('acme.ui.bgcolor') -> 'blue'
+
+preferences.set('acme.ui.width', 100)
+preferences.get('acme.ui.width') -> '100'
+
+preferences.set('acme.ui.visible', True)
+preferences.get('acme.ui.visible') -> 'True'
+
+
+

Raise a ‘ValueError’ exception if the path is the empty string.

+
+ +
+ +
+
+

apptools.preferences.package_globals module

+

Package-scope globals.

+

The default preferences node is currently used by ‘PreferencesHelper’ and +‘PreferencesBinding’ instances if no specific preferences node is set. This +makes it easy for them to access the root node of an application-wide +preferences hierarchy.

+
+
+apptools.preferences.package_globals.get_default_preferences()[source]
+

Get the default preferences node.

+
+ +
+
+apptools.preferences.package_globals.set_default_preferences(default_preferences)[source]
+

Set the default preferences node.

+
+ +
+
+

apptools.preferences.preference_binding module

+

A binding between a trait on an object and a preference value.

+
+
+class apptools.preferences.preference_binding.PreferenceBinding(**traits)[source]
+

Bases: traits.has_traits.HasTraits

+

A binding between a trait on an object and a preference value.

+
+ +
+
+apptools.preferences.preference_binding.bind_preference(obj, trait_name, preference_path, preferences=None)[source]
+

Create a new preference binding.

+
+ +
+
+

apptools.preferences.preferences module

+

The default implementation of a node in a preferences hierarchy.

+
+
+class apptools.preferences.preferences.Preferences(**traits)[source]
+

Bases: traits.has_traits.HasTraits

+

The default implementation of a node in a preferences hierarchy.

+
+
+add_preferences_listener(listener, path='')[source]
+

Add a listener for changes to a node’s preferences.

+
+ +
+
+clear(path='')[source]
+

Remove all preferences from the node at the specified path.

+
+ +
+
+dump(indent='')[source]
+

Dump the preferences hierarchy to stdout.

+
+ +
+
+flush()[source]
+

Force any changes in the node to the backing store.

+

This includes any changes to the node’s descendants.

+
+ +
+
+get(path, default=None, inherit=False)[source]
+

Get the value of the preference at the specified path.

+
+ +
+
+keys(path='')[source]
+

Return the preference keys of the node at the specified path.

+
+ +
+
+load(file_or_filename=None)[source]
+

Load preferences from a file.

+

This is a merge operation i.e. the contents of the file are added to +the node.

+

This implementation uses ‘ConfigObj’ files.

+
+ +
+
+node(path='')[source]
+

Return the node at the specified path.

+
+ +
+
+node_exists(path='')[source]
+

Return True if the node at the specified path exists.

+
+ +
+
+node_names(path='')[source]
+

Return the names of the children of the node at the specified path.

+
+ +
+
+remove(path)[source]
+

Remove the preference at the specified path.

+
+ +
+
+remove_preferences_listener(listener, path='')[source]
+

Remove a listener for changes to a node’s preferences.

+
+ +
+
+save(file_or_filename=None)[source]
+

Save the node’s preferences to a file.

+

This implementation uses ‘ConfigObj’ files.

+
+ +
+
+set(path, value)[source]
+

Set the value of the preference at the specified path.

+
+ +
+ +
+
+

apptools.preferences.preferences_helper module

+

An object that can be initialized from a preferences node.

+
+
+class apptools.preferences.preferences_helper.PreferencesHelper(**traits)[source]
+

Bases: traits.has_traits.HasTraits

+

A base class for objects that can be initialized from a preferences +node.

+

Additional traits defined on subclasses will be listened to. Changes +are then synchronized with the preferences. Note that mutations on nested +containers e.g. List(List(Str)) cannot be synchronized and should be +avoided.

+
+ +
+
+

apptools.preferences.scoped_preferences module

+

A preferences node that adds the notion of preferences scopes.

+
+
+class apptools.preferences.scoped_preferences.ScopedPreferences(**traits)[source]
+

Bases: apptools.preferences.preferences.Preferences

+

A preferences node that adds the notion of preferences scopes.

+

Scopes provide a way to access preferences in a precedence order, usually +depending on where they came from, for example from the command-line, +or set by the user in a preferences file, or the defaults (set by the +developer).

+

By default, this class provides two scopes - ‘application’ which is +persistent and ‘default’ which is not.

+

Path names passed to ‘ScopedPreferences’ nodes can be either:

+
a) a preference path as used in a standard 'Preferences' node, e.g::
+
+'acme.widget.bgcolor'.
+
+In this case the operation either takes place in the primary scope
+(for operations such as 'set' etc), or on all scopes in precedence
+order (for operations such as 'get' etc).
+
+or
+
+b) a preference path that refers to a specific scope e.g::
+
+'default/acme.widget.bgcolor'
+
+In this case the operation takes place *only* in the specified scope.
+
+
+

There is one drawback to this scheme. If you want to access a scope node +itself via the ‘clear’, ‘keys’, ‘node’, ‘node_exists’ or ‘node_names’ +methods then you have to append a trailing ‘/’ to the path. Without that, +the node would try to perform the operation in the primary scope.

+

e.g. To get the names of the children of the ‘application’ scope, use:

+
scoped.node_names('application/')
+
+
+

If you did this:

+
scoped.node_names('application')
+
+
+

Then the node would get the primary scope and try to find its child node +called ‘application’.

+

Of course you can just get the scope via:

+
application_scope = scoped.get_scope('application')
+
+
+

and then call whatever methods you like on it - which is definitely more +intentional and is highly recommended:

+
application_scope.node_names()
+
+
+
+
+add_preferences_listener(listener, path='')[source]
+

Add a listener for changes to a node’s preferences.

+
+ +
+
+clear(path='')[source]
+

Remove all preference from the node at the specified path.

+
+ +
+
+dump(indent='')[source]
+

Dump the preferences hierarchy to stdout.

+
+ +
+
+get(path, default=None, inherit=False)[source]
+

Get the value of the preference at the specified path.

+
+ +
+
+get_scope(scope_name)[source]
+

Return the scope with the specified name.

+

Return None if no such scope exists.

+
+ +
+
+keys(path='')[source]
+

Return the preference keys of the node at the specified path.

+
+ +
+
+load(file_or_filename=None)[source]
+

Load preferences from a file.

+

This loads the preferences into the primary scope.

+

fixme: I’m not sure it is worth providing an implentation here. I +think it would be better to encourage people to explicitly reference +a particular scope.

+
+ +
+
+node(path='')[source]
+

Return the node at the specified path.

+
+ +
+
+node_exists(path='')[source]
+

Return True if the node at the specified path exists.

+
+ +
+
+node_names(path='')[source]
+

Return the names of the children of the node at the specified path.

+
+ +
+
+remove(path)[source]
+

Remove the preference at the specified path.

+
+ +
+
+remove_preferences_listener(listener, path='')[source]
+

Remove a listener for changes to a node’s preferences.

+
+ +
+
+save(file_or_filename=None)[source]
+

Save the node’s preferences to a file.

+

This asks each scope in turn to save its preferences.

+

If a file or filename is specified then it is only passed to the +primary scope.

+
+ +
+
+set(path, value)[source]
+

Set the value of the preference at the specified path.

+
+ +
+ +
+
+

Module contents

+

Manages application preferences. +Part of the AppTools project of the Enthought Tool Suite

+
+
+ + +
+
+
+ +
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/5.0/api/apptools.preferences.ui.html b/5.0/api/apptools.preferences.ui.html new file mode 100644 index 000000000..fa72bce2b --- /dev/null +++ b/5.0/api/apptools.preferences.ui.html @@ -0,0 +1,405 @@ + + + + + + + apptools.preferences.ui package — Apptools Documentation + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ + + + +
+
+ +
+
+ +
+

apptools.preferences.ui package

+
+

Submodules

+
+
+

apptools.preferences.ui.api module

+
+
+

apptools.preferences.ui.i_preferences_page module

+

The interface for pages in a preferences dialog.

+
+
+class apptools.preferences.ui.i_preferences_page.IPreferencesPage[source]
+

Bases: traits.has_traits.Interface

+

The interface for pages in a preferences dialog.

+
+
+apply()[source]
+

Apply the page’s preferences.

+
+ +
+ +
+
+

apptools.preferences.ui.preferences_manager module

+

The preferences manager.

+
+
+class apptools.preferences.ui.preferences_manager.PreferencesHelpWindow[source]
+

Bases: traits.has_traits.HasTraits

+

Container class to present a view with string info.

+
+
+traits_view()[source]
+

Default view to show for this class.

+
+ +
+ +
+
+class apptools.preferences.ui.preferences_manager.PreferencesManager[source]
+

Bases: traits.has_traits.HasTraits

+

The preferences manager.

+
+
+apply()[source]
+

Apply all changes made in the manager.

+
+ +
+
+traits_view()[source]
+

Default traits view for this class.

+
+ +
+ +
+
+class apptools.preferences.ui.preferences_manager.PreferencesManagerHandler[source]
+

Bases: traitsui.handler.Handler

+

The traits UI handler for the preferences manager.

+
+
+apply(info)[source]
+

Handle the Apply button being clicked.

+
+ +
+
+close(info, is_ok)[source]
+

Close a dialog-based user interface.

+
+ +
+
+init(info)[source]
+

Initialize the controls of a user interface.

+
+ +
+
+preferences_help(info)[source]
+

Custom preferences help panel. The Traits help doesn’t work.

+
+ +
+ +
+
+

apptools.preferences.ui.preferences_node module

+

Abstract base class for a node in a preferences dialog.

+
+
+class apptools.preferences.ui.preferences_node.PreferencesNode[source]
+

Bases: apptools.preferences.ui.tree_item.TreeItem

+

Abstract base class for a node in a preferences dialog.

+

A preferences node has a name and an image which are used to represent the +node in a preferences dialog (usually in the form of a tree).

+
+
+create_page(parent)[source]
+

Creates the preference page for this node.

+
+ +
+
+dump(indent='')[source]
+

Pretty-print the node to stdout.

+
+ +
+
+lookup(name)[source]
+

Returns the child of this node with the specified Id.

+

Returns None if no such child exists.

+
+ +
+ +
+
+

apptools.preferences.ui.preferences_page module

+

A page in a preferences dialog.

+
+
+class apptools.preferences.ui.preferences_page.PreferencesPage(**traits)[source]
+

Bases: apptools.preferences.preferences_helper.PreferencesHelper

+

A page in a preferences dialog.

+
+
+apply()[source]
+

Apply the page’s preferences.

+
+ +
+ +
+
+

apptools.preferences.ui.tree_item module

+

A generic base-class for items in a tree data structure.

+

An example:-

+

root = TreeItem(data=’Root’)

+

fruit = TreeItem(data=’Fruit’) +fruit.append(TreeItem(data=’Apple’, allows_children=False)) +fruit.append(TreeItem(data=’Orange’, allows_children=False)) +fruit.append(TreeItem(data=’Pear’, allows_children=False)) +root.append(fruit)

+

veg = TreeItem(data=’Veg’) +veg.append(TreeItem(data=’Carrot’, allows_children=False)) +veg.append(TreeItem(data=’Cauliflower’, allows_children=False)) +veg.append(TreeItem(data=’Sprout’, allows_children=False)) +root.append(veg)

+
+
+class apptools.preferences.ui.tree_item.TreeItem[source]
+

Bases: traits.has_traits.HasTraits

+

A generic base-class for items in a tree data structure.

+
+
+append(child)[source]
+

Appends a child to this item.

+

This removes the child from its current parent (if it has one).

+
+ +
+
+insert(index, child)[source]
+

Inserts a child into this item at the specified index.

+

This removes the child from its current parent (if it has one).

+
+ +
+
+insert_after(after, child)[source]
+

Inserts a child into this item after the specified item.

+

This removes the child from its current parent (if it has one).

+
+ +
+
+insert_before(before, child)[source]
+

Inserts a child into this item before the specified item.

+

This removes the child from its current parent (if it has one).

+
+ +
+
+remove(child)[source]
+

Removes a child from this item.

+
+ +
+ +
+
+

apptools.preferences.ui.widget_editor module

+

An instance editor that allows total control over widget creation.

+
+
+class apptools.preferences.ui.widget_editor.WidgetEditor(*args, **traits)[source]
+

Bases: traitsui.editor_factory.EditorFactory

+

A factory widget editors.

+
+
+custom_editor(ui, object, name, description, parent)
+

Create a simple editor.

+
+ +
+
+readonly_editor(ui, object, name, description, parent)
+

Create a simple editor.

+
+ +
+
+simple_editor(ui, object, name, description, parent)[source]
+

Create a simple editor.

+
+ +
+
+text_editor(ui, object, name, description, parent)
+

Create a simple editor.

+
+ +
+ +
+
+

Module contents

+
+
+ + +
+
+
+ +
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/5.0/api/apptools.scripting.html b/5.0/api/apptools.scripting.html new file mode 100644 index 000000000..8ec515512 --- /dev/null +++ b/5.0/api/apptools.scripting.html @@ -0,0 +1,414 @@ + + + + + + + apptools.scripting package — Apptools Documentation + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +
+

apptools.scripting package

+
+

Submodules

+
+
+

apptools.scripting.api module

+

Public API for the scripting package.

+
+
+

apptools.scripting.package_globals module

+

Globals for the scripting package.

+
+
+apptools.scripting.package_globals.get_recorder()[source]
+

Return the global recorder. Does not create a new one if none +exists.

+
+ +
+
+apptools.scripting.package_globals.set_recorder(rec)[source]
+

Set the global recorder instance.

+
+ +
+
+

apptools.scripting.recordable module

+

Decorator to mark functions and methods as recordable.

+
+
+apptools.scripting.recordable.recordable(func)[source]
+

A decorator that wraps a function into one that is recordable.

+

This will record the function only if the global recorder has been +set via a set_recorder function call.

+
+ +
+
+

apptools.scripting.recorder module

+

Code to support recording to a readable and executable Python script.

+
+
FIXME:
    +
  • Support for dictionaries?

  • +
+
+
+
+
+class apptools.scripting.recorder.Recorder[source]
+

Bases: traits.has_traits.HasTraits

+
+
+clear()[source]
+

Clears all previous recorded state and unregisters all +registered objects.

+
+ +
+
+get_code()[source]
+

Returns the recorded lines as a string of printable code.

+
+ +
+
+get_object_path(object)[source]
+

Returns the path in the object hierarchy of a registered +object. Useful for debugging.

+
+ +
+
+get_script_id(object)[source]
+

Returns the script_id of a registered object. Useful when +you want to manually add a record statement.

+
+ +
+
+is_registered(object)[source]
+

Returns True if the given object is registered with the +recorder.

+
+ +
+
+record(code)[source]
+

Record a string to be stored to the output file.

+
+
Parameters
+

code (str) – A string of text.

+
+
+
+ +
+
+record_function(func, args, kw)[source]
+

Record a function call given the function and its +arguments.

+
+ +
+
+register(object, parent=None, trait_name_on_parent='', ignore=None, known=False, script_id=None)[source]
+

Register an object with the recorder. This sets up the +object for recording.

+

By default all traits (except those starting and ending with +‘_’) are recorded. For attributes that are themselves +recordable, one may mark traits with a ‘record’ metadata as +follows:

+
    +
  • If metadata record=False is set, the nested object will not be +recorded.

  • +
  • If record=True, then that object is also recorded if it is +not None.

  • +
+

If the object is a list or dict that is marked with +record=True, the list is itself not listened to for changes +but all its contents are registered.

+

If the object has a trait named recorder then this recorder +instance will be set to it if possible.

+
+
Parameters
+
    +
  • object (Instance(HasTraits)) – The object to register in the registry.

  • +
  • parent (Instance(HasTraits)) – An optional parent object in which object is contained

  • +
  • trait_name_on_parent (str) – An optional trait name of the object in the parent.

  • +
  • ignore (list(str)) – An optional list of trait names on the object to be +ignored.

  • +
  • known (bool) – Optional specification if the object id is known on the +interpreter. This is needed if you are manually injecting +code to define/create an object.

  • +
  • script_id (str) – Optionally specify a script_id to use for this object. It +is not guaranteed that this ID will be used since it may +already be in use.

  • +
+
+
+
+ +
+
+save(file)[source]
+

Save the recorded lines to the given file. It does not close +the file.

+
+ +
+
+ui_save()[source]
+

Save recording to file, pop up a UI dialog to find out where +and close the file when done.

+
+ +
+
+unregister(object)[source]
+

Unregister the given object from the recorder. This inverts +the logic of the register(…) method.

+
+ +
+
+write_script_id_in_namespace(script_id)[source]
+

If a script_id is not known in the current script’s namespace, +this sets it using the path of the object or actually +instantiating it. If this is not possible (since the script_id +matches no existing object), nothing is recorded but the +framework is notified that the particular script_id is available +in the namespace. This is useful when you want to inject code +in the namespace to create a particular object.

+
+ +
+ +
+
+exception apptools.scripting.recorder.RecorderError[source]
+

Bases: Exception

+
+ +
+
+

apptools.scripting.recorder_with_ui module

+

A Recorder subclass that presents a simple user interface.

+
+
+class apptools.scripting.recorder_with_ui.CloseHandler[source]
+

Bases: traitsui.handler.Handler

+

This class cleans up after the UI for the recorder is closed.

+
+
+close(info, is_ok)[source]
+

This method is invoked when the user closes the UI.

+
+ +
+ +
+
+class apptools.scripting.recorder_with_ui.RecorderWithUI[source]
+

Bases: apptools.scripting.recorder.Recorder

+

This class represents a Recorder but with a simple user interface.

+
+
+on_ui_close()[source]
+

Called from the CloseHandler when the UI is closed. This +method basically stops the recording.

+
+ +
+ +
+
+

apptools.scripting.util module

+

Simple utility functions provided by the scripting API.

+
+
+apptools.scripting.util.start_recording(object, ui=True, **kw)[source]
+

Convenience function to start recording. Returns the recorder.

+
+
Parameters
+
    +
  • object (object to record.) –

  • +
  • ui (bool specifying if a UI is to be shown or not) –

  • +
  • kw (Keyword arguments to pass to the register function of the) –

  • +
  • recorder.

  • +
+
+
+
+ +
+
+apptools.scripting.util.stop_recording(object, save=True)[source]
+

Stop recording the object. If save is True, this will pop up +a UI to ask where to save the script.

+
+ +
+
+

Module contents

+

Automatic script recording framework, part of the AppTools project +of the Enthought Tool Suite.

+
+
+ + +
+
+
+ +
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/5.0/api/apptools.selection.html b/5.0/api/apptools.selection.html new file mode 100644 index 000000000..a8950c469 --- /dev/null +++ b/5.0/api/apptools.selection.html @@ -0,0 +1,482 @@ + + + + + + + apptools.selection package — Apptools Documentation + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +
+

apptools.selection package

+
+

Submodules

+
+
+

apptools.selection.api module

+
+
+

apptools.selection.errors module

+
+
+exception apptools.selection.errors.IDConflictError(provider_id)[source]
+

Bases: Exception

+

Raised when a provider is added and its ID is already registered.

+
+ +
+
+exception apptools.selection.errors.ListenerNotConnectedError(provider_id, listener)[source]
+

Bases: Exception

+

Raised when a listener that was never connected is disconnected.

+
+ +
+
+exception apptools.selection.errors.ProviderNotRegisteredError(provider_id)[source]
+

Bases: Exception

+

Raised when a provider is requested by ID and not found.

+
+ +
+
+

apptools.selection.i_selection module

+
+
+class apptools.selection.i_selection.IListSelection[source]
+

Bases: apptools.selection.i_selection.ISelection

+

Selection for ordered sequences of items.

+
+
+indices = List
+

Indices of the selected objects in the selection provider.

+
+ +
+
+items = List
+

Selected objects.

+
+ +
+ +
+
+class apptools.selection.i_selection.ISelection[source]
+

Bases: traits.has_traits.Interface

+

Collection of selected items.

+
+
+is_empty()[source]
+

Is the selection empty?

+
+ +
+
+provider_id = Str
+

ID of the selection provider that created this selection object.

+
+ +
+ +
+
+

apptools.selection.i_selection_provider module

+
+
+class apptools.selection.i_selection_provider.ISelectionProvider[source]
+

Bases: traits.has_traits.Interface

+

Source of selections.

+
+
+get_selection()[source]
+

Return the current selection.

+
+
Returns
+

+
selection – ISelection

Object representing the current selection.

+
+
+

+
+
+
+ +
+
+provider_id = Str()
+

Unique ID identifying the provider.

+
+ +
+
+selection = Event
+

Event triggered when the selection changes. +The content of the event is an ISelection instance.

+
+ +
+
+set_selection(items, ignore_missing=False)[source]
+

Set the current selection to the given items.

+

If ignore_missing is True, items that are not available in the +selection provider are silently ignored. If it is False (default), +an ValueError should be raised.

+
+
Parameters
+
    +
  • -- list (items) – List of items to be selected.

  • +
  • -- bool (ignore_missing) – If False (default), the provider raises an exception if any +of the items in items is not available to be selected. +Otherwise, missing elements are silently ignored, and the rest +is selected.

  • +
+
+
+
+ +
+ +
+
+

apptools.selection.list_selection module

+
+
+class apptools.selection.list_selection.ListSelection[source]
+

Bases: traits.has_traits.HasTraits

+

Selection for ordered sequences of items.

+

This is the default implementation of the IListSelection +interface.

+
+
+classmethod from_available_items(provider_id, selected, all_items)[source]
+

Create a list selection given a list of all available items.

+

Fills in the required information (in particular, the indices) based +on a list of selected items and a list of all available items.

+
+

Note

+
    +
  • The list of available items must not contain any duplicate items.

  • +
  • It is expected that selected is populated by items in +all_items.

  • +
+
+
+ +
+
+indices = List
+

Indices of the selected objects in the selection provider.

+
+ +
+
+is_empty()[source]
+

Is the selection empty?

+
+ +
+
+items = List
+

Selected objects.

+
+ +
+
+provider_id = Str
+

ID of the selection provider that created this selection object.

+
+ +
+ +
+
+

apptools.selection.selection_service module

+
+
+class apptools.selection.selection_service.SelectionService[source]
+

Bases: traits.has_traits.HasTraits

+

The selection service connects selection providers and listeners.

+

The selection service is a register of selection providers, i.e., objects +that publish their current selection.

+

Selections can be requested actively, by explicitly requesting the current +selection in a provider (get_selection(id)()), or passively by +connecting selection listeners.

+
+
+add_selection_provider(provider)[source]
+

Add a selection provider.

+

The provider is identified by its ID. If a provider with the same +ID has been already registered, an IDConflictError +is raised.

+
+
Parameters
+

-- ISelectionProvider (provider) – The selection provider added to the internal registry.

+
+
+
+ +
+
+connect_selection_listener(provider_id, func)[source]
+

Connect a listener to selection events from a specific provider.

+

The signature if the listener callback is func(i_selection). +The listener is called:

+
    +
  1. When a provider with the given ID is registered, with its initial +selection as argument, or

  2. +
  3. whenever the provider fires a selection event.

  4. +
+

It is perfectly valid to connect a listener before a provider with the +given ID is registered. The listener will remain connected even if +the provider is repeatedly connected and disconnected.

+
+
Parameters
+
    +
  • -- str (provider_id) – The selection provider ID.

  • +
  • -- callable (func) – A callable object that is notified when the selection changes.

  • +
+
+
+
+ +
+
+disconnect_selection_listener(provider_id, func)[source]
+

Disconnect a listener from a specific provider.

+
+
Parameters
+
    +
  • -- str (provider_id) – The selection provider ID.

  • +
  • -- callable (func) – A callable object that is notified when the selection changes.

  • +
+
+
+
+ +
+
+get_selection(provider_id)[source]
+

Return the current selection of the provider with the given ID.

+

If a provider with that ID has not been registered, a +ProviderNotRegisteredError is raised.

+
+
Parameters
+

-- str (provider_id) – The selection provider ID.

+
+
Returns
+

+
selection – ISelection

The current selection of the provider.

+
+
+

+
+
+
+ +
+
+has_selection_provider(provider_id)[source]
+

Has a provider with the given ID been registered?

+
+ +
+
+remove_selection_provider(provider)[source]
+

Remove a selection provider.

+

If the provider has not been registered, a +ProviderNotRegisteredError is raised.

+
+
Parameters
+

-- ISelectionProvider (provider) – The selection provider added to the internal registry.

+
+
+
+ +
+
+set_selection(provider_id, items, ignore_missing=False)[source]
+

Set the current selection in a provider to the given items.

+

If a provider with the given ID has not been registered, a +ProviderNotRegisteredError is raised.

+

If ignore_missing is True, items that are not available in the +selection provider are silently ignored. If it is False (default), +a ValueError should be raised.

+
+
Parameters
+
    +
  • -- str (provider_id) – The selection provider ID.

  • +
  • -- list (items) – List of items to be selected.

  • +
  • -- bool (ignore_missing) – If False (default), the provider raises an exception if any +of the items in items is not available to be selected. +Otherwise, missing elements are silently ignored, and the rest +is selected.

  • +
+
+
+
+ +
+ +
+
+

Module contents

+
+
+ + +
+
+
+ +
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/5.0/api/apptools.type_registry.html b/5.0/api/apptools.type_registry.html new file mode 100644 index 000000000..276d40e0b --- /dev/null +++ b/5.0/api/apptools.type_registry.html @@ -0,0 +1,344 @@ + + + + + + + apptools.type_registry package — Apptools Documentation + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +
+

apptools.type_registry package

+
+

Submodules

+
+
+

apptools.type_registry.api module

+
+
+

apptools.type_registry.type_registry module

+
+
+class apptools.type_registry.type_registry.LazyRegistry[source]
+

Bases: apptools.type_registry.type_registry.TypeRegistry

+

A type registry that will lazily import the registered objects.

+

Register ‘__module__:__name__’ strings for the lazily imported objects. +These will only be imported when the matching type is looked up. The module +name must be a fully-qualified absolute name with all of the parent +packages specified.

+
+
+lookup_by_type(typ)[source]
+

Look up the registered object for a type.

+
+ +
+ +
+
+class apptools.type_registry.type_registry.TypeRegistry[source]
+

Bases: object

+

Register objects for types.

+

Each type maintains a stack of registered objects that can be pushed and +popped.

+
+
+lookup(instance)[source]
+

Look up the registered object for the given instance.

+
+
Parameters
+

instance (object) – An instance of a possibly registered type.

+
+
Returns
+

obj – The registered object for the type of the instance, one of the +type’s superclasses, or else one of the ABCs the type implements.

+
+
Return type
+

object

+
+
Raises
+

KeyError if the instance's type has not been registered.

+
+
+
+ +
+
+lookup_all(instance)[source]
+

Look up all the registered objects for the given instance.

+
+
Parameters
+

instance (object) – An instance of a possibly registered type.

+
+
Returns
+

objs – The list of registered objects for the instance. If the given +instance is not registered, its superclasses are searched. If none +of the superclasses are registered, search the possible ABCs.

+
+
Return type
+

list of objects

+
+
Raises
+

KeyError if the instance's type has not been registered.

+
+
+
+ +
+
+lookup_all_by_type(typ)[source]
+

Look up all the registered objects for a type.

+
+
Parameters
+

typ (type) –

+
+
Returns
+

objs – The list of registered objects for the type. If the given type is +not registered, its superclasses are searched. If none of the +superclasses are registered, search the possible ABCs.

+
+
Return type
+

list of objects

+
+
Raises
+

KeyError if the type has not been registered.

+
+
+
+ +
+
+lookup_by_type(typ)[source]
+

Look up the registered object for a type.

+
+
Parameters
+

typ (type) –

+
+
Returns
+

obj – The registered object for the type, one of its superclasses, or +else one of the ABCs it implements.

+
+
Return type
+

object

+
+
Raises
+

KeyError if the type has not been registered.

+
+
+
+ +
+
+pop(typ)[source]
+

Pop a registered object for the given type.

+
+
Parameters
+

typ (type or '__module__:__name__' string for a type) –

+
+
Returns
+

obj – The last registered object for the type.

+
+
Return type
+

object

+
+
Raises
+

KeyError if the type is not registered.

+
+
+
+ +
+
+push(typ, obj)[source]
+

Push an object onto the stack for the given type.

+
+
Parameters
+
    +
  • typ (type or '__module__:__name__' string for a type) –

  • +
  • obj (object) – The object to register.

  • +
+
+
+
+ +
+
+push_abc(typ, obj)[source]
+

Push an object onto the stack for the given ABC.

+
+
Parameters
+
    +
  • typ (abc.ABCMeta) –

  • +
  • obj (object) –

  • +
+
+
+
+ +
+ +
+
+apptools.type_registry.type_registry.get_mro(obj_class)[source]
+

Get a reasonable method resolution order of a class and its +superclasses for both old-style and new-style classes.

+
+ +
+
+

Module contents

+
+
+ + +
+
+
+
+ +
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/5.0/api/apptools.undo.action.html b/5.0/api/apptools.undo.action.html new file mode 100644 index 000000000..375395026 --- /dev/null +++ b/5.0/api/apptools.undo.action.html @@ -0,0 +1,241 @@ + + + + + + + apptools.undo.action package — Apptools Documentation + + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ + + + +
+
+ +
+
+ +
+

apptools.undo.action package

+
+

Submodules

+
+
+

apptools.undo.action.abstract_command_stack_action module

+
+
+class apptools.undo.action.abstract_command_stack_action.AbstractCommandStackAction(**traits)[source]
+

Bases: pyface.action.action.Action

+

The abstract base class for all actions that operate on a command +stack.

+
+
+destroy()[source]
+

Called when the action is no longer required.

+

By default this method does nothing, but this would be a great place to +unhook trait listeners etc.

+
+ +
+ +
+
+

apptools.undo.action.api module

+
+
+

apptools.undo.action.command_action module

+
+
+class apptools.undo.action.command_action.CommandAction[source]
+

Bases: pyface.action.action.Action

+

The CommandAction class is an Action class that wraps undo/redo +commands. It is only useful for commands that do not take any arguments or +return any result.

+
+
+perform(event)[source]
+

This is reimplemented to push a new command instance onto the +command stack.

+
+ +
+ +
+
+

apptools.undo.action.redo_action module

+
+
+class apptools.undo.action.redo_action.RedoAction(**traits)[source]
+

Bases: apptools.undo.action.abstract_command_stack_action.AbstractCommandStackAction

+

An action that redos the last command undone of the active command +stack.

+
+
+perform(event)[source]
+

Perform the action.

+
+ +
+ +
+
+

apptools.undo.action.undo_action module

+
+
+class apptools.undo.action.undo_action.UndoAction(**traits)[source]
+

Bases: apptools.undo.action.abstract_command_stack_action.AbstractCommandStackAction

+

An action that undos the last command of the active command stack.

+
+
+perform(event)[source]
+

Perform the action.

+
+ +
+ +
+
+

Module contents

+
+
+ + +
+
+
+ +
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/5.0/api/apptools.undo.html b/5.0/api/apptools.undo.html new file mode 100644 index 000000000..e78c602c1 --- /dev/null +++ b/5.0/api/apptools.undo.html @@ -0,0 +1,468 @@ + + + + + + + apptools.undo package — Apptools Documentation + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +
+

apptools.undo package

+ +
+

Submodules

+
+
+

apptools.undo.abstract_command module

+
+
+class apptools.undo.abstract_command.AbstractCommand[source]
+

Bases: traits.has_traits.HasTraits

+

The AbstractCommand class is an abstract base class that implements the +ICommand interface.

+
+
+do()[source]
+

This is called by the command stack to do the command and to return +any value. The command must save any state necessary for the ‘redo()’ +and ‘undo()’ methods to work. The class’s __init__() must also ensure +that deep copies of any arguments are made if appropriate. It is +guaranteed that this will only ever be called once and that it will be +called before any call to ‘redo()’ or ‘undo()’.

+
+ +
+
+merge(other)[source]
+

This is called by the command stack to try and merge another +command with this one. True is returned if the commands were merged. +‘other’ is the command that is about to be executed. If the commands +are merged then ‘other’ will discarded and not placed on the command +stack. A subsequent undo or redo of this modified command must have +the same effect as the two original commands.

+
+ +
+
+redo()[source]
+

This is called by the command stack to redo the command. Any +returned value will replace the value that the command stack references +from the original call to ‘do()’ or previous call to ‘redo()’.

+
+ +
+
+undo()[source]
+

This is called by the command stack to undo the command.

+
+ +
+ +
+
+

apptools.undo.api module

+
+
+

apptools.undo.command_stack module

+
+
+class apptools.undo.command_stack.CommandStack[source]
+

Bases: traits.has_traits.HasTraits

+

The CommandStack class is the default implementation of the +ICommandStack interface.

+
+
+begin_macro(name)[source]
+

This begins a macro by creating an empty command with the given +‘name’. All subsequent calls to ‘push()’ create commands that will be +children of the empty command until the next call to ‘end_macro()’. +Macros may be nested. The stack is disabled (ie. nothing can be undone +or redone) while a macro is being created (ie. while there is an +outstanding ‘end_macro()’ call).

+
+ +
+
+clear()[source]
+

This clears the stack, without undoing or redoing any commands, and +leaves the stack in a clean state. It is typically used when all +changes to the data have been abandoned.

+
+ +
+
+end_macro()[source]
+

This ends a macro.

+
+ +
+
+push(command)[source]
+

This executes a command and saves it on the command stack so that +it can be subsequently undone and redone. ‘command’ is an instance +that implements the ICommand interface. Its ‘do()’ method is called +to execute the command. If any value is returned by ‘do()’ then it is +returned by ‘push()’.

+
+ +
+
+redo(sequence_nr=0)[source]
+

If ‘sequence_nr’ is 0 then the last command that was undone is +redone and any result returned. Otherwise commands are redone up to +and including the given ‘sequence_nr’ and any result of the last of +these is returned.

+
+ +
+
+undo(sequence_nr=0)[source]
+

If ‘sequence_nr’ is 0 then the last command is undone. Otherwise +commands are undone up to and including the given ‘sequence_nr’.

+
+ +
+ +
+
+

apptools.undo.i_command module

+
+
+class apptools.undo.i_command.ICommand[source]
+

Bases: traits.has_traits.Interface

+

The command interface. The state of the data can be changed by passing +an instance that implements this interface to the ‘push()’ method of a +command stack along with any arguments.

+
+
+do()[source]
+

This is called by the command stack to do the command and to return +any value. The command must save any state necessary for the ‘redo()’ +and ‘undo()’ methods to work. The class’s __init__() must also ensure +that deep copies of any arguments are made if appropriate. It is +guaranteed that this will only ever be called once and that it will be +called before any call to ‘redo()’ or ‘undo()’.

+
+ +
+
+merge(other)[source]
+

This is called by the command stack to try and merge another +command with this one. True is returned if the commands were merged. +‘other’ is the command that is about to be executed. If the commands +are merged then ‘other’ will discarded and not placed on the command +stack. A subsequent undo or redo of this modified command must have +the same effect as the two original commands.

+
+ +
+
+redo()[source]
+

This is called by the command stack to redo the command. Any +returned value will replace the value that the command stack references +from the original call to ‘do()’ or previous call to ‘redo()’.

+
+ +
+
+undo()[source]
+

This is called by the command stack to undo the command.

+
+ +
+ +
+
+

apptools.undo.i_command_stack module

+
+
+class apptools.undo.i_command_stack.ICommandStack[source]
+

Bases: traits.has_traits.Interface

+

The command stack interface. A command stack is responsible for +managing the changes to a data model and recording those changes so that +they can be undone or redone.

+
+
+begin_macro(name)[source]
+

This begins a macro by creating an empty command with the given +‘name’. The commands passed to all subsequent calls to ‘push()’ will +be contained in the macro until the next call to ‘end_macro()’. Macros +may be nested. The stack is disabled (ie. nothing can be undone or +redone) while a macro is being created (ie. while there is an +outstanding ‘end_macro()’ call).

+
+ +
+
+clear()[source]
+

This clears the stack, without undoing or redoing any commands, and +leaves the stack in a clean state. It is typically used when all +changes to the data have been abandoned.

+
+ +
+
+end_macro()[source]
+

This ends a macro.

+
+ +
+
+push(command)[source]
+

This executes a command and saves it on the command stack so that +it can be subsequently undone and redone. ‘command’ is an instance +that implements the ICommand interface. Its ‘do()’ method is called +to execute the command. If any value is returned by ‘do()’ then it is +returned by ‘push()’. The command stack will keep a reference to the +result so that it can recognise it as an argument to a subsequent +command (which allows a script to properly save a result needed later).

+
+ +
+
+redo(sequence_nr=0)[source]
+

If ‘sequence_nr’ is 0 then the last command that was undone is +redone and any result returned. Otherwise commands are redone up to +and including the given ‘sequence_nr’ and any result of the last of +these is returned.

+
+ +
+
+undo(sequence_nr=0)[source]
+

If ‘sequence_nr’ is 0 then the last command is undone. Otherwise +commands are undone up to and including the given ‘sequence_nr’.

+
+ +
+ +
+
+

apptools.undo.i_undo_manager module

+
+
+class apptools.undo.i_undo_manager.IUndoManager[source]
+

Bases: traits.has_traits.Interface

+

The undo manager interface. An undo manager is responsible for one or +more command stacks. Typically an application would have a single undo +manager.

+
+
+redo()[source]
+

Redo the last undone command of the active command stack.

+
+ +
+
+undo()[source]
+

Undo the last command of the active command stack.

+
+ +
+ +
+
+

apptools.undo.undo_manager module

+
+
+class apptools.undo.undo_manager.UndoManager[source]
+

Bases: traits.has_traits.HasTraits

+

The UndoManager class is the default implementation of the +IUndoManager interface.

+
+
+redo()[source]
+

Redo the last undone command of the active command stack.

+
+ +
+
+undo()[source]
+

Undo the last command of the active command stack.

+
+ +
+ +
+
+

Module contents

+

Supports undoing and scripting application commands. +Part of the AppTools project of the Enthought Tool Suite.

+
+
+ + +
+
+
+ +
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/5.0/api/modules.html b/5.0/api/modules.html new file mode 100644 index 000000000..2cef3b579 --- /dev/null +++ b/5.0/api/modules.html @@ -0,0 +1,280 @@ + + + + + + + apptools — Apptools Documentation + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +
+

apptools

+
+ +
+
+ + +
+
+
+
+
+ +

Previous topic

+

API documentation

+

Next topic

+

apptools package

+

This Page

+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/5.0/genindex.html b/5.0/genindex.html new file mode 100644 index 000000000..abcc35441 --- /dev/null +++ b/5.0/genindex.html @@ -0,0 +1,1536 @@ + + + + + + + + Index — Apptools Documentation + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ + +

Index

+ +
+ A + | B + | C + | D + | E + | F + | G + | H + | I + | J + | K + | L + | M + | N + | O + | P + | Q + | R + | S + | T + | U + | V + | W + +
+

A

+ + + +
+ +

B

+ + + +
+ +

C

+ + + +
+ +

D

+ + + +
+ +

E

+ + + +
+ +

F

+ + + +
+ +

G

+ + + +
+ +

H

+ + + +
+ +

I

+ + + +
+ +

J

+ + +
+ +

K

+ + +
+ +

L

+ + + +
+ +

M

+ + + +
+ +

N

+ + + +
+ +

O

+ + + +
+ +

P

+ + + +
+ +

Q

+ + +
+ +

R

+ + + +
+ +

S

+ + + +
+ +

T

+ + + +
+ +

U

+ + + +
+ +

V

+ + + +
+ +

W

+ + + +
+ + + +
+
+
+
+
+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/5.0/index.html b/5.0/index.html new file mode 100644 index 000000000..53e7b1311 --- /dev/null +++ b/5.0/index.html @@ -0,0 +1,179 @@ + + + + + + + AppTools Documentation — Apptools Documentation + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + + +
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/5.0/io/introduction.html b/5.0/io/introduction.html new file mode 100644 index 000000000..1f4d10d3d --- /dev/null +++ b/5.0/io/introduction.html @@ -0,0 +1,169 @@ + + + + + + + File I/O — Apptools Documentation + + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +
+

File I/O

+

The apptools.io package provides a traited File object provides +properties and methods for common file path manipulation operations. Much of +this functionality was implemented before Python 3 pathlib standard library +became available to provide similar support. For new code we encourage users +to investigate if pathlib can satisfy their use cases before they turn to +the apptools.io File object

+
+

HDF5 File Support

+

The apptools.io.h5 sub-package provides a wrapper around PyTables +with a dictionary-style mapping.

+
+
+ + +
+
+
+
+
+ +

Table of Contents

+ + +

Previous topic

+

Naming

+

Next topic

+

API documentation

+

This Page

+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/5.0/naming/Introduction.html b/5.0/naming/Introduction.html new file mode 100644 index 000000000..6c5f08423 --- /dev/null +++ b/5.0/naming/Introduction.html @@ -0,0 +1,154 @@ + + + + + + + Naming — Apptools Documentation + + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +
+

Naming

+

apptools.naming package is a Python implementation of the Naming portion of the Java +Naming and Directory Interface, +including specific implementations for a heirarchy of Python objects. You can +also find the Java JNDI tutorial here.

+
+ + +
+
+
+
+
+ +

Previous topic

+

The selection service

+

Next topic

+

File I/O

+

This Page

+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/5.0/objects.inv b/5.0/objects.inv new file mode 100644 index 000000000..784d3243d Binary files /dev/null and b/5.0/objects.inv differ diff --git a/5.0/preferences/Preferences.html b/5.0/preferences/Preferences.html new file mode 100644 index 000000000..062f6c0c0 --- /dev/null +++ b/5.0/preferences/Preferences.html @@ -0,0 +1,466 @@ + + + + + + + Preferences — Apptools Documentation + + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +
+

Preferences

+

The preferences package provides a simple API for managing application +preferences. The classes in the package are implemented using a layered +approach where the lowest layer provides access to the raw preferences +mechanism and each layer on top providing more convenient ways to get and set +preference values.

+
+

The Basic Preferences Mechanism

+

Lets start by taking a look at the lowest layer which consists of the +IPreferences interface and its default implementation in the Preferences +class. This layer implements the basic preferences system which is a +hierarchical arrangement of preferences ‘nodes’ (where each node is simply an +object that implements the IPreferences interface). Nodes in the hierarchy can +contain preference settings and/or child nodes. This layer also provides a +default way to read and write preferences from the filesystem using the +excellent ConfigObj package.

+

This all sounds a bit complicated but, believe me, it isn’t! To prove it +(hopefully) lets look at an example. Say I have the following preferences in +a file ‘example.ini’:

+
[acme.ui]
+bgcolor = blue
+width = 50
+ratio = 1.0
+visible = True
+
+[acme.ui.splash_screen]
+image = splash
+fgcolor = red
+
+
+

I can create a preferences hierarchy from this file by:

+
>>> from apptools.preferences.api import Preferences
+>>> preferences = Preferences(filename='example.ini')
+>>> preferences.dump()
+
+ Node() {}
+   Node(acme) {}
+     Node(ui) {'bgcolor': 'blue', 'width': '50', 'ratio': '1.0', 'visible': 'True'}
+       Node(splash_screen) {'image': 'splash', 'fgcolor': 'red'}
+
+
+

The ‘dump’ method (useful for debugging etc) simply ‘pretty prints’ a +preferences hierarchy. The dictionary next to each node contains the node’s +actual preferences. In this case, the root node (the node with no name) is the +preferences object that we created. This node now has one child node ‘acme’, +which contains no preferences. The ‘acme’ node has one child, ‘ui’, which +contains some preferences (e.g. ‘bgcolor’) and also a child node +‘splash_screen’ which also contains preferences (e.g. ‘image’).

+

To look up a preference we use:

+
>>> preferences.get('acme.ui.bgcolor')
+'blue'
+
+
+

If no such preferences exists then, by default, None is returned:

+
>>> preferences.get('acme.ui.bogus') is None
+True
+
+
+

You can also specify an explicit default value:

+
>>> preferences.get('acme.ui.bogus', 'fred')
+'fred'
+
+
+

To set a preference we use:

+
>>> preferences.set('acme.ui.bgcolor', 'red')
+>>> preferences.get('acme.ui.bgcolor')
+'red'
+
+
+

And to make sure the preferences are saved back to disk:

+
>>> preferences.flush()
+
+
+

To add a new preference value we simply set it:

+
>>> preferences.set('acme.ui.fgcolor', 'black')
+>>> preferences.get('acme.ui.fgcolor')
+'black'
+
+
+

Any missing nodes in a call to ‘set’ are created automatically, hence:

+
>>> preferences.set('acme.ui.button.fgcolor', 'white')
+>>> preferences.get('acme.ui.button.fgcolor')
+'white'
+
+
+

Preferences can also be ‘inherited’. e.g. Notice that the ‘splash_screen’ +node does not contain a ‘bgcolor’ preference, and hence:

+
>>> preferences.get('acme.ui.splash_screen.bgcolor') is None
+True
+
+
+

But if we allow the ‘inheritance’ of preference values then:

+
>>> preferences.get('acme.ui.splash_screen.bgcolor', inherit=True)
+'red'
+
+
+

By using ‘inheritance’ here the preferences system will try the following +preferences:

+
'acme.ui.splash_screen.bgcolor'
+'acme.ui.bgcolor'
+'acme.bgcolor'
+'bgcolor'
+
+
+
+

Strings, Glorious Strings

+

At this point it is worth mentioning that preferences are always stored and +returned as strings. This is because of the limitations of the traditional +‘.ini’ file format i.e. they don’t contain any type information! Now before you +start panicking, this doesn’t mean that all of your preferences have to be +strings! Currently the preferences system allows, strings(!), booleans, ints, +longs, floats and complex numbers. When you store a non-string value it gets +converted to a string for you, but you always get a string back:

+
>>> preferences.get('acme.ui.width')
+'50'
+>>> preferences.set('acme.ui.width', 100)
+>>> preferences.get('acme.ui.width')
+'100'
+
+>>> preferences.get('acme.ui.visible')
+'True'
+>>> preferences.set('acme.ui.visible', False)
+>>> preferences.get('acme.ui.visible')
+'False'
+
+
+

This is obviously not terribly convenient, and so the following section +discusses how we associate type information with our preferences to make +getting and setting them more natural.

+
+
+
+

Preferences and Types

+

As mentioned previously, we would like to be able to get and set non-string +preferences in a more convenient way. This is where the PreferencesHelper +class comes in.

+

Let’s take another look at ‘example.ini’:

+
[acme.ui]
+bgcolor = blue
+width = 50
+ratio = 1.0
+visible = True
+
+[acme.ui.splash_screen]
+image = splash
+fgcolor = red
+
+
+

Say, I am interested in the preferences in the ‘acme.ui’ section. I can use a +preferences helper as follows:

+
from apptools.preferences.api import PreferencesHelper
+
+class SplashScreenPreferences(PreferencesHelper):
+    """ A preferences helper for the splash screen. """
+
+    preferences_path = 'acme.ui'
+
+    bgcolor = Str
+    width   = Int
+    ratio   = Float
+    visible = Bool
+
+>>> preferences = Preferences(filename='example.ini')
+>>> helper = SplashScreenPreferences(preferences=preferences)
+>>> helper.bgcolor
+'blue'
+>>> helper.width
+50
+>>> helper.ratio
+1.0
+>>> helper.visible
+True
+
+
+

And, obviously, I can set the value of the preferences via the helper too:

+
>>> helper.ratio = 0.5
+
+
+

And if you want to prove to yourself it really did set the preference:

+
>>> preferences.get('acme.ui.ratio')
+'0.5'
+
+
+

Using a preferences helper you also get notified via the usual trait +mechanism when the preferences are changed (either via the helper or via the +preferences node directly:

+
def listener(obj, trait_name, old, new):
+    print(trait_name, old, new)
+
+>>> helper.on_trait_change(listener)
+>>> helper.ratio = 0.75
+ratio 0.5 0.75
+>>> preferences.set('acme.ui.ratio', 0.33)
+ratio 0.75 0.33
+
+
+
+
+

Scoped Preferences

+

In many applications the idea of preferences scopes is useful. In a scoped +system, an actual preference value can be stored in any scope and when a call +is made to the ‘get’ method the scopes are searched in order of precedence.

+

The default implementation (in the ScopedPreferences class) provides two +scopes by default:

+
    +
  1. The application scope

  2. +
+

This scope stores itself in the ‘ETSConfig.application_home’ directory. This +scope is generally used when setting any user preferences.

+
    +
  1. The default scope

  2. +
+

This scope is transient (i.e. it does not store itself anywhere). This scope +is generally used to load any predefined default values into the preferences +system.

+

If you are happy with the default arrangement, then using the scoped +preferences is just like using the plain old non-scoped version:

+
>>> from apptools.preferences.api import ScopedPreferences
+>>> preferences = ScopedPreferences(filename='example.ini')
+>>> preferences.load('example.ini')
+>>> preferences.dump()
+
+ Node() {}
+   Node(application) {}
+     Node(acme) {}
+       Node(ui) {'bgcolor': 'blue', 'width': '50', 'ratio': '1.0', 'visible': 'True'}
+         Node(splash_screen) {'image': 'splash', 'fgcolor': 'red'}
+   Node(default) {}
+
+
+

Here you can see that the root node now has a child node representing each +scope.

+

When we are getting and setting preferences using scopes we generally want the +following behaviour:

+

a) When we get a preference we want to look it up in each scope in order. The +first scope that contains a value ‘wins’.

+

b) When we set a preference, we want to set it in the first scope. By default +this means that when we set a preference it will be set in the application +scope. This is exactly what we want as the application scope is the scope that +is persistent.

+

So usually, we just use the scoped preferences as before:

+
>>> preferences.get('acme.ui.bgcolor')
+'blue'
+>>> preferences.set('acme.ui.bgcolor', 'red')
+>>> preferences.dump()
+
+ Node() {}
+   Node(application) {}
+     Node(acme) {}
+       Node(ui) {'bgcolor': 'red', 'width': '50', 'ratio': '1.0', 'visible': 'True'}
+         Node(splash_screen) {'image': 'splash', 'fgcolor': 'red'}
+   Node(default) {}
+
+
+

And, conveniently, preference helpers work just the same with scoped +preferences too:

+
>>> helper = SplashScreenPreferences(preferences=preferences)
+>>> helper.bgcolor
+'red'
+>>> helper.width
+50
+>>> helper.ratio
+1.0
+>>> helper.visible
+True
+
+
+
+

Accessing a particular scope

+

Should you care about getting or setting a preference in a particular scope +then you use the following syntax:

+
>>> preferences.set('default/acme.ui.bgcolor', 'red')
+>>> preferences.get('default/acme.ui.bgcolor')
+'red'
+>>> preferences.dump()
+
+ Node() {}
+   Node(application) {}
+     Node(acme) {}
+       Node(ui) {'bgcolor': 'red', 'width': '50', 'ratio': '1.0', 'visible': 'True'}
+         Node(splash_screen) {'image': 'splash', 'fgcolor': 'red'}
+   Node(default) {}
+     Node(acme) {}
+       Node(ui) {'bgcolor': 'red'}
+
+
+

You can also get hold of a scope via:

+
>>> default = preferences.get_scope('default')
+
+
+

And then perform any of the usual operations on it.

+
+
+
+

Further Reading

+

So that’s a quick tour around the basic useage of the preferences API. For more +information about what is provided take a look at the API documentation.

+

If you are using Envisage to build your applications then you might also be +interested in the Preferences in Envisage section.

+
+
+ + +
+
+
+
+ +
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/5.0/preferences/PreferencesInEnvisage.html b/5.0/preferences/PreferencesInEnvisage.html new file mode 100644 index 000000000..cba25dc9f --- /dev/null +++ b/5.0/preferences/PreferencesInEnvisage.html @@ -0,0 +1,189 @@ + + + + + + + Preferences in Envisage — Apptools Documentation + + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +
+

Preferences in Envisage

+

This section discusses how an Envisage application uses the preferences +mechanism. Envisage tries not to dictate too much, and so this describes the +default behaviour, but you are free to override it as desired.

+

Envisage uses the default implementation of the ScopedPreferences class which +is made available via the application’s ‘preferences’ trait:

+
>>> application = Application(id='myapplication')
+>>> application.preferences.set('acme.ui.bgcolor', 'yellow')
+>>> application.preferences.get('acme.ui.bgcolor')
+'yellow'
+
+
+

Hence, you use the Envisage preferences just like you would any other scoped +preferences.

+

It also registers itself as the default preferences node used by the +PreferencesHelper class. Hence you don’t need to provide a preferences node +explicitly to your helper:

+
>>> helper = SplashScreenPreferences()
+>>> helper.bgcolor
+'blue'
+>>> helper.width
+100
+>>> helper.ratio
+1.0
+>>> helper.visible
+True
+
+
+

The only extra thing that Envisage does for you is to provide an extension +point that allows you to contribute any number of ‘.ini’ files that are +loaded into the default scope when the application is started.

+

e.g. To contribute a preference file for my plugin I might use:

+
class MyPlugin(Plugin):
+    ...
+
+    @contributes_to('envisage.preferences')
+    def get_preferences(self, application):
+        return ['pkgfile://mypackage:preferences.ini']
+
+
+
+ + +
+
+
+
+
+ +

Previous topic

+

Preferences

+

Next topic

+

Automatic script recording

+

This Page

+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/5.0/py-modindex.html b/5.0/py-modindex.html new file mode 100644 index 000000000..7b3cbde79 --- /dev/null +++ b/5.0/py-modindex.html @@ -0,0 +1,692 @@ + + + + + + + Python Module Index — Apptools Documentation + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ + +

Python Module Index

+ +
+ a +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
 
+ a
+ apptools +
    + apptools.io +
    + apptools.io.api +
    + apptools.io.file +
    + apptools.io.h5 +
    + apptools.io.h5.dict_node +
    + apptools.io.h5.file +
    + apptools.io.h5.table_node +
    + apptools.io.h5.utils +
    + apptools.logger +
    + apptools.logger.agent +
    + apptools.logger.agent.attachments +
    + apptools.logger.agent.quality_agent_mailer +
    + apptools.logger.agent.quality_agent_view +
    + apptools.logger.api +
    + apptools.logger.custom_excepthook +
    + apptools.logger.log_point +
    + apptools.logger.log_queue_handler +
    + apptools.logger.logger +
    + apptools.logger.plugin +
    + apptools.logger.plugin.logger_plugin +
    + apptools.logger.plugin.logger_preferences +
    + apptools.logger.plugin.logger_service +
    + apptools.logger.plugin.view +
    + apptools.logger.plugin.view.logger_preferences_page +
    + apptools.logger.plugin.view.logger_view +
    + apptools.logger.ring_buffer +
    + apptools.naming +
    + apptools.naming.address +
    + apptools.naming.api +
    + apptools.naming.binding +
    + apptools.naming.context +
    + apptools.naming.dir_context +
    + apptools.naming.dynamic_context +
    + apptools.naming.exception +
    + apptools.naming.initial_context +
    + apptools.naming.initial_context_factory +
    + apptools.naming.naming_event +
    + apptools.naming.naming_manager +
    + apptools.naming.object_factory +
    + apptools.naming.object_serializer +
    + apptools.naming.py_context +
    + apptools.naming.py_object_factory +
    + apptools.naming.pyfs_context +
    + apptools.naming.pyfs_context_factory +
    + apptools.naming.pyfs_initial_context_factory +
    + apptools.naming.pyfs_object_factory +
    + apptools.naming.pyfs_state_factory +
    + apptools.naming.reference +
    + apptools.naming.referenceable +
    + apptools.naming.referenceable_state_factory +
    + apptools.naming.state_factory +
    + apptools.naming.trait_defs +
    + apptools.naming.trait_defs.api +
    + apptools.naming.trait_defs.naming_traits +
    + apptools.naming.unique_name +
    + apptools.persistence +
    + apptools.persistence.file_path +
    + apptools.persistence.project_loader +
    + apptools.persistence.state_pickler +
    + apptools.persistence.updater +
    + apptools.persistence.version_registry +
    + apptools.persistence.versioned_unpickler +
    + apptools.preferences +
    + apptools.preferences.api +
    + apptools.preferences.i_preferences +
    + apptools.preferences.package_globals +
    + apptools.preferences.preference_binding +
    + apptools.preferences.preferences +
    + apptools.preferences.preferences_helper +
    + apptools.preferences.scoped_preferences +
    + apptools.preferences.ui +
    + apptools.preferences.ui.api +
    + apptools.preferences.ui.i_preferences_page +
    + apptools.preferences.ui.preferences_manager +
    + apptools.preferences.ui.preferences_node +
    + apptools.preferences.ui.preferences_page +
    + apptools.preferences.ui.tree_item +
    + apptools.preferences.ui.widget_editor +
    + apptools.scripting +
    + apptools.scripting.api +
    + apptools.scripting.package_globals +
    + apptools.scripting.recordable +
    + apptools.scripting.recorder +
    + apptools.scripting.recorder_with_ui +
    + apptools.scripting.util +
    + apptools.selection +
    + apptools.selection.api +
    + apptools.selection.errors +
    + apptools.selection.i_selection +
    + apptools.selection.i_selection_provider +
    + apptools.selection.list_selection +
    + apptools.selection.selection_service +
    + apptools.type_registry +
    + apptools.type_registry.api +
    + apptools.type_registry.type_registry +
    + apptools.undo +
    + apptools.undo.abstract_command +
    + apptools.undo.action +
    + apptools.undo.action.abstract_command_stack_action +
    + apptools.undo.action.api +
    + apptools.undo.action.command_action +
    + apptools.undo.action.redo_action +
    + apptools.undo.action.undo_action +
    + apptools.undo.api +
    + apptools.undo.command_stack +
    + apptools.undo.i_command +
    + apptools.undo.i_command_stack +
    + apptools.undo.i_undo_manager +
    + apptools.undo.undo_manager +
+ + +
+
+
+
+
+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/5.0/scripting/introduction.html b/5.0/scripting/introduction.html new file mode 100644 index 000000000..add6b06ce --- /dev/null +++ b/5.0/scripting/introduction.html @@ -0,0 +1,336 @@ + + + + + + + Automatic script recording — Apptools Documentation + + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +
+

Automatic script recording

+

This package provides a very handy and powerful Python script recording +facility. This can be used to:

+
+
    +
  • record all actions performed on a traits based UI into a human +readable, Python script that should be able to recreate your UI +actions.

  • +
  • easily learn the scripting API of an application.

  • +
+
+

This package is not just a toy framework and is powerful enough to +provide full script recording to the Mayavi application. Mayavi is a +powerful 3D visualization tool that is part of ETS.

+
+

The scripting API

+

The scripting API primarily allows you to record UI actions for objects +that have Traits. Technically the framework listens to all trait +changes so will work outside a UI. We do not document the full API +here, the best place to look for that is the +apptools.scripting.recorder module which is reasonably well +documented. We provide a high level overview of the library.

+

The quickest way to get started is to look at a small example.

+
+

A tour by example

+

The following example is taken from the test suite. Consider a set of +simple objects organized in a hierarchy:

+
from traits.api import (HasTraits, Float, Instance,
+        Str, List, Bool, HasStrictTraits, Tuple, PrefixMap, Range,
+        Trait)
+from apptools.scripting.api import (Recorder, recordable,
+    set_recorder)
+
+class Property(HasStrictTraits):
+    color = Tuple(Range(0.0, 1.0), Range(0.0, 1.0), Range(0.0, 1.0))
+    opacity = Range(0.0, 1.0, 1.0)
+    representation = PrefixMap(
+        {"surface": 2, "wireframe": 1, "points": 0},
+        default_value="surface"
+    )
+
+class Toy(HasTraits):
+    color = Str
+    type = Str
+    # Note the use of the trait metadata to ignore this trait.
+    ignore = Bool(False, record=False)
+
+class Child(HasTraits):
+    name = Str('child')
+    age = Float(10.0)
+    # The recorder walks through sub-instances if they are marked
+    # with record=True
+    property = Instance(Property, (), record=True)
+    toy = Instance(Toy, record=True)
+    friends = List(Str)
+
+    # The decorator records the method.
+    @recordable
+    def grow(self, x):
+        """Increase age by x years."""
+        self.age += x
+
+class Parent(HasTraits):
+    children = List(Child, record=True)
+    recorder = Instance(Recorder, record=False)
+
+
+

Using these simple classes we first create a simple object hierarchy as +follows:

+
p = Parent()
+c = Child()
+t = Toy()
+c.toy = t
+p.children.append(c)
+
+
+

Given this hierarchy, we’d like to be able to record a script. To do +this we setup the recording infrastructure:

+
from mayavi.core.recorder import Recorder, set_recorder
+# Create a recorder.
+r = Recorder()
+# Set the global recorder so the decorator works.
+set_recorder(r)
+r.register(p)
+r.recording = True
+
+
+

The key method here is the r.register(p) call above. It looks at +the traits of p and finds all traits and nested objects that specify +a record=True in their trait metadata (all methods starting and +ending with _ are ignored). All sub-objects are in turn registered +with the recorder and so on. Callbacks are attached to traits changes +and these are wired up to produce readable and executable code. The +set_recorder(r) call is also very important and sets the global +recorder so the framework listens to any functions that are decorated +with the recordable decorator.

+

Now lets test this out like so:

+
# The following will be recorded.
+c.name = 'Shiva'
+c.property.representation = 'w'
+c.property.opacity = 0.4
+c.grow(1)
+
+
+

To see what’s been recorded do this:

+
print(r.script)
+
+
+

This prints:

+
child = parent.children[0]
+child.name = 'Shiva'
+child.property.representation = 'wireframe'
+child.property.opacity = 0.40000000000000002
+child.grow(1)
+
+
+

The recorder internally maintains a mapping between objects and unique +names for each object. It also stores the information about the +location of a particular object in the object hierarchy. For example, +the path to the Toy instance in the hierarchy above is +parent.children[0].toy. Since scripting with lists this way can be +tedious, the recorder first instantiates the child:

+
child = parent.children[0]
+
+
+

Subsequent lines use the child attribute. The recorder always tries +to instantiate the object referred to using its path information in this +manner.

+

To record a function or method call one must simply decorate the +function/method with the recordable decorator. Nested recordable +functions are not recorded and trait changes are also not recorded if +done inside a recordable function.

+
+

Note

+
    +
  1. It is very important to note that the global recorder must be set +via the set_recorder method. The recordable decorator +relies on this being set to work.

  2. +
  3. The recordable decorator will work with plain Python classes +and with functions too.

  4. +
+
+

To stop recording do this:

+
r.unregister(p)
+r.recording = False
+
+
+

The r.unregister(p) reverses the r.register(p) call and +unregisters all nested objects as well.

+
+
+

Advanced use cases

+

Here are a few advanced use cases.

+
+
    +
  • The API also provides a RecorderWithUI class that provides a +simple user interface that prints the recorded script and allows the +user to save the script.

  • +
  • Sometimes it is not enough to just record trait changes, one may want +to pass an arbitrary string or command when recording is occurring. +To allow for this, if one defines a recorder trait on the object, +it is set to the current recorder. One can then use this recorder to +do whatever one wants. This is very convenient.

  • +
  • To ignore specific traits one must specify either a record=False +metadata to the trait definition or specify a list of strings to the +register method in the ignore keyword argument.

  • +
  • If you want to use a specific name for an object on the script you +can pass the script_id parameter to the register function.

  • +
+
+

For more details on the recorder itself we suggest reading the module +source code. It is fairly well documented and with the above background +should be enough to get you going.

+
+
+
+ + +
+
+
+
+
+ +

Table of Contents

+ + +

Previous topic

+

Preferences in Envisage

+

Next topic

+

Undo Framework

+

This Page

+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/5.0/search.html b/5.0/search.html new file mode 100644 index 000000000..fb3726636 --- /dev/null +++ b/5.0/search.html @@ -0,0 +1,143 @@ + + + + + + + Search — Apptools Documentation + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +

Search

+
+ +

+ Please activate JavaScript to enable the search + functionality. +

+
+

+ From here you can search these documents. Enter your search + words into the box below and click "search". Note that the search + function will automatically search for all of the words. Pages + containing fewer words won't appear in the result list. +

+
+ + + +
+ +
+ +
+ +
+
+
+
+
+ +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/5.0/searchindex.js b/5.0/searchindex.js new file mode 100644 index 000000000..2f5fef6a4 --- /dev/null +++ b/5.0/searchindex.js @@ -0,0 +1 @@ +Search.setIndex({docnames:["api","api/apptools","api/apptools.io","api/apptools.io.h5","api/apptools.logger","api/apptools.logger.agent","api/apptools.logger.plugin","api/apptools.logger.plugin.view","api/apptools.naming","api/apptools.naming.trait_defs","api/apptools.persistence","api/apptools.preferences","api/apptools.preferences.ui","api/apptools.scripting","api/apptools.selection","api/apptools.type_registry","api/apptools.undo","api/apptools.undo.action","api/modules","index","io/introduction","naming/Introduction","preferences/Preferences","preferences/PreferencesInEnvisage","scripting/introduction","selection/selection","undo/Introduction"],envversion:{"sphinx.domains.c":1,"sphinx.domains.changeset":1,"sphinx.domains.citation":1,"sphinx.domains.cpp":1,"sphinx.domains.javascript":1,"sphinx.domains.math":2,"sphinx.domains.python":1,"sphinx.domains.rst":1,"sphinx.domains.std":1,"sphinx.ext.viewcode":1,sphinx:56},filenames:["api.rst","api/apptools.rst","api/apptools.io.rst","api/apptools.io.h5.rst","api/apptools.logger.rst","api/apptools.logger.agent.rst","api/apptools.logger.plugin.rst","api/apptools.logger.plugin.view.rst","api/apptools.naming.rst","api/apptools.naming.trait_defs.rst","api/apptools.persistence.rst","api/apptools.preferences.rst","api/apptools.preferences.ui.rst","api/apptools.scripting.rst","api/apptools.selection.rst","api/apptools.type_registry.rst","api/apptools.undo.rst","api/apptools.undo.action.rst","api/modules.rst","index.rst","io/introduction.rst","naming/Introduction.rst","preferences/Preferences.rst","preferences/PreferencesInEnvisage.rst","scripting/introduction.rst","selection/selection.rst","undo/Introduction.rst"],objects:{"":{apptools:[1,0,0,"-"]},"apptools.io":{api:[2,0,0,"-"],file:[2,0,0,"-"],h5:[3,0,0,"-"]},"apptools.io.file":{File:[2,1,1,""]},"apptools.io.file.File":{"delete":[2,2,1,""],copy:[2,2,1,""],create_file:[2,2,1,""],create_folder:[2,2,1,""],create_folders:[2,2,1,""],create_package:[2,2,1,""],make_writeable:[2,2,1,""],move:[2,2,1,""]},"apptools.io.h5":{dict_node:[3,0,0,"-"],file:[3,0,0,"-"],table_node:[3,0,0,"-"],utils:[3,0,0,"-"]},"apptools.io.h5.dict_node":{ARRAY_PROXY_KEY:[3,3,1,""],H5DictNode:[3,1,1,""]},"apptools.io.h5.dict_node.H5DictNode":{add_to_h5file:[3,2,1,""],data:[3,2,1,""],flush:[3,2,1,""],is_dict_node:[3,2,1,""],keys:[3,2,1,""]},"apptools.io.h5.file":{H5Attrs:[3,1,1,""],H5File:[3,1,1,""],H5Group:[3,1,1,""],get_atom:[3,5,1,""],h5_group_wrapper:[3,5,1,""],iterator_length:[3,5,1,""]},"apptools.io.h5.file.H5Attrs":{get:[3,2,1,""],items:[3,2,1,""],keys:[3,2,1,""],values:[3,2,1,""]},"apptools.io.h5.file.H5File":{close:[3,2,1,""],create_array:[3,2,1,""],create_dict:[3,2,1,""],create_group:[3,2,1,""],create_table:[3,2,1,""],exists_error:[3,4,1,""],is_open:[3,2,1,""],iteritems:[3,2,1,""],join_path:[3,2,1,""],open:[3,2,1,""],remove_group:[3,2,1,""],remove_node:[3,2,1,""],root:[3,2,1,""],split_path:[3,2,1,""]},"apptools.io.h5.file.H5Group":{children_names:[3,2,1,""],create_array:[3,2,1,""],create_dict:[3,2,1,""],create_group:[3,2,1,""],create_table:[3,2,1,""],filename:[3,2,1,""],iter_groups:[3,2,1,""],name:[3,2,1,""],pathname:[3,2,1,""],remove_group:[3,2,1,""],remove_node:[3,2,1,""],root:[3,2,1,""],subgroup_names:[3,2,1,""]},"apptools.io.h5.table_node":{H5TableNode:[3,1,1,""]},"apptools.io.h5.table_node.H5TableNode":{add_to_h5file:[3,2,1,""],append:[3,2,1,""],is_table_node:[3,2,1,""],ix:[3,2,1,""],keys:[3,2,1,""],to_dataframe:[3,2,1,""]},"apptools.io.h5.utils":{open_h5file:[3,5,1,""]},"apptools.logger":{agent:[5,0,0,"-"],api:[4,0,0,"-"],custom_excepthook:[4,0,0,"-"],log_point:[4,0,0,"-"],log_queue_handler:[4,0,0,"-"],logger:[4,0,0,"-"],plugin:[6,0,0,"-"],ring_buffer:[4,0,0,"-"]},"apptools.logger.agent":{attachments:[5,0,0,"-"],quality_agent_mailer:[5,0,0,"-"],quality_agent_view:[5,0,0,"-"]},"apptools.logger.agent.attachments":{Attachments:[5,1,1,""]},"apptools.logger.agent.attachments.Attachments":{package_any_relevant_files:[5,2,1,""],package_single_project:[5,2,1,""],package_workspace:[5,2,1,""]},"apptools.logger.agent.quality_agent_mailer":{create_email_message:[5,5,1,""]},"apptools.logger.agent.quality_agent_view":{QualityAgentView:[5,1,1,""]},"apptools.logger.agent.quality_agent_view.QualityAgentView":{cc_address:[5,4,1,""],comments:[5,4,1,""],from_address:[5,4,1,""],help_id:[5,4,1,""],include_userdata:[5,4,1,""],msg:[5,4,1,""],priority:[5,4,1,""],service:[5,4,1,""],size:[5,4,1,""],smtp_server:[5,4,1,""],subject:[5,4,1,""],title:[5,4,1,""],to_address:[5,4,1,""]},"apptools.logger.custom_excepthook":{custom_excepthook:[4,5,1,""]},"apptools.logger.log_point":{log_point:[4,5,1,""]},"apptools.logger.log_queue_handler":{LogQueueHandler:[4,1,1,""]},"apptools.logger.log_queue_handler.LogQueueHandler":{emit:[4,2,1,""],get:[4,2,1,""],has_new_records:[4,2,1,""],reset:[4,2,1,""]},"apptools.logger.logger":{LogFileHandler:[4,1,1,""],add_log_queue_handler:[4,5,1,""]},"apptools.logger.plugin":{logger_plugin:[6,0,0,"-"],logger_preferences:[6,0,0,"-"],logger_service:[6,0,0,"-"],view:[7,0,0,"-"]},"apptools.logger.plugin.logger_plugin":{LoggerPlugin:[6,1,1,""]},"apptools.logger.plugin.logger_plugin.LoggerPlugin":{MAIL_FILES:[6,4,1,""],PREFERENCES:[6,4,1,""],PREFERENCES_PAGES:[6,4,1,""],VIEWS:[6,4,1,""],id:[6,4,1,""],mail_files:[6,4,1,""],name:[6,4,1,""],preferences:[6,4,1,""],preferences_pages:[6,4,1,""],start:[6,2,1,""],stop:[6,2,1,""],views:[6,4,1,""]},"apptools.logger.plugin.logger_preferences":{LoggerPreferences:[6,1,1,""]},"apptools.logger.plugin.logger_service":{LoggerService:[6,1,1,""]},"apptools.logger.plugin.logger_service.LoggerService":{create_email_message:[6,2,1,""],save_preferences:[6,2,1,""],send_bug_report:[6,2,1,""],whole_log_text:[6,2,1,""]},"apptools.logger.plugin.view":{logger_preferences_page:[7,0,0,"-"],logger_view:[7,0,0,"-"]},"apptools.logger.plugin.view.logger_preferences_page":{LoggerPreferencesPage:[7,1,1,""]},"apptools.logger.plugin.view.logger_view":{LogRecordAdapter:[7,1,1,""],LoggerView:[7,1,1,""]},"apptools.logger.plugin.view.logger_view.LogRecordAdapter":{column_widths:[7,4,1,""],get_width:[7,2,1,""]},"apptools.logger.plugin.view.logger_view.LoggerView":{activated:[7,4,1,""],activated_text:[7,4,1,""],code_editor:[7,4,1,""],copy_button:[7,4,1,""],formatted_records:[7,4,1,""],id:[7,4,1,""],log_records:[7,4,1,""],log_records_editor:[7,4,1,""],name:[7,4,1,""],reset_button:[7,4,1,""],service:[7,4,1,""],show_button:[7,4,1,""],trait_view:[7,4,1,""],update:[7,2,1,""]},"apptools.logger.ring_buffer":{RingBuffer:[4,1,1,""],RingBufferFull:[4,1,1,""]},"apptools.logger.ring_buffer.RingBuffer":{append:[4,2,1,""],get:[4,2,1,""]},"apptools.logger.ring_buffer.RingBufferFull":{append:[4,2,1,""],get:[4,2,1,""]},"apptools.naming":{address:[8,0,0,"-"],api:[8,0,0,"-"],binding:[8,0,0,"-"],context:[8,0,0,"-"],dir_context:[8,0,0,"-"],dynamic_context:[8,0,0,"-"],exception:[8,0,0,"-"],initial_context:[8,0,0,"-"],initial_context_factory:[8,0,0,"-"],naming_event:[8,0,0,"-"],naming_manager:[8,0,0,"-"],object_factory:[8,0,0,"-"],object_serializer:[8,0,0,"-"],py_context:[8,0,0,"-"],py_object_factory:[8,0,0,"-"],pyfs_context:[8,0,0,"-"],pyfs_context_factory:[8,0,0,"-"],pyfs_initial_context_factory:[8,0,0,"-"],pyfs_object_factory:[8,0,0,"-"],pyfs_state_factory:[8,0,0,"-"],reference:[8,0,0,"-"],referenceable:[8,0,0,"-"],referenceable_state_factory:[8,0,0,"-"],state_factory:[8,0,0,"-"],trait_defs:[9,0,0,"-"],unique_name:[8,0,0,"-"]},"apptools.naming.address":{Address:[8,1,1,""]},"apptools.naming.binding":{Binding:[8,1,1,""]},"apptools.naming.context":{Context:[8,1,1,""]},"apptools.naming.context.Context":{INITIAL_CONTEXT_FACTORY:[8,4,1,""],OBJECT_FACTORIES:[8,4,1,""],STATE_FACTORIES:[8,4,1,""],bind:[8,2,1,""],create_subcontext:[8,2,1,""],destroy_subcontext:[8,2,1,""],get_unique_name:[8,2,1,""],is_context:[8,2,1,""],list_bindings:[8,2,1,""],list_names:[8,2,1,""],lookup:[8,2,1,""],lookup_binding:[8,2,1,""],lookup_context:[8,2,1,""],rebind:[8,2,1,""],rename:[8,2,1,""],search:[8,2,1,""],unbind:[8,2,1,""]},"apptools.naming.dir_context":{DirContext:[8,1,1,""]},"apptools.naming.dir_context.DirContext":{find_bindings:[8,2,1,""],get_attributes:[8,2,1,""],set_attributes:[8,2,1,""]},"apptools.naming.dynamic_context":{DynamicContext:[8,1,1,""]},"apptools.naming.exception":{InvalidNameError:[8,6,1,""],NameAlreadyBoundError:[8,6,1,""],NameNotFoundError:[8,6,1,""],NamingError:[8,6,1,""],NotContextError:[8,6,1,""],OperationNotSupportedError:[8,6,1,""]},"apptools.naming.initial_context":{InitialContext:[8,5,1,""]},"apptools.naming.initial_context_factory":{InitialContextFactory:[8,1,1,""]},"apptools.naming.initial_context_factory.InitialContextFactory":{get_initial_context:[8,2,1,""]},"apptools.naming.naming_event":{NamingEvent:[8,1,1,""]},"apptools.naming.naming_manager":{NamingManager:[8,1,1,""]},"apptools.naming.naming_manager.NamingManager":{get_object_instance:[8,2,1,""],get_state_to_bind:[8,2,1,""]},"apptools.naming.object_factory":{ObjectFactory:[8,1,1,""]},"apptools.naming.object_factory.ObjectFactory":{get_object_instance:[8,2,1,""]},"apptools.naming.object_serializer":{ObjectSerializer:[8,1,1,""]},"apptools.naming.object_serializer.ObjectSerializer":{can_load:[8,2,1,""],can_save:[8,2,1,""],load:[8,2,1,""],save:[8,2,1,""]},"apptools.naming.py_context":{PyContext:[8,1,1,""]},"apptools.naming.py_object_factory":{PyObjectFactory:[8,1,1,""]},"apptools.naming.py_object_factory.PyObjectFactory":{get_object_instance:[8,2,1,""]},"apptools.naming.pyfs_context":{PyFSContext:[8,1,1,""]},"apptools.naming.pyfs_context.PyFSContext":{ATTRIBUTES_FILE:[8,4,1,""],FILTERS:[8,4,1,""],OBJECT_SERIALIZERS:[8,4,1,""],get_unique_name:[8,2,1,""],refresh:[8,2,1,""]},"apptools.naming.pyfs_context_factory":{PyFSContextFactory:[8,1,1,""]},"apptools.naming.pyfs_context_factory.PyFSContextFactory":{get_object_instance:[8,2,1,""]},"apptools.naming.pyfs_initial_context_factory":{PyFSInitialContextFactory:[8,1,1,""]},"apptools.naming.pyfs_initial_context_factory.PyFSInitialContextFactory":{get_initial_context:[8,2,1,""]},"apptools.naming.pyfs_object_factory":{PyFSObjectFactory:[8,1,1,""]},"apptools.naming.pyfs_object_factory.PyFSObjectFactory":{get_object_instance:[8,2,1,""]},"apptools.naming.pyfs_state_factory":{PyFSStateFactory:[8,1,1,""]},"apptools.naming.pyfs_state_factory.PyFSStateFactory":{get_state_to_bind:[8,2,1,""]},"apptools.naming.reference":{Reference:[8,1,1,""]},"apptools.naming.referenceable":{Referenceable:[8,1,1,""]},"apptools.naming.referenceable_state_factory":{ReferenceableStateFactory:[8,1,1,""]},"apptools.naming.referenceable_state_factory.ReferenceableStateFactory":{get_state_to_bind:[8,2,1,""]},"apptools.naming.state_factory":{StateFactory:[8,1,1,""]},"apptools.naming.state_factory.StateFactory":{get_state_to_bind:[8,2,1,""]},"apptools.naming.trait_defs":{api:[9,0,0,"-"],naming_traits:[9,0,0,"-"]},"apptools.naming.trait_defs.naming_traits":{NamingTraitHandler:[9,1,1,""]},"apptools.naming.trait_defs.naming_traits.NamingTraitHandler":{find_class:[9,2,1,""],get_editor:[9,2,1,""],info:[9,2,1,""],post_setattr:[9,2,1,""],resolve_class:[9,2,1,""],validate:[9,2,1,""],validate_failed:[9,2,1,""]},"apptools.naming.unique_name":{make_unique_name:[8,5,1,""]},"apptools.persistence":{file_path:[10,0,0,"-"],project_loader:[10,0,0,"-"],state_pickler:[10,0,0,"-"],updater:[10,0,0,"-"],version_registry:[10,0,0,"-"],versioned_unpickler:[10,0,0,"-"]},"apptools.persistence.file_path":{FilePath:[10,1,1,""]},"apptools.persistence.file_path.FilePath":{get:[10,2,1,""],set:[10,2,1,""],set_absolute:[10,2,1,""],set_relative:[10,2,1,""]},"apptools.persistence.project_loader":{load_project:[10,5,1,""],upgrade_project:[10,5,1,""]},"apptools.persistence.state_pickler":{State:[10,1,1,""],StateDict:[10,1,1,""],StateList:[10,1,1,""],StatePickler:[10,1,1,""],StatePicklerError:[10,6,1,""],StateSetter:[10,1,1,""],StateSetterError:[10,6,1,""],StateTuple:[10,1,1,""],StateUnpickler:[10,1,1,""],StateUnpicklerError:[10,6,1,""],create_instance:[10,5,1,""],dump:[10,5,1,""],dumps:[10,5,1,""],get_state:[10,5,1,""],gunzip_string:[10,5,1,""],gzip_string:[10,5,1,""],load_state:[10,5,1,""],loads_state:[10,5,1,""],set_state:[10,5,1,""],update_state:[10,5,1,""]},"apptools.persistence.state_pickler.StatePickler":{dump:[10,2,1,""],dump_state:[10,2,1,""],dumps:[10,2,1,""]},"apptools.persistence.state_pickler.StateSetter":{set:[10,2,1,""]},"apptools.persistence.state_pickler.StateUnpickler":{load_state:[10,2,1,""],loads_state:[10,2,1,""]},"apptools.persistence.updater":{Updater:[10,1,1,""]},"apptools.persistence.updater.Updater":{get_latest:[10,2,1,""],strip:[10,2,1,""]},"apptools.persistence.version_registry":{HandlerRegistry:[10,1,1,""],get_version:[10,5,1,""]},"apptools.persistence.version_registry.HandlerRegistry":{register:[10,2,1,""],unregister:[10,2,1,""],update:[10,2,1,""]},"apptools.persistence.versioned_unpickler":{NewUnpickler:[10,1,1,""],VersionedUnpickler:[10,1,1,""]},"apptools.persistence.versioned_unpickler.NewUnpickler":{initialize:[10,2,1,""],load:[10,2,1,""],load_build:[10,2,1,""]},"apptools.persistence.versioned_unpickler.VersionedUnpickler":{add_updater:[10,2,1,""],backup_setstate:[10,2,1,""],find_class:[10,2,1,""],import_name:[10,2,1,""]},"apptools.preferences":{api:[11,0,0,"-"],i_preferences:[11,0,0,"-"],package_globals:[11,0,0,"-"],preference_binding:[11,0,0,"-"],preferences:[11,0,0,"-"],preferences_helper:[11,0,0,"-"],scoped_preferences:[11,0,0,"-"],ui:[12,0,0,"-"]},"apptools.preferences.i_preferences":{IPreferences:[11,1,1,""]},"apptools.preferences.i_preferences.IPreferences":{clear:[11,2,1,""],flush:[11,2,1,""],get:[11,2,1,""],keys:[11,2,1,""],node:[11,2,1,""],node_exists:[11,2,1,""],node_names:[11,2,1,""],remove:[11,2,1,""],set:[11,2,1,""]},"apptools.preferences.package_globals":{get_default_preferences:[11,5,1,""],set_default_preferences:[11,5,1,""]},"apptools.preferences.preference_binding":{PreferenceBinding:[11,1,1,""],bind_preference:[11,5,1,""]},"apptools.preferences.preferences":{Preferences:[11,1,1,""]},"apptools.preferences.preferences.Preferences":{add_preferences_listener:[11,2,1,""],clear:[11,2,1,""],dump:[11,2,1,""],flush:[11,2,1,""],get:[11,2,1,""],keys:[11,2,1,""],load:[11,2,1,""],node:[11,2,1,""],node_exists:[11,2,1,""],node_names:[11,2,1,""],remove:[11,2,1,""],remove_preferences_listener:[11,2,1,""],save:[11,2,1,""],set:[11,2,1,""]},"apptools.preferences.preferences_helper":{PreferencesHelper:[11,1,1,""]},"apptools.preferences.scoped_preferences":{ScopedPreferences:[11,1,1,""]},"apptools.preferences.scoped_preferences.ScopedPreferences":{add_preferences_listener:[11,2,1,""],clear:[11,2,1,""],dump:[11,2,1,""],get:[11,2,1,""],get_scope:[11,2,1,""],keys:[11,2,1,""],load:[11,2,1,""],node:[11,2,1,""],node_exists:[11,2,1,""],node_names:[11,2,1,""],remove:[11,2,1,""],remove_preferences_listener:[11,2,1,""],save:[11,2,1,""],set:[11,2,1,""]},"apptools.preferences.ui":{api:[12,0,0,"-"],i_preferences_page:[12,0,0,"-"],preferences_manager:[12,0,0,"-"],preferences_node:[12,0,0,"-"],preferences_page:[12,0,0,"-"],tree_item:[12,0,0,"-"],widget_editor:[12,0,0,"-"]},"apptools.preferences.ui.i_preferences_page":{IPreferencesPage:[12,1,1,""]},"apptools.preferences.ui.i_preferences_page.IPreferencesPage":{apply:[12,2,1,""]},"apptools.preferences.ui.preferences_manager":{PreferencesHelpWindow:[12,1,1,""],PreferencesManager:[12,1,1,""],PreferencesManagerHandler:[12,1,1,""]},"apptools.preferences.ui.preferences_manager.PreferencesHelpWindow":{traits_view:[12,2,1,""]},"apptools.preferences.ui.preferences_manager.PreferencesManager":{apply:[12,2,1,""],traits_view:[12,2,1,""]},"apptools.preferences.ui.preferences_manager.PreferencesManagerHandler":{apply:[12,2,1,""],close:[12,2,1,""],init:[12,2,1,""],preferences_help:[12,2,1,""]},"apptools.preferences.ui.preferences_node":{PreferencesNode:[12,1,1,""]},"apptools.preferences.ui.preferences_node.PreferencesNode":{create_page:[12,2,1,""],dump:[12,2,1,""],lookup:[12,2,1,""]},"apptools.preferences.ui.preferences_page":{PreferencesPage:[12,1,1,""]},"apptools.preferences.ui.preferences_page.PreferencesPage":{apply:[12,2,1,""]},"apptools.preferences.ui.tree_item":{TreeItem:[12,1,1,""]},"apptools.preferences.ui.tree_item.TreeItem":{append:[12,2,1,""],insert:[12,2,1,""],insert_after:[12,2,1,""],insert_before:[12,2,1,""],remove:[12,2,1,""]},"apptools.preferences.ui.widget_editor":{WidgetEditor:[12,1,1,""]},"apptools.preferences.ui.widget_editor.WidgetEditor":{custom_editor:[12,2,1,""],readonly_editor:[12,2,1,""],simple_editor:[12,2,1,""],text_editor:[12,2,1,""]},"apptools.scripting":{api:[13,0,0,"-"],package_globals:[13,0,0,"-"],recordable:[13,0,0,"-"],recorder:[13,0,0,"-"],recorder_with_ui:[13,0,0,"-"],util:[13,0,0,"-"]},"apptools.scripting.package_globals":{get_recorder:[13,5,1,""],set_recorder:[13,5,1,""]},"apptools.scripting.recordable":{recordable:[13,5,1,""]},"apptools.scripting.recorder":{Recorder:[13,1,1,""],RecorderError:[13,6,1,""]},"apptools.scripting.recorder.Recorder":{clear:[13,2,1,""],get_code:[13,2,1,""],get_object_path:[13,2,1,""],get_script_id:[13,2,1,""],is_registered:[13,2,1,""],record:[13,2,1,""],record_function:[13,2,1,""],register:[13,2,1,""],save:[13,2,1,""],ui_save:[13,2,1,""],unregister:[13,2,1,""],write_script_id_in_namespace:[13,2,1,""]},"apptools.scripting.recorder_with_ui":{CloseHandler:[13,1,1,""],RecorderWithUI:[13,1,1,""]},"apptools.scripting.recorder_with_ui.CloseHandler":{close:[13,2,1,""]},"apptools.scripting.recorder_with_ui.RecorderWithUI":{on_ui_close:[13,2,1,""]},"apptools.scripting.util":{start_recording:[13,5,1,""],stop_recording:[13,5,1,""]},"apptools.selection":{api:[14,0,0,"-"],errors:[14,0,0,"-"],i_selection:[14,0,0,"-"],i_selection_provider:[14,0,0,"-"],list_selection:[14,0,0,"-"],selection_service:[14,0,0,"-"]},"apptools.selection.errors":{IDConflictError:[14,6,1,""],ListenerNotConnectedError:[14,6,1,""],ProviderNotRegisteredError:[14,6,1,""]},"apptools.selection.i_selection":{IListSelection:[14,1,1,""],ISelection:[14,1,1,""]},"apptools.selection.i_selection.IListSelection":{indices:[14,4,1,""],items:[14,4,1,""]},"apptools.selection.i_selection.ISelection":{is_empty:[14,2,1,""],provider_id:[14,4,1,""]},"apptools.selection.i_selection_provider":{ISelectionProvider:[14,1,1,""]},"apptools.selection.i_selection_provider.ISelectionProvider":{get_selection:[14,2,1,""],provider_id:[14,4,1,""],selection:[14,4,1,""],set_selection:[14,2,1,""]},"apptools.selection.list_selection":{ListSelection:[14,1,1,""]},"apptools.selection.list_selection.ListSelection":{from_available_items:[14,2,1,""],indices:[14,4,1,""],is_empty:[14,2,1,""],items:[14,4,1,""],provider_id:[14,4,1,""]},"apptools.selection.selection_service":{SelectionService:[14,1,1,""]},"apptools.selection.selection_service.SelectionService":{add_selection_provider:[14,2,1,""],connect_selection_listener:[14,2,1,""],disconnect_selection_listener:[14,2,1,""],get_selection:[14,2,1,""],has_selection_provider:[14,2,1,""],remove_selection_provider:[14,2,1,""],set_selection:[14,2,1,""]},"apptools.type_registry":{api:[15,0,0,"-"],type_registry:[15,0,0,"-"]},"apptools.type_registry.type_registry":{LazyRegistry:[15,1,1,""],TypeRegistry:[15,1,1,""],get_mro:[15,5,1,""]},"apptools.type_registry.type_registry.LazyRegistry":{lookup_by_type:[15,2,1,""]},"apptools.type_registry.type_registry.TypeRegistry":{lookup:[15,2,1,""],lookup_all:[15,2,1,""],lookup_all_by_type:[15,2,1,""],lookup_by_type:[15,2,1,""],pop:[15,2,1,""],push:[15,2,1,""],push_abc:[15,2,1,""]},"apptools.undo":{abstract_command:[16,0,0,"-"],action:[17,0,0,"-"],api:[16,0,0,"-"],command_stack:[16,0,0,"-"],i_command:[16,0,0,"-"],i_command_stack:[16,0,0,"-"],i_undo_manager:[16,0,0,"-"],undo_manager:[16,0,0,"-"]},"apptools.undo.abstract_command":{AbstractCommand:[16,1,1,""]},"apptools.undo.abstract_command.AbstractCommand":{"do":[16,2,1,""],merge:[16,2,1,""],redo:[16,2,1,""],undo:[16,2,1,""]},"apptools.undo.action":{abstract_command_stack_action:[17,0,0,"-"],api:[17,0,0,"-"],command_action:[17,0,0,"-"],redo_action:[17,0,0,"-"],undo_action:[17,0,0,"-"]},"apptools.undo.action.abstract_command_stack_action":{AbstractCommandStackAction:[17,1,1,""]},"apptools.undo.action.abstract_command_stack_action.AbstractCommandStackAction":{destroy:[17,2,1,""]},"apptools.undo.action.command_action":{CommandAction:[17,1,1,""]},"apptools.undo.action.command_action.CommandAction":{perform:[17,2,1,""]},"apptools.undo.action.redo_action":{RedoAction:[17,1,1,""]},"apptools.undo.action.redo_action.RedoAction":{perform:[17,2,1,""]},"apptools.undo.action.undo_action":{UndoAction:[17,1,1,""]},"apptools.undo.action.undo_action.UndoAction":{perform:[17,2,1,""]},"apptools.undo.command_stack":{CommandStack:[16,1,1,""]},"apptools.undo.command_stack.CommandStack":{begin_macro:[16,2,1,""],clear:[16,2,1,""],end_macro:[16,2,1,""],push:[16,2,1,""],redo:[16,2,1,""],undo:[16,2,1,""]},"apptools.undo.i_command":{ICommand:[16,1,1,""]},"apptools.undo.i_command.ICommand":{"do":[16,2,1,""],merge:[16,2,1,""],redo:[16,2,1,""],undo:[16,2,1,""]},"apptools.undo.i_command_stack":{ICommandStack:[16,1,1,""]},"apptools.undo.i_command_stack.ICommandStack":{begin_macro:[16,2,1,""],clear:[16,2,1,""],end_macro:[16,2,1,""],push:[16,2,1,""],redo:[16,2,1,""],undo:[16,2,1,""]},"apptools.undo.i_undo_manager":{IUndoManager:[16,1,1,""]},"apptools.undo.i_undo_manager.IUndoManager":{redo:[16,2,1,""],undo:[16,2,1,""]},"apptools.undo.undo_manager":{UndoManager:[16,1,1,""]},"apptools.undo.undo_manager.UndoManager":{redo:[16,2,1,""],undo:[16,2,1,""]},apptools:{io:[2,0,0,"-"],logger:[4,0,0,"-"],naming:[8,0,0,"-"],persistence:[10,0,0,"-"],preferences:[11,0,0,"-"],scripting:[13,0,0,"-"],selection:[14,0,0,"-"],type_registry:[15,0,0,"-"],undo:[16,0,0,"-"]}},objnames:{"0":["py","module","Python module"],"1":["py","class","Python class"],"2":["py","method","Python method"],"3":["py","data","Python data"],"4":["py","attribute","Python attribute"],"5":["py","function","Python function"],"6":["py","exception","Python exception"]},objtypes:{"0":"py:module","1":"py:class","2":"py:method","3":"py:data","4":"py:attribute","5":"py:function","6":"py:exception"},terms:{"abstract":[2,10,12,16,17,26],"boolean":[8,22,26],"case":[5,10,11,20,22,25],"class":[2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,22,23,24,26],"default":[3,4,7,9,10,11,12,13,14,16,17,22,23,26],"final":25,"float":[7,8,10,22,24],"function":[4,8,9,10,13,20,24,25],"import":[4,10,15,22,24,25],"int":[10,22],"long":[10,22,26],"new":[3,7,8,9,10,11,13,15,17,20,22,25],"public":[5,13,25],"return":[3,4,6,7,8,9,10,11,12,13,14,15,16,17,22,23,25,26],"static":8,"transient":22,"true":[3,6,8,10,11,13,14,16,22,23,24,25,26],"try":[11,16,22,26],"while":[7,10,16,25,26],And:22,But:22,ETS:24,For:[3,9,10,13,20,22,24,25],Has:14,Its:[10,16,26],Not:8,One:24,That:3,The:[3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,19,20,23,26],Then:11,There:11,These:15,Used:10,Useful:13,Using:[22,24,26],__array__:3,__attributes__:8,__class__:10,__dict__:10,__getstate__:10,__init__:[10,16,26],__main__:10,__metadata__:10,__module__:15,__name__:[10,15],__set_pure_state__:10,__setitem__:3,__setstate__:10,__version__:10,_unpickl:10,abandon:[16,26],abc:[3,15],abcmeta:15,abl:[22,24],about:[8,10,16,22,24,25],abov:24,absolut:[3,10,15],abstract_command:[1,18],abstract_command_stack_act:[1,16],abstractcommand:16,abstractcommandstackact:17,accept:[8,9],access:[3,11],aclass:9,acm:[11,22,23],act:[8,25],action:[1,16,24,25,26],activ:[7,14,16,17,26],activated_text:7,active_stack:26,active_stack_clean:26,actual:[4,7,8,9,10,13,22],adapt:7,add:[3,4,7,10,11,13,14,22,26],add_log_queue_handl:4,add_preferences_listen:11,add_selection_provid:[14,25],add_to_h5fil:3,add_updat:10,added:[11,14],adding:8,addit:[3,8,11],addition:10,address:[1,18],affect:11,after:[3,10,12,13],age:24,agent:[1,4],alia:5,all:[2,6,7,8,10,11,12,13,14,15,16,17,22,24,26],all_item:14,alloc:26,allow:[3,7,8,9,10,11,12,16,22,23,24,26],allows_children:12,almost:10,along:[10,16],alreadi:[2,3,8,13,14],also:[3,8,10,11,13,16,21,22,23,24,25,26],alter:3,altern:[9,10,26],alwai:[11,22,24],amount:7,ani:[2,5,7,8,9,10,11,14,16,17,22,23,24,25,26],anoth:[8,16,22],answer:10,anymor:25,anywher:22,api:[1,6,18,19,22],app:10,appear:[10,26],append:[3,4,11,12,24],appl:12,appli:[10,12],applic:[4,8,10,11,16,22,23,24,25,26],application_hom:22,application_scop:11,application_vers:10,approach:22,appropri:[10,16,26],apptool:[0,20,21,22,24],arbitrari:[9,24],arg:[3,5,6,7,12,13,26],argmument:3,argument:[3,13,14,16,17,24,25,26],around:[3,20,22,26],arrai:[3,10],arrang:22,array_or_shap:3,array_proxy_kei:3,arriv:7,ascend:8,ascii:10,ask:[8,11,13],assert:10,assign:[7,9],assist:8,associ:[8,22],assum:[3,10],atom:3,attach:[1,4,24],attempt:[2,8],attribut:[3,8,9,10,13,24],attributes_fil:8,auto:0,auto_flush:3,auto_group:3,auto_open:3,automat:[3,8,11,13,19,22,26],avail:[7,13,14,20,23,25,26],avoid:[8,10,11],back:[10,11,22],background:24,backup_setst:10,backupcount:4,base64:10,base:[2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,24,25,26],base_f_nam:10,base_toolkit:5,basic:[10,13,19],becam:20,becaus:[5,8,10,22,25],becom:[25,26],been:[3,13,14,15,16,24,25,26],befor:[4,10,12,14,16,20,22,25,26],begin:[8,16,26],begin_macro:[16,26],behavior:3,behaviour:[22,23],being:[8,9,10,12,16,24,26],believ:22,below:3,best:[10,24],better:11,between:[10,11,24,25],bgcolor:[11,22,23],bind:[1,11,18],bind_prefer:11,bit:22,black:22,blog:4,blue:[11,22,23],bogu:22,bool:[3,10,13,14,22,24],both:[15,26],bound:8,brief:26,broker:25,brows:10,buffer:[3,4],bug:6,build:22,builtin:10,bump:10,bunch:10,button:[7,12,22,25],calcul:[3,7,8],call:[3,4,8,9,10,11,13,14,16,17,22,24,25,26],callabl:[14,25,26],callback:[14,24,25],came:11,can:[3,4,5,8,9,10,11,14,15,16,20,21,22,24,25,26],can_load:8,can_sav:8,cannot:[8,11],capabl:8,care:[10,22,26],carrot:12,categori:8,cauliflow:12,caveat:1,cc_address:5,ccaddr:[5,6],central:25,chang:[8,11,12,13,14,16,22,24,25,26],charact:26,check:10,child:[11,12,22,24],children:[3,11,16,24],children_nam:3,chunk:3,class_nam:10,classmethod:[3,10,14],clean:[13,16,26],cleaner:3,clear:[11,13,16,26],click:12,close:[3,12,13,25],closehandl:13,code:[5,8,10,13,20,24],code_editor:7,collaps:26,collect:[3,14,25],color:24,column:[3,7],column_width:7,combin:9,come:22,command:[11,16,17,24,26],command_act:[1,16],command_stack:[1,18,26],commandact:17,commandstack:16,comment:[5,6],common:[10,20,25,26],commuic:8,commun:[8,25],complet:[9,10,26],complex:[10,22,25],complic:[10,22],compon:[8,25,26],compos:8,concept:19,concern:10,configobj:[11,22],configur:26,conform:8,confus:26,connect:[14,25],connect_selection_listen:[14,25],consid:24,consist:[8,22],consumpt:25,contain:[0,3,8,10,11,12,13,14,16,22,25,26],content:[18,25],context:[1,3,10,18],context_nam:8,context_ord:8,continu:8,contribut:[8,23],contributes_to:23,control:[3,12,25],conveni:[4,10,13,22,24,26],convers:10,convert:[3,7,10,22],cookbook:4,copi:[2,4,16,26],copy_button:7,core:24,correct:10,correctli:10,correspond:25,could:25,couldn:26,cours:11,creat:[2,3,4,7,8,10,11,12,13,14,16,22,24,26],create_:3,create_arrai:3,create_carrai:3,create_dict:3,create_email_messag:[5,6],create_fil:2,create_fold:2,create_group:3,create_inst:10,create_packag:2,create_pag:12,create_subcontext:8,create_t:3,creation:[8,12],criteria:8,current:[8,10,11,12,13,14,22,24,25,26],custom:12,custom_editor:12,custom_excepthook:[1,18],data:[3,6,8,10,12,16,26],datafram:3,debug:[13,22],decid:10,decor:[13,24],decreas:7,deep:[16,26],def:[10,22,23,24],default_prefer:11,default_valu:24,defin:[7,9,10,11,13,24,25,26],definit:[8,11,24],delet:[2,3],delete_exist:3,demonstr:26,depend:[10,11,25],descend:11,describ:[8,9,10,23],descript:[3,12],desir:[3,8,23],destin:2,destroi:[8,17,25],destroy_subcontext:8,detail:[10,24],determin:[8,10],develop:[11,25,26],dialog:[12,13,25],dict:[3,10,13],dict_nod:[1,2],dictat:23,dictionari:[3,8,10,13,20,22],did:[11,22],differ:[3,8,10],dir_context:[1,18],dircontext:8,direct:25,directi:10,directli:[11,22,25],directori:[8,21,22],disabl:[16,26],disappear:25,discard:16,disconnect:[14,25],disconnect_selection_listen:[14,25],discuss:[22,23],disk:[3,10,22,26],displai:[4,25],distinct:25,divid:7,docstr:3,document:[3,22,24,26],doe:[2,3,4,8,10,11,13,17,22,23],doesn:[12,22],don:[22,23],done:[13,24,25,26],drawback:11,dtype:3,dump:[10,11,12,22],dump_stat:10,duplic:[10,14],dure:10,dynam:[7,8],dynamic_context:[1,18],dynamiccontext:8,each:[7,8,10,11,15,22,24,26],easi:[3,10,11],easili:[10,24],edit:[9,10,26],editor:[7,9,10,12,25,26],editor_factori:12,editorfactori:12,effect:[16,26],either:[3,9,10,11,22,24],element:[4,8,14,25,26],elimin:10,els:[3,10,15],email:6,embed:10,emit:4,empti:[8,11,14,16,26],encapsul:10,encod:10,encourag:[11,20],end:[4,8,10,13,16,24,26],end_macro:[16,26],endo:26,endpoint:8,enlib:5,enough:24,enqueu:4,ensur:[10,16,26],enthought:[2,8,10,11,13,16,26],enthoughtbas:4,entir:10,entri:26,environ:[3,8],envisag:[5,6,8,19,22,25],equal:7,error:[1,9,10,18],especi:25,etc:[4,8,10,11,17,22],etsconfig:22,even:14,event:[8,14,17,25,26],ever:[16,26],everi:4,everyth:10,exactli:22,examin:8,exampl:[3,9,10,11,12,22,25,26],excel:22,except:[1,4,9,10,11,13,14,18],exclud:10,execut:[4,13,16,24,26],exist:[2,3,8,10,11,12,13,22],exists_error:3,expect:14,explan:7,explicit:22,explicitli:[3,8,11,14,23,26],expos:[3,6,25],extend:[3,8],extens:[5,23,25],extern:25,extra:23,facil:24,factori:[8,12,26],fairli:24,fals:[3,5,6,7,8,11,12,13,14,22,24],featur:[1,26],few:24,fgcolor:22,file:[1,4,5,6,8,10,11,13,18,19,22,23],file_or_filenam:11,file_path:[1,18],filenam:[3,11,22],filenod:3,filepath:10,filesystem:22,fill:14,filter:8,find:[8,11,13,21,24],find_bind:8,find_class:[9,10],fire:[8,14,25,26],first:[3,10,22,24,25],fix:[7,10],fix_import:10,fixm:[5,11,13],flexibl:10,flush:[3,11,22],folder:2,follow:[13,22,24,26],forc:[7,11],form:[10,12],format:[6,8,10,22],formatt:4,formatted_record:7,forwardproperti:7,found:[8,14],fraction:7,framework:[8,13,19,24],fred:22,free:23,friend:[10,24],from:[4,6,8,10,11,12,13,14,16,22,24],from_address:5,from_available_item:14,fromaddr:[5,6],fruit:12,full:24,fulli:15,func:[13,14],further:19,gener:[0,4,8,10,12,22,26],get:[3,4,8,10,11,15,22,23,24,25],get_atom:3,get_attribut:8,get_cod:13,get_default_prefer:11,get_editor:9,get_initial_context:8,get_latest:10,get_mro:15,get_object_inst:8,get_object_path:13,get_prefer:23,get_record:13,get_scop:[11,22],get_script_id:13,get_select:[14,25],get_stat:10,get_state_to_bind:8,get_unique_nam:8,get_vers:10,get_width:7,give:[10,26],given:[3,7,8,10,11,13,14,15,16,24,25,26],global:[11,13,24],going:[10,24],great:17,group:[3,7],group_path:3,group_subpath:3,grow:24,guarante:[13,16,26],gui:[25,26],guid:9,gunzip_str:10,gzip:10,gzip_str:10,h5_group:3,h5_group_wrapp:3,h5attr:3,h5dictnod:3,h5file:3,h5filter:3,h5group:3,h5tablenod:3,halt:4,handi:24,handl:[10,12,25,26],handler:[4,7,9,10,12,13],handlerregistri:10,happen:8,happi:22,hard:5,has:[4,7,8,10,12,13,14,15,22,25,26],has_inst:10,has_new_record:4,has_selection_provid:14,has_trait:[2,5,6,8,11,12,13,14,16],hasprivatetrait:[2,8],hasstricttrait:24,hastrait:[5,6,8,9,11,12,13,14,16,24],have:[3,7,10,11,16,22,24,25,26],hdf5:[3,19],heirarchi:[8,21],help:[3,10,12],help_id:5,helper:[22,23],henc:[22,23],here:[5,10,11,21,22,24],hid_quality_agent_dlg:5,hierarch:22,hierarchi:[10,11,13,22,24],high:24,highli:[10,11],hold:22,hopefulli:22,horizont:7,how:[8,22,23,26],howev:[10,26],html:26,human:24,i_command:[1,18],i_command_stack:[1,18],i_prefer:[1,18],i_preferences_pag:[1,11],i_select:[1,18],i_selection_provid:[1,18],i_undo_manag:[1,18],icommand:16,icommandstack:[16,26],idconflicterror:14,idea:[10,22],ideal:[10,25],identifi:[3,14,26],ignor:[10,13,14,24,26],ignore_miss:[14,25],ilistselect:14,imag:[12,22],immedi:26,implement:[3,9,10,11,14,15,16,20,21,22,23,25,26],implent:11,import_nam:10,inadequ:10,inappropri:26,includ:[9,10,11,16,21,26],include_environ:6,include_project:5,include_userdata:[5,6],increas:[7,24],increment:[10,26],indent:[11,12],independ:26,index:[12,26],indic:[8,14,25,26],info:[8,9,12,13],info_text:9,inform:[3,8,9,10,14,22,24,25],infrastructur:24,inherit:[11,22],ini:[22,23],init:12,initarg:10,initi:[3,8,10,11,12,14,25],initial_context:[1,18],initial_context_factori:[1,18],initialcontext:8,initialcontextfactori:8,inject:13,input:3,insert:12,insert_aft:12,insert_befor:12,insid:24,instal:3,instanc:[3,7,8,9,10,11,12,13,14,15,16,17,24,25,26],instanti:[13,24],instead:[9,10,25],insuffici:10,integ:[7,26],intend:26,intent:11,interact:8,intercept:3,interest:[8,22],interfac:[3,7,9,11,12,13,14,16,21,22,24,25,26],intermedi:[2,8],intern:[14,24,25],interpret:[10,13],invalid:8,invalidnameerror:8,invert:13,investig:20,invok:[13,26],iprefer:[11,22],ipreferencespag:12,irrespect:26,is_context:8,is_dict_nod:3,is_empti:14,is_ok:[12,13],is_open:3,is_regist:13,is_table_nod:3,iselect:[14,25],iselectionprovid:[14,25],isn:22,issu:10,item:[3,7,8,12,14,25,26],items:3,iter:3,iter_group:3,iterator_length:3,iteritem:3,its:[7,8,10,11,12,13,14,15,22,24,25,26],itself:[8,10,11,13,22,23,24,26],iundomanag:[16,26],java:21,jndi:21,join:3,join_path:3,json:3,just:[10,11,22,23,24],keep:[10,16,25],kei:[3,10,11,24],keyboard:26,keyerror:15,keyword:[3,13,24,25],klass:10,know:10,knowledg:10,known:[10,13],kwarg:[3,5,6,7],larg:10,last:[10,15,16,17,26],later:[4,10,16],latest:10,layer:22,lazi:26,lazili:15,lazyregistri:15,learn:24,leav:[7,16,26],let:[22,24],level:[4,8,24],lib:5,librari:[20,24],like:[3,4,10,11,22,23,24],limit:22,line:[11,13,24],link:26,list:[3,4,6,7,8,10,11,13,14,15,24,25],list_bind:8,list_nam:8,list_select:[1,18],listen:[11,13,14,17,19,22,24],listenernotconnectederror:14,listselect:[14,25],littl:7,live:8,load:[8,10,11,22,23,26],load_build:10,load_project:10,load_stat:10,loads_stat:10,local:8,locat:[8,24],log:[4,6,7],log_point:[1,18],log_queue_handl:[1,18],log_record:7,log_records_editor:7,logfilehandl:4,logger:[1,18],logger_plugin:[1,4],logger_prefer:[1,4],logger_preferences_pag:[1,4,6],logger_servic:[1,4],logger_view:[1,4,6],loggerplugin:6,loggerprefer:6,loggerpreferencespag:7,loggerservic:6,loggerview:7,logic:13,logqueuehandl:4,logrecord:7,logrecordadapt:7,longer:[10,17,25],look:[3,8,11,15,22,24],lookup:[8,12,15],lookup_al:15,lookup_all_by_typ:15,lookup_bind:8,lookup_by_typ:15,lookup_context:8,lot:10,lowest:22,macro:[16,26],made:[8,12,16,22,23,26],mai:[8,10,13,16,24,26],mail_fil:6,main:25,maintain:[3,15,24,26],major:[10,26],make:[2,9,10,11,22,25],make_context:8,make_unique_nam:8,make_writ:2,manag:[3,8,10,11,12,16,22,25,26],mani:[10,22,26],manipul:[20,26],manner:24,manual:13,map:[3,10,20,24],mark:[13,24,26],match:[8,13,15],max_pass:10,maxbyt:4,maximum:7,mayavi:24,mean:[7,10,22],mechan:[8,19,23],mention:22,menu:26,merg:[11,16,26],messag:[4,5,6],metadata:[8,10,13,24],method:[3,8,9,10,11,13,15,16,17,20,22,24,25,26],might:[10,22,23,25],minu:7,miss:[2,8,11,14,22],mode:3,model:[8,16],modifi:[9,10,16,26],modul:[18,24],more:[3,4,9,11,16,22,24,25,26],motiv:10,move:[2,26],mro:10,msg:[4,5],much:[20,23],multidimension:3,multipl:[25,26],multipli:7,must:[2,3,8,9,14,15,16,24,25,26],mutablemap:3,mutat:11,my_dict:3,my_tabl:3,myapplic:23,mypackag:23,myplugin:23,name:[1,3,6,7,10,11,12,13,15,16,18,19,22,24,26],namealreadybounderror:8,namenotfounderror:8,namespac:[8,13],naming_ev:[1,18],naming_manag:[1,18],naming_trait:[1,8],namingerror:8,namingev:8,namingmanag:8,namingtraithandl:9,natur:22,navig:10,necessari:[3,10,16,26],need:[9,10,13,16,23,25,26],nest:[11,13,16,24,26],never:[8,14],new_nam:8,newest:4,newunpickl:10,next:[16,22,26],node:[3,11,12,22,23],node_attr:3,node_exist:11,node_nam:11,node_path:3,node_subpath:3,nodepath:3,non:[3,8,9,22],none:[3,4,8,10,11,12,13,15,22,26],normal:[3,7],notcontexterror:8,note:[3,7,8,9,10,11,24],noth:[2,11,13,16,17,26],notic:22,notif:25,notifi:[13,14,22,25],notion:11,now:[10,22,24],number:[10,22,23,26],numer:10,numpi:3,obj:[8,10,11,15,22],obj_class:15,object:[3,4,5,6,7,8,9,10,11,12,13,14,15,19,20,21,22,24,26],object_factori:[1,18],object_seri:[1,18],objectfactori:8,objectseri:8,obtain:10,obvious:22,occur:[9,24],often:10,ogbuji:4,old:[10,15,22],old_nam:8,oldest:4,on_trait_chang:22,on_ui_clos:13,onc:[4,16,26],one:[8,10,11,12,13,15,16,22,24,25,26],ones:10,onli:[3,9,10,11,13,15,16,17,23,25,26],onto:[15,17,26],opac:24,open:[3,10,25],open_h5fil:3,oper:[8,11,17,20,22,26],operationnotsupportederror:8,opportun:10,option:[10,13,25,26],or_non:9,orang:12,order:[8,10,11,14,15,22],organ:[24,25],organis:26,orient:7,origin:[3,8,9,10,16,26],other:[3,8,9,10,16,23,25,26],otherwis:[3,14,16,26],our:[3,7,22],out:[10,11,13,24],output:[10,13],outsid:[8,24],outstand:[16,26],over:[3,8,12],overrid:23,overridden:[9,10],overview:[19,24],overwrit:3,packag:[0,18,20,21,22,24,25],package_any_relevant_fil:5,package_glob:[1,18],package_single_project:5,package_workspac:5,page:[7,12,19],pair:3,panda:3,panel:12,panick:22,paramet:[3,9,10,13,14,15,24],parent:[3,12,13,15,24],pars:10,part:[2,3,4,8,10,11,13,16,24,25],particular:[8,9,10,11,13,14,24,26],particularli:[8,26],pass:[3,4,8,9,10,11,13,16,24,26],passiv:14,path:[2,3,4,8,10,11,13,20,24],pathlib:20,pathnam:3,pattern:26,pear:12,peopl:11,perfectli:14,perform:[7,8,11,17,22,24],perhap:10,persist:[1,6,11,18,22],phrase:9,pickl:10,pickle_filenam:10,pickler:10,pixel:7,pkgfile:23,place:[9,10,11,16,17,24,26],placehold:10,plain:[10,22,24],pleas:10,plug:8,plugin:[1,4,5,10,23,25,26],point:[5,8,22,23,24,26],pop:[13,15],popul:14,portion:21,posit:[8,26],posix:10,possibl:[10,13,15,25,26],post_setattr:9,potenti:26,power:24,pprint:10,preced:[11,22],predefin:[9,22],prefer:[1,6,7,8,18,19],preference_bind:[1,18],preference_path:11,preferencebind:11,preferences_help:[1,6,12,18],preferences_manag:[1,11],preferences_nod:[1,11],preferences_pag:[1,6,7,11],preferences_path:22,preferencesbind:11,preferenceshelp:[6,11,12,22,23],preferenceshelpwindow:12,preferencesmanag:12,preferencesmanagerhandl:12,preferencesnod:12,preferencespag:[7,12],prefix:8,prefixmap:24,present:[8,12,13],preserv:3,presum:10,pretti:[12,22],previou:[13,16,26],previous:22,primari:11,primarili:24,primit:11,print:[4,12,22,24],printabl:13,prioriti:[5,6],problem:10,process:10,produc:[8,24],program:3,project:[2,4,5,8,10,11,13,16],project_load:[1,18],project_vers:10,properli:16,properti:[3,20,24],propos:9,protocol:10,prove:[10,22],provid:[2,3,8,10,11,13,14,19,20,22,23,24,26],provider_id:[14,25],providernotregisterederror:[14,25],proxi:10,publish:[14,25],pure:10,purpos:9,push:[15,16,17,26],push_abc:15,put:4,py_context:[1,18],py_object_factori:[1,18],pycontext:8,pyf:8,pyfac:[5,7,17,26],pyfs_context:[1,18],pyfs_context_factori:[1,18],pyfs_initial_context_factori:[1,18],pyfs_object_factori:[1,18],pyfs_state_factori:[1,18],pyfscontext:8,pyfscontextfactori:8,pyfsinitialcontextfactori:8,pyfsobjectfactori:8,pyfsstatefactori:8,pyobjectfactori:8,pytabl:[3,20],pytables_group:3,pytables_nod:3,python:[3,4,8,10,11,13,20,21,24],qualifi:15,quality_agent_mail:[1,4],quality_agent_view:[1,4],qualityagentview:5,queue:4,quick:22,quickest:24,quit:[10,25],rais:[3,8,9,11,14,15,25],rang:24,rather:[3,8,9],ratio:[22,23],raw:22,reach:8,react:25,read:[3,10,19,24],readabl:[3,13,24],readi:4,readonly_editor:12,real:10,realli:[10,22],reason:[15,24],rebind:8,rec:13,receiv:[9,25],recogn:8,recognis:[8,16],recommend:11,reconstitut:10,record:[1,3,4,7,16,18,19],record_funct:13,recorder_with_ui:[1,18],recordererror:13,recorderwithui:[13,24],recreat:[10,24],red:22,redo:[16,17,26],redo_act:[1,16],redo_nam:26,redoabl:26,redoact:17,redon:[16,26],refactor:10,refer:[1,7,9,10,11,16,18,24,26],referenc:[1,18],referenceable_state_factori:[1,18],referenceablestatefactori:8,reflect:[8,26],refresh:8,regard:[8,25],regist:[10,13,14,15,23,24,25],registi:10,registri:[10,13,14,15],reimplement:17,rel:[3,8,10],rel_pth:10,releas:10,relev:[5,10],reli:24,remain:[5,10,14],remov:[3,11,12,14,26],remove_group:3,remove_nod:3,remove_preferences_listen:11,remove_selection_provid:[14,25],renam:8,repeat:26,repeatedli:[10,14],replac:16,report:6,repres:[8,10,12,13,14,22,25],represent:[2,8,10,24],request:[8,14,25],requir:[3,7,8,9,10,14,17,26],reset:4,reset_button:7,resiz:7,resolut:[8,15],resolv:8,resolve_class:9,respect:10,respons:[16,26],rest:14,restor:26,result:[7,8,9,16,17,26],reus:5,revers:[10,24],revert:26,revis:10,rewrit:5,ring_buff:[1,18],ringbuff:4,ringbufferful:4,root:[3,11,12,22],rotatingfilehandl:4,row:3,safer:8,saferepr:10,sai:[10,22],same:[7,8,10,14,16,22,25,26],satisfi:20,save:[6,8,10,11,13,16,22,24,26],save_prefer:6,scan:10,scheme:11,scope:[8,11,19,23],scope_nam:11,scoped_prefer:[1,18],scopedprefer:[11,22,23],screen:22,script:[1,16,18,19],script_id:[13,24],search:[8,15,19,22],second:10,section:[0,22,23,26],see:[3,10,22,24],select:[1,18,19],selection_servic:[1,18],selectionservic:[14,19],self:[10,23,24],send:[6,25],send_bug_report:6,sens:9,sentenc:9,seq:10,sequenc:[3,8,14,26],sequence_nr:[16,26],serial:8,servic:[5,6,7,14,19],set:[3,7,8,10,11,13,14,22,23,24,26],set_absolut:10,set_attribut:8,set_default_prefer:11,set_record:[13,24],set_rel:10,set_select:[14,25],set_stat:10,setup:[10,24],shape:3,shiva:24,shortcut:26,should:[3,5,8,9,10,11,14,22,24,25,26],show:[7,8,12,25],show_button:7,show_label:7,shown:13,signatur:14,silent:14,similar:[9,20,26],similarli:10,simpl:[7,10,12,13,22,24],simple_editor:12,simpli:[10,22,24],simplifi:10,sinc:[3,8,10,13,24,26],singl:[16,26],size:[4,5,7],size_max:4,small:24,smtp_server:[5,6],some:[3,8,22,26],someon:[8,10],sometim:24,somewher:8,soon:25,sort:[8,26],sound:22,sourc:[2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,24],space:7,special:10,specif:[8,9,10,11,13,14,21,24,25],specifi:[3,7,8,9,10,11,12,13,15,22,24,25],splash:22,splash_screen:22,splashscreenprefer:[22,23],split:3,split_path:3,sprocket:9,sprout:12,squar:9,stack:[4,15,16,17,26],stack_trac:[5,6],stack_upd:26,stage:10,standard:[8,10,11,20,26],start:[4,6,8,13,22,23,24],start_record:13,startup:4,state:[8,10,13,16,26],state_factori:[1,18],state_pickl:[1,18],statedict:10,statefactori:8,statelist:10,statement:13,statepickl:10,statepicklererror:10,statesett:10,statesettererror:10,statetupl:10,stateunpickl:10,stateunpicklererror:10,statu:26,stdout:[11,12],stop:[6,13,24],stop_record:13,storag:[3,10],store:[3,8,10,11,13,22,24],str:[3,5,7,9,11,13,14,22,24,26],strict:10,strightfoward:10,string:[3,8,9,10,11,12,13,15,24],strip:10,structur:12,stuff:[5,10],style:[7,15,20],sub:[8,20,24,26],subclass:[9,11,13],subgroup_nam:3,subject:[5,6],submodul:[1,18],subpackag:18,subsequ:[16,24,26],suffici:26,suggest:24,suit:[2,8,10,11,13,16,24,26],suitabl:8,superclass:15,support:[8,10,13,16,19,25,26],sure:[11,22,25],surfac:24,synchron:[11,25],synchronis:26,syntax:[8,22],system:[2,4,8,22],tabl:[3,7],table_nod:[1,2],tabular_adapt:7,tabular_editor:7,tabularadapt:7,tabulareditor:7,take:[11,17,22,25,26],taken:[10,24],technic:24,tediou:24,tell:26,terribl:22,test:24,text:[6,10,13,26],text_editor:12,than:[3,4,8,9],thei:[10,11,16,20,22,24,25,26],them:[4,8,10,11,22,26],themselv:[8,13],therefor:9,thi:[0,2,3,4,5,7,8,9,10,11,12,13,14,16,17,20,22,23,24,25,26],thin:3,thing:23,think:[8,10,11],those:[8,13,16,26],though:[8,10],thought:26,through:[8,24,25],thrown:8,thu:7,time:[4,7,8,10,25,26],titl:5,to_address:5,to_datafram:3,toaddr:[5,6],togeth:7,toi:24,too:[10,22,23,24],tool:[2,8,10,11,13,16,24,26],toolbar:25,toolkiteditorfactori:7,top:22,total:[7,12],tour:22,trace:4,traceback:4,tradit:22,trail:11,trait:[2,5,6,7,8,9,11,12,13,14,16,17,20,22,23,24,26],trait_def:[1,8],trait_handl:9,trait_modifi:7,trait_nam:[11,22],trait_name_on_par:13,trait_typ:[5,6,7],trait_view:7,traiterror:9,traithandl:9,traits_ui_view:7,traits_view:12,traitsui:[7,12,13],traitsuiview:7,transform:10,treat:[7,8,26],tree:[8,12,25],tree_item:[1,11],treeitem:12,tri:[23,24],trigger:14,tupl:[3,5,10,24],turn:[10,11,20,24],tutori:21,two:[10,11,16,22,25,26],typ:15,type:[3,4,7,8,9,10,11,15,19,24,26],type_registri:[1,18],typeregistri:15,typic:[10,16,25,26],uch:4,ui_sav:13,unbind:8,unchang:7,undo:[1,18,19],undo_act:[1,16],undo_manag:[1,18,26],undo_nam:26,undoabl:26,undoact:17,undomanag:16,undon:[16,17,26],unhook:17,unimpl:5,uniqu:[8,14,24,25,26],unique_nam:[1,18],unless:25,unlik:10,unnorm:7,unpickl:10,unregist:[10,13,24],unseri:10,until:[8,10,16,26],unzip:10,updat:[1,7,18,26],update1:10,update2:10,update3:10,update_st:10,updater_path:10,upgrad:10,upgrade_project:10,usabl:8,usag:26,use:[7,8,9,10,11,13,20,22,23,25],useag:22,used:[3,8,10,11,12,13,16,22,23,24,25,26],useful:[8,10,13,17,22],user:[7,8,9,10,11,12,13,20,22,24,25,26],uses:[11,23],using:[3,8,9,10,13,22,24,25],usual:[10,11,12,22],util:[1,2,5,18],valid:[3,9,10,14],validate_fail:9,valu:[3,4,7,8,9,10,11,16,22,26],valueerror:[3,11,14],variou:[10,26],veg:12,veri:[10,24],verifi:9,version:[8,10,22],version_registri:[1,18],versioned_unpickl:[1,18],versionedunpickl:10,via:[5,10,11,13,22,23,24],view:[1,3,4,6,10,12,25],visibl:[11,22,23],visitor:8,visual:24,wai:[8,11,22,24],walk:[10,24],want:[10,11,13,22,24,25],well:[10,24],were:[16,26],what:[7,10,22,24,25],whatev:[9,11,24],when:[3,4,8,10,13,14,15,16,17,22,23,24,25,26],whenev:[3,9,14,25,26],where:[3,8,10,11,13,22,25],whether:[3,9],which:[3,7,8,10,11,12,13,16,22,23,24,25,26],white:22,whole:10,whole_log_text:6,whose:[9,10],wide:11,widget:[11,12],widget_editor:[1,11],widgeteditor:12,width:[7,11,22,23],win:22,window:25,wire:24,wirefram:24,wish:25,within:8,without:[11,16,26],word:26,work:[3,10,12,16,22,24,26],workbench:[6,7,26],worth:[10,11,22],would:[3,10,11,16,17,22,23,25],wrap:[3,13,17,26],wrapper:[3,20,26],write:[3,10,22],write_script_id_in_namespac:13,writeabl:2,writer:8,written:8,xmarshal:10,xxx:3,year:24,yellow:23,yet:5,you:[3,10,11,13,21,22,23,24],your:[22,23,24],yourself:22,zip:5},titles:["API documentation","apptools package","apptools.io package","apptools.io.h5 package","apptools.logger package","apptools.logger.agent package","apptools.logger.plugin package","apptools.logger.plugin.view package","apptools.naming package","apptools.naming.trait_defs package","apptools.persistence package","apptools.preferences package","apptools.preferences.ui package","apptools.scripting package","apptools.selection package","apptools.type_registry package","apptools.undo package","apptools.undo.action package","apptools","AppTools Documentation","File I/O","Naming","Preferences","Preferences in Envisage","Automatic script recording","The selection service","Undo Framework"],titleterms:{"case":24,The:[22,24,25],abstract_command:16,abstract_command_stack_act:17,abstractcommand:26,access:22,action:17,activ:25,address:8,advanc:24,agent:5,api:[0,2,4,8,9,11,12,13,14,15,16,17,24,26],apptool:[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19],attach:5,automat:24,basic:22,bind:8,caveat:10,command_act:17,command_stack:16,commandact:26,commandstack:26,concept:26,content:[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17],context:8,custom_excepthook:4,dict_nod:3,dir_context:8,document:[0,19],dynamic_context:8,envisag:23,error:14,exampl:24,except:8,featur:10,file:[2,3,20],file_path:10,framework:26,further:22,gloriou:22,hdf5:20,i_command:16,i_command_stack:16,i_prefer:11,i_preferences_pag:12,i_select:14,i_selection_provid:14,i_undo_manag:16,icommand:26,initial_context:8,initial_context_factori:8,list_select:14,listen:25,log_point:4,log_queue_handl:4,logger:[4,5,6,7],logger_plugin:6,logger_prefer:6,logger_preferences_pag:7,logger_servic:6,logger_view:7,mechan:22,modul:[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17],name:[8,9,21],naming_ev:8,naming_manag:8,naming_trait:9,object:25,object_factori:8,object_seri:8,overview:26,packag:[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17],package_glob:[11,13],particular:22,passiv:25,persist:10,plugin:[6,7],prefer:[11,12,22,23],preference_bind:11,preferences_help:11,preferences_manag:12,preferences_nod:12,preferences_pag:12,project_load:10,provid:25,py_context:8,py_object_factori:8,pyfs_context:8,pyfs_context_factori:8,pyfs_initial_context_factori:8,pyfs_object_factori:8,pyfs_state_factori:8,quality_agent_mail:5,quality_agent_view:5,queri:25,read:22,record:[13,24],recorder_with_ui:13,redo_act:17,redoact:26,refer:8,referenc:8,referenceable_state_factori:8,registr:25,ring_buff:4,scope:22,scoped_prefer:11,script:[13,24],select:[14,25],selection_servic:14,selectionservic:25,servic:25,set:25,state_factori:8,state_pickl:10,string:22,submodul:[2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17],subpackag:[1,2,4,6,8,11,16],support:20,table_nod:3,tour:24,trait_def:9,tree_item:12,type:22,type_registri:15,undo:[16,17,26],undo_act:17,undo_manag:16,undoact:26,undomanag:26,unique_nam:8,updat:10,use:24,util:[3,13],version_registri:10,versioned_unpickl:10,view:7,widget_editor:12}}) \ No newline at end of file diff --git a/5.0/selection/selection.html b/5.0/selection/selection.html new file mode 100644 index 000000000..9d1f7613a --- /dev/null +++ b/5.0/selection/selection.html @@ -0,0 +1,282 @@ + + + + + + + The selection service — Apptools Documentation + + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +
+

The selection service

+

It is quite common in GUI applications to have a UI element displaying a +collection of items that a user can select (“selection providers”), while +other parts of the application must react to changes in the selection +(“selection listeners”).

+

Ideally, the listeners would not have a direct dependency on the UI object. +This is especially important in extensible envisage applications, where +a plugin might need to react to a selection change, but we do not want to +expose the internal organization of the application to external developers.

+

This package defines a selection service that manages the communication +between providers and listener.

+
+

The SelectionService object

+

The SelectionService object is the central manager that handles +the communication between selection providers and listener.

+

Selection providers are components that wish to +publish information about their current selection for public consumption. +They register to a selection +service instance when they first have a selection available (e.g., when the +UI showing a list of selectable items is initialized), and un-register as soon +as the selection is not available anymore (e.g., the UI is destroyed when the +windows is closed).

+

Selection listeners can query the selection +service to get the current selection published by a provider, using the +provider unique ID.

+

The service acts as a broker between providers and listeners, making sure that +they are notified when the +selection +event is fired.

+
+
+

Selection providers

+

Any object can become a selection provider by implementing the +ISelectionProvider +interface, and registering to the selection service.

+

Selection providers must provide a unique ID +provider_id, +which is used by listeners to request its current selection.

+

Whenever its selection changes, providers fire a +selection +event. The content of the event is an instance implementing +ISelection that contains information about the selected items. +For example, a ListSelection object contains a list of selected +items, and their indices.

+

Selection providers can also be queried directly about their current selection +using the +get_selection +method, and can be requested to change their selection to a new one with the +set_selection +method.

+
+

Registration

+

Selection providers publish their selection by registering to the selection +service using the +add_selection_provider +method. When the selection is no longer available, selection providers +should un-register through +remove_selection_provider.

+

Typically, selection providers are UI objects showing a list or tree of items, +they register as soon as the UI component is initialized, and un-register +when the UI component disappears (e.g., because their window has been closed). +In more complex applications, the registration could be done by a controller +object instead.

+
+
+
+

Selection listeners

+

Selection listeners request information regarding the current selection +of a selection provider given their provider ID. The SelectionService +supports two distinct use cases:

+
+
    +
  1. Passively listening to selection changes: listener connect to a specific +provider and are notified when the provider’s selection changes.

  2. +
  3. Actively querying a provider for its current selection: the selection +service can be used to query a provider using its unique ID.

  4. +
+
+
+

Passive listening

+

Listeners connect to the selection events for a given provider using the +connect_selection_listener +method. They need to provide the unique ID of the provider, and a function +(or callable) that is called to send the event. This callback function takes +one argument, an implementation of the ISelection that represents +the selection.

+

It is possible for a listener to connect to a provider ID before it is +registered. As soon as the provider is registered, the listener will receive +a notification containing the provider’s initial selection.

+

To disconnect a listener use the methods +disconnect_selection_listener.

+
+
+

Active querying

+

In other instances, an element of the application only needs the current +selection at a specific time. For example, a toolbar button could open dialog +representing a user action based on what is currently selected in the active +editor.

+

The +get_selection +method calls the corresponding method on the provider with the given ID and +returns an ISelection instance.

+
+
+

Setting a selection

+

Finally, it is possible to request a provider to set its selection to a given +set of objects with +set_selection. +The main use case for this method is multiple views of the same list of +objects, which need to keep their selection synchronized.

+

If the items specified in the arguments are not available in the provider, +a ProviderNotRegisteredError is raised, +unless the optional keyword argument ignore_missing is set to True.

+
+
+
+ + +
+
+
+
+
+ +

Table of Contents

+ + +

Previous topic

+

Undo Framework

+

Next topic

+

Naming

+

This Page

+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/5.0/undo/Introduction.html b/5.0/undo/Introduction.html new file mode 100644 index 000000000..4351eaac1 --- /dev/null +++ b/5.0/undo/Introduction.html @@ -0,0 +1,386 @@ + + + + + + + Undo Framework — Apptools Documentation + + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ + + + + + +
+
+
+ + +
+
+ +
+
+ +
+

Undo Framework

+

The Undo Framework is a component of the Enthought Tool Suite that provides +developers with an API that implements the standard pattern for do/undo/redo +commands.

+

The framework is completely configurable. Alternate implementations of all +major components can be provided if necessary.

+
+

Framework Concepts

+

The following are the concepts supported by the framework.

+
    +
  • Command

    +

    A command is an application defined operation that can be done (i.e. +executed), undone (i.e. reverted) and redone (i.e. repeated).

    +

    A command operates on some data and maintains sufficient state to allow it to +revert or repeat a change to the data.

    +

    Commands may be merged so that potentially long sequences of similar +commands (e.g. to add a character to some text) can be collapsed into a +single command (e.g. to add a word to some text).

    +
  • +
  • Macro

    +

    A macro is a sequence of commands that is treated as a single command when +being undone or redone.

    +
  • +
  • Command Stack

    +

    A command is done by pushing it onto a command stack. The last command can +be undone and redone by calling appropriate command stack methods. It is +also possible to move the stack’s position to any point and the command stack +will ensure that commands are undone or redone as required.

    +

    A command stack maintains a clean state which is updated as commands are +done and undone. It may be explicitly set, for example when the data being +manipulated by the commands is saved to disk.

    +

    Canned PyFace actions are provided as wrappers around command stack methods +to implement common menu items.

    +
  • +
  • Undo Manager

    +

    An undo manager is responsible for one or more command stacks and maintains +a reference to the currently active stack. It provides convenience undo and +redo methods that operate on the currently active stack.

    +

    An undo manager ensures that each command execution is allocated a unique +sequence number, irrespective of which command stack it is pushed to. Using +this it is possible to synchronise multiple command stacks and restore them +to a particular point in time.

    +

    An undo manager will generate an event whenever the clean state of the active +stack changes. This can be used to maintain some sort of GUI status +indicator to tell the user that their data has been modified since it was +last saved.

    +
  • +
+

Typically an application will have one undo manager and one undo stack for +each data type that can be edited. However this is not a requirement: how the +command stack’s in particular are organised and linked (with the user +manager’s sequence number) can need careful thought so as not to confuse the +user - particularly in a plugin based application that may have many editors.

+

To support this typical usage the PyFace Workbench class has an +undo_manager trait and the PyFace Editor class has a command_stack +trait. Both are lazy loaded so can be completely ignored if they are not used.

+
+
+

API Overview

+

This section gives a brief overview of the various classes implemented in the +framework. The complete API documentation is available as endo generated +HTML.

+

The example application demonstrates all the major features of the framework.

+
+

UndoManager

+

The UndoManager class is the default implementation of the IUndoManager +interface.

+
+
active_stack

This trait is a reference to the currently active command stack and may be +None. Typically it is set when some sort of editor becomes active.

+
+
active_stack_clean

This boolean trait reflects the clean state of the currently active +command stack. It is intended to support a “document modified” indicator +in the GUI. It is maintained by the undo manager.

+
+
stack_updated

This event is fired when the index of a command stack is changed. A +reference to the stack is passed as an argument to the event and may not +be the currently active stack.

+
+
undo_name

This Str trait is the name of the command that can be undone, and will +be empty if there is no such command. It is maintained by the undo +manager.

+
+
redo_name

This Str trait is the name of the command that can be redone, and will +be empty if there is no such command. It is maintained by the undo +manager.

+
+
sequence_nr

This integer trait is the sequence number of the next command to be +executed. It is incremented immediately before a command’s do() +method is called. A particular sequence number identifies the state of +all command stacks handled by the undo manager and allows those stacks to +be set to the point they were at at a particular point in time. In other +words, the sequence number allows otherwise independent command stacks to +be synchronised.

+
+
undo()

This method calls the undo() method of the last command on the active +command stack.

+
+
redo()

This method calls the redo() method of the last undone command on the +active command stack.

+
+
+
+
+

CommandStack

+

The CommandStack class is the default implementation of the +ICommandStack interface.

+
+
clean

This boolean traits reflects the clean state of the command stack. Its +value changes as commands are executed, undone and redone. It may also be +explicitly set to mark the current stack position as being clean (when +data is saved to disk for example).

+
+
undo_name

This Str trait is the name of the command that can be undone, and will +be empty if there is no such command. It is maintained by the command +stack.

+
+
redo_name

This Str trait is the name of the command that can be redone, and will +be empty if there is no such command. It is maintained by the command +stack.

+
+
undo_manager

This trait is a reference to the undo manager that manages the command +stack.

+
+
push(command)

This method executes the given command by calling its do() method. +Any value returned by do() is returned by push(). If the command +couldn’t be merged with the previous one then it is saved on the command +stack.

+
+
undo(sequence_nr=0)

This method undoes the last command. If a sequence number is given then +all commands are undone up to an including the sequence number.

+
+
redo(sequence_nr=0)

This method redoes the last command and returns any result. If a sequence +number is given then all commands are redone up to an including the +sequence number and any result of the last of these is returned.

+
+
clear()

This method clears the command stack, without undoing or redoing any +commands, and leaves the stack in a clean state. It is typically used +when all changes to the data have been abandoned.

+
+
begin_macro(name)

This method begins a macro by creating an empty command with the given +name. The commands passed to all subsequent calls to push() will be +contained in the macro until the next call to end_macro(). Macros may +be nested. The command stack is disabled (ie. nothing can be undone or +redone) while a macro is being created (ie. while there is an outstanding +end_macro() call).

+
+
end_macro()

This method ends the current macro.

+
+
+
+
+

ICommand

+

The ICommand interface defines the interface that must be implemented by +any undoable/redoable command.

+
+
data

This optional trait is a reference to the data object that the command +operates on. It is not used by the framework itself.

+
+
name

This Str trait is the name of the command as it will appear in any GUI +element (e.g. in the text of an undo and redo menu entry). It may include +& to indicate a keyboard shortcut which will be automatically removed +whenever it is inappropriate.

+
+
__init__(*args)

If the command takes arguments then the command must ensure that deep +copies should be made if appropriate.

+
+
do()

This method is called by a command stack to execute the command and to +return any result. The command must save any state necessary for the +undo() and redo() methods to work. It is guaranteed that this +will only ever be called once and that it will be called before any call +to undo() or redo().

+
+
undo()

This method is called by a command stack to undo the command.

+
+
redo()

This method is called by a command stack to redo the command and to return +any result.

+
+
merge(other)

This method is called by the command stack to try and merge the other +command with this one. True should be returned if the commands were +merged. If the commands are merged then other will not be placed on +the command stack. A subsequent undo or redo of this modified command +must have the same effect as the two original commands.

+
+
+
+
+

AbstractCommand

+

AbstractCommand is an abstract base class that implements the ICommand +interface. It provides a default implementation of the merge() method.

+
+
+

CommandAction

+

The CommandAction class is a sub-class of the PyFace Action class that +is used to wrap commands.

+
+
command

This callable trait must be set to a factory that will return an object +that implements ICommand. It will be called when the action is invoked +and the object created pushed onto the command stack.

+
+
command_stack

This instance trait must be set to the command stack that commands invoked +by the action are pushed to.

+
+
data

This optional trait is a reference to the data object that will be passed +to the command factory when it is called.

+
+
+
+
+

UndoAction

+

The UndoAction class is a canned PyFace action that undoes the last +command of the active command stack.

+
+
+

RedoAction

+

The RedoAction class is a canned PyFace action that redoes the last +command undone of the active command stack.

+
+
+
+ + +
+
+
+
+
+ +

Table of Contents

+ + +

Previous topic

+

Automatic script recording

+

Next topic

+

The selection service

+

This Page

+ + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/_modules/apptools/io/file.html b/_modules/apptools/io/file.html index 5119052ac..a996811e5 100644 --- a/_modules/apptools/io/file.html +++ b/_modules/apptools/io/file.html @@ -13,9 +13,11 @@ @@ -72,27 +74,26 @@
-
+

Source code for apptools.io.file

-#------------------------------------------------------------------------------
-# Copyright (c) 2005, Enthought, Inc.
+# (C) Copyright 2005-2020 Enthought, Inc., Austin, TX
 # All rights reserved.
 #
 # This software is provided without warranty under the terms of the BSD
-# license included in enthought/LICENSE.txt and may be redistributed only
-# under the conditions described in the aforementioned license.  The license
+# license included in LICENSE.txt and may be redistributed only under
+# the conditions described in the aforementioned license. The license
 # is also available online at http://www.enthought.com/licenses/BSD.txt
-# Thanks for using Enthought open source!
 #
-# Author: Enthought, Inc.
-# Description: <Enthought IO package component>
-#------------------------------------------------------------------------------
+# Thanks for using Enthought open source!
 """ A representation of files and folders in a file system. """
 
 
 # Standard/built-in imports.
-import mimetypes, os, shutil, stat
+import mimetypes
+import os
+import shutil
+import stat
 
 # Enthought library imports.
 from traits.api import Bool, HasPrivateTraits, Instance, List, Property
@@ -108,7 +109,7 @@ 

Source code for apptools.io.file

     absolute_path = Property(Str)
 
     # The folder's children (for files this is always None).
-    children = Property(List('File'))
+    children = Property(List("File"))
 
     # The file extension (for folders this is always the empty string).
     #
@@ -140,7 +141,7 @@ 

Source code for apptools.io.file

     name = Property(Str)
 
     # The parent of this file/folder (None if it has no parent).
-    parent = Property(Instance('File'))
+    parent = Property(Instance("File"))
 
     # The path name of this file/folder.
     path = Str
@@ -157,19 +158,10 @@ 

Source code for apptools.io.file

 
         super(File, self).__init__(path=path, **traits)
 
-        return
-
-    def __cmp__(self, other):
-        """ Comparison operators. """
-        if isinstance(other, File):
-            return cmp(self.path, other.path)
-
-        return 1
-
     def __str__(self):
         """ Returns an 'informal' string representation of the object. """
 
-        return 'File(%s)' % self.path
+        return "File(%s)" % self.path
 
     ###########################################################################
     # 'File' interface.
@@ -183,7 +175,7 @@ 

Source code for apptools.io.file

         return os.path.abspath(self.path)
 
     def _get_children(self):
-        """ Returns the folder's children.
+        """Returns the folder's children.
 
         Returns None if the path does not exist or is not a folder.
 
@@ -224,7 +216,7 @@ 

Source code for apptools.io.file

     def _get_is_package(self):
         """ Returns True if the path exists and is a Python package. """
 
-        return self.is_folder and '__init__.py' in os.listdir(self.path)
+        return self.is_folder and "__init__.py" in os.listdir(self.path)
 
     def _get_is_readonly(self):
         """ Returns True if the file/folder is readonly, otherwise False. """
@@ -279,7 +271,7 @@ 

Source code for apptools.io.file

         """ Returns the path as a URL. """
 
         # Strip out the leading slash on POSIX systems.
-        return 'file:///%s' % self.absolute_path.lstrip('/')
+        return "file:///%s" % self.absolute_path.lstrip("/")
 
     #### Methods ##############################################################
 
@@ -294,24 +286,20 @@ 

Source code for apptools.io.file

             shutil.copytree(self.path, destination.path)
 
         elif self.is_file:
-            shutil.copyfile(self.path, destination.path)
-
-        return
+ shutil.copyfile(self.path, destination.path)
-
[docs] def create_file(self, contents=''): +
[docs] def create_file(self, contents=""): """ Creates a file at this path. """ if self.exists: raise ValueError("file %s already exists" % self.path) - f = open(self.path, 'w') + f = open(self.path, "w") f.write(contents) - f.close() - - return
+ f.close()
[docs] def create_folder(self): - """ Creates a folder at this path. + """Creates a folder at this path. All intermediate folders MUST already exist. @@ -320,12 +308,10 @@

Source code for apptools.io.file

         if self.exists:
             raise ValueError("folder %s already exists" % self.path)
 
-        os.mkdir(self.path)
-
-        return
+ os.mkdir(self.path)
[docs] def create_folders(self): - """ Creates a folder at this path. + """Creates a folder at this path. This will attempt to create any missing intermediate folders. @@ -334,12 +320,10 @@

Source code for apptools.io.file

         if self.exists:
             raise ValueError("folder %s already exists" % self.path)
 
-        os.makedirs(self.path)
-
-        return
+ os.makedirs(self.path)
[docs] def create_package(self): - """ Creates a package at this path. + """Creates a package at this path. All intermediate folders/packages MUST already exist. @@ -352,13 +336,11 @@

Source code for apptools.io.file

 
         # Create the '__init__.py' file that actually turns the folder into a
         # package!
-        init = File(os.path.join(self.path, '__init__.py'))
-        init.create_file()
-
-        return
+ init = File(os.path.join(self.path, "__init__.py")) + init.create_file()
[docs] def delete(self): - """ Deletes this file/folder. + """Deletes this file/folder. Does nothing if the file/folder does not exist. @@ -376,9 +358,7 @@

Source code for apptools.io.file

             self.make_writeable()
 
             # Delete it!
-            os.remove(self.path)
-
-        return
+ os.remove(self.path)
[docs] def make_writeable(self): """ Attempt to make the file/folder writeable. """ @@ -397,9 +377,7 @@

Source code for apptools.io.file

             # Try to make sure that the file is writeable (i.e., can be
             # deleted!).
             if not os.access(self.path, os.W_OK):
-                os.chmod(self.path, stat.S_IWUSR)
-
-        return
+ os.chmod(self.path, stat.S_IWUSR)
[docs] def move(self, destination): """ Moves this file/folder. """ @@ -412,11 +390,7 @@

Source code for apptools.io.file

         self.make_writeable()
 
         # Move it!
-        shutil.move(self.path, destination.path)
-
-        return
- -#### EOF ###################################################################### + shutil.move(self.path, destination.path)
@@ -428,13 +402,11 @@

Source code for apptools.io.file

               
             

@@ -458,10 +430,10 @@

Quick search

© Copyright 2008-2020, Enthought
  • - Last updated on Jun 12, 2020. + Last updated on Dec 17, 2020.
  • - Created using Sphinx 1.8.5. + Created using Sphinx 2.3.1.
  • diff --git a/_modules/apptools/io/h5/dict_node.html b/_modules/apptools/io/h5/dict_node.html index 84bf2ec2f..1497f2caa 100644 --- a/_modules/apptools/io/h5/dict_node.html +++ b/_modules/apptools/io/h5/dict_node.html @@ -13,9 +13,11 @@ @@ -72,10 +74,19 @@
    -
    +

    Source code for apptools.io.h5.dict_node

    -from contextlib import closing
    +# (C) Copyright 2005-2020 Enthought, Inc., Austin, TX
    +# All rights reserved.
    +#
    +# This software is provided without warranty under the terms of the BSD
    +# license included in LICENSE.txt and may be redistributed only under
    +# the conditions described in the aforementioned license. The license
    +# is also available online at http://www.enthought.com/licenses/BSD.txt
    +#
    +# Thanks for using Enthought open source!
    +from contextlib import closing
     import json
     
     from numpy import ndarray
    @@ -85,12 +96,12 @@ 

    Source code for apptools.io.h5.dict_node

     
     
     #: The key name which identifies array objects in the JSON dict.
    -ARRAY_PROXY_KEY = '__array__'
    -NODE_KEY = 'node_name'
    +ARRAY_PROXY_KEY = "__array__"
    +NODE_KEY = "node_name"
     
     
     
    [docs]class H5DictNode(object): - """ Dictionary-like node interface. + """Dictionary-like node interface. Data for the dict is stored as a JSON file in a PyTables FileNode. This allows easy storage of Python objects, such as dictionaries and lists of @@ -109,7 +120,7 @@

    Source code for apptools.io.h5.dict_node

         """
     
         #: Name of filenode where dict data is stored.
    -    _pyobject_data_node = '_pyobject_data'
    +    _pyobject_data_node = "_pyobject_data"
     
         def __init__(self, h5_group, auto_flush=True):
             assert self.is_dict_node(h5_group)
    @@ -122,12 +133,12 @@ 

    Source code for apptools.io.h5.dict_node

             dict_node = getattr(h5_group, self._pyobject_data_node)
             with closing(filenode.open_node(dict_node)) as f:
                 self._pyobject_data = json.loads(
    -                f.read().decode('ascii'), object_hook=self._object_hook
    +                f.read().decode("ascii"), object_hook=self._object_hook
                 )
     
    -    #--------------------------------------------------------------------------
    +    # --------------------------------------------------------------------------
         #  Dictionary interface
    -    #--------------------------------------------------------------------------
    +    # --------------------------------------------------------------------------
     
         def __getitem__(self, key):
             return self.data[key]
    @@ -148,9 +159,9 @@ 

    Source code for apptools.io.h5.dict_node

     
    [docs] def keys(self): return self.data.keys()
    - #-------------------------------------------------------------------------- + # -------------------------------------------------------------------------- # Public interface - #-------------------------------------------------------------------------- + # -------------------------------------------------------------------------- @property def data(self): @@ -169,7 +180,7 @@

    Source code for apptools.io.h5.dict_node

     
     
    [docs] @classmethod def add_to_h5file(cls, h5, node_path, data=None, **kwargs): - """ Add dict node to an H5 file at the specified path. + """Add dict node to an H5 file at the specified path. Parameters ---------- @@ -188,7 +199,7 @@

    Source code for apptools.io.h5.dict_node

     
     
    [docs] @classmethod def is_dict_node(cls, pytables_node): - """ Return True if PyTables node looks like an H5DictNode. + """Return True if PyTables node looks like an H5DictNode. NOTE: That this returns False if the node is an `H5DictNode` instance, since the input node should be a normal PyTables Group node. @@ -204,12 +215,12 @@

    Source code for apptools.io.h5.dict_node

     
             return cls._pyobject_data_node in pytables_node._v_children
    - #-------------------------------------------------------------------------- + # -------------------------------------------------------------------------- # Private interface - #-------------------------------------------------------------------------- + # -------------------------------------------------------------------------- def _f_remove(self): - """ This is called by H5File whenever a node is removed. + """This is called by H5File whenever a node is removed. All nodes in `_h5_group` will be removed. """ @@ -222,7 +233,7 @@

    Source code for apptools.io.h5.dict_node

             self._h5_group._f_remove()
     
         def _object_hook(self, dct):
    -        """ This gets passed object dictionaries by `json.load(s)` and if it
    +        """This gets passed object dictionaries by `json.load(s)` and if it
             finds `ARRAY_PROXY_KEY` in the object description it returns the
             proxied array object.
             """
    @@ -251,17 +262,17 @@ 

    Source code for apptools.io.h5.dict_node

     
             kwargs = dict(where=node_path, name=cls._pyobject_data_node)
             with closing(filenode.new_node(pyt_file, **kwargs)) as f:
    -            f.write(json.dumps(out_data).encode('ascii'))
    +            f.write(json.dumps(out_data).encode("ascii"))
     
         @classmethod
         def _get_pyt_group(self, group):
    -        if hasattr(group, '_h5_group'):
    +        if hasattr(group, "_h5_group"):
                 group = group._h5_group
             return group
     
         @classmethod
         def _array_proxy(cls, pyt_file, group, key, array):
    -        """ Stores an array as a normal H5 node and returns the proxy object
    +        """Stores an array as a normal H5 node and returns the proxy object
             which will be serialized to JSON.
     
             `ARRAY_PROXY_KEY` marks the object dictionary as an array proxy so that
    @@ -310,13 +321,11 @@ 

    Source code for apptools.io.h5.dict_node

                   
                 

    @@ -340,10 +349,10 @@

    Quick search

    © Copyright 2008-2020, Enthought
  • - Last updated on Jun 12, 2020. + Last updated on Dec 17, 2020.
  • - Created using Sphinx 1.8.5. + Created using Sphinx 2.3.1.
  • diff --git a/_modules/apptools/io/h5/file.html b/_modules/apptools/io/h5/file.html index 4d4013242..5fdccad23 100644 --- a/_modules/apptools/io/h5/file.html +++ b/_modules/apptools/io/h5/file.html @@ -13,9 +13,11 @@ @@ -72,11 +74,21 @@
    -
    +

    Source code for apptools.io.h5.file

    -from collections import Mapping, MutableMapping
    +# (C) Copyright 2005-2020 Enthought, Inc., Austin, TX
    +# All rights reserved.
    +#
    +# This software is provided without warranty under the terms of the BSD
    +# license included in LICENSE.txt and may be redistributed only under
    +# the conditions described in the aforementioned license. The license
    +# is also available online at http://www.enthought.com/licenses/BSD.txt
    +#
    +# Thanks for using Enthought open source!
    +from collections import Mapping, MutableMapping
     from functools import partial
    +import inspect
     
     import numpy as np
     import tables
    @@ -86,8 +98,7 @@ 

    Source code for apptools.io.h5.file

     
     
     
    [docs]def get_atom(dtype): - """ Return a PyTables Atom for the given dtype or dtype string. - """ + """Return a PyTables Atom for the given dtype or dtype string.""" return tables.Atom.from_dtype(np.dtype(dtype))
    @@ -101,8 +112,10 @@

    Source code for apptools.io.h5.file

     Note that the first argument is a nodepath relative to the group, rather than
     an absolute path. Below is the original docstring:
     
    -    """.format(func_name=wrapped.__name__)
    -    wrapped.__doc__ = PREAMBLE + original.__doc__
    +""".format(
    +        func_name=wrapped.__name__
    +    )
    +    wrapped.__doc__ = PREAMBLE + inspect.cleandoc(original.__doc__)
         return wrapped
     
     
    @@ -141,17 +154,28 @@ 

    Source code for apptools.io.h5.file

             array (see PyTables `create_carray`).
     
         """
    -    exists_error = ("'{}' exists in '{}'; set `delete_existing` attribute "
    -                    "to True to overwrite existing calculations.")
     
    -    def __init__(self, filename, mode='r+', delete_existing=False,
    -                 auto_groups=True, auto_open=True, h5filters=None):
    +    exists_error = (
    +        "'{}' exists in '{}'; set `delete_existing` attribute "
    +        "to True to overwrite existing calculations."
    +    )
    +
    +    def __init__(
    +        self,
    +        filename,
    +        mode="r+",
    +        delete_existing=False,
    +        auto_groups=True,
    +        auto_open=True,
    +        h5filters=None,
    +    ):
             self.mode = mode
             self.delete_existing = delete_existing
             self.auto_groups = auto_groups
             if h5filters is None:
    -            self.h5filters = tables.Filters(complib='blosc', complevel=5,
    -                                            shuffle=True)
    +            self.h5filters = tables.Filters(
    +                complib="blosc", complevel=5, shuffle=True
    +            )
             self._h5 = None
     
             if isinstance(filename, tables.File):
    @@ -175,7 +199,7 @@ 

    Source code for apptools.io.h5.file

     
         @property
         def root(self):
    -        return self['/']
    +        return self["/"]
     
         @property
         def is_open(self):
    @@ -199,19 +223,26 @@ 

    Source code for apptools.io.h5.file

             return _wrap_node(node)
     
         def __iter__(self):
    -        return (_wrap_node(n) for n in self._h5.iter_nodes(where='/'))
    +        return (_wrap_node(n) for n in self._h5.iter_nodes(where="/"))
     
         def __len__(self):
             return iterator_length(self)
     
    -
    [docs] def iteritems(self, path='/'): +
    [docs] def iteritems(self, path="/"): """ Iterate over node paths and nodes of the h5 file. """ for node in self._h5.walk_nodes(where=path): node_path = node._v_pathname yield node_path, _wrap_node(node)
    -
    [docs] def create_array(self, node_path, array_or_shape, dtype=None, - chunked=False, extendable=False, **kwargs): +
    [docs] def create_array( + self, + node_path, + array_or_shape, + dtype=None, + chunked=False, + extendable=False, + **kwargs + ): """Create node to store an array. Parameters @@ -251,14 +282,16 @@

    Source code for apptools.io.h5.file

             if extendable:
                 shape = (0,) + shape[1:]
                 atom = get_atom(dtype)
    -            node = h5.create_earray(path, name, atom, shape,
    -                                    filters=self.h5filters, **kwargs)
    +            node = h5.create_earray(
    +                path, name, atom, shape, filters=self.h5filters, **kwargs
    +            )
                 if array is not None:
                     node.append(array)
             elif chunked:
                 atom = get_atom(dtype)
    -            node = h5.create_carray(path, name, atom, shape,
    -                                    filters=self.h5filters, **kwargs)
    +            node = h5.create_carray(
    +                path, name, atom, shape, filters=self.h5filters, **kwargs
    +            )
                 if array is not None:
                     node[:] = array
             else:
    @@ -284,7 +317,7 @@ 

    Source code for apptools.io.h5.file

             return self[group_path]
    [docs] def create_dict(self, node_path, data=None, **kwargs): - """ Create dict node at the specified path. + """Create dict node at the specified path. Parameters ---------- @@ -299,7 +332,7 @@

    Source code for apptools.io.h5.file

             return self[node_path]
    [docs] def create_table(self, node_path, description, **kwargs): - """ Create table node at the specified path. + """Create table node at the specified path. Parameters ---------- @@ -367,7 +400,7 @@

    Source code for apptools.io.h5.file

     
         @classmethod
         def _assert_valid_path(self, node_path):
    -        if 'attrs' in node_path.split('/'):
    +        if "attrs" in node_path.split("/"):
                 raise ValueError("'attrs' is an invalid node name.")
     
     
    [docs] @classmethod @@ -381,9 +414,9 @@

    Source code for apptools.io.h5.file

             node_path : str
                 PyTable node path; e.g. '/path/to/node'.
             """
    -        i = node_path.rfind('/')
    +        i = node_path.rfind("/")
             if i == 0:
    -            return '/', node_path[1:]
    +            return "/", node_path[1:]
             else:
                 return node_path[:i], node_path[i + 1:]
    @@ -399,14 +432,14 @@

    Source code for apptools.io.h5.file

             args : str
                 Parts of path to be joined.
             """
    -        path = '/'.join(part.strip('/') for part in args)
    -        if not path.startswith('/'):
    -            path = '/' + path
    +        path = "/".join(part.strip("/") for part in args)
    +        if not path.startswith("/"):
    +            path = "/" + path
             return path
    [docs]class H5Attrs(MutableMapping): - """ An attributes dictionary for an h5 node. + """An attributes dictionary for an h5 node. This intercepts `__setitem__` so that python sequences can be converted to numpy arrays. This helps preserve the readability of our HDF5 files by @@ -447,7 +480,7 @@

    Source code for apptools.io.h5.file

     
     
     
    [docs]class H5Group(Mapping): - """ A group node in an H5File. + """A group node in an H5File. This is a thin wrapper around PyTables' Group object to expose attributes and maintain the dict interface of H5File. @@ -467,14 +500,14 @@

    Source code for apptools.io.h5.file

             return repr(self._h5_group)
     
         def __getitem__(self, node_path):
    -        parts = node_path.split('/')
    +        parts = node_path.split("/")
             # PyTables stores children as attributes
             node = self._h5_group.__getattr__(parts[0])
             node = _wrap_node(node)
             if len(parts) == 1:
                 return node
             else:
    -            return node['/'.join(parts[1:])]
    +            return node["/".join(parts[1:])]
     
         def __iter__(self):
             return (_wrap_node(c) for c in self._h5_group)
    @@ -517,40 +550,59 @@ 

    Source code for apptools.io.h5.file

     
     
    [docs] @h5_group_wrapper(H5File.create_group) def create_group(self, group_subpath, delete_existing=False, **kwargs): - return self._delegate_to_h5file('create_group', group_subpath, - delete_existing=delete_existing, - **kwargs)
    + return self._delegate_to_h5file( + "create_group", + group_subpath, + delete_existing=delete_existing, + **kwargs + )
    [docs] @h5_group_wrapper(H5File.remove_group) def remove_group(self, group_subpath, **kwargs): - return self._delegate_to_h5file('remove_group', group_subpath, - **kwargs)
    + return self._delegate_to_h5file( + "remove_group", group_subpath, **kwargs + )
    [docs] @h5_group_wrapper(H5File.create_array) - def create_array(self, node_subpath, array_or_shape, dtype=None, - chunked=False, extendable=False, **kwargs): - return self._delegate_to_h5file('create_array', node_subpath, - array_or_shape, dtype=dtype, - chunked=chunked, extendable=extendable, - **kwargs)
    + def create_array( + self, + node_subpath, + array_or_shape, + dtype=None, + chunked=False, + extendable=False, + **kwargs + ): + return self._delegate_to_h5file( + "create_array", + node_subpath, + array_or_shape, + dtype=dtype, + chunked=chunked, + extendable=extendable, + **kwargs + )
    [docs] @h5_group_wrapper(H5File.create_table) def create_table(self, node_subpath, description, *args, **kwargs): - return self._delegate_to_h5file('create_table', node_subpath, - description, *args, **kwargs)
    + return self._delegate_to_h5file( + "create_table", node_subpath, description, *args, **kwargs + )
    [docs] @h5_group_wrapper(H5File.create_dict) def create_dict(self, node_subpath, data=None, **kwargs): - return self._delegate_to_h5file('create_dict', node_subpath, data=data, - **kwargs)
    + return self._delegate_to_h5file( + "create_dict", node_subpath, data=data, **kwargs + )
    [docs] @h5_group_wrapper(H5File.remove_node) def remove_node(self, node_subpath, **kwargs): - return self._delegate_to_h5file('remove_node', node_subpath, **kwargs)
    + return self._delegate_to_h5file("remove_node", node_subpath, **kwargs)
    - def _delegate_to_h5file(self, function_name, node_subpath, - *args, **kwargs): - delete_existing = kwargs.pop('delete_existing', False) + def _delegate_to_h5file( + self, function_name, node_subpath, *args, **kwargs + ): + delete_existing = kwargs.pop("delete_existing", False) h5 = H5File(self._h5_group._v_file, delete_existing=delete_existing) group_path = h5.join_path(self.pathname, node_subpath) func = getattr(h5, function_name) @@ -578,13 +630,11 @@

    Source code for apptools.io.h5.file

                   
                 

    @@ -608,10 +658,10 @@

    Quick search

    © Copyright 2008-2020, Enthought
  • - Last updated on Jun 12, 2020. + Last updated on Dec 17, 2020.
  • - Created using Sphinx 1.8.5. + Created using Sphinx 2.3.1.
  • diff --git a/_modules/apptools/io/h5/table_node.html b/_modules/apptools/io/h5/table_node.html index c8da24049..755c69191 100644 --- a/_modules/apptools/io/h5/table_node.html +++ b/_modules/apptools/io/h5/table_node.html @@ -13,9 +13,11 @@ @@ -72,18 +74,26 @@
    -
    +

    Source code for apptools.io.h5.table_node

    -import numpy as np
    -from pandas import DataFrame
    -import six
    +# (C) Copyright 2005-2020 Enthought, Inc., Austin, TX
    +# All rights reserved.
    +#
    +# This software is provided without warranty under the terms of the BSD
    +# license included in LICENSE.txt and may be redistributed only under
    +# the conditions described in the aforementioned license. The license
    +# is also available online at http://www.enthought.com/licenses/BSD.txt
    +#
    +# Thanks for using Enthought open source!
    +import numpy as np
    +
     from tables.table import Table as PyTablesTable
     
     
     class _TableRowAccessor(object):
    -    """ A simple object which provides read access to the rows in a Table.
    -    """
    +    """A simple object which provides read access to the rows in a Table."""
    +
         def __init__(self, h5_table):
             self._h5_table = h5_table
     
    @@ -92,7 +102,7 @@ 

    Source code for apptools.io.h5.table_node

     
     
     
    [docs]class H5TableNode(object): - """ A wrapper for PyTables Table nodes. + """A wrapper for PyTables Table nodes. Parameters ---------- @@ -105,16 +115,16 @@

    Source code for apptools.io.h5.table_node

             from .file import H5Attrs
     
             assert self.is_table_node(node)
    -        self._h5_table = node._h5_table if hasattr(node, '_h5_table') else node
    +        self._h5_table = node._h5_table if hasattr(node, "_h5_table") else node
             self.attrs = H5Attrs(self._h5_table._v_attrs)
     
    -    #--------------------------------------------------------------------------
    +    # --------------------------------------------------------------------------
         #  Creation methods
    -    #--------------------------------------------------------------------------
    +    # --------------------------------------------------------------------------
     
     
    [docs] @classmethod def add_to_h5file(cls, h5, node_path, description, **kwargs): - """ Add table node to an H5 file at the specified path. + """Add table node to an H5 file at the specified path. Parameters ---------- @@ -140,16 +150,16 @@

    Source code for apptools.io.h5.table_node

     
     
    [docs] @classmethod def is_table_node(cls, pytables_node): - """ Return True if pytables_node is a pytables.Table or a H5TableNode. + """Return True if pytables_node is a pytables.Table or a H5TableNode. """ return isinstance(pytables_node, (PyTablesTable, H5TableNode))
    - #-------------------------------------------------------------------------- + # -------------------------------------------------------------------------- # Public interface - #-------------------------------------------------------------------------- + # --------------------------------------------------------------------------
    [docs] def append(self, data): - """ Add some data to the table. + """Add some data to the table. Parameters ---------- @@ -160,7 +170,7 @@

    Source code for apptools.io.h5.table_node

             self._h5_table.append(rows)
    def __getitem__(self, col_or_cols): - """ Return one or more columns of data from the table. + """Return one or more columns of data from the table. Parameters ---------- @@ -173,7 +183,7 @@

    Source code for apptools.io.h5.table_node

                 An array of column data with the column order matching that of
                 `col_or_cols`.
             """
    -        if isinstance(col_or_cols, six.string_types):
    +        if isinstance(col_or_cols, str):
                 return self._h5_table.col(col_or_cols)
     
             column_data = [self._h5_table.col(name) for name in col_or_cols]
    @@ -181,24 +191,27 @@ 

    Source code for apptools.io.h5.table_node

     
         @property
         def ix(self):
    -        """ Return an object which provides access to row data.
    -        """
    +        """Return an object which provides access to row data."""
             return _TableRowAccessor(self._h5_table)
     
     
    [docs] def keys(self): return self._h5_table.colnames
    [docs] def to_dataframe(self): - """ Return table data as a pandas `DataFrame`. + """Return table data as a pandas `DataFrame`. XXX: This does not work if the table contains a multidimensional column + + This method requires pandas to have been installed in the environment. """ + from pandas import DataFrame + # Slicing rows gives a numpy struct array, which DataFrame understands. return DataFrame(self.ix[:])
    - #-------------------------------------------------------------------------- + # -------------------------------------------------------------------------- # Object interface - #-------------------------------------------------------------------------- + # -------------------------------------------------------------------------- def __repr__(self): return repr(self._h5_table) @@ -206,12 +219,12 @@

    Source code for apptools.io.h5.table_node

         def __len__(self):
             return self._h5_table.nrows
     
    -    #--------------------------------------------------------------------------
    +    # --------------------------------------------------------------------------
         #  Private interface
    -    #--------------------------------------------------------------------------
    +    # --------------------------------------------------------------------------
     
         def _f_remove(self):
    -        """ Implement the PyTables `Node._f_remove` method so that H5File
    +        """Implement the PyTables `Node._f_remove` method so that H5File
             doesn't choke when trying to remove our node.
             """
             self._h5_table._f_remove()
    @@ -233,13 +246,11 @@ 

    Source code for apptools.io.h5.table_node

                   
                 

    @@ -263,10 +274,10 @@

    Quick search

    © Copyright 2008-2020, Enthought
  • - Last updated on Jun 12, 2020. + Last updated on Dec 17, 2020.
  • - Created using Sphinx 1.8.5. + Created using Sphinx 2.3.1.
  • diff --git a/_modules/apptools/io/h5/utils.html b/_modules/apptools/io/h5/utils.html index b89f2b187..a35477daa 100644 --- a/_modules/apptools/io/h5/utils.html +++ b/_modules/apptools/io/h5/utils.html @@ -13,9 +13,11 @@ @@ -72,16 +74,25 @@
    -
    +

    Source code for apptools.io.h5.utils

    -from contextlib import contextmanager
    +# (C) Copyright 2005-2020 Enthought, Inc., Austin, TX
    +# All rights reserved.
    +#
    +# This software is provided without warranty under the terms of the BSD
    +# license included in LICENSE.txt and may be redistributed only under
    +# the conditions described in the aforementioned license. The license
    +# is also available online at http://www.enthought.com/licenses/BSD.txt
    +#
    +# Thanks for using Enthought open source!
    +from contextlib import contextmanager
     
     from .file import H5File
     
     
     
    [docs]@contextmanager -def open_h5file(filename, mode='r+', **kwargs): +def open_h5file(filename, mode="r+", **kwargs): """Context manager for reading an HDF5 file as an H5File object. Parameters @@ -114,13 +125,11 @@

    Source code for apptools.io.h5.utils

                   
                 

    @@ -144,10 +153,10 @@

    Quick search

    © Copyright 2008-2020, Enthought
  • - Last updated on Jun 12, 2020. + Last updated on Dec 17, 2020.
  • - Created using Sphinx 1.8.5. + Created using Sphinx 2.3.1.
  • diff --git a/_modules/apptools/logger/agent/attachments.html b/_modules/apptools/logger/agent/attachments.html index 7fea4bb9e..f0d664cbb 100644 --- a/_modules/apptools/logger/agent/attachments.html +++ b/_modules/apptools/logger/agent/attachments.html @@ -13,9 +13,11 @@ @@ -72,10 +74,19 @@
    -
    +

    Source code for apptools.logger.agent.attachments

    -""" Attach relevant project files.
    +# (C) Copyright 2005-2020 Enthought, Inc., Austin, TX
    +# All rights reserved.
    +#
    +# This software is provided without warranty under the terms of the BSD
    +# license included in LICENSE.txt and may be redistributed only under
    +# the conditions described in the aforementioned license. The license
    +# is also available online at http://www.enthought.com/licenses/BSD.txt
    +#
    +# Thanks for using Enthought open source!
    +""" Attach relevant project files.
     
     FIXME: there are no public project plugins for Envisage 3, yet. In any case,
     this stuff should not be hard-coded, but extensible via extension points. The
    @@ -101,35 +112,34 @@ 

    Source code for apptools.logger.agent.attachments

    def __init__(self, message, **traits): traits = traits.copy() - traits['message'] = message + traits["message"] = message super(Attachments, self).__init__(**traits) - - # FIXME: all of the package_*() methods refer to deprecated project plugins. + # FIXME: all of the package_*() methods refer to deprecated project plugins
    [docs] def package_workspace(self): if self.application is None: pass - workspace = self.application.get_service('envisage.project.IWorkspace') + workspace = self.application.get_service("envisage.project.IWorkspace") if workspace is not None: dir = workspace.path - self._attach_directory(dir) - return
    + self._attach_directory(dir)
    [docs] def package_single_project(self): if self.application is None: pass - single_project = self.application.get_service('envisage.single_project.ModelService') + single_project = self.application.get_service( + "envisage.single_project.ModelService" + ) if single_project is not None: dir = single_project.location self._attach_directory(dir)
    [docs] def package_any_relevant_files(self): self.package_workspace() - self.package_single_project() - return
    + self.package_single_project()
    def _attach_directory(self, dir): relpath = os.path.basename(dir) @@ -137,27 +147,27 @@

    Source code for apptools.logger.agent.attachments

    import zipfile from io import BytesIO - ctype = 'application/octet-stream' - maintype, subtype = ctype.split('/', 1) + ctype = "application/octet-stream" + maintype, subtype = ctype.split("/", 1) msg = MIMEBase(maintype, subtype) file_object = BytesIO() - zip = zipfile.ZipFile(file_object, 'w') + zip = zipfile.ZipFile(file_object, "w") _append_to_zip_archive(zip, dir, relpath) zip.close() msg.set_payload(file_object.getvalue()) - encoders.encode_base64(msg) # Encode the payload using Base64 - msg.add_header('Content-Disposition', 'attachment', filename='project.zip') + encoders.encode_base64(msg) # Encode the payload using Base64 + msg.add_header( + "Content-Disposition", "attachment", filename="project.zip" + ) self.message.attach(msg) file_object.close()
    - - def _append_to_zip_archive(zip, dir, relpath): """ Add all files in and below directory dir into zip archive""" for filename in os.listdir(dir): @@ -166,13 +176,13 @@

    Source code for apptools.logger.agent.attachments

    if os.path.isfile(path): name = os.path.join(relpath, filename) zip.write(path, name) - logger.debug('adding %s to error report' % path) + logger.debug("adding %s to error report" % path) else: - if filename != ".svn": # skip svn files if any + if filename != ".svn": # skip svn files if any subdir = os.path.join(dir, filename) - _append_to_zip_archive(zip, subdir, os.path.join(relpath, filename)) - return - + _append_to_zip_archive( + zip, subdir, os.path.join(relpath, filename) + )
    @@ -184,13 +194,11 @@

    Source code for apptools.logger.agent.attachments

    @@ -214,10 +222,10 @@

    Quick search

    © Copyright 2008-2020, Enthought
  • - Last updated on Jun 12, 2020. + Last updated on Dec 17, 2020.
  • - Created using Sphinx 1.8.5. + Created using Sphinx 2.3.1.
  • diff --git a/_modules/apptools/logger/agent/quality_agent_mailer.html b/_modules/apptools/logger/agent/quality_agent_mailer.html index adafb08ef..d6d7b3c5c 100644 --- a/_modules/apptools/logger/agent/quality_agent_mailer.html +++ b/_modules/apptools/logger/agent/quality_agent_mailer.html @@ -13,9 +13,11 @@ @@ -72,22 +74,18 @@
    -
    +

    Source code for apptools.logger.agent.quality_agent_mailer

    -#------------------------------------------------------------------------------
    -# Copyright (c) 2005, Enthought, Inc.
    +# (C) Copyright 2005-2020 Enthought, Inc., Austin, TX
     # All rights reserved.
     #
     # This software is provided without warranty under the terms of the BSD
    -# license included in enthought/LICENSE.txt and may be redistributed only
    -# under the conditions described in the aforementioned license.  The license
    +# license included in LICENSE.txt and may be redistributed only under
    +# the conditions described in the aforementioned license. The license
     # is also available online at http://www.enthought.com/licenses/BSD.txt
    -# Thanks for using Enthought open source!
     #
    -# Author: Enthought, Inc.
    -# Description: <Enthought logger package component>
    -#------------------------------------------------------------------------------
    +# Thanks for using Enthought open source!
     
     # Standard library imports.
     import logging
    @@ -101,8 +99,16 @@ 

    Source code for apptools.logger.agent.quality_agent_mailer

    logger = logging.getLogger(__name__) -
    [docs]def create_email_message(fromaddr, toaddrs, ccaddrs, subject, priority, - include_project=False, stack_trace="", comments=""): +
    [docs]def create_email_message( + fromaddr, + toaddrs, + ccaddrs, + subject, + priority, + include_project=False, + stack_trace="", + comments="", +): # format a message suitable to be sent to the Roundup bug tracker from email.MIMEMultipart import MIMEMultipart @@ -110,12 +116,12 @@

    Source code for apptools.logger.agent.quality_agent_mailer

    from email.MIMEBase import MIMEBase message = MIMEMultipart() - message['Subject'] = "%s [priority=%s]" % (subject, priority) - message['To'] = ', '.join(toaddrs) - message['Cc'] = ', '.join(ccaddrs) - message['From'] = fromaddr - message.preamble = 'You will not see this in a MIME-aware mail reader.\n' - message.epilogue = ' ' # To guarantee the message ends with a newline + message["Subject"] = "%s [priority=%s]" % (subject, priority) + message["To"] = ", ".join(toaddrs) + message["Cc"] = ", ".join(ccaddrs) + message["From"] = fromaddr + message.preamble = "You will not see this in a MIME-aware mail reader.\n" + message.epilogue = " " # To guarantee the message ends with a newline # First section is simple ASCII data ... m = [] @@ -135,26 +141,28 @@

    Source code for apptools.logger.agent.quality_agent_mailer

    m.append(stack_trace) m.append("") - msg = MIMEText('\n'.join(m)) + msg = MIMEText("\n".join(m)) message.attach(msg) # Include the log file ... if True: try: - log = os.path.join(get_home_directory(), 'envisage.log') - f = open(log, 'r') + log = os.path.join(get_home_directory(), "envisage.log") + f = open(log, "r") entries = f.readlines() f.close() - ctype = 'application/octet-stream' - maintype, subtype = ctype.split('/', 1) + ctype = "application/octet-stream" + maintype, subtype = ctype.split("/", 1) msg = MIMEBase(maintype, subtype) - msg = MIMEText(''.join(entries)) - msg.add_header('Content-Disposition', 'attachment', filename='logfile.txt') + msg = MIMEText("".join(entries)) + msg.add_header( + "Content-Disposition", "attachment", filename="logfile.txt" + ) message.attach(msg) - except: - logger.exception('Failed to include log file with message') + except Exception: + logger.exception("Failed to include log file with message") # Include the environment variables ... if True: @@ -166,34 +174,24 @@

    Source code for apptools.logger.agent.quality_agent_mailer

    try: entries = [] for key, value in os.environ.items(): - entries.append('%30s : %s\n' % (key, value)) + entries.append("%30s : %s\n" % (key, value)) - ctype = 'application/octet-stream' - maintype, subtype = ctype.split('/', 1) + ctype = "application/octet-stream" + maintype, subtype = ctype.split("/", 1) msg = MIMEBase(maintype, subtype) - msg = MIMEText(''.join(entries)) - msg.add_header('Content-Disposition', 'attachment', filename='environment.txt') + msg = MIMEText("".join(entries)) + msg.add_header( + "Content-Disposition", "attachment", filename="environment.txt" + ) message.attach(msg) - except: - logger.exception('Failed to include environment variables with message') - - -# FIXME: no project plugins exist for Envisage 3, yet, and this isn't the right -# way to do it, either. See the docstring of attachments.py. -# # Attach the project if requested ... -# if include_project: -# from attachments import Attachments -# try: -# attachments = Attachments(message) -# attachments.package_any_relevant_files() -# except: -# logger.exception('Failed to include workspace files with message') + except Exception: + logger.exception( + "Failed to include environment variables with message" + ) return message
    - -
    @@ -205,13 +203,11 @@

    Source code for apptools.logger.agent.quality_agent_mailer

    @@ -235,10 +231,10 @@

    Quick search

    © Copyright 2008-2020, Enthought
  • - Last updated on Jun 12, 2020. + Last updated on Dec 17, 2020.
  • - Created using Sphinx 1.8.5. + Created using Sphinx 2.3.1.
  • diff --git a/_modules/apptools/logger/agent/quality_agent_view.html b/_modules/apptools/logger/agent/quality_agent_view.html index b8af52a60..8a09b4bfa 100644 --- a/_modules/apptools/logger/agent/quality_agent_view.html +++ b/_modules/apptools/logger/agent/quality_agent_view.html @@ -13,9 +13,11 @@ @@ -72,22 +74,18 @@
    -
    +

    Source code for apptools.logger.agent.quality_agent_view

    -#------------------------------------------------------------------------------
    -# Copyright (c) 2005, Enthought, Inc.
    +# (C) Copyright 2005-2020 Enthought, Inc., Austin, TX
     # All rights reserved.
     #
     # This software is provided without warranty under the terms of the BSD
    -# license included in enthought/LICENSE.txt and may be redistributed only
    -# under the conditions described in the aforementioned license.  The license
    +# license included in LICENSE.txt and may be redistributed only under
    +# the conditions described in the aforementioned license. The license
     # is also available online at http://www.enthought.com/licenses/BSD.txt
    -# Thanks for using Enthought open source!
     #
    -# Author: Enthought, Inc.
    -# Description: <Enthought logger package component>
    -#------------------------------------------------------------------------------
    +# Thanks for using Enthought open source!
     
     # Standard library imports.
     import logging
    @@ -101,25 +99,25 @@ 

    Source code for apptools.logger.agent.quality_agent_view

    logger = logging.getLogger(__name__) -priority_levels = ['Low', 'Medium', 'High', 'Critical'] +priority_levels = ["Low", "Medium", "High", "Critical"]
    [docs]class QualityAgentView(Dialog): size = Tuple((700, 900)) - title = Str('Quality Agent') + title = Str("Quality Agent") # The associated LoggerService. service = Any() - msg = Str('') - subject = Str('Untitled Error Report') + msg = Str("") + subject = Str("Untitled Error Report") to_address = Str() - cc_address = Str('') + cc_address = Str("") from_address = Str() smtp_server = Str() priority = Str(priority_levels[2]) - comments = Str('None') + comments = Str("None") include_userdata = Any ########################################################################### @@ -128,7 +126,7 @@

    Source code for apptools.logger.agent.quality_agent_view

    # fixme: Ideally, this should be passed in; this topic ID belongs to the # Enlib help project/plug-in. - help_id = 'enlib|HID_Quality_Agent_Dlg' + help_id = "enlib|HID_Quality_Agent_Dlg" def _create_dialog_area(self, parent): """ Creates the main content of the dialog. """ @@ -142,28 +140,30 @@

    Source code for apptools.logger.agent.quality_agent_view

    panel.SetSizer(sizer) panel.SetAutoLayout(True) - # Add a descriptive label at the top ... label = wx.StaticText(panel, -1, "Send a comment or bug report ...") sizer.Add(label, 0, wx.ALL, border=5) # Add the stack trace view ... error_panel = self._create_error_panel(panel) - sizer.Add(error_panel, 1, wx.ALL|wx.EXPAND|wx.CLIP_CHILDREN, border=5) + sizer.Add( + error_panel, 1, wx.ALL | wx.EXPAND | wx.CLIP_CHILDREN, border=5 + ) # Update the layout: sizer.Fit(panel) # Add the error report view ... report_panel = self._create_report_panel(panel) - sizer.Add(report_panel, 2, wx.ALL|wx.EXPAND|wx.CLIP_CHILDREN, border=5) + sizer.Add( + report_panel, 2, wx.ALL | wx.EXPAND | wx.CLIP_CHILDREN, border=5 + ) # Update the layout: sizer.Fit(panel) return panel - def _create_buttons(self, parent): """ Creates the buttons. """ import wx @@ -189,15 +189,6 @@

    Source code for apptools.logger.agent.quality_agent_view

    return sizer - def _on_help(self, event): - """Called when the 'Help' button is pressed. """ - - hp = self.service.application.get_service('apptools.help.IHelp') - hp.library.show_topic(self.help_id) - - return - - ### Utility methods ####################################################### def _create_error_panel(self, parent): @@ -207,26 +198,38 @@

    Source code for apptools.logger.agent.quality_agent_view

    sizer = wx.StaticBoxSizer(box, wx.VERTICAL) # Print the stack trace - label2 = wx.StaticText(parent, -1,"The following information will be included in the report:") - sizer.Add(label2, 0, wx.LEFT|wx.TOP|wx.BOTTOM|wx.CLIP_CHILDREN, border=5) - - details = wx.TextCtrl(parent, -1, self.msg, size=(-1,75), - style=wx.TE_MULTILINE | - wx.TE_READONLY | - wx.HSCROLL | - wx.VSCROLL | - wx.TE_RICH2 | - wx.CLIP_CHILDREN) + label2 = wx.StaticText( + parent, + -1, + "The following information will be included in the report:", + ) + sizer.Add( + label2, + 0, + wx.LEFT | wx.TOP | wx.BOTTOM | wx.CLIP_CHILDREN, + border=5, + ) + + details = wx.TextCtrl( + parent, + -1, + self.msg, + size=(-1, 75), + style=wx.TE_MULTILINE + | wx.TE_READONLY + | wx.HSCROLL + | wx.VSCROLL + | wx.TE_RICH2 + | wx.CLIP_CHILDREN, + ) details.SetSizeHints(minW=-1, minH=75) # Set the font to not be proportional font = wx.Font(12, wx.MODERN, wx.NORMAL, wx.NORMAL) details.SetStyle(0, len(self.msg), wx.TextAttr(font=font)) - sizer.Add(details, 1, wx.EXPAND|wx.ALL|wx.CLIP_CHILDREN, 5) - + sizer.Add(details, 1, wx.EXPAND | wx.ALL | wx.CLIP_CHILDREN, 5) return sizer - def _create_report_panel(self, parent): import wx @@ -234,23 +237,28 @@

    Source code for apptools.logger.agent.quality_agent_view

    sizer = wx.StaticBoxSizer(box, wx.VERTICAL) # Add email info ... - sizer.Add(self._create_email_info(parent), 0, wx.ALL|wx.EXPAND, 5) + sizer.Add(self._create_email_info(parent), 0, wx.ALL | wx.EXPAND, 5) # Add priority combo: - sizer.Add(self._create_priority_combo(parent), 0, wx.ALL|wx.RIGHT, 5) + sizer.Add(self._create_priority_combo(parent), 0, wx.ALL | wx.RIGHT, 5) # Extra comments from the user: label3 = wx.StaticText(parent, -1, "Additional Comments:") - sizer.Add(label3, 0, wx.LEFT|wx.TOP|wx.BOTTOM|wx.CLIP_CHILDREN, 5) + sizer.Add( + label3, 0, wx.LEFT | wx.TOP | wx.BOTTOM | wx.CLIP_CHILDREN, 5 + ) - comments_field = wx.TextCtrl(parent, -1, self.comments, size=(-1,75), - style=wx.TE_MULTILINE | - wx.TE_RICH2 | - wx.CLIP_CHILDREN) + comments_field = wx.TextCtrl( + parent, + -1, + self.comments, + size=(-1, 75), + style=wx.TE_MULTILINE | wx.TE_RICH2 | wx.CLIP_CHILDREN, + ) comments_field.SetSizeHints(minW=-1, minH=75) font = wx.Font(12, wx.MODERN, wx.NORMAL, wx.NORMAL) comments_field.SetStyle(0, len(self.comments), wx.TextAttr(font=font)) - sizer.Add(comments_field, 1, wx.ALL|wx.EXPAND|wx.CLIP_CHILDREN, 5) + sizer.Add(comments_field, 1, wx.ALL | wx.EXPAND | wx.CLIP_CHILDREN, 5) wx.EVT_TEXT(parent, comments_field.GetId(), self._on_comments) # Include the project combobox? @@ -259,47 +267,61 @@

    Source code for apptools.logger.agent.quality_agent_view

    return sizer - def _create_email_info(self, parent): import wx # Layout setup .. - sizer = wx.FlexGridSizer(5,2,10,10) + sizer = wx.FlexGridSizer(5, 2, 10, 10) sizer.AddGrowableCol(1) title_label = wx.StaticText(parent, -1, "Subject:") - sizer.Add(title_label , 0, wx.ALL|wx.ALIGN_RIGHT) - title_field = wx.TextCtrl(parent, -1, self.subject, wx.Point(-1,-1)) - sizer.Add(title_field, 1, wx.EXPAND|wx.ALL|wx.ALIGN_RIGHT|wx.CLIP_CHILDREN) + sizer.Add(title_label, 0, wx.ALL | wx.ALIGN_RIGHT) + title_field = wx.TextCtrl(parent, -1, self.subject, wx.Point(-1, -1)) + sizer.Add( + title_field, + 1, + wx.EXPAND | wx.ALL | wx.ALIGN_RIGHT | wx.CLIP_CHILDREN, + ) wx.EVT_TEXT(parent, title_field.GetId(), self._on_subject) to_label = wx.StaticText(parent, -1, "To:") - sizer.Add(to_label , 0, wx.ALL|wx.ALIGN_RIGHT) + sizer.Add(to_label, 0, wx.ALL | wx.ALIGN_RIGHT) to_field = wx.TextCtrl(parent, -1, self.to_address) - sizer.Add(to_field, 1, wx.EXPAND|wx.ALL|wx.ALIGN_RIGHT|wx.CLIP_CHILDREN) + sizer.Add( + to_field, 1, wx.EXPAND | wx.ALL | wx.ALIGN_RIGHT | wx.CLIP_CHILDREN + ) wx.EVT_TEXT(parent, to_field.GetId(), self._on_to) cc_label = wx.StaticText(parent, -1, "Cc:") - sizer.Add(cc_label, 0, wx.ALL|wx.ALIGN_RIGHT) + sizer.Add(cc_label, 0, wx.ALL | wx.ALIGN_RIGHT) cc_field = wx.TextCtrl(parent, -1, "") - sizer.Add(cc_field, 1, wx.EXPAND|wx.ALL|wx.ALIGN_RIGHT|wx.CLIP_CHILDREN) + sizer.Add( + cc_field, 1, wx.EXPAND | wx.ALL | wx.ALIGN_RIGHT | wx.CLIP_CHILDREN + ) wx.EVT_TEXT(parent, cc_field.GetId(), self._on_cc) from_label = wx.StaticText(parent, -1, "From:") - sizer.Add(from_label, 0, wx.ALL|wx.ALIGN_RIGHT) + sizer.Add(from_label, 0, wx.ALL | wx.ALIGN_RIGHT) from_field = wx.TextCtrl(parent, -1, self.from_address) - sizer.Add(from_field, 1, wx.EXPAND|wx.ALL|wx.ALIGN_RIGHT|wx.CLIP_CHILDREN) + sizer.Add( + from_field, + 1, + wx.EXPAND | wx.ALL | wx.ALIGN_RIGHT | wx.CLIP_CHILDREN, + ) wx.EVT_TEXT(parent, from_field.GetId(), self._on_from) smtp_label = wx.StaticText(parent, -1, "SMTP Server:") - sizer.Add(smtp_label, 0, wx.ALL|wx.ALIGN_RIGHT) + sizer.Add(smtp_label, 0, wx.ALL | wx.ALIGN_RIGHT) smtp_server_field = wx.TextCtrl(parent, -1, self.smtp_server) - sizer.Add(smtp_server_field, 1, wx.EXPAND|wx.ALL|wx.ALIGN_RIGHT|wx.CLIP_CHILDREN) + sizer.Add( + smtp_server_field, + 1, + wx.EXPAND | wx.ALL | wx.ALIGN_RIGHT | wx.CLIP_CHILDREN, + ) wx.EVT_TEXT(parent, smtp_server_field.GetId(), self._on_smtp_server) return sizer - def _create_priority_combo(self, parent): import wx @@ -308,69 +330,74 @@

    Source code for apptools.logger.agent.quality_agent_view

    label = wx.StaticText(parent, -1, "How critical is this issue?") sizer.Add(label, 0, wx.ALL, border=0) - cb = wx.ComboBox(parent, -1, self.priority, - wx.Point(90, 50), wx.Size(95, -1), - priority_levels, wx.CB_READONLY) - sizer.Add(cb, 1, wx.EXPAND|wx.LEFT|wx.CLIP_CHILDREN, border=10) + cb = wx.ComboBox( + parent, + -1, + self.priority, + wx.Point(90, 50), + wx.Size(95, -1), + priority_levels, + wx.CB_READONLY, + ) + sizer.Add(cb, 1, wx.EXPAND | wx.LEFT | wx.CLIP_CHILDREN, border=10) wx.EVT_COMBOBOX(parent, cb.GetId(), self._on_priority) return sizer - def _create_project_upload(self, parent): import wx id = wx.NewId() - cb = wx.CheckBox(parent, id, "Include Workspace Files (will increase email size) ", - wx.Point(65, 80), wx.Size(-1, 20), wx.NO_BORDER) + cb = wx.CheckBox( + parent, + id, + "Include Workspace Files (will increase email size) ", + wx.Point(65, 80), + wx.Size(-1, 20), + wx.NO_BORDER, + ) wx.EVT_CHECKBOX(parent, id, self._on_project) return cb - ## UI Listeners ########################################################### def _on_subject(self, event): self.subject = event.GetEventObject().GetValue() - def _on_to(self, event): self.to_address = event.GetEventObject().GetValue() - def _on_cc(self, event): self.cc_address = event.GetEventObject().GetValue() - def _on_from(self, event): self.from_address = event.GetEventObject().GetValue() - def _on_smtp_server(self, event): self.smtp_server = event.GetEventObject().GetValue() - def _on_priority(self, event): self.priority = event.GetEventObject().GetStringSelection() - def _on_comments(self, event): self.comments = event.GetEventObject().GetValue() - def _on_project(self, event): self.include_userdata = event.Checked() cb = event.GetEventObject() if event.Checked(): - cb.SetLabel("Include Workspace Files (approx. %.2f MBytes)" % self._compute_project_size()) + cb.SetLabel( + "Include Workspace Files (approx. %.2f MBytes)" + % self._compute_project_size() + ) else: cb.SetLabel("Include Workspace Files (will increase email size)") - return def _on_send(self, event): - import wx + # Disable the Send button while we go through the possibly # time-consuming email-sending process. button = event.GetEventObject() @@ -379,8 +406,9 @@

    Source code for apptools.logger.agent.quality_agent_view

    fromaddr, toaddrs, ccaddrs = self._create_email_addresses() message = self._create_email(fromaddr, toaddrs, ccaddrs) - self.service.send_bug_report(self.smtp_server, fromaddr, toaddrs, - ccaddrs, message) + self.service.send_bug_report( + self.smtp_server, fromaddr, toaddrs, ccaddrs, message + ) # save the user's preferences self.service.preferences.smtp_server = self.smtp_server @@ -390,8 +418,6 @@

    Source code for apptools.logger.agent.quality_agent_view

    # finally we close the dialog self._wx_on_ok(event) - return - ## Private ################################################################ def _create_email_addresses(self): @@ -406,17 +432,17 @@

    Source code for apptools.logger.agent.quality_agent_view

    return fromaddr, toaddrs, ccaddrs - def _compute_project_size(self): # determine size of email in MBytes fromaddr, toaddrs, ccaddrs = self._create_email_addresses() message = self._create_email(fromaddr, toaddrs, ccaddrs) - return len(message.as_string()) / (2.0**20) - + return len(message.as_string()) / (2.0 ** 20) def _create_email(self, fromaddr, toaddrs, ccaddrs): return self.service.create_email_message( - fromaddr, toaddrs, ccaddrs, + fromaddr, + toaddrs, + ccaddrs, self.subject, self.priority, self.include_userdata, @@ -432,8 +458,6 @@

    Source code for apptools.logger.agent.quality_agent_view

    def _smtp_server_default(self): return self.service.preferences.smtp_server
    - -####### EOF #############################################################
    @@ -445,13 +469,11 @@

    Source code for apptools.logger.agent.quality_agent_view

    @@ -475,10 +497,10 @@

    Quick search

    © Copyright 2008-2020, Enthought
  • - Last updated on Jun 12, 2020. + Last updated on Dec 17, 2020.
  • - Created using Sphinx 1.8.5. + Created using Sphinx 2.3.1.
  • diff --git a/_modules/apptools/logger/custom_excepthook.html b/_modules/apptools/logger/custom_excepthook.html index 79ab1051b..371e3aa28 100644 --- a/_modules/apptools/logger/custom_excepthook.html +++ b/_modules/apptools/logger/custom_excepthook.html @@ -13,9 +13,11 @@ @@ -72,22 +74,18 @@
    -
    +

    Source code for apptools.logger.custom_excepthook

    -#------------------------------------------------------------------------------
    -# Copyright (c) 2005, Enthought, Inc.
    +# (C) Copyright 2005-2020 Enthought, Inc., Austin, TX
     # All rights reserved.
     #
     # This software is provided without warranty under the terms of the BSD
    -# license included in enthought/LICENSE.txt and may be redistributed only
    -# under the conditions described in the aforementioned license.  The license
    +# license included in LICENSE.txt and may be redistributed only under
    +# the conditions described in the aforementioned license. The license
     # is also available online at http://www.enthought.com/licenses/BSD.txt
    -# Thanks for using Enthought open source!
     #
    -# Author: Enthought, Inc.
    -# Description: <Enthought logger package component>
    -#------------------------------------------------------------------------------
    +# Thanks for using Enthought open source!
     
     
     # Standard library imports.
    @@ -95,30 +93,26 @@ 

    Source code for apptools.logger.custom_excepthook

    from traceback import format_exception - """ To catch exceptions with our own code this code needs to be added sys.excepthook = custom_excepthook """ +
    [docs]def custom_excepthook(type, value, traceback): """ Pass on the exception to the logging system. """ - msg = 'Custom - Traceback (most recent call last):\n' + msg = "Custom - Traceback (most recent call last):\n" list = format_exception(type, value, traceback) msg = "".join(list) # Try to find the module that the exception actually came from. - name = getattr(traceback.tb_frame, 'f_globals', {}).get('__name__', - __name__) + name = getattr(traceback.tb_frame, "f_globals", {}).get( + "__name__", __name__ + ) logger = logging.getLogger(name) - logger.error(msg) - - return
    - - -## EOF ################################################################## + logger.error(msg)
    @@ -130,13 +124,11 @@

    Source code for apptools.logger.custom_excepthook

    @@ -160,10 +152,10 @@

    Quick search

    © Copyright 2008-2020, Enthought
  • - Last updated on Jun 12, 2020. + Last updated on Dec 17, 2020.
  • - Created using Sphinx 1.8.5. + Created using Sphinx 2.3.1.
  • diff --git a/_modules/apptools/logger/log_point.html b/_modules/apptools/logger/log_point.html index df3e03d36..b1b3cd71c 100644 --- a/_modules/apptools/logger/log_point.html +++ b/_modules/apptools/logger/log_point.html @@ -13,9 +13,11 @@ @@ -72,22 +74,18 @@
    -
    +

    Source code for apptools.logger.log_point

    -#------------------------------------------------------------------------------
    -# Copyright (c) 2005, Enthought, Inc.
    +# (C) Copyright 2005-2020 Enthought, Inc., Austin, TX
     # All rights reserved.
     #
     # This software is provided without warranty under the terms of the BSD
    -# license included in enthought/LICENSE.txt and may be redistributed only
    -# under the conditions described in the aforementioned license.  The license
    +# license included in LICENSE.txt and may be redistributed only under
    +# the conditions described in the aforementioned license. The license
     # is also available online at http://www.enthought.com/licenses/BSD.txt
    -# Thanks for using Enthought open source!
     #
    -# Author: Enthought, Inc.
    -# Description: <Enthought logger package component>
    -#------------------------------------------------------------------------------
    +# Thanks for using Enthought open source!
     """ Prints a stack trace every time it is called but does not halt execution
         of the application.
     
    @@ -96,34 +94,30 @@ 

    Source code for apptools.logger.log_point

     
     # Standard library imports.
     import inspect
    +from io import StringIO
     
    -# Third-party library imports.
    -from six import StringIO
     
    -
    -
    [docs]def log_point(msg='\n'): +
    [docs]def log_point(msg="\n"): stack = inspect.stack() # get rid of logPoint's part of the stack: stack = stack[1:] stack.reverse() output = StringIO() if msg: - output.write(str(msg) + '\n') + output.write(str(msg) + "\n") for stackLine in stack: frame, filename, line, funcname, lines, unknown = stackLine - if filename.endswith('/unittest.py'): + if filename.endswith("/unittest.py"): # unittest.py code is a boring part of the traceback continue - if filename.startswith('./'): + if filename.startswith("./"): filename = filename[2:] - output.write('%s:%s in %s:\n' % (filename, line, funcname)) + output.write("%s:%s in %s:\n" % (filename, line, funcname)) if lines: - output.write(' %s\n' % ''.join(lines)[:-1]) + output.write(" %s\n" % "".join(lines)[:-1]) s = output.getvalue() return s
    - -## EOF ##################################################################
    @@ -135,13 +129,11 @@

    Source code for apptools.logger.log_point

                   
                 

    @@ -165,10 +157,10 @@

    Quick search

    © Copyright 2008-2020, Enthought
  • - Last updated on Jun 12, 2020. + Last updated on Dec 17, 2020.
  • - Created using Sphinx 1.8.5. + Created using Sphinx 2.3.1.
  • diff --git a/_modules/apptools/logger/log_queue_handler.html b/_modules/apptools/logger/log_queue_handler.html index c80ea916d..30cce403c 100644 --- a/_modules/apptools/logger/log_queue_handler.html +++ b/_modules/apptools/logger/log_queue_handler.html @@ -13,9 +13,11 @@ @@ -72,22 +74,18 @@
    -
    +

    Source code for apptools.logger.log_queue_handler

    -#------------------------------------------------------------------------------
    -# Copyright (c) 2005, Enthought, Inc.
    +# (C) Copyright 2005-2020 Enthought, Inc., Austin, TX
     # All rights reserved.
     #
     # This software is provided without warranty under the terms of the BSD
    -# license included in enthought/LICENSE.txt and may be redistributed only
    -# under the conditions described in the aforementioned license.  The license
    +# license included in LICENSE.txt and may be redistributed only under
    +# the conditions described in the aforementioned license. The license
     # is also available online at http://www.enthought.com/licenses/BSD.txt
    -# Thanks for using Enthought open source!
     #
    -# Author: Enthought, Inc.
    -# Description: <Enthought logger package component>
    -#------------------------------------------------------------------------------
    +# Thanks for using Enthought open source!
     
     # Standard library imports.
     from logging import Handler
    @@ -98,24 +96,21 @@ 

    Source code for apptools.logger.log_queue_handler

    [docs]class LogQueueHandler(Handler): - """ Buffers up the log messages so that we can display them later. - This is important on startup when log messages are generated before - the ui has started. By putting them in this queue we can display - them once the ui is ready. + """Buffers up the log messages so that we can display them later. + This is important on startup when log messages are generated before + the ui has started. By putting them in this queue we can display + them once the ui is ready. """ # The view where updates will go _view = None - def __init__(self, size=1000): Handler.__init__(self) # only buffer 1000 log records self.size = size self.ring = RingBuffer(self.size) self.dirty = False - return -
    [docs] def emit(self, record): """ Actually this is more like an enqueue than an emit().""" @@ -123,42 +118,34 @@

    Source code for apptools.logger.log_queue_handler

    if self._view is not None: try: self._view.update() - except Exception as e: + except Exception: pass - self.dirty = True - return
    - + self.dirty = True
    [docs] def get(self): self.dirty = False try: result = self.ring.get() - except Exception as msg: + except Exception: # we did our best and it won't cause too much damage # to just return a bogus message result = [] return result
    -
    [docs] def has_new_records(self): return self.dirty
    -
    [docs] def reset(self): # start over with a new empty buffer self.ring = RingBuffer(self.size) if self._view is not None: try: self._view.update() - except Exception as e: + except Exception: pass - self.dirty = True - return
    - - -## EOF ################################################################## + self.dirty = True
    @@ -170,13 +157,11 @@

    Source code for apptools.logger.log_queue_handler

    @@ -200,10 +185,10 @@

    Quick search

    © Copyright 2008-2020, Enthought
  • - Last updated on Jun 12, 2020. + Last updated on Dec 17, 2020.
  • - Created using Sphinx 1.8.5. + Created using Sphinx 2.3.1.
  • diff --git a/_modules/apptools/logger/logger.html b/_modules/apptools/logger/logger.html index a3e602b76..7c65ef5cc 100644 --- a/_modules/apptools/logger/logger.html +++ b/_modules/apptools/logger/logger.html @@ -13,9 +13,11 @@ @@ -72,22 +74,18 @@
    -
    +

    Source code for apptools.logger.logger

    -#------------------------------------------------------------------------------
    -# Copyright (c) 2005, Enthought, Inc.
    +# (C) Copyright 2005-2020 Enthought, Inc., Austin, TX
     # All rights reserved.
     #
     # This software is provided without warranty under the terms of the BSD
    -# license included in enthought/LICENSE.txt and may be redistributed only
    -# under the conditions described in the aforementioned license.  The license
    +# license included in LICENSE.txt and may be redistributed only under
    +# the conditions described in the aforementioned license. The license
     # is also available online at http://www.enthought.com/licenses/BSD.txt
    -# Thanks for using Enthought open source!
     #
    -# Author: Enthought, Inc.
    -# Description: <Enthought logger package component>
    -#------------------------------------------------------------------------------
    +# Thanks for using Enthought open source!
     """ Convenience functions for creating logging handlers etc. """
     
     
    @@ -95,9 +93,6 @@ 

    Source code for apptools.logger.logger

     import logging
     from logging.handlers import RotatingFileHandler
     
    -# Enthought library imports.
    -from traits.util.api import deprecated
    -
     # Local imports.
     from .log_queue_handler import LogQueueHandler
     
    @@ -106,15 +101,15 @@ 

    Source code for apptools.logger.logger

     LEVEL = logging.DEBUG
     
     # The default formatter.
    -FORMATTER = logging.Formatter('%(levelname)s|%(asctime)s|%(message)s')
    +FORMATTER = logging.Formatter("%(levelname)s|%(asctime)s|%(message)s")
     
     
     
    [docs]class LogFileHandler(RotatingFileHandler): - """ The default log file handler. - """ + """The default log file handler.""" - def __init__(self, path, maxBytes=1000000, backupCount=3, level=None, - formatter=None): + def __init__( + self, path, maxBytes=1000000, backupCount=3, level=None, formatter=None + ): RotatingFileHandler.__init__( self, path, maxBytes=maxBytes, backupCount=3 ) @@ -127,36 +122,9 @@

    Source code for apptools.logger.logger

             self.setFormatter(formatter)
             self.setLevel(level)
    -
    [docs]@deprecated('use "LogFileHandler"') -def create_log_file_handler(path, maxBytes=1000000, backupCount=3, level=None, - formatter=None): - """ Creates a log file handler. - - This is just a convenience function to make it easy to create the same - kind of handlers across applications. - - It sets the handler's formatter to the default formatter, and its logging - level to the default logging level. - - """ - if level is None: - level = LEVEL - if formatter is None: - formatter = FORMATTER - - handler = RotatingFileHandler( - path, maxBytes=maxBytes, backupCount=backupCount - ) - - handler.setFormatter(formatter) - handler.setLevel(level) - - return handler
    -
    [docs]def add_log_queue_handler(logger, level=None, formatter=None): - """ Adds a queueing log handler to a logger. - """ + """Adds a queueing log handler to a logger.""" if level is None: level = LEVEL if formatter is None: @@ -168,9 +136,6 @@

    Source code for apptools.logger.logger

         log_queue_handler.setFormatter(formatter)
         logger.addHandler(log_queue_handler)
         return log_queue_handler
    - - -#### EOF ######################################################################
    @@ -182,13 +147,11 @@

    Source code for apptools.logger.logger

                   
                 

    @@ -212,10 +175,10 @@

    Quick search

    © Copyright 2008-2020, Enthought
  • - Last updated on Jun 12, 2020. + Last updated on Dec 17, 2020.
  • - Created using Sphinx 1.8.5. + Created using Sphinx 2.3.1.
  • diff --git a/_modules/apptools/logger/plugin/logger_plugin.html b/_modules/apptools/logger/plugin/logger_plugin.html index f8feb5c37..467379f49 100644 --- a/_modules/apptools/logger/plugin/logger_plugin.html +++ b/_modules/apptools/logger/plugin/logger_plugin.html @@ -13,9 +13,11 @@ @@ -72,22 +74,18 @@
    -
    +

    Source code for apptools.logger.plugin.logger_plugin

    -#------------------------------------------------------------------------------
    -# Copyright (c) 2005, Enthought, Inc.
    +# (C) Copyright 2005-2020 Enthought, Inc., Austin, TX
     # All rights reserved.
     #
     # This software is provided without warranty under the terms of the BSD
    -# license included in enthought/LICENSE.txt and may be redistributed only
    -# under the conditions described in the aforementioned license.  The license
    +# license included in LICENSE.txt and may be redistributed only under
    +# the conditions described in the aforementioned license. The license
     # is also available online at http://www.enthought.com/licenses/BSD.txt
    -# Thanks for using Enthought open source!
     #
    -# Author: Enthought, Inc.
    -# Description: <Enthought logger package component>
    -#------------------------------------------------------------------------------
    +# Thanks for using Enthought open source!
     """ Logger plugin.
     """
     
    @@ -104,22 +102,24 @@ 

    Source code for apptools.logger.plugin.logger_plugin

    from .logger_service import LoggerService -ID = 'apptools.logger' -ILOGGER = ID + '.plugin.logger_service.LoggerService' +ID = "apptools.logger" +ILOGGER = ID + ".plugin.logger_service.LoggerService" +
    [docs]class LoggerPlugin(Plugin): - """ Logger plugin. - """ + """Logger plugin.""" id = ID - name = 'Logger plugin' + name = "Logger plugin" - #### Extension points for this plugin ###################################### + #### Extension points for this plugin ##################################### - MAIL_FILES = 'apptools.logger.plugin.mail_files' + MAIL_FILES = "apptools.logger.plugin.mail_files" mail_files = ExtensionPoint( - List(Callable), id=MAIL_FILES, desc=""" + List(Callable), + id=MAIL_FILES, + desc=""" This extension point allows you to contribute functions which will be called to add project files to the zip file that the user mails back @@ -127,41 +127,41 @@

    Source code for apptools.logger.plugin.logger_plugin

    The function will be passed a zipfile.ZipFile object. - """ + """, ) - #### Contributions to extension points made by this plugin ################# + #### Contributions to extension points made by this plugin ################ - PREFERENCES = 'envisage.preferences' - PREFERENCES_PAGES = 'envisage.ui.workbench.preferences_pages' - VIEWS = 'envisage.ui.workbench.views' + PREFERENCES = "envisage.preferences" + PREFERENCES_PAGES = "envisage.ui.workbench.preferences_pages" + VIEWS = "envisage.ui.workbench.views" preferences = List(contributes_to=PREFERENCES) preferences_pages = List(contributes_to=PREFERENCES_PAGES) views = List(contributes_to=VIEWS) - def _preferences_default(self): - return ['pkgfile://%s/plugin/preferences.ini' % ID] + return ["pkgfile://%s/plugin/preferences.ini" % ID] def _preferences_pages_default(self): - from apptools.logger.plugin.view.logger_preferences_page import \ - LoggerPreferencesPage + from apptools.logger.plugin.view.logger_preferences_page import ( + LoggerPreferencesPage, + ) + return [LoggerPreferencesPage] def _views_default(self): return [self._logger_view_factory] - - #### Plugin interface ###################################################### + #### Plugin interface #####################################################
    [docs] def start(self): - """ Starts the plugin. - """ + """Starts the plugin.""" preferences = LoggerPreferences() - service = LoggerService(application=self.application, - preferences=preferences) - formatter = logging.Formatter('%(levelname)s|%(asctime)s|%(message)s') + service = LoggerService( + application=self.application, preferences=preferences + ) + formatter = logging.Formatter("%(levelname)s|%(asctime)s|%(message)s") handler = LogQueueHandler() handler.setLevel(preferences.level_) handler.setFormatter(formatter) @@ -172,24 +172,20 @@

    Source code for apptools.logger.plugin.logger_plugin

    self.application.register_service(ILOGGER, service)
    [docs] def stop(self): - """ Stops the plugin. - """ + """Stops the plugin.""" service = self.application.get_service(ILOGGER) service.save_preferences()
    - - #### LoggerPlugin private interface ######################################## + #### LoggerPlugin private interface ####################################### def _logger_view_factory(self, **traits): from apptools.logger.plugin.view.logger_view import LoggerView + service = self.application.get_service(ILOGGER) view = LoggerView(service=service, **traits) # Record the created view on the service. service.plugin_view = view return view
    - - -#### EOF ######################################################################
    @@ -201,13 +197,11 @@

    Source code for apptools.logger.plugin.logger_plugin

    @@ -231,10 +225,10 @@

    Quick search

    © Copyright 2008-2020, Enthought
  • - Last updated on Jun 12, 2020. + Last updated on Dec 17, 2020.
  • - Created using Sphinx 1.8.5. + Created using Sphinx 2.3.1.
  • diff --git a/_modules/apptools/logger/plugin/logger_preferences.html b/_modules/apptools/logger/plugin/logger_preferences.html index 899b6ea90..d3be2d62e 100644 --- a/_modules/apptools/logger/plugin/logger_preferences.html +++ b/_modules/apptools/logger/plugin/logger_preferences.html @@ -13,9 +13,11 @@ @@ -72,30 +74,40 @@
    -
    +

    Source code for apptools.logger.plugin.logger_preferences

    -import logging
    +# (C) Copyright 2005-2020 Enthought, Inc., Austin, TX
    +# All rights reserved.
    +#
    +# This software is provided without warranty under the terms of the BSD
    +# license included in LICENSE.txt and may be redistributed only under
    +# the conditions described in the aforementioned license. The license
    +# is also available online at http://www.enthought.com/licenses/BSD.txt
    +#
    +# Thanks for using Enthought open source!
    +import logging
     
     from apptools.preferences.api import PreferencesHelper
     from traits.api import Bool, Str, Trait
     
     
     
    [docs]class LoggerPreferences(PreferencesHelper): - """ The persistent service exposing the Logger plugin's API. - """ + """The persistent service exposing the Logger plugin's API.""" - #### Preferences ########################################################### + #### Preferences ########################################################## # The log levels - level = Trait('Info', - {'Debug' : logging.DEBUG, - 'Info' : logging.INFO, - 'Warning' : logging.WARNING, - 'Error' : logging.ERROR, - 'Critical' : logging.CRITICAL, + level = Trait( + "Info", + { + "Debug": logging.DEBUG, + "Info": logging.INFO, + "Warning": logging.WARNING, + "Error": logging.ERROR, + "Critical": logging.CRITICAL, }, - is_str = True, + is_str=True, ) enable_agent = Bool(False) @@ -104,7 +116,7 @@

    Source code for apptools.logger.plugin.logger_preferences

    from_address = Str() # The path to the preferences node that contains the preferences. - preferences_path = Str('apptools.logger')
    + preferences_path = Str("apptools.logger")
    @@ -116,13 +128,11 @@

    Source code for apptools.logger.plugin.logger_preferences

    @@ -146,10 +156,10 @@

    Quick search

    © Copyright 2008-2020, Enthought
  • - Last updated on Jun 12, 2020. + Last updated on Dec 17, 2020.
  • - Created using Sphinx 1.8.5. + Created using Sphinx 2.3.1.
  • diff --git a/_modules/apptools/logger/plugin/logger_service.html b/_modules/apptools/logger/plugin/logger_service.html index a3e4a36da..69028d2ce 100644 --- a/_modules/apptools/logger/plugin/logger_service.html +++ b/_modules/apptools/logger/plugin/logger_service.html @@ -13,9 +13,11 @@ @@ -72,29 +74,43 @@
    -
    +

    Source code for apptools.logger.plugin.logger_service

    -# Standard library imports
    +# (C) Copyright 2005-2020 Enthought, Inc., Austin, TX
    +# All rights reserved.
    +#
    +# This software is provided without warranty under the terms of the BSD
    +# license included in LICENSE.txt and may be redistributed only under
    +# the conditions described in the aforementioned license. The license
    +# is also available online at http://www.enthought.com/licenses/BSD.txt
    +#
    +# Thanks for using Enthought open source!
    +# Standard library imports
    +from io import BytesIO
     import logging
     import os
     import zipfile
     
    -# Third-party library imports
    -from io import BytesIO
    -
     # Enthought library imports
     from pyface.workbench.api import View as WorkbenchView
    -from traits.api import Any, Callable, HasTraits, Instance, List, \
    -    Property, Undefined, on_trait_change
    +from traits.api import (
    +    Any,
    +    Callable,
    +    HasTraits,
    +    Instance,
    +    List,
    +    Property,
    +    Undefined,
    +    on_trait_change,
    +)
     
     root_logger = logging.getLogger()
     logger = logging.getLogger(__name__)
     
     
     
    [docs]class LoggerService(HasTraits): - """ The persistent service exposing the Logger plugin's API. - """ + """The persistent service exposing the Logger plugin's API.""" # The Envisage application. application = Any() @@ -112,36 +128,43 @@

    Source code for apptools.logger.plugin.logger_service

    mail_files = Property(List(Callable))
    [docs] def save_preferences(self): - """ Save the preferences. - """ + """Save the preferences.""" self.preferences.preferences.save()
    [docs] def whole_log_text(self): - """ Return all of the logged data as formatted text. - """ - lines = [ self.handler.format(rec) for rec in self.handler.get() ] + """Return all of the logged data as formatted text.""" + lines = [self.handler.format(rec) for rec in self.handler.get()] # Ensure that we end with a newline. - lines.append('') - text = '\n'.join(lines) + lines.append("") + text = "\n".join(lines) return text
    -
    [docs] def create_email_message(self, fromaddr, toaddrs, ccaddrs, subject, - priority, include_userdata=False, stack_trace="", - comments="", include_environment=True): - """ Format a bug report email from the log files. - """ +
    [docs] def create_email_message( + self, + fromaddr, + toaddrs, + ccaddrs, + subject, + priority, + include_userdata=False, + stack_trace="", + comments="", + include_environment=True, + ): + """Format a bug report email from the log files.""" from email.mime.application import MIMEApplication from email.mime.multipart import MIMEMultipart from email.mime.text import MIMEText message = MIMEMultipart() - message['Subject'] = "%s [priority=%s]" % (subject, priority) - message['To'] = ', '.join(toaddrs) - message['Cc'] = ', '.join(ccaddrs) - message['From'] = fromaddr - message.preamble = 'You will not see this in a MIME-aware mail ' \ - 'reader.\n' - message.epilogue = ' ' # To guarantee the message ends with a newline + message["Subject"] = "%s [priority=%s]" % (subject, priority) + message["To"] = ", ".join(toaddrs) + message["Cc"] = ", ".join(ccaddrs) + message["From"] = fromaddr + message.preamble = ( + "You will not see this in a MIME-aware mail " "reader.\n" + ) + message.epilogue = " " # To guarantee the message ends with a newline # First section is simple ASCII data ... m = [] @@ -161,69 +184,78 @@

    Source code for apptools.logger.plugin.logger_service

    m.append(stack_trace) m.append("") - msg = MIMEText('\n'.join(m)) + msg = MIMEText("\n".join(m)) message.attach(msg) # Include the log file ... logtext = self.whole_log_text() msg = MIMEText(logtext) - msg.add_header('Content-Disposition', 'attachment', - filename='logfile.txt') + msg.add_header( + "Content-Disposition", "attachment", filename="logfile.txt" + ) message.attach(msg) # Include the environment variables ... # FIXME: ask the user, maybe? if include_environment: - # Transmit the user's environment settings as well. Main purpose is - # to work out the user name to help with following up on bug reports - # and in future we should probably send less data. + # Transmit the user's environment settings as well. Main purpose + # is to work out the user name to help with following up on bug + # reports and in future we should probably send less data. entries = [] for key, value in sorted(os.environ.items()): - entries.append('%30s : %s\n' % (key, value)) + entries.append("%30s : %s\n" % (key, value)) - msg = MIMEText(''.join(entries)) - msg.add_header('Content-Disposition', 'attachment', - filename='environment.txt') + msg = MIMEText("".join(entries)) + msg.add_header( + "Content-Disposition", "attachment", filename="environment.txt" + ) message.attach(msg) if include_userdata and len(self.mail_files) != 0: f = BytesIO() - zf = zipfile.ZipFile(f, 'w') + zf = zipfile.ZipFile(f, "w") for mf in self.mail_files: mf(zf) zf.close() msg = MIMEApplication(f.getvalue()) - msg.add_header('Content-Disposition', 'attachment', - filename='userdata.zip') + msg.add_header( + "Content-Disposition", "attachment", filename="userdata.zip" + ) message.attach(msg) return message
    -
    [docs] def send_bug_report(self, smtp_server, fromaddr, toaddrs, ccaddrs, message): - """ Send a bug report email. - """ +
    [docs] def send_bug_report( + self, smtp_server, fromaddr, toaddrs, ccaddrs, message + ): + """Send a bug report email.""" try: import smtplib + logger.debug("Connecting to: %s" % smtp_server) server = smtplib.SMTP(host=smtp_server) logger.debug("Connected: %s" % server) - #server.set_debuglevel(1) + # server.set_debuglevel(1) server.sendmail(fromaddr, toaddrs + ccaddrs, message.as_string()) server.quit() - except Exception as e: + except Exception: logger.exception("Problem sending error report")
    #### Traits stuff ######################################################### def _get_mail_files(self): return self.application.get_extensions( - 'apptools.logger.plugin.mail_files') + "apptools.logger.plugin.mail_files" + ) - @on_trait_change('preferences.level_') + @on_trait_change("preferences.level_") def _level_changed(self, new): - if (new is not None and new is not Undefined and - self.handler is not None): + if ( + new is not None + and new is not Undefined + and self.handler is not None + ): root_logger.setLevel(self.preferences.level_) self.handler.setLevel(self.preferences.level_)
    @@ -237,13 +269,11 @@

    Source code for apptools.logger.plugin.logger_service

    @@ -267,10 +297,10 @@

    Quick search

    © Copyright 2008-2020, Enthought
  • - Last updated on Jun 12, 2020. + Last updated on Dec 17, 2020.
  • - Created using Sphinx 1.8.5. + Created using Sphinx 2.3.1.
  • diff --git a/_modules/apptools/logger/plugin/view/logger_preferences_page.html b/_modules/apptools/logger/plugin/view/logger_preferences_page.html index 684b0e247..a0f07b780 100644 --- a/_modules/apptools/logger/plugin/view/logger_preferences_page.html +++ b/_modules/apptools/logger/plugin/view/logger_preferences_page.html @@ -13,9 +13,11 @@ @@ -72,22 +74,18 @@
    -
    +

    Source code for apptools.logger.plugin.view.logger_preferences_page

    -#------------------------------------------------------------------------------
    -# Copyright (c) 2005, Enthought, Inc.
    +# (C) Copyright 2005-2020 Enthought, Inc., Austin, TX
     # All rights reserved.
     #
     # This software is provided without warranty under the terms of the BSD
    -# license included in enthought/LICENSE.txt and may be redistributed only
    -# under the conditions described in the aforementioned license.  The license
    +# license included in LICENSE.txt and may be redistributed only under
    +# the conditions described in the aforementioned license. The license
     # is also available online at http://www.enthought.com/licenses/BSD.txt
    -# Thanks for using Enthought open source!
     #
    -# Author: Enthought, Inc.
    -# Description: <Enthought logger package component>
    -#------------------------------------------------------------------------------
    +# Thanks for using Enthought open source!
     
     import logging
     
    @@ -95,38 +93,39 @@ 

    Source code for apptools.logger.plugin.view.logger_preferences_page

    from traits.api import Bool, Trait, Str from traitsui.api import EnumEditor, Group, Item, View +
    [docs]class LoggerPreferencesPage(PreferencesPage): - """ A preference page for the logger plugin. - """ + """A preference page for the logger plugin.""" #### 'PreferencesPage' interface ########################################## # The page's category (e.g. 'General/Appearance'). The empty string means # that this is a top-level page. - category = '' + category = "" # The page's help identifier (optional). If a help Id *is* provided then # there will be a 'Help' button shown on the preference page. - help_id = '' + help_id = "" # The page name (this is what is shown in the preferences dialog. - name = 'Logger' + name = "Logger" # The path to the preferences node that contains the preferences. - preferences_path = 'apptools.logger' + preferences_path = "apptools.logger" - - #### Preferences ########################################################### + #### Preferences ########################################################## # The log levels - level = Trait('Info', - {'Debug' : logging.DEBUG, - 'Info' : logging.INFO, - 'Warning' : logging.WARNING, - 'Error' : logging.ERROR, - 'Critical' : logging.CRITICAL, + level = Trait( + "Info", + { + "Debug": logging.DEBUG, + "Info": logging.INFO, + "Warning": logging.WARNING, + "Error": logging.ERROR, + "Critical": logging.CRITICAL, }, - is_str = True, + is_str=True, ) enable_agent = Bool(False) @@ -134,42 +133,47 @@

    Source code for apptools.logger.plugin.view.logger_preferences_page

    to_address = Str from_address = Str - # The view used to change the plugin preferences traits_view = View( Group( Group( Item( - name='level', + name="level", editor=EnumEditor( values={ - 'Debug' : '1:Debug', - 'Info' : '2:Info', - 'Warning' : '3:Warning', - 'Error' : '4:Error' , - 'Critical' : '5:Critical', + "Debug": "1:Debug", + "Info": "2:Info", + "Warning": "3:Warning", + "Error": "4:Error", + "Critical": "5:Critical", }, ), - style='simple', + style="simple", ), - label='Logger Settings', + label="Logger Settings", show_border=True, ), - Group(Item(name='10')), + Group(Item(name="10")), Group( Group( - Group(Item(name='enable_agent', label='Enable quality agent'), show_left=False), - Group(Item(name='smtp_server', label='SMTP server'), - Item(name='from_address'), - Item(name='to_address'), enabled_when='enable_agent==True')), - label='Quality Agent Settings', + Group( + Item( + name="enable_agent", label="Enable quality agent" + ), + show_left=False, + ), + Group( + Item(name="smtp_server", label="SMTP server"), + Item(name="from_address"), + Item(name="to_address"), + enabled_when="enable_agent==True", + ), + ), + label="Quality Agent Settings", show_border=True, ), ), )
    - - -#### EOF ######################################################################
    @@ -181,13 +185,11 @@

    Source code for apptools.logger.plugin.view.logger_preferences_page

    diff --git a/_modules/apptools/logger/plugin/view/logger_view.html b/_modules/apptools/logger/plugin/view/logger_view.html index 7535cb118..237263148 100644 --- a/_modules/apptools/logger/plugin/view/logger_view.html +++ b/_modules/apptools/logger/plugin/view/logger_view.html @@ -13,9 +13,11 @@ @@ -72,22 +74,18 @@
    -
    +

    Source code for apptools.logger.plugin.view.logger_view

    -#------------------------------------------------------------------------------
    -# Copyright (c) 2005, Enthought, Inc.
    +# (C) Copyright 2005-2020 Enthought, Inc., Austin, TX
     # All rights reserved.
     #
     # This software is provided without warranty under the terms of the BSD
    -# license included in enthought/LICENSE.txt and may be redistributed only
    -# under the conditions described in the aforementioned license.  The license
    +# license included in LICENSE.txt and may be redistributed only under
    +# the conditions described in the aforementioned license. The license
     # is also available online at http://www.enthought.com/licenses/BSD.txt
    -# Thanks for using Enthought open source!
     #
    -# Author: Enthought, Inc.
    -# Description: <Enthought logger package component>
    -#------------------------------------------------------------------------------
    +# Thanks for using Enthought open source!
     
     # Standard library imports
     from datetime import datetime
    @@ -96,32 +94,42 @@ 

    Source code for apptools.logger.plugin.view.logger_view

    # Enthought library imports. from pyface.api import ImageResource, clipboard from pyface.workbench.api import TraitsUIView -from traits.api import Button, Instance, List, Property, Str, \ - cached_property, on_trait_change -from traitsui.api import View, Group, Item, CodeEditor, \ - TabularEditor, spring +from traits.api import ( + Button, + Instance, + List, + Property, + Str, + cached_property, + on_trait_change, +) +from traitsui.api import View, Group, Item, CodeEditor, TabularEditor, spring from traitsui.tabular_adapter import TabularAdapter # Local imports from apptools.logger.agent.quality_agent_view import QualityAgentView -from apptools.logger.plugin import view from apptools.logger.plugin.logger_service import LoggerService # Constants -_IMAGE_MAP = { logging.DEBUG: ImageResource('debug'), - logging.INFO: ImageResource('info'), - logging.WARNING: ImageResource('warning'), - logging.ERROR: ImageResource('error'), - logging.CRITICAL: ImageResource('crit_error') } +_IMAGE_MAP = { + logging.DEBUG: ImageResource("debug"), + logging.INFO: ImageResource("info"), + logging.WARNING: ImageResource("warning"), + logging.ERROR: ImageResource("error"), + logging.CRITICAL: ImageResource("crit_error"), +}
    [docs]class LogRecordAdapter(TabularAdapter): - """ A TabularEditor adapter for logging.LogRecord objects. - """ + """A TabularEditor adapter for logging.LogRecord objects.""" - columns = [ ('Level', 'level'), ('Date', 'date'), ('Time', 'time'), - ('Message', 'message') ] - column_widths = [ 80, 100, 120, -1 ] + columns = [ + ("Level", "level"), + ("Date", "date"), + ("Time", "time"), + ("Message", "message"), + ] + column_widths = [80, 100, 120, -1] level_image = Property level_text = Property(Str) @@ -149,60 +157,65 @@

    Source code for apptools.logger.plugin.view.logger_view

    def _get_message_text(self): # Just display the first line of multiline messages, like stacktraces. msg = self.item.getMessage() - msgs = msg.strip().split('\n') + msgs = msg.strip().split("\n") if len(msgs) > 1: - suffix = '... [double click for details]' + suffix = "... [double click for details]" else: - suffix = '' + suffix = "" abbrev_msg = msgs[0] + suffix return abbrev_msg
    [docs]class LoggerView(TraitsUIView): - """ The Workbench View showing the list of log items. - """ + """The Workbench View showing the list of log items.""" - id = Str('apptools.logger.plugin.view.logger_view.LoggerView') - name = Str('Logger') + id = Str("apptools.logger.plugin.view.logger_view.LoggerView") + name = Str("Logger") service = Instance(LoggerService) log_records = List(Instance(logging.LogRecord)) - formatted_records = Property(Str, depends_on='log_records') + formatted_records = Property(Str, depends_on="log_records") activated = Instance(logging.LogRecord) - activated_text = Property(Str, depends_on='activated') + activated_text = Property(Str, depends_on="activated") reset_button = Button("Reset Logs") show_button = Button("Complete Text Log") copy_button = Button("Copy Log to Clipboard") - - code_editor = CodeEditor(lexer='null', - show_line_numbers=False) - log_records_editor = TabularEditor(adapter=LogRecordAdapter(), - editable=False, - activated='activated') - trait_view = View(Group(Item('log_records', - editor=log_records_editor), - Group(Item('reset_button'), - spring, - Item('show_button'), - Item('copy_button'), - orientation='horizontal', - show_labels=False), - show_labels=False)) + code_editor = CodeEditor(lexer="null", show_line_numbers=False) + log_records_editor = TabularEditor( + adapter=LogRecordAdapter(), editable=False, activated="activated" + ) + trait_view = View( + Group( + Item("log_records", editor=log_records_editor), + Group( + Item("reset_button"), + spring, + Item("show_button"), + Item("copy_button"), + orientation="horizontal", + show_labels=False, + ), + show_labels=False, + ) + ) ########################################################################### # LogQueueHandler view interface ###########################################################################
    [docs] def update(self, force=False): - """ Update 'log_records' if our handler has new records or 'force' is - set. + """Update 'log_records' if our handler has new records or 'force' is + set. """ service = self.service if service.handler.has_new_records() or force: - log_records = [ rec for rec in service.handler.get() - if rec.levelno >= service.preferences.level_ ] + log_records = [ + rec + for rec in service.handler.get() + if rec.levelno >= service.preferences.level_ + ] log_records.reverse() self.log_records = log_records
    @@ -210,7 +223,7 @@

    Source code for apptools.logger.plugin.view.logger_view

    # Private interface ########################################################################### - @on_trait_change('service.preferences.level_') + @on_trait_change("service.preferences.level_") def _update_log_records(self): self.service.handler._view = self self.update(force=True) @@ -220,21 +233,33 @@

    Source code for apptools.logger.plugin.view.logger_view

    self.log_records = [] def _show_button_fired(self): - self.edit_traits(view=View(Item('formatted_records', - editor=self.code_editor, - style='readonly', - show_label=False), - width=800, height=600, resizable=True, - buttons=[ 'OK' ], - title='Complete Text Log')) + self.edit_traits( + view=View( + Item( + "formatted_records", + editor=self.code_editor, + style="readonly", + show_label=False, + ), + width=800, + height=600, + resizable=True, + buttons=["OK"], + title="Complete Text Log", + ) + ) def _copy_button_fired(self): clipboard.text_data = self.formatted_records @cached_property def _get_formatted_records(self): - return '\n'.join([ self.service.handler.formatter.format(record) - for record in self.log_records ]) + return "\n".join( + [ + self.service.handler.formatter.format(record) + for record in self.log_records + ] + ) def _activated_changed(self): if self.activated is None: @@ -244,22 +269,28 @@

    Source code for apptools.logger.plugin.view.logger_view

    dialog = QualityAgentView(msg=msg, service=self.service) dialog.open() else: - self.edit_traits(view=View(Item('activated_text', - editor=self.code_editor, - style='readonly', - show_label=False), - width=800, height=600, resizable=True, - buttons=[ 'OK' ], - title='Log Message Detail')) + self.edit_traits( + view=View( + Item( + "activated_text", + editor=self.code_editor, + style="readonly", + show_label=False, + ), + width=800, + height=600, + resizable=True, + buttons=["OK"], + title="Log Message Detail", + ) + ) @cached_property def _get_activated_text(self): if self.activated is None: - return '' + return "" else: return self.activated.getMessage()
    - -#### EOF ######################################################################
    @@ -271,13 +302,11 @@

    Source code for apptools.logger.plugin.view.logger_view

    @@ -301,10 +330,10 @@

    Quick search

    © Copyright 2008-2020, Enthought
  • - Last updated on Jun 12, 2020. + Last updated on Dec 17, 2020.
  • - Created using Sphinx 1.8.5. + Created using Sphinx 2.3.1.
  • diff --git a/_modules/apptools/logger/ring_buffer.html b/_modules/apptools/logger/ring_buffer.html index e4742d1b5..bbfb99f9f 100644 --- a/_modules/apptools/logger/ring_buffer.html +++ b/_modules/apptools/logger/ring_buffer.html @@ -13,9 +13,11 @@ @@ -72,50 +74,51 @@
    -
    +

    Source code for apptools.logger.ring_buffer

    -#------------------------------------------------------------------------------
    -# Copyright (c) 2005, Enthought, Inc.
    +# (C) Copyright 2005-2020 Enthought, Inc., Austin, TX
     # All rights reserved.
     #
     # This software is provided without warranty under the terms of the BSD
    -# license included in enthought/LICENSE.txt and may be redistributed only
    -# under the conditions described in the aforementioned license.  The license
    +# license included in LICENSE.txt and may be redistributed only under
    +# the conditions described in the aforementioned license. The license
     # is also available online at http://www.enthought.com/licenses/BSD.txt
    -# Thanks for using Enthought open source!
     #
    -# Author: Enthought, Inc.
    -# Description: <Enthought util package component>
    -#------------------------------------------------------------------------------
    +# Thanks for using Enthought open source!
     """
     Copied from Python Cookbook.
     
     """
     
    +
     
    [docs]class RingBuffer: - def __init__(self,size_max): + def __init__(self, size_max): self.max = size_max self.data = [] -
    [docs] def append(self,x): + +
    [docs] def append(self, x): """append an element at the end of the buffer""" self.data.append(x) if len(self.data) == self.max: self.cur = 0 self.__class__ = RingBufferFull
    +
    [docs] def get(self): """ return a list of elements from the oldest to the newest""" return self.data
    [docs]class RingBufferFull: - def __init__(self,n): + def __init__(self, n): raise Exception("you should use RingBuffer") -
    [docs] def append(self,x): - self.data[self.cur]=x - self.cur=(self.cur+1) % self.max
    + +
    [docs] def append(self, x): + self.data[self.cur] = x + self.cur = (self.cur + 1) % self.max
    +
    [docs] def get(self): - return self.data[self.cur:]+self.data[:self.cur]
    + return self.data[self.cur:] + self.data[: self.cur]
    # sample of use @@ -139,13 +142,11 @@

    Source code for apptools.logger.ring_buffer

                   
                 

    @@ -169,10 +170,10 @@

    Quick search

    © Copyright 2008-2020, Enthought
  • - Last updated on Jun 12, 2020. + Last updated on Dec 17, 2020.
  • - Created using Sphinx 1.8.5. + Created using Sphinx 2.3.1.
  • diff --git a/_modules/apptools/naming/address.html b/_modules/apptools/naming/address.html index 06fe23fc8..c0bb64dc7 100644 --- a/_modules/apptools/naming/address.html +++ b/_modules/apptools/naming/address.html @@ -13,9 +13,11 @@ @@ -72,22 +74,18 @@
    -
    +

    Source code for apptools.naming.address

    -#------------------------------------------------------------------------------
    -# Copyright (c) 2005, Enthought, Inc.
    +# (C) Copyright 2005-2020 Enthought, Inc., Austin, TX
     # All rights reserved.
     #
     # This software is provided without warranty under the terms of the BSD
    -# license included in enthought/LICENSE.txt and may be redistributed only
    -# under the conditions described in the aforementioned license.  The license
    +# license included in LICENSE.txt and may be redistributed only under
    +# the conditions described in the aforementioned license. The license
     # is also available online at http://www.enthought.com/licenses/BSD.txt
    -# Thanks for using Enthought open source!
     #
    -# Author: Enthought, Inc.
    -# Description: <Enthought naming package component>
    -#------------------------------------------------------------------------------
    +# Thanks for using Enthought open source!
     """ The address of a commuications endpoint. """
     
     
    @@ -96,7 +94,7 @@ 

    Source code for apptools.naming.address

     
     
     
    [docs]class Address(HasTraits): - """ The address of a communications end-point. + """The address of a communications end-point. It contains a type that describes the communication mechanism, and the actual address content. @@ -108,8 +106,6 @@

    Source code for apptools.naming.address

     
         # The actual content.
         content = Any
    - -#### EOF ######################################################################
    @@ -121,13 +117,11 @@

    Source code for apptools.naming.address

                   
                 

    @@ -151,10 +145,10 @@

    Quick search

    © Copyright 2008-2020, Enthought
  • - Last updated on Jun 12, 2020. + Last updated on Dec 17, 2020.
  • - Created using Sphinx 1.8.5. + Created using Sphinx 2.3.1.
  • diff --git a/_modules/apptools/naming/binding.html b/_modules/apptools/naming/binding.html index 6a72bf86d..396897ce3 100644 --- a/_modules/apptools/naming/binding.html +++ b/_modules/apptools/naming/binding.html @@ -13,9 +13,11 @@ @@ -72,22 +74,18 @@
    -
    +

    Source code for apptools.naming.binding

    -#------------------------------------------------------------------------------
    -# Copyright (c) 2005, Enthought, Inc.
    +# (C) Copyright 2005-2020 Enthought, Inc., Austin, TX
     # All rights reserved.
     #
     # This software is provided without warranty under the terms of the BSD
    -# license included in enthought/LICENSE.txt and may be redistributed only
    -# under the conditions described in the aforementioned license.  The license
    +# license included in LICENSE.txt and may be redistributed only under
    +# the conditions described in the aforementioned license. The license
     # is also available online at http://www.enthought.com/licenses/BSD.txt
    -# Thanks for using Enthought open source!
     #
    -# Author: Enthought, Inc.
    -# Description: <Enthought naming package component>
    -#------------------------------------------------------------------------------
    +# Thanks for using Enthought open source!
     """ The representation of a name-to-object binding in a context. """
     
     
    @@ -135,8 +133,10 @@ 

    Source code for apptools.naming.binding

         def __str__(self):
             """ Returns an informal string representation of the object. """
     
    -        return super(Binding, self).__str__() + '(name=%s, obj=%s)' % (
    -               self.name, self.obj)
    +        return super(Binding, self).__str__() + "(name=%s, obj=%s)" % (
    +            self.name,
    +            self.obj,
    +        )
     
         ###########################################################################
         # 'Binding' interface.
    @@ -155,7 +155,7 @@ 

    Source code for apptools.naming.binding

                 else:
                     klass = self.obj.__class__
     
    -                class_name = '%s.%s' % (klass.__module__, klass.__name__)
    +                class_name = "%s.%s" % (klass.__module__, klass.__name__)
     
             return class_name
     
    @@ -164,8 +164,6 @@ 

    Source code for apptools.naming.binding

     
             self._class_name = class_name
     
    -        return
    -
         # namespace_name
         def _get_namespace_name(self):
             """ Returns the name of the context within its own namespace. """
    @@ -174,17 +172,15 @@ 

    Source code for apptools.naming.binding

                 base = self.context.namespace_name
     
             else:
    -            base = ''
    +            base = ""
     
             if len(base) > 0:
    -            namespace_name = base + '/' + self.name
    +            namespace_name = base + "/" + self.name
     
             else:
                 namespace_name = self.name
     
             return namespace_name
    - -#### EOF ######################################################################
    @@ -196,13 +192,11 @@

    Source code for apptools.naming.binding

                   
                 

    @@ -226,10 +220,10 @@

    Quick search

    © Copyright 2008-2020, Enthought
  • - Last updated on Jun 12, 2020. + Last updated on Dec 17, 2020.
  • - Created using Sphinx 1.8.5. + Created using Sphinx 2.3.1.
  • diff --git a/_modules/apptools/naming/context.html b/_modules/apptools/naming/context.html index 1fe488f43..d87dae45b 100644 --- a/_modules/apptools/naming/context.html +++ b/_modules/apptools/naming/context.html @@ -13,9 +13,11 @@ @@ -72,39 +74,31 @@
    -
    +

    Source code for apptools.naming.context

    -#------------------------------------------------------------------------------
    -# Copyright (c) 2005, Enthought, Inc.
    +# (C) Copyright 2005-2020 Enthought, Inc., Austin, TX
     # All rights reserved.
     #
     # This software is provided without warranty under the terms of the BSD
    -# license included in enthought/LICENSE.txt and may be redistributed only
    -# under the conditions described in the aforementioned license.  The license
    +# license included in LICENSE.txt and may be redistributed only under
    +# the conditions described in the aforementioned license. The license
     # is also available online at http://www.enthought.com/licenses/BSD.txt
    -# Thanks for using Enthought open source!
     #
    -# Author: Enthought, Inc.
    -# Description: <Enthought naming package component>
    -#------------------------------------------------------------------------------
    +# Thanks for using Enthought open source!
     """ The base class for all naming contexts. """
     
     
     # Enthought library imports.
    -from traits.api import Any, Dict, Event, HasTraits, Instance
    +from traits.api import Any, Dict, Event, HasTraits
     from traits.api import Property, Str
    -from apptools.type_manager.api import TypeManager
     
     # Local imports.
     from .binding import Binding
     from .exception import InvalidNameError, NameAlreadyBoundError
     from .exception import NameNotFoundError, NotContextError
    -from .exception import OperationNotSupportedError
     from .naming_event import NamingEvent
     from .naming_manager import naming_manager
    -from .object_factory import ObjectFactory
    -from .state_factory import StateFactory
     from .unique_name import make_unique_name
     
     
    @@ -113,18 +107,12 @@ 

    Source code for apptools.naming.context

     OBJECT_FACTORIES = "apptools.naming.factory.object"
     STATE_FACTORIES = "apptools.naming.factory.state"
     
    -# Non-JNDI.
    -TYPE_MANAGER = "apptools.naming.factory.type.manager"
    -
     
     # The default environment.
     ENVIRONMENT = {
         # 'Context' properties.
    -    OBJECT_FACTORIES          : [],
    -    STATE_FACTORIES           : [],
    -
    -    # Non-JNDI.
    -    TYPE_MANAGER              : None,
    +    OBJECT_FACTORIES: [],
    +    STATE_FACTORIES: [],
     }
     
     
    @@ -136,9 +124,6 @@ 

    Source code for apptools.naming.context

         OBJECT_FACTORIES = OBJECT_FACTORIES
         STATE_FACTORIES = STATE_FACTORIES
     
    -    # Non-JNDI.
    -    TYPE_MANAGER = TYPE_MANAGER
    -
         #### 'Context' interface ##################################################
     
         # The naming environment in effect for this context.
    @@ -147,14 +132,6 @@ 

    Source code for apptools.naming.context

         # The name of the context within its own namespace.
         namespace_name = Property(Str)
     
    -    # The type manager in the context's environment (used to create context
    -    # adapters etc.).
    -    #
    -    # fixme: This is an experimental 'convenience' trait, since it is common
    -    # to get hold of the context's type manager to see if some object has a
    -    # context adapter.
    -    type_manager = Property(Instance(TypeManager))
    -
         #### Events ####
     
         # Fired when an object has been added to the context (either via 'bind' or
    @@ -174,7 +151,7 @@ 

    Source code for apptools.naming.context

         # Fired when the contents of the context have changed dramatically.
         context_changed = Event(NamingEvent)
     
    -     #### Protected 'Context' interface #######################################
    +    #### Protected 'Context' interface #######################################
     
         # The bindings in the context.
         _bindings = Dict(Str, Any)
    @@ -208,23 +185,13 @@ 

    Source code for apptools.naming.context

             # 'enabled_when' evaluation.  This is because the Traits evaluation
             # code calls the 'get()' method on the Context which attempts to
             # retrieve the current namespace_name value.
    -        #raise OperationNotSupportedError()
    -        return ''
    -
    -    def _get_type_manager(self):
    -        """ Returns the type manager in the context's environment.
    -
    -        This will return None if no type manager was used to create the initial
    -        context.
    -
    -        """
    -
    -        return self.environment.get(self.TYPE_MANAGER)
    +        # raise OperationNotSupportedError()
    +        return ""
     
         #### Methods ##############################################################
     
     
    [docs] def bind(self, name, obj, make_contexts=False): - """ Binds a name to an object. + """Binds a name to an object. If 'make_contexts' is True then any missing intermediate contexts are created automatically. @@ -232,7 +199,7 @@

    Source code for apptools.naming.context

             """
     
             if len(name) == 0:
    -            raise InvalidNameError('empty name')
    +            raise InvalidNameError("empty name")
     
             # Parse the name.
             components = self._parse_name(name)
    @@ -264,12 +231,10 @@ 

    Source code for apptools.naming.context

                         raise NameNotFoundError(components[0])
     
                 next_context = self._get_next_context(components[0])
    -            next_context.bind('/'.join(components[1:]), obj, make_contexts)
    -
    -        return
    + next_context.bind("/".join(components[1:]), obj, make_contexts)
    [docs] def rebind(self, name, obj, make_contexts=False): - """ Binds an object to a name that may already be bound. + """Binds an object to a name that may already be bound. If 'make_contexts' is True then any missing intermediate contexts are created automatically. @@ -282,7 +247,7 @@

    Source code for apptools.naming.context

             """
     
             if len(name) == 0:
    -            raise InvalidNameError('empty name')
    +            raise InvalidNameError("empty name")
     
             # Parse the name.
             components = self._parse_name(name)
    @@ -308,15 +273,13 @@ 

    Source code for apptools.naming.context

                         raise NameNotFoundError(components[0])
     
                 next_context = self._get_next_context(components[0])
    -            next_context.rebind('/'.join(components[1:]), obj, make_contexts)
    -
    -        return
    + next_context.rebind("/".join(components[1:]), obj, make_contexts)
    [docs] def unbind(self, name): """ Unbinds a name. """ if len(name) == 0: - raise InvalidNameError('empty name') + raise InvalidNameError("empty name") # Parse the name. components = self._parse_name(name) @@ -347,15 +310,13 @@

    Source code for apptools.naming.context

                     raise NameNotFoundError(components[0])
     
                 next_context = self._get_next_context(components[0])
    -            next_context.unbind('/'.join(components[1:]))
    -
    -        return
    + next_context.unbind("/".join(components[1:]))
    [docs] def rename(self, old_name, new_name): """ Binds a new name to an object. """ if len(old_name) == 0 or len(new_name) == 0: - raise InvalidNameError('empty name') + raise InvalidNameError("empty name") # Parse the names. old_components = self._parse_name(old_name) @@ -382,7 +343,7 @@

    Source code for apptools.naming.context

                 # Trait event notification.
                 self.object_renamed = NamingEvent(
                     old_binding=Binding(name=old_name, obj=obj, context=self),
    -                new_binding=Binding(name=new_name, obj=obj, context=self)
    +                new_binding=Binding(name=new_name, obj=obj, context=self),
                 )
     
             else:
    @@ -397,9 +358,7 @@ 

    Source code for apptools.naming.context

                 self.bind(new_name, obj)
     
                 # Unbind the old one.
    -            self.unbind(old_name)
    -
    -        return
    + self.unbind(old_name)
    [docs] def lookup(self, name): """ Resolves a name relative to this context. """ @@ -430,17 +389,16 @@

    Source code for apptools.naming.context

                     raise NameNotFoundError(components[0])
     
                 next_context = self._get_next_context(components[0])
    -            obj = next_context.lookup('/'.join(components[1:]))
    +            obj = next_context.lookup("/".join(components[1:]))
     
             return obj
    - # fixme: Non-JNDI
    [docs] def lookup_binding(self, name): """ Looks up the binding for a name relative to this context. """ if len(name) == 0: - raise InvalidNameError('empty name') + raise InvalidNameError("empty name") # Parse the name. components = self._parse_name(name) @@ -462,16 +420,15 @@

    Source code for apptools.naming.context

                     raise NameNotFoundError(components[0])
     
                 next_context = self._get_next_context(components[0])
    -            binding = next_context.lookup_binding('/'.join(components[1:]))
    +            binding = next_context.lookup_binding("/".join(components[1:]))
     
             return binding
    # fixme: Non-JNDI
    [docs] def lookup_context(self, name): - """ Resolves a name relative to this context. + """Resolves a name relative to this context. - The name MUST resolve to a context. This method is useful to return - context adapters. + The name MUST resolve to a context. """ @@ -501,7 +458,7 @@

    Source code for apptools.naming.context

                     raise NameNotFoundError(components[0])
     
                 next_context = self._get_next_context(components[0])
    -            obj = next_context.lookup('/'.join(components[1:]))
    +            obj = next_context.lookup("/".join(components[1:]))
     
             return obj
    @@ -509,7 +466,7 @@

    Source code for apptools.naming.context

             """ Creates a sub-context. """
     
             if len(name) == 0:
    -            raise InvalidNameError('empty name')
    +            raise InvalidNameError("empty name")
     
             # Parse the name.
             components = self._parse_name(name)
    @@ -537,7 +494,7 @@ 

    Source code for apptools.naming.context

                     raise NameNotFoundError(components[0])
     
                 next_context = self._get_next_context(components[0])
    -            sub = next_context.create_subcontext('/'.join(components[1:]))
    +            sub = next_context.create_subcontext("/".join(components[1:]))
     
             return sub
    @@ -545,7 +502,7 @@

    Source code for apptools.naming.context

             """ Destroys a sub-context. """
     
             if len(name) == 0:
    -            raise InvalidNameError('empty name')
    +            raise InvalidNameError("empty name")
     
             # Parse the name.
             components = self._parse_name(name)
    @@ -560,7 +517,7 @@ 

    Source code for apptools.naming.context

     
                 obj = self._lookup(atom)
                 if not self._is_context(atom):
    -               raise NotContextError(name)
    +                raise NotContextError(name)
     
                 # Do the actual destruction of the sub-context.
                 self._destroy_subcontext(atom)
    @@ -576,23 +533,21 @@ 

    Source code for apptools.naming.context

                     raise NameNotFoundError(components[0])
     
                 next_context = self._get_next_context(components[0])
    -            next_context.destroy_subcontext('/'.join(components[1:]))
    -
    -        return
    + next_context.destroy_subcontext("/".join(components[1:]))
    # fixme: Non-JNDI
    [docs] def get_unique_name(self, prefix): - """ Returns a name that is unique within the context. + """Returns a name that is unique within the context. The name returned will start with the specified prefix. """ - return make_unique_name(prefix, existing=self.list_names(''), - format='%s (%d)')
    - + return make_unique_name( + prefix, existing=self.list_names(""), format="%s (%d)" + )
    -
    [docs] def list_names(self, name=''): +
    [docs] def list_names(self, name=""): """ Lists the names bound in a context. """ # If the name is empty then the operation takes place in this context. @@ -608,11 +563,11 @@

    Source code for apptools.naming.context

                     raise NameNotFoundError(components[0])
     
                 next_context = self._get_next_context(components[0])
    -            names = next_context.list_names('/'.join(components[1:]))
    +            names = next_context.list_names("/".join(components[1:]))
     
             return names
    -
    [docs] def list_bindings(self, name=''): +
    [docs] def list_bindings(self, name=""): """ Lists the bindings in a context. """ # If the name is empty then the operation takes place in this context. @@ -628,7 +583,7 @@

    Source code for apptools.naming.context

                     raise NameNotFoundError(components[0])
     
                 next_context = self._get_next_context(components[0])
    -            bindings = next_context.list_bindings('/'.join(components[1:]))
    +            bindings = next_context.list_bindings("/".join(components[1:]))
     
             return bindings
    @@ -661,7 +616,7 @@

    Source code for apptools.naming.context

                         raise NameNotFoundError(components[0])
     
                     next_context = self._get_next_context(components[0])
    -                is_context = next_context.is_context('/'.join(components[1:]))
    +                is_context = next_context.is_context("/".join(components[1:]))
     
             return is_context
    @@ -679,7 +634,7 @@

    Source code for apptools.naming.context

             # path contain the name components down to the current context
             path = []
     
    -        self._search( obj, names, path, {} )
    +        self._search(obj, names, path, {})
     
             return names
    @@ -688,13 +643,13 @@

    Source code for apptools.naming.context

         ###########################################################################
     
         def _parse_name(self, name):
    -        """ Parse a name into a list of components.
    +        """Parse a name into a list of components.
     
             e.g. 'foo/bar/baz' -> ['foo', 'bar', 'baz']
     
             """
     
    -        return name.split('/')
    +        return name.split("/")
     
         def _is_bound(self, name):
             """ Is a name bound in this context? """
    @@ -719,22 +674,16 @@ 

    Source code for apptools.naming.context

             state = naming_manager.get_state_to_bind(obj, name, self)
             self._bindings[name] = state
     
    -        return
    -
         def _rebind(self, name, obj):
             """ Rebinds a name to an object in this context. """
     
             self._bind(name, obj)
     
    -        return
    -
         def _unbind(self, name):
             """ Unbinds a name from this context. """
     
             del self._bindings[name]
     
    -        return
    -
         def _rename(self, old_name, new_name):
             """ Renames an object in this context. """
     
    @@ -744,8 +693,6 @@ 

    Source code for apptools.naming.context

             # Unbind the old one.
             del self._bindings[old_name]
     
    -        return
    -
         def _create_subcontext(self, name):
             """ Creates a sub-context of this context. """
     
    @@ -759,8 +706,6 @@ 

    Source code for apptools.naming.context

     
             del self._bindings[name]
     
    -        return
    -
         def _list_bindings(self):
             """ Lists the bindings in this context. """
     
    @@ -790,63 +735,32 @@ 

    Source code for apptools.naming.context

             # If the object is a context then everything is just dandy.
             if isinstance(obj, Context):
                 next_context = obj
    -
    -        # Otherwise, instead of just giving up, see if the context has a type
    -        # manager that knows how to adapt the object to make it quack like a
    -        # context.
             else:
    -            next_context = self._get_context_adapter(obj)
    -
    -            # If no adapter was found then we cannot continue name resolution.
    -            if next_context is None:
    -                raise NotContextError(name)
    +            raise NotContextError(name)
     
             return next_context
     
    -    def _search( self, obj, names, path, searched):
    -        """ Append to names any name bound to obj.
    -            Join path and name with '/' to for a complete name from the
    -            top context.
    +    def _search(self, obj, names, path, searched):
    +        """Append to names any name bound to obj.
    +        Join path and name with '/' to for a complete name from the
    +        top context.
             """
     
             # Check the bindings recursively.
             for binding in self.list_bindings():
                 if binding.obj is obj:
    -                path.append( binding.name )
    -                names.append( '/'.join(path) )
    +                path.append(binding.name)
    +                names.append("/".join(path))
                     path.pop()
     
    -            if isinstance( binding.obj, Context ) \
    -                and not binding.obj in searched:
    -                path.append( binding.name )
    +            if (
    +                isinstance(binding.obj, Context)
    +                and binding.obj not in searched
    +            ):
    +                path.append(binding.name)
                     searched[binding.obj] = True
    -                binding.obj._search( obj, names, path, searched )
    -                path.pop()
    -
    -        return
    -
    -    ###########################################################################
    -    # Private interface.
    -    ###########################################################################
    -
    -    def _get_context_adapter(self, obj):
    -        """ Returns a context adapter for an object.
    -
    -        Returns None if no such adapter is available.
    -
    -        """
    -
    -        if self.type_manager is not None:
    -            adapter = self.type_manager.object_as(
    -                obj, Context, environment=self.environment, context=self
    -            )
    -
    -        else:
    -            adapter = None
    -
    -        return adapter
    - -#### EOF ###################################################################### + binding.obj._search(obj, names, path, searched) + path.pop()
    @@ -858,13 +772,11 @@

    Source code for apptools.naming.context

                   
                 

    @@ -888,10 +800,10 @@

    Quick search

    © Copyright 2008-2020, Enthought
  • - Last updated on Jun 12, 2020. + Last updated on Dec 17, 2020.
  • - Created using Sphinx 1.8.5. + Created using Sphinx 2.3.1.
  • diff --git a/_modules/apptools/naming/dir_context.html b/_modules/apptools/naming/dir_context.html index 97f34dee8..edc6864a6 100644 --- a/_modules/apptools/naming/dir_context.html +++ b/_modules/apptools/naming/dir_context.html @@ -13,9 +13,11 @@ @@ -72,22 +74,18 @@
    -
    +

    Source code for apptools.naming.dir_context

    -#------------------------------------------------------------------------------
    -# Copyright (c) 2005, Enthought, Inc.
    +# (C) Copyright 2005-2020 Enthought, Inc., Austin, TX
     # All rights reserved.
     #
     # This software is provided without warranty under the terms of the BSD
    -# license included in enthought/LICENSE.txt and may be redistributed only
    -# under the conditions described in the aforementioned license.  The license
    +# license included in LICENSE.txt and may be redistributed only under
    +# the conditions described in the aforementioned license. The license
     # is also available online at http://www.enthought.com/licenses/BSD.txt
    -# Thanks for using Enthought open source!
     #
    -# Author: Enthought, Inc.
    -# Description: <Enthought naming package component>
    -#------------------------------------------------------------------------------
    +# Thanks for using Enthought open source!
     """ The base class for all directory contexts. """
     
     
    @@ -96,7 +94,7 @@ 

    Source code for apptools.naming.dir_context

     
     # Local imports.
     from .context import Context
    -from .exception import NameNotFoundError, NotContextError
    +from .exception import NameNotFoundError
     
     
     
    [docs]class DirContext(Context): @@ -141,7 +139,8 @@

    Source code for apptools.naming.dir_context

     
                     next_context = self._get_next_context(components[0])
                     attributes = next_context.get_attributes(
    -                    '/'.join(components[1:]))
    +                    "/".join(components[1:])
    +                )
     
             return attributes
    @@ -174,14 +173,12 @@

    Source code for apptools.naming.dir_context

     
                     next_context = self._get_next_context(components[0])
                     next_context.set_attributes(
    -                    '/'.join(components[1:]), attributes
    -                )
    -
    -        return
    + "/".join(components[1:]), attributes + )
    # fixme: Non-JNDI
    [docs] def find_bindings(self, visitor): - """ Find bindings with attributes matching criteria in visitor. + """Find bindings with attributes matching criteria in visitor. Visitor is a function that is passed the bindings for each level of the heirarchy and the attribute dictionary for those bindings. The visitor @@ -216,8 +213,6 @@

    Source code for apptools.naming.dir_context

     
             self._attributes[name] = attributes
     
    -        return
    -
         ###########################################################################
         # Protected 'Context' interface.
         ###########################################################################
    @@ -230,8 +225,6 @@ 

    Source code for apptools.naming.dir_context

             if name in self._attributes:
                 del self._attributes[name]
     
    -        return
    -
         def _rename(self, old_name, new_name):
             """ Renames an object in this context. """
     
    @@ -241,19 +234,13 @@ 

    Source code for apptools.naming.dir_context

                 self._attributes[new_name] = self._attributes[old_name]
                 del self._attributes[old_name]
     
    -        return
    -
         def _destroy_subcontext(self, name):
             """ Destroys a sub-context of this context. """
     
             super(DirContext, self)._destroy_subcontext(name)
     
             if name in self._attributes:
    -            del self._attributes[name]
    -
    -        return
    - -#### EOF ###################################################################### + del self._attributes[name]
    @@ -265,13 +252,11 @@

    Source code for apptools.naming.dir_context

                   
                 

    @@ -295,10 +280,10 @@

    Quick search

    © Copyright 2008-2020, Enthought
  • - Last updated on Jun 12, 2020. + Last updated on Dec 17, 2020.
  • - Created using Sphinx 1.8.5. + Created using Sphinx 2.3.1.
  • diff --git a/_modules/apptools/naming/dynamic_context.html b/_modules/apptools/naming/dynamic_context.html index 58dcd472d..5b69be61c 100644 --- a/_modules/apptools/naming/dynamic_context.html +++ b/_modules/apptools/naming/dynamic_context.html @@ -13,9 +13,11 @@ @@ -72,15 +74,18 @@
    -
    +

    Source code for apptools.naming.dynamic_context

    -#-----------------------------------------------------------------------------
    +# (C) Copyright 2005-2020 Enthought, Inc., Austin, TX
    +# All rights reserved.
     #
    -#  Copyright (c) 2006 by Enthought, Inc.
    -#  All rights reserved.
    +# This software is provided without warranty under the terms of the BSD
    +# license included in LICENSE.txt and may be redistributed only under
    +# the conditions described in the aforementioned license. The license
    +# is also available online at http://www.enthought.com/licenses/BSD.txt
     #
    -#-----------------------------------------------------------------------------
    +# Thanks for using Enthought open source!
     
     """ Provider of a framework that dynamically determines the contents of a
         context at the time of interaction with the contents rather than at the
    @@ -131,13 +136,13 @@ 

    Source code for apptools.naming.dynamic_context

    <
    [docs]class DynamicContext(Context): - """ A framework that dynamically determines the contents of a context at - the time of interaction with the contents rather than at the time a - context class is written. + """A framework that dynamically determines the contents of a context at + the time of interaction with the contents rather than at the time a + context class is written. - It should be noted that this capability is explicitly different from - contexts that look at another container to determine their contents, - such as a file system context! + It should be noted that this capability is explicitly different from + contexts that look at another container to determine their contents, + such as a file system context! """ ########################################################################## @@ -147,48 +152,41 @@

    Source code for apptools.naming.dynamic_context

    < ### protected interface ################################################## def _is_bound(self, name): - """ Is a name bound in this context? - """ + """Is a name bound in this context?""" item = self._get_contributed_context_item(name) result = item != (None, None) return result - def _is_context(self, name): - """ Returns True if a name is bound to a context. - """ + """Returns True if a name is bound to a context.""" item = self._get_contributed_context_item(name) if item != (None, None): obj, trait = item - result = True == trait.is_context + result = trait.is_context is True else: result = False return result - def _list_bindings(self): - """ Lists the bindings in this context. - """ - result = [ Binding(name=n, obj=o, context=self) for n, o, t in \ - self._get_contributed_context_items() ] + """Lists the bindings in this context.""" + result = [ + Binding(name=n, obj=o, context=self) + for n, o, t in self._get_contributed_context_items() + ] return result - def _list_names(self): - """ Lists the names bound in this context. - """ - result = [ n for n, o, t in self._get_contributed_context_items() ] + """Lists the names bound in this context.""" + result = [n for n, o, t in self._get_contributed_context_items()] return result - def _lookup(self, name): - """ Looks up a name in this context. - """ + """Looks up a name in this context.""" item = self._get_contributed_context_item(name) if item != (None, None): obj, trait = item @@ -198,10 +196,8 @@

    Source code for apptools.naming.dynamic_context

    < return result - def _rename(self, old_name, new_name): - """ Renames an object in this context. - """ + """Renames an object in this context.""" item = self._get_contributed_context_item(old_name) if item != (None, None): @@ -210,16 +206,14 @@

    Source code for apptools.naming.dynamic_context

    < else: raise ValueError('Name "%s" not in context', old_name) - def _unbind(self, name): - """ Unbinds a name from this context. - """ + """Unbinds a name from this context.""" # It is an error to try to unbind any contributed context items item = self._get_contributed_context_item(name) if item != (None, None): - raise OperationNotSupportedError('Unable to unbind ' + \ - 'built-in with name [%s]' % name) - + raise OperationNotSupportedError( + "Unable to unbind " + "built-in with name [%s]" % name + ) ########################################################################## # 'DynamicContext' interface. @@ -228,9 +222,9 @@

    Source code for apptools.naming.dynamic_context

    < ### protected interface ################################################## def _get_contributed_context_item(self, name): - """ If the specified name matches a contributed context item then - returns a tuple of the item's current value and trait definition - (in that order.) Otherwise, returns a tuple of (None, None). + """If the specified name matches a contributed context item then + returns a tuple of the item's current value and trait definition + (in that order.) Otherwise, returns a tuple of (None, None). """ result = (None, None) @@ -240,34 +234,28 @@

    Source code for apptools.naming.dynamic_context

    < return result - def _get_contributed_context_items(self): - """ Returns an ordered list of items to be treated as part of our - context. + """Returns an ordered list of items to be treated as part of our + context. - Each item in the list is a tuple of its name, object, and trait - definition (in that order.) + Each item in the list is a tuple of its name, object, and trait + definition (in that order.) """ # Our traits that get treated as context items are those that declare # themselves via metadata on the trait definition. - filter = { - 'context_name': lambda v: v is not None and len(v) > 0 - } + filter = {"context_name": lambda v: v is not None and len(v) > 0} traits = self.traits(**filter) # Sort the list of context items according to the name of the item. - traits = [ (t.context_order, n, t) for n, t in traits.items() ] + traits = [(t.context_order, n, t) for n, t in traits.items()] traits.sort() - # Convert these trait definitions into a list of name and object tuples. - result = [(t.context_name, getattr(self, n), t) for order, n, t \ - in traits] + # Convert these trait definitions into a list of name and object tuples + result = [ + (t.context_name, getattr(self, n), t) for order, n, t in traits + ] return result
    - - -### EOF ###################################################################### -
    @@ -279,13 +267,11 @@

    Source code for apptools.naming.dynamic_context

    <

    @@ -309,10 +295,10 @@

    Quick search

    © Copyright 2008-2020, Enthought
  • - Last updated on Jun 12, 2020. + Last updated on Dec 17, 2020.
  • - Created using Sphinx 1.8.5. + Created using Sphinx 2.3.1.
  • diff --git a/_modules/apptools/naming/exception.html b/_modules/apptools/naming/exception.html index 5a6e22135..8c73dc462 100644 --- a/_modules/apptools/naming/exception.html +++ b/_modules/apptools/naming/exception.html @@ -13,9 +13,11 @@ @@ -72,56 +74,54 @@
    -
    +

    Source code for apptools.naming.exception

    -#------------------------------------------------------------------------------
    -# Copyright (c) 2005, Enthought, Inc.
    +# (C) Copyright 2005-2020 Enthought, Inc., Austin, TX
     # All rights reserved.
     #
     # This software is provided without warranty under the terms of the BSD
    -# license included in enthought/LICENSE.txt and may be redistributed only
    -# under the conditions described in the aforementioned license.  The license
    +# license included in LICENSE.txt and may be redistributed only under
    +# the conditions described in the aforementioned license. The license
     # is also available online at http://www.enthought.com/licenses/BSD.txt
    -# Thanks for using Enthought open source!
     #
    -# Author: Enthought, Inc.
    -# Description: <Enthought naming package component>
    -#------------------------------------------------------------------------------
    +# Thanks for using Enthought open source!
     """ Naming exceptions. """
     
     
     
    [docs]class NamingError(Exception): - """ Base class for all naming exceptions. + """Base class for all naming exceptions."""
    - """
    [docs]class InvalidNameError(NamingError): - """ Invalid name. + """Invalid name. This exception is thrown when the name passed to a naming operation does not conform to the syntax of the naming system (or is empty etc). """
    +
    [docs]class NameAlreadyBoundError(NamingError): - """ Name already bound. + """Name already bound. This exception is thrown when an attempt is made to bind a name that is already bound in the current context. """
    +
    [docs]class NameNotFoundError(NamingError): - """ Name not found. + """Name not found. This exception is thrown when a component of a name cannot be resolved because it is not bound in the current context. """
    +
    [docs]class NotContextError(NamingError): - """ Not a context. + """Not a context. This exception is thrown when a naming operation has reached a point where a context is required to continue the operation, but the resolved object @@ -129,12 +129,9 @@

    Source code for apptools.naming.exception

     
         """
    -
    [docs]class OperationNotSupportedError(NamingError): - """ The context does support the requested operation. - """
    - -#### EOF ###################################################################### +
    [docs]class OperationNotSupportedError(NamingError): + """The context does support the requested operation."""
    @@ -146,13 +143,11 @@

    Source code for apptools.naming.exception

                   
                 

    @@ -176,10 +171,10 @@

    Quick search

    © Copyright 2008-2020, Enthought
  • - Last updated on Jun 12, 2020. + Last updated on Dec 17, 2020.
  • - Created using Sphinx 1.8.5. + Created using Sphinx 2.3.1.
  • diff --git a/_modules/apptools/naming/initial_context.html b/_modules/apptools/naming/initial_context.html index ffe407dd7..d26ad66b5 100644 --- a/_modules/apptools/naming/initial_context.html +++ b/_modules/apptools/naming/initial_context.html @@ -13,9 +13,11 @@ @@ -72,22 +74,18 @@
    -
    +

    Source code for apptools.naming.initial_context

    -#------------------------------------------------------------------------------
    -# Copyright (c) 2005, Enthought, Inc.
    +# (C) Copyright 2005-2020 Enthought, Inc., Austin, TX
     # All rights reserved.
     #
     # This software is provided without warranty under the terms of the BSD
    -# license included in enthought/LICENSE.txt and may be redistributed only
    -# under the conditions described in the aforementioned license.  The license
    +# license included in LICENSE.txt and may be redistributed only under
    +# the conditions described in the aforementioned license. The license
     # is also available online at http://www.enthought.com/licenses/BSD.txt
    -# Thanks for using Enthought open source!
     #
    -# Author: Enthought, Inc.
    -# Description: <Enthought naming package component>
    -#------------------------------------------------------------------------------
    +# Thanks for using Enthought open source!
     """ The starting point for performing naming operations. """
     
     
    @@ -117,7 +115,7 @@ 

    Source code for apptools.naming.initial_context

    < # want naming to be dependent on Envisage, so we need some other package # for useful 'Python' tools etc. def _import_symbol(symbol_path): - """ Imports the symbol defined by 'symbol_path'. + """Imports the symbol defined by 'symbol_path'. 'symbol_path' is a string in the form 'foo.bar.baz' which is turned into an import statement 'from foo.bar import baz' (ie. the last @@ -126,17 +124,15 @@

    Source code for apptools.naming.initial_context

    < """ - components = symbol_path.split('.') + components = symbol_path.split(".") - module_name = '.'.join(components[:-1]) + module_name = ".".join(components[:-1]) symbol_name = components[-1] module = __import__(module_name, globals(), locals(), [symbol_name]) symbol = getattr(module, symbol_name) return symbol - -#### EOF ######################################################################
    @@ -148,13 +144,11 @@

    Source code for apptools.naming.initial_context

    <

    @@ -178,10 +172,10 @@

    Quick search

    © Copyright 2008-2020, Enthought
  • - Last updated on Jun 12, 2020. + Last updated on Dec 17, 2020.
  • - Created using Sphinx 1.8.5. + Created using Sphinx 2.3.1.
  • diff --git a/_modules/apptools/naming/initial_context_factory.html b/_modules/apptools/naming/initial_context_factory.html index b4d91647b..8c80347bc 100644 --- a/_modules/apptools/naming/initial_context_factory.html +++ b/_modules/apptools/naming/initial_context_factory.html @@ -13,9 +13,11 @@ @@ -72,22 +74,18 @@
    -
    +

    Source code for apptools.naming.initial_context_factory

    -#------------------------------------------------------------------------------
    -# Copyright (c) 2005, Enthought, Inc.
    +# (C) Copyright 2005-2020 Enthought, Inc., Austin, TX
     # All rights reserved.
     #
     # This software is provided without warranty under the terms of the BSD
    -# license included in enthought/LICENSE.txt and may be redistributed only
    -# under the conditions described in the aforementioned license.  The license
    +# license included in LICENSE.txt and may be redistributed only under
    +# the conditions described in the aforementioned license. The license
     # is also available online at http://www.enthought.com/licenses/BSD.txt
    -# Thanks for using Enthought open source!
     #
    -# Author: Enthought, Inc.
    -# Description: <Enthought naming package component>
    -#------------------------------------------------------------------------------
    +# Thanks for using Enthought open source!
     """ The base class for all initial context factories. """
     
     
    @@ -109,8 +107,6 @@ 

    Source code for apptools.naming.initial_context_factory

    """ Creates an initial context for beginning name resolution. """ return Context(environment=environment)
    - -#### EOF ######################################################################
    @@ -122,13 +118,11 @@

    Source code for apptools.naming.initial_context_factory

    @@ -152,10 +146,10 @@

    Quick search

    © Copyright 2008-2020, Enthought
  • - Last updated on Jun 12, 2020. + Last updated on Dec 17, 2020.
  • - Created using Sphinx 1.8.5. + Created using Sphinx 2.3.1.
  • diff --git a/_modules/apptools/naming/naming_event.html b/_modules/apptools/naming/naming_event.html index 41de0f64d..e119c59e8 100644 --- a/_modules/apptools/naming/naming_event.html +++ b/_modules/apptools/naming/naming_event.html @@ -13,9 +13,11 @@ @@ -72,22 +74,18 @@
    -
    +

    Source code for apptools.naming.naming_event

    -#------------------------------------------------------------------------------
    -# Copyright (c) 2005, Enthought, Inc.
    +# (C) Copyright 2005-2020 Enthought, Inc., Austin, TX
     # All rights reserved.
     #
     # This software is provided without warranty under the terms of the BSD
    -# license included in enthought/LICENSE.txt and may be redistributed only
    -# under the conditions described in the aforementioned license.  The license
    +# license included in LICENSE.txt and may be redistributed only under
    +# the conditions described in the aforementioned license. The license
     # is also available online at http://www.enthought.com/licenses/BSD.txt
    -# Thanks for using Enthought open source!
     #
    -# Author: Enthought, Inc.
    -# Description: <Enthought naming package component>
    -#------------------------------------------------------------------------------
    +# Thanks for using Enthought open source!
     """ The event fired by the tree model when it changes. """
     
     
    @@ -107,8 +105,6 @@ 

    Source code for apptools.naming.naming_event

    # The new binding.
         new_binding = Instance(Binding)
    - -#### EOF ######################################################################
    @@ -120,13 +116,11 @@

    Source code for apptools.naming.naming_event

    diff --git a/_modules/apptools/naming/naming_manager.html b/_modules/apptools/naming/naming_manager.html index d46a20642..124e9b884 100644 --- a/_modules/apptools/naming/naming_manager.html +++ b/_modules/apptools/naming/naming_manager.html @@ -13,9 +13,11 @@ @@ -72,22 +74,18 @@
    -
    +

    Source code for apptools.naming.naming_manager

    -#------------------------------------------------------------------------------
    -# Copyright (c) 2005, Enthought, Inc.
    +# (C) Copyright 2005-2020 Enthought, Inc., Austin, TX
     # All rights reserved.
     #
     # This software is provided without warranty under the terms of the BSD
    -# license included in enthought/LICENSE.txt and may be redistributed only
    -# under the conditions described in the aforementioned license.  The license
    +# license included in LICENSE.txt and may be redistributed only under
    +# the conditions described in the aforementioned license. The license
     # is also available online at http://www.enthought.com/licenses/BSD.txt
    -# Thanks for using Enthought open source!
     #
    -# Author: Enthought, Inc.
    -# Description: <Enthought naming package component>
    -#------------------------------------------------------------------------------
    +# Thanks for using Enthought open source!
     """ The naming manager. """
     
     
    @@ -103,7 +101,7 @@ 

    Source code for apptools.naming.naming_manager

    ###########################################################################

    [docs] def get_state_to_bind(self, obj, name, context): - """ Returns the state of an object for binding. + """Returns the state of an object for binding. The naming manager asks the context for its list of STATE factories and then calls them one by one until it gets a non-None result @@ -132,7 +130,7 @@

    Source code for apptools.naming.naming_manager

    return state

    [docs] def get_object_instance(self, info, name, context): - """ Creates an object using the specified state information. + """Creates an object using the specified state information. The naming manager asks the context for its list of OBJECT factories and calls them one by one until it gets a non-None result, indicating @@ -163,8 +161,6 @@

    Source code for apptools.naming.naming_manager

    # Singleton instance. naming_manager = NamingManager() - -### EOF #######################################################################

    @@ -176,13 +172,11 @@

    Source code for apptools.naming.naming_manager

    @@ -206,10 +200,10 @@

    Quick search

    © Copyright 2008-2020, Enthought
  • - Last updated on Jun 12, 2020. + Last updated on Dec 17, 2020.
  • - Created using Sphinx 1.8.5. + Created using Sphinx 2.3.1.
  • diff --git a/_modules/apptools/naming/object_factory.html b/_modules/apptools/naming/object_factory.html index e1f681add..8277c2eec 100644 --- a/_modules/apptools/naming/object_factory.html +++ b/_modules/apptools/naming/object_factory.html @@ -13,9 +13,11 @@ @@ -72,22 +74,18 @@
    -
    +

    Source code for apptools.naming.object_factory

    -#------------------------------------------------------------------------------
    -# Copyright (c) 2005, Enthought, Inc.
    +# (C) Copyright 2005-2020 Enthought, Inc., Austin, TX
     # All rights reserved.
     #
     # This software is provided without warranty under the terms of the BSD
    -# license included in enthought/LICENSE.txt and may be redistributed only
    -# under the conditions described in the aforementioned license.  The license
    +# license included in LICENSE.txt and may be redistributed only under
    +# the conditions described in the aforementioned license. The license
     # is also available online at http://www.enthought.com/licenses/BSD.txt
    -# Thanks for using Enthought open source!
     #
    -# Author: Enthought, Inc.
    -# Description: <Enthought naming package component>
    -#------------------------------------------------------------------------------
    +# Thanks for using Enthought open source!
     """ The base class for all object factories. """
     
     
    @@ -96,7 +94,7 @@ 

    Source code for apptools.naming.object_factory

    [docs]class ObjectFactory(HasTraits): - """ The base class for all object factories. + """The base class for all object factories. An object factory accepts some information about how to create an object (such as a reference) and returns an instance of that object. @@ -108,7 +106,7 @@

    Source code for apptools.naming.object_factory

    ###########################################################################

    [docs] def get_object_instance(self, state, name, context): - """ Creates an object using the specified state information. + """Creates an object using the specified state information. Returns None if the factory cannot create the object (ie. it does not recognise the state passed to it). @@ -116,8 +114,6 @@

    Source code for apptools.naming.object_factory

    """ raise NotImplementedError

    - -### EOF #######################################################################
    @@ -129,13 +125,11 @@

    Source code for apptools.naming.object_factory

    @@ -159,10 +153,10 @@

    Quick search

    © Copyright 2008-2020, Enthought
  • - Last updated on Jun 12, 2020. + Last updated on Dec 17, 2020.
  • - Created using Sphinx 1.8.5. + Created using Sphinx 2.3.1.
  • diff --git a/_modules/apptools/naming/object_serializer.html b/_modules/apptools/naming/object_serializer.html index d42ab950f..8df9f1aab 100644 --- a/_modules/apptools/naming/object_serializer.html +++ b/_modules/apptools/naming/object_serializer.html @@ -13,9 +13,11 @@ @@ -72,22 +74,18 @@
    -
    +

    Source code for apptools.naming.object_serializer

    -#------------------------------------------------------------------------------
    -# Copyright (c) 2005, Enthought, Inc.
    +# (C) Copyright 2005-2020 Enthought, Inc., Austin, TX
     # All rights reserved.
     #
     # This software is provided without warranty under the terms of the BSD
    -# license included in enthought/LICENSE.txt and may be redistributed only
    -# under the conditions described in the aforementioned license.  The license
    +# license included in LICENSE.txt and may be redistributed only under
    +# the conditions described in the aforementioned license. The license
     # is also available online at http://www.enthought.com/licenses/BSD.txt
    -# Thanks for using Enthought open source!
     #
    -# Author: Enthought, Inc.
    -# Description: <Enthought naming package component>
    -#------------------------------------------------------------------------------
    +# Thanks for using Enthought open source!
     """ The base class for all object serializers. """
     
     
    @@ -95,11 +93,10 @@ 

    Source code for apptools.naming.object_serializer

    import logging from traceback import print_exc from os.path import splitext -#import cPickle -#import pickle +import pickle # Enthought library imports. -import apptools.sweet_pickle as sweet_pickle +from apptools.persistence.versioned_unpickler import VersionedUnpickler from traits.api import HasTraits, Str @@ -113,7 +110,7 @@

    Source code for apptools.naming.object_serializer

    #### 'ObjectSerializer' interface ######################################### # The file extension recognized by this serializer. - ext = Str('.pickle') + ext = Str(".pickle") ########################################################################### # 'ObjectSerializer' interface. @@ -130,15 +127,15 @@

    Source code for apptools.naming.object_serializer

    """ Loads an object from a file. """ # Unpickle the object. - f = open(path, 'rb') + f = open(path, "rb") try: try: - obj = sweet_pickle.load(f) -# obj = cPickle.load(f) -# obj = pickle.load(f) + obj = VersionedUnpickler(f).load() except Exception as ex: print_exc() - logger.exception( "Failed to load pickle file: %s, %s" % (path, ex)) + logger.exception( + "Failed to load pickle file: %s, %s" % (path, ex) + ) raise finally: @@ -161,20 +158,18 @@

    Source code for apptools.naming.object_serializer

    actual_path = path # Pickle the object. - f = open(actual_path, 'wb') + f = open(actual_path, "wb") try: - sweet_pickle.dump(obj, f, 1) -# cPickle.dump(obj, f, 1) -# pickle.dump(obj, f, 1) + pickle.dump(obj, f, 1) except Exception as ex: - logger.exception( "Failed to pickle into file: %s, %s, object:%s" - % (path, ex, obj)) + logger.exception( + "Failed to pickle into file: %s, %s, object:%s" + % (path, ex, obj) + ) print_exc() f.close() return actual_path
    - -### EOF #######################################################################
    @@ -186,13 +181,11 @@

    Source code for apptools.naming.object_serializer

    @@ -216,10 +209,10 @@

    Quick search

    © Copyright 2008-2020, Enthought
  • - Last updated on Jun 12, 2020. + Last updated on Dec 17, 2020.
  • - Created using Sphinx 1.8.5. + Created using Sphinx 2.3.1.
  • diff --git a/_modules/apptools/naming/py_context.html b/_modules/apptools/naming/py_context.html index 7e76fa8d1..b3bb934f3 100644 --- a/_modules/apptools/naming/py_context.html +++ b/_modules/apptools/naming/py_context.html @@ -13,9 +13,11 @@ @@ -72,22 +74,18 @@
    -
    +

    Source code for apptools.naming.py_context

    -#------------------------------------------------------------------------------
    -# Copyright (c) 2005, Enthought, Inc.
    +# (C) Copyright 2005-2020 Enthought, Inc., Austin, TX
     # All rights reserved.
     #
     # This software is provided without warranty under the terms of the BSD
    -# license included in enthought/LICENSE.txt and may be redistributed only
    -# under the conditions described in the aforementioned license.  The license
    +# license included in LICENSE.txt and may be redistributed only under
    +# the conditions described in the aforementioned license. The license
     # is also available online at http://www.enthought.com/licenses/BSD.txt
    -# Thanks for using Enthought open source!
     #
    -# Author: Enthought, Inc.
    -# Description: <Enthought naming package component>
    -#------------------------------------------------------------------------------
    +# Thanks for using Enthought open source!
     """ A naming context for a Python namespace. """
     
     
    @@ -108,8 +106,8 @@ 

    Source code for apptools.naming.py_context

     # The default environment.
     ENVIRONMENT = {
         # 'Context' properties.
    -    Context.OBJECT_FACTORIES : [PyObjectFactory()],
    -    Context.STATE_FACTORIES  : [ReferenceableStateFactory()],
    +    Context.OBJECT_FACTORIES: [PyObjectFactory()],
    +    Context.STATE_FACTORIES: [ReferenceableStateFactory()],
     }
     
     
    @@ -147,14 +145,12 @@ 

    Source code for apptools.naming.py_context

             super(PyContext, self).__init__(**traits)
     
             if type(self.namespace) is not dict:
    -            if hasattr(self.namespace, '__dict__'):
    +            if hasattr(self.namespace, "__dict__"):
                     self.obj = self.namespace
                     self.namespace = self.namespace.__dict__
     
                 else:
    -                raise ValueError('Need a dictionary or a __dict__ attribute')
    -
    -        return
    +                raise ValueError("Need a dictionary or a __dict__ attribute")
     
         ###########################################################################
         # 'Referenceable' interface.
    @@ -166,8 +162,8 @@ 

    Source code for apptools.naming.py_context

             """ Returns a reference to this object suitable for binding. """
     
             reference = Reference(
    -            class_name = self.__class__.__name__,
    -            addresses  = [Address(type='py_context', content=self.namespace)]
    +            class_name=self.__class__.__name__,
    +            addresses=[Address(type="py_context", content=self.namespace)],
             )
     
             return reference
    @@ -191,34 +187,21 @@ 

    Source code for apptools.naming.py_context

         def _bind(self, name, obj):
             """ Binds a name to an object in this context. """
     
    -        state = naming_manager.get_state_to_bind(obj, name,self)
    +        state = naming_manager.get_state_to_bind(obj, name, self)
             self.namespace[name] = state
     
    -        # Trait event notification.
    -        # An "added" event is fired by the bind method of the base calss (which calls
    -        # this one), so we don't need to do the changed here (which would be the wrong
    -        # thing anyway) -- LGV
    -        #
    -        # self.trait_property_changed('context_changed', None, None)
    -
    -        return
    -
         def _rebind(self, name, obj):
             """ Rebinds a name to a object in this context. """
     
             self._bind(name, obj)
     
    -        return
    -
         def _unbind(self, name):
             """ Unbinds a name from this context. """
     
             del self.namespace[name]
     
             # Trait event notification.
    -        self.trait_property_changed('context_changed', None, None)
    -
    -        return
    +        self.trait_property_changed("context_changed", None, None)
     
         def _rename(self, old_name, new_name):
             """ Renames an object in this context. """
    @@ -234,8 +217,6 @@ 

    Source code for apptools.naming.py_context

             # Trait event notification.
             self.context_changed = True
     
    -        return
    -
         def _create_subcontext(self, name):
             """ Creates a sub-context of this context. """
     
    @@ -243,7 +224,7 @@ 

    Source code for apptools.naming.py_context

             self.namespace[name] = sub
     
             # Trait event notification.
    -        self.trait_property_changed('context_changed', None, None)
    +        self.trait_property_changed("context_changed", None, None)
     
             return sub
     
    @@ -253,17 +234,16 @@ 

    Source code for apptools.naming.py_context

             del self.namespace[name]
     
             # Trait event notification.
    -        self.trait_property_changed('context_changed', None, None)
    -
    -        return
    +        self.trait_property_changed("context_changed", None, None)
     
         def _list_bindings(self):
             """ Lists the bindings in this context. """
     
             bindings = []
             for name, value in self.namespace.items():
    -            bindings.append(Binding(name=name, obj=self._lookup(name),
    -                                    context=self))
    +            bindings.append(
    +                Binding(name=name, obj=self._lookup(name), context=self)
    +            )
             return bindings
     
         def _list_names(self):
    @@ -279,8 +259,6 @@ 

    Source code for apptools.naming.py_context

             """ Create a sub-context. """
     
             return self.__class__(namespace=namespace)
    - -#### EOF ######################################################################
    @@ -292,13 +270,11 @@

    Source code for apptools.naming.py_context

                   
                 

    @@ -322,10 +298,10 @@

    Quick search

    © Copyright 2008-2020, Enthought
  • - Last updated on Jun 12, 2020. + Last updated on Dec 17, 2020.
  • - Created using Sphinx 1.8.5. + Created using Sphinx 2.3.1.
  • diff --git a/_modules/apptools/naming/py_object_factory.html b/_modules/apptools/naming/py_object_factory.html index 81d0b3fe3..4a049b8ad 100644 --- a/_modules/apptools/naming/py_object_factory.html +++ b/_modules/apptools/naming/py_object_factory.html @@ -13,9 +13,11 @@ @@ -72,22 +74,18 @@
    -
    +

    Source code for apptools.naming.py_object_factory

    -#------------------------------------------------------------------------------
    -# Copyright (c) 2005, Enthought, Inc.
    +# (C) Copyright 2005-2020 Enthought, Inc., Austin, TX
     # All rights reserved.
     #
     # This software is provided without warranty under the terms of the BSD
    -# license included in enthought/LICENSE.txt and may be redistributed only
    -# under the conditions described in the aforementioned license.  The license
    +# license included in LICENSE.txt and may be redistributed only under
    +# the conditions described in the aforementioned license. The license
     # is also available online at http://www.enthought.com/licenses/BSD.txt
    -# Thanks for using Enthought open source!
     #
    -# Author: Enthought, Inc.
    -# Description: <Enthought naming package component>
    -#------------------------------------------------------------------------------
    +# Thanks for using Enthought open source!
     """ Object factory for Python namespace contexts. """
     
     
    @@ -110,18 +108,17 @@ 

    Source code for apptools.naming.py_object_factory

    if isinstance(state, Reference): if len(state.addresses) > 0: - if state.addresses[0].type == 'py_context': + if state.addresses[0].type == "py_context": namespace = state.addresses[0].content obj = context._context_factory(name, namespace) - elif hasattr(state, '__dict__'): + elif hasattr(state, "__dict__"): from apptools.naming.py_context import PyContext + if not isinstance(state, PyContext): obj = context._context_factory(name, state) return obj
    - -### EOF #######################################################################
    @@ -133,13 +130,11 @@

    Source code for apptools.naming.py_object_factory

    @@ -163,10 +158,10 @@

    Quick search

    © Copyright 2008-2020, Enthought
  • - Last updated on Jun 12, 2020. + Last updated on Dec 17, 2020.
  • - Created using Sphinx 1.8.5. + Created using Sphinx 2.3.1.
  • diff --git a/_modules/apptools/naming/pyfs_context.html b/_modules/apptools/naming/pyfs_context.html index 2f64e4cf0..819d1dbd6 100644 --- a/_modules/apptools/naming/pyfs_context.html +++ b/_modules/apptools/naming/pyfs_context.html @@ -13,9 +13,11 @@ @@ -72,22 +74,18 @@
    -
    +

    Source code for apptools.naming.pyfs_context

    -#------------------------------------------------------------------------------
    -# Copyright (c) 2005, Enthought, Inc.
    +# (C) Copyright 2005-2020 Enthought, Inc., Austin, TX
     # All rights reserved.
     #
     # This software is provided without warranty under the terms of the BSD
    -# license included in enthought/LICENSE.txt and may be redistributed only
    -# under the conditions described in the aforementioned license.  The license
    +# license included in LICENSE.txt and may be redistributed only under
    +# the conditions described in the aforementioned license. The license
     # is also available online at http://www.enthought.com/licenses/BSD.txt
    -# Thanks for using Enthought open source!
     #
    -# Author: Enthought, Inc.
    -# Description: <Enthought naming package component>
    -#------------------------------------------------------------------------------
    +# Thanks for using Enthought open source!
     """ A Python File System context. """
     
     
    @@ -96,9 +94,7 @@ 

    Source code for apptools.naming.pyfs_context

    import logging
     import os
     from os.path import join, splitext
    -
    -# Third-party library imports.
    -import six.moves.cPickle as pickle
    +import pickle
     
     # Enthought library imports.
     from apptools.io.api import File
    @@ -109,7 +105,6 @@ 

    Source code for apptools.naming.pyfs_context

    from .binding import Binding
     from .context import Context
     from .dir_context import DirContext
    -from .exception import NameNotFoundError, NotContextError
     from .naming_event import NamingEvent
     from .naming_manager import naming_manager
     from .object_serializer import ObjectSerializer
    @@ -125,7 +120,7 @@ 

    Source code for apptools.naming.pyfs_context

    # The name of the 'special' file in which we store object attributes.
    -ATTRIBUTES_FILE = '__attributes__'
    +ATTRIBUTES_FILE = "__attributes__"
     
     # Constants for environment property keys.
     FILTERS = "apptools.naming.pyfs.filters"
    @@ -135,29 +130,24 @@ 

    Source code for apptools.naming.pyfs_context

    # The default environment.
     ENVIRONMENT = {
         #### 'Context' properties #################################################
    -
         # Object factories.
    -    Context.OBJECT_FACTORIES : [PyFSObjectFactory(), PyFSContextFactory()],
    -
    +    Context.OBJECT_FACTORIES: [PyFSObjectFactory(), PyFSContextFactory()],
         # State factories.
    -    Context.STATE_FACTORIES  : [PyFSStateFactory()],
    -
    +    Context.STATE_FACTORIES: [PyFSStateFactory()],
         #### 'PyFSContext' properties #############################################
    -
         # Object serializers.
    -    OBJECT_SERIALIZERS : [ObjectSerializer()],
    -
    +    OBJECT_SERIALIZERS: [ObjectSerializer()],
         # List of filename patterns to ignore.  These patterns are passed to
         # 'glob.glob', so things like '*.pyc' will do what you expect.
         #
         # fixme: We should have a generalized filter mechanism here, and '.svn'
         # should be moved elsewhere!
    -    FILTERS : [ATTRIBUTES_FILE, '.svn']
    +    FILTERS: [ATTRIBUTES_FILE, ".svn"],
     }
     
     
     
    [docs]class PyFSContext(DirContext, Referenceable): - """ A Python File System context. + """A Python File System context. This context represents a directory on a local file system. @@ -195,7 +185,7 @@

    Source code for apptools.naming.pyfs_context

    # A mapping from bound name to the name of the corresponding file or
         # directory on the file system.
    -    _name_to_filename_map = Dict#(Str, Str)
    +    _name_to_filename_map = Dict  # (Str, Str)
     
         # The attributes of every object in the context.  The attributes for the
         # context itself have the empty string as the key.
    @@ -221,8 +211,6 @@ 

    Source code for apptools.naming.pyfs_context

    # serialized Python object return a reference to exactly the same one.
             self._cache = {}
     
    -        return
    -
         ###########################################################################
         # 'PyFSContext' interface.
         ###########################################################################
    @@ -233,8 +221,8 @@ 

    Source code for apptools.naming.pyfs_context

    """ Returns the name of the context within its own namespace. """
     
             # fixme: clean this up with an initial context API!
    -        if 'root' in self.environment:
    -            root = self.environment['root']
    +        if "root" in self.environment:
    +            root = self.environment["root"]
     
                 namespace_name = self.path[len(root) + 1:]
     
    @@ -243,7 +231,7 @@ 

    Source code for apptools.naming.pyfs_context

    # fixme: This is a bit dodgy 'cos we actually return a name that can
             # be looked up, and not the file system name...
    -        namespace_name = '/'.join(namespace_name.split(os.path.sep))
    +        namespace_name = "/".join(namespace_name.split(os.path.sep))
     
             return namespace_name
     
    @@ -257,7 +245,7 @@ 

    Source code for apptools.naming.pyfs_context

    # This causes the initializer to run again the next time the trait is
             # accessed.
    -        self.reset_traits(['_name_to_filename_map'])
    +        self.reset_traits(["_name_to_filename_map"])
     
             # Clear out the cache.
             self._cache = {}
    @@ -266,9 +254,7 @@ 

    Source code for apptools.naming.pyfs_context

    # not be None!
             self.context_changed = NamingEvent(
                 new_binding=Binding(name=self.name, obj=self, context=None)
    -        )
    -
    -        return
    + )
    ########################################################################### # 'Referenceable' interface. @@ -282,8 +268,8 @@

    Source code for apptools.naming.pyfs_context

    abspath = os.path.abspath(self.path)
     
             reference = Reference(
    -            class_name = self.__class__.__name__,
    -            addresses  = [Address(type='pyfs_context', content=abspath)]
    +            class_name=self.__class__.__name__,
    +            addresses=[Address(type="pyfs_context", content=abspath)],
             )
     
             return reference
    @@ -316,9 +302,9 @@ 

    Source code for apptools.naming.pyfs_context

    # If the load fails then we create a generic file resource
                         # (the idea being that it might be useful to have access to
                         # the file to see what went wrong).
    -                    except:
    +                    except:  # noqa: E722
                             state = File(path)
    -                        logger.exception('Error loading resource at %s' % path)
    +                        logger.exception("Error loading resource at %s" % path)
     
                         break
     
    @@ -333,7 +319,7 @@ 

    Source code for apptools.naming.pyfs_context

    state = File(path)
     
                     else:
    -                    raise ValueError('unrecognized file for %s' % name)
    +                    raise ValueError("unrecognized file for %s" % name)
     
                 # Get the actual object from the naming manager.
                 obj = naming_manager.get_object_instance(state, name, self)
    @@ -367,7 +353,7 @@ 

    Source code for apptools.naming.pyfs_context

    break
     
                 else:
    -                raise ValueError('cannot serialize object %s' % name)
    +                raise ValueError("cannot serialize object %s" % name)
     
             # Update the name to filename map.
             self._name_to_filename_map[name] = filename
    @@ -380,15 +366,8 @@ 

    Source code for apptools.naming.pyfs_context

    def _rebind(self, name, obj):
             """ Rebinds a name to an object in this context. """
     
    -        # We unbind first to make sure that the old file gets removed (this
    -        # is handy if the object that we are rebinding has a different
    -        # serializer than the current one).
    -        #self._unbind(name)
    -
             self._bind(name, obj)
     
    -        return
    -
         def _unbind(self, name):
             """ Unbinds a name from this context. """
     
    @@ -411,8 +390,6 @@ 

    Source code for apptools.naming.pyfs_context

    del self._attributes[name]
                 self._save_attributes()
     
    -        return
    -
         def _rename(self, old_name, new_name):
             """ Renames an object in this context. """
     
    @@ -496,8 +473,6 @@ 

    Source code for apptools.naming.pyfs_context

    del self._attributes[old_name]
                 self._save_attributes()
     
    -        return
    -
         def _create_subcontext(self, name):
             """ Creates a sub-context of this context. """
     
    @@ -534,7 +509,7 @@ 

    Source code for apptools.naming.pyfs_context

    ext = splitext(name)[1]
     
             # specially handle '.py' files
    -        if ext != '.py':
    +        if ext != ".py":
                 return super(PyFSContext, self).get_unique_name(name)
     
             body = splitext(name)[0]
    @@ -542,7 +517,7 @@ 

    Source code for apptools.naming.pyfs_context

    i = 2
             unique = name
             while unique in names:
    -            unique = body + '_' + str(i) + '.py'
    +            unique = body + "_" + str(i) + ".py"
                 i += 1
     
             return unique
    @@ -564,8 +539,6 @@

    Source code for apptools.naming.pyfs_context

    self._attributes[name] = attributes
             self._save_attributes()
     
    -        return
    -
         ###########################################################################
         # Private interface.
         ###########################################################################
    @@ -590,12 +563,10 @@ 

    Source code for apptools.naming.pyfs_context

    path = join(self.path, self.ATTRIBUTES_FILE)
     
    -        f = open(path, 'wb')
    +        f = open(path, "wb")
             pickle.dump(self._attributes, f, 1)
             f.close()
     
    -        return
    -
         #### Trait initializers ###################################################
     
         def __name_to_filename_map_default(self):
    @@ -634,7 +605,7 @@ 

    Source code for apptools.naming.pyfs_context

    attributes_file = File(join(self.path, self.ATTRIBUTES_FILE))
             if attributes_file.is_file:
    -            f = open(attributes_file.path, 'rb')
    +            f = open(attributes_file.path, "rb")
                 attributes = pickle.load(f)
                 f.close()
     
    @@ -650,11 +621,7 @@ 

    Source code for apptools.naming.pyfs_context

    basename = os.path.basename(self.path)
     
    -        self.name, ext = os.path.splitext(basename)
    -
    -        return
    - -#### EOF ###################################################################### + self.name, ext = os.path.splitext(basename)
    @@ -666,13 +633,11 @@

    Source code for apptools.naming.pyfs_context

    diff --git a/_modules/apptools/naming/pyfs_context_factory.html b/_modules/apptools/naming/pyfs_context_factory.html index 600e5be9e..13c30f4ea 100644 --- a/_modules/apptools/naming/pyfs_context_factory.html +++ b/_modules/apptools/naming/pyfs_context_factory.html @@ -13,9 +13,11 @@ @@ -72,22 +74,18 @@
    -
    +

    Source code for apptools.naming.pyfs_context_factory

    -#------------------------------------------------------------------------------
    -# Copyright (c) 2005, Enthought, Inc.
    +# (C) Copyright 2005-2020 Enthought, Inc., Austin, TX
     # All rights reserved.
     #
     # This software is provided without warranty under the terms of the BSD
    -# license included in enthought/LICENSE.txt and may be redistributed only
    -# under the conditions described in the aforementioned license.  The license
    +# license included in LICENSE.txt and may be redistributed only under
    +# the conditions described in the aforementioned license. The license
     # is also available online at http://www.enthought.com/licenses/BSD.txt
    -# Thanks for using Enthought open source!
     #
    -# Author: Enthought, Inc.
    -# Description: <Enthought naming package component>
    -#------------------------------------------------------------------------------
    +# Thanks for using Enthought open source!
     """ Object factory for Python File System contexts. """
     
     
    @@ -110,13 +108,11 @@ 

    Source code for apptools.naming.pyfs_context_factory

    if isinstance(state, Reference): if len(state.addresses) > 0: - if state.addresses[0].type == 'pyfs_context': + if state.addresses[0].type == "pyfs_context": path = state.addresses[0].content obj = context._context_factory(name, path) return obj
    - -### EOF #######################################################################
    @@ -128,13 +124,11 @@

    Source code for apptools.naming.pyfs_context_factory

    @@ -158,10 +152,10 @@

    Quick search

    © Copyright 2008-2020, Enthought
  • - Last updated on Jun 12, 2020. + Last updated on Dec 17, 2020.
  • - Created using Sphinx 1.8.5. + Created using Sphinx 2.3.1.
  • diff --git a/_modules/apptools/naming/pyfs_initial_context_factory.html b/_modules/apptools/naming/pyfs_initial_context_factory.html index ab20eda97..6dc9fafdc 100644 --- a/_modules/apptools/naming/pyfs_initial_context_factory.html +++ b/_modules/apptools/naming/pyfs_initial_context_factory.html @@ -13,9 +13,11 @@ @@ -72,22 +74,18 @@
    -
    +

    Source code for apptools.naming.pyfs_initial_context_factory

    -#------------------------------------------------------------------------------
    -# Copyright (c) 2005, Enthought, Inc.
    +# (C) Copyright 2005-2020 Enthought, Inc., Austin, TX
     # All rights reserved.
     #
     # This software is provided without warranty under the terms of the BSD
    -# license included in enthought/LICENSE.txt and may be redistributed only
    -# under the conditions described in the aforementioned license.  The license
    +# license included in LICENSE.txt and may be redistributed only under
    +# the conditions described in the aforementioned license. The license
     # is also available online at http://www.enthought.com/licenses/BSD.txt
    -# Thanks for using Enthought open source!
     #
    -# Author: Enthought, Inc.
    -# Description: <Enthought naming package component>
    -#------------------------------------------------------------------------------
    +# Thanks for using Enthought open source!
     """ The initial context factory for Python file system contexts. """
     
     
    @@ -123,9 +121,7 @@ 

    Source code for apptools.naming.pyfs_initial_context_factory

    object_serializers = [ObjectSerializer()] environment[PyFSContext.OBJECT_SERIALIZERS] = object_serializers - return PyFSContext(path=r'', environment=environment)
    - -#### EOF ###################################################################### + return PyFSContext(path=r"", environment=environment)
    @@ -137,13 +133,11 @@

    Source code for apptools.naming.pyfs_initial_context_factory

    @@ -167,10 +161,10 @@

    Quick search

    © Copyright 2008-2020, Enthought
  • - Last updated on Jun 12, 2020. + Last updated on Dec 17, 2020.
  • - Created using Sphinx 1.8.5. + Created using Sphinx 2.3.1.
  • diff --git a/_modules/apptools/naming/pyfs_object_factory.html b/_modules/apptools/naming/pyfs_object_factory.html index d40b4ab61..394ba4730 100644 --- a/_modules/apptools/naming/pyfs_object_factory.html +++ b/_modules/apptools/naming/pyfs_object_factory.html @@ -13,9 +13,11 @@ @@ -72,22 +74,18 @@
    -
    +

    Source code for apptools.naming.pyfs_object_factory

    -#------------------------------------------------------------------------------
    -# Copyright (c) 2005, Enthought, Inc.
    +# (C) Copyright 2005-2020 Enthought, Inc., Austin, TX
     # All rights reserved.
     #
     # This software is provided without warranty under the terms of the BSD
    -# license included in enthought/LICENSE.txt and may be redistributed only
    -# under the conditions described in the aforementioned license.  The license
    +# license included in LICENSE.txt and may be redistributed only under
    +# the conditions described in the aforementioned license. The license
     # is also available online at http://www.enthought.com/licenses/BSD.txt
    -# Thanks for using Enthought open source!
     #
    -# Author: Enthought, Inc.
    -# Description: <Enthought naming package component>
    -#------------------------------------------------------------------------------
    +# Thanks for using Enthought open source!
     """ Object factory for Python File System contexts. """
     
     
    @@ -112,12 +110,10 @@ 

    Source code for apptools.naming.pyfs_object_factory

    obj = None if isinstance(state, Reference): - if state.class_name == 'File' and len(state.addresses) > 0: + if state.class_name == "File" and len(state.addresses) > 0: obj = File(state.addresses[0].content) return obj
    - -### EOF #######################################################################
    @@ -129,13 +125,11 @@

    Source code for apptools.naming.pyfs_object_factory

    @@ -159,10 +153,10 @@

    Quick search

    © Copyright 2008-2020, Enthought
  • - Last updated on Jun 12, 2020. + Last updated on Dec 17, 2020.
  • - Created using Sphinx 1.8.5. + Created using Sphinx 2.3.1.
  • diff --git a/_modules/apptools/naming/pyfs_state_factory.html b/_modules/apptools/naming/pyfs_state_factory.html index 582b2491c..b942c237e 100644 --- a/_modules/apptools/naming/pyfs_state_factory.html +++ b/_modules/apptools/naming/pyfs_state_factory.html @@ -13,9 +13,11 @@ @@ -72,22 +74,18 @@
    -
    +

    Source code for apptools.naming.pyfs_state_factory

    -#------------------------------------------------------------------------------
    -# Copyright (c) 2005, Enthought, Inc.
    +# (C) Copyright 2005-2020 Enthought, Inc., Austin, TX
     # All rights reserved.
     #
     # This software is provided without warranty under the terms of the BSD
    -# license included in enthought/LICENSE.txt and may be redistributed only
    -# under the conditions described in the aforementioned license.  The license
    +# license included in LICENSE.txt and may be redistributed only under
    +# the conditions described in the aforementioned license. The license
     # is also available online at http://www.enthought.com/licenses/BSD.txt
    -# Thanks for using Enthought open source!
     #
    -# Author: Enthought, Inc.
    -# Description: <Enthought naming package component>
    -#------------------------------------------------------------------------------
    +# Thanks for using Enthought open source!
     """ State factory for Python File System contexts. """
     
     
    @@ -117,13 +115,11 @@ 

    Source code for apptools.naming.pyfs_state_factory

    # context then we create and bind a reference to it. if obj.parent.path != context.path: state = Reference( - class_name = obj.__class__.__name__, - addresses = [Address(type='file', content=obj.path)] + class_name=obj.__class__.__name__, + addresses=[Address(type="file", content=obj.path)], ) return state
    - -### EOF #######################################################################
    @@ -135,13 +131,11 @@

    Source code for apptools.naming.pyfs_state_factory

    @@ -165,10 +159,10 @@

    Quick search

    © Copyright 2008-2020, Enthought
  • - Last updated on Jun 12, 2020. + Last updated on Dec 17, 2020.
  • - Created using Sphinx 1.8.5. + Created using Sphinx 2.3.1.
  • diff --git a/_modules/apptools/naming/reference.html b/_modules/apptools/naming/reference.html index f57ba249a..4e9f94dde 100644 --- a/_modules/apptools/naming/reference.html +++ b/_modules/apptools/naming/reference.html @@ -13,9 +13,11 @@ @@ -72,34 +74,30 @@
    -
    +

    Source code for apptools.naming.reference

    -#------------------------------------------------------------------------------
    -# Copyright (c) 2005, Enthought, Inc.
    +# (C) Copyright 2005-2020 Enthought, Inc., Austin, TX
     # All rights reserved.
     #
     # This software is provided without warranty under the terms of the BSD
    -# license included in enthought/LICENSE.txt and may be redistributed only
    -# under the conditions described in the aforementioned license.  The license
    +# license included in LICENSE.txt and may be redistributed only under
    +# the conditions described in the aforementioned license. The license
     # is also available online at http://www.enthought.com/licenses/BSD.txt
    -# Thanks for using Enthought open source!
     #
    -# Author: Enthought, Inc.
    -# Description: <Enthought naming package component>
    -#------------------------------------------------------------------------------
    +# Thanks for using Enthought open source!
     """ A reference to an object that lives outside of the naming system. """
     
     
     # Enthought library imports.
    -from traits.api import Any, HasPrivateTraits, List, Str
    +from traits.api import HasPrivateTraits, List, Str
     
     # Local imports.
     from .address import Address
     
     
     
    [docs]class Reference(HasPrivateTraits): - """ A reference to an object that lives outside of the naming system. + """A reference to an object that lives outside of the naming system. References provide a way to store the address(s) of objects that live outside of the naming system. A reference consists of a list of @@ -123,8 +121,6 @@

    Source code for apptools.naming.reference

     
         # The class name of the object factory.
         factory_class_name = Str
    - -#### EOF ######################################################################
    @@ -136,13 +132,11 @@

    Source code for apptools.naming.reference

                   
                 

    @@ -166,10 +160,10 @@

    Quick search

    © Copyright 2008-2020, Enthought
  • - Last updated on Jun 12, 2020. + Last updated on Dec 17, 2020.
  • - Created using Sphinx 1.8.5. + Created using Sphinx 2.3.1.
  • diff --git a/_modules/apptools/naming/referenceable.html b/_modules/apptools/naming/referenceable.html index d0094040a..4989cb547 100644 --- a/_modules/apptools/naming/referenceable.html +++ b/_modules/apptools/naming/referenceable.html @@ -13,9 +13,11 @@ @@ -72,22 +74,18 @@
    -
    +

    Source code for apptools.naming.referenceable

    -#------------------------------------------------------------------------------
    -# Copyright (c) 2005, Enthought, Inc.
    +# (C) Copyright 2005-2020 Enthought, Inc., Austin, TX
     # All rights reserved.
     #
     # This software is provided without warranty under the terms of the BSD
    -# license included in enthought/LICENSE.txt and may be redistributed only
    -# under the conditions described in the aforementioned license.  The license
    +# license included in LICENSE.txt and may be redistributed only under
    +# the conditions described in the aforementioned license. The license
     # is also available online at http://www.enthought.com/licenses/BSD.txt
    -# Thanks for using Enthought open source!
     #
    -# Author: Enthought, Inc.
    -# Description: <Enthought naming package component>
    -#------------------------------------------------------------------------------
    +# Thanks for using Enthought open source!
     """ Base class for classes that can produce a reference to themselves. """
     
     
    @@ -105,8 +103,6 @@ 

    Source code for apptools.naming.referenceable

    # The object's reference suitable for binding in a naming context. reference = Instance(Reference)
    - -#### EOF ######################################################################
    @@ -118,13 +114,11 @@

    Source code for apptools.naming.referenceable

    diff --git a/_modules/apptools/naming/referenceable_state_factory.html b/_modules/apptools/naming/referenceable_state_factory.html index fdeaab2f4..6735d1441 100644 --- a/_modules/apptools/naming/referenceable_state_factory.html +++ b/_modules/apptools/naming/referenceable_state_factory.html @@ -13,9 +13,11 @@ @@ -72,22 +74,18 @@
    -
    +

    Source code for apptools.naming.referenceable_state_factory

    -#------------------------------------------------------------------------------
    -# Copyright (c) 2005, Enthought, Inc.
    +# (C) Copyright 2005-2020 Enthought, Inc., Austin, TX
     # All rights reserved.
     #
     # This software is provided without warranty under the terms of the BSD
    -# license included in enthought/LICENSE.txt and may be redistributed only
    -# under the conditions described in the aforementioned license.  The license
    +# license included in LICENSE.txt and may be redistributed only under
    +# the conditions described in the aforementioned license. The license
     # is also available online at http://www.enthought.com/licenses/BSD.txt
    -# Thanks for using Enthought open source!
     #
    -# Author: Enthought, Inc.
    -# Description: <Enthought naming package component>
    -#------------------------------------------------------------------------------
    +# Thanks for using Enthought open source!
     """ State factory for referenceable objects. """
     
     
    @@ -114,8 +112,6 @@ 

    Source code for apptools.naming.referenceable_state_factory

    state = obj.reference return state
    - -### EOF #######################################################################
    @@ -127,13 +123,11 @@

    Source code for apptools.naming.referenceable_state_factory

    @@ -157,10 +151,10 @@

    Quick search

    © Copyright 2008-2020, Enthought
  • - Last updated on Jun 12, 2020. + Last updated on Dec 17, 2020.
  • - Created using Sphinx 1.8.5. + Created using Sphinx 2.3.1.
  • diff --git a/_modules/apptools/naming/state_factory.html b/_modules/apptools/naming/state_factory.html index 944e18555..6e858ad08 100644 --- a/_modules/apptools/naming/state_factory.html +++ b/_modules/apptools/naming/state_factory.html @@ -13,9 +13,11 @@ @@ -72,22 +74,18 @@
    -
    +

    Source code for apptools.naming.state_factory

    -#------------------------------------------------------------------------------
    -# Copyright (c) 2005, Enthought, Inc.
    +# (C) Copyright 2005-2020 Enthought, Inc., Austin, TX
     # All rights reserved.
     #
     # This software is provided without warranty under the terms of the BSD
    -# license included in enthought/LICENSE.txt and may be redistributed only
    -# under the conditions described in the aforementioned license.  The license
    +# license included in LICENSE.txt and may be redistributed only under
    +# the conditions described in the aforementioned license. The license
     # is also available online at http://www.enthought.com/licenses/BSD.txt
    -# Thanks for using Enthought open source!
     #
    -# Author: Enthought, Inc.
    -# Description: <Enthought naming package component>
    -#------------------------------------------------------------------------------
    +# Thanks for using Enthought open source!
     """ The base class for all state factories. """
     
     
    @@ -96,7 +94,7 @@ 

    Source code for apptools.naming.state_factory

    [docs]class StateFactory(HasPrivateTraits): - """ The base class for all state factories. + """The base class for all state factories. A state factory accepts an object and returns some data representing the object that is suitable for storing in a particular context. @@ -108,7 +106,7 @@

    Source code for apptools.naming.state_factory

    ###########################################################################
    [docs] def get_state_to_bind(self, obj, name, context): - """ Returns the state of an object for binding. + """Returns the state of an object for binding. Returns None if the factory cannot create the state (ie. it does not recognise the object passed to it). @@ -116,8 +114,6 @@

    Source code for apptools.naming.state_factory

    """ raise NotImplementedError
    - -### EOF #######################################################################
    @@ -129,13 +125,11 @@

    Source code for apptools.naming.state_factory

    diff --git a/_modules/apptools/naming/trait_defs/naming_traits.html b/_modules/apptools/naming/trait_defs/naming_traits.html index eee8de7e2..ad3cc1734 100644 --- a/_modules/apptools/naming/trait_defs/naming_traits.html +++ b/_modules/apptools/naming/trait_defs/naming_traits.html @@ -13,9 +13,11 @@ @@ -72,181 +74,180 @@
    -
    +

    Source code for apptools.naming.trait_defs.naming_traits

    -#-------------------------------------------------------------------------------
    +# (C) Copyright 2005-2020 Enthought, Inc., Austin, TX
    +# All rights reserved.
     #
    -#  Defines the NamingLog and NamingIndex traits
    +# This software is provided without warranty under the terms of the BSD
    +# license included in LICENSE.txt and may be redistributed only under
    +# the conditions described in the aforementioned license. The license
    +# is also available online at http://www.enthought.com/licenses/BSD.txt
     #
    -#  Written by: David C. Morrill
    -#
    -#  Date: 08/15/2005
    -#
    -#  (c) Copyright 2005 by Enthought, Inc.
    -#
    -#-------------------------------------------------------------------------------
    +# Thanks for using Enthought open source!
     
    -#-------------------------------------------------------------------------------
    +# -------------------------------------------------------------------------------
     #  Imports:
    -#-------------------------------------------------------------------------------
    +# -------------------------------------------------------------------------------
     
     import sys
     
    -import six
    +from traits.api import Trait, TraitHandler, TraitFactory
     
    -from traits.api \
    -    import Trait, TraitHandler, TraitFactory
    +from traits.trait_base import class_of, get_module_name
     
    -from traits.trait_base \
    -    import class_of, get_module_name
    +from apptools.naming.api import Binding
     
    -from traitsui.api \
    -    import DropEditor
     
    -from apptools.naming.api \
    -    import Binding
    +# -------------------------------------------------------------------------------
    +#  'NamingInstance' trait factory:
    +# -------------------------------------------------------------------------------
     
     
    -#-------------------------------------------------------------------------------
    -#  'NamingInstance' trait factory:
    -#-------------------------------------------------------------------------------
    +def NamingInstance(klass=None, value="", allow_none=False, **metadata):
    +    metadata.setdefault("copy", "deep")
    +    return Trait(
    +        value,
    +        NamingTraitHandler(
    +            klass, or_none=allow_none, module=get_module_name()
    +        ),
    +        **metadata
    +    )
     
    -def NamingInstance ( klass = None, value = '', allow_none = False, **metadata ):
    -    metadata.setdefault( 'copy', 'deep' )
    -    return Trait( value, NamingTraitHandler( klass, or_none = allow_none,
    -                  module = get_module_name() ), **metadata )
     
    -NamingInstance = TraitFactory( NamingInstance )
    +NamingInstance = TraitFactory(NamingInstance)
     
    -#-------------------------------------------------------------------------------
    +# -------------------------------------------------------------------------------
     #  'NamingTraitHandler' class:
    -#-------------------------------------------------------------------------------
    +# -------------------------------------------------------------------------------
    +
     
    -
    [docs]class NamingTraitHandler ( TraitHandler ): +
    [docs]class NamingTraitHandler(TraitHandler): - #--------------------------------------------------------------------------- + # --------------------------------------------------------------------------- # Initializes the object: - #--------------------------------------------------------------------------- - - def __init__ ( self, aClass, or_none, module ): - """ Initializes the object. - """ - self.or_none = (or_none != False) - self.module = module - self.aClass = aClass - if (aClass is not None) \ - and (not isinstance( aClass, ( six.string_types, type ) )): + # --------------------------------------------------------------------------- + + def __init__(self, aClass, or_none, module): + """Initializes the object.""" + self.or_none = or_none is not False + self.module = module + self.aClass = aClass + if (aClass is not None) and ( + not isinstance(aClass, (str, type)) + ): self.aClass = aClass.__class__ -
    [docs] def validate ( self, object, name, value ): - if isinstance( value, six.string_types ): - if value == '': +
    [docs] def validate(self, object, name, value): + if isinstance(value, str): + if value == "": if self.or_none: - return '' + return "" else: - self.validate_failed( object, name, value ) + self.validate_failed(object, name, value) try: - value = self._get_binding_for( value ) - except: - self.validate_failed( object, name, value ) + value = self._get_binding_for(value) + except: # noqa: E722 + self.validate_failed(object, name, value) - if isinstance(self.aClass, six.string_types): - self.resolve_class( object, name, value ) + if isinstance(self.aClass, str): + self.resolve_class(object, name, value) - if (isinstance( value, Binding ) and - ((self.aClass is None) or isinstance( value.obj, self.aClass ))): + if isinstance(value, Binding) and ( + (self.aClass is None) or isinstance(value.obj, self.aClass) + ): return value.namespace_name - self.validate_failed( object, name, value )
    + self.validate_failed(object, name, value)
    -
    [docs] def info ( self ): +
    [docs] def info(self): aClass = self.aClass if aClass is None: - result = 'path' + result = "path" else: - if type( aClass ) is not str: + if type(aClass) is not str: aClass = aClass.__name__ - result = 'path to an instance of ' + class_of( aClass ) + result = "path to an instance of " + class_of(aClass) if self.or_none is None: - return result + ' or an empty string' + return result + " or an empty string" return result
    -
    [docs] def validate_failed ( self, object, name, value ): - if not isinstance( value, type ): - msg = 'class %s' % value.__class__.__name__ +
    [docs] def validate_failed(self, object, name, value): + if not isinstance(value, type): + msg = "class %s" % value.__class__.__name__ else: - msg = '%s (i.e. %s)' % ( str( type( value ) )[1:-1], repr( value ) ) - self.error( object, name, msg )
    + msg = "%s (i.e. %s)" % (str(type(value))[1:-1], repr(value)) + self.error(object, name, msg)
    -
    [docs] def get_editor ( self, trait ): +
    [docs] def get_editor(self, trait): if self.editor is None: from traitsui.api import DropEditor - self.editor = DropEditor( klass = self.aClass, - binding = True, - readonly = False ) + self.editor = DropEditor( + klass=self.aClass, binding=True, readonly=False + ) return self.editor
    -
    [docs] def post_setattr ( self, object, name, value ): +
    [docs] def post_setattr(self, object, name, value): other = None - if value != '': - other = self._get_binding_for( value ).obj - object.__dict__[ name + '_' ] = other
    + if value != "": + other = self._get_binding_for(value).obj + object.__dict__[name + "_"] = other
    - def _get_binding_for ( self, value ): + def _get_binding_for(self, value): result = None - # FIXME: The following code makes this whole component have a dependency - # on envisage, and worse, assumes the use of a particular project - # plugin! This is horrible and should be refactored out, possibly to - # a custom sub-class of whoever needs this behavior. + # FIXME: The following code makes this whole component have a + # dependency on envisage, and worse, assumes the use of a particular + # project plugin! This is horrible and should be refactored out, + # possibly to a custom sub-class of whoever needs this behavior. try: from envisage import get_application + workspace = get_application().service_registry.get_service( - 'envisage.project.IWorkspace' ) - result = workspace.lookup_binding( value ) + "envisage.project.IWorkspace" + ) + result = workspace.lookup_binding(value) except ImportError: pass return result - -
    [docs] def resolve_class ( self, object, name, value ): +
    [docs] def resolve_class(self, object, name, value): aClass = self.find_class() if aClass is None: - self.validate_failed( object, name, value ) + self.validate_failed(object, name, value) self.aClass = aClass # fixme: The following is quite ugly, because it wants to try and fix - # the trait referencing this handler to use the 'fast path' now that the - # actual class has been resolved. The problem is finding the trait, + # the trait referencing this handler to use the 'fast path' now that + # the actual class has been resolved. The problem is finding the trait, # especially in the case of List(Instance('foo')), where the # object.base_trait(...) value is the List trait, not the Instance # trait, so we need to check for this and pull out the List # 'item_trait'. Obviously this does not extend well to other traits # containing nested trait references (Dict?)... - trait = object.base_trait( name ) + trait = object.base_trait(name) handler = trait.handler - if (handler is not self) and hasattr( handler, 'item_trait' ): + if (handler is not self) and hasattr(handler, "item_trait"): trait = handler.item_trait - trait.validate( self.fast_validate )
    + trait.validate(self.fast_validate)
    -
    [docs] def find_class ( self ): +
    [docs] def find_class(self): module = self.module aClass = self.aClass - col = aClass.rfind( '.' ) + col = aClass.rfind(".") if col >= 0: - module = aClass[ : col ] - aClass = aClass[ col + 1: ] - theClass = getattr( sys.modules.get( module ), aClass, None ) + module = aClass[:col] + aClass = aClass[col + 1:] + theClass = getattr(sys.modules.get(module), aClass, None) if (theClass is None) and (col >= 0): try: - theClass = getattr( __import__( module ), aClass, None ) - except: + theClass = getattr(__import__(module), aClass, None) + except Exception: pass return theClass
    -
    @@ -258,13 +259,11 @@

    Source code for apptools.naming.trait_defs.naming_traits

    @@ -288,10 +287,10 @@

    Quick search

    © Copyright 2008-2020, Enthought
  • - Last updated on Jun 12, 2020. + Last updated on Dec 17, 2020.
  • - Created using Sphinx 1.8.5. + Created using Sphinx 2.3.1.
  • diff --git a/_modules/apptools/naming/unique_name.html b/_modules/apptools/naming/unique_name.html index 905803230..e33f1657a 100644 --- a/_modules/apptools/naming/unique_name.html +++ b/_modules/apptools/naming/unique_name.html @@ -13,9 +13,11 @@ @@ -72,15 +74,18 @@
    -
    +

    Source code for apptools.naming.unique_name

    -#-----------------------------------------------------------------------------
    +# (C) Copyright 2005-2020 Enthought, Inc., Austin, TX
    +# All rights reserved.
     #
    -#  Copyright (c) 2007 by Enthought, Inc.
    -#  All rights reserved.
    +# This software is provided without warranty under the terms of the BSD
    +# license included in LICENSE.txt and may be redistributed only under
    +# the conditions described in the aforementioned license. The license
    +# is also available online at http://www.enthought.com/licenses/BSD.txt
     #
    -#-----------------------------------------------------------------------------
    +# Thanks for using Enthought open source!
     
     
     """
    @@ -89,6 +94,7 @@ 

    Source code for apptools.naming.unique_name

     
     """
     
    +
     
    [docs]def make_unique_name(base, existing=[], format="%s_%s"): """ Return a name, unique within a context, based on the specified name. @@ -106,10 +112,6 @@

    Source code for apptools.naming.unique_name

             count += 1
     
         return name
    - - -#### EOF #################################################################### -
    @@ -121,13 +123,11 @@

    Source code for apptools.naming.unique_name

                   
                 

    @@ -151,10 +151,10 @@

    Quick search

    © Copyright 2008-2020, Enthought
  • - Last updated on Jun 12, 2020. + Last updated on Dec 17, 2020.
  • - Created using Sphinx 1.8.5. + Created using Sphinx 2.3.1.
  • diff --git a/_modules/apptools/persistence/file_path.html b/_modules/apptools/persistence/file_path.html index 5f54eeb01..2391cf819 100644 --- a/_modules/apptools/persistence/file_path.html +++ b/_modules/apptools/persistence/file_path.html @@ -13,9 +13,11 @@ @@ -72,20 +74,26 @@
    -
    +

    Source code for apptools.persistence.file_path

    -"""Simple class to support file path objects that work well in the
    +# (C) Copyright 2005-2020 Enthought, Inc., Austin, TX
    +# All rights reserved.
    +#
    +# This software is provided without warranty under the terms of the BSD
    +# license included in LICENSE.txt and may be redistributed only under
    +# the conditions described in the aforementioned license. The license
    +# is also available online at http://www.enthought.com/licenses/BSD.txt
    +#
    +# Thanks for using Enthought open source!
    +"""Simple class to support file path objects that work well in the
     context of persistent storage with the state_pickler.
     
     """
    -# Author: Prabhu Ramachandran <prabhu_r@users.sf.net>
    -# Copyright (c) 2005, Enthought, Inc.
    -# License: BSD Style.
     
     # Standard library imports.
     import os
    -from os.path import abspath, normpath, dirname, commonprefix, join
    +from os.path import abspath, normpath, dirname, join
     
     
     
    [docs]class FilePath(object): @@ -96,7 +104,8 @@

    Source code for apptools.persistence.file_path

    stored relative path is used to set the absolute path correctly based on the path of the saved file. """ - def __init__(self, value=''): + + def __init__(self, value=""): self.set(value) def __str__(self): @@ -106,18 +115,16 @@

    Source code for apptools.persistence.file_path

    return self.abs_pth.__repr__()

    [docs] def get(self): - """Get the path. - """ + """Get the path.""" return self.abs_pth
    [docs] def set(self, value): - """Sets the value of the path. - """ + """Sets the value of the path.""" self.rel_pth = value if value: self.abs_pth = normpath(abspath(value)) else: - self.abs_pth = ''
    + self.abs_pth = ""
    [docs] def set_relative(self, base_f_name): """Sets the path relative to `base_f_name`. Note that @@ -132,7 +139,7 @@

    Source code for apptools.persistence.file_path

    # Now strip out any common prefix between the two paths. for part in _src.split(os.sep): - if _dst.startswith(part+os.sep): + if _dst.startswith(part + os.sep): length = len(part) + 1 _src = _src[length:] _dst = _dst[length:] @@ -141,11 +148,11 @@

    Source code for apptools.persistence.file_path

    # For each directory in the source, we need to add a reference to # the parent directory to the destination. - ret = (_src.count(os.sep) * ('..' + os.sep)) + _dst + ret = (_src.count(os.sep) * (".." + os.sep)) + _dst # Make it posix style. - if os.sep != '/': - ret.replace(os.sep, '/') + if os.sep != "/": + ret.replace(os.sep, "/") # Store it. self.rel_pth = ret

    @@ -159,7 +166,6 @@

    Source code for apptools.persistence.file_path

    file_name = join(dirname(base_f_name), rel_file_name) file_name = os.path.normpath(file_name) self.abs_pth = file_name

    -
    @@ -171,13 +177,11 @@

    Source code for apptools.persistence.file_path

    @@ -201,10 +205,10 @@

    Quick search

    © Copyright 2008-2020, Enthought
  • - Last updated on Jun 12, 2020. + Last updated on Dec 17, 2020.
  • - Created using Sphinx 1.8.5. + Created using Sphinx 2.3.1.
  • diff --git a/_modules/apptools/persistence/project_loader.html b/_modules/apptools/persistence/project_loader.html index 336220782..75559d5eb 100644 --- a/_modules/apptools/persistence/project_loader.html +++ b/_modules/apptools/persistence/project_loader.html @@ -13,9 +13,11 @@ @@ -72,10 +74,18 @@
    -
    +

    Source code for apptools.persistence.project_loader

    -
    +# (C) Copyright 2005-2020 Enthought, Inc., Austin, TX
    +# All rights reserved.
    +#
    +# This software is provided without warranty under the terms of the BSD
    +# license included in LICENSE.txt and may be redistributed only under
    +# the conditions described in the aforementioned license. The license
    +# is also available online at http://www.enthought.com/licenses/BSD.txt
    +#
    +# Thanks for using Enthought open source!
     # Standard library imports
     import sys
     import pickle
    @@ -88,44 +98,58 @@ 

    Source code for apptools.persistence.project_loader

    logger = logging.getLogger(__name__) -
    [docs]def load_project(pickle_filename, updater_path, application_version, protocol, - max_pass=-1): - """ Reads a project from a pickle file and if necessary will update it to +
    [docs]def load_project( + pickle_filename, updater_path, application_version, protocol, max_pass=-1 +): + """Reads a project from a pickle file and if necessary will update it to the latest version of the application. """ latest_file = pickle_filename # Read the pickled project's metadata. - f = open(latest_file, 'rb') + f = open(latest_file, "rb") metadata = VersionedUnpickler(f).load(max_pass) f.close() - project_version = metadata.get('version', False) + project_version = metadata.get("version", False) if not project_version: raise ValueError("Could not read version number from the project file") - logger.debug('Project version: %d, Application version: %d' % - (project_version, application_version)) + logger.debug( + "Project version: %d, Application version: %d" + % (project_version, application_version) + ) # here you can temporarily force an upgrade each time for testing .... # project_version = 0 - latest_file = upgrade_project(pickle_filename, updater_path, - project_version, application_version, protocol, - max_pass) + latest_file = upgrade_project( + pickle_filename, + updater_path, + project_version, + application_version, + protocol, + max_pass, + ) # Finally we can import the project ... - logger.info('loading %s' % latest_file) - i_f = open(latest_file, 'rb') - version = VersionedUnpickler(i_f).load(max_pass) + logger.info("loading %s" % latest_file) + i_f = open(latest_file, "rb") project = VersionedUnpickler(i_f).load(max_pass) i_f.close() return project
    -
    [docs]def upgrade_project(pickle_filename, updater_path, project_version, application_version, protocol, max_pass=-1): - """ Repeatedly read and write the project to disk updating it one version +
    [docs]def upgrade_project( + pickle_filename, + updater_path, + project_version, + application_version, + protocol, + max_pass=-1, +): + """Repeatedly read and write the project to disk updating it one version at a time. Example the p5.project is at version 0 @@ -147,37 +171,36 @@

    Source code for apptools.persistence.project_loader

    next_version = project_version + 1 if first_time: - i_f = open(pickle_filename, 'rb') + i_f = open(pickle_filename, "rb") data = i_f.read() - open('%s.bak' % pickle_filename, 'wb').write(data) - i_f.seek(0) # rewind the file to the start + open("%s.bak" % pickle_filename, "wb").write(data) + i_f.seek(0) # rewind the file to the start else: - name = '%s.v%d' % (pickle_filename, project_version) - i_f = open(name, 'rb') + name = "%s.v%d" % (pickle_filename, project_version) + i_f = open(name, "rb") latest_file = name - logger.info('converting %s' % latest_file) + logger.info("converting %s" % latest_file) # find this version's updater ... - updater_name = '%s.update%d' % (updater_path, next_version) + updater_name = "%s.update%d" % (updater_path, next_version) __import__(updater_name) mod = sys.modules[updater_name] - klass = getattr(mod, 'Update%d' % next_version) + klass = getattr(mod, "Update%d" % next_version) updater = klass() # load and update this version of the project - version = VersionedUnpickler(i_f).load(max_pass) project = VersionedUnpickler(i_f, updater).load(max_pass) i_f.close() # set the project version to be the same as the updater we just # ran on the unpickled files ... - project.metadata['version'] = next_version + project.metadata["version"] = next_version # Persist the updated project ... - name = '%s.v%d' % (pickle_filename, next_version) + name = "%s.v%d" % (pickle_filename, next_version) latest_file = name - o_f = open(name, 'wb') + o_f = open(name, "wb") pickle.dump(project.metadata, o_f, protocol=protocol) pickle.dump(project, o_f, protocol=protocol) o_f.close() @@ -187,10 +210,6 @@

    Source code for apptools.persistence.project_loader

    first_time = False return latest_file
    - - -### EOF ################################################################# -
    @@ -202,13 +221,11 @@

    Source code for apptools.persistence.project_loader

    @@ -232,10 +249,10 @@

    Quick search

    © Copyright 2008-2020, Enthought
  • - Last updated on Jun 12, 2020. + Last updated on Dec 17, 2020.
  • - Created using Sphinx 1.8.5. + Created using Sphinx 2.3.1.
  • diff --git a/_modules/apptools/persistence/state_pickler.html b/_modules/apptools/persistence/state_pickler.html index a1ece00ba..21a0effe1 100644 --- a/_modules/apptools/persistence/state_pickler.html +++ b/_modules/apptools/persistence/state_pickler.html @@ -13,9 +13,11 @@ @@ -72,10 +74,19 @@
    -
    +

    Source code for apptools.persistence.state_pickler

    -"""This module provides code that allows one to pickle the state of a
    +# (C) Copyright 2005-2020 Enthought, Inc., Austin, TX
    +# All rights reserved.
    +#
    +# This software is provided without warranty under the terms of the BSD
    +# license included in LICENSE.txt and may be redistributed only under
    +# the conditions described in the aforementioned license. The license
    +# is also available online at http://www.enthought.com/licenses/BSD.txt
    +#
    +# Thanks for using Enthought open source!
    +"""This module provides code that allows one to pickle the state of a
     Python object to a dictionary.
     
     The motivation for this is simple.  The standard Python
    @@ -177,7 +188,6 @@ 

    Source code for apptools.persistence.state_pickler

    # Standard library imports. import base64 import sys -import types import pickle import gzip from io import BytesIO, StringIO @@ -188,15 +198,13 @@

    Source code for apptools.persistence.state_pickler

    from . import version_registry from .file_path import FilePath -PY_VER = sys.version_info[0] NumpyArrayType = type(numpy.array([]))
    [docs]def gzip_string(data): - """Given a string (`data`) this gzips the string and returns it. - """ + """Given a string (`data`) this gzips the string and returns it.""" s = BytesIO() - writer = gzip.GzipFile(mode='wb', fileobj=s) + writer = gzip.GzipFile(mode="wb", fileobj=s) writer.write(data) writer.close() s.seek(0) @@ -207,24 +215,28 @@

    Source code for apptools.persistence.state_pickler

    """Given a gzipped string (`data`) this unzips the string and returns it. """ - if PY_VER== 2 or (bytes is not str and type(data) is bytes): + if type(data) is bytes: s = BytesIO(data) else: s = StringIO(data) - writer = gzip.GzipFile(mode='rb', fileobj=s) + writer = gzip.GzipFile(mode="rb", fileobj=s) data = writer.read() writer.close() return data
    +
    [docs]class StatePicklerError(Exception): pass
    +
    [docs]class StateUnpicklerError(Exception): pass
    +
    [docs]class StateSetterError(Exception): pass
    + ###################################################################### # `State` class ###################################################################### @@ -234,10 +246,12 @@

    Source code for apptools.persistence.state_pickler

    that has class specific details like the class name, module name etc. """ + def __init__(self, **kw): dict.__init__(self, **kw) self.__dict__ = self
    + ###################################################################### # `StateDict` class ###################################################################### @@ -246,10 +260,12 @@

    Source code for apptools.persistence.state_pickler

    The has_instance attribute specifies if the dict has an instance embedded in it. """ + def __init__(self, **kw): dict.__init__(self, **kw) self.has_instance = False
    + ###################################################################### # `StateList` class ###################################################################### @@ -258,6 +274,7 @@

    Source code for apptools.persistence.state_pickler

    has_instance attribute specifies if the list has an instance embedded in it. """ + def __init__(self, seq=None): if seq: list.__init__(self, seq) @@ -265,6 +282,7 @@

    Source code for apptools.persistence.state_pickler

    list.__init__(self) self.has_instance = False
    + ###################################################################### # `StateTuple` class ###################################################################### @@ -273,6 +291,7 @@

    Source code for apptools.persistence.state_pickler

    has_instance attribute specifies if the tuple has an instance embedded in it. """ + def __new__(cls, seq=None): if seq: obj = super(StateTuple, cls).__new__(cls, tuple(seq)) @@ -292,7 +311,7 @@

    Source code for apptools.persistence.state_pickler

    will return the dictionary that is pickled. The format of the state dict is quite strightfoward. Basic types - (bool, int, long, float, complex, None, string and unicode) are + (bool, int, long, float, complex, None, string) are represented as they are. Everything else is stored as a dictionary containing metadata information on the object's type etc. and also the actual object in the 'data' key. For example:: @@ -330,24 +349,23 @@

    Source code for apptools.persistence.state_pickler

    can be pickled and are stored as a gzipped base64 encoded string. """ + def __init__(self): self._clear() - type_map = {bool: self._do_basic_type, - complex: self._do_basic_type, - float: self._do_basic_type, - int: self._do_basic_type, - type(None): self._do_basic_type, - str: self._do_basic_type, - bytes: self._do_basic_type, - tuple: self._do_tuple, - list: self._do_list, - dict: self._do_dict, - NumpyArrayType: self._do_numeric, - State: self._do_state, - } - if PY_VER == 2: - type_map[long] = self._do_basic_type - type_map[unicode] = self._do_basic_type + type_map = { + bool: self._do_basic_type, + complex: self._do_basic_type, + float: self._do_basic_type, + int: self._do_basic_type, + type(None): self._do_basic_type, + str: self._do_basic_type, + bytes: self._do_basic_type, + tuple: self._do_tuple, + list: self._do_list, + dict: self._do_dict, + NumpyArrayType: self._do_numeric, + State: self._do_state, + } self.type_map = type_map
    [docs] def dump(self, value, file): @@ -383,7 +401,7 @@

    Source code for apptools.persistence.state_pickler

    # Stores the file name of the file being used to dump the # state. This is used to change any embedded paths relative # to the saved file. - self.file_name = '' + self.file_name = "" # Caches id's to handle references. self.obj_cache = {} # Misc cache to cache things that are not persistent. For @@ -398,7 +416,6 @@

    Source code for apptools.persistence.state_pickler

    are set in the `__dict__` so we can pickle it. """ # Not needed with Traits3. - return def _do(self, obj): obj_type = type(obj) @@ -416,7 +433,7 @@

    Source code for apptools.persistence.state_pickler

    elif isinstance(obj, dict): # Takes care of TraitDictObjects. return self._do_dict(obj) - elif hasattr(obj, '__dict__'): + elif hasattr(obj, "__dict__"): return self._do_instance(obj) def _get_id(self, value): @@ -439,7 +456,7 @@

    Source code for apptools.persistence.state_pickler

    def _do_reference(self, value): key = self._get_id(value) idx = self.obj_cache[key] - return dict(type='reference', id=idx, data=None) + return dict(type="reference", id=idx, data=None) def _do_instance(self, value): # Flush out the traits. @@ -451,18 +468,18 @@

    Source code for apptools.persistence.state_pickler

    # Get the initargs. args = () - if hasattr(value, '__getinitargs__') and value.__getinitargs__: + if hasattr(value, "__getinitargs__") and value.__getinitargs__: args = value.__getinitargs__() # Get the object state. - if hasattr(value, '__get_pure_state__'): + if hasattr(value, "__get_pure_state__"): state = value.__get_pure_state__() - elif hasattr(value, '__getstate__'): + elif hasattr(value, "__getstate__"): state = value.__getstate__() else: state = value.__dict__ - state.pop('__traits_version__', None) + state.pop("__traits_version__", None) # Cache the args and state since they are likely to be gc'd. self._misc_cache.extend([args, state]) @@ -476,19 +493,21 @@

    Source code for apptools.persistence.state_pickler

    module = value.__class__.__module__ class_name = value.__class__.__name__ - return dict(type='instance', - module=module, - class_name=class_name, - version=version, - id=idx, - initargs=args_data, - data=data) + return dict( + type="instance", + module=module, + class_name=class_name, + version=version, + id=idx, + initargs=args_data, + data=data, + ) def _do_state(self, value): metadata = value.__metadata__ - args = metadata.get('initargs') + args = metadata.get("initargs") state = dict(value) - state.pop('__metadata__') + state.pop("__metadata__") self._misc_cache.extend([args, state]) @@ -496,38 +515,36 @@

    Source code for apptools.persistence.state_pickler

    args_data = self._do(args) data = self._do(state) - return dict(type='instance', - module=metadata['module'], - class_name=metadata['class_name'], - version=metadata['version'], - id=idx, - initargs=args_data, - data=data) + return dict( + type="instance", + module=metadata["module"], + class_name=metadata["class_name"], + version=metadata["version"], + id=idx, + initargs=args_data, + data=data, + ) def _do_tuple(self, value): idx = self._register(value) data = tuple([self._do(x) for x in value]) - return dict(type='tuple', id=idx, data=data) + return dict(type="tuple", id=idx, data=data) def _do_list(self, value): idx = self._register(value) data = [self._do(x) for x in value] - return dict(type='list', id=idx, data=data) + return dict(type="list", id=idx, data=data) def _do_dict(self, value): idx = self._register(value) vals = [self._do(x) for x in value.values()] data = dict(zip(value.keys(), vals)) - return dict(type='dict', id=idx, data=data) + return dict(type="dict", id=idx, data=data) def _do_numeric(self, value): idx = self._register(value) - if PY_VER > 2: - data = base64.encodebytes(gzip_string(numpy.ndarray.dumps(value))) - else: - data = base64.encodestring(gzip_string(numpy.ndarray.dumps(value))) - return dict(type='numeric', id=idx, data=data)
    - + data = base64.encodebytes(gzip_string(numpy.ndarray.dumps(value))) + return dict(type="numeric", id=idx, data=data)
    ###################################################################### @@ -573,13 +590,14 @@

    Source code for apptools.persistence.state_pickler

    def __init__(self): self._clear() - self.type_map = {'reference': self._do_reference, - 'instance': self._do_instance, - 'tuple': self._do_tuple, - 'list': self._do_list, - 'dict': self._do_dict, - 'numeric': self._do_numeric, - } + self.type_map = { + "reference": self._do_reference, + "instance": self._do_instance, + "tuple": self._do_tuple, + "list": self._do_list, + "dict": self._do_dict, + "numeric": self._do_numeric, + }
    [docs] def load_state(self, file): """Returns the state of an object loaded from the pickled data @@ -606,7 +624,7 @@

    Source code for apptools.persistence.state_pickler

    ###################################################################### def _clear(self): # The file from which we are being loaded. - self.file_name = '' + self.file_name = "" # Cache of the objects. self._obj_cache = {} # Paths to the instances. @@ -618,7 +636,7 @@

    Source code for apptools.persistence.state_pickler

    def _set_has_instance(self, obj, value): if isinstance(obj, State): - obj.__metadata__['has_instance'] = value + obj.__metadata__["has_instance"] = value elif isinstance(obj, (StateDict, StateList, StateTuple)): obj.has_instance = value @@ -630,10 +648,10 @@

    Source code for apptools.persistence.state_pickler

    for key, (path, val) in self._numeric.items(): if isinstance(result, StateTuple): result = list(result) - exec('result%s = val'%path) + exec("result%s = val" % path) result = StateTuple(result) else: - exec('result%s = val'%path) + exec("result%s = val" % path) # Setup the references so they really are references. for key, paths in self._refs.items(): @@ -641,10 +659,10 @@

    Source code for apptools.persistence.state_pickler

    x = self._obj_cache[key] if isinstance(result, StateTuple): result = list(result) - exec('result%s = x'%path) + exec("result%s = x" % path) result = StateTuple(result) else: - exec('result%s = x'%path) + exec("result%s = x" % path) # if the reference is to an instance append its path. if isinstance(x, State): self._instances.append(path) @@ -655,23 +673,23 @@

    Source code for apptools.persistence.state_pickler

    for path in self._instances: pth = path while pth: - ns = {'result': result} - exec('val = result%s'%pth, ns, ns) - self._set_has_instance(ns['val'], True) - end = pth.rfind('[') + ns = {"result": result} + exec("val = result%s" % pth, ns, ns) + self._set_has_instance(ns["val"], True) + end = pth.rfind("[") pth = pth[:end] # Now make sure that the first element also has_instance. self._set_has_instance(result, True) return result - def _do(self, data, path=''): + def _do(self, data, path=""): if type(data) is dict: - return self.type_map[data['type']](data, path) + return self.type_map[data["type"]](data, path) else: return data def _do_reference(self, value, path): - id = value['id'] + id = value["id"] if id in self._refs: self._refs[id].append(path) else: @@ -679,68 +697,69 @@

    Source code for apptools.persistence.state_pickler

    return State(__metadata__=value) def _handle_file_path(self, value): - if (value['class_name'] == 'FilePath') and \ - ('file_path' in value['module']) and \ - self.file_name: - data = value['data']['data'] - fp = FilePath(data['rel_pth']) + if ( + (value["class_name"] == "FilePath") + and ("file_path" in value["module"]) + and self.file_name + ): + data = value["data"]["data"] + fp = FilePath(data["rel_pth"]) fp.set_absolute(self.file_name) - data['abs_pth'] = fp.abs_pth + data["abs_pth"] = fp.abs_pth def _do_instance(self, value, path): self._instances.append(path) - initargs = self._do(value['initargs'], - path + '.__metadata__["initargs"]') + initargs = self._do( + value["initargs"], path + '.__metadata__["initargs"]' + ) # Handle FilePaths. self._handle_file_path(value) - d = self._do(value['data'], path) - md = dict(type='instance', - module=value['module'], - class_name=value['class_name'], - version=value['version'], - id=value['id'], - initargs=initargs, - has_instance=True) + d = self._do(value["data"], path) + md = dict( + type="instance", + module=value["module"], + class_name=value["class_name"], + version=value["version"], + id=value["id"], + initargs=initargs, + has_instance=True, + ) result = State(**d) result.__metadata__ = md - self._obj_cache[value['id']] = result + self._obj_cache[value["id"]] = result return result def _do_tuple(self, value, path): res = [] - for i, x in enumerate(value['data']): - res.append(self._do(x, path + '[%d]'%i)) + for i, x in enumerate(value["data"]): + res.append(self._do(x, path + "[%d]" % i)) result = StateTuple(res) - self._obj_cache[value['id']] = result + self._obj_cache[value["id"]] = result return result def _do_list(self, value, path): result = StateList() - for i, x in enumerate(value['data']): - result.append(self._do(x, path + '[%d]'%i)) - self._obj_cache[value['id']] = result + for i, x in enumerate(value["data"]): + result.append(self._do(x, path + "[%d]" % i)) + self._obj_cache[value["id"]] = result return result def _do_dict(self, value, path): result = StateDict() - for key, val in value['data'].items(): - result[key] = self._do(val, path + '["%s"]'%key) - self._obj_cache[value['id']] = result + for key, val in value["data"].items(): + result[key] = self._do(val, path + '["%s"]' % key) + self._obj_cache[value["id"]] = result return result def _do_numeric(self, value, path): - if PY_VER > 2: - data = value['data'] - if isinstance(data, str): - data = value['data'].encode('utf-8') - junk = gunzip_string(base64.decodebytes(data)) - result = pickle.loads(junk, encoding='bytes') - else: - junk = gunzip_string(value['data'].decode('base64')) - result = pickle.loads(junk) - self._numeric[value['id']] = (path, result) - self._obj_cache[value['id']] = result + data = value["data"] + if isinstance(data, str): + data = value["data"].encode("utf-8") + junk = gunzip_string(base64.decodebytes(data)) + result = pickle.loads(junk, encoding="bytes") + self._numeric[value["id"]] = (path, result) + self._obj_cache[value["id"]] = result return result
    @@ -753,14 +772,16 @@

    Source code for apptools.persistence.state_pickler

    checks to see if a `__set_pure_state__` method exists and calls that when it sets the state. """ + def __init__(self): # Stores the ids of instances already done. self._instance_ids = [] - self.type_map = {State: self._do_instance, - StateTuple: self._do_tuple, - StateList: self._do_list, - StateDict: self._do_dict, - } + self.type_map = { + State: self._do_instance, + StateTuple: self._do_tuple, + StateList: self._do_list, + StateDict: self._do_dict, + }
    [docs] def set(self, obj, state, ignore=None, first=None, last=None): """Sets the state of the object. @@ -803,10 +824,11 @@

    Source code for apptools.persistence.state_pickler

    order), after all other attributes are set. """ - if (not isinstance(state, State)) and \ - state.__metadata__['type'] != 'instance': + if (not isinstance(state, State)) and state.__metadata__[ + "type" + ] != "instance": raise StateSetterError( - 'Can only set the attributes of an instance.' + "Can only set the attributes of an instance." ) # Upgrade the state to the latest using the registry. @@ -817,7 +839,7 @@

    Source code for apptools.persistence.state_pickler

    # This wierdness is needed since the state's own `keys` might # be set to something else. state_keys = list(dict.keys(state)) - state_keys.remove('__metadata__') + state_keys.remove("__metadata__") if first is None: first = [] @@ -826,7 +848,7 @@

    Source code for apptools.persistence.state_pickler

    # Remove all the ignored keys. if ignore: - if '*' in ignore: + if "*" in ignore: state_keys = first + last else: for name in ignore: @@ -861,7 +883,7 @@

    Source code for apptools.persistence.state_pickler

    self._instance_ids.append(idx) def _is_registered(self, obj): - return (id(obj) in self._instance_ids) + return id(obj) in self._instance_ids def _has_instance(self, value): """Given something (`value`) that is part of the state this @@ -879,9 +901,7 @@

    Source code for apptools.persistence.state_pickler

    """ result = value if self._has_instance(value): - raise StateSetterError( - 'Value has an instance: %s'%value - ) + raise StateSetterError("Value has an instance: %s" % value) if isinstance(value, (StateList, StateTuple)): result = [self._get_pure(x) for x in value] if isinstance(value, StateTuple): @@ -904,23 +924,23 @@

    Source code for apptools.persistence.state_pickler

    # Make sure object and state have the same class and module names. metadata = state.__metadata__ cls = obj.__class__ - if (metadata['class_name'] != cls.__name__): + if metadata["class_name"] != cls.__name__: raise StateSetterError( - 'Instance (%s) and state (%s) do not have the same class'\ - ' name!'%(cls.__name__, metadata['class_name']) + "Instance (%s) and state (%s) do not have the same class" + " name!" % (cls.__name__, metadata["class_name"]) ) - if (metadata['module'] != cls.__module__): + if metadata["module"] != cls.__module__: raise StateSetterError( - 'Instance (%s) and state (%s) do not have the same module'\ - ' name!'%(cls.__module__, metadata['module']) + "Instance (%s) and state (%s) do not have the same module" + " name!" % (cls.__module__, metadata["module"]) ) def _do(self, obj, key, value): try: - attr = getattr(obj, key) + getattr(obj, key) except AttributeError: raise StateSetterError( - 'Object %s does not have an attribute called: %s'%(obj, key) + "Object %s does not have an attribute called: %s" % (obj, key) ) if isinstance(value, (State, StateDict, StateList, StateTuple)): @@ -945,13 +965,13 @@

    Source code for apptools.persistence.state_pickler

    self._register(obj) metadata = state.__metadata__ - if hasattr(obj, '__set_pure_state__'): + if hasattr(obj, "__set_pure_state__"): self._update_and_check_state(obj, state) obj.__set_pure_state__(state) - elif 'tvtk_classes' in metadata['module']: + elif "tvtk_classes" in metadata["module"]: self._update_and_check_state(obj, state) tmp = self._get_pure(StateDict(**state)) - del tmp['__metadata__'] + del tmp["__metadata__"] obj.__setstate__(tmp) else: # No need to update or check since `set` does it for us. @@ -976,7 +996,7 @@

    Source code for apptools.persistence.state_pickler

    self._do_object(obj[i], state[i]) else: raise StateSetterError( - 'Cannot set state of list of incorrect size.' + "Cannot set state of list of incorrect size." ) def _do_dict(self, obj, state): @@ -993,16 +1013,17 @@

    Source code for apptools.persistence.state_pickler

    # Internal Utility functions. ###################################################################### def _get_file_read(f): - if hasattr(f, 'read'): + if hasattr(f, "read"): return f else: - return open(f, 'rb') + return open(f, "rb") + def _get_file_write(f): - if hasattr(f, 'write'): + if hasattr(f, "write"): return f else: - return open(f, 'wb') + return open(f, "wb") ###################################################################### @@ -1022,8 +1043,7 @@

    Source code for apptools.persistence.state_pickler

    [docs]def dumps(value): - """Pickles the state of the object (`value`) and returns a string. - """ + """Pickles the state of the object (`value`) and returns a string.""" return StatePickler().dumps(value)
    @@ -1058,6 +1078,8 @@

    Source code for apptools.persistence.state_pickler

    [docs]def set_state(obj, state, ignore=None, first=None, last=None): StateSetter().set(obj, state, ignore, first, last)
    + + set_state.__doc__ = StateSetter.set.__doc__ @@ -1070,24 +1092,25 @@

    Source code for apptools.persistence.state_pickler

    [docs]def create_instance(state): - """Create an instance from the state if possible. - """ - if (not isinstance(state, State)) and \ - ('class_name' not in state.__metadata__): - raise StateSetterError('No class information in state') + """Create an instance from the state if possible.""" + if (not isinstance(state, State)) and ( + "class_name" not in state.__metadata__ + ): + raise StateSetterError("No class information in state") metadata = state.__metadata__ - class_name = metadata.get('class_name') - mod_name = metadata.get('module') - if 'tvtk_classes' in mod_name: + class_name = metadata.get("class_name") + mod_name = metadata.get("module") + if "tvtk_classes" in mod_name: # FIXME: This sort of special-case is probably indicative of something # that needs more thought, plus it makes it tought to decide whether # this component depends on tvtk! from tvtk.api import tvtk + return getattr(tvtk, class_name)() - initargs = metadata['initargs'] + initargs = metadata["initargs"] if initargs.has_instance: - raise StateUnpicklerError('Cannot unpickle non-trivial initargs') + raise StateUnpicklerError("Cannot unpickle non-trivial initargs") __import__(mod_name, globals(), locals(), class_name) mod = sys.modules[mod_name] @@ -1104,13 +1127,11 @@

    Source code for apptools.persistence.state_pickler

    @@ -1134,10 +1155,10 @@

    Quick search

    © Copyright 2008-2020, Enthought
  • - Last updated on Jun 12, 2020. + Last updated on Dec 17, 2020.
  • - Created using Sphinx 1.8.5. + Created using Sphinx 2.3.1.
  • diff --git a/_modules/apptools/persistence/updater.html b/_modules/apptools/persistence/updater.html index 9d68df9ce..8d32271d2 100644 --- a/_modules/apptools/persistence/updater.html +++ b/_modules/apptools/persistence/updater.html @@ -13,9 +13,11 @@ @@ -72,40 +74,46 @@
    -
    +

    Source code for apptools.persistence.updater

    -def __replacement_setstate__(self, state):
    -    """
    -    """
    +# (C) Copyright 2005-2020 Enthought, Inc., Austin, TX
    +# All rights reserved.
    +#
    +# This software is provided without warranty under the terms of the BSD
    +# license included in LICENSE.txt and may be redistributed only under
    +# the conditions described in the aforementioned license. The license
    +# is also available online at http://www.enthought.com/licenses/BSD.txt
    +#
    +# Thanks for using Enthought open source!
    +
    +
    +def __replacement_setstate__(self, state):
    +    """"""
         state = self.__updater__(state)
         self.__dict__.update(state)
     
    -    return
    -
    -
    -
     
     
    [docs]class Updater: - """ An abstract class to provide functionality common to the updaters. - """ + """An abstract class to provide functionality common to the updaters."""
    [docs] def get_latest(self, module, name): - """ The refactorings dictionary contains mappings between old and new + """The refactorings dictionary contains mappings between old and new module names. Since we only bump the version number one increment there is only one possible answer. """ - if hasattr(self, 'refactorings'): + if hasattr(self, "refactorings"): module = self.strip(module) name = self.strip(name) # returns the new module and name if it exists otherwise defaults # to using the original module and name - module, name = self.refactorings.get((module, name), (module, name)) + module, name = self.refactorings.get( + (module, name), (module, name) + ) return module, name
    -
    [docs] def strip(self, string): # Who would have thought that pickle would pass us # names with \013 on the end? Is this after the files have @@ -114,8 +122,6 @@

    Source code for apptools.persistence.updater

    return string[:-1]
     
             return string
    - -#### EOF #######################################################################
    @@ -127,13 +133,11 @@

    Source code for apptools.persistence.updater

    diff --git a/_modules/apptools/persistence/version_registry.html b/_modules/apptools/persistence/version_registry.html index b7a89a612..040c4e8eb 100644 --- a/_modules/apptools/persistence/version_registry.html +++ b/_modules/apptools/persistence/version_registry.html @@ -13,9 +13,11 @@ @@ -72,15 +74,22 @@
    -
    +

    Source code for apptools.persistence.version_registry

    -"""A version registry that manages handlers for different state
    +# (C) Copyright 2005-2020 Enthought, Inc., Austin, TX
    +# All rights reserved.
    +#
    +# This software is provided without warranty under the terms of the BSD
    +# license included in LICENSE.txt and may be redistributed only under
    +# the conditions described in the aforementioned license. The license
    +# is also available online at http://www.enthought.com/licenses/BSD.txt
    +#
    +# Thanks for using Enthought open source!
    +"""A version registry that manages handlers for different state
     versions.
     """
    -# Author: Prabhu Ramachandran <prabhu_r@users.sf.net>
    -# Copyright (c) 2005, Enthought, Inc.
    -# License: BSD Style.
    +
     
     # Standard library imports.
     import sys
    @@ -102,14 +111,14 @@ 

    Source code for apptools.persistence.version_registry

    res = [] for cls in inspect.getmro(obj.__class__): class_name, module = cls.__name__, cls.__module__ - if module in ['__builtin__']: + if module in ["__builtin__"]: # No point in versioning builtins. continue try: version = cls.__version__ except AttributeError: version = -1 - res.append( ( (class_name, module), version) ) + res.append(((class_name, module), version)) res.reverse() return res
    @@ -139,22 +148,21 @@

    Source code for apptools.persistence.version_registry

    """ key = (class_name, module) if key in self.handlers: - msg = 'Overwriting version handler for (%s, %s)'%(key[0], key[1]) + msg = "Overwriting version handler for (%s, %s)" % (key[0], key[1]) logger.warn(msg) self.handlers[(class_name, module)] = handler
    [docs] def unregister(self, class_name, module): - """Unregisters any handlers for a class and module. - """ + """Unregisters any handlers for a class and module.""" self.handlers.pop((class_name, module))
    [docs] def update(self, state): """Updates the given state using the handlers. Note that the state is modified in-place. """ - if (not self.handlers) or (not hasattr(state, '__metadata__')): + if (not self.handlers) or (not hasattr(state, "__metadata__")): return - versions = state.__metadata__['version'] + versions = state.__metadata__["version"] for ver in versions: key = ver[0] try: @@ -164,13 +172,12 @@

    Source code for apptools.persistence.version_registry

    def _create_registry(): - """Creates a reload safe, singleton registry. - """ + """Creates a reload safe, singleton registry.""" registry = None for key in sys.modules.keys(): - if 'version_registry' in key: + if "version_registry" in key: mod = sys.modules[key] - if hasattr(mod, 'registry'): + if hasattr(mod, "registry"): registry = mod.registry break if not registry: @@ -180,7 +187,6 @@

    Source code for apptools.persistence.version_registry

    # The singleton registry. registry = _create_registry() -
    @@ -192,13 +198,11 @@

    Source code for apptools.persistence.version_registry

    @@ -222,10 +226,10 @@

    Quick search

    © Copyright 2008-2020, Enthought
  • - Last updated on Jun 12, 2020. + Last updated on Dec 17, 2020.
  • - Created using Sphinx 1.8.5. + Created using Sphinx 2.3.1.
  • diff --git a/_modules/apptools/persistence/versioned_unpickler.html b/_modules/apptools/persistence/versioned_unpickler.html index 4f222a87f..667bf909c 100644 --- a/_modules/apptools/persistence/versioned_unpickler.html +++ b/_modules/apptools/persistence/versioned_unpickler.html @@ -13,9 +13,11 @@ @@ -72,14 +74,23 @@
    -
    +

    Source code for apptools.persistence.versioned_unpickler

    -# Standard library imports
    -from pickle import *
    -import sys
    +# (C) Copyright 2005-2020 Enthought, Inc., Austin, TX
    +# All rights reserved.
    +#
    +# This software is provided without warranty under the terms of the BSD
    +# license included in LICENSE.txt and may be redistributed only under
    +# the conditions described in the aforementioned license. The license
    +# is also available online at http://www.enthought.com/licenses/BSD.txt
    +#
    +# Thanks for using Enthought open source!
    +# Standard library imports
    +from pickle import _Unpickler as Unpickler
    +from pickle import UnpicklingError, BUILD
     import logging
    -from types import GeneratorType, MethodType
    +from types import GeneratorType
     
     # Enthought library imports
     from apptools.persistence.updater import __replacement_setstate__
    @@ -88,24 +99,11 @@ 

    Source code for apptools.persistence.versioned_unpickler

    logger = logging.getLogger(__name__) -def _unbound_method(method, klass): - """ - Python-version-agnostic unbound_method generator. - - For Python 2, use MethodType. Python 3 doesn't have a separate - type for unbound methods; just return the method itself. - """ - if sys.version_info < (3,): - return MethodType(method, None, klass) - else: - return method - - ############################################################################## # class 'NewUnpickler' ##############################################################################
    [docs]class NewUnpickler(Unpickler): - """ An unpickler that implements a two-stage pickling process to make it + """An unpickler that implements a two-stage pickling process to make it possible to unpickle complicated Python object hierarchies where the unserialized state of an object depends on the state of other objects in the same pickle. @@ -138,14 +136,15 @@

    Source code for apptools.persistence.versioned_unpickler

    # Execute object's initialize to setup the generators. for obj in self.objects: - if hasattr(obj, '__initialize__') and \ - callable(obj.__initialize__): + if hasattr(obj, "__initialize__") and callable(obj.__initialize__): ret = obj.__initialize__() if isinstance(ret, GeneratorType): generators.append((obj, ret)) elif ret is not None: - raise UnpicklingError('Unexpected return value from ' - '__initialize__. %s returned %s' % (obj, ret)) + raise UnpicklingError( + "Unexpected return value from " + "__initialize__. %s returned %s" % (obj, ret) + ) # Ensure a maximum number of passes if max_pass < 0: @@ -159,7 +158,10 @@

    Source code for apptools.persistence.versioned_unpickler

    not_done = [x[0] for x in generators] msg = """Reached maximum pass count %s. You may have a deadlock! The following objects are - uninitialized: %s""" % (max_pass, not_done) + uninitialized: %s""" % ( + max_pass, + not_done, + ) raise UnpicklingError(msg) for o, g in generators[:]: try: @@ -168,9 +170,9 @@

    Source code for apptools.persistence.versioned_unpickler

    generators.remove((o, g))
    # Make this a class method since dispatch is a class variable. - # Otherwise, supposing the initial sweet_pickle.load call (which would - # have overloaded the load_build method) makes a pickle.load call at some - # point, we would have the dispatch still pointing to + # Otherwise, supposing the initial VersionedUnpickler.load call (which + # would have overloaded the load_build method) makes a pickle.load call at + # some point, we would have the dispatch still pointing to # NewPickler.load_build whereas the object being passed in will be an # Unpickler instance, causing a TypeError.
    [docs] def load_build(cls, obj): @@ -178,11 +180,12 @@

    Source code for apptools.persistence.versioned_unpickler

    if isinstance(obj, NewUnpickler): obj.objects.append(obj.stack[-2]) Unpickler.load_build(obj)
    + load_build = classmethod(load_build)
    [docs]class VersionedUnpickler(NewUnpickler): - """ This class reads in a pickled file created at revision version 'n' + """This class reads in a pickled file created at revision version 'n' and then applies the transforms specified in the updater class to generate a new set of objects which are at revision version 'n+1'. @@ -194,15 +197,12 @@

    Source code for apptools.persistence.versioned_unpickler

    actual version numbers - all it needs to do is upgrade one release. """ - def __init__(self, file, updater=None): Unpickler.__init__(self, file) self.updater = updater - return -
    [docs] def find_class(self, module, name): - """ Overridden method from Unpickler. + """Overridden method from Unpickler. NB __setstate__ is not called until later. """ @@ -210,15 +210,10 @@

    Source code for apptools.persistence.versioned_unpickler

    if self.updater: # check to see if this class needs to be mapped to a new class # or module name - original_module, original_name = module, name - #logger.debug('omodule:%s oname:%s' % (original_module, original_name)) + original_module, original_name = module, name module, name = self.updater.get_latest(module, name) - #logger.debug('module:%s name:%s' % (module, name)) # load the class... - '''__import__(module) - mod = sys.modules[module] - klass = getattr(mod, name)''' klass = self.import_name(module, name) # add the updater.... TODO - why the old name? @@ -229,21 +224,21 @@

    Source code for apptools.persistence.versioned_unpickler

    # version of the file... try: klass = Unpickler.find_class(self, module, name) - except: + except Exception: logger.error("Looking for [%s] [%s]" % (module, name)) - logger.exception('Problem using default unpickle functionality') + logger.exception( + "Problem using default unpickle functionality" + ) # restore the original __setstate__ if necessary - fn = getattr(klass, '__setstate_original__', False) + fn = getattr(klass, "__setstate_original__", False) if fn: - m = _unbound_method(fn, klass) - setattr(klass, '__setstate__', m) + setattr(klass, "__setstate__", fn) return klass
    -
    [docs] def add_updater(self, module, name, klass): - """ If there is an updater defined for this class we will add it to the + """If there is an updater defined for this class we will add it to the class as the __setstate__ method. """ @@ -254,44 +249,32 @@

    Source code for apptools.persistence.versioned_unpickler

    self.backup_setstate(module, klass) # add the updater into the class - m = _unbound_method(fn, klass) - setattr(klass, '__updater__', m) + setattr(klass, "__updater__", fn) # hook up our __setstate__ which updates self.__dict__ - m = _unbound_method(__replacement_setstate__, klass) - setattr(klass, '__setstate__', m) + setattr(klass, "__setstate__", __replacement_setstate__) else: - pass - #print('No updater fn to worry about') - - return
    - + pass
    [docs] def backup_setstate(self, module, klass): - """ If the class has a user defined __setstate__ we back it up. - """ - if getattr(klass, '__setstate__', False): + """If the class has a user defined __setstate__ we back it up.""" + if getattr(klass, "__setstate__", False): - if getattr(klass, '__setstate_original__', False): + if getattr(klass, "__setstate_original__", False): # don't overwrite the original __setstate__ - name = '__setstate__%s' % self.updater.__class__ + name = "__setstate__%s" % self.updater.__class__ else: # backup the original __setstate__ which we will restore # and run later when we have finished updating the class - name = '__setstate_original__' + name = "__setstate_original__" - #logger.debug('renaming __setstate__ to %s' % name) - method = getattr(klass, '__setstate__') - m = _unbound_method(method, klass) - setattr(klass, name, m) + method = getattr(klass, "__setstate__") + setattr(klass, name, method) else: # the class has no __setstate__ method so do nothing - pass - - return
    - + pass
    [docs] def import_name(self, module, name): """ @@ -305,11 +288,8 @@

    Source code for apptools.persistence.versioned_unpickler

    objects that are required for v1 and v2 do not have to exist they only need to be placeholders for the state during an upgrade. """ - #print("importing %s %s" % (name, module)) module = __import__(module, globals(), locals(), [name]) return vars(module)[name]
    - -### EOF #################################################################
    @@ -321,13 +301,11 @@

    Source code for apptools.persistence.versioned_unpickler

    @@ -351,10 +329,10 @@

    Quick search

    © Copyright 2008-2020, Enthought
  • - Last updated on Jun 12, 2020. + Last updated on Dec 17, 2020.
  • - Created using Sphinx 1.8.5. + Created using Sphinx 2.3.1.
  • diff --git a/_modules/apptools/preferences/i_preferences.html b/_modules/apptools/preferences/i_preferences.html index 601fcc5a4..1b5559d48 100644 --- a/_modules/apptools/preferences/i_preferences.html +++ b/_modules/apptools/preferences/i_preferences.html @@ -13,9 +13,11 @@ @@ -72,10 +74,19 @@
    -
    +

    Source code for apptools.preferences.i_preferences

    -""" The interface for a node in a preferences hierarchy. """
    +# (C) Copyright 2005-2020 Enthought, Inc., Austin, TX
    +# All rights reserved.
    +#
    +# This software is provided without warranty under the terms of the BSD
    +# license included in LICENSE.txt and may be redistributed only under
    +# the conditions described in the aforementioned license. The license
    +# is also available online at http://www.enthought.com/licenses/BSD.txt
    +#
    +# Thanks for using Enthought open source!
    +""" The interface for a node in a preferences hierarchy. """
     
     
     # Enthought library imports.
    @@ -90,7 +101,7 @@ 

    Source code for apptools.preferences.i_preferences

    path = Str # The parent node (None if this node *is* the root node). - parent = Instance('IPreferences') + parent = Instance("IPreferences") # The name of the node relative to its parent (the empty string if this # node *is* the root node). @@ -99,7 +110,7 @@

    Source code for apptools.preferences.i_preferences

    #### Methods where 'path' refers to a preference ####
    [docs] def get(self, path, default=None, inherit=False): - """ Get the value of the preference at the specified path. + """Get the value of the preference at the specified path. If no value exists for the path (or any part of the path does not exist) then return the default value. @@ -134,7 +145,7 @@

    Source code for apptools.preferences.i_preferences

    """
    [docs] def remove(self, path): - """ Remove the preference at the specified path. + """Remove the preference at the specified path. Does nothing if no value exists for the path (or any part of the path does not exist. @@ -148,7 +159,7 @@

    Source code for apptools.preferences.i_preferences

    """
    [docs] def set(self, path, value): - """ Set the value of the preference at the specified path. + """Set the value of the preference at the specified path. Any missing nodes are created automatically. @@ -172,8 +183,8 @@

    Source code for apptools.preferences.i_preferences

    #### Methods where 'path' refers to a node #### -
    [docs] def clear(self, path=''): - """ Remove all preference from the node at the specified path. +
    [docs] def clear(self, path=""): + """Remove all preference from the node at the specified path. If the path is the empty string (the default) then remove the preferences in *this* node. @@ -190,8 +201,8 @@

    Source code for apptools.preferences.i_preferences

    """
    -
    [docs] def keys(self, path=''): - """ Return the preference keys of the node at the specified path. +
    [docs] def keys(self, path=""): + """Return the preference keys of the node at the specified path. If the path is the empty string (the default) then return the preference keys of *this* node. @@ -202,8 +213,8 @@

    Source code for apptools.preferences.i_preferences

    """
    -
    [docs] def node(self, path=''): - """ Return the node at the specified path. +
    [docs] def node(self, path=""): + """Return the node at the specified path. If the path is the empty string (the default) then return *this* node. @@ -216,8 +227,8 @@

    Source code for apptools.preferences.i_preferences

    """
    -
    [docs] def node_exists(self, path=''): - """ Return True if the node at the specified path exists +
    [docs] def node_exists(self, path=""): + """Return True if the node at the specified path exists If the path is the empty string (the default) then return True. @@ -227,8 +238,8 @@

    Source code for apptools.preferences.i_preferences

    """
    -
    [docs] def node_names(self, path=''): - """ Return the names of the children of the node at the specified path. +
    [docs] def node_names(self, path=""): + """Return the names of the children of the node at the specified path. If the path is the empty string (the default) then return the names of the children of *this* node. @@ -242,13 +253,11 @@

    Source code for apptools.preferences.i_preferences

    #### Persistence methods ####
    [docs] def flush(self): - """ Force any changes in the node to the backing store. + """Force any changes in the node to the backing store. This includes any changes to the node's descendants. """
    - -#### EOF ######################################################################
    @@ -260,13 +269,11 @@

    Source code for apptools.preferences.i_preferences

    @@ -290,10 +297,10 @@

    Quick search

    © Copyright 2008-2020, Enthought
  • - Last updated on Jun 12, 2020. + Last updated on Dec 17, 2020.
  • - Created using Sphinx 1.8.5. + Created using Sphinx 2.3.1.
  • diff --git a/_modules/apptools/preferences/package_globals.html b/_modules/apptools/preferences/package_globals.html index 4936f8634..e477fc92e 100644 --- a/_modules/apptools/preferences/package_globals.html +++ b/_modules/apptools/preferences/package_globals.html @@ -13,9 +13,11 @@ @@ -72,10 +74,19 @@
    -
    +

    Source code for apptools.preferences.package_globals

    -""" Package-scope globals.
    +# (C) Copyright 2005-2020 Enthought, Inc., Austin, TX
    +# All rights reserved.
    +#
    +# This software is provided without warranty under the terms of the BSD
    +# license included in LICENSE.txt and may be redistributed only under
    +# the conditions described in the aforementioned license. The license
    +# is also available online at http://www.enthought.com/licenses/BSD.txt
    +#
    +# Thanks for using Enthought open source!
    +""" Package-scope globals.
     
     The default preferences node is currently used by 'PreferencesHelper' and
     'PreferencesBinding' instances if no specific preferences node is set. This
    @@ -88,11 +99,13 @@ 

    Source code for apptools.preferences.package_globals

    # The default preferences node. _default_preferences = None +
    [docs]def get_default_preferences(): """ Get the default preferences node. """ return _default_preferences
    +
    [docs]def set_default_preferences(default_preferences): """ Set the default preferences node. """ @@ -102,8 +115,6 @@

    Source code for apptools.preferences.package_globals

    # For convenience. return _default_preferences
    - -#### EOF ######################################################################
    @@ -115,13 +126,11 @@

    Source code for apptools.preferences.package_globals

    @@ -145,10 +154,10 @@

    Quick search

    © Copyright 2008-2020, Enthought
  • - Last updated on Jun 12, 2020. + Last updated on Dec 17, 2020.
  • - Created using Sphinx 1.8.5. + Created using Sphinx 2.3.1.
  • diff --git a/_modules/apptools/preferences/preference_binding.html b/_modules/apptools/preferences/preference_binding.html index 41b9155cc..5cb1678c2 100644 --- a/_modules/apptools/preferences/preference_binding.html +++ b/_modules/apptools/preferences/preference_binding.html @@ -13,9 +13,11 @@ @@ -72,18 +74,23 @@
    -
    +

    Source code for apptools.preferences.preference_binding

    -""" A binding between a trait on an object and a preference value. """
    +# (C) Copyright 2005-2020 Enthought, Inc., Austin, TX
    +# All rights reserved.
    +#
    +# This software is provided without warranty under the terms of the BSD
    +# license included in LICENSE.txt and may be redistributed only under
    +# the conditions described in the aforementioned license. The license
    +# is also available online at http://www.enthought.com/licenses/BSD.txt
    +#
    +# Thanks for using Enthought open source!
    +""" A binding between a trait on an object and a preference value. """
     
     
     # Enthought library imports.
     from traits.api import Any, HasTraits, Instance, Str, Undefined
    -from traits.api import Unicode
    -
    -# Third-party librart imports.
    -import six
     
     # Local imports.
     from .i_preferences import IPreferences
    @@ -124,8 +131,6 @@ 

    Source code for apptools.preferences.preference_binding

    # Wire-up trait change handlers etc. self._initialize() - return - ########################################################################### # 'PreferenceBinding' interface. ########################################################################### @@ -148,25 +153,21 @@

    Source code for apptools.preferences.preference_binding

    self.preferences.set(self.preference_path, new) - return - #### Other observer pattern listeners ##################################### def _preferences_listener(self, node, key, old, new): """ Listener called when a preference value is changed. """ - components = self.preference_path.split('.') + components = self.preference_path.split(".") if key == components[-1]: self._set_trait() - return - #### Methods ############################################################## # fixme: This method is mostly duplicated in 'PreferencesHelper' (the only # difference is the line that gets the handler). def _get_value(self, trait_name, value): - """ Get the actual value to set. + """Get the actual value to set. This method makes sure that any required work is done to convert the preference value from a string. @@ -179,9 +180,9 @@

    Source code for apptools.preferences.preference_binding

    if type(handler) is Str: pass - # If the trait type is 'Unicode' then we convert the raw value. - elif type(handler) is Unicode: - value = six.text_type(value) + # If the trait type is 'Str' then we convert the raw value. + elif type(handler) is Str: + value = str(value) # Otherwise, we eval it! else: @@ -190,7 +191,7 @@

    Source code for apptools.preferences.preference_binding

    # If the eval fails then there is probably a syntax error, but # we will let the handler validation throw the exception. - except: + except Exception: pass return handler.validate(self, trait_name, value) @@ -202,26 +203,22 @@

    Source code for apptools.preferences.preference_binding

    self.obj.on_trait_change(self._on_trait_changed, self.trait_name) # Listen for the preference value being changed. - components = self.preference_path.split('.') - node = '.'.join(components[:-1]) + components = self.preference_path.split(".") + node = ".".join(components[:-1]) self.preferences.add_preferences_listener( self._preferences_listener, node ) - return - def _set_trait(self, notify=True): """ Set the object's trait to the value of the preference. """ value = self.preferences.get(self.preference_path, Undefined) if value is not Undefined: trait_value = self._get_value(self.trait_name, value) - traits = {self.trait_name : trait_value} - - self.obj.trait_set(trait_change_notify=notify, **traits) + traits = {self.trait_name: trait_value} - return
    + self.obj.trait_set(trait_change_notify=notify, **traits)
    # Factory function for creating bindings. @@ -241,17 +238,15 @@

    Source code for apptools.preferences.preference_binding

    # constructor (we could of course split that out, which may be the 'right' # way to do it ;^). traits = { - 'obj' : obj, - 'trait_name' : trait_name, - 'preference_path' : preference_path + "obj": obj, + "trait_name": trait_name, + "preference_path": preference_path, } if preferences is not None: - traits['preferences'] = preferences + traits["preferences"] = preferences return PreferenceBinding(**traits)
    - -#### EOF ######################################################################
    @@ -263,13 +258,11 @@

    Source code for apptools.preferences.preference_binding

    @@ -293,10 +286,10 @@

    Quick search

    © Copyright 2008-2020, Enthought
  • - Last updated on Jun 12, 2020. + Last updated on Dec 17, 2020.
  • - Created using Sphinx 1.8.5. + Created using Sphinx 2.3.1.
  • diff --git a/_modules/apptools/preferences/preferences.html b/_modules/apptools/preferences/preferences.html index 264942b98..380b6bf59 100644 --- a/_modules/apptools/preferences/preferences.html +++ b/_modules/apptools/preferences/preferences.html @@ -13,9 +13,11 @@ @@ -72,18 +74,23 @@
    -
    +

    Source code for apptools.preferences.preferences

    -""" The default implementation of a node in a preferences hierarchy. """
    -
    -from __future__ import print_function
    +# (C) Copyright 2005-2020 Enthought, Inc., Austin, TX
    +# All rights reserved.
    +#
    +# This software is provided without warranty under the terms of the BSD
    +# license included in LICENSE.txt and may be redistributed only under
    +# the conditions described in the aforementioned license. The license
    +# is also available online at http://www.enthought.com/licenses/BSD.txt
    +#
    +# Thanks for using Enthought open source!
    +""" The default implementation of a node in a preferences hierarchy. """
     
     # Standard library imports.
    -import logging, threading
    -
    -# Third-party library imports.
    -import six
    +import logging
    +import threading
     
     # Enthought library imports.
     from traits.api import Any, Callable, Dict, HasTraits, Instance, List
    @@ -101,7 +108,6 @@ 

    Source code for apptools.preferences.preferences

    class Preferences(HasTraits): """ The default implementation of a node in a preferences hierarchy. """ - #### 'IPreferences' interface ############################################# # The absolute path to this node from the root node (the empty string if @@ -163,8 +169,6 @@

    Source code for apptools.preferences.preferences

    if len(self.filename) > 0: self.load() - return - ########################################################################### # 'IPreferences' interface. ########################################################################### @@ -183,7 +187,7 @@

    Source code for apptools.preferences.preferences

    names.reverse() - return '.'.join(names) + return ".".join(names) #### Methods ############################################################## @@ -193,9 +197,9 @@

    Source code for apptools.preferences.preferences

    """ Get the value of the preference at the specified path. """ if len(path) == 0: - raise ValueError('empty path') + raise ValueError("empty path") - components = path.split('.') + components = path.split(".") # If there is only one component in the path then the operation takes # place in this node. @@ -206,7 +210,7 @@

    Source code for apptools.preferences.preferences

    else: node = self._get_child(components[0]) if node is not None: - value = node.get('.'.join(components[1:]), Undefined) + value = node.get(".".join(components[1:]), Undefined) else: value = Undefined @@ -224,7 +228,7 @@

    Source code for apptools.preferences.preferences

    del components[-2] # ... and try that. - value = self.get('.'.join(components), default=Undefined) + value = self.get(".".join(components), default=Undefined) if value is Undefined: value = default @@ -235,9 +239,9 @@

    Source code for apptools.preferences.preferences

    """ Remove the preference at the specified path. """ if len(path) == 0: - raise ValueError('empty path') + raise ValueError("empty path") - components = path.split('.') + components = path.split(".") # If there is only one component in the path then the operation takes # place in this node. @@ -248,17 +252,15 @@

    Source code for apptools.preferences.preferences

    else: node = self._get_child(components[0]) if node is not None: - node.remove('.'.join(components[1:])) - - return
    + node.remove(".".join(components[1:]))
    [docs] def set(self, path, value): """ Set the value of the preference at the specified path. """ if len(path) == 0: - raise ValueError('empty path') + raise ValueError("empty path") - components = path.split('.') + components = path.split(".") # If there is only one component in the path then the operation takes # place in this node. @@ -269,13 +271,11 @@

    Source code for apptools.preferences.preferences

    # and pass the rest of the path to that. else: node = self._node(components[0]) - node.set('.'.join(components[1:]), value) - - return
    + node.set(".".join(components[1:]), value)
    #### Methods where 'path' refers to a node #### -
    [docs] def clear(self, path=''): +
    [docs] def clear(self, path=""): """ Remove all preferences from the node at the specified path. """ # If the path is empty then the operation takes place in this node. @@ -284,15 +284,13 @@

    Source code for apptools.preferences.preferences

    # Otherwise, find the next node and pass the rest of the path to that. else: - components = path.split('.') + components = path.split(".") node = self._get_child(components[0]) if node is not None: - node.clear('.'.join(components[1:])) + node.clear(".".join(components[1:]))
    - return
    - -
    [docs] def keys(self, path=''): +
    [docs] def keys(self, path=""): """ Return the preference keys of the node at the specified path. """ # If the path is empty then the operation takes place in this node. @@ -301,18 +299,18 @@

    Source code for apptools.preferences.preferences

    # Otherwise, find the next node and pass the rest of the path to that. else: - components = path.split('.') + components = path.split(".") node = self._get_child(components[0]) if node is not None: - keys = node.keys('.'.join(components[1:])) + keys = node.keys(".".join(components[1:])) else: keys = [] return keys
    -
    [docs] def node(self, path=''): +
    [docs] def node(self, path=""): """ Return the node at the specified path. """ # If the path is empty then the operation takes place in this node. @@ -321,14 +319,14 @@

    Source code for apptools.preferences.preferences

    # Otherwise, find the next node and pass the rest of the path to that. else: - components = path.split('.') + components = path.split(".") node = self._node(components[0]) - node = node.node('.'.join(components[1:])) + node = node.node(".".join(components[1:])) return node
    -
    [docs] def node_exists(self, path=''): +
    [docs] def node_exists(self, path=""): """ Return True if the node at the specified path exists. """ # If the path is empty then the operation takes place in this node. @@ -337,20 +335,19 @@

    Source code for apptools.preferences.preferences

    # Otherwise, find the next node and pass the rest of the path to that. else: - components = path.split('.') + components = path.split(".") node = self._get_child(components[0]) if node is not None: - exists = node.node_exists('.'.join(components[1:])) + exists = node.node_exists(".".join(components[1:])) else: exists = False return exists
    -
    [docs] def node_names(self, path=''): - """ Return the names of the children of the node at the specified path. - +
    [docs] def node_names(self, path=""): + """Return the names of the children of the node at the specified path. """ # If the path is empty then the operation takes place in this node. @@ -359,11 +356,11 @@

    Source code for apptools.preferences.preferences

    # Otherwise, find the next node and pass the rest of the path to that. else: - components = path.split('.') + components = path.split(".") node = self._get_child(components[0]) if node is not None: - names = node.node_names('.'.join(components[1:])) + names = node.node_names(".".join(components[1:])) else: names = [] @@ -373,15 +370,13 @@

    Source code for apptools.preferences.preferences

    #### Persistence methods ####
    [docs] def flush(self): - """ Force any changes in the node to the backing store. + """Force any changes in the node to the backing store. This includes any changes to the node's descendants. """ - self.save() - - return
    + self.save()
    ########################################################################### # 'Preferences' interface. @@ -389,42 +384,40 @@

    Source code for apptools.preferences.preferences

    #### Listener methods #### -
    [docs] def add_preferences_listener(self, listener, path=''): +
    [docs] def add_preferences_listener(self, listener, path=""): """ Add a listener for changes to a node's preferences. """ # If the path is empty then the operation takes place in this node. if len(path) == 0: - names = self._add_preferences_listener(listener) + self._add_preferences_listener(listener) # Otherwise, find the next node and pass the rest of the path to that. else: - components = path.split('.') + components = path.split(".") node = self._node(components[0]) - node.add_preferences_listener(listener, '.'.join(components[1:])) + node.add_preferences_listener(listener, ".".join(components[1:]))
    - return
    - -
    [docs] def remove_preferences_listener(self, listener, path=''): +
    [docs] def remove_preferences_listener(self, listener, path=""): """ Remove a listener for changes to a node's preferences. """ # If the path is empty then the operation takes place in this node. if len(path) == 0: - names = self._remove_preferences_listener(listener) + self._remove_preferences_listener(listener) # Otherwise, find the next node and pass the rest of the path to that. else: - components = path.split('.') + components = path.split(".") node = self._node(components[0]) - node.remove_preferences_listener(listener,'.'.join(components[1:])) - - return
    + node.remove_preferences_listener( + listener, ".".join(components[1:]) + )
    #### Persistence methods ####
    [docs] def load(self, file_or_filename=None): - """ Load preferences from a file. + """Load preferences from a file. This is a *merge* operation i.e. the contents of the file are added to the node. @@ -436,32 +429,30 @@

    Source code for apptools.preferences.preferences

    if file_or_filename is None: file_or_filename = self.filename - logger.debug('loading preferences from <%s>', file_or_filename) + logger.debug("loading preferences from <%s>", file_or_filename) # Do the import here so that we don't make 'ConfigObj' a requirement # if preferences aren't ever persisted (or a derived class chooses to # use a different persistence mechanism). from configobj import ConfigObj - config_obj = ConfigObj(file_or_filename, encoding='utf-8') + config_obj = ConfigObj(file_or_filename, encoding="utf-8") # 'name' is the section name, 'value' is a dictionary containing the # name/value pairs in the section (the actual preferences ;^). for name, value in config_obj.items(): # Create/get the node from the section name. - components = name.split('.') + components = name.split(".") node = self for component in components: node = node._node(component) # Add the contents of the section to the node. - self._add_dictionary_to_node(node, value) - - return
    + self._add_dictionary_to_node(node, value)
    [docs] def save(self, file_or_filename=None): - """ Save the node's preferences to a file. + """Save the node's preferences to a file. This implementation uses 'ConfigObj' files. @@ -477,13 +468,11 @@

    Source code for apptools.preferences.preferences

    # class chooses to use a different persistence mechanism). from configobj import ConfigObj - logger.debug('saving preferences to <%s>', file_or_filename) + logger.debug("saving preferences to <%s>", file_or_filename) - config_obj = ConfigObj(file_or_filename, encoding='utf-8') + config_obj = ConfigObj(file_or_filename, encoding="utf-8") self._add_node_to_dictionary(self, config_obj) - config_obj.write() - - return
    + config_obj.write()
    ########################################################################### # Protected 'Preferences' interface. @@ -502,8 +491,6 @@

    Source code for apptools.preferences.preferences

    node._preferences.update(dictionary) self._lk.release() - return - def _add_node_to_dictionary(self, node, dictionary): """ Add a node's preferences to a dictionary. """ @@ -518,8 +505,6 @@

    Source code for apptools.preferences.preferences

    for name in node._node_names(): self._add_node_to_dictionary(node._get_child(name), dictionary) - return - def _add_preferences_listener(self, listener): """ Add a listener for changes to thisnode's preferences. """ @@ -527,8 +512,6 @@

    Source code for apptools.preferences.preferences

    self._preferences_listeners.append(listener) self._lk.release() - return - def _clear(self): """ Remove all preferences from this node. """ @@ -536,8 +519,6 @@

    Source code for apptools.preferences.preferences

    self._preferences.clear() self._lk.release() - return - def _create_child(self, name): """ Create a child of this node with the specified name. """ @@ -557,7 +538,7 @@

    Source code for apptools.preferences.preferences

    return value def _get_child(self, name): - """ Return the child of this node with the specified name. + """Return the child of this node with the specified name. Return None if no such child exists. @@ -579,7 +560,7 @@

    Source code for apptools.preferences.preferences

    return keys def _node(self, name): - """ Return the child of this node with the specified name. + """Return the child of this node with the specified name. Create the child node if it does not exist. @@ -608,8 +589,6 @@

    Source code for apptools.preferences.preferences

    del self._preferences[name] self._lk.release() - return - def _remove_preferences_listener(self, listener): """ Remove a listener for changes to the node's preferences. """ @@ -618,15 +597,13 @@

    Source code for apptools.preferences.preferences

    self._preferences_listeners.remove(listener) self._lk.release() - return - def _set(self, key, value): """ Set the value of a preference in this node. """ - + # everything must be unicode encoded so that ConfigObj configuration # can properly serialize the data. Python str are supposed to be ASCII # encoded. - value = six.text_type(value) + value = str(value) self._lk.acquire() old = self._preferences.get(key) @@ -643,27 +620,21 @@

    Source code for apptools.preferences.preferences

    for listener in listeners: listener(self, key, old, value) - return - ########################################################################### # Debugging interface. ########################################################################### -
    [docs] def dump(self, indent=''): +
    [docs] def dump(self, indent=""): """ Dump the preferences hierarchy to stdout. """ - if indent == '': + if indent == "": print() - print(indent, 'Node(%s)' % self.name, self._preferences) - indent += ' ' + print(indent, "Node(%s)" % self.name, self._preferences) + indent += " " for child in self._children.values(): - child.dump(indent) - - return
    - -#### EOF ###################################################################### + child.dump(indent)
    @@ -675,13 +646,11 @@

    Source code for apptools.preferences.preferences

    @@ -705,10 +674,10 @@

    Quick search

    © Copyright 2008-2020, Enthought
  • - Last updated on Jun 12, 2020. + Last updated on Dec 17, 2020.
  • - Created using Sphinx 1.8.5. + Created using Sphinx 2.3.1.
  • diff --git a/_modules/apptools/preferences/preferences_helper.html b/_modules/apptools/preferences/preferences_helper.html index 480b00685..982d2dd8c 100644 --- a/_modules/apptools/preferences/preferences_helper.html +++ b/_modules/apptools/preferences/preferences_helper.html @@ -13,9 +13,11 @@ @@ -72,17 +74,26 @@
    -
    +

    Source code for apptools.preferences.preferences_helper

    -""" An object that can be initialized from a preferences node. """
    +# (C) Copyright 2005-2020 Enthought, Inc., Austin, TX
    +# All rights reserved.
    +#
    +# This software is provided without warranty under the terms of the BSD
    +# license included in LICENSE.txt and may be redistributed only under
    +# the conditions described in the aforementioned license. The license
    +# is also available online at http://www.enthought.com/licenses/BSD.txt
    +#
    +# Thanks for using Enthought open source!
    +""" An object that can be initialized from a preferences node. """
     
     
     # Standard library imports.
     import logging
     
     # Enthought library imports.
    -from traits.api import HasTraits, Instance, Str, Unicode
    +from traits.api import HasTraits, Instance, Str
     
     # Local imports.
     from .i_preferences import IPreferences
    @@ -94,7 +105,14 @@ 

    Source code for apptools.preferences.preferences_helper

    [docs]class PreferencesHelper(HasTraits): - """ An object that can be initialized from a preferences node. """ + """ A base class for objects that can be initialized from a preferences + node. + + Additional traits defined on subclasses will be listened to. Changes + are then synchronized with the preferences. Note that mutations on nested + containers e.g. List(List(Str)) cannot be synchronized and should be + avoided. + """ #### 'PreferencesHelper' interface ######################################## @@ -122,8 +140,6 @@

    Source code for apptools.preferences.preferences_helper

    if self.preferences: self._initialize(self.preferences) - return - ########################################################################### # Private interface. ########################################################################### @@ -142,12 +158,24 @@

    Source code for apptools.preferences.preferences_helper

    def _anytrait_changed(self, trait_name, old, new): """ Static trait change handler. """ - # If we were the one that set the trait (because the underlying - # preferences node changed) then do nothing. - if self.preferences and self._is_preference_trait(trait_name): - self.preferences.set('%s.%s' % (self._get_path(), trait_name), new) + if self.preferences is None: + return + + if self._is_preference_trait(trait_name): + self.preferences.set("%s.%s" % (self._get_path(), trait_name), new) + + # If the trait was a list or dict '_items' trait then just treat it as + # if the entire list or dict was changed. + elif trait_name.endswith('_items'): + trait_name = trait_name[:-6] + if self._is_preference_trait(trait_name): + self.preferences.set( + '%s.%s' % (self._get_path(), trait_name), + getattr(self, trait_name) + ) - return + # If the change refers to a trait defined on this class, then + # the trait is not a preference trait and we do nothing. def _preferences_changed(self, old, new): """ Static trait change handler. """ @@ -163,8 +191,6 @@

    Source code for apptools.preferences.preferences_helper

    # listener for preferences being changed in the new node). self._initialize(new, notify=True) - return - #### Other observer pattern listeners ##################################### def _preferences_changed_listener(self, node, key, old, new): @@ -173,8 +199,6 @@

    Source code for apptools.preferences.preferences_helper

    if key in self.trait_names(): setattr(self, key, self._get_value(key, new)) - return - #### Methods ############################################################## def _get_path(self): @@ -184,9 +208,9 @@

    Source code for apptools.preferences.preferences_helper

    path = self.preferences_path else: - path = getattr(self, 'PREFERENCES_PATH', None) + path = getattr(self, "PREFERENCES_PATH", None) if path is None: - raise SystemError('no preferences path, %s' % self) + raise SystemError("no preferences path, %s" % self) else: logger.warn('DEPRECATED: use "preferences_path" %s' % self) @@ -194,7 +218,7 @@

    Source code for apptools.preferences.preferences_helper

    return path def _get_value(self, trait_name, value): - """ Get the actual value to set. + """Get the actual value to set. This method makes sure that any required work is done to convert the preference value from a string. Str traits or those with the metadata @@ -205,8 +229,8 @@

    Source code for apptools.preferences.preferences_helper

    trait = self.trait(trait_name) handler = trait.handler - # If the trait type is 'Str' or Unicode then we just take the raw value. - if isinstance(handler, (Str, Unicode)) or trait.is_str: + # If the trait type is 'Str' then we just take the raw value. + if isinstance(handler, Str) or trait.is_str: pass # Otherwise, we eval it! @@ -216,7 +240,7 @@

    Source code for apptools.preferences.preferences_helper

    # If the eval fails then there is probably a syntax error, but # we will let the handler validation throw the exception. - except: + except Exception: pass if handler.validate is not None: @@ -236,7 +260,7 @@

    Source code for apptools.preferences.preferences_helper

    traits_to_set = {} for trait_name in self.trait_names(): if trait_name in keys: - key = '%s.%s' % (path, trait_name) + key = "%s.%s" % (path, trait_name) value = self._get_value(trait_name, preferences.get(key)) traits_to_set[trait_name] = value @@ -247,20 +271,19 @@

    Source code for apptools.preferences.preferences_helper

    self._preferences_changed_listener, path ) - return - # fixme: Pretty much duplicated in 'PreferencesPage' (except for the # class name of course!). def _is_preference_trait(self, trait_name): """ Return True if a trait represents a preference value. """ - if trait_name.startswith('_') or trait_name.endswith('_') \ - or trait_name in PreferencesHelper.class_traits(): + if ( + trait_name.startswith("_") + or trait_name.endswith("_") + or trait_name in PreferencesHelper.class_traits() + ): return False - return True
    - -#### EOF ###################################################################### + return trait_name in self.editable_traits()
    @@ -272,13 +295,11 @@

    Source code for apptools.preferences.preferences_helper

    @@ -302,10 +323,10 @@

    Quick search

    © Copyright 2008-2020, Enthought
  • - Last updated on Jun 12, 2020. + Last updated on Dec 17, 2020.
  • - Created using Sphinx 1.8.5. + Created using Sphinx 2.3.1.
  • diff --git a/_modules/apptools/preferences/scoped_preferences.html b/_modules/apptools/preferences/scoped_preferences.html index c0744338a..e2937244e 100644 --- a/_modules/apptools/preferences/scoped_preferences.html +++ b/_modules/apptools/preferences/scoped_preferences.html @@ -13,9 +13,11 @@ @@ -72,12 +74,19 @@
    -
    +

    Source code for apptools.preferences.scoped_preferences

    -""" A preferences node that adds the notion of preferences scopes. """
    -
    -from __future__ import print_function
    +# (C) Copyright 2005-2020 Enthought, Inc., Austin, TX
    +# All rights reserved.
    +#
    +# This software is provided without warranty under the terms of the BSD
    +# license included in LICENSE.txt and may be redistributed only under
    +# the conditions described in the aforementioned license. The license
    +# is also available online at http://www.enthought.com/licenses/BSD.txt
    +#
    +# Thanks for using Enthought open source!
    +""" A preferences node that adds the notion of preferences scopes. """
     
     # Standard library imports.
     from os.path import join
    @@ -92,7 +101,7 @@ 

    Source code for apptools.preferences.scoped_preferences

    [docs]class ScopedPreferences(Preferences): - """ A preferences node that adds the notion of preferences scopes. + """A preferences node that adds the notion of preferences scopes. Scopes provide a way to access preferences in a precedence order, usually depending on where they came from, for example from the command-line, @@ -104,21 +113,21 @@

    Source code for apptools.preferences.scoped_preferences

    Path names passed to 'ScopedPreferences' nodes can be either:: - a) a preference path as used in a standard 'Preferences' node, e.g:: + a) a preference path as used in a standard 'Preferences' node, e.g:: - 'acme.widget.bgcolor'. + 'acme.widget.bgcolor'. - In this case the operation either takes place in the primary scope - (for operations such as 'set' etc), or on all scopes in precedence order - (for operations such as 'get' etc). + In this case the operation either takes place in the primary scope + (for operations such as 'set' etc), or on all scopes in precedence + order (for operations such as 'get' etc). - or + or - b) a preference path that refers to a specific scope e.g:: + b) a preference path that refers to a specific scope e.g:: - 'default/acme.widget.bgcolor' + 'default/acme.widget.bgcolor' - In this case the operation takes place *only* in the specified scope. + In this case the operation takes place *only* in the specified scope. There is one drawback to this scheme. If you want to access a scope node itself via the 'clear', 'keys', 'node', 'node_exists' or 'node_names' @@ -127,23 +136,23 @@

    Source code for apptools.preferences.scoped_preferences

    e.g. To get the names of the children of the 'application' scope, use:: - scoped.node_names('application/') + scoped.node_names('application/') If you did this:: - scoped.node_names('application') + scoped.node_names('application') Then the node would get the primary scope and try to find its child node called 'application'. Of course you can just get the scope via:: - application_scope = scoped.get_scope('application') + application_scope = scoped.get_scope('application') and then call whatever methods you like on it - which is definitely more intentional and is highly recommended:: - application_scope.node_names() + application_scope.node_names() """ @@ -182,7 +191,7 @@

    Source code for apptools.preferences.scoped_preferences

    """ Get the value of the preference at the specified path. """ if len(path) == 0: - raise ValueError('empty path') + raise ValueError("empty path") # If the path contains a specific scope then lookup the preference in # just that scope. @@ -209,7 +218,7 @@

    Source code for apptools.preferences.scoped_preferences

    """ Remove the preference at the specified path. """ if len(path) == 0: - raise ValueError('empty path') + raise ValueError("empty path") # If the path contains a specific scope then remove the preference from # just that scope. @@ -221,15 +230,13 @@

    Source code for apptools.preferences.scoped_preferences

    else: node = self._get_primary_scope() - node.remove(path) - - return
    + node.remove(path)
    [docs] def set(self, path, value): """ Set the value of the preference at the specified path. """ if len(path) == 0: - raise ValueError('empty path') + raise ValueError("empty path") # If the path contains a specific scope then set the value in that # scope. @@ -241,13 +248,11 @@

    Source code for apptools.preferences.scoped_preferences

    else: node = self._get_primary_scope() - node.set(path, value) - - return
    + node.set(path, value)
    #### Methods where 'path' refers to a node #### -
    [docs] def clear(self, path=''): +
    [docs] def clear(self, path=""): """ Remove all preference from the node at the specified path. """ # If the path contains a specific scope then remove the preferences @@ -262,7 +267,7 @@

    Source code for apptools.preferences.scoped_preferences

    return node.clear(path)
    -
    [docs] def keys(self, path=''): +
    [docs] def keys(self, path=""): """ Return the preference keys of the node at the specified path. """ # If the path contains a specific scope then get the keys of the node @@ -281,7 +286,7 @@

    Source code for apptools.preferences.scoped_preferences

    return list(keys)
    -
    [docs] def node(self, path=''): +
    [docs] def node(self, path=""): """ Return the node at the specified path. """ if len(path) == 0: @@ -302,7 +307,7 @@

    Source code for apptools.preferences.scoped_preferences

    return node
    -
    [docs] def node_exists(self, path=''): +
    [docs] def node_exists(self, path=""): """ Return True if the node at the specified path exists. """ # If the path contains a specific scope then look for the node in that @@ -317,9 +322,8 @@

    Source code for apptools.preferences.scoped_preferences

    return node.node_exists(path)
    -
    [docs] def node_names(self, path=''): - """ Return the names of the children of the node at the specified path. - +
    [docs] def node_names(self, path=""): + """Return the names of the children of the node at the specified path. """ # If the path contains a specific scope then get the names of the @@ -344,7 +348,7 @@

    Source code for apptools.preferences.scoped_preferences

    #### Listener methods #### -
    [docs] def add_preferences_listener(self, listener, path=''): +
    [docs] def add_preferences_listener(self, listener, path=""): """ Add a listener for changes to a node's preferences. """ # If the path contains a specific scope then add a preferences listener @@ -358,11 +362,9 @@

    Source code for apptools.preferences.scoped_preferences

    nodes = self.scopes for node in nodes: - node.add_preferences_listener(listener, path) - - return
    + node.add_preferences_listener(listener, path)
    -
    [docs] def remove_preferences_listener(self, listener, path=''): +
    [docs] def remove_preferences_listener(self, listener, path=""): """ Remove a listener for changes to a node's preferences. """ # If the path contains a specific scope then remove a preferences @@ -376,14 +378,12 @@

    Source code for apptools.preferences.scoped_preferences

    nodes = self.scopes for node in nodes: - node.remove_preferences_listener(listener, path) - - return
    + node.remove_preferences_listener(listener, path)
    #### Persistence methods ####
    [docs] def load(self, file_or_filename=None): - """ Load preferences from a file. + """Load preferences from a file. This loads the preferences into the primary scope. @@ -397,12 +397,10 @@

    Source code for apptools.preferences.scoped_preferences

    file_or_filename = self.filename node = self._get_primary_scope() - node.load(file_or_filename) - - return
    + node.load(file_or_filename)
    [docs] def save(self, file_or_filename=None): - """ Save the node's preferences to a file. + """Save the node's preferences to a file. This asks each scope in turn to save its preferences. @@ -417,9 +415,7 @@

    Source code for apptools.preferences.scoped_preferences

    self._get_primary_scope().save(file_or_filename) for scope in self.scopes: if scope is not self._get_primary_scope(): - scope.save() - - return
    + scope.save()
    ########################################################################### # 'ScopedPreferences' protocol. @@ -428,7 +424,7 @@

    Source code for apptools.preferences.scoped_preferences

    def _application_preferences_filename_default(self): """ Trait initializer. """ - return join(ETSConfig.application_home, 'preferences.ini') + return join(ETSConfig.application_home, "preferences.ini") # fixme: In hindsight, I don't think this class should have provided # default scopes. This should have been an 'abstract' class that could @@ -438,17 +434,16 @@

    Source code for apptools.preferences.scoped_preferences

    scopes = [ Preferences( - name = 'application', - filename = self.application_preferences_filename + name="application", + filename=self.application_preferences_filename, ), - - Preferences(name='default') + Preferences(name="default"), ] return scopes
    [docs] def get_scope(self, scope_name): - """ Return the scope with the specified name. + """Return the scope with the specified name. Return None if no such scope exists. @@ -481,7 +476,7 @@

    Source code for apptools.preferences.scoped_preferences

    return value def _get_scope(self, scope_name): - """ Return the scope with the specified name. + """Return the scope with the specified name. Raise a 'ValueError' is no such scope exists. @@ -489,12 +484,12 @@

    Source code for apptools.preferences.scoped_preferences

    scope = self.get_scope(scope_name) if scope is None: - raise ValueError('no such scope %s' % scope_name) + raise ValueError("no such scope %s" % scope_name) return scope def _get_primary_scope(self): - """ Return the primary scope. + """Return the primary scope. By default, this is the first scope. @@ -511,34 +506,30 @@

    Source code for apptools.preferences.scoped_preferences

    def _path_contains_scope(self, path): """ Return True if the path contains a scope component. """ - return '/' in path + return "/" in path def _parse_path(self, path): """ 'Parse' the path into two parts, the scope name and the rest! """ - components = path.split('/') + components = path.split("/") - return components[0], '/'.join(components[1:]) + return components[0], "/".join(components[1:]) ########################################################################### # Debugging interface. ########################################################################### -
    [docs] def dump(self, indent=''): +
    [docs] def dump(self, indent=""): """ Dump the preferences hierarchy to stdout. """ - if indent == '': + if indent == "": print() - print(indent, 'Node(%s)' % self.name, self._preferences) - indent += ' ' + print(indent, "Node(%s)" % self.name, self._preferences) + indent += " " for child in self.scopes: - child.dump(indent) - - return
    - -#### EOF ###################################################################### + child.dump(indent)
    @@ -550,13 +541,11 @@

    Source code for apptools.preferences.scoped_preferences

    @@ -580,10 +569,10 @@

    Quick search

    © Copyright 2008-2020, Enthought
  • - Last updated on Jun 12, 2020. + Last updated on Dec 17, 2020.
  • - Created using Sphinx 1.8.5. + Created using Sphinx 2.3.1.
  • diff --git a/_modules/apptools/preferences/ui/i_preferences_page.html b/_modules/apptools/preferences/ui/i_preferences_page.html index db3f35d6f..bada9bfa3 100644 --- a/_modules/apptools/preferences/ui/i_preferences_page.html +++ b/_modules/apptools/preferences/ui/i_preferences_page.html @@ -13,9 +13,11 @@ @@ -72,10 +74,19 @@
    -
    +

    Source code for apptools.preferences.ui.i_preferences_page

    -""" The interface for pages in a preferences dialog. """
    +# (C) Copyright 2005-2020 Enthought, Inc., Austin, TX
    +# All rights reserved.
    +#
    +# This software is provided without warranty under the terms of the BSD
    +# license included in LICENSE.txt and may be redistributed only under
    +# the conditions described in the aforementioned license. The license
    +# is also available online at http://www.enthought.com/licenses/BSD.txt
    +#
    +# Thanks for using Enthought open source!
    +""" The interface for pages in a preferences dialog. """
     
     
     # Enthought library imports.
    @@ -97,18 +108,8 @@ 

    Source code for apptools.preferences.ui.i_preferences_page

    name = Str
    [docs] def apply(self): - """ Apply the page's preferences. """
    - - # fixme: We would like to be able to have the following API so that - # developers are not forced into using traits UI for their preferences - # pages, but at the moment I can't work out how to do it! -## def create_control(self, parent): -## """ Create the toolkit-specific control that represents the page. """ - -## def destroy_control(self, parent): -## """ Destroy the toolkit-specific control that represents the page. """ - -#### EOF ###################################################################### + """ Apply the page's preferences. """ + pass
    @@ -120,13 +121,11 @@

    Source code for apptools.preferences.ui.i_preferences_page

    @@ -150,10 +149,10 @@

    Quick search

    © Copyright 2008-2020, Enthought
  • - Last updated on Jun 12, 2020. + Last updated on Dec 17, 2020.
  • - Created using Sphinx 1.8.5. + Created using Sphinx 2.3.1.
  • diff --git a/_modules/apptools/preferences/ui/preferences_manager.html b/_modules/apptools/preferences/ui/preferences_manager.html index 6a250cd78..c084f3ff2 100644 --- a/_modules/apptools/preferences/ui/preferences_manager.html +++ b/_modules/apptools/preferences/ui/preferences_manager.html @@ -13,9 +13,11 @@ @@ -72,15 +74,23 @@
    -
    +

    Source code for apptools.preferences.ui.preferences_manager

    -""" The preferences manager. """
    +# (C) Copyright 2005-2020 Enthought, Inc., Austin, TX
    +# All rights reserved.
    +#
    +# This software is provided without warranty under the terms of the BSD
    +# license included in LICENSE.txt and may be redistributed only under
    +# the conditions described in the aforementioned license. The license
    +# is also available online at http://www.enthought.com/licenses/BSD.txt
    +#
    +# Thanks for using Enthought open source!
    +""" The preferences manager. """
     
     
     # Enthought library imports.
    -from traits.api import HasTraits, Instance, List, Property, \
    -    Any, Bool, Dict
    +from traits.api import HasTraits, Instance, List, Property, Bool
     from traitsui.api import Handler, HSplit, Item, TreeEditor
     from traitsui.api import TreeNode, View, HTMLEditor
     from traitsui.menu import Action
    @@ -89,31 +99,26 @@ 

    Source code for apptools.preferences.ui.preferences_manager

    from .preferences_node import PreferencesNode from .preferences_page import PreferencesPage -# fixme: This is part of the attempt to allow developers to use non-Traits UI -# preferences pages. It doesn't work yet! -##from widget_editor import WidgetEditor - # A tree editor for preferences nodes. tree_editor = TreeEditor( - nodes = [ + nodes=[ TreeNode( - node_for = [PreferencesNode], - auto_open = False, - children = 'children', - label = 'name', - rename = False, - copy = False, - delete = False, - insert = False, - menu = None, + node_for=[PreferencesNode], + auto_open=False, + children="children", + label="name", + rename=False, + copy=False, + delete=False, + insert=False, + menu=None, ), ], - - editable = False, - hide_root = True, - selected = 'selected_node', - show_icons = False + editable=False, + hide_root=True, + selected="selected_node", + show_icons=False, ) @@ -123,22 +128,21 @@

    Source code for apptools.preferences.ui.preferences_manager

    [docs] def traits_view(self): """ Default view to show for this class. """ args = [] - kw_args = {'title' : 'Preferences Page Help', - 'buttons' : ['OK'], - 'width' : 800, - 'height' : 800, - 'resizable' : True, - 'id' : 'apptools.preferences.ui.preferences_manager.help'} + kw_args = { + "title": "Preferences Page Help", + "buttons": ["OK"], + "width": 800, + "height": 800, + "resizable": True, + "id": "apptools.preferences.ui.preferences_manager.help", + } to_show = {} for name, trait_obj in self.traits().items(): - if name != 'trait_added' and name != 'trait_modified': + if name != "trait_added" and name != "trait_modified": to_show[name] = trait_obj.help for name in to_show: - args.append(Item(name, - style='readonly', - editor=HTMLEditor() - )) + args.append(Item(name, style="readonly", editor=HTMLEditor())) view = View(*args, **kw_args) return view
    @@ -156,8 +160,7 @@

    Source code for apptools.preferences.ui.preferences_manager

    [docs] def apply(self, info): """ Handle the **Apply** button being clicked. """ - info.object.apply() - return
    + info.object.apply()
    [docs] def init(self, info): """ Initialize the controls of a user interface. """ @@ -167,7 +170,6 @@

    Source code for apptools.preferences.ui.preferences_manager

    return super(PreferencesManagerHandler, self).init(info)
    -
    [docs] def close(self, info, is_ok): """ Close a dialog-based user interface. """ @@ -176,19 +178,16 @@

    Source code for apptools.preferences.ui.preferences_manager

    return super(PreferencesManagerHandler, self).close(info, is_ok)
    -
    [docs] def preferences_help(self, info): """ Custom preferences help panel. The Traits help doesn't work.""" current_page = self.model.selected_page to_show = {} for trait_name, trait_obj in current_page.traits().items(): - if hasattr(trait_obj, 'show_help') and trait_obj.show_help: + if hasattr(trait_obj, "show_help") and trait_obj.show_help: to_show[trait_name] = trait_obj.help help_obj = PreferencesHelpWindow(**to_show) - help_obj.edit_traits(kind='livemodal') - return
    - + help_obj.edit_traits(kind="livemodal")
    ########################################################################### # Private interface. @@ -201,9 +200,7 @@

    Source code for apptools.preferences.ui.preferences_manager

    if len(root.children) > 0: node = root.children[0] - info.object.selected_page = node.page - - return
    + info.object.selected_page = node.page
    [docs]class PreferencesManager(HasTraits): @@ -235,63 +232,60 @@

    Source code for apptools.preferences.ui.preferences_manager

    [docs] def traits_view(self): """ Default traits view for this class. """ - help_action = Action(name = 'Info', action = 'preferences_help') + help_action = Action(name="Info", action="preferences_help") - buttons = ['OK', 'Cancel'] + buttons = ["OK", "Cancel"] if self.show_apply: - buttons = ['Apply'] + buttons + buttons = ["Apply"] + buttons if self.show_help: buttons = [help_action] + buttons - # A tree editor for preferences nodes. tree_editor = TreeEditor( - nodes = [ + nodes=[ TreeNode( - node_for = [PreferencesNode], - auto_open = False, - children = 'children', - label = 'name', - rename = False, - copy = False, - delete = False, - insert = False, - menu = None, + node_for=[PreferencesNode], + auto_open=False, + children="children", + label="name", + rename=False, + copy=False, + delete=False, + insert=False, + menu=None, ), ], - on_select = self._selection_changed, - editable = False, - hide_root = True, - selected = 'selected_node', - show_icons = False + on_select=self._selection_changed, + editable=False, + hide_root=True, + selected="selected_node", + show_icons=False, ) view = View( HSplit( Item( - name = 'root', - editor = tree_editor, - show_label = False, - width = 250, + name="root", + editor=tree_editor, + show_label=False, + width=250, ), - Item( - name = 'selected_page', - #editor = WidgetEditor(), - show_label = False, - width = 450, - style = 'custom', + name="selected_page", + # editor = WidgetEditor(), + show_label=False, + width=450, + style="custom", ), ), - - buttons = buttons, - handler = PreferencesManagerHandler(model=self), - resizable = True, - title = 'Preferences', - width = .3, - height = .3, - kind = 'modal' + buttons=buttons, + handler=PreferencesManagerHandler(model=self), + resizable=True, + title="Preferences", + width=0.3, + height=0.3, + kind="modal", ) self.selected_page = self.pages[0] return view
    @@ -316,7 +310,7 @@

    Source code for apptools.preferences.ui.preferences_manager

    len_a = 0 else: - len_a = len(a.category.split('/')) + len_a = len(a.category.split("/")) return len_a @@ -327,8 +321,8 @@

    Source code for apptools.preferences.ui.preferences_manager

    # # fixme: Currently we have to create a dummy page for the root node # event though the root does not get shown in the tree! - root_page = PreferencesPage(name='Root', preferences_path='root') - root = PreferencesNode(page=root_page) + root_page = PreferencesPage(name="Root", preferences_path="root") + root = PreferencesNode(page=root_page) for page in self.pages: # Get the page's parent node. @@ -344,23 +338,18 @@

    Source code for apptools.preferences.ui.preferences_manager

    def _selection_changed(self, new_selection): self.selected_node = new_selection - def _selected_node_changed(self, new): """ Static trait change handler. """ if self.selected_node: self.selected_page = self.selected_node.page - return - #### Methods ##############################################################
    [docs] def apply(self): """ Apply all changes made in the manager. """ for page in self.pages: - page.apply() - - return
    + page.apply()
    ########################################################################### # Private interface. @@ -372,13 +361,11 @@

    Source code for apptools.preferences.ui.preferences_manager

    parent = root if len(page.category) > 0: - components = page.category.split('/') + components = page.category.split("/") for component in components: parent = parent.lookup(component) return parent
    - -#### EOF ######################################################################
    @@ -390,13 +377,11 @@

    Source code for apptools.preferences.ui.preferences_manager

    @@ -420,10 +405,10 @@

    Quick search

    © Copyright 2008-2020, Enthought
  • - Last updated on Jun 12, 2020. + Last updated on Dec 17, 2020.
  • - Created using Sphinx 1.8.5. + Created using Sphinx 2.3.1.
  • diff --git a/_modules/apptools/preferences/ui/preferences_node.html b/_modules/apptools/preferences/ui/preferences_node.html index d2d514482..2aed6f3a0 100644 --- a/_modules/apptools/preferences/ui/preferences_node.html +++ b/_modules/apptools/preferences/ui/preferences_node.html @@ -13,9 +13,11 @@ @@ -72,28 +74,22 @@
    -
    +

    Source code for apptools.preferences.ui.preferences_node

    -#------------------------------------------------------------------------------
    -# Copyright (c) 2005, Enthought, Inc.
    +# (C) Copyright 2005-2020 Enthought, Inc., Austin, TX
     # All rights reserved.
     #
     # This software is provided without warranty under the terms of the BSD
    -# license included in enthought/LICENSE.txt and may be redistributed only
    -# under the conditions described in the aforementioned license.  The license
    +# license included in LICENSE.txt and may be redistributed only under
    +# the conditions described in the aforementioned license. The license
     # is also available online at http://www.enthought.com/licenses/BSD.txt
    -# Thanks for using Enthought open source!
     #
    -# Author: Enthought, Inc.
    -# Description: <Enthought pyface package component>
    -#------------------------------------------------------------------------------
    +# Thanks for using Enthought open source!
     """ Abstract base class for a node in a preferences dialog. """
     
    -from __future__ import print_function
    -
     # Enthought library imports.
    -from traits.api import Delegate, Instance, Str
    +from traits.api import Delegate, Instance
     
     # Local imports.
     from .i_preferences_page import IPreferencesPage
    @@ -101,7 +97,7 @@ 

    Source code for apptools.preferences.ui.preferences_node

    [docs]class PreferencesNode(TreeItem): - """ Abstract base class for a node in a preferences dialog. + """Abstract base class for a node in a preferences dialog. A preferences node has a name and an image which are used to represent the node in a preferences dialog (usually in the form of a tree). @@ -112,10 +108,10 @@

    Source code for apptools.preferences.ui.preferences_node

    # The page's help identifier (optional). If a help Id *is* provided then # there will be a 'Help' button shown on the preference page. - help_id = Delegate('page') + help_id = Delegate("page") # The page name (this is what is shown in the preferences dialog. - name = Delegate('page') + name = Delegate("page") # The page that we are a node for. page = Instance(IPreferencesPage) @@ -128,7 +124,7 @@

    Source code for apptools.preferences.ui.preferences_node

    """ Returns the string representation of the item. """ if self.page is None: - s = 'root' + s = "root" else: s = self.page.name @@ -147,7 +143,7 @@

    Source code for apptools.preferences.ui.preferences_node

    return self.page.create_control(parent)
    [docs] def lookup(self, name): - """ Returns the child of this node with the specified Id. + """Returns the child of this node with the specified Id. Returns None if no such child exists. @@ -166,17 +162,13 @@

    Source code for apptools.preferences.ui.preferences_node

    # Debugging interface. ########################################################################### -
    [docs] def dump(self, indent=''): +
    [docs] def dump(self, indent=""): """ Pretty-print the node to stdout. """ - print(indent, 'Node', str(self)) + print(indent, "Node", str(self)) for child in self.children: - child.dump(indent+' ') - - return
    - -#### EOF ###################################################################### + child.dump(indent + " ")
    @@ -188,13 +180,11 @@

    Source code for apptools.preferences.ui.preferences_node

    @@ -218,10 +208,10 @@

    Quick search

    © Copyright 2008-2020, Enthought
  • - Last updated on Jun 12, 2020. + Last updated on Dec 17, 2020.
  • - Created using Sphinx 1.8.5. + Created using Sphinx 2.3.1.
  • diff --git a/_modules/apptools/preferences/ui/preferences_page.html b/_modules/apptools/preferences/ui/preferences_page.html index 0b8d1e09f..b9aa66f87 100644 --- a/_modules/apptools/preferences/ui/preferences_page.html +++ b/_modules/apptools/preferences/ui/preferences_page.html @@ -13,9 +13,11 @@ @@ -72,10 +74,19 @@
    -
    +

    Source code for apptools.preferences.ui.preferences_page

    -""" A page in a preferences dialog. """
    +# (C) Copyright 2005-2020 Enthought, Inc., Austin, TX
    +# All rights reserved.
    +#
    +# This software is provided without warranty under the terms of the BSD
    +# license included in LICENSE.txt and may be redistributed only under
    +# the conditions described in the aforementioned license. The license
    +# is also available online at http://www.enthought.com/licenses/BSD.txt
    +#
    +# Thanks for using Enthought open source!
    +""" A page in a preferences dialog. """
     
     
     # Enthought library imports.
    @@ -90,8 +101,6 @@ 

    Source code for apptools.preferences.ui.preferences_page

    class PreferencesPage(PreferencesHelper): """ A page in a preferences dialog. """ - - #### 'IPreferencesPage' interface ######################################### # The page's category (e.g. 'General/Appearance'). The empty string means @@ -130,31 +139,9 @@

    Source code for apptools.preferences.ui.preferences_page

    for trait_name, value in self._changed.items(): if self._is_preference_trait(trait_name): - self.preferences.set('%s.%s' % (path, trait_name), value) - - self._changed.clear() - - return
    - - # fixme: We would like to be able to have the following API so that - # developers are not forced into using traits UI for their preferences - # pages, but at the moment I can't work out how to do it! -## def create_control(self, parent): -## """ Create the toolkit-specific control that represents the page. """ - -## if self._ui is None: -## self._ui = self.edit_traits(parent=parent, kind='subpanel') - -## return self._ui.control + self.preferences.set("%s.%s" % (path, trait_name), value) -## def destroy_control(self): -## """ Destroy the toolkit-specific control that represents the page. """ - -## if self._ui is not None: -## self._ui.dispose() -## self._ui = None - -## return + self._changed.clear()
    ########################################################################### # Private interface. @@ -163,7 +150,7 @@

    Source code for apptools.preferences.ui.preferences_page

    #### Trait change handlers ################################################ def _anytrait_changed(self, trait_name, old, new): - """ Static trait change handler. + """Static trait change handler. This is an important override! In the base-class when a trait is changed the preferences node is updated too. Here, we stop that from @@ -172,30 +159,28 @@

    Source code for apptools.preferences.ui.preferences_page

    """ - # If the trait was a list or dict '_items' trait then just treat it as - # if the entire list or dict was changed. - if trait_name.endswith('_items'): + if self._is_preference_trait(trait_name): + self._changed[trait_name] = new + elif trait_name.endswith("_items"): + # If the trait was a list or dict '_items' trait then just treat it + # as if the entire list or dict was changed. trait_name = trait_name[:-6] if self._is_preference_trait(trait_name): self._changed[trait_name] = getattr(self, trait_name) - elif self._is_preference_trait(trait_name): - self._changed[trait_name] = new - - return - # fixme: Pretty much duplicated in 'PreferencesHelper' (except for the # class name of course!). def _is_preference_trait(self, trait_name): """ Return True if a trait represents a preference value. """ - if trait_name.startswith('_') or trait_name.endswith('_') \ - or trait_name in PreferencesPage.class_traits(): + if ( + trait_name.startswith("_") + or trait_name.endswith("_") + or trait_name in PreferencesPage.class_traits() + ): return False - return True
    - -#### EOF ###################################################################### + return trait_name in self.editable_traits()
    @@ -207,13 +192,11 @@

    Source code for apptools.preferences.ui.preferences_page

    @@ -237,10 +220,10 @@

    Quick search

    © Copyright 2008-2020, Enthought
  • - Last updated on Jun 12, 2020. + Last updated on Dec 17, 2020.
  • - Created using Sphinx 1.8.5. + Created using Sphinx 2.3.1.
  • diff --git a/_modules/apptools/preferences/ui/tree_item.html b/_modules/apptools/preferences/ui/tree_item.html index a8965549a..ffcc109ca 100644 --- a/_modules/apptools/preferences/ui/tree_item.html +++ b/_modules/apptools/preferences/ui/tree_item.html @@ -13,9 +13,11 @@ @@ -72,22 +74,18 @@
    -
    +

    Source code for apptools.preferences.ui.tree_item

    -#------------------------------------------------------------------------------
    -# Copyright (c) 2005, Enthought, Inc.
    +# (C) Copyright 2005-2020 Enthought, Inc., Austin, TX
     # All rights reserved.
     #
     # This software is provided without warranty under the terms of the BSD
    -# license included in enthought/LICENSE.txt and may be redistributed only
    -# under the conditions described in the aforementioned license.  The license
    +# license included in LICENSE.txt and may be redistributed only under
    +# the conditions described in the aforementioned license. The license
     # is also available online at http://www.enthought.com/licenses/BSD.txt
    -# Thanks for using Enthought open source!
     #
    -# Author: Enthought, Inc.
    -# Description: <Enthought pyface package component>
    -#------------------------------------------------------------------------------
    +# Thanks for using Enthought open source!
     """ A generic base-class for items in a tree data structure.
     
     An example:-
    @@ -122,7 +120,7 @@ 

    Source code for apptools.preferences.ui.tree_item

    allows_children = Bool(True) # The item's children. - children = List(Instance('TreeItem')) + children = List(Instance("TreeItem")) # Arbitrary data associated with the item. data = Any @@ -131,7 +129,7 @@

    Source code for apptools.preferences.ui.tree_item

    has_children = Property(Bool) # The item's parent. - parent = Instance('TreeItem') + parent = Instance("TreeItem") ########################################################################### # 'object' interface. @@ -141,7 +139,7 @@

    Source code for apptools.preferences.ui.tree_item

    """ Returns the informal string representation of the object. """ if self.data is None: - s = '' + s = "" else: s = str(self.data) @@ -163,7 +161,7 @@

    Source code for apptools.preferences.ui.tree_item

    #### Methods ##############################################################
    [docs] def append(self, child): - """ Appends a child to this item. + """Appends a child to this item. This removes the child from its current parent (if it has one). @@ -172,7 +170,7 @@

    Source code for apptools.preferences.ui.tree_item

    return self.insert(len(self.children), child)
    [docs] def insert(self, index, child): - """ Inserts a child into this item at the specified index. + """Inserts a child into this item at the specified index. This removes the child from its current parent (if it has one). @@ -195,7 +193,7 @@

    Source code for apptools.preferences.ui.tree_item

    return child
    [docs] def insert_before(self, before, child): - """ Inserts a child into this item before the specified item. + """Inserts a child into this item before the specified item. This removes the child from its current parent (if it has one). @@ -208,7 +206,7 @@

    Source code for apptools.preferences.ui.tree_item

    return (index, child)
    [docs] def insert_after(self, after, child): - """ Inserts a child into this item after the specified item. + """Inserts a child into this item after the specified item. This removes the child from its current parent (if it has one). @@ -219,8 +217,6 @@

    Source code for apptools.preferences.ui.tree_item

    self.insert(index + 1, child) return (index, child)
    - -#### EOF ######################################################################
    @@ -232,13 +228,11 @@

    Source code for apptools.preferences.ui.tree_item

    @@ -262,10 +256,10 @@

    Quick search

    © Copyright 2008-2020, Enthought
  • - Last updated on Jun 12, 2020. + Last updated on Dec 17, 2020.
  • - Created using Sphinx 1.8.5. + Created using Sphinx 2.3.1.
  • diff --git a/_modules/apptools/preferences/ui/widget_editor.html b/_modules/apptools/preferences/ui/widget_editor.html new file mode 100644 index 000000000..431d64f87 --- /dev/null +++ b/_modules/apptools/preferences/ui/widget_editor.html @@ -0,0 +1,232 @@ + + + + + + + apptools.preferences.ui.widget_editor — Apptools Documentation + + + + + + + + + + + + + + + + + + + +
    +
    +
    +
    + +
    +
    + +
    +
    +
    + + + + + + +
    +
    +
    + + +
    +
    + +
    +
    + +

    Source code for apptools.preferences.ui.widget_editor

    +# (C) Copyright 2005-2020 Enthought, Inc., Austin, TX
    +# All rights reserved.
    +#
    +# This software is provided without warranty under the terms of the BSD
    +# license included in LICENSE.txt and may be redistributed only under
    +# the conditions described in the aforementioned license. The license
    +# is also available online at http://www.enthought.com/licenses/BSD.txt
    +#
    +# Thanks for using Enthought open source!
    +""" An instance editor that allows total control over widget creation. """
    +
    +
    +# Enthought library imports.
    +from traits.api import Any
    +from traitsui.api import EditorFactory
    +from traitsui.toolkit import toolkit_object
    +Editor = toolkit_object('editor:Editor')
    +
    +
    +class _WidgetEditor(Editor):
    +    """ An instance editor that allows total control over widget creation. """
    +
    +    #### '_WidgetEditor' interface ############################################
    +
    +    # The toolkit-specific parent of the editor.
    +    parent = Any
    +
    +    ###########################################################################
    +    # '_WidgetEditor' interface.
    +    ###########################################################################
    +
    +    def init(self, parent):
    +        """ Initialize the editor. """
    +
    +        self.parent = parent
    +
    +        # fixme: What if there are no pages?!?
    +        page = self.object.pages[0]
    +
    +        # Create the editor's control.
    +        self.control = page.create_control(parent)
    +
    +        # Listen for the page being changed.
    +        self.object.on_trait_change(self._on_page_changed, "selected_page")
    +
    +    def dispose(self):
    +        """ Dispose of the editor. """
    +
    +        page = self.object.selected_page
    +        page.destroy_control()
    +
    +    def update_editor(self):
    +        """ Update the editor. """
    +
    +        pass
    +
    +    ###########################################################################
    +    # Private interface.
    +    ###########################################################################
    +
    +    def _on_page_changed(self, obj, trait_name, old, new):
    +        """ Dynamic trait change handler. """
    +
    +        if old is not None:
    +            old.destroy_control()
    +
    +        if new is not None:
    +            self.control = new.create_control(self.parent)
    +
    +
    +
    [docs]class WidgetEditor(EditorFactory): + """ A factory widget editors. """ + + ########################################################################### + # 'object' interface. + ########################################################################### + + def __call__(self, *args, **traits): + """ Call the object. """ + + return self.trait_set(**traits) + + ########################################################################### + # 'EditorFactory' interface. + ########################################################################### + +
    [docs] def simple_editor(self, ui, object, name, description, parent): + """ Create a simple editor. """ + + editor = _WidgetEditor( + parent, + factory=self, + ui=ui, + object=object, + name=name, + description=description, + ) + + return editor
    + + custom_editor = simple_editor + text_editor = simple_editor + readonly_editor = simple_editor
    +
    + +
    +
    +
    +
    +
    + + + +
    +
    +
    +
    +
    + +
    +
    + +
    +
    +
    + +
    + + \ No newline at end of file diff --git a/_modules/apptools/scripting/package_globals.html b/_modules/apptools/scripting/package_globals.html index fd0119b6b..34096d085 100644 --- a/_modules/apptools/scripting/package_globals.html +++ b/_modules/apptools/scripting/package_globals.html @@ -13,9 +13,11 @@ @@ -72,20 +74,27 @@
    -
    +

    Source code for apptools.scripting.package_globals

    -"""
    +# (C) Copyright 2005-2020 Enthought, Inc., Austin, TX
    +# All rights reserved.
    +#
    +# This software is provided without warranty under the terms of the BSD
    +# license included in LICENSE.txt and may be redistributed only under
    +# the conditions described in the aforementioned license. The license
    +# is also available online at http://www.enthought.com/licenses/BSD.txt
    +#
    +# Thanks for using Enthought open source!
    +"""
     Globals for the scripting package.
     """
    -# Author: Prabhu Ramachandran <prabhu@aero.iitb.ac.in>
    -# Copyright (c) 2008, Prabhu Ramachandran and Enthought, Inc.
    -# License: BSD Style.
     
     
     # The global recorder.
     _recorder = None
     
    +
     
    [docs]def get_recorder(): """Return the global recorder. Does not create a new one if none exists. @@ -93,13 +102,11 @@

    Source code for apptools.scripting.package_globals

    global _recorder return _recorder
    +
    [docs]def set_recorder(rec): - """Set the global recorder instance. - """ + """Set the global recorder instance.""" global _recorder _recorder = rec
    - -
    @@ -111,13 +118,11 @@

    Source code for apptools.scripting.package_globals

    @@ -141,10 +146,10 @@

    Quick search

    © Copyright 2008-2020, Enthought
  • - Last updated on Jun 12, 2020. + Last updated on Dec 17, 2020.
  • - Created using Sphinx 1.8.5. + Created using Sphinx 2.3.1.
  • diff --git a/_modules/apptools/scripting/recordable.html b/_modules/apptools/scripting/recordable.html index 1958670ae..324ccca9d 100644 --- a/_modules/apptools/scripting/recordable.html +++ b/_modules/apptools/scripting/recordable.html @@ -13,9 +13,11 @@ @@ -72,15 +74,21 @@
    -
    +

    Source code for apptools.scripting.recordable

    -"""
    +# (C) Copyright 2005-2020 Enthought, Inc., Austin, TX
    +# All rights reserved.
    +#
    +# This software is provided without warranty under the terms of the BSD
    +# license included in LICENSE.txt and may be redistributed only under
    +# the conditions described in the aforementioned license. The license
    +# is also available online at http://www.enthought.com/licenses/BSD.txt
    +#
    +# Thanks for using Enthought open source!
    +"""
     Decorator to mark functions and methods as recordable.
     """
    -# Author: Prabhu Ramachandran <prabhu@aero.iitb.ac.in>
    -# Copyright (c) 2008, Prabhu Ramachandran and Enthought, Inc.
    -# License: BSD Style.
     
     from .package_globals import get_recorder
     
    @@ -95,9 +103,6 @@ 

    Source code for apptools.scripting.recordable

    This will record the function only if the global recorder has been set via a `set_recorder` function call. - - This is almost entirely copied from the - apptools.appscripting.scriptable.scriptable decorator. """ def _wrapper(*args, **kw): @@ -140,13 +145,11 @@

    Source code for apptools.scripting.recordable

    diff --git a/_modules/apptools/scripting/recorder.html b/_modules/apptools/scripting/recorder.html index b3ae49a23..2c84d2f66 100644 --- a/_modules/apptools/scripting/recorder.html +++ b/_modules/apptools/scripting/recorder.html @@ -13,9 +13,11 @@ @@ -72,33 +74,44 @@
    -
    +

    Source code for apptools.scripting.recorder

    -"""
    +# (C) Copyright 2005-2020 Enthought, Inc., Austin, TX
    +# All rights reserved.
    +#
    +# This software is provided without warranty under the terms of the BSD
    +# license included in LICENSE.txt and may be redistributed only under
    +# the conditions described in the aforementioned license. The license
    +# is also available online at http://www.enthought.com/licenses/BSD.txt
    +#
    +# Thanks for using Enthought open source!
    +"""
     Code to support recording to a readable and executable Python script.
     
    -TODO:
    +FIXME:
         - Support for dictionaries?
    -
     """
    -# Author: Prabhu Ramachandran <prabhu@aero.iitb.ac.in>
    -# Copyright (c) 2008-2015, Enthought, Inc.
    -# License: BSD Style.
     
    +import builtins
     import warnings
     
    -import six
    -import six.moves.builtins
    -
    -from traits.api import (HasTraits, List, Str, Dict, Bool,
    -        Unicode, Property, Int, Instance)
    +from traits.api import (
    +    HasTraits,
    +    List,
    +    Str,
    +    Dict,
    +    Bool,
    +    Property,
    +    Int,
    +    Instance,
    +)
     from traits.util.camel_case import camel_case_to_python
     
     
    -################################################################################
    +###############################################################################
     # `_RegistryData` class.
    -################################################################################
    +###############################################################################
     class _RegistryData(HasTraits):
         # Object's script ID
         script_id = Property(Str)
    @@ -107,10 +120,10 @@ 

    Source code for apptools.scripting.recorder

         path = Property(Str)
     
         # Parent data for this object if any.
    -    parent_data = Instance('_RegistryData', allow_none=True)
    +    parent_data = Instance("_RegistryData", allow_none=True)
     
         # The name of the trait on the parent which is this object.
    -    trait_name_on_parent = Str('')
    +    trait_name_on_parent = Str("")
     
         # List of traits we are listening for on this object.
         names = List(Str)
    @@ -121,28 +134,28 @@ 

    Source code for apptools.scripting.recorder

         # List of traits that are lists.
         list_names = List(Str)
     
    -    _script_id = Str('')
    +    _script_id = Str("")
     
    -    ######################################################################
    +    ###########################################################################
         # Non-public interface.
    -    ######################################################################
    +    ###########################################################################
         def _get_path(self):
             pdata = self.parent_data
    -        path = ''
    +        path = ""
             if pdata is not None:
                 pid = pdata.script_id
                 ppath = pdata.path
                 tnop = self.trait_name_on_parent
    -            if '[' in tnop:
    +            if "[" in tnop:
                     # If the object is a nested object through an iterator,
                     # we instantiate it and don't refer to it through the
                     # path, this makes scripting convenient.
                     if len(ppath) == 0:
    -                    path = pid + '.' + tnop
    +                    path = pid + "." + tnop
                     else:
    -                    path = ppath + '.' + tnop
    +                    path = ppath + "." + tnop
                 else:
    -                path = ppath + '.' + tnop
    +                path = ppath + "." + tnop
     
             return path
     
    @@ -150,35 +163,34 @@ 

    Source code for apptools.scripting.recorder

             sid = self._script_id
             if len(sid) == 0:
                 pdata = self.parent_data
    -            sid = pdata.script_id + '.' + self.trait_name_on_parent
    +            sid = pdata.script_id + "." + self.trait_name_on_parent
             return sid
     
         def _set_script_id(self, id):
             self._script_id = id
     
     
    -
    -################################################################################
    +###############################################################################
     # `RecorderError` class.
    -################################################################################
    +###############################################################################
     
    [docs]class RecorderError(Exception): pass
    -################################################################################ +############################################################################### # `Recorder` class. -################################################################################ +###############################################################################
    [docs]class Recorder(HasTraits): # The lines of code recorded. lines = List(Str) # Are we recording or not? - recording = Bool(False, desc='if script recording is enabled or not') + recording = Bool(False, desc="if script recording is enabled or not") # The Python script we have recorded so far. This is just a # convenience trait for the `get_code()` method. - script = Property(Unicode) + script = Property(Str) ######################################## # Private traits. @@ -214,16 +226,17 @@

    Source code for apptools.scripting.recorder

         # in which case we don't want to do any recording.
         _in_function = Bool(False)
     
    -    ######################################################################
    +    ###########################################################################
         # `Recorder` interface.
    -    ######################################################################
    +    ###########################################################################
     
    [docs] def record(self, code): """Record a string to be stored to the output file. - Parameters: - ----------- + Parameters + ---------- - code - A string of text. + code : str + A string of text. """ if self.recording and not self._in_function: lines = self.lines @@ -232,8 +245,15 @@

    Source code for apptools.scripting.recorder

                 # Add the code.
                 lines.append(code)
    -
    [docs] def register(self, object, parent=None, trait_name_on_parent='', - ignore=None, known=False, script_id=None): +
    [docs] def register( + self, + object, + parent=None, + trait_name_on_parent="", + ignore=None, + known=False, + script_id=None, + ): """Register an object with the recorder. This sets up the object for recording. @@ -255,8 +275,8 @@

    Source code for apptools.scripting.recorder

             If the `object` has a trait named `recorder` then this recorder
             instance will be set to it if possible.
     
    -        Parameters:
    -        -----------
    +        Parameters
    +        ----------
     
             object : Instance(HasTraits)
                 The object to register in the registry.
    @@ -296,22 +316,28 @@ 

    Source code for apptools.scripting.recorder

     
             if isinstance(object, HasTraits):
                 # Always ignore these.
    -            ignore.extend(['trait_added', 'trait_modified'])
    +            ignore.extend(["trait_added", "trait_modified"])
     
                 sub_recordables = list(object.traits(record=True).keys())
                 # Find all the trait names we must ignore.
                 ignore.extend(object.traits(record=False).keys())
                 # The traits to listen for.
    -            tnames = [t for t in object.trait_names()
    -                      if not t.startswith('_') and not t.endswith('_') \
    -                         and t not in ignore]
    +            tnames = [
    +                t
    +                for t in object.trait_names()
    +                if not t.startswith("_")
    +                and not t.endswith("_")
    +                and t not in ignore
    +            ]
                 # Find all list traits.
                 trts = object.traits()
                 list_names = []
                 for t in tnames:
                     tt = trts[t].trait_type
    -                if hasattr(tt, 'default_value_type') and \
    -                        tt.default_value_type == 5:
    +                if (
    +                    hasattr(tt, "default_value_type")
    +                    and tt.default_value_type == 5
    +                ):
                         list_names.append(t)
             else:
                 # No traits, so we can't do much.
    @@ -322,11 +348,11 @@ 

    Source code for apptools.scripting.recorder

             # Setup the registry data.
     
             # If a script id is supplied try and use it.
    -        sid = ''
    +        sid = ""
             if script_id is not None:
                 r_registry = self._reverse_registry
                 while script_id in r_registry:
    -                script_id = '%s1'%script_id
    +                script_id = "%s1" % script_id
                 sid = script_id
                 # Add the chosen id to special_id list.
                 self._special_ids.append(sid)
    @@ -338,19 +364,21 @@ 

    Source code for apptools.scripting.recorder

             else:
                 pdata = self._get_registry_data(parent)
                 tnop = trait_name_on_parent
    -            if '[' in tnop:
    +            if "[" in tnop:
                     # If the object is a nested object through an iterator,
                     # we instantiate it and don't refer to it through the
                     # path, this makes scripting convenient.
                     sid = self._get_unique_name(object)
     
             # Register the object with the data.
    -        data = _RegistryData(script_id=sid,
    -                             parent_data=pdata,
    -                             trait_name_on_parent=trait_name_on_parent,
    -                             names=tnames,
    -                             sub_recordables=sub_recordables,
    -                             list_names=list_names)
    +        data = _RegistryData(
    +            script_id=sid,
    +            parent_data=pdata,
    +            trait_name_on_parent=trait_name_on_parent,
    +            names=tnames,
    +            sub_recordables=sub_recordables,
    +            list_names=list_names,
    +        )
             registry[object] = data
     
             # Now get the script id of the object -- note that if sid is ''
    @@ -366,19 +394,22 @@ 

    Source code for apptools.scripting.recorder

                 self._known_ids.append(sid)
     
             # Try and set the recorder attribute if necessary.
    -        if hasattr(object, 'recorder'):
    +        if hasattr(object, "recorder"):
                 try:
                     object.recorder = self
                 except Exception as e:
    -                msg = "Cannot set 'recorder' trait of object %r: "\
    -                      "%s"%(object, e)
    +                msg = "Cannot set 'recorder' trait of object %r: " "%s" % (
    +                    object,
    +                    e,
    +                )
                     warnings.warn(msg, warnings.RuntimeWarning)
     
             if isinstance(object, HasTraits):
                 # Add handler for lists.
                 for name in list_names:
    -                object.on_trait_change(self._list_items_listner,
    -                                       '%s_items'%name)
    +                object.on_trait_change(
    +                    self._list_items_listner, "%s_items" % name
    +                )
     
                 # Register all sub-recordables.
                 for name in sub_recordables:
    @@ -387,12 +418,14 @@ 

    Source code for apptools.scripting.recorder

                         # Don't register the object itself but register its
                         # children.
                         for i, child in enumerate(obj):
    -                        attr = '%s[%d]'%(name, i)
    -                        self.register(child, parent=object,
    -                                      trait_name_on_parent=attr)
    +                        attr = "%s[%d]" % (name, i)
    +                        self.register(
    +                            child, parent=object, trait_name_on_parent=attr
    +                        )
                     elif obj is not None:
    -                    self.register(obj, parent=object,
    -                                  trait_name_on_parent=name)
    +                    self.register(
    +                        obj, parent=object, trait_name_on_parent=name
    +                    )
                     # Listen for changes to the trait itself so the newly
                     # assigned object can also be listened to.
                     object.on_trait_change(self._object_changed_handler, name)
    @@ -411,19 +444,22 @@ 

    Source code for apptools.scripting.recorder

             data = registry[object]
     
             # Try and unset the recorder attribute if necessary.
    -        if hasattr(object, 'recorder'):
    +        if hasattr(object, "recorder"):
                 try:
                     object.recorder = None
                 except Exception as e:
    -                msg = "Cannot unset 'recorder' trait of object %r:"\
    -                      "%s"%(object, e)
    +                msg = "Cannot unset 'recorder' trait of object %r:" "%s" % (
    +                    object,
    +                    e,
    +                )
                     warnings.warn(msg, warnings.RuntimeWarning)
     
             if isinstance(object, HasTraits):
                 # Remove all list_items handlers.
                 for name in data.list_names:
    -                object.on_trait_change(self._list_items_listner,
    -                                       '%s_items'%name, remove=True)
    +                object.on_trait_change(
    +                    self._list_items_listner, "%s_items" % name, remove=True
    +                )
     
                 # Unregister all sub-recordables.
                 for name in data.sub_recordables:
    @@ -435,8 +471,9 @@ 

    Source code for apptools.scripting.recorder

                     elif obj is not None:
                         self.unregister(obj)
                     # Remove the trait handler for trait assignments.
    -                object.on_trait_change(self._object_changed_handler,
    -                                       name, remove=True)
    +                object.on_trait_change(
    +                    self._object_changed_handler, name, remove=True
    +                )
                 # Now remove listner for the object itself.
                 object.on_trait_change(self._listner, data.names, remove=True)
     
    @@ -450,10 +487,7 @@ 

    Source code for apptools.scripting.recorder

             """Save the recorded lines to the given file.  It does not close
             the file.
             """
    -        if six.PY3:
    -            file.write(self.get_code())
    -        else:
    -            file.write(six.text_type(self.get_code(), encoding='utf-8'))
    +        file.write(self.get_code())
             file.flush()
    [docs] def record_function(self, func, args, kw): @@ -470,7 +504,7 @@

    Source code for apptools.scripting.recorder

                     self._in_function = False
     
                 # Register the result if it is not None.
    -            if func.__name__ == '__init__':
    +            if func.__name__ == "__init__":
                     f_self = args[0]
                     code = self._import_class_string(f_self.__class__)
                     self.lines.append(code)
    @@ -478,9 +512,9 @@ 

    Source code for apptools.scripting.recorder

                 else:
                     return_str = self._return_as_string(result)
                 if len(return_str) > 0:
    -                self.lines.append('%s = %s'%(return_str, call_str))
    +                self.lines.append("%s = %s" % (return_str, call_str))
                 else:
    -                self.lines.append('%s'%(call_str))
    +                self.lines.append("%s" % (call_str))
             else:
                 result = func(*args, **kw)
             return result
    @@ -490,13 +524,14 @@

    Source code for apptools.scripting.recorder

             and close the file when done.
             """
             from pyface.api import FileDialog, OK
    -        wildcard = 'Python files (*.py)|*.py|' + FileDialog.WILDCARD_ALL
    -        dialog = FileDialog(title='Save Script',
    -                            action='save as', wildcard=wildcard
    -                            )
    +
    +        wildcard = "Python files (*.py)|*.py|" + FileDialog.WILDCARD_ALL
    +        dialog = FileDialog(
    +            title="Save Script", action="save as", wildcard=wildcard
    +        )
             if dialog.open() == OK:
                 fname = dialog.path
    -            f = open(fname, 'w')
    +            f = open(fname, "w")
                 self.save(f)
                 f.close()
    @@ -518,7 +553,7 @@

    Source code for apptools.scripting.recorder

     
     
    [docs] def get_code(self): """Returns the recorded lines as a string of printable code.""" - return '\n'.join(self.lines) + '\n'
    + return "\n".join(self.lines) + "\n"
    [docs] def is_registered(self, object): """Returns True if the given object is registered with the @@ -553,24 +588,23 @@

    Source code for apptools.scripting.recorder

                 known_ids.append(script_id)
                 if obj is not None:
                     data = self._registry.get(obj)
    -                result = ''
    +                result = ""
                     if len(data.path) > 0:
                         # Record code for instantiation of object.
    -                    result = '%s = %s'%(script_id, data.path)
    +                    result = "%s = %s" % (script_id, data.path)
                     else:
                         # This is not the best thing to do but better than
                         # nothing.
                         result = self._import_class_string(obj.__class__)
                         cls = obj.__class__.__name__
    -                    mod = obj.__module__
    -                    result += '\n%s = %s()'%(script_id, cls)
    +                    result += "\n%s = %s()" % (script_id, cls)
     
                     if len(result) > 0:
    -                    self.lines.extend(result.split('\n'))
    + self.lines.extend(result.split("\n"))
    - ###################################################################### + ########################################################################### # Non-public interface. - ###################################################################### + ########################################################################### def _get_unique_name(self, obj): """Return a unique object name (a string). Note that this does not cache the object, so if called with the same object 3 times @@ -578,11 +612,11 @@

    Source code for apptools.scripting.recorder

             """
             cname = obj.__class__.__name__
             nm = self._name_map
    -        result = ''
    +        result = ""
             builtin = False
    -        if cname in six.moves.builtins.__dict__:
    +        if cname in builtins.__dict__:
                 builtin = True
    -            if hasattr(obj, '__name__'):
    +            if hasattr(obj, "__name__"):
                     cname = obj.__name__
             else:
                 cname = camel_case_to_python(cname)
    @@ -592,12 +626,12 @@ 

    Source code for apptools.scripting.recorder

                 if cname in nm:
                     id = nm[cname] + 1
                     nm[cname] = id
    -                result = '%s%d'%(cname, id)
    +                result = "%s%d" % (cname, id)
                 else:
                     nm[cname] = 0
                     # The first id doesn't need a number if it isn't builtin.
                     if builtin:
    -                    result = '%s0'%(cname)
    +                    result = "%s0" % (cname)
                     else:
                         result = cname
             return result
    @@ -606,8 +640,10 @@ 

    Source code for apptools.scripting.recorder

             """Get the data for an object from registry."""
             data = self._registry.get(object)
             if data is None:
    -            msg = "Recorder: Can't get script_id since object %s not registered"
    -            raise RecorderError(msg%(object))
    +            msg = (
    +                "Recorder: Can't get script_id since object %s not registered"
    +            )
    +            raise RecorderError(msg % (object))
             return data
     
         def _listner(self, object, name, old, new):
    @@ -632,17 +668,16 @@ 

    Source code for apptools.scripting.recorder

                 new_repr = repr(new)
                 sid = self._get_registry_data(object).script_id
                 if len(sid) == 0:
    -                msg = '%s = %r'%(name, new)
    +                msg = "%s = %r" % (name, new)
                 else:
    -                msg = '%s.%s = %r'%(sid, name, new)
    -            if new_repr.startswith('<') and new_repr.endswith('>'):
    -                self.record('# ' + msg)
    +                msg = "%s.%s = %r" % (sid, name, new)
    +            if new_repr.startswith("<") and new_repr.endswith(">"):
    +                self.record("# " + msg)
                 else:
                     self.record(msg)
     
         def _list_items_listner(self, object, name, old, event):
    -        """The listner for *_items on list traits of the object.
    -        """
    +        """The listner for *_items on list traits of the object."""
             # Set the path of registered objects in the modified list and
             # all their children.  This is done by unregistering the object
             # and re-registering them.  This is slow but.
    @@ -655,7 +690,7 @@ 

    Source code for apptools.scripting.recorder

                     data = registry.get(item)
                     tnop = data.trait_name_on_parent
                     if len(tnop) > 0:
    -                    data.trait_name_on_parent = '%s[%d]'%(trait_name, i)
    +                    data.trait_name_on_parent = "%s[%d]" % (trait_name, i)
     
             # Record the change.
             if self.recording and not self._in_function:
    @@ -663,12 +698,11 @@ 

    Source code for apptools.scripting.recorder

                 removed = event.removed
                 added = event.added
                 nr = len(removed)
    -            slice = '[%d:%d]'%(index, index + nr)
    -            na = len(added)
    +            slice = "[%d:%d]" % (index, index + nr)
                 rhs = [self._object_as_string(item) for item in added]
    -            rhs = ', '.join(rhs)
    -            obj = '%s.%s'%(sid, name[:-6])
    -            msg = '%s%s = [%s]'%(obj, slice, rhs)
    +            rhs = ", ".join(rhs)
    +            obj = "%s.%s" % (sid, name[:-6])
    +            msg = "%s%s = [%s]" % (obj, slice, rhs)
                 self.record(msg)
     
         def _object_changed_handler(self, object, name, old, new):
    @@ -679,24 +713,21 @@ 

    Source code for apptools.scripting.recorder

                     self.unregister(old)
             if new is not None:
                 if new not in registry:
    -                self.register(new, parent=object,
    -                              trait_name_on_parent=name)
    +                self.register(new, parent=object, trait_name_on_parent=name)
     
         def _get_script(self):
             return self.get_code()
     
         def _analyze_code(self, code):
    -        """Analyze the code and return extra code if needed.
    -        """
    -        known_ids = self._known_ids
    -        lhs = ''
    +        """Analyze the code and return extra code if needed."""
    +        lhs = ""
             try:
                 lhs = code.split()[0]
             except IndexError:
                 pass
     
    -        if '.' in lhs:
    -            ob_name = lhs.split('.')[0]
    +        if "." in lhs:
    +            ob_name = lhs.split(".")[0]
                 self.write_script_id_in_namespace(ob_name)
     
         def _function_as_string(self, func, args, kw):
    @@ -706,53 +737,53 @@ 

    Source code for apptools.scripting.recorder

             # Even if func is really a decorated method it never shows up as
             # a bound or unbound method here, so we have to inspect the
             # argument names to figure out if this is a method or function.
    -        if func_code.co_argcount > 0 and \
    -           func_code.co_varnames[0] == 'self':
    +        if func_code.co_argcount > 0 and func_code.co_varnames[0] == "self":
                 # This is a method, the first argument is bound to self.
                 f_self = args[0]
                 # Convert the remaining arguments to strings.
                 argl = [self._object_as_string(arg) for arg in args[1:]]
     
                 # If this is __init__ we special case it.
    -            if func_name == '__init__':
    +            if func_name == "__init__":
                     # Register the object.
                     self.register(f_self, known=True)
                     func_name = f_self.__class__.__name__
                 else:
                     sid = self._object_as_string(f_self)
    -                func_name = '%s.%s'%(sid, func_name)
    +                func_name = "%s.%s" % (sid, func_name)
             else:
                 argl = [self._object_as_string(arg) for arg in args]
     
             # Convert the keyword args.
    -        kwl = ['%s=%s'%(key, self._object_as_string(value))
    -               for key, value in kw.items()]
    +        kwl = [
    +            "%s=%s" % (key, self._object_as_string(value))
    +            for key, value in kw.items()
    +        ]
             argl.extend(kwl)
     
             # Make a string representation of the args, kw.
    -        argstr = ', '.join(argl)
    -        return '%s(%s)'%(func_name, argstr)
    +        argstr = ", ".join(argl)
    +        return "%s(%s)" % (func_name, argstr)
     
         def _is_arbitrary_object(self, object):
             """Return True if the object is an arbitrary non-primitive object.
     
    -        As done in appscripting, we assume that if the hex id of the object is
    -        in its string representation then it is an arbitrary object.
    +        We assume that if the hex id of the object is in its string
    +        representation then it is an arbitrary object.
             """
             ob_id = id(object)
             orepr = repr(object)
    -        hex_id = "%x"%ob_id
    +        hex_id = "%x" % ob_id
             return hex_id.upper() in orepr.upper()
     
         def _object_as_string(self, object):
    -        """Return a string representing the object.
    -        """
    +        """Return a string representing the object."""
             registry = self._registry
             if object in registry:
                 # Return script id if the object is known; create the script
                 # id on the namespace if needed before that.
                 sid = registry.get(object).script_id
    -            base_id = sid.split('.')[0]
    +            base_id = sid.split(".")[0]
                 self.write_script_id_in_namespace(base_id)
                 return sid
             else:
    @@ -765,11 +796,9 @@ 

    Source code for apptools.scripting.recorder

             return self._object_as_string(object)
     
         def _return_as_string(self, object):
    -        """Return a string given a returned object from a function.
    -        """
    -        result = ''
    -        long_type = long if six.PY2 else int
    -        ignore = (float, complex, bool, int, long_type, str)
    +        """Return a string given a returned object from a function."""
    +        result = ""
    +        ignore = (float, complex, bool, int, str)
             if object is not None and type(object) not in ignore:
                 # If object is not know, register it.
                 registry = self._registry
    @@ -783,15 +812,14 @@ 

    Source code for apptools.scripting.recorder

             return result
     
         def _import_class_string(self, cls):
    -        """Import a class if needed.
    -        """
    +        """Import a class if needed."""
             cname = cls.__name__
    -        result = ''
    -        if cname not in six.moves.builtins.__dict__:
    +        result = ""
    +        if cname not in builtins.__dict__:
                 mod = cls.__module__
    -            typename = '%s.%s'%(mod, cname)
    +            typename = "%s.%s" % (mod, cname)
                 if typename not in self._known_types:
    -                result = 'from %s import %s'%(mod, cname)
    +                result = "from %s import %s" % (mod, cname)
                     self._known_types.append(typename)
             return result
    @@ -805,13 +833,11 @@

    Source code for apptools.scripting.recorder

                   
                 

    @@ -835,10 +861,10 @@

    Quick search

    © Copyright 2008-2020, Enthought
  • - Last updated on Jun 12, 2020. + Last updated on Dec 17, 2020.
  • - Created using Sphinx 1.8.5. + Created using Sphinx 2.3.1.
  • diff --git a/_modules/apptools/scripting/recorder_with_ui.html b/_modules/apptools/scripting/recorder_with_ui.html index 4947321e7..8323559a9 100644 --- a/_modules/apptools/scripting/recorder_with_ui.html +++ b/_modules/apptools/scripting/recorder_with_ui.html @@ -13,9 +13,11 @@ @@ -72,25 +74,31 @@
    -
    +

    Source code for apptools.scripting.recorder_with_ui

    -"""
    +# (C) Copyright 2005-2020 Enthought, Inc., Austin, TX
    +# All rights reserved.
    +#
    +# This software is provided without warranty under the terms of the BSD
    +# license included in LICENSE.txt and may be redistributed only under
    +# the conditions described in the aforementioned license. The license
    +# is also available online at http://www.enthought.com/licenses/BSD.txt
    +#
    +# Thanks for using Enthought open source!
    +"""
     A Recorder subclass that presents a simple user interface.
     """
    -# Author: Prabhu Ramachandran <prabhu@aero.iitb.ac.in>
    -# Copyright (c) 2008, Prabhu Ramachandran.
    -# License: BSD Style.
     
     from traits.api import Code, Button, Int, on_trait_change, Any
    -from traitsui.api import (View, Item, Group, HGroup, CodeEditor,
    -                                     spring, Handler)
    +from traitsui.api import View, Item, Group, HGroup, CodeEditor, spring, Handler
     
     from .recorder import Recorder
     
    -######################################################################
    +
    +###############################################################################
     # `CloseHandler` class.
    -######################################################################
    +###############################################################################
     
    [docs]class CloseHandler(Handler): """This class cleans up after the UI for the recorder is closed.""" @@ -101,19 +109,19 @@

    Source code for apptools.scripting.recorder_with_ui

    return True
    -################################################################################ +############################################################################### # `RecorderWithUI` class. -################################################################################ +###############################################################################
    [docs]class RecorderWithUI(Recorder): """ This class represents a Recorder but with a simple user interface. """ # The code to display - code = Code(editor=CodeEditor(line='current_line')) + code = Code(editor=CodeEditor(line="current_line")) # Button to save script to file. - save_script = Button('Save Script') + save_script = Button("Save Script") # The current line to show, used by the editor. current_line = Int @@ -124,20 +132,21 @@

    Source code for apptools.scripting.recorder_with_ui

    ######################################## # Traits View. view = View( - Group( - HGroup(Item('recording', show_label=True), - spring, - Item('save_script', show_label=False), - ), - Group(Item('code', show_label=False)), - ), - width=600, - height=360, - id='apptools.scripting.recorder_with_ui', - buttons=['Cancel'], - resizable=True, - handler=CloseHandler() - ) + Group( + HGroup( + Item("recording", show_label=True), + spring, + Item("save_script", show_label=False), + ), + Group(Item("code", show_label=False)), + ), + width=600, + height=360, + id="apptools.scripting.recorder_with_ui", + buttons=["Cancel"], + resizable=True, + handler=CloseHandler(), + ) ###################################################################### # RecorderWithUI interface. @@ -158,7 +167,7 @@

    Source code for apptools.scripting.recorder_with_ui

    ###################################################################### # Non-public interface. ###################################################################### - @on_trait_change('lines[]') + @on_trait_change("lines[]") def _update_code(self): self.code = self.get_code() self.current_line = len(self.lines) + 1 @@ -176,13 +185,11 @@

    Source code for apptools.scripting.recorder_with_ui

    @@ -206,10 +213,10 @@

    Quick search

    © Copyright 2008-2020, Enthought
  • - Last updated on Jun 12, 2020. + Last updated on Dec 17, 2020.
  • - Created using Sphinx 1.8.5. + Created using Sphinx 2.3.1.
  • diff --git a/_modules/apptools/scripting/util.html b/_modules/apptools/scripting/util.html index d9f142517..39a0ea9ef 100644 --- a/_modules/apptools/scripting/util.html +++ b/_modules/apptools/scripting/util.html @@ -13,9 +13,11 @@ @@ -72,28 +74,34 @@
    -
    +

    Source code for apptools.scripting.util

    -"""Simple utility functions provided by the scripting API.
    +# (C) Copyright 2005-2020 Enthought, Inc., Austin, TX
    +# All rights reserved.
    +#
    +# This software is provided without warranty under the terms of the BSD
    +# license included in LICENSE.txt and may be redistributed only under
    +# the conditions described in the aforementioned license. The license
    +# is also available online at http://www.enthought.com/licenses/BSD.txt
    +#
    +# Thanks for using Enthought open source!
    +"""Simple utility functions provided by the scripting API.
     """
    -# Author: Prabhu Ramachandran <prabhu [at] aero . iitb . ac . in>
    -# Copyright (c) 2008,  Prabhu Ramachandran
    -# License: BSD Style.
     
     from .recorder import Recorder
     from .recorder_with_ui import RecorderWithUI
     from .package_globals import get_recorder, set_recorder
     
     
    -################################################################################
    +###############################################################################
     # Utility functions.
    -################################################################################
    +###############################################################################
     
    [docs]def start_recording(object, ui=True, **kw): """Convenience function to start recording. Returns the recorder. - Parameters: - ----------- + Parameters + ---------- object : object to record. @@ -104,7 +112,7 @@

    Source code for apptools.scripting.util

         """
         if ui:
             r = RecorderWithUI(root=object)
    -        r.edit_traits(kind='live')
    +        r.edit_traits(kind="live")
         else:
             r = Recorder()
         # Set the global recorder.
    @@ -113,6 +121,7 @@ 

    Source code for apptools.scripting.util

         r.register(object, **kw)
         return r
    +
    [docs]def stop_recording(object, save=True): """Stop recording the object. If `save` is `True`, this will pop up a UI to ask where to save the script. @@ -136,13 +145,11 @@

    Source code for apptools.scripting.util

                   
                 

    @@ -166,10 +173,10 @@

    Quick search

    © Copyright 2008-2020, Enthought
  • - Last updated on Jun 12, 2020. + Last updated on Dec 17, 2020.
  • - Created using Sphinx 1.8.5. + Created using Sphinx 2.3.1.
  • diff --git a/_modules/apptools/selection/errors.html b/_modules/apptools/selection/errors.html index d440c8edd..441880612 100644 --- a/_modules/apptools/selection/errors.html +++ b/_modules/apptools/selection/errors.html @@ -13,9 +13,11 @@ @@ -72,10 +74,21 @@
    -
    +

    Source code for apptools.selection.errors

    -
    [docs]class ProviderNotRegisteredError(Exception): +# (C) Copyright 2005-2020 Enthought, Inc., Austin, TX +# All rights reserved. +# +# This software is provided without warranty under the terms of the BSD +# license included in LICENSE.txt and may be redistributed only under +# the conditions described in the aforementioned license. The license +# is also available online at http://www.enthought.com/licenses/BSD.txt +# +# Thanks for using Enthought open source! + + +
    [docs]class ProviderNotRegisteredError(Exception): """ Raised when a provider is requested by ID and not found. """ def __init__(self, provider_id): @@ -86,7 +99,7 @@

    Source code for apptools.selection.errors

             return msg.format(id=self.provider_id)
    -
    [docs]class IDConflictError(Exception): +
    [docs]class IDConflictError(Exception): """ Raised when a provider is added and its ID is already registered. """ def __init__(self, provider_id): @@ -97,7 +110,7 @@

    Source code for apptools.selection.errors

             return msg.format(id=self.provider_id)
    -
    [docs]class ListenerNotConnectedError(Exception): +
    [docs]class ListenerNotConnectedError(Exception): """ Raised when a listener that was never connected is disconnected. """ def __init__(self, provider_id, listener): @@ -105,8 +118,8 @@

    Source code for apptools.selection.errors

             self.listener = listener
     
         def __str__(self):
    -        msg = "Selection listener {l} is not connected to provider '{id}'."
    -        return msg.format(l=self.listener, id=self.provider_id)
    + msg = "Selection listener {lr} is not connected to provider '{id}'." + return msg.format(lr=self.listener, id=self.provider_id)
    @@ -118,13 +131,11 @@

    Source code for apptools.selection.errors

                   
                 

    @@ -148,10 +159,10 @@

    Quick search

    © Copyright 2008-2020, Enthought
  • - Last updated on Jun 12, 2020. + Last updated on Dec 17, 2020.
  • - Created using Sphinx 1.8.5. + Created using Sphinx 2.3.1.
  • diff --git a/_modules/apptools/selection/i_selection.html b/_modules/apptools/selection/i_selection.html index b570483d5..bcb99d64a 100644 --- a/_modules/apptools/selection/i_selection.html +++ b/_modules/apptools/selection/i_selection.html @@ -13,9 +13,11 @@ @@ -72,23 +74,32 @@
    -
    +

    Source code for apptools.selection.i_selection

    -from traits.api import Interface, List, Str
    +# (C) Copyright 2005-2020 Enthought, Inc., Austin, TX
    +# All rights reserved.
    +#
    +# This software is provided without warranty under the terms of the BSD
    +# license included in LICENSE.txt and may be redistributed only under
    +# the conditions described in the aforementioned license. The license
    +# is also available online at http://www.enthought.com/licenses/BSD.txt
    +#
    +# Thanks for using Enthought open source!
    +from traits.api import Interface, List, Str
     
     
    -
    [docs]class ISelection(Interface): +
    [docs]class ISelection(Interface): """ Collection of selected items. """ #: ID of the selection provider that created this selection object. provider_id = Str -
    [docs] def is_empty(self): +
    [docs] def is_empty(self): """ Is the selection empty? """
    -
    [docs]class IListSelection(ISelection): +
    [docs]class IListSelection(ISelection): """ Selection for ordered sequences of items. """ #: Selected objects. @@ -107,13 +118,11 @@

    Source code for apptools.selection.i_selection

    @@ -137,10 +146,10 @@

    Quick search

    © Copyright 2008-2020, Enthought
  • - Last updated on Jun 12, 2020. + Last updated on Dec 17, 2020.
  • - Created using Sphinx 1.8.5. + Created using Sphinx 2.3.1.
  • diff --git a/_modules/apptools/selection/i_selection_provider.html b/_modules/apptools/selection/i_selection_provider.html index 24061c8da..d2ffa29bc 100644 --- a/_modules/apptools/selection/i_selection_provider.html +++ b/_modules/apptools/selection/i_selection_provider.html @@ -13,9 +13,11 @@ @@ -72,13 +74,22 @@
    -
    +

    Source code for apptools.selection.i_selection_provider

    -from traits.api import Event, Interface, Str
    +# (C) Copyright 2005-2020 Enthought, Inc., Austin, TX
    +# All rights reserved.
    +#
    +# This software is provided without warranty under the terms of the BSD
    +# license included in LICENSE.txt and may be redistributed only under
    +# the conditions described in the aforementioned license. The license
    +# is also available online at http://www.enthought.com/licenses/BSD.txt
    +#
    +# Thanks for using Enthought open source!
    +from traits.api import Event, Interface, Str
     
     
    -
    [docs]class ISelectionProvider(Interface): +
    [docs]class ISelectionProvider(Interface): """ Source of selections. """ #: Unique ID identifying the provider. @@ -88,16 +99,16 @@

    Source code for apptools.selection.i_selection_provider

    #: The content of the event is an :class:`~.ISelection` instance. selection = Event -
    [docs] def get_selection(self): - """ Return the current selection. +
    [docs] def get_selection(self): + """Return the current selection. Returns: selection -- ISelection Object representing the current selection. """
    -
    [docs] def set_selection(self, items, ignore_missing=False): - """ Set the current selection to the given items. +
    [docs] def set_selection(self, items, ignore_missing=False): + """Set the current selection to the given items. If ``ignore_missing`` is ``True``, items that are not available in the selection provider are silently ignored. If it is ``False`` (default), @@ -124,13 +135,11 @@

    Source code for apptools.selection.i_selection_provider

    @@ -154,10 +163,10 @@

    Quick search

    © Copyright 2008-2020, Enthought
  • - Last updated on Jun 12, 2020. + Last updated on Dec 17, 2020.
  • - Created using Sphinx 1.8.5. + Created using Sphinx 2.3.1.
  • diff --git a/_modules/apptools/selection/list_selection.html b/_modules/apptools/selection/list_selection.html index 741413d8b..cd640f662 100644 --- a/_modules/apptools/selection/list_selection.html +++ b/_modules/apptools/selection/list_selection.html @@ -13,9 +13,11 @@ @@ -72,17 +74,26 @@
    -
    +

    Source code for apptools.selection.list_selection

    -from traits.api import HasTraits, List, provides, Str
    +# (C) Copyright 2005-2020 Enthought, Inc., Austin, TX
    +# All rights reserved.
    +#
    +# This software is provided without warranty under the terms of the BSD
    +# license included in LICENSE.txt and may be redistributed only under
    +# the conditions described in the aforementioned license. The license
    +# is also available online at http://www.enthought.com/licenses/BSD.txt
    +#
    +# Thanks for using Enthought open source!
    +from traits.api import HasTraits, List, provides, Str
     
     from apptools.selection.i_selection import IListSelection
     
     
    -
    [docs]@provides(IListSelection) +
    [docs]@provides(IListSelection) class ListSelection(HasTraits): - """ Selection for ordered sequences of items. + """Selection for ordered sequences of items. This is the default implementation of the :class:`~.IListSelection` interface. @@ -93,7 +104,7 @@

    Source code for apptools.selection.list_selection

    #: ID of the selection provider that created this selection object. provider_id = Str -
    [docs] def is_empty(self): +
    [docs] def is_empty(self): """ Is the selection empty? """ return len(self.items) == 0
    @@ -107,9 +118,9 @@

    Source code for apptools.selection.list_selection

    #### 'ListSelection' class protocol ####################################### -
    [docs] @classmethod +
    [docs] @classmethod def from_available_items(cls, provider_id, selected, all_items): - """ Create a list selection given a list of all available items. + """Create a list selection given a list of all available items. Fills in the required information (in particular, the indices) based on a list of selected items and a list of all available items. @@ -129,7 +140,7 @@

    Source code for apptools.selection.list_selection

    indices.append(index) break else: - msg = 'Selected item: {!r}, could not be found' + msg = "Selected item: {!r}, could not be found" raise ValueError(msg.format(item)) return cls(provider_id=provider_id, items=selected, indices=indices)
    @@ -144,13 +155,11 @@

    Source code for apptools.selection.list_selection

    @@ -174,10 +183,10 @@

    Quick search

    © Copyright 2008-2020, Enthought
  • - Last updated on Jun 12, 2020. + Last updated on Dec 17, 2020.
  • - Created using Sphinx 1.8.5. + Created using Sphinx 2.3.1.
  • diff --git a/_modules/apptools/selection/selection_service.html b/_modules/apptools/selection/selection_service.html index 275b7b320..53ff56ffa 100644 --- a/_modules/apptools/selection/selection_service.html +++ b/_modules/apptools/selection/selection_service.html @@ -13,9 +13,11 @@ @@ -72,18 +74,29 @@
    -
    +

    Source code for apptools.selection.selection_service

    -from traits.api import Dict, HasTraits
    +# (C) Copyright 2005-2020 Enthought, Inc., Austin, TX
    +# All rights reserved.
    +#
    +# This software is provided without warranty under the terms of the BSD
    +# license included in LICENSE.txt and may be redistributed only under
    +# the conditions described in the aforementioned license. The license
    +# is also available online at http://www.enthought.com/licenses/BSD.txt
    +#
    +# Thanks for using Enthought open source!
    +from traits.api import Dict, HasTraits
     
     from apptools.selection.errors import (
    -    ProviderNotRegisteredError, IDConflictError, ListenerNotConnectedError
    +    ProviderNotRegisteredError,
    +    IDConflictError,
    +    ListenerNotConnectedError,
     )
     
     
    -
    [docs]class SelectionService(HasTraits): - """ The selection service connects selection providers and listeners. +
    [docs]class SelectionService(HasTraits): + """The selection service connects selection providers and listeners. The selection service is a register of selection providers, i.e., objects that publish their current selection. @@ -95,8 +108,8 @@

    Source code for apptools.selection.selection_service

    #### 'SelectionService' protocol ########################################## -
    [docs] def add_selection_provider(self, provider): - """ Add a selection provider. +
    [docs] def add_selection_provider(self, provider): + """Add a selection provider. The provider is identified by its ID. If a provider with the same ID has been already registered, an :class:`~.IDConflictError` @@ -116,12 +129,12 @@

    Source code for apptools.selection.selection_service

    if provider_id in self._listeners: self._connect_all_listeners(provider_id)
    -
    [docs] def has_selection_provider(self, provider_id): +
    [docs] def has_selection_provider(self, provider_id): """ Has a provider with the given ID been registered? """ return provider_id in self._providers
    -
    [docs] def remove_selection_provider(self, provider): - """ Remove a selection provider. +
    [docs] def remove_selection_provider(self, provider): + """Remove a selection provider. If the provider has not been registered, a :class:`~.ProviderNotRegisteredError` is raised. @@ -138,8 +151,8 @@

    Source code for apptools.selection.selection_service

    del self._providers[provider_id]
    -
    [docs] def get_selection(self, provider_id): - """ Return the current selection of the provider with the given ID. +
    [docs] def get_selection(self, provider_id): + """Return the current selection of the provider with the given ID. If a provider with that ID has not been registered, a :class:`~.ProviderNotRegisteredError` is raised. @@ -156,8 +169,8 @@

    Source code for apptools.selection.selection_service

    provider = self._providers[provider_id] return provider.get_selection()
    -
    [docs] def set_selection(self, provider_id, items, ignore_missing=False): - """ Set the current selection in a provider to the given items. +
    [docs] def set_selection(self, provider_id, items, ignore_missing=False): + """Set the current selection in a provider to the given items. If a provider with the given ID has not been registered, a :class:`~.ProviderNotRegisteredError` is raised. @@ -183,8 +196,8 @@

    Source code for apptools.selection.selection_service

    provider = self._providers[provider_id] return provider.set_selection(items, ignore_missing=ignore_missing)
    -
    [docs] def connect_selection_listener(self, provider_id, func): - """ Connect a listener to selection events from a specific provider. +
    [docs] def connect_selection_listener(self, provider_id, func): + """Connect a listener to selection events from a specific provider. The signature if the listener callback is ``func(i_selection)``. The listener is called: @@ -210,8 +223,8 @@

    Source code for apptools.selection.selection_service

    if self.has_selection_provider(provider_id): self._toggle_listener(provider_id, func, remove=False)
    -
    [docs] def disconnect_selection_listener(self, provider_id, func): - """ Disconnect a listener from a specific provider. +
    [docs] def disconnect_selection_listener(self, provider_id, func): + """Disconnect a listener from a specific provider. Arguments: provider_id -- str @@ -226,8 +239,9 @@

    Source code for apptools.selection.selection_service

    try: self._listeners[provider_id].remove(func) except (ValueError, KeyError): - raise ListenerNotConnectedError(provider_id=provider_id, - listener=func)
    + raise ListenerNotConnectedError( + provider_id=provider_id, listener=func + )
    #### Private protocol ##################################################### @@ -237,10 +251,10 @@

    Source code for apptools.selection.selection_service

    def _toggle_listener(self, provider_id, func, remove): provider = self._providers[provider_id] - provider.on_trait_change(func, 'selection', remove=remove) + provider.on_trait_change(func, "selection", remove=remove) def _connect_all_listeners(self, provider_id): - """ Connect all listeners connected to a provider. + """Connect all listeners connected to a provider. As soon as they are connected, they receive the initial selection. """ @@ -270,13 +284,11 @@

    Source code for apptools.selection.selection_service

    @@ -300,10 +312,10 @@

    Quick search

    © Copyright 2008-2020, Enthought
  • - Last updated on Jun 12, 2020. + Last updated on Dec 17, 2020.
  • - Created using Sphinx 1.8.5. + Created using Sphinx 2.3.1.
  • diff --git a/_modules/apptools/type_registry/type_registry.html b/_modules/apptools/type_registry/type_registry.html index 7abb81d2e..6a0642e6b 100644 --- a/_modules/apptools/type_registry/type_registry.html +++ b/_modules/apptools/type_registry/type_registry.html @@ -13,9 +13,11 @@ @@ -72,17 +74,25 @@
    -
    +

    Source code for apptools.type_registry.type_registry

    -import six
    +# (C) Copyright 2005-2020 Enthought, Inc., Austin, TX
    +# All rights reserved.
    +#
    +# This software is provided without warranty under the terms of the BSD
    +# license included in LICENSE.txt and may be redistributed only under
    +# the conditions described in the aforementioned license. The license
    +# is also available online at http://www.enthought.com/licenses/BSD.txt
    +#
    +# Thanks for using Enthought open source!
     
     
     
    [docs]def get_mro(obj_class): - """ Get a reasonable method resolution order of a class and its + """Get a reasonable method resolution order of a class and its superclasses for both old-style and new-style classes. """ - if not hasattr(obj_class, '__mro__'): + if not hasattr(obj_class, "__mro__"): # Old-style class. Mix in object to make a fake new-style class. try: obj_class = type(obj_class.__name__, (obj_class, object), {}) @@ -97,16 +107,15 @@

    Source code for apptools.type_registry.type_registry

    def _mod_name_key(typ): - """ Return a '__module__:__name__' key for a type. - """ - module = getattr(typ, '__module__', None) - name = getattr(typ, '__name__', None) - key = '{0}:{1}'.format(module, name) + """Return a '__module__:__name__' key for a type.""" + module = getattr(typ, "__module__", None) + name = getattr(typ, "__name__", None) + key = "{0}:{1}".format(module, name) return key
    [docs]class TypeRegistry(object): - """ Register objects for types. + """Register objects for types. Each type maintains a stack of registered objects that can be pushed and popped. @@ -126,7 +135,7 @@

    Source code for apptools.type_registry.type_registry

    #### TypeRegistry public interface ########################################
    [docs] def push(self, typ, obj): - """ Push an object onto the stack for the given type. + """Push an object onto the stack for the given type. Parameters ---------- @@ -134,7 +143,7 @@

    Source code for apptools.type_registry.type_registry

    obj : object The object to register. """ - if isinstance(typ, six.string_types): + if isinstance(typ, str): # Check the cached types. for cls in self.type_map: if _mod_name_key(cls) == typ: @@ -150,7 +159,7 @@

    Source code for apptools.type_registry.type_registry

    self.type_map[typ].append(obj)
    [docs] def push_abc(self, typ, obj): - """ Push an object onto the stack for the given ABC. + """Push an object onto the stack for the given ABC. Parameters ---------- @@ -162,7 +171,7 @@

    Source code for apptools.type_registry.type_registry

    self.abc_map[typ].append(obj)
    [docs] def pop(self, typ): - """ Pop a registered object for the given type. + """Pop a registered object for the given type. Parameters ---------- @@ -177,7 +186,7 @@

    Source code for apptools.type_registry.type_registry

    ------ KeyError if the type is not registered. """ - if isinstance(typ, six.string_types): + if isinstance(typ, str): if typ not in self.name_map: # We may have it cached in the type map. We will have to # iterate over all of the types to check. @@ -199,7 +208,7 @@

    Source code for apptools.type_registry.type_registry

    return old
    [docs] def lookup(self, instance): - """ Look up the registered object for the given instance. + """Look up the registered object for the given instance. Parameters ---------- @@ -219,7 +228,7 @@

    Source code for apptools.type_registry.type_registry

    return self.lookup_by_type(type(instance))
    [docs] def lookup_by_type(self, typ): - """ Look up the registered object for a type. + """Look up the registered object for a type. Parameters ---------- @@ -238,7 +247,7 @@

    Source code for apptools.type_registry.type_registry

    return self.lookup_all_by_type(typ)[-1]
    [docs] def lookup_all(self, instance): - """ Look up all the registered objects for the given instance. + """Look up all the registered objects for the given instance. Parameters ---------- @@ -259,7 +268,7 @@

    Source code for apptools.type_registry.type_registry

    return self.lookup_all_by_type(type(instance))
    [docs] def lookup_all_by_type(self, typ): - """ Look up all the registered objects for a type. + """Look up all the registered objects for a type. Parameters ---------- @@ -294,7 +303,7 @@

    Source code for apptools.type_registry.type_registry

    #### Private implementation ############################################### def _pop_value(self, mapping, key): - """ Pop a value from a keyed stack in a mapping, taking care to remove + """Pop a value from a keyed stack in a mapping, taking care to remove the key if the stack is depleted. """ objs = mapping[key] @@ -304,7 +313,7 @@

    Source code for apptools.type_registry.type_registry

    return old def _in_name_map(self, typ): - """ Check if the given type is specified in the name map. + """Check if the given type is specified in the name map. Parameters ---------- @@ -325,7 +334,7 @@

    Source code for apptools.type_registry.type_registry

    [docs]class LazyRegistry(TypeRegistry): - """ A type registry that will lazily import the registered objects. + """A type registry that will lazily import the registered objects. Register '__module__:__name__' strings for the lazily imported objects. These will only be imported when the matching type is looked up. The module @@ -334,13 +343,12 @@

    Source code for apptools.type_registry.type_registry

    """
    [docs] def lookup_by_type(self, typ): - """ Look up the registered object for a type. - """ + """Look up the registered object for a type.""" mod_name = TypeRegistry.lookup_by_type(self, typ) return self._import_object(mod_name)
    def _import_object(self, mod_object): - module, name = mod_object.split(':') + module, name = mod_object.split(":") mod = __import__(module, {}, {}, [name], 0) return getattr(mod, name)
    @@ -354,13 +362,11 @@

    Source code for apptools.type_registry.type_registry

    @@ -384,10 +390,10 @@

    Quick search

    © Copyright 2008-2020, Enthought
  • - Last updated on Jun 12, 2020. + Last updated on Dec 17, 2020.
  • - Created using Sphinx 1.8.5. + Created using Sphinx 2.3.1.
  • diff --git a/_modules/apptools/undo/abstract_command.html b/_modules/apptools/undo/abstract_command.html index d408525a2..48a26016b 100644 --- a/_modules/apptools/undo/abstract_command.html +++ b/_modules/apptools/undo/abstract_command.html @@ -13,9 +13,11 @@ @@ -72,10 +74,10 @@
    -
    +

    Source code for apptools.undo.abstract_command

    -#------------------------------------------------------------------------------
    +# ------------------------------------------------------------------------------
     # Copyright (c) 2007, Riverbank Computing Limited
     # All rights reserved.
     #
    @@ -87,10 +89,10 @@ 

    Source code for apptools.undo.abstract_command

    # # Author: Riverbank Computing Limited # Description: <Enthought undo package component> -#------------------------------------------------------------------------------ +# ------------------------------------------------------------------------------ # Enthought library imports. -from traits.api import Any, HasTraits, Unicode, provides +from traits.api import Any, HasTraits, Str, provides # Local imports. from .i_command import ICommand @@ -98,7 +100,7 @@

    Source code for apptools.undo.abstract_command

    [docs]@provides(ICommand) class AbstractCommand(HasTraits): - """ The AbstractCommand class is an abstract base class that implements the + """The AbstractCommand class is an abstract base class that implements the ICommand interface. """ @@ -110,14 +112,14 @@

    Source code for apptools.undo.abstract_command

    # This is the name of the command as it will appear in any GUI element. It # may include '&' which will be automatically removed whenever it is # inappropriate. - name = Unicode + name = Str ########################################################################### # 'ICommand' interface. ###########################################################################

    [docs] def do(self): - """ This is called by the command stack to do the command and to return + """This is called by the command stack to do the command and to return any value. The command must save any state necessary for the 'redo()' and 'undo()' methods to work. The class's __init__() must also ensure that deep copies of any arguments are made if appropriate. It is @@ -128,7 +130,7 @@

    Source code for apptools.undo.abstract_command

    raise NotImplementedError

    [docs] def merge(self, other): - """ This is called by the command stack to try and merge another + """This is called by the command stack to try and merge another command with this one. True is returned if the commands were merged. 'other' is the command that is about to be executed. If the commands are merged then 'other' will discarded and not placed on the command @@ -140,7 +142,7 @@

    Source code for apptools.undo.abstract_command

    return False

    [docs] def redo(self): - """ This is called by the command stack to redo the command. Any + """This is called by the command stack to redo the command. Any returned value will replace the value that the command stack references from the original call to 'do()' or previous call to 'redo()'. """ @@ -162,13 +164,11 @@

    Source code for apptools.undo.abstract_command

    @@ -192,10 +192,10 @@

    Quick search

    © Copyright 2008-2020, Enthought
  • - Last updated on Jun 12, 2020. + Last updated on Dec 17, 2020.
  • - Created using Sphinx 1.8.5. + Created using Sphinx 2.3.1.
  • diff --git a/_modules/apptools/undo/action/abstract_command_stack_action.html b/_modules/apptools/undo/action/abstract_command_stack_action.html index 3ea7b67d9..eef451dd3 100644 --- a/_modules/apptools/undo/action/abstract_command_stack_action.html +++ b/_modules/apptools/undo/action/abstract_command_stack_action.html @@ -13,9 +13,11 @@ @@ -72,10 +74,10 @@
    -
    +

    Source code for apptools.undo.action.abstract_command_stack_action

    -#------------------------------------------------------------------------------
    +# ------------------------------------------------------------------------------
     # Copyright (c) 2008, Riverbank Computing Limited
     # All rights reserved.
     #
    @@ -87,7 +89,7 @@ 

    Source code for apptools.undo.action.abstract_command_stack_action

    # # Author: Riverbank Computing Limited # Description: <Enthought undo package component> -#------------------------------------------------------------------------------ +# ------------------------------------------------------------------------------ # Enthought library imports. from pyface.action.api import Action @@ -98,7 +100,7 @@

    Source code for apptools.undo.action.abstract_command_stack_action

    [docs]class AbstractCommandStackAction(Action): - """ The abstract base class for all actions that operate on a command + """The abstract base class for all actions that operate on a command stack. """ @@ -116,7 +118,9 @@

    Source code for apptools.undo.action.abstract_command_stack_action

    super(AbstractCommandStackAction, self).__init__(**traits) - self.undo_manager.on_trait_event(self._on_stack_updated, 'stack_updated') + self.undo_manager.on_trait_event( + self._on_stack_updated, "stack_updated" + ) # Update the action to initialise it. self._update_action() @@ -126,15 +130,16 @@

    Source code for apptools.undo.action.abstract_command_stack_action

    ###########################################################################
    [docs] def destroy(self): - """ Called when the action is no longer required. + """Called when the action is no longer required. By default this method does nothing, but this would be a great place to unhook trait listeners etc. """ - self.undo_manager.on_trait_event(self._on_stack_updated, - 'stack_updated', remove=True)
    + self.undo_manager.on_trait_event( + self._on_stack_updated, "stack_updated", remove=True + )
    ########################################################################### # Protected interface. @@ -166,13 +171,11 @@

    Source code for apptools.undo.action.abstract_command_stack_action

    diff --git a/_modules/apptools/undo/action/command_action.html b/_modules/apptools/undo/action/command_action.html index 270a9fc5b..151e51aaa 100644 --- a/_modules/apptools/undo/action/command_action.html +++ b/_modules/apptools/undo/action/command_action.html @@ -13,9 +13,11 @@ @@ -72,10 +74,10 @@
    -
    +

    Source code for apptools.undo.action.command_action

    -#------------------------------------------------------------------------------
    +# ------------------------------------------------------------------------------
     # Copyright (c) 2007, Riverbank Computing Limited
     # All rights reserved.
     #
    @@ -87,7 +89,7 @@ 

    Source code for apptools.undo.action.command_action

    # # Author: Riverbank Computing Limited # Description: <Enthought undo package component> -#------------------------------------------------------------------------------ +# ------------------------------------------------------------------------------ # Enthought library imports. from pyface.action.api import Action @@ -96,7 +98,7 @@

    Source code for apptools.undo.action.command_action

    [docs]class CommandAction(Action): - """ The CommandAction class is an Action class that wraps undo/redo + """The CommandAction class is an Action class that wraps undo/redo commands. It is only useful for commands that do not take any arguments or return any result. """ @@ -118,7 +120,7 @@

    Source code for apptools.undo.action.command_action

    ###########################################################################
    [docs] def perform(self, event): - """ This is reimplemented to push a new command instance onto the + """This is reimplemented to push a new command instance onto the command stack. """ @@ -144,13 +146,11 @@

    Source code for apptools.undo.action.command_action

    @@ -174,10 +174,10 @@

    Quick search

    © Copyright 2008-2020, Enthought
  • - Last updated on Jun 12, 2020. + Last updated on Dec 17, 2020.
  • - Created using Sphinx 1.8.5. + Created using Sphinx 2.3.1.
  • diff --git a/_modules/apptools/undo/action/redo_action.html b/_modules/apptools/undo/action/redo_action.html index 670291670..34960ff83 100644 --- a/_modules/apptools/undo/action/redo_action.html +++ b/_modules/apptools/undo/action/redo_action.html @@ -13,9 +13,11 @@ @@ -72,10 +74,10 @@
    -
    +

    Source code for apptools.undo.action.redo_action

    -#------------------------------------------------------------------------------
    +# ------------------------------------------------------------------------------
     # Copyright (c) 2007, Riverbank Computing Limited
     # All rights reserved.
     #
    @@ -87,14 +89,14 @@ 

    Source code for apptools.undo.action.redo_action

    # # Author: Riverbank Computing Limited # Description: <Enthought undo package component> -#------------------------------------------------------------------------------ +# ------------------------------------------------------------------------------ # Local imports. from .abstract_command_stack_action import AbstractCommandStackAction
    [docs]class RedoAction(AbstractCommandStackAction): - """ An action that redos the last command undone of the active command + """An action that redos the last command undone of the active command stack. """ @@ -135,13 +137,11 @@

    Source code for apptools.undo.action.redo_action

    @@ -165,10 +165,10 @@

    Quick search

    © Copyright 2008-2020, Enthought
  • - Last updated on Jun 12, 2020. + Last updated on Dec 17, 2020.
  • - Created using Sphinx 1.8.5. + Created using Sphinx 2.3.1.
  • diff --git a/_modules/apptools/undo/action/undo_action.html b/_modules/apptools/undo/action/undo_action.html index 04038b756..c5910362b 100644 --- a/_modules/apptools/undo/action/undo_action.html +++ b/_modules/apptools/undo/action/undo_action.html @@ -13,9 +13,11 @@ @@ -72,10 +74,10 @@
    -
    +

    Source code for apptools.undo.action.undo_action

    -#------------------------------------------------------------------------------
    +# ------------------------------------------------------------------------------
     # Copyright (c) 2007, Riverbank Computing Limited
     # All rights reserved.
     #
    @@ -87,7 +89,7 @@ 

    Source code for apptools.undo.action.undo_action

    # # Author: Riverbank Computing Limited # Description: <Enthought undo package component> -#------------------------------------------------------------------------------ +# ------------------------------------------------------------------------------ # Local imports. from .abstract_command_stack_action import AbstractCommandStackAction @@ -133,13 +135,11 @@

    Source code for apptools.undo.action.undo_action

    @@ -163,10 +163,10 @@

    Quick search

    © Copyright 2008-2020, Enthought
  • - Last updated on Jun 12, 2020. + Last updated on Dec 17, 2020.
  • - Created using Sphinx 1.8.5. + Created using Sphinx 2.3.1.
  • diff --git a/_modules/apptools/undo/command_stack.html b/_modules/apptools/undo/command_stack.html index f4b5aa7c2..bba612ffb 100644 --- a/_modules/apptools/undo/command_stack.html +++ b/_modules/apptools/undo/command_stack.html @@ -13,9 +13,11 @@ @@ -72,10 +74,10 @@
    -
    +

    Source code for apptools.undo.command_stack

    -#------------------------------------------------------------------------------
    +# ------------------------------------------------------------------------------
     # Copyright (c) 2008, Riverbank Computing Limited
     # All rights reserved.
     #
    @@ -87,11 +89,19 @@ 

    Source code for apptools.undo.command_stack

     #
     # Author: Riverbank Computing Limited
     # Description: <Enthought undo package component>
    -#------------------------------------------------------------------------------
    +# ------------------------------------------------------------------------------
     
     # Enthought library imports.
    -from traits.api import Bool, HasTraits, Instance, Int, List, Property, \
    -    Unicode, provides
    +from traits.api import (
    +    Bool,
    +    HasTraits,
    +    Instance,
    +    Int,
    +    List,
    +    Property,
    +    Str,
    +    provides,
    +)
     
     # Local imports.
     from .abstract_command import AbstractCommand
    @@ -161,7 +171,7 @@ 

    Source code for apptools.undo.command_stack

     
     
    [docs]@provides(ICommandStack) class CommandStack(HasTraits): - """ The CommandStack class is the default implementation of the + """The CommandStack class is the default implementation of the ICommandStack interface. """ @@ -176,7 +186,7 @@

    Source code for apptools.undo.command_stack

         # This is the name of the command that can be redone.  It will be empty if
         # there is no command that can be redone.  It is maintained by the undo
         # stack.
    -    redo_name = Property(Unicode)
    +    redo_name = Property(Str)
     
         # This is the undo manager that manages this stack.
         undo_manager = Instance(IUndoManager)
    @@ -184,7 +194,7 @@ 

    Source code for apptools.undo.command_stack

         # This is the name of the command that can be undone.  It will be empty if
         # there is no command that can be undone.  It is maintained by the undo
         # stack.
    -    undo_name = Property(Unicode)
    +    undo_name = Property(Str)
     
         #### Private interface ####################################################
     
    @@ -202,7 +212,7 @@ 

    Source code for apptools.undo.command_stack

         ###########################################################################
     
     
    [docs] def begin_macro(self, name): - """ This begins a macro by creating an empty command with the given + """This begins a macro by creating an empty command with the given 'name'. All subsequent calls to 'push()' create commands that will be children of the empty command until the next call to 'end_macro()'. Macros may be nested. The stack is disabled (ie. nothing can be undone @@ -215,7 +225,7 @@

    Source code for apptools.undo.command_stack

             self._macro_stack.append(command)
    [docs] def clear(self): - """ This clears the stack, without undoing or redoing any commands, and + """This clears the stack, without undoing or redoing any commands, and leaves the stack in a clean state. It is typically used when all changes to the data have been abandoned. """ @@ -235,7 +245,7 @@

    Source code for apptools.undo.command_stack

                 pass
    [docs] def push(self, command): - """ This executes a command and saves it on the command stack so that + """This executes a command and saves it on the command stack so that it can be subsequently undone and redone. 'command' is an instance that implements the ICommand interface. Its 'do()' method is called to execute the command. If any value is returned by 'do()' then it is @@ -270,8 +280,9 @@

    Source code for apptools.undo.command_stack

                 del self._stack[self._index:]
     
                 # Create a new stack entry and add it to the stack.
    -            entry = _StackEntry(command=command,
    -                    sequence_nr=self.undo_manager.sequence_nr)
    +            entry = _StackEntry(
    +                command=command, sequence_nr=self.undo_manager.sequence_nr
    +            )
     
                 self._stack.append(entry)
                 self.undo_manager.stack_updated = self
    @@ -282,7 +293,7 @@ 

    Source code for apptools.undo.command_stack

             return result
    [docs] def redo(self, sequence_nr=0): - """ If 'sequence_nr' is 0 then the last command that was undone is + """If 'sequence_nr' is 0 then the last command that was undone is redone and any result returned. Otherwise commands are redone up to and including the given 'sequence_nr' and any result of the last of these is returned. @@ -308,7 +319,7 @@

    Source code for apptools.undo.command_stack

             return result
    [docs] def undo(self, sequence_nr=0): - """ If 'sequence_nr' is 0 then the last command is undone. Otherwise + """If 'sequence_nr' is 0 then the last command is undone. Otherwise commands are undone up to and including the given 'sequence_nr'. """ @@ -369,7 +380,9 @@

    Source code for apptools.undo.command_stack

             redo_name = ""
     
             if len(self._macro_stack) == 0 and self._index + 1 < len(self._stack):
    -            redo_name = self._stack[self._index + 1].command.name.replace('&', '')
    +            redo_name = self._stack[self._index + 1].command.name.replace(
    +                "&", ""
    +            )
     
             return redo_name
     
    @@ -380,7 +393,7 @@ 

    Source code for apptools.undo.command_stack

     
             if len(self._macro_stack) == 0 and self._index >= 0:
                 command = self._stack[self._index].command
    -            undo_name = command.name.replace('&', '')
    +            undo_name = command.name.replace("&", "")
     
             return undo_name
    @@ -394,13 +407,11 @@

    Source code for apptools.undo.command_stack

                   
                 

    @@ -424,10 +435,10 @@

    Quick search

    © Copyright 2008-2020, Enthought
  • - Last updated on Jun 12, 2020. + Last updated on Dec 17, 2020.
  • - Created using Sphinx 1.8.5. + Created using Sphinx 2.3.1.
  • diff --git a/_modules/apptools/undo/i_command.html b/_modules/apptools/undo/i_command.html index 8c0d2596d..2be484b01 100644 --- a/_modules/apptools/undo/i_command.html +++ b/_modules/apptools/undo/i_command.html @@ -13,9 +13,11 @@ @@ -72,10 +74,10 @@
    -
    +

    Source code for apptools.undo.i_command

    -#------------------------------------------------------------------------------
    +# ------------------------------------------------------------------------------
     # Copyright (c) 2007, Riverbank Computing Limited
     # All rights reserved.
     #
    @@ -87,15 +89,15 @@ 

    Source code for apptools.undo.i_command

     #
     # Author: Riverbank Computing Limited
     # Description: <Enthought undo package component>
    -#------------------------------------------------------------------------------
    +# ------------------------------------------------------------------------------
     
     
     # Enthought library imports.
    -from traits.api import Any, Interface, Unicode
    +from traits.api import Any, Interface, Str
     
     
     
    [docs]class ICommand(Interface): - """ The command interface. The state of the data can be changed by passing + """The command interface. The state of the data can be changed by passing an instance that implements this interface to the 'push()' method of a command stack along with any arguments. """ @@ -108,14 +110,14 @@

    Source code for apptools.undo.i_command

         # This is the name of the command as it will appear in any GUI element.  It
         # may include '&' which will be automatically removed whenever it is
         # inappropriate.
    -    name = Unicode
    +    name = Str
     
         ###########################################################################
         # 'ICommand' interface.
         ###########################################################################
     
     
    [docs] def do(self): - """ This is called by the command stack to do the command and to return + """This is called by the command stack to do the command and to return any value. The command must save any state necessary for the 'redo()' and 'undo()' methods to work. The class's __init__() must also ensure that deep copies of any arguments are made if appropriate. It is @@ -124,7 +126,7 @@

    Source code for apptools.undo.i_command

             """
    [docs] def merge(self, other): - """ This is called by the command stack to try and merge another + """This is called by the command stack to try and merge another command with this one. True is returned if the commands were merged. 'other' is the command that is about to be executed. If the commands are merged then 'other' will discarded and not placed on the command @@ -133,7 +135,7 @@

    Source code for apptools.undo.i_command

             """
    [docs] def redo(self): - """ This is called by the command stack to redo the command. Any + """This is called by the command stack to redo the command. Any returned value will replace the value that the command stack references from the original call to 'do()' or previous call to 'redo()'. """
    @@ -151,13 +153,11 @@

    Source code for apptools.undo.i_command

                   
                 

    @@ -181,10 +181,10 @@

    Quick search

    © Copyright 2008-2020, Enthought
  • - Last updated on Jun 12, 2020. + Last updated on Dec 17, 2020.
  • - Created using Sphinx 1.8.5. + Created using Sphinx 2.3.1.
  • diff --git a/_modules/apptools/undo/i_command_stack.html b/_modules/apptools/undo/i_command_stack.html index 392086ebf..38cfbb57b 100644 --- a/_modules/apptools/undo/i_command_stack.html +++ b/_modules/apptools/undo/i_command_stack.html @@ -13,9 +13,11 @@ @@ -72,10 +74,10 @@
    -
    +

    Source code for apptools.undo.i_command_stack

    -#------------------------------------------------------------------------------
    +# ------------------------------------------------------------------------------
     # Copyright (c) 2007, Riverbank Computing Limited
     # All rights reserved.
     #
    @@ -87,17 +89,17 @@ 

    Source code for apptools.undo.i_command_stack

    # # Author: Riverbank Computing Limited # Description: <Enthought undo package component> -#------------------------------------------------------------------------------ +# ------------------------------------------------------------------------------ # Enthought library imports. -from traits.api import Bool, Instance, Interface, Unicode +from traits.api import Bool, Instance, Interface, Str # Local imports. from .i_undo_manager import IUndoManager
    [docs]class ICommandStack(Interface): - """ The command stack interface. A command stack is responsible for + """The command stack interface. A command stack is responsible for managing the changes to a data model and recording those changes so that they can be undone or redone. """ @@ -113,7 +115,7 @@

    Source code for apptools.undo.i_command_stack

    # This is the name of the command that can be redone. It will be empty if # there is no command that can be redone. It is maintained by the undo # stack. - redo_name = Unicode + redo_name = Str # This is the undo manager that manages this stack. undo_manager = Instance(IUndoManager) @@ -121,14 +123,14 @@

    Source code for apptools.undo.i_command_stack

    # This is the name of the command that can be undone. It will be empty if # there is no command that can be undone. It is maintained by the undo # stack. - undo_name = Unicode + undo_name = Str ########################################################################### # 'ICommandStack' interface. ###########################################################################
    [docs] def begin_macro(self, name): - """ This begins a macro by creating an empty command with the given + """This begins a macro by creating an empty command with the given 'name'. The commands passed to all subsequent calls to 'push()' will be contained in the macro until the next call to 'end_macro()'. Macros may be nested. The stack is disabled (ie. nothing can be undone or @@ -137,7 +139,7 @@

    Source code for apptools.undo.i_command_stack

    """
    [docs] def clear(self): - """ This clears the stack, without undoing or redoing any commands, and + """This clears the stack, without undoing or redoing any commands, and leaves the stack in a clean state. It is typically used when all changes to the data have been abandoned. """
    @@ -146,7 +148,7 @@

    Source code for apptools.undo.i_command_stack

    """ This ends a macro. """
    [docs] def push(self, command): - """ This executes a command and saves it on the command stack so that + """This executes a command and saves it on the command stack so that it can be subsequently undone and redone. 'command' is an instance that implements the ICommand interface. Its 'do()' method is called to execute the command. If any value is returned by 'do()' then it is @@ -156,14 +158,14 @@

    Source code for apptools.undo.i_command_stack

    """
    [docs] def redo(self, sequence_nr=0): - """ If 'sequence_nr' is 0 then the last command that was undone is + """If 'sequence_nr' is 0 then the last command that was undone is redone and any result returned. Otherwise commands are redone up to and including the given 'sequence_nr' and any result of the last of these is returned. """
    [docs] def undo(self, sequence_nr=0): - """ If 'sequence_nr' is 0 then the last command is undone. Otherwise + """If 'sequence_nr' is 0 then the last command is undone. Otherwise commands are undone up to and including the given 'sequence_nr'. """
    @@ -177,13 +179,11 @@

    Source code for apptools.undo.i_command_stack

    diff --git a/_modules/apptools/undo/i_undo_manager.html b/_modules/apptools/undo/i_undo_manager.html index 9ae732e95..cefd9792d 100644 --- a/_modules/apptools/undo/i_undo_manager.html +++ b/_modules/apptools/undo/i_undo_manager.html @@ -13,9 +13,11 @@ @@ -72,10 +74,10 @@
    -
    +

    Source code for apptools.undo.i_undo_manager

    -#------------------------------------------------------------------------------
    +# ------------------------------------------------------------------------------
     # Copyright (c) 2008, Riverbank Computing Limited
     # All rights reserved.
     #
    @@ -87,14 +89,14 @@ 

    Source code for apptools.undo.i_undo_manager

    #
     # Author: Riverbank Computing Limited
     # Description: <Enthought undo package component>
    -#------------------------------------------------------------------------------
    +# ------------------------------------------------------------------------------
     
     # Enthought library imports.
    -from traits.api import Bool, Event, Instance, Int, Interface, Unicode
    +from traits.api import Bool, Event, Instance, Int, Interface, Str
     
     
     
    [docs]class IUndoManager(Interface): - """ The undo manager interface. An undo manager is responsible for one or + """The undo manager interface. An undo manager is responsible for one or more command stacks. Typically an application would have a single undo manager. """ @@ -103,7 +105,7 @@

    Source code for apptools.undo.i_undo_manager

    # This is the currently active command stack and may be None.  Typically it
         # is set when some sort of editor becomes active.
    -    active_stack = Instance('apptools.undo.api.ICommandStack')
    +    active_stack = Instance("apptools.undo.api.ICommandStack")
     
         # This reflects the clean state of the currently active command stack.  It
         # is intended to support a "document modified" indicator in the GUI.  It is
    @@ -113,7 +115,7 @@ 

    Source code for apptools.undo.i_undo_manager

    # This is the name of the command that can be redone.  It will be empty if
         # there is no command that can be redone.  It is maintained by the undo
         # manager.
    -    redo_name = Unicode
    +    redo_name = Str
     
         # This is the sequence number of the next command to be performed.  It is
         # incremented immediately before a command is invoked (by its 'do()'
    @@ -122,12 +124,12 @@ 

    Source code for apptools.undo.i_undo_manager

    # This event is fired when the index of a command stack changes.  Note that
         # it may not be the active stack.
    -    stack_updated = Event(Instance('apptools.undo.api.ICommandStack'))
    +    stack_updated = Event(Instance("apptools.undo.api.ICommandStack"))
     
         # This is the name of the command that can be undone.  It will be empty if
         # there is no command that can be undone.  It is maintained by the undo
         # manager.
    -    undo_name = Unicode
    +    undo_name = Str
     
         ###########################################################################
         # 'IUndoManager' interface.
    @@ -149,13 +151,11 @@ 

    Source code for apptools.undo.i_undo_manager

    diff --git a/_modules/apptools/undo/undo_manager.html b/_modules/apptools/undo/undo_manager.html index 1d20792fa..0707f8edf 100644 --- a/_modules/apptools/undo/undo_manager.html +++ b/_modules/apptools/undo/undo_manager.html @@ -13,9 +13,11 @@ @@ -72,10 +74,10 @@
    -
    +

    Source code for apptools.undo.undo_manager

    -#------------------------------------------------------------------------------
    +# ------------------------------------------------------------------------------
     # Copyright (c) 2008, Riverbank Computing Limited
     # All rights reserved.
     #
    @@ -87,11 +89,19 @@ 

    Source code for apptools.undo.undo_manager

     #
     # Author: Riverbank Computing Limited
     # Description: <Enthought undo package component>
    -#------------------------------------------------------------------------------
    +# ------------------------------------------------------------------------------
     
     # Enthought library imports.
    -from traits.api import Bool, Event, HasTraits, Instance, Int, Property, \
    -    Unicode, provides
    +from traits.api import (
    +    Bool,
    +    Event,
    +    HasTraits,
    +    Instance,
    +    Int,
    +    Property,
    +    Str,
    +    provides,
    +)
     
     # Local imports.
     from .i_undo_manager import IUndoManager
    @@ -99,7 +109,7 @@ 

    Source code for apptools.undo.undo_manager

     
     
    [docs]@provides(IUndoManager) class UndoManager(HasTraits): - """ The UndoManager class is the default implementation of the + """The UndoManager class is the default implementation of the IUndoManager interface. """ @@ -107,7 +117,7 @@

    Source code for apptools.undo.undo_manager

     
         # This is the currently active command stack and may be None.  Typically it
         # is set when some sort of editor becomes active.
    -    active_stack = Instance('apptools.undo.api.ICommandStack')
    +    active_stack = Instance("apptools.undo.api.ICommandStack")
     
         # This reflects the clean state of the currently active command stack.  It
         # is intended to support a "document modified" indicator in the GUI.  It is
    @@ -117,7 +127,7 @@ 

    Source code for apptools.undo.undo_manager

         # This is the name of the command that can be redone.  It will be empty if
         # there is no command that can be redone.  It is maintained by the undo
         # manager.
    -    redo_name = Property(Unicode)
    +    redo_name = Property(Str)
     
         # This is the sequence number of the next command to be performed.  It is
         # incremented immediately before a command is invoked (by its 'do()'
    @@ -132,7 +142,7 @@ 

    Source code for apptools.undo.undo_manager

         # This is the name of the command that can be undone.  It will be empty if
         # there is no command that can be undone.  It is maintained by the undo
         # manager.
    -    undo_name = Property(Unicode)
    +    undo_name = Property(Str)
     
         ###########################################################################
         # 'IUndoManager' interface.
    @@ -200,13 +210,11 @@ 

    Source code for apptools.undo.undo_manager

                   
                 

    @@ -230,10 +238,10 @@

    Quick search

    © Copyright 2008-2020, Enthought
  • - Last updated on Jun 12, 2020. + Last updated on Dec 17, 2020.
  • - Created using Sphinx 1.8.5. + Created using Sphinx 2.3.1.
  • diff --git a/_modules/index.html b/_modules/index.html index 478b3a6bc..53b122600 100644 --- a/_modules/index.html +++ b/_modules/index.html @@ -13,9 +13,11 @@ @@ -70,33 +72,10 @@
    -
    +

    All modules for which code is available

    -
    diff --git a/_modules/traits/trait_types.html b/_modules/traits/trait_types.html index 784122855..aee7cb0dd 100644 --- a/_modules/traits/trait_types.html +++ b/_modules/traits/trait_types.html @@ -13,9 +13,11 @@ @@ -72,115 +74,90 @@
    -
    +

    Source code for traits.trait_types

    -# ------------------------------------------------------------------------------
    +# (C) Copyright 2005-2020 Enthought, Inc., Austin, TX
    +# All rights reserved.
     #
    -#  Copyright (c) 2007, Enthought, Inc.
    -#  All rights reserved.
    +# This software is provided without warranty under the terms of the BSD
    +# license included in LICENSE.txt and may be redistributed only under
    +# the conditions described in the aforementioned license. The license
    +# is also available online at http://www.enthought.com/licenses/BSD.txt
     #
    -#  This software is provided without warranty under the terms of the BSD
    -#  license included in enthought/LICENSE.txt and may be redistributed only
    -#  under the conditions described in the aforementioned license.  The license
    -#  is also available online at http://www.enthought.com/licenses/BSD.txt
    -#
    -#  Thanks for using Enthought open source!
    -#
    -#  Author: David C. Morrill
    -#  Date:   03/22/2007
    -#
    -# ------------------------------------------------------------------------------
    +# Thanks for using Enthought open source!
     
     """ Core Trait definitions.
     """
     
    -# -------------------------------------------------------------------------------
    -#  Imports:
    -# -------------------------------------------------------------------------------
    -
    -from __future__ import absolute_import
    -
    +import collections.abc
     import datetime
    +from importlib import import_module
     import operator
     import re
     import sys
    +try:
    +    from os import fspath
    +except ImportError:
    +    fspath = None
     from os.path import isfile, isdir
     from types import FunctionType, MethodType, ModuleType
     import uuid
     
    -import six
    -
    -from . import trait_handlers
    -
    +from .constants import DefaultValue, TraitKind, ValidateTrait
     from .trait_base import (
         strx,
         get_module_name,
    +    HandleWeakRef,
         class_of,
    +    RangeTypes,
    +    safe_contains,
         SequenceTypes,
         TypeTypes,
    -    ClassTypes,
         Undefined,
         TraitsCache,
    +    xgetattr,
     )
    -
    -from .trait_handlers import (
    -    TraitType,
    -    TraitInstance,
    -    TraitListObject,
    -    TraitSetObject,
    -    TraitSetEvent,
    -    TraitDictObject,
    -    TraitDictEvent,
    -    ThisClass,
    -    items_event,
    -    RangeTypes,
    -    HandleWeakRef,
    -    OBJECT_DEFAULT_VALUE,
    -    TRAIT_LIST_OBJECT_DEFAULT_VALUE,
    -    TRAIT_DICT_OBJECT_DEFAULT_VALUE,
    -    CALLABLE_AND_ARGS_DEFAULT_VALUE,
    -    CALLABLE_DEFAULT_VALUE,
    -    TRAIT_SET_OBJECT_DEFAULT_VALUE,
    -)
    -
    +from .trait_converters import trait_from, trait_cast
    +from .trait_dict_object import TraitDictEvent, TraitDictObject
    +from .trait_errors import TraitError
    +from .trait_list_object import TraitListEvent, TraitListObject
    +from .trait_set_object import TraitSetEvent, TraitSetObject
    +from .trait_type import TraitType, _infer_default_value_type
     from .traits import (
         Trait,
    -    trait_from,
         _TraitMaker,
         _InstanceArgs,
    +)
    +from .util.import_symbol import import_symbol
    +
    +# TraitsUI integration imports
    +from .editor_factories import (
         code_editor,
         html_editor,
         password_editor,
         shell_editor,
         date_editor,
    +    datetime_editor,
         time_editor,
         list_editor,
     )
     
    -from .trait_errors import TraitError
     
    -from . import _py2to3
    -from ._py2to3 import LONG_TYPE
    +# Constants
     
    -# -------------------------------------------------------------------------------
    -#  Constants:
    -# -------------------------------------------------------------------------------
    -
    -MutableTypes = (list, dict)
     SetTypes = SequenceTypes + (set,)
     
    -# -------------------------------------------------------------------------------
    -#  Numeric type fast validator definitions:
    -# -------------------------------------------------------------------------------
    +# Numeric type fast validator definitions
     
     # A few words about the next block of code:
     
    -# Validator #11 is a generic validator for possibly coercible types
    +# The coerce validator is a generic validator for possibly coercible types
     # (see validate_trait_coerce_type in ctraits.c).
     #
     # The tuples below are of the form
    -# (11, type1, [type2, type3, ...], [None, ctype1, [ctype2, ...]])
    +# (ValidateTrait.coerce, type1, [type2, type3, ...],
    +#     [None, ctype1, [ctype2, ...]])
     #
     # 'type1' corresponds to the main type for the trait
     # 'None' acts as the separator between 'types' and 'ctypes' (coercible types)
    @@ -197,11 +174,17 @@ 

    Source code for traits.trait_types

         # The numpy enhanced definitions:
         from numpy import integer, floating, complexfloating, bool_
     
    -    int_fast_validate = (11, int, integer)
    -    long_fast_validate = (11, LONG_TYPE, None, int, integer)
    -    float_fast_validate = (11, float, floating, None, int, LONG_TYPE, integer)
    +    int_fast_validate = (ValidateTrait.coerce, int, integer)
    +    float_fast_validate = (
    +        ValidateTrait.coerce,
    +        float,
    +        floating,
    +        None,
    +        int,
    +        integer,
    +    )
         complex_fast_validate = (
    -        11,
    +        ValidateTrait.coerce,
             complex,
             complexfloating,
             None,
    @@ -210,25 +193,35 @@ 

    Source code for traits.trait_types

             int,
             integer,
         )
    -    bool_fast_validate = (11, bool, None, bool_)
    +    bool_fast_validate = (ValidateTrait.coerce, bool, None, bool_)
         # Tuple or single type suitable for an isinstance check.
         _BOOL_TYPES = (bool, bool_)
     except ImportError:
         # The standard python definitions (without numpy):
    -    int_fast_validate = (11, int)
    -    long_fast_validate = (11, LONG_TYPE, None, int)
    -    float_fast_validate = (11, float, None, int, LONG_TYPE)
    -    complex_fast_validate = (11, complex, None, float, int)
    -    bool_fast_validate = (11, bool)
    +    int_fast_validate = (ValidateTrait.coerce, int)
    +    float_fast_validate = (ValidateTrait.coerce, float, None, int)
    +    complex_fast_validate = (ValidateTrait.coerce, complex, None, float, int)
    +    bool_fast_validate = (ValidateTrait.coerce, bool)
         # Tuple or single type suitable for an isinstance check.
         _BOOL_TYPES = bool
     
    -# -------------------------------------------------------------------------------
    -#  Returns a default text editor:
    -# -------------------------------------------------------------------------------
    -
     
     def default_text_editor(trait, type=None):
    +    """ Return a default text editor for a trait.
    +
    +    Parameters
    +    ----------
    +    trait : TraitType
    +        The trait we are constructing the editor for.
    +    type : callable, optional
    +        A callable (usually a Python type) to use to evaluate the text content
    +        of the editor and return the correct type of value for the trait.
    +
    +    Returns
    +    -------
    +    TextEditor
    +        A TraitsUI TextEditor instance for the trait.
    +    """
         auto_set = trait.auto_set
         if auto_set is None:
             auto_set = True
    @@ -245,12 +238,19 @@ 

    Source code for traits.trait_types

     
     # Generic validators
     
    +def _validate_int(value):
    +    """ Convert an integer-like Python object to an int, or raise TypeError.
    +    """
    +    if type(value) is int:
    +        return value
    +    else:
    +        return int(operator.index(value))
    +
     
     def _validate_float(value):
    -    """
    -    Convert an arbitrary Python object to a float, or raise TypeError.
    +    """ Convert an arbitrary Python object to a float, or raise TypeError.
         """
    -    if type(value) == float:  # fast path for common case
    +    if type(value) is float:  # fast path for common case
             return value
         try:
             nb_float = type(value).__float__
    @@ -261,13 +261,10 @@ 

    Source code for traits.trait_types

         return nb_float(value)
     
     
    -# -------------------------------------------------------------------------------
    -#  'Any' trait:
    -# -------------------------------------------------------------------------------
    -
    +# Trait Types
     
     class Any(TraitType):
    -    """ Defines a trait whose value can be anything.
    +    """ A trait type whose value can be anything.
         """
     
         #: The default value for the trait:
    @@ -277,27 +274,11 @@ 

    Source code for traits.trait_types

         info_text = "any value"
     
     
    -# -------------------------------------------------------------------------------
    -#  'Generic' trait:
    -# -------------------------------------------------------------------------------
    -
    -
    -class Generic(Any):
    -    """ Defines a trait whose value can be anything and whose definition can
    -        be redefined via assignment using a TraitValue object.
    -    """
    -
    -    #: The standard metadata for the trait:
    -    metadata = {"trait_value": True}
    -
    -
    -# -------------------------------------------------------------------------------
    -#  'BaseInt' and 'Int' traits:
    -# -------------------------------------------------------------------------------
    -
    -
     class BaseInt(TraitType):
    -    """ Defines a trait whose type must be an int or long.
    +    """ A trait type whose value must be an int.
    +
    +    Values which support the Python index protocol will validate and will be
    +    converted to the corresponding int value.
         """
     
         #: The function to use for evaluating strings to this type:
    @@ -307,24 +288,15 @@ 

    Source code for traits.trait_types

         default_value = 0
     
         #: A description of the type of value this trait accepts:
    -    info_text = "an integer (int or long)"
    +    info_text = "an integer"
     
         def validate(self, object, name, value):
             """ Validates that a specified value is valid for this trait.
             """
    -        if type(value) is int:
    -            return value
    -        elif type(value) is LONG_TYPE:
    -            return int(value)
    -
             try:
    -            int_value = operator.index(value)
    +            return _validate_int(value)
             except TypeError:
    -            pass
    -        else:
    -            return int(int_value)
    -
    -        self.error(object, name, value)
    +            self.error(object, name, value)
     
         def create_editor(self):
             """ Returns the default traits UI editor for this type of trait.
    @@ -333,67 +305,22 @@ 

    Source code for traits.trait_types

     
     
     class Int(BaseInt):
    -    """ Defines a trait whose type must be an int or long using a C-level fast
    -        validator.
    -    """
    -
    -    #: The C-level fast validator to use:
    -    fast_validate = (20,)
    -
    -
    -# -------------------------------------------------------------------------------
    -#  'BaseLong' and 'Long' traits:
    -# -------------------------------------------------------------------------------
    -
    -
    -class BaseLong(TraitType):
    -    """ Defines a trait whose value must be a Python long.
    -    """
    -
    -    #: The function to use for evaluating strings to this type:
    -    evaluate = LONG_TYPE
    -
    -    #: The default value for the trait:
    -    default_value = LONG_TYPE(0)
    -
    -    #: A description of the type of value this trait accepts:
    -    info_text = "a long"
    -
    -    def validate(self, object, name, value):
    -        """ Validates that a specified value is valid for this trait.
    -
    -            Note: The 'fast validator' version performs this check in C.
    -        """
    -        if isinstance(value, int):
    -            return LONG_TYPE(value)
    -
    -        if isinstance(value, six.integer_types):
    -            return value
    -
    -        self.error(object, name, value)
    +    """ A fast-validating trait type whose value must be an integer.
     
    -    def create_editor(self):
    -        """ Returns the default traits UI editor for this type of trait.
    -        """
    -        return default_text_editor(self, LONG_TYPE)
    -
    -
    -class Long(BaseLong):
    -    """ Defines a trait whose value must be a Python long using a C-level fast
    -        validator.
    +    Values which support the Python index protocol will validate and will be
    +    converted to the corresponding int value.
         """
     
         #: The C-level fast validator to use:
    -    fast_validate = long_fast_validate
    -
    -
    -# -------------------------------------------------------------------------------
    -#  'BaseFloat' and 'Float' traits:
    -# -------------------------------------------------------------------------------
    +    fast_validate = (ValidateTrait.int,)
     
     
     class BaseFloat(TraitType):
    -    """ Defines a trait whose value must be a Python float.
    +    """ A trait type whose value must be a float.
    +
    +    Values which support automatic conversion to floats via the Python
    +    __float__ method will validate and will be converted to the corresponding
    +    float value.
         """
     
         #: The function to use for evaluating strings to this type:
    @@ -408,7 +335,7 @@ 

    Source code for traits.trait_types

         def validate(self, object, name, value):
             """ Validates that a specified value is valid for this trait.
     
    -            Note: The 'fast validator' version performs this check in C.
    +        Note: The 'fast validator' version performs this check in C.
             """
             try:
                 return _validate_float(value)
    @@ -422,21 +349,22 @@ 

    Source code for traits.trait_types

     
     
     class Float(BaseFloat):
    -    """ Defines a trait whose value must be a Python float using a C-level fast
    -        validator.
    +    """ A fast-validating trait type whose value must be a float.
    +
    +    Values which support automatic conversion to floats via the Python
    +    __float__ method will validate and will be converted to the corresponding
    +    float value.
         """
     
         #: The C-level fast validator to use:
    -    fast_validate = (21,)
    -
    -
    -# -------------------------------------------------------------------------------
    -#  'BaseComplex' and 'Complex' traits:
    -# -------------------------------------------------------------------------------
    +    fast_validate = (ValidateTrait.float,)
     
     
     class BaseComplex(TraitType):
    -    """ Defines a trait whose value must be a Python complex.
    +    """ A trait type whose value must be a complex number.
    +
    +    Integers and floating-point numbers will be converted to the
    +    corresponding complex value.
         """
     
         #: The function to use for evaluating strings to this type:
    @@ -451,7 +379,7 @@ 

    Source code for traits.trait_types

         def validate(self, object, name, value):
             """ Validates that a specified value is valid for this trait.
     
    -            Note: The 'fast validator' version performs this check in C.
    +        Note: The 'fast validator' version performs this check in C.
             """
             if isinstance(value, complex):
                 return value
    @@ -468,21 +396,18 @@ 

    Source code for traits.trait_types

     
     
     class Complex(BaseComplex):
    -    """ Defines a trait whose value must be a Python complex using a C-level
    -        fast validator.
    +    """ A fast-validating trait type whose value must be a complex number.
    +
    +    Integers and floating-point numbers will be converted to the
    +    corresponding complex value.
         """
     
         #: The C-level fast validator to use:
         fast_validate = complex_fast_validate
     
     
    -# -------------------------------------------------------------------------------
    -#  'BaseStr' and 'Str' traits:
    -# -------------------------------------------------------------------------------
    -
    -
     class BaseStr(TraitType):
    -    """ Defines a trait whose value must be a Python string.
    +    """ A trait type whose value must be a string.
         """
     
         #: The default value for the trait:
    @@ -494,9 +419,9 @@ 

    Source code for traits.trait_types

         def validate(self, object, name, value):
             """ Validates that a specified value is valid for this trait.
     
    -            Note: The 'fast validator' version performs this check in C.
    +        Note: The 'fast validator' version performs this check in C.
             """
    -        if isinstance(value, six.string_types):
    +        if isinstance(value, str):
                 return value
     
             self.error(object, name, value)
    @@ -504,7 +429,7 @@ 

    Source code for traits.trait_types

         def create_editor(self):
             """ Returns the default traits UI editor for this type of trait.
             """
    -        from .traits import multi_line_text_editor
    +        from .editor_factories import multi_line_text_editor
     
             auto_set = self.auto_set
             if auto_set is None:
    @@ -515,17 +440,15 @@ 

    Source code for traits.trait_types

     
     
     class Str(BaseStr):
    -    """ Defines a trait whose value must be a Python string using a C-level
    -        fast validator.
    +    """ A fast-validating trait type whose value must be a complex number.
         """
     
         #: The C-level fast validator to use:
    -    fast_validate = (11,) + six.string_types
    +    fast_validate = (ValidateTrait.coerce, str)
     
     
     class Title(Str):
    -    """ Defines a string type which by default uses the traits ui TitleEditor
    -        when used in a View.
    +    """ A Str trait which by default uses a TraitsUI TitleEditor.
         """
     
         def create_editor(self):
    @@ -539,63 +462,8 @@ 

    Source code for traits.trait_types

                 return TitleEditor()
     
     
    -# -------------------------------------------------------------------------------
    -#  'BaseUnicode' and 'Unicode' traits:
    -# -------------------------------------------------------------------------------
    -
    -
    -class BaseUnicode(TraitType):
    -    """ Defines a trait whose value must be a Python unicode string.
    -    """
    -
    -    #: The default value for the trait:
    -    default_value = u""
    -
    -    #: A description of the type of value this trait accepts:
    -    info_text = "a unicode string"
    -
    -    def validate(self, object, name, value):
    -        """ Validates that a specified value is valid for this trait.
    -
    -            Note: The 'fast validator' version performs this check in C.
    -        """
    -        if isinstance(value, six.text_type):
    -            return value
    -
    -        if isinstance(value, str):
    -            return six.text_type(value)
    -
    -        self.error(object, name, value)
    -
    -    def create_editor(self):
    -        """ Returns the default traits UI editor for this type of trait.
    -        """
    -        from .traits import multi_line_text_editor
    -
    -        auto_set = self.auto_set
    -        if auto_set is None:
    -            auto_set = True
    -        enter_set = self.enter_set or False
    -
    -        return multi_line_text_editor(auto_set, enter_set)
    -
    -
    -class Unicode(BaseUnicode):
    -    """ Defines a trait whose value must be a Python unicode string using a
    -        C-level fast validator.
    -    """
    -
    -    #: The C-level fast validator to use:
    -    fast_validate = (11, six.text_type, None, str)
    -
    -
    -# -------------------------------------------------------------------------------
    -#  'BaseBytes' and 'Bytes' traits:
    -# -------------------------------------------------------------------------------
    -
    -
     class BaseBytes(TraitType):
    -    """ Defines a trait whose value must be a Python bytes string.
    +    """ A trait type whose value must be a bytestring.
         """
     
         #: The default value for the trait:
    @@ -610,7 +478,7 @@ 

    Source code for traits.trait_types

         def validate(self, object, name, value):
             """ Validates that a specified value is valid for this trait.
     
    -            Note: The 'fast validator' version performs this check in C.
    +        Note: The 'fast validator' version performs this check in C.
             """
             if isinstance(value, bytes):
                 return value
    @@ -631,21 +499,15 @@ 

    Source code for traits.trait_types

     
     
     class Bytes(BaseBytes):
    -    """ Defines a trait whose value must be a Python bytes string using a
    -        C-level fast validator.
    +    """ A fast-validating trait type whose value must be a bytestring.
         """
     
         #: The C-level fast validator to use:
    -    fast_validate = (11, bytes)
    -
    -
    -# -------------------------------------------------------------------------------
    -#  'BaseBool' and 'Bool' traits:
    -# -------------------------------------------------------------------------------
    +    fast_validate = (ValidateTrait.coerce, bytes)
     
     
     class BaseBool(TraitType):
    -    """ Defines a trait whose value must be a Python boolean.
    +    """ A trait type whose value must be a bool.
         """
     
         #: The function to use for evaluating strings to this type:
    @@ -660,7 +522,7 @@ 

    Source code for traits.trait_types

         def validate(self, object, name, value):
             """ Validates that a specified value is valid for this trait.
     
    -            Note: The 'fast validator' version performs this check in C.
    +        Note: The 'fast validator' version performs this check in C.
             """
             if isinstance(value, _BOOL_TYPES):
                 return bool(value)
    @@ -676,22 +538,15 @@ 

    Source code for traits.trait_types

     
     
     class Bool(BaseBool):
    -    """ Defines a trait whose value must be a Python boolean using a C-level
    -        fast validator.
    +    """ A fast-validating trait type whose value must be a bool.
         """
     
         #: The C-level fast validator to use:
         fast_validate = bool_fast_validate
     
     
    -# -------------------------------------------------------------------------------
    -#  'BaseCInt' and 'CInt' traits:
    -# -------------------------------------------------------------------------------
    -
    -
     class BaseCInt(BaseInt):
    -    """ Defines a trait whose value must be a Python int and which supports
    -        coercions of non-int values to int.
    +    """ A coercing trait type whose value is an integer.
         """
     
         #: The function to use for evaluating strings to this type:
    @@ -700,64 +555,24 @@ 

    Source code for traits.trait_types

         def validate(self, object, name, value):
             """ Validates that a specified value is valid for this trait.
     
    -            Note: The 'fast validator' version performs this check in C.
    +        Note: The 'fast validator' version performs this check in C.
             """
             try:
                 return int(value)
    -        except:
    +        except (ValueError, TypeError):
                 self.error(object, name, value)
     
     
     class CInt(BaseCInt):
    -    """ Defines a trait whose value must be a Python int and which supports
    -        coercions of non-int values to int using a C-level fast validator.
    -    """
    -
    -    #: The C-level fast validator to use:
    -    fast_validate = (12, int)
    -
    -
    -# -------------------------------------------------------------------------------
    -#  'BaseCLong' and 'CLong' traits:
    -# -------------------------------------------------------------------------------
    -
    -
    -class BaseCLong(BaseLong):
    -    """ Defines a trait whose value must be a Python long and which supports
    -        coercions of non-long values to long.
    -    """
    -
    -    #: The function to use for evaluating strings to this type:
    -    evaluate = LONG_TYPE
    -
    -    def validate(self, object, name, value):
    -        """ Validates that a specified value is valid for this trait.
    -
    -            Note: The 'fast validator' version performs this check in C.
    -        """
    -        try:
    -            return LONG_TYPE(value)
    -        except:
    -            self.error(object, name, value)
    -
    -
    -class CLong(BaseCLong):
    -    """ Defines a trait whose value must be a Python long and which supports
    -        coercions of non-long values to long using a C-level fast validator.
    +    """ A fast-validating, coercing trait type whose value is an int.
         """
     
         #: The C-level fast validator to use:
    -    fast_validate = (12, LONG_TYPE)
    -
    -
    -# -------------------------------------------------------------------------------
    -#  'BaseCFloat' and 'CFloat' traits:
    -# -------------------------------------------------------------------------------
    +    fast_validate = (ValidateTrait.cast, int)
     
     
     class BaseCFloat(BaseFloat):
    -    """ Defines a trait whose value must be a Python float and which supports
    -        coercions of non-float values to float.
    +    """ A coercing trait type whose value is a float.
         """
     
         #: The function to use for evaluating strings to this type:
    @@ -766,31 +581,24 @@ 

    Source code for traits.trait_types

         def validate(self, object, name, value):
             """ Validates that a specified value is valid for this trait.
     
    -            Note: The 'fast validator' version performs this check in C.
    +        Note: The 'fast validator' version performs this check in C.
             """
             try:
                 return float(value)
    -        except:
    +        except (ValueError, TypeError):
                 self.error(object, name, value)
     
     
     class CFloat(BaseCFloat):
    -    """ Defines a trait whose value must be a Python float and which supports
    -        coercions of non-float values to float using a C-level fast validator.
    +    """ A fast-validating, coercing trait type whose value is a float.
         """
     
         #: The C-level fast validator to use:
    -    fast_validate = (12, float)
    -
    -
    -# -------------------------------------------------------------------------------
    -#  'BaseCComplex' and 'CComplex' traits:
    -# -------------------------------------------------------------------------------
    +    fast_validate = (ValidateTrait.cast, float)
     
     
     class BaseCComplex(BaseComplex):
    -    """ Defines a trait whose value must be a Python complex and which supports
    -        coercions of non-complex values to complex.
    +    """ A coercing trait type whose value is a complex number.
         """
     
         #: The function to use for evaluating strings to this type:
    @@ -799,103 +607,53 @@ 

    Source code for traits.trait_types

         def validate(self, object, name, value):
             """ Validates that a specified value is valid for this trait.
     
    -            Note: The 'fast validator' version performs this check in C.
    +        Note: The 'fast validator' version performs this check in C.
             """
             try:
                 return complex(value)
    -        except:
    +        except (ValueError, TypeError):
                 self.error(object, name, value)
     
     
     class CComplex(BaseCComplex):
    -    """ Defines a trait whose value must be a Python complex and which supports
    -        coercions of non-complex values to complex using a C-level fast
    -        validator.
    +    """ A fast-validating, coercing trait type whose value is a complex number.
         """
     
         #: The C-level fast validator to use:
    -    fast_validate = (12, complex)
    -
    -
    -# -------------------------------------------------------------------------------
    -#  'BaseCStr' and 'CStr' traits:
    -# -------------------------------------------------------------------------------
    +    fast_validate = (ValidateTrait.cast, complex)
     
     
     class BaseCStr(BaseStr):
    -    """ Defines a trait whose value must be a Python string and which supports
    -        coercions of non-string values to string.
    +    """ A coercing trait type whose value is a string.
         """
     
         def validate(self, object, name, value):
             """ Validates that a specified value is valid for this trait.
     
    -            Note: The 'fast validator' version performs this check in C.
    +        Note: The 'fast validator' version performs this check in C.
             """
             try:
                 return str(value)
    -        except:
    -            try:
    -                return six.text_type(value)
    -            except:
    -                self.error(object, name, value)
    -
    -
    -class CStr(BaseCStr):
    -    """ Defines a trait whose value must be a Python string and which supports
    -        coercions of non-string values to string using a C-level fast
    -        validator.
    -    """
    -
    -    #: The C-level fast validator to use:
    -    fast_validate = (7, ((12, str), (12, six.text_type)))
    -
    -
    -# -------------------------------------------------------------------------------
    -#  'BaseCUnicode' and 'CUnicode' traits:
    -# -------------------------------------------------------------------------------
    -
    -
    -class BaseCUnicode(BaseUnicode):
    -    """ Defines a trait whose value must be a Python unicode string and which
    -        supports coercions of non-unicode values to unicode.
    -    """
    -
    -    def validate(self, object, name, value):
    -        """ Validates that a specified value is valid for this trait.
    -
    -            Note: The 'fast validator' version performs this check in C.
    -        """
    -        try:
    -            return six.text_type(value)
             except:
                 self.error(object, name, value)
     
     
    -class CUnicode(BaseCUnicode):
    -    """ Defines a trait whose value must be a Python unicode string and which
    -        supports coercions of non-unicode values to unicode using a C-level
    -        fast validator.
    +class CStr(BaseCStr):
    +    """ A fast-validating, coercing trait type whose value is a string.
         """
     
         #: The C-level fast validator to use:
    -    fast_validate = (12, six.text_type)
    -
    -
    -# -------------------------------------------------------------------------------
    -#  'BaseCBytes' and 'CBytes' traits:
    -# -------------------------------------------------------------------------------
    +    fast_validate = (ValidateTrait.cast, str)
     
     
     class BaseCBytes(BaseBytes):
    -    """ Defines a trait whose value must be a Python bytes object and which
    -        supports coercions of non-bytes values to bytes.
    +    """ A coercing trait type whose value is a bytestring.
         """
     
         def validate(self, object, name, value):
             """ Validates that a specified value is valid for this trait.
     
    -            Note: The 'fast validator' version performs this check in C.
    +        Note: The 'fast validator' version performs this check in C.
             """
             try:
                 return bytes(value)
    @@ -904,23 +662,15 @@ 

    Source code for traits.trait_types

     
     
     class CBytes(BaseCBytes):
    -    """ Defines a trait whose value must be a Python bytes and which
    -        supports coercions of non-bytes values bytes using a C-level
    -        fast validator.
    +    """ A fast-validating, coercing trait type whose value is a bytestring.
         """
     
         #: The C-level fast validator to use:
    -    fast_validate = (12, bytes)
    -
    -
    -# -------------------------------------------------------------------------------
    -#  'BaseCBool' and 'CBool' traits:
    -# -------------------------------------------------------------------------------
    +    fast_validate = (ValidateTrait.cast, bytes)
     
     
     class BaseCBool(BaseBool):
    -    """ Defines a trait whose value must be a Python boolean and which supports
    -        coercions of non-boolean values to boolean.
    +    """ A coercing trait type whose value is a bool.
         """
     
         #: The function to use for evaluating strings to this type:
    @@ -929,7 +679,7 @@ 

    Source code for traits.trait_types

         def validate(self, object, name, value):
             """ Validates that a specified value is valid for this trait.
     
    -            Note: The 'fast validator' version performs this check in C.
    +        Note: The 'fast validator' version performs this check in C.
             """
             try:
                 return bool(value)
    @@ -938,43 +688,45 @@ 

    Source code for traits.trait_types

     
     
     class CBool(BaseCBool):
    -    """ Defines a trait whose value must be a Python boolean and which supports
    -        coercions of non-boolean values to boolean using a C-level fast
    -        validator.
    +    """ A fast-validating, coercing trait type whose value is a bool.
         """
     
         #: The C-level fast validator to use:
    -    fast_validate = (12, bool)
    -
    -
    -# -------------------------------------------------------------------------------
    -#  'String' trait:
    -# -------------------------------------------------------------------------------
    +    fast_validate = (ValidateTrait.cast, bool)
     
     
     class String(TraitType):
    -    """ Defines a trait whose value must be a Python string whose length is
    -        optionally in a specified range, and which optionally matches a
    -        specified regular expression.
    +    """ A trait type whose value must be a string with optional constraints.
    +
    +    The value is a string whose length is in a specified range, and which
    +    optionally matches a specified regular expression.
    +
    +    Parameters
    +    ----------
    +    value : str
    +        The default value for the string.
    +    minlen : integer
    +        The minimum length allowed for the string.
    +    maxlen : integer
    +        The maximum length allowed for the string.
    +    regex : str
    +        A Python regular expression that the string must match.
    +    **metadata
    +        The trait metadata for the trait.
    +
    +    Attributes
    +    ----------
    +    minlen : integer
    +        The minimum length allowed for the string.
    +    maxlen : integer
    +        The maximum length allowed for the string.
    +    regex : str
    +        A Python regular expression that the string must match.
         """
     
         def __init__(
    -        self, value="", minlen=0, maxlen=six.MAXSIZE, regex="", **metadata
    +        self, value="", minlen=0, maxlen=sys.maxsize, regex="", **metadata
         ):
    -        """ Creates a String trait.
    -
    -        Parameters
    -        ----------
    -        value : str
    -            The default value for the string.
    -        minlen : integer
    -            The minimum length allowed for the string.
    -        maxlen : integer
    -            The maximum length allowed for the string.
    -        regex : str
    -            A Python regular expression that the string must match.
    -
    -        """
             super(String, self).__init__(value, **metadata)
             self.minlen = max(0, minlen)
             self.maxlen = max(self.minlen, maxlen)
    @@ -983,14 +735,14 @@ 

    Source code for traits.trait_types

     
         def _init(self):
             """ Completes initialization of the trait at construction or unpickling
    -            time.
    +        time.
             """
             self._validate = "validate_all"
             if self.regex != "":
                 self.match = re.compile(self.regex).match
    -            if (self.minlen == 0) and (self.maxlen == six.MAXSIZE):
    +            if (self.minlen == 0) and (self.maxlen == sys.maxsize):
                     self._validate = "validate_regex"
    -        elif (self.minlen == 0) and (self.maxlen == six.MAXSIZE):
    +        elif (self.minlen == 0) and (self.maxlen == sys.maxsize):
                 self._validate = "validate_str"
             else:
                 self._validate = "validate_len"
    @@ -1027,7 +779,7 @@ 

    Source code for traits.trait_types

     
         def validate_len(self, object, name, value):
             """ Validates that the value is a valid string in the specified length
    -            range.
    +        range.
             """
             try:
                 value = strx(value)
    @@ -1040,7 +792,7 @@ 

    Source code for traits.trait_types

     
         def validate_regex(self, object, name, value):
             """ Validates that the value is a valid string which matches the
    -            specified regular expression.
    +        specified regular expression.
             """
             try:
                 value = strx(value)
    @@ -1055,12 +807,12 @@ 

    Source code for traits.trait_types

             """ Returns a description of the trait.
             """
             msg = ""
    -        if (self.minlen != 0) and (self.maxlen != six.MAXSIZE):
    +        if (self.minlen != 0) and (self.maxlen != sys.maxsize):
                 msg = " between %d and %d characters long" % (
                     self.minlen,
                     self.maxlen,
                 )
    -        elif self.maxlen != six.MAXSIZE:
    +        elif self.maxlen != sys.maxsize:
                 msg = " <= %d characters long" % self.maxlen
             elif self.minlen != 0:
                 msg = " >= %d characters long" % self.minlen
    @@ -1092,86 +844,58 @@ 

    Source code for traits.trait_types

             self._init()
     
     
    -# -------------------------------------------------------------------------------
    -#  'Regex' trait:
    -# -------------------------------------------------------------------------------
    -
    -
     class Regex(String):
    -    """ Defines a trait whose value is a Python string that matches a specified
    -        regular expression.
    +    """ A trait type whose value must match a regular expression.
    +
    +    Parameters
    +    ----------
    +    value : str
    +        The default value of the trait.
    +    regex : str
    +        The regular expression that the trait value must match.
    +    **metadata
    +        Trait metadata.
         """
     
         def __init__(self, value="", regex=".*", **metadata):
    -        """ Creates a Regex trait.
    -
    -        Parameters
    -        ----------
    -        value : str
    -            The default value of the trait.
    -        regex : str
    -            The regular expression that the trait value must match.
    -
    -        Default Value
    -        -------------
    -        *value* or ''
    -        """
             super(Regex, self).__init__(value=value, regex=regex, **metadata)
     
     
    -# -------------------------------------------------------------------------------
    -#  'Code' trait:
    -# -------------------------------------------------------------------------------
    -
    -
     class Code(String):
    -    """ Defines a trait whose value is a Python string that represents source
    -        code in some language.
    +    """ A trait type whose value holds a string of source code.
    +
    +    Validation does not perform any sort of syntax checking. The default
    +    TraitsUI editor is a CodeEditor.
         """
     
         #: The standard metadata for the trait:
         metadata = {"editor": code_editor}
     
     
    -# -------------------------------------------------------------------------------
    -#  'HTML' trait:
    -# -------------------------------------------------------------------------------
    -
    -
     class HTML(String):
    -    """ Defines a trait whose value must be a string that is interpreted as
    -    being HTML. By default the value is parsed and displayed as HTML in
    -    TraitsUI views. The validation of the value does not enforce HTML syntax.
    +    """ A trait type whose value holds an HTML string.
    +
    +    The validation of the value does not enforce HTML syntax.  The default
    +    TraitsUI editor is an HTMLEditor.
         """
     
         #: The standard metadata for the trait:
         metadata = {"editor": html_editor}
     
     
    -# -------------------------------------------------------------------------------
    -#  'Password' trait:
    -# -------------------------------------------------------------------------------
    -
    -
     class Password(String):
    -    """ Defines a trait whose value must be a string, optionally of constrained
    -    length or matching a regular expression.
    +    """ A trait type whose value holds a password string.
     
    -    The trait is identical to a String trait except that by default it uses a
    -    PasswordEditor in TraitsUI views, which obscures text entered by the user.
    +    The default TraitsUI editor is an PasswordEditor, which obscures text
    +    entered by the user.
         """
     
         #: The standard metadata for the trait:
         metadata = {"editor": password_editor}
     
     
    -# -------------------------------------------------------------------------------
    -#  'Callable' trait:
    -# -------------------------------------------------------------------------------
    -
    -
    -class Callable(TraitType):
    -    """ Defines a trait whose value must be a Python callable.
    +class BaseCallable(TraitType):
    +    """ A trait type whose value must be a Python callable.
         """
     
         #: The standard metadata for the trait:
    @@ -1192,13 +916,22 @@ 

    Source code for traits.trait_types

             self.error(object, name, value)
     
     
    -# -------------------------------------------------------------------------------
    -#  'BaseType' base class:
    -# -------------------------------------------------------------------------------
    +class Callable(BaseCallable):
    +    """ A fast-validating trait type whose value must be a Python callable.
    +    """
    +    def __init__(self, value=None, allow_none=True, **metadata):
    +
    +        self.fast_validate = (ValidateTrait.callable, allow_none)
    +
    +        default_value = metadata.pop("default_value", value)
    +
    +        super().__init__(default_value, **metadata)
     
     
     class BaseType(TraitType):
    -    """ Defines a trait whose value must be an instance of a simple Python type.
    +    """ A trait type whose value must be an instance of a Python type.
    +
    +    This is an abstract class and should not be directly instantiated.
         """
     
         def validate(self, object, name, value):
    @@ -1211,11 +944,11 @@ 

    Source code for traits.trait_types

     
     
     class This(BaseType):
    -    """ Defines a trait whose value must be an instance of the defining class.
    +    """ A trait type whose value must be an instance of the defining class.
         """
     
         #: The C-level fast validator to use:
    -    fast_validate = (2,)
    +    fast_validate = (ValidateTrait.self_type,)
     
         #: A description of the type of value this trait accepts:
         info_text = "an instance of the same type as the receiver"
    @@ -1224,7 +957,7 @@ 

    Source code for traits.trait_types

             super(This, self).__init__(value, **metadata)
     
             if allow_none:
    -            self.fast_validate = (2, None)
    +            self.fast_validate = (ValidateTrait.self_type, None)
                 self.validate = self.validate_none
                 self.info = self.info_none
     
    @@ -1232,13 +965,13 @@ 

    Source code for traits.trait_types

             if isinstance(value, object.__class__):
                 return value
     
    -        self.validate_failed(object, name, value)
    +        self.error(object, name, value)
     
         def validate_none(self, object, name, value):
             if isinstance(value, object.__class__) or (value is None):
                 return value
     
    -        self.validate_failed(object, name, value)
    +        self.error(object, name, value)
     
         def info(self):
             return "an instance of the same type as the receiver"
    @@ -1246,84 +979,59 @@ 

    Source code for traits.trait_types

         def info_none(self):
             return "an instance of the same type as the receiver or None"
     
    -    def validate_failed(self, object, name, value):
    -        kind = type(value)
    -        if _py2to3.is_InstanceType(kind):
    -            msg = "class %s" % value.__class__.__name__
    -        else:
    -            msg = "%s (i.e. %s)" % (str(kind)[1:-1], repr(value))
    -
    -        self.error(object, name, msg)
    -
     
     class self(This):
    -    """ Defines a trait whose value must be an instance of the defining class
    -        and whose default value is the object containing the trait.
    +    """ A trait type whose default value is the object containing the trait.
    +
    +    The trait can be assigned to, but any new value must be an instance of
    +    the defining class.
         """
     
         #: The default value type to use (i.e. 'self'):
    -    default_value_type = OBJECT_DEFAULT_VALUE
    +    default_value_type = DefaultValue.object
     
     
     class Function(TraitType):
    -    """ Defines a trait whose value must be a Python function.
    +    """ A trait type whose value must be a function.
         """
     
         #: The C-level fast validator to use:
    -    fast_validate = (11, FunctionType)
    +    fast_validate = (ValidateTrait.coerce, FunctionType)
     
         #: A description of the type of value this trait accepts:
         info_text = "a function"
     
     
     class Method(TraitType):
    -    """ Defines a trait whose value must be a Python method.
    +    """ A trait type whose value must be a method.
         """
     
         #: The C-level fast validator to use:
    -    fast_validate = (11, MethodType)
    +    fast_validate = (ValidateTrait.coerce, MethodType)
     
         #: A description of the type of value this trait accepts:
         info_text = "a method"
     
     
    -if six.PY2:
    -    from types import ClassType
    -
    -    class Class(TraitType):
    -        """ Defines a trait whose value must be an old-style Python class.
    -        """
    -
    -        #: The C-level fast validator to use:
    -        fast_validate = (11, ClassType)
    -
    -        #: A description of the type of value this trait accepts:
    -        info_text = "an old-style class"
    -
    -
     class Module(TraitType):
    -    """ Defines a trait whose value must be a Python module.
    +    """ A trait type whose value must be a module.
         """
     
         #: The C-level fast validator to use:
    -    fast_validate = (11, ModuleType)
    +    fast_validate = (ValidateTrait.coerce, ModuleType)
     
         #: A description of the type of value this trait accepts:
         info_text = "a module"
     
     
    -# -------------------------------------------------------------------------------
    -#  'Python' trait:
    -# -------------------------------------------------------------------------------
    -
    -
     class Python(TraitType):
    -    """ Defines a trait that provides behavior identical to a standard Python
    -        attribute. That is, it allows any value to be assigned, and raises an
    -        ValueError if an attempt is made to get the value before one has been
    -        assigned. It has no default value. This trait is most often used in
    -        conjunction with wildcard naming. See the *Traits User Manual* for
    -        details on wildcards.
    +    """ A trait type that behaves as a standard Python attribute.
    +
    +    This trait type allows any value to be assigned, and raises an
    +    ValueError if an attempt is made to get the value before one has been
    +    assigned. It has no default value. This trait is most often used in
    +    conjunction with wildcard naming. See the *Traits User Manual* for
    +    details on wildcards.
         """
     
         #: The standard metadata for the trait:
    @@ -1333,25 +1041,21 @@ 

    Source code for traits.trait_types

         default_value = Undefined
     
     
    -# -------------------------------------------------------------------------------
    -#  'ReadOnly' trait:
    -# -------------------------------------------------------------------------------
    -
    -
     class ReadOnly(TraitType):
    -    """ Defines a trait that is write-once, and then read-only.
    -        The initial value of the attribute is the special, singleton object
    -        Undefined. The trait allows any value to be assigned to the attribute
    -        if the current value is the Undefined object. Once any other value is
    -        assigned, no further assignment is allowed. Normally, the initial
    -        assignment to the attribute is performed in the class constructor,
    -        based on information passed to the constructor. If the read-only value
    -        is known in advance of run time, use the Constant() function instead of
    -        ReadOnly to define the trait.
    +    """ A trait type that is write-once, and then read-only.
    +
    +    The initial value of the attribute is the special, singleton object
    +    Undefined. The trait allows any value to be assigned to the attribute
    +    if the current value is the Undefined object. Once any other value is
    +    assigned, no further assignment is allowed. Normally, the initial
    +    assignment to the attribute is performed in the class constructor,
    +    based on information passed to the constructor. If the read-only value
    +    is known in advance of run time, use Constant instead of ReadOnly to
    +    define the trait.
         """
     
         # Defines the CTrait type to use for this trait:
    -    ctrait_type = 6
    +    ctrait_type = TraitKind.read_only
     
         #: The default value for the trait:
         default_value = Undefined
    @@ -1360,79 +1064,108 @@ 

    Source code for traits.trait_types

     # Create a singleton instance as the trait:
     ReadOnly = ReadOnly()
     
    -# -------------------------------------------------------------------------------
    -#  'Disallow' trait:
    -# -------------------------------------------------------------------------------
    -
     
     class Disallow(TraitType):
    -    """ Defines a trait that prevents any value from being assigned or read.
    -        That is, any attempt to get or set the value of the trait attribute
    -        raises an exception. This trait is most often used in conjunction with
    -        wildcard naming, for example, to catch spelling mistakes in attribute
    -        names. See the *Traits User Manual* for details on wildcards.
    +    """ A trait that prevents any value from being assigned or read.
    +
    +    Any attempt to get or set the value of the trait attribute raises an
    +    exception. This trait is most often used in conjunction with wildcard
    +    naming, for example, to catch spelling mistakes in attribute names.
    +
    +    See the *Traits User Manual* for details on wildcards.
         """
     
         #: Defines the CTrait type to use for this trait:
    -    ctrait_type = 5
    +    ctrait_type = TraitKind.disallow
     
     
     # Create a singleton instance as the trait:
     Disallow = Disallow()
     
    -# -------------------------------------------------------------------------------
    -#  'Constant' trait:
    -# -------------------------------------------------------------------------------
    -
     
     class Constant(TraitType):
    -    """  Defines a trait whose value is a constant.
    +    """ A trait type whose value is a constant.
    +
    +    Traits of this type are very space efficient (and fast) because
    +    *value* is not stored in each instance using the trait, but only in
    +    the trait object itself.
    +
    +    Parameters
    +    ----------
    +    value : any
    +        The constant value for the trait.
    +    **metadata
    +        Trait metadata for the trait.
         """
     
         #: Defines the CTrait type to use for this trait:
    -    ctrait_type = 7
    +    ctrait_type = TraitKind.constant
     
         #: The standard metadata for the trait:
         metadata = {"type": "constant", "transient": True}
     
    -    def __init__(self, value, **metadata):
    -        """ Returns a constant, read-only trait whose value is *value*.
    -
    -            Parameters
    -            ----------
    -            value : any type except a list or dictionary
    -                The default value for the trait.
    -
    -            Default Value
    -            -------------
    -            *value*
    -
    -            Description
    -            -----------
    -            Traits of this type are very space efficient (and fast) because
    -            *value* is not stored in each instance using the trait, but only in
    -            the trait object itself. The *value* cannot be a list or dictionary,
    -            because those types have mutable values.
    -        """
    -        if type(value) in MutableTypes:
    -            raise TraitError(
    -                "Cannot define a constant using a mutable list or dictionary"
    -            )
    -
    -        super(Constant, self).__init__(value, **metadata)
    -
    -
    -# -------------------------------------------------------------------------------
    -#  'Delegate' trait:
    -# -------------------------------------------------------------------------------
    -
     
     class Delegate(TraitType):
    -    """ Defines a trait whose value is delegated to a trait on another object.
    +    """ A trait type whose value is delegated to a trait on another object.
    +
    +    This is a base class that shouldn't be used directly, rather use one of
    +    the subclasses DelegatesTo or PrototypesFrom, depending on desired
    +    behaviour.
    +
    +    An object containing a delegator trait attribute must contain a
    +    second attribute that references the object containing the delegate
    +    trait attribute. The name of this second attribute is passed as the
    +    *delegate* argument.
    +
    +    The following rules govern the application of the prefix parameter:
    +
    +    * If *prefix* is empty or omitted, the delegation is to an attribute
    +      of the delegate object with the same name as the delegator
    +      attribute.
    +    * If *prefix* is a valid Python attribute name, then the delegation
    +      is to an attribute whose name is the value of *prefix*.
    +    * If *prefix* ends with an asterisk ('*') and is longer than one
    +      character, then the delegation is to an attribute whose name is
    +      the value of *prefix*, minus the trailing asterisk, prepended to
    +      the delegator attribute name.
    +    * If *prefix* is equal to a single asterisk, the delegation is to an
    +      attribute whose name is the value of the delegator object's
    +      __prefix__ attribute prepended to delegator attribute name.
    +
    +    Parameters
    +    ----------
    +    delegate : str
    +        The name of the trait that holds the HasTraits instance that the
    +        value is delegated to.
    +    prefix : str
    +        The name of the trait on the delegate that holds the delegated
    +        value.  If empty, then the name of this trait will be used.
    +    modify : bool
    +        Whether modifications of this trait are applied to the delegated
    +        object.  This differentiates the behaviour of DelegatesTo and
    +        PrototypedFrom.
    +    listenable : bool
    +        Whether changes to the delegated trait will fire listeners to
    +        this trait.
    +
    +    Attributes
    +    ----------
    +    delegate : str
    +        The name of the trait that holds the HasTraits instance that the
    +        value is delegated to.
    +    prefix : str
    +        The name of the trait on the delegate that holds the delegated
    +        value.  If empty, then the name of this trait will be used.
    +    prefix_type : int
    +        An integer giving the type of prefix being used.
    +    modify : bool
    +        Whether modifications of this trait are applied to the delegated
    +        object.  This differentiates the behaviour of DelegatesTo and
    +        PrototypedFrom.
         """
     
         #: Defines the CTrait type to use for this trait:
    -    ctrait_type = 3
    +    ctrait_type = TraitKind.delegate
     
         #: The standard metadata for the trait:
         metadata = {"type": "delegate", "transient": False}
    @@ -1475,58 +1208,52 @@ 

    Source code for traits.trait_types

             return trait
     
     
    -# -------------------------------------------------------------------------------
    -#  'DelegatesTo' trait:
    -# -------------------------------------------------------------------------------
    -
    -
     class DelegatesTo(Delegate):
    -    """ Defines a trait delegate that matches the standard 'delegate' design
    -        pattern.
    +    """ A trait type that matches the 'delegate' design pattern.
    +
    +    This defines a trait whose value and definition is "delegated" to
    +    another trait on a different object.
    +
    +    An object containing a delegator trait attribute must contain a
    +    second attribute that references the object containing the delegate
    +    trait attribute. The name of this second attribute is passed as the
    +    *delegate* argument to the DelegatesTo() function.
    +
    +    The following rules govern the application of the prefix parameter:
    +
    +    * If *prefix* is empty or omitted, the delegation is to an attribute
    +      of the delegate object with the same name as the delegator
    +      attribute.
    +    * If *prefix* is a valid Python attribute name, then the delegation
    +      is to an attribute whose name is the value of *prefix*.
    +    * If *prefix* ends with an asterisk ('*') and is longer than one
    +      character, then the delegation is to an attribute whose name is
    +      the value of *prefix*, minus the trailing asterisk, prepended to
    +      the delegator attribute name.
    +    * If *prefix* is equal to a single asterisk, the delegation is to an
    +      attribute whose name is the value of the delegator object's
    +      __prefix__ attribute prepended to delegator attribute name.
    +
    +    Note that any changes to the delegator attribute are actually
    +    applied to the corresponding attribute on the delegate object. The
    +    original object containing the delegator trait is not modified.
    +
    +    Parameters
    +    ----------
    +    delegate : str
    +        Name of the attribute on the current object which references
    +        the object that is the trait's delegate.
    +    prefix : str
    +        A prefix or substitution applied to the original attribute when
    +        looking up the delegated attribute.
    +    listenable : bool
    +        Indicates whether a listener can be attached to this attribute
    +        such that changes to the delegated attribute will trigger it.
    +    **metadata
    +        Trait metadata for the trait.
         """
     
         def __init__(self, delegate, prefix="", listenable=True, **metadata):
    -        """ Creates a "delegator" trait, whose definition and default value are
    -            delegated to a *delegate* trait attribute on another object.
    -
    -            Parameters
    -            ----------
    -            delegate : str
    -                Name of the attribute on the current object which references
    -                the object that is the trait's delegate.
    -            prefix : str
    -                A prefix or substitution applied to the original attribute when
    -                looking up the delegated attribute.
    -            listenable : bool
    -                Indicates whether a listener can be attached to this attribute
    -                such that changes to the delagate attribute will trigger it.
    -
    -            Description
    -            -----------
    -            An object containing a delegator trait attribute must contain a
    -            second attribute that references the object containing the delegate
    -            trait attribute. The name of this second attribute is passed as the
    -            *delegate* argument to the DelegatesTo() function.
    -
    -            The following rules govern the application of the prefix parameter:
    -
    -            * If *prefix* is empty or omitted, the delegation is to an attribute
    -              of the delegate object with the same name as the delegator
    -              attribute.
    -            * If *prefix* is a valid Python attribute name, then the delegation
    -              is to an attribute whose name is the value of *prefix*.
    -            * If *prefix* ends with an asterisk ('*') and is longer than one
    -              character, then the delegation is to an attribute whose name is
    -              the value of *prefix*, minus the trailing asterisk, prepended to
    -              the delegator attribute name.
    -            * If *prefix* is equal to a single asterisk, the delegation is to an
    -              attribute whose name is the value of the delegator object's
    -              __prefix__ attribute prepended to delegator attribute name.
    -
    -            Note that any changes to the delegator attribute are actually
    -            applied to the corresponding attribute on the delegate object. The
    -            original object containing the delegator trait is not modified.
    -        """
             super(DelegatesTo, self).__init__(
                 delegate,
                 prefix=prefix,
    @@ -1536,61 +1263,54 @@ 

    Source code for traits.trait_types

             )
     
     
    -# -------------------------------------------------------------------------------
    -#  'PrototypedFrom' trait:
    -# -------------------------------------------------------------------------------
    -
    -
     class PrototypedFrom(Delegate):
    -    """ Defines a trait delegate that matches the standard 'prototype' design
    -        pattern.
    +    """ A trait type that matches the 'prototype' design pattern.
    +
    +    This defines a trait whose default value and definition is "prototyped"
    +    from another trait on a different object.
    +
    +    An object containing a prototyped trait attribute must contain a
    +    second attribute that references the object containing the prototype
    +    trait attribute. The name of this second attribute is passed as the
    +    *prototype* argument to the PrototypedFrom() function.
    +
    +    The following rules govern the application of the prefix parameter:
    +
    +    * If *prefix* is empty or omitted, the prototype delegation is to an
    +      attribute of the prototype object with the same name as the
    +      prototyped attribute.
    +    * If *prefix* is a valid Python attribute name, then the prototype
    +      delegation is to an attribute whose name is the value of *prefix*.
    +    * If *prefix* ends with an asterisk ('*') and is longer than one
    +      character, then the prototype delegation is to an attribute whose
    +      name is the value of *prefix*, minus the trailing asterisk,
    +      prepended to the prototyped attribute name.
    +    * If *prefix* is equal to a single asterisk, the prototype
    +      delegation is to an attribute whose name is the value of the
    +      prototype object's __prefix__ attribute prepended to the
    +      prototyped attribute name.
    +
    +    Note that any changes to the prototyped attribute are made to the
    +    original object, not the prototype object. The prototype object is
    +    only used to define to trait type and default value.
    +
    +    Parameters
    +    ----------
    +    prototype : str
    +        Name of the attribute on the current object which references the
    +        object that is the trait's prototype.
    +    prefix : str
    +        A prefix or substitution applied to the original attribute when
    +        looking up the prototyped attribute.
    +    listenable : bool
    +        Indicates whether a listener can be attached to this attribute
    +        such that changes to the corresponding attribute on the
    +        prototype object will trigger it.
    +    **metadata
    +        Trait metadata for the trait.
         """
     
         def __init__(self, prototype, prefix="", listenable=True, **metadata):
    -        """ Creates a "prototyped" trait, whose definition and default value are
    -            obtained from a trait attribute on another object.
    -
    -            Parameters
    -            ----------
    -            prototype : str
    -                Name of the attribute on the current object which references the
    -                object that is the trait's prototype.
    -            prefix : str
    -                A prefix or substitution applied to the original attribute when
    -                looking up the prototyped attribute.
    -            listenable : bool
    -                Indicates whether a listener can be attached to this attribute
    -                such that changes to the corresponding attribute on the
    -                prototype object will trigger it.
    -
    -            Description
    -            -----------
    -            An object containing a prototyped trait attribute must contain a
    -            second attribute that references the object containing the prototype
    -            trait attribute. The name of this second attribute is passed as the
    -            *prototype* argument to the PrototypedFrom() function.
    -
    -            The following rules govern the application of the prefix parameter:
    -
    -            * If *prefix* is empty or omitted, the prototype delegation is to an
    -              attribute of the prototype object with the same name as the
    -              prototyped attribute.
    -            * If *prefix* is a valid Python attribute name, then the prototype
    -              delegation is to an attribute whose name is the value of *prefix*.
    -            * If *prefix* ends with an asterisk ('*') and is longer than one
    -              character, then the prototype delegation is to an attribute whose
    -              name is the value of *prefix*, minus the trailing asterisk,
    -              prepended to the prototyped attribute name.
    -            * If *prefix* is equal to a single asterisk, the prototype
    -              delegation is to an attribute whose name is the value of the
    -              prototype object's __prefix__ attribute prepended to the
    -              prototyped attribute name.
    -
    -            Note that any changes to the prototyped attribute are made to the
    -            original object, not the prototype object. The prototype object is
    -            only used to define to trait type and default value.
    -
    -        """
             super(PrototypedFrom, self).__init__(
                 prototype,
                 prefix=prefix,
    @@ -1600,15 +1320,11 @@ 

    Source code for traits.trait_types

             )
     
     
    -# -------------------------------------------------------------------------------
    -#  'Expression' class:
    -# -------------------------------------------------------------------------------
    -
    -
     class Expression(TraitType):
    -    """ Defines a trait whose value must be a valid Python expression. The
    -        compiled form of a valid expression is stored as the mapped value of
    -        the trait.
    +    """ A trait type whose value must be a valid Python expression.
    +
    +    The compiled form of a valid expression is stored as the mapped value of
    +    the trait.
         """
     
         #: The default value for the trait:
    @@ -1643,34 +1359,62 @@ 

    Source code for traits.trait_types

             """
             # Tell the C code that 'setattr' should store the original, unadapted
             # value passed to it:
    -        return super(Expression, self).as_ctrait().setattr_original_value(True)
    -
    -
    -# -------------------------------------------------------------------------------
    -#  'PythonValue' trait:
    -# -------------------------------------------------------------------------------
    +        ctrait = super(Expression, self).as_ctrait()
    +        ctrait.setattr_original_value = True
    +        return ctrait
     
     
     class PythonValue(Any):
    -    """ Defines a trait whose value can be of any type, and whose default
    -    editor is a Python shell.
    +    """ A trait type whose value can be of any type.
    +
    +    The default editor is a ShellEditor.
         """
     
         #: The standard metadata for the trait:
         metadata = {"editor": shell_editor}
     
     
    -# -------------------------------------------------------------------------------
    -#  'BaseFile' and 'File' traits:
    -# -------------------------------------------------------------------------------
    -
    -
     class BaseFile(BaseStr):
    -    """ Defines a trait whose value must be the name of a file.
    +    """ A trait type whose value must be a file path string.
    +
    +    For Python 3.6 and later this will accept os.pathlib Path objects,
    +    converting them to the corresponding string value.
    +
    +    Parameters
    +    ----------
    +    value : str
    +        The default value for the trait.
    +    filter : str
    +        A wildcard string to filter filenames in the file dialog box used by
    +        the attribute trait editor.
    +    auto_set : bool
    +        Indicates whether the file editor updates the trait value after
    +        every key stroke.
    +    entries : int
    +        A hint to the TraitsUI editor about how many values to display in
    +        the editor.
    +    exists : bool
    +        Indicates whether the trait value must be an existing file or
    +        not.
    +
    +    Attributes
    +    ----------
    +    filter : str
    +        A wildcard string to filter filenames in the file dialog box used by
    +        the attribute trait editor.
    +    auto_set : bool
    +        Indicates whether the file editor updates the trait value after
    +        every key stroke.
    +    entries : int
    +        A hint to the TraitsUI editor about how many values to display in
    +        the editor.
    +    exists : bool
    +        Indicates whether the trait value must be an existing file or
    +        not.
         """
     
         #: A description of the type of value this trait accepts:
    -    info_text = "a file name"
    +    info_text = "a filename or object implementing the os.PathLike interface"
     
         def __init__(
             self,
    @@ -1681,26 +1425,6 @@ 

    Source code for traits.trait_types

             exists=False,
             **metadata
         ):
    -        """ Creates a File trait.
    -
    -        Parameters
    -        ----------
    -        value : str
    -            The default value for the trait.
    -        filter : str
    -            A wildcard string to filter filenames in the file dialog box used by
    -            the attribute trait editor.
    -        auto_set : bool
    -            Indicates whether the file editor updates the trait value after
    -            every key stroke.
    -        exists : bool
    -            Indicates whether the trait value must be an existing file or
    -            not.
    -
    -        Default Value
    -        -------------
    -        *value* or ''
    -        """
             self.filter = filter
             self.auto_set = auto_set
             self.entries = entries
    @@ -1713,6 +1437,16 @@ 

    Source code for traits.trait_types

     
                 Note: The 'fast validator' version performs this check in C.
             """
    +        if fspath is not None:
    +            # Python 3.5 does not implement __fspath__
    +            try:
    +                # If value is of type os.PathLike, get the path representation
    +                # The path representation could be either a str or bytes type
    +                # If fspath returns bytes, further validation will fail.
    +                value = fspath(value)
    +            except TypeError:
    +                pass
    +
             validated_value = super(BaseFile, self).validate(object, name, value)
             if not self.exists:
                 return validated_value
    @@ -1734,8 +1468,42 @@ 

    Source code for traits.trait_types

     
     
     class File(BaseFile):
    -    """ Defines a trait whose value must be the name of a file using a C-level
    -        fast validator.
    +    """ A fast-validating trait type whose value must be a file path string.
    +
    +    For Python 3.6 and later this will accept os.pathlib Path objects,
    +    converting them to the corresponding string value.
    +
    +    Parameters
    +    ----------
    +    value : str
    +        The default value for the trait.
    +    filter : str
    +        A wildcard string to filter filenames in the file dialog box used by
    +        the attribute trait editor.
    +    auto_set : bool
    +        Indicates whether the file editor updates the trait value after
    +        every key stroke.
    +    entries : int
    +        A hint to the TraitsUI editor about how many values to display in
    +        the editor.
    +    exists : bool
    +        Indicates whether the trait value must be an existing file or
    +        not.
    +
    +    Attributes
    +    ----------
    +    filter : str
    +        A wildcard string to filter filenames in the file dialog box used by
    +        the attribute trait editor.
    +    auto_set : bool
    +        Indicates whether the file editor updates the trait value after
    +        every key stroke.
    +    entries : int
    +        A hint to the TraitsUI editor about how many values to display in
    +        the editor.
    +    exists : bool
    +        Indicates whether the trait value must be an existing file or
    +        not.
         """
     
         def __init__(
    @@ -1747,67 +1515,52 @@ 

    Source code for traits.trait_types

             exists=False,
             **metadata
         ):
    -        """ Creates a File trait.
    -
    -        Parameters
    -        ----------
    -        value : str
    -            The default value for the trait.
    -        filter : str
    -            A wildcard string to filter filenames in the file dialog box used
    -            by the attribute trait editor.
    -        auto_set : bool
    -            Indicates whether the file editor updates the trait value after
    -            every key stroke.
    -        exists : bool
    -            Indicates whether the trait value must be an existing file or
    -            not.
    -
    -        Default Value
    -        -------------
    -        *value* or ''
    -        """
    -        if not exists:
    -            # Define the C-level fast validator to use:
    -            self.fast_validate = (11,) + six.string_types
    -
             super(File, self).__init__(
                 value, filter, auto_set, entries, exists, **metadata
             )
     
     
    -# -------------------------------------------------------------------------------
    -#  'BaseDirectory' and 'Directory' traits:
    -# -------------------------------------------------------------------------------
    -
    -
     class BaseDirectory(BaseStr):
    -    """ Defines a trait whose value must be the name of a directory.
    +    """ A trait type whose value must be a directory path string.
    +
    +    For Python 3.6 and greater, it also accepts objects implementing
    +    the :class:`os.PathLike` interface, converting them to the corresponding
    +    string.
    +
    +    Parameters
    +    ----------
    +    value : str
    +        The default value for the trait.
    +    auto_set : bool
    +        Indicates whether the directory editor updates the trait value
    +        after every key stroke.
    +    entries : int
    +        A hint to the TraitsUI editor about how many values to display in
    +        the editor.
    +    exists : bool
    +        Indicates whether the trait value must be an existing directory or
    +        not.
    +
    +    Attributes
    +    ----------
    +    auto_set : bool
    +        Indicates whether the directory editor updates the trait value
    +        after every key stroke.
    +    entries : int
    +        A hint to the TraitsUI editor about how many values to display in
    +        the editor.
    +    exists : bool
    +        Indicates whether the trait value must be an existing directory or
    +        not.
         """
     
         #: A description of the type of value this trait accepts:
    -    info_text = "a directory name"
    +    info_text = ("a directory name or an object implementing "
    +                 "the os.PathLike interface")
     
         def __init__(
             self, value="", auto_set=False, entries=0, exists=False, **metadata
         ):
    -        """ Creates a BaseDirectory trait.
    -
    -        Parameters
    -        ----------
    -        value : str
    -            The default value for the trait.
    -        auto_set : bool
    -            Indicates whether the directory editor updates the trait value
    -            after every key stroke.
    -        exists : bool
    -            Indicates whether the trait value must be an existing directory or
    -            not.
    -
    -        Default Value
    -        -------------
    -        *value* or ''
    -        """
             self.entries = entries
             self.auto_set = auto_set
             self.exists = exists
    @@ -1817,8 +1570,15 @@ 

    Source code for traits.trait_types

         def validate(self, object, name, value):
             """ Validates that a specified value is valid for this trait.
     
    -            Note: The 'fast validator' version performs this check in C.
    +        Note: The 'fast validator' version performs this check in C.
             """
    +        if fspath is not None:
    +            # Python 3.5 does not implement __fspath__
    +            try:
    +                value = fspath(value)
    +            except TypeError:
    +                pass
    +
             validated_value = super(BaseDirectory, self).validate(
                 object, name, value
             )
    @@ -1837,46 +1597,74 @@ 

    Source code for traits.trait_types

     
     
     class Directory(BaseDirectory):
    -    """ Defines a trait whose value must be the name of a directory using a
    -        C-level fast validator.
    +    """ A fast-validating trait type whose value is a directory path string.
    +
    +    For Python 3.6 and greater, it also accepts objects implementing
    +    the :class:`os.PathLike` interface, converting them to the corresponding
    +    string.
    +
    +    Parameters
    +    ----------
    +    value : str
    +        The default value for the trait.
    +    auto_set : bool
    +        Indicates whether the directory editor updates the trait value
    +        after every key stroke.
    +    entries : int
    +        A hint to the TraitsUI editor about how many values to display in
    +        the editor.
    +    exists : bool
    +        Indicates whether the trait value must be an existing directory or
    +        not.
    +
    +    Attributes
    +    ----------
    +    auto_set : bool
    +        Indicates whether the directory editor updates the trait value
    +        after every key stroke.
    +    entries : int
    +        A hint to the TraitsUI editor about how many values to display in
    +        the editor.
    +    exists : bool
    +        Indicates whether the trait value must be an existing directory or
    +        not.
         """
     
         def __init__(
             self, value="", auto_set=False, entries=0, exists=False, **metadata
         ):
    -        """ Creates a Directory trait.
    -
    -        Parameters
    -        ----------
    -        value : str
    -            The default value for the trait.
    -        auto_set : bool
    -            Indicates whether the directory editor updates the trait value
    -            after every key stroke.
    -        exists : bool
    -            Indicates whether the trait value must be an existing directory or
    -            not.
    -
    -        Default Value
    -        -------------
    -        *value* or ''
    -        """
    -        # Define the C-level fast validator to use if the directory existence
    -        #: test is not required:
    -        if not exists:
    -            self.fast_validate = (11,) + six.string_types
    +        # Fast validation is disabled (Github issue #877).
             super(Directory, self).__init__(
                 value, auto_set, entries, exists, **metadata
             )
     
     
    -# -------------------------------------------------------------------------------
    -#  'BaseRange' and 'Range' traits:
    -# -------------------------------------------------------------------------------
    -
    -
     class BaseRange(TraitType):
    -    """ Defines a trait whose numeric value must be in a specified range.
    +    """ A trait type whose numeric value lies inside a range.
    +
    +    The value held will be either an integer or a float, which type is
    +    determined by whether the *low*, *high* and *value* arguments are
    +    integers or floats.
    +
    +    The *low*, *high*, and *value* arguments must be of the same type
    +    (integer or float), except in the case where either *low* or *high* is
    +    a string (i.e. extended trait name).
    +
    +    If *value* is None or omitted, the default value is *low*, unless *low*
    +    is None or omitted, in which case the default value is *high*.
    +
    +    Parameters
    +    ----------
    +    low : integer, float or string (i.e. extended trait name)
    +        The low end of the range.
    +    high : integer, float or string (i.e. extended trait name)
    +        The high end of the range.
    +    value : integer, float or string (i.e. extended trait name)
    +        The default value of the trait.
    +    exclude_low : bool
    +        Indicates whether the low end of the range is exclusive.
    +    exclude_high : bool
    +        Indicates whether the high end of the range is exclusive.
         """
     
         def __init__(
    @@ -1888,31 +1676,6 @@ 

    Source code for traits.trait_types

             exclude_high=False,
             **metadata
         ):
    -        """ Creates a Range trait.
    -
    -        Parameters
    -        ----------
    -        low : integer, float or string (i.e. extended trait name)
    -            The low end of the range.
    -        high : integer, float or string (i.e. extended trait name)
    -            The high end of the range.
    -        value : integer, float or string (i.e. extended trait name)
    -            The default value of the trait.
    -        exclude_low : bool
    -            Indicates whether the low end of the range is exclusive.
    -        exclude_high : bool
    -            Indicates whether the high end of the range is exclusive.
    -
    -        The *low*, *high*, and *value* arguments must be of the same type
    -        (integer or float), except in the case where either *low* or *high* is
    -        a string (i.e. extended trait name).
    -
    -        Default Value
    -        -------------
    -        *value*; if *value* is None or omitted, the default value is *low*,
    -        unless *low* is None or omitted, in which case the default value is
    -        *high*.
    -        """
             if value is None:
                 if low is not None:
                     value = low
    @@ -1923,23 +1686,25 @@ 

    Source code for traits.trait_types

     
             vtype = type(high)
             if (low is not None) and (
    -            not issubclass(vtype, (float,) + six.string_types)
    +            not issubclass(vtype, (float, str))
             ):
                 vtype = type(low)
     
    -        is_static = not issubclass(vtype, six.string_types)
    +        is_static = not issubclass(vtype, str)
             if is_static and (vtype not in RangeTypes):
                 raise TraitError(
    -                "Range can only be use for int, long or float "
    +                "Range can only be use for int or float "
                     "values, but a value of type %s was specified." % vtype
                 )
     
             self._low_name = self._high_name = ""
             self._vtype = Undefined
     
    +        kind = None
    +
             if vtype is float:
                 self._validate = "float_validate"
    -            kind = 4
    +            kind = ValidateTrait.float_range
                 self._type_desc = "a floating point number"
                 if low is not None:
                     low = float(low)
    @@ -1947,18 +1712,8 @@ 

    Source code for traits.trait_types

                 if high is not None:
                     high = float(high)
     
    -        elif vtype is LONG_TYPE:
    -            self._validate = "long_validate"
    -            self._type_desc = "a long integer"
    -            if low is not None:
    -                low = LONG_TYPE(low)
    -
    -            if high is not None:
    -                high = LONG_TYPE(high)
    -
             elif vtype is int:
                 self._validate = "int_validate"
    -            kind = 3
                 self._type_desc = "an integer"
                 if low is not None:
                     low = int(low)
    @@ -1970,23 +1725,23 @@ 

    Source code for traits.trait_types

                 self._vtype = None
                 self._type_desc = "a number"
     
    -            if isinstance(high, six.string_types):
    +            if isinstance(high, str):
                     self._high_name = high = "object." + high
                 else:
                     self._vtype = type(high)
                 high = compile(str(high), "<string>", "eval")
     
    -            if isinstance(low, six.string_types):
    +            if isinstance(low, str):
                     self._low_name = low = "object." + low
                 else:
                     self._vtype = type(low)
                 low = compile(str(low), "<string>", "eval")
     
    -            if isinstance(value, six.string_types):
    +            if isinstance(value, str):
                     value = "object." + value
                 self._value = compile(str(value), "<string>", "eval")
     
    -            self.default_value_type = CALLABLE_DEFAULT_VALUE
    +            self.default_value_type = DefaultValue.callable
                 self.default_value = self._get_default_value
     
             exclude_mask = 0
    @@ -1996,8 +1751,8 @@ 

    Source code for traits.trait_types

             if exclude_high:
                 exclude_mask |= 2
     
    -        if is_static and (vtype is not LONG_TYPE):
    -            self.init_fast_validator(kind, low, high, exclude_mask)
    +        if is_static and kind is not None:
    +            self.init_fast_validate(kind, low, high, exclude_mask)
     
             #: Assign type-corrected arguments to handler attributes:
             self._low = low
    @@ -2005,9 +1760,9 @@ 

    Source code for traits.trait_types

             self._exclude_low = exclude_low
             self._exclude_high = exclude_high
     
    -    def init_fast_validator(self, *args):
    +    def init_fast_validate(self, *args):
             """ Does nothing for the BaseRange class. Used in the Range class to
    -            set up the fast validator.
    +        set up the fast validator.
             """
             pass
     
    @@ -2019,73 +1774,58 @@ 

    Source code for traits.trait_types

         def float_validate(self, object, name, value):
             """ Validate that the value is a float value in the specified range.
             """
    +        # Convert to exact type float, re-raising a TypeError as a TraitError
    +        # and letting other errors propagate. Keep original value for
    +        # error-reporting purposes.
    +        original_value = value
             try:
    -            if (
    -                isinstance(value, RangeTypes)
    -                and (
    -                    (self._low is None)
    -                    or (self._exclude_low and (self._low < value))
    -                    or ((not self._exclude_low) and (self._low <= value))
    -                )
    -                and (
    -                    (self._high is None)
    -                    or (self._exclude_high and (self._high > value))
    -                    or ((not self._exclude_high) and (self._high >= value))
    -                )
    -            ):
    -                return float(value)
    -        except:
    -            pass
    +            value = _validate_float(value)
    +        except TypeError:
    +            self.error(object, name, original_value)
     
    -        self.error(object, name, value)
    +        if (
    +            (
    +                (self._low is None)
    +                or (self._exclude_low and (self._low < value))
    +                or ((not self._exclude_low) and (self._low <= value))
    +            )
    +            and (
    +                (self._high is None)
    +                or (self._exclude_high and (self._high > value))
    +                or ((not self._exclude_high) and (self._high >= value))
    +            )
    +        ):
    +            return value
    +
    +        self.error(object, name, original_value)
     
         def int_validate(self, object, name, value):
             """ Validate that the value is an int value in the specified range.
             """
    +        # Convert to exact type float, re-raising a TypeError as a TraitError
    +        # and letting other errors propagate. Keep original value for
    +        # error-reporting purposes.
    +        original_value = value
             try:
    -            if (
    -                isinstance(value, int_fast_validate[1:])
    -                and (
    -                    (self._low is None)
    -                    or (self._exclude_low and (self._low < value))
    -                    or ((not self._exclude_low) and (self._low <= value))
    -                )
    -                and (
    -                    (self._high is None)
    -                    or (self._exclude_high and (self._high > value))
    -                    or ((not self._exclude_high) and (self._high >= value))
    -                )
    -            ):
    -                return value
    -        except:
    -            pass
    -
    -        self.error(object, name, value)
    +            value = _validate_int(value)
    +        except TypeError:
    +            self.error(object, name, original_value)
     
    -    def long_validate(self, object, name, value):
    -        """ Validate that the value is a long value in the specified range.
    -        """
    -        try:
    -            valid_types = list(long_fast_validate[1:])
    -            valid_types.remove(None)
    -            if (
    -                isinstance(value, tuple(valid_types))
    -                and (
    -                    (self._low is None)
    -                    or (self._exclude_low and (self._low < value))
    -                    or ((not self._exclude_low) and (self._low <= value))
    -                )
    -                and (
    -                    (self._high is None)
    -                    or (self._exclude_high and (self._high > value))
    -                    or ((not self._exclude_high) and (self._high >= value))
    -                )
    -            ):
    -                return value
    -        except:
    -            pass
    +        if (
    +            (
    +                (self._low is None)
    +                or (self._exclude_low and (self._low < value))
    +                or ((not self._exclude_low) and (self._low <= value))
    +            )
    +            and (
    +                (self._high is None)
    +                or (self._exclude_high and (self._high > value))
    +                or ((not self._exclude_high) and (self._high >= value))
    +            )
    +        ):
    +            return value
     
    -        self.error(object, name, value)
    +        self.error(object, name, original_value)
     
         def _get_default_value(self, object):
             """ Returns the default value of the range.
    @@ -2112,7 +1852,7 @@ 

    Source code for traits.trait_types

         def _set(self, object, name, value):
             """ Sets the current value of a dynamic range trait.
             """
    -        if not isinstance(value, six.string_types):
    +        if not isinstance(value, str):
                 try:
                     low = eval(self._low)
                     high = eval(self._high)
    @@ -2184,22 +1924,22 @@ 

    Source code for traits.trait_types

     
                 return "%s <%s %s" % (
                     self._type_desc,
    -                "="[self._exclude_high :],
    +                "="[self._exclude_high:],
                     high,
                 )
     
             elif high is None:
                 return "%s >%s %s" % (
                     self._type_desc,
    -                "="[self._exclude_low :],
    +                "="[self._exclude_low:],
                     low,
                 )
     
             return "%s <%s %s <%s %s" % (
                 low,
    -            "="[self._exclude_low :],
    +            "="[self._exclude_low:],
                 self._type_desc,
    -            "="[self._exclude_high :],
    +            "="[self._exclude_high:],
                 high,
             )
     
    @@ -2228,67 +1968,142 @@ 

    Source code for traits.trait_types

     
     
     class Range(BaseRange):
    -    """ Defines a trait whose numeric value must be in a specified range using
    -        a C-level fast validator.
    +    """ A fast-validating trait type whose numeric value lies inside a range.
         """
     
    -    def init_fast_validator(self, *args):
    +    def init_fast_validate(self, *args):
             """ Set up the C-level fast validator.
             """
             self.fast_validate = args
     
     
    -# -------------------------------------------------------------------------------
    -#  'BaseEnum' and 'Enum' traits:
    -# -------------------------------------------------------------------------------
    -
    -
     class BaseEnum(TraitType):
    -    """ Defines a trait whose value must be one of a specified set of values.
    +    """ A trait type whose value is an element of a finite collection.
    +
    +    This trait type can be either *static*, with the collection of valid values
    +    specified directly in the constructor, or *dynamic*, with the collection
    +    provided by the value of another trait attribute.
    +
    +    For both static and dynamic enumerations, a default value can be provided
    +    as a positional argument. If no default is provided, the default is the
    +    first item (in iteration order) of the underlying collection.
    +
    +    Notes
    +    -----
    +
    +    1. If the enumeration is based on an unordered collection like a
    +       ``set``, and no explicit default is given, the default used will
    +       effectively be arbitrary (the first element of the set in iteration
    +       order). It's recommended that a default be given explicitly in this
    +       case.
    +
    +    2. Instances of ``str``, ``bytes`` and ``bytearray`` are not treated
    +       as collections for the purposes of this trait type, both for pragmatic
    +       reasons (it's more likely that a user wants to use a string as an
    +       element in a collection than as a collection in its own right), and
    +       because the behavior of the ``in`` operator for those types does not
    +       express the usual membership semantics (for example, ``"bc" in "abc"``
    +       is ``True``).
    +
    +    Parameters
    +    ----------
    +    *args
    +        The enumeration of all valid values for the trait. For a static
    +        enumeration trait (where the *values* keyword argument is not given)
    +        the supported signatures for ``args`` are as follows:
    +
    +        (collection,)
    +            A nonempty collection of valid values. The default is the first
    +            element of the collection, in iteration order.
    +        (default, collection)
    +            The default value, followed by a nonempty collection of valid
    +            values. The default should be an element of the collection, but
    +            this is not checked.
    +        (item1, item2, ..., itemn)
    +            One or more items giving the valid values for the collection.
    +            The default is *item1*.
    +
    +        For a dynamic enumeration trait, where the *values* keyword argument
    +        is given, the supported signatures for ``args`` are:
    +
    +        ()
    +            No arguments given. In this case the default is the first item
    +            of the collection, in iteration order.
    +        (default,)
    +            The default value for the collection.
    +
    +        For the static case, the ambiguity in the signatures is resolved
    +        as follows: if ``args`` has length ``1`` or ``2``, ``args[-1]`` can be
    +        iterated over, and ``args[-1]`` is not an instance of ``str``,
    +        ``bytes`` or ``bytearray``, then ``args[-1]`` is assumed to give the
    +        collection of values. Otherwise, all elements of ``args`` are assumed
    +        to be items in the collection. Thus the first two signatures are safe
    +        from ambiguity, and it's recommended to use one of these two signatures
    +        in preference to the third form.
    +    values : str, optional
    +        The name of a trait holding the valid values. If given, this is
    +        a dynamic enumeration, otherwise it's a static numeration.
    +    **metadata
    +        Metadata for the trait.
    +
    +    Attributes
    +    ----------
    +    values : tuple or None
    +        For a static enumeration, this is a tuple holding the valid values.
    +        For a dynamic enumeration, this is None.
    +    name : str or None
    +        For a dynamic enumeration, this is the name of a trait holding
    +        the collection of valid values. For a static enumeration, this is
    +        None.
         """
     
    -    def __init__(self, *args, **metadata):
    -        """ Returns an Enum trait.
    +    def __init__(self, *args, values=None, **metadata):
    +        self.name = values
     
    -        Parameters
    -        ----------
    -        values : list or tuple
    -            The enumeration of all legal values for the trait
    -
    -        Default Value
    -        -------------
    -        values[0]
    -        """
    -        values = metadata.pop("values", None)
    -        if isinstance(values, six.string_types):
    -            n = len(args)
    -            if n == 0:
    -                default_value = None
    -            elif n == 1:
    +        nargs = len(args)
    +        if self.name is not None:
    +            # Dynamic enumeration
    +            self.values = None
    +            self.get, self.set, self.validate = self._get, self._set, None
    +            if nargs == 0:
    +                super(BaseEnum, self).__init__(**metadata)
    +            elif nargs == 1:
                     default_value = args[0]
    +                super(BaseEnum, self).__init__(default_value, **metadata)
                 else:
                     raise TraitError(
                         "Incorrect number of arguments specified "
                         "when using the 'values' keyword"
                     )
    -            self.name = values
    -            self.values = compile("object." + values, "<string>", "eval")
    -            self.get, self.set, self.validate = self._get, self._set, None
             else:
    -            default_value = args[0]
    -            if (len(args) == 1) and isinstance(default_value, SequenceTypes):
    -                args = default_value
    +            # Static enumeration
    +            if nargs == 0:
    +                raise TraitError("Enum trait requires at least 1 argument")
    +
    +            # If we have either 1 or 2 arguments and the last argument is a
    +            # collection, then that collection provides the values of the
    +            # enumeration. Otherwise, args itself is the collection.
    +            have_collection_arg = (
    +                nargs <= 2
    +                and not isinstance(args[-1], (str, bytes, bytearray))
    +                and isinstance(args[-1], collections.abc.Iterable)
    +            )
    +            self.values = tuple(args[-1]) if have_collection_arg else args
    +            if not self.values:
    +                raise TraitError("Enum collection should be nonempty")
    +
    +            # In the two-argument collection case, the first argument is
    +            # the default. Otherwise, we take the first element of self.values.
    +            if have_collection_arg and nargs == 2:
                     default_value = args[0]
    -            elif (len(args) == 2) and isinstance(args[1], SequenceTypes):
    -                args = args[1]
    +            else:
    +                default_value = self.values[0]
     
    -            self.name = ""
    -            self.values = tuple(args)
    -            self.init_fast_validator(5, self.values)
    +            self.init_fast_validate(ValidateTrait.enum, self.values)
     
    -        super(BaseEnum, self).__init__(default_value, **metadata)
    +            super(BaseEnum, self).__init__(default_value, **metadata)
     
    -    def init_fast_validator(self, *args):
    +    def init_fast_validate(self, *args):
             """ Does nothing for the BaseEnum class. Used in the Enum class to set
                 up the fast validator.
             """
    @@ -2296,7 +2111,7 @@ 

    Source code for traits.trait_types

     
         def validate(self, object, name, value):
             """ Validates that the value is one of the enumerated set of valid
    -            values.
    +        values.
             """
             if value in self.values:
                 return value
    @@ -2306,10 +2121,10 @@ 

    Source code for traits.trait_types

         def full_info(self, object, name, value):
             """ Returns a description of the trait.
             """
    -        if self.name == "":
    +        if self.name is None:
                 values = self.values
             else:
    -            values = eval(self.values)
    +            values = xgetattr(object, self.name)
     
             return " or ".join([repr(x) for x in values])
     
    @@ -2318,101 +2133,183 @@ 

    Source code for traits.trait_types

             """
             from traitsui.api import EnumEditor
     
    -        values = self
    -        if self.name != "":
    +        if self.name is None:
    +            values = self.values
    +            name = ""
    +        else:
                 values = None
    +            name = self.name
     
    -        return EnumEditor(
    -            values=values,
    -            name=self.name,
    +        editor = EnumEditor(
    +            name=name,
                 cols=self.cols or 3,
                 evaluate=self.evaluate,
    -            mode=self.mode or "radio",
    +            format_func=self.format_func,
    +            mode=self.mode if self.mode else "radio",
             )
    +        # Workaround enthought/traitsui#782
    +        if values is not None:
    +            editor.values = values
    +        return editor
     
         def _get(self, object, name, trait):
             """ Returns the current value of a dynamic enum trait.
             """
             value = self.get_value(object, name, trait)
    -        values = eval(self.values)
    -        if value not in values:
    -            value = None
    -            if len(values) > 0:
    -                value = values[0]
    -
    +        values = xgetattr(object, self.name)
    +        if not safe_contains(value, values):
    +            value = next(iter(values), None)
             return value
     
         def _set(self, object, name, value):
             """ Sets the current value of a dynamic range trait.
             """
    -        if value in eval(self.values):
    +        if safe_contains(value, xgetattr(object, self.name)):
                 self.set_value(object, name, value)
             else:
                 self.error(object, name, value)
     
     
     class Enum(BaseEnum):
    -    """ Defines a trait whose value must be one of a specified set of values
    -        using a C-level fast validator.
    +    """ A fast-validating trait type whose value is an element of a finite
    +    collection.
    +
    +    This trait type can be either *static*, with the collection of valid values
    +    specified directly in the constructor, or *dynamic*, with the collection
    +    provided by the value of another trait attribute.
    +
    +    For both static and dynamic enumerations, a default value can be provided
    +    as a positional argument. If no default is provided, the default is the
    +    first item (in iteration order) of the underlying collection.
    +
    +    Notes
    +    -----
    +
    +    1. If the enumeration is based on an unordered collection like a
    +       ``set``, and no explicit default is given, the default used will
    +       effectively be arbitrary (the first element of the set in iteration
    +       order). It's recommended that a default be given explicitly in this
    +       case.
    +
    +    2. Instances of ``str``, ``bytes`` and ``bytearray`` are not treated
    +       as collections for the purposes of this trait type, both for pragmatic
    +       reasons (it's more likely that a user wants to use a string as an
    +       element in a collection than as a collection in its own right), and
    +       because the behavior of the ``in`` operator for those types does not
    +       express the usual membership semantics (for example, ``"bc" in "abc"``
    +       is ``True``).
    +
    +    Parameters
    +    ----------
    +    *args
    +        The enumeration of all valid values for the trait. For a static
    +        enumeration trait (where the *values* keyword argument is not given)
    +        the supported signatures for ``args`` are as follows:
    +
    +        (collection,)
    +            A nonempty collection of valid values. The default is the first
    +            element of the collection, in iteration order.
    +        (default, collection)
    +            The default value, followed by a nonempty collection of valid
    +            values. The default should be an element of the collection, but
    +            this is not checked.
    +        (item1, item2, ..., itemn)
    +            One or more items giving the valid values for the collection.
    +            The default is *item1*.
    +
    +        For a dynamic enumeration trait, where the *values* keyword argument
    +        is given, the supported signatures for ``args`` are:
    +
    +        ()
    +            No arguments given. In this case the default is the first item
    +            of the collection, in iteration order.
    +        (default,)
    +            The default value for the collection.
    +
    +        For the static case, the ambiguity in the signatures is resolved
    +        as follows: if ``args`` has length ``1`` or ``2``, ``args[-1]`` can be
    +        iterated over, and ``args[-1]`` is not an instance of ``str``,
    +        ``bytes`` or ``bytearray``, then ``args[-1]`` is assumed to give the
    +        collection of values. Otherwise, all elements of ``args`` are assumed
    +        to be items in the collection. Thus the first two signatures are safe
    +        from ambiguity, and it's recommended to use one of these two signatures
    +        in preference to the third form.
    +    values : str, optional
    +        The name of a trait holding the valid values. If given, this is
    +        a dynamic enumeration, otherwise it's a static numeration.
    +    **metadata
    +        Metadata for the trait.
    +
    +    Attributes
    +    ----------
    +    values : tuple or None
    +        For a static enumeration, this is a tuple holding the valid values.
    +        For a dynamic enumeration, this is None.
    +    name : str or None
    +        For a dynamic enumeration, this is the name of a trait holding
    +        the collection of valid values. For a static enumeration, this is
    +        None.
         """
     
    -    def init_fast_validator(self, *args):
    -        """ Set up the C-level fast validator.
    -        """
    +    def init_fast_validate(self, *args):
    +        """ Set up C-level fast validation. """
             self.fast_validate = args
     
     
    -# -------------------------------------------------------------------------------
    -#  'BaseTuple' and 'Tuple' and 'ValidatedTuple' traits:
    -# -------------------------------------------------------------------------------
    -
    -
     class BaseTuple(TraitType):
    -    """ Defines a trait whose value must be a tuple of specified trait types.
    +    """ A trait type holding a tuple with typed elements.
    +
    +    The default value is determined as follows:
    +
    +    1.  If no arguments are specified, the default value is ().
    +    2.  If a tuple is specified as the first argument, it is the default
    +        value.
    +    3.  If a tuple is not specified as the first argument, the default
    +        value is a tuple whose length is the length of the argument list,
    +        and whose values are the default values for the corresponding trait
    +        types.
    +
    +    Example for case #2::
    +
    +        mytuple = Tuple(('Fred', 'Betty', 5))
    +
    +    The trait's value must be a 3-element tuple whose first and second
    +    elements are strings, and whose third element is an integer. The
    +    default value is ``('Fred', 'Betty', 5)``.
    +
    +    Example for case #3::
    +
    +        mytuple = Tuple('Fred', 'Betty', 5)
    +
    +    The trait's value must be a 3-element tuple whose first and second
    +    elements are strings, and whose third element is an integer. The
    +    default value is ``('','',0)``.
    +
    +    Parameters
    +    ----------
    +    *types
    +        Definition of the default and allowed tuples. If the first item of
    +        *types* is a tuple, it is used as the default value.
    +        The remaining argument list is used to form a tuple that constrains
    +        the  values assigned to the returned trait. The trait's value must
    +        be a tuple of the same length as the remaining argument list, whose
    +        elements must match the types specified by the corresponding items
    +        of the remaining argument list.
    +    **metadata
    +        Trait metadata for the trait.
    +
    +    Attributes
    +    ----------
    +    types : tuple
    +        The tuple of traits specifying the type of each element in order.
    +    no_type_check : bool
    +        Flag to indicate whether validation should check the type of each
    +        element.
         """
     
         def __init__(self, *types, **metadata):
    -        """ Returns a Tuple trait.
    -
    -        Parameters
    -        ----------
    -        types : zero or more arguments
    -            Definition of the default and allowed tuples. If the first item of
    -            *types* is a tuple, it is used as the default value.
    -            The remaining argument list is used to form a tuple that constrains
    -            the  values assigned to the returned trait. The trait's value must
    -            be a tuple of the same length as the remaining argument list, whose
    -            elements must match the types specified by the corresponding items
    -            of the remaining argument list.
    -
    -        Default Value
    -        -------------
    -        1. If no arguments are specified, the default value is ().
    -        2. If a tuple is specified as the first argument, it is the default
    -           value.
    -        3. If a tuple is not specified as the first argument, the default
    -           value is a tuple whose length is the length of the argument list,
    -           and whose values are the default values for the corresponding trait
    -           types.
    -
    -        Example for case #2::
    -
    -            mytuple = Tuple(('Fred', 'Betty', 5))
    -
    -        The trait's value must be a 3-element tuple whose first and second
    -        elements are strings, and whose third element is an integer. The
    -        default value is ``('Fred', 'Betty', 5)``.
    -
    -        Example for case #3::
    -
    -            mytuple = Tuple('Fred', 'Betty', 5)
    -
    -        The trait's value must be a 3-element tuple whose first and second
    -        elements are strings, and whose third element is an integer. The
    -        default value is ``('','',0)``.
    -        """
             if len(types) == 0:
    -            self.init_fast_validator(11, tuple, None, list)
    +            self.init_fast_validate(ValidateTrait.coerce, tuple, None, list)
     
                 super(BaseTuple, self).__init__((), **metadata)
     
    @@ -2426,7 +2323,7 @@ 

    Source code for traits.trait_types

                     types = [Trait(element) for element in default_value]
     
             self.types = tuple([trait_from(type) for type in types])
    -        self.init_fast_validator(9, self.types)
    +        self.init_fast_validate(ValidateTrait.tuple, self.types)
     
             if default_value is None:
                 default_value = tuple(
    @@ -2435,10 +2332,10 @@ 

    Source code for traits.trait_types

     
             super(BaseTuple, self).__init__(default_value, **metadata)
     
    -    def init_fast_validator(self, *args):
    +    def init_fast_validate(self, *args):
             """ Saves the validation parameters.
             """
    -        self.no_type_check = args[0] == 11
    +        self.no_type_check = args[0] == ValidateTrait.coerce
     
         def validate(self, object, name, value):
             """ Validates that the value is a valid tuple.
    @@ -2501,45 +2398,47 @@ 

    Source code for traits.trait_types

     
     
     class Tuple(BaseTuple):
    -    """ Defines a trait whose value must be a tuple of specified trait types
    -        using a C-level fast validator.
    +    """ A fast-validating trait type holding a tuple with typed elements.
         """
     
    -    def init_fast_validator(self, *args):
    +    def init_fast_validate(self, *args):
             """ Set up the C-level fast validator.
             """
    -        super(Tuple, self).init_fast_validator(*args)
    +        super(Tuple, self).init_fast_validate(*args)
     
             self.fast_validate = args
     
     
     class ValidatedTuple(BaseTuple):
    -    """ A Tuple trait that supports custom validation.
    +    """ A trait type holding a tuple with customized validation.
    +
    +    Parameters
    +    ----------
    +    *types
    +        Definition of the default and allowed tuples. (see
    +        :class:`~.BaseTuple` for more details)
    +    fvalidate : callable, optional
    +        A callable to provide the additional custom validation for the
    +        tuple. The callable will be passed the tuple value and should
    +        return True or False.
    +    fvalidate_info : string, optional
    +        A string describing the custom validation to use for the error
    +        messages.
    +    **metadata
    +        Trait metadata for the trait.
    +
    +    Example
    +    -------
    +    The definition::
    +
    +        value_range = ValidatedTuple(
    +            Int(0), Int(1), fvalidate=lambda x: x[0] < x[1])
    +
    +    will accept only tuples ``(a, b)`` containing two integers that
    +    satisfy ``a < b``.
         """
     
         def __init__(self, *types, **metadata):
    -        """ Returns a ValidatedTuple trait
    -
    -        Parameters
    -        ----------
    -        types : zero or more arguments
    -            Definition of the default and allowed tuples. (see
    -            :class:`~.BaseTuple` for more details)
    -        fvalidate : callable, optional
    -            A callable to provide the additional custom validation for the
    -            tuple. The callable will be passed the tuple value and should
    -            return True or False.
    -        fvalidate_info : string, optional
    -            A string describing the custom validation to use for the error
    -            messages.
    -
    -        For example::
    -
    -          value_range = ValidatedTuple(Int(0), Int(1), fvalidate=lambda x: x[0] < x[1])
    -
    -        This definition will accept only tuples ``(a, b)`` containing two integers
    -        that satisfy ``a < b``.
    -        """
             metadata.setdefault("fvalidate", None)
             metadata.setdefault("fvalidate_info", "")
             super(ValidatedTuple, self).__init__(*types, **metadata)
    @@ -2569,18 +2468,43 @@ 

    Source code for traits.trait_types

             return message.format(types_info, fvalidate_info)
     
     
    -# -------------------------------------------------------------------------------
    -#  'List' trait:
    -# -------------------------------------------------------------------------------
    -
    -
     class List(TraitType):
    -    """ Defines a trait whose value must be a list whose items are of the
    -        specified trait type.
    +    """ A trait type for a list of values of the specified type.
    +
    +    The length of the list assigned to the trait must be such that::
    +
    +        minlen <= len(list) <= maxlen
    +
    +    Parameters
    +    ----------
    +    trait : a trait or value that can be converted using trait_from()
    +        The type of item that the list contains. If not specified, the list
    +        can contain items of any type.
    +    value : list
    +        Default value for the list.
    +    minlen : integer
    +        The minimum length of a list that can be assigned to the trait.
    +    maxlen : integer
    +        The maximum length of a list that can be assigned to the trait.
    +    items : bool
    +        Whether there is a corresponding `<name>_items` trait.
    +    **metadata
    +        Trait metadata for the trait.
    +
    +    Attributes
    +    ----------
    +    item_trait : trait
    +        The type of item that the list contains.
    +    minlen : integer
    +        The minimum length of a list that can be assigned to the trait.
    +    maxlen : integer
    +        The maximum length of a list that can be assigned to the trait.
    +    has_items : bool
    +        Whether there is a corresponding `<name>_items` trait.
         """
     
         info_trait = None
    -    default_value_type = TRAIT_LIST_OBJECT_DEFAULT_VALUE
    +    default_value_type = DefaultValue.trait_list_object
         _items_event = None
     
         def __init__(
    @@ -2588,32 +2512,10 @@ 

    Source code for traits.trait_types

             trait=None,
             value=None,
             minlen=0,
    -        maxlen=six.MAXSIZE,
    +        maxlen=sys.maxsize,
             items=True,
             **metadata
    -    ):
    -        """ Returns a List trait.
    -
    -        Parameters
    -        ----------
    -        trait : a trait or value that can be converted to a trait using Trait()
    -            The type of item that the list contains. If not specified, the list
    -            can contain items of any type.
    -        value : list
    -            Default value for the list.
    -        minlen : integer
    -            The minimum length of a list that can be assigned to the trait.
    -        maxlen : integer
    -            The maximum length of a list that can be assigned to the trait.
    -
    -        The length of the list assigned to the trait must be such that::
    -
    -            minlen <= len(list) <= maxlen
    -
    -        Default Value
    -        -------------
    -        *value* or None
    -        """
    +    ):
             metadata.setdefault("copy", "deep")
     
             if isinstance(trait, SequenceTypes):
    @@ -2655,12 +2557,12 @@ 

    Source code for traits.trait_types

             """ Returns a description of the trait.
             """
             if self.minlen == 0:
    -            if self.maxlen == six.MAXSIZE:
    +            if self.maxlen == sys.maxsize:
                     size = "items"
                 else:
                     size = "at most %d items" % self.maxlen
             else:
    -            if self.maxlen == six.MAXSIZE:
    +            if self.maxlen == sys.maxsize:
                     size = "at least %d items" % self.minlen
                 else:
                     size = "from %s to %s items" % (self.minlen, self.maxlen)
    @@ -2680,21 +2582,20 @@ 

    Source code for traits.trait_types

             """
             return (self.item_trait,)
     
    -    # -- Private Methods --------------------------------------------------------
    +    # -- Private Methods ------------------------------------------------------
     
         def items_event(self):
    -        return items_event()
    -
    +        cls = self.__class__
    +        if cls._items_event is None:
    +            cls._items_event = Event(
    +                TraitListEvent, is_base=False
    +            ).as_ctrait()
     
    -# -------------------------------------------------------------------------------
    -#  'CList' trait:
    -# -------------------------------------------------------------------------------
    +        return cls._items_event
     
     
     class CList(List):
    -    """ Defines a trait whose values must be a list whose items are of the
    -        specified trait type or which can be coerced to a list whose values are
    -        of the specified trait type.
    +    """ A coercing trait type for a list of values of the specified type.
         """
     
         def validate(self, object, name, value):
    @@ -2719,35 +2620,133 @@ 

    Source code for traits.trait_types

             )
     
     
    -# -------------------------------------------------------------------------------
    -#  'Set' trait:
    -# -------------------------------------------------------------------------------
    +class PrefixList(TraitType):
    +    r"""Ensures that a value assigned to the attribute is a member of a list of
    +     specified string values, or is a unique prefix of one of those values.
    +
    +    The values that can be assigned to a trait attribute of type PrefixList
    +    type is the set of all strings supplied to the PrefixList constructor,
    +    as well as any unique prefix of those strings. That is, if the set of
    +    strings supplied to the constructor is described by
    +    [*s*\ :sub:`1`\ , *s*\ :sub:`2`\ , ..., *s*\ :sub:`n`\ ], then the
    +    string *v* is a valid value for the trait if *v* == *s*\ :sub:`i[:j]`
    +    for one and only one pair of values (i, j). If *v* is a valid value,
    +    then the actual value assigned to the trait attribute is the
    +    corresponding *s*\ :sub:`i` value that *v* matched.
    +
    +    The legal values can be provided as an iterable of values.
    +
    +    Example
    +    -------
    +    ::
    +        class Person(HasTraits):
    +            married = PrefixList(['yes', 'no'])
    +
    +    The Person class has a **married** trait that accepts any of the
    +    strings 'y', 'ye', 'yes', 'n', or 'no' as valid values. However, the
    +    actual values assigned as the value of the trait attribute are limited
    +    to either 'yes' or 'no'. That is, if the value 'y' is assigned to the
    +    **married** attribute, the actual value assigned will be 'yes'.
    +
    +    Note that the algorithm used by PrefixList in determining whether
    +    a string is a valid value is fairly efficient in terms of both time and
    +    space, and is not based on a brute force set of comparisons.
    +
    +    Parameters
    +    ----------
    +    values
    +        A single iterable of legal string values.
    +
    +    Attributes
    +    ----------
    +    values : tuple of strings
    +        Enumeration of all legal values for a trait.
    +    """
    +
    +    #: The default value for the trait:
    +    default_value = None
    +
    +    #: The default value type to use (i.e. 'constant'):
    +    default_value_type = DefaultValue.constant
    +
    +    def __init__(self, values, **metadata):
    +        if isinstance(values, (str, bytes, bytearray)):
    +            raise TypeError(
    +                "Legal values should be provided via an iterable of strings, "
    +                "got {!r}.".format(values)
    +            )
    +        self.values = list(values)
    +        self.values_ = values_ = {}
    +        for key in values:
    +            values_[key] = key
    +
    +        default = self.default_value
    +        if 'default_value' in metadata:
    +            default = metadata.pop('default_value')
    +            default = self.value_for(default)
    +        elif self.values:
    +            default = self.values[0]
    +
    +        super().__init__(default, **metadata)
    +
    +    def value_for(self, value):
    +        if not isinstance(value, str):
    +            raise TraitError(
    +                "The value of a {} trait must be {}, but a value of {!r} {!r} "
    +                "was specified.".format(
    +                    self.__class__.__name__, self.info(), value, type(value))
    +            )
    +
    +        if value in self.values_:
    +            return self.values_[value]
    +
    +        matches = [key for key in self.values if key.startswith(value)]
    +        if len(matches) == 1:
    +            self.values_[value] = match = matches[0]
    +            return match
    +
    +        raise TraitError(
    +            "The value of a {} trait must be {}, but a value of {!r} {!r} was "
    +            "specified.".format(
    +                self.__class__.__name__, self.info(), value, type(value))
    +        )
    +
    +    def info(self):
    +        return (
    +            " or ".join([repr(x) for x in self.values])
    +            + " (or any unique prefix)"
    +        )
     
     
     class Set(TraitType):
    -    """ Defines a trait whose value must be a set whose items are of the
    -        specified trait type.
    +    """ A trait type for a set of values of the specified type.
    +
    +    Parameters
    +    ----------
    +    trait : a trait or value that can be converted to a trait using Trait()
    +        The type of item that the list contains. If not specified, the list
    +        can contain items of any type.
    +    value : set
    +        Default value for the set.
    +    items : bool
    +        Whether there is a corresponding `<name>_items` trait.
    +    **metadata
    +        Trait metadata for the trait.
    +
    +    Attributes
    +    ----------
    +    item_trait : a trait or value that can be converted to a trait
    +        The type of item that the list contains. If not specified, the list
    +        can contain items of any type.
    +    has_items : bool
    +        Whether there is a corresponding `<name>_items` trait.
         """
     
         info_trait = None
    -    default_value_type = TRAIT_SET_OBJECT_DEFAULT_VALUE
    +    default_value_type = DefaultValue.trait_set_object
         _items_event = None
     
         def __init__(self, trait=None, value=None, items=True, **metadata):
    -        """ Returns a Set trait.
    -
    -        Parameters
    -        ----------
    -        trait : a trait or value that can be converted to a trait using Trait()
    -            The type of item that the list contains. If not specified, the list
    -            can contain items of any type.
    -        value : set
    -            Default value for the set.
    -
    -        Default Value
    -        -------------
    -        *value* or None
    -        """
             metadata.setdefault("copy", "deep")
     
             if isinstance(trait, SetTypes):
    @@ -2795,7 +2794,7 @@ 

    Source code for traits.trait_types

             """
             return (self.item_trait,)
     
    -    # -- Private Methods --------------------------------------------------------
    +    # -- Private Methods ------------------------------------------------------
     
         def items_event(self):
             if self.__class__._items_event is None:
    @@ -2806,15 +2805,8 @@ 

    Source code for traits.trait_types

             return self.__class__._items_event
     
     
    -# -------------------------------------------------------------------------------
    -#  'CSet' trait:
    -# -------------------------------------------------------------------------------
    -
    -
     class CSet(Set):
    -    """ Defines a trait whose values must be a set whose items are of the
    -        specified trait type or which can be coerced to a set whose values are
    -        of the specified trait type.
    +    """ A coercing trait type for a set of values of the specified type.
         """
     
         def validate(self, object, name, value):
    @@ -2839,18 +2831,39 @@ 

    Source code for traits.trait_types

             )
     
     
    -# -------------------------------------------------------------------------------
    -#  'Dict' trait:
    -# -------------------------------------------------------------------------------
    -
    -
     class Dict(TraitType):
    -    """ Defines a trait whose value must be a dictionary, optionally with
    -        specified types for keys and values.
    +    """ A trait type for a dictionary with specified key and value types.
    +
    +
    +    Parameters
    +    ----------
    +    key_trait : a trait or value that can be converted using trait_from()
    +        The trait type for keys in the dictionary; if not specified, any
    +        values can be used as keys.
    +    value_trait : a trait or value that can be converted using trait_from()
    +        The trait type for values in the dictionary; if not specified, any
    +        values can be used as dictionary values.
    +    value : dict
    +        The default value for the returned trait.
    +    items : bool
    +        Indicates whether the value contains items.
    +
    +    Attributes
    +    ----------
    +    key_trait : a trait
    +        The trait type for keys in the dictionary; if not specified, any
    +        values can be used as keys.
    +    value_trait : a trait
    +        The trait type for values in the dictionary; if not specified, any
    +        values can be used as dictionary values.
    +    value_trait_handler : TraitHandler
    +        The TraitHandler for the value_trait.
    +    has_items : bool
    +        Indicates whether the value contains items.
         """
     
         info_trait = None
    -    default_value_type = TRAIT_DICT_OBJECT_DEFAULT_VALUE
    +    default_value_type = DefaultValue.trait_dict_object
         _items_event = None
     
         def __init__(
    @@ -2861,25 +2874,6 @@ 

    Source code for traits.trait_types

             items=True,
             **metadata
         ):
    -        """ Returns a Dict trait.
    -
    -        Parameters
    -        ----------
    -        key_trait : a trait or value that can convert to a trait using Trait()
    -            The trait type for keys in the dictionary; if not specified, any
    -            values can be used as keys.
    -        value_trait : a trait or value that can convert to a trait using Trait()
    -            The trait type for values in the dictionary; if not specified, any
    -            values can be used as dictionary values.
    -        value : dict
    -            The default value for the returned trait.
    -        items : bool
    -            Indicates whether the value contains items.
    -
    -        Default Value
    -        -------------
    -        *value* or {}
    -        """
             if isinstance(key_trait, dict):
                 key_trait, value_trait, value = value_trait, value, key_trait
     
    @@ -2901,11 +2895,10 @@ 

    Source code for traits.trait_types

         def validate(self, object, name, value):
             """ Validates that the value is a valid dictionary.
     
    -        .. note::
    -
    -            `object` can be None when validating a default value (see e.g.
    -            :meth:`~traits.trait_handlers.TraitType.clone`)
    -
    +        Note
    +        ----
    +        `object` can be None when validating a default value (see e.g.
    +        :meth:`~traits.trait_handlers.TraitType.clone`)
             """
             if isinstance(value, dict):
                 if object is None:
    @@ -2937,7 +2930,7 @@ 

    Source code for traits.trait_types

             """
             return (self.key_trait, self.value_trait)
     
    -    # -- Private Methods --------------------------------------------------------
    +    # -- Private Methods ------------------------------------------------------
     
         def items_event(self):
             cls = self.__class__
    @@ -2947,29 +2940,235 @@ 

    Source code for traits.trait_types

             return cls._items_event
     
     
    -# -------------------------------------------------------------------------------
    -#  'BaseInstance' and 'Instance' traits:
    -# -------------------------------------------------------------------------------
    -
    -# Allowed values and mappings for the 'adapt' keyword:
    +#: Allowed values and mappings for the 'adapt' keyword.
    +#:
    +#: - 'no': Adaptation is not allowed.
    +#: - 'yes': Adaptation is allowed. If adaptation fails, an
    +#:   exception should be raised.
    +#: - 'default': Adaptation is allowed. If adaptation fails, the
    +#:   default value for the trait should be used.
     AdaptMap = {"no": 0, "yes": 1, "default": 2}
     
     
    -class BaseClass(TraitType):
    -    """ Base class for types which have an associated class which can be
    -        determined dynamically by specifying a string name for the class (e.g.
    -        'package1.package2.module.class'.
    +class Map(TraitType):
    +    """ Checks that the value assigned to a trait attribute is a key of a
    +        specified dictionary, and also assigns the dictionary value
    +        corresponding to that key to a *shadow* attribute.
    +
    +        A trait attribute of type Map is called a *mapped* trait
    +        attribute. In practice, this means that the resulting object actually
    +        contains two attributes: one whose value is a key of the Map
    +        dictionary, and the other whose value is the corresponding value of the
    +        Map dictionary. The name of the shadow attribute is simply the base
    +        attribute name with an underscore ('_') appended. Mapped trait
    +        attributes can be used to allow a variety of user-friendly input values
    +        to be mapped to a set of internal, program-friendly values.
    +
    +        Example
    +        -------
    +
    +        The following example defines a ``Person`` class::
    +
    +            >>> class Person(HasTraits):
    +            ...     married = Map({'yes': 1, 'no': 0 }, default_value="yes")
    +            ...
    +            >>> bob = Person()
    +            >>> print(bob.married)
    +            yes
    +            >>> print(bob.married_)
    +            1
    +
    +        In this example, the default value of the ``married`` attribute of the
    +        Person class is 'yes'. Because this attribute is defined using
    +        Map, instances of Person have another attribute,
    +        ``married_``, whose default value is 1, the dictionary value
    +        corresponding to the key 'yes'.
    +
    +        Parameters
    +        ----------
    +        map : dict
    +            A dictionary whose keys are valid values for the trait attribute,
    +            and whose corresponding values are the values for the shadow
    +            trait attribute.
    +        default_value : object, optional
    +            The default value for the trait. If given, this should be a key
    +            from the mapping. If not given, the first key from the mapping (in
    +            normal dictionary iteration order) will be used as the default.
    +
    +        Attributes
    +        ----------
    +        map : dict
    +            A dictionary whose keys are valid values for the trait attribute,
    +            and whose corresponding values are the values for the shadow
    +            trait attribute.
    +    """
    +
    +    is_mapped = True
    +
    +    def __init__(self, map, **metadata):
    +
    +        self.map = map
    +        self.fast_validate = (ValidateTrait.map, map)
    +
    +        try:
    +            default_value = metadata.pop("default_value")
    +        except KeyError:
    +            default_value = next(iter(self.map))
     
    -        Any subclass must define instances with 'klass' and 'module' attributes
    -        that contain the string name of the class (or actual class object) and
    -        the module name that contained the original trait definition (used for
    -        resolving local class names (e.g. 'LocalClass')).
    +        super().__init__(default_value, **metadata)
     
    -        This is an abstract class that only provides helper methods used to
    -        resolve the class name into an actual class object.
    +    def validate(self, object, name, value):
    +        try:
    +            if value in self.map:
    +                return value
    +        except TypeError:
    +            pass
    +
    +        self.error(object, name, value)
    +
    +    def mapped_value(self, value):
    +        """ Get the mapped value for a value. """
    +        return self.map[value]
    +
    +    def post_setattr(self, object, name, value):
    +        setattr(object, name + "_", self.mapped_value(value))
    +
    +    def info(self):
    +        keys = sorted(repr(x) for x in self.map.keys())
    +        return " or ".join(keys)
    +
    +    def get_editor(self, trait):
    +        from traitsui.api import EnumEditor
    +
    +        return EnumEditor(values=self, cols=trait.cols or 3)
    +
    +
    +class PrefixMap(TraitType):
    +    """ A cross between the PrefixList and Map classes.
    +
    +    Like Map, PrefixMap is created using a dictionary, but in this
    +    case, the keys of the dictionary must be strings. Like PrefixList,
    +    a string *v* is a valid value for the trait attribute if it is a prefix of
    +    one and only one key *k* in the dictionary. The actual values assigned to
    +    the trait attribute is *k*, and its corresponding mapped attribute is
    +    *map*[*k*].
    +
    +    Example
    +    -------
    +    ::
    +
    +        mapping = {'true': 1, 'yes': 1, 'false': 0, 'no': 0 }
    +        boolean_map = PrefixMap(mapping)
    +
    +    This example defines a Boolean trait that accepts any prefix of 'true',
    +    'yes', 'false', or 'no', and maps them to 1 or 0.
    +
    +    Parameters
    +    ----------
    +    map : dict
    +        A dictionary whose keys are strings that are valid values for the
    +        trait attribute, and whose corresponding values are the values for
    +        the shadow trait attribute.
    +    default_value : object, optional
    +        The default value for the trait. If given, this should be either a key
    +        from the mapping or a unique prefix of a key from the mapping. If not
    +        given, the first key from the mapping (in normal dictionary iteration
    +        order) will be used as the default.
    +
    +    Attributes
    +    ----------
    +    map : dict
    +        A dictionary whose keys are strings that are valid values for the
    +        trait attribute, and whose corresponding values are the values for
    +        the shadow trait attribute.
    +    """
    +    is_mapped = True
    +
    +    def __init__(self, map, **metadata):
    +        self.map = map
    +        self._map = {}
    +        for key in map.keys():
    +            self._map[key] = key
    +
    +        try:
    +            default_value = metadata.pop("default_value")
    +        except KeyError:
    +            default_value = next(iter(self.map))
    +        else:
    +            default_value = self.value_for(default_value)
    +
    +        super().__init__(default_value, **metadata)
    +
    +    def value_for(self, value):
    +        if not isinstance(value, str):
    +            raise TraitError(
    +                "Value must be {}, but a value {!r} was specified.".format(
    +                    self.info(), value)
    +            )
    +
    +        if value in self._map:
    +            return self._map[value]
    +
    +        matches = [key for key in self.map if key.startswith(value)]
    +        if len(matches) == 1:
    +            self._map[value] = match = matches[0]
    +            return match
    +
    +        raise TraitError(
    +            "Value must be {}, but a value {!r} was specified.".format(
    +                self.info(), value)
    +        )
    +
    +    def mapped_value(self, value):
    +        """ Get the mapped value for a value. """
    +        return self.map[value]
    +
    +    def post_setattr(self, object, name, value):
    +        setattr(object, name + "_", self.mapped_value(value))
    +
    +    def info(self):
    +        keys = sorted(repr(x) for x in self.map.keys())
    +        return " or ".join(keys) + " (or any unique prefix)"
    +
    +    def get_editor(self, trait):
    +        from traitsui.api import EnumEditor
    +
    +        return EnumEditor(values=self, cols=trait.cols or 3)
    +
    +
    +class BaseClass(TraitType):
    +    """ A base trait type for trait types which have an associated class.
    +
    +    Traits sometimes need to be able to access classes which have not
    +    yet been defined, or which are from a module that we want to defer
    +    importing from.  To support this, classes can be determined
    +    dynamically by specifying a string name for the class (e.g.
    +    ``'package1.package2.module.class'``).  This base class provides the
    +    machinery for this sort of deferred access to classes.
    +
    +    Any subclass must define instances with 'klass' and 'module' attributes
    +    that contain the string name of the class (or actual class object) and
    +    the module name that contained the original trait definition (used for
    +    resolving local class names (e.g. 'LocalClass')).
    +
    +    This is an abstract class that only provides helper methods used to
    +    resolve the class name into an actual class object.
    +
    +    Attributes
    +    ----------
    +    klass : type or str
    +        The class object or a string that refers to it.
    +    module : str
    +        The name of the module that contains the class.
         """
     
         def resolve_class(self, object, name, value):
    +        """ Resolve the class object as part of validation.
    +
    +        This is called when the ``klass`` attribute is a string and sets the
    +        ``klass`` attribute to the actual klass object as a side-effect.  If
    +        the class cannot be resolved, it will call validate_failed().
    +        """
             klass = self.validate_class(self.find_class(self.klass))
             if klass is None:
                 self.validate_failed(object, name, value)
    @@ -2977,56 +3176,94 @@ 

    Source code for traits.trait_types

             self.klass = klass
     
         def validate_class(self, klass):
    +        """ Validate a class object. """
             return klass
     
         def find_class(self, klass):
    +        """ Given a string describing a class, get the class object.
    +        """
             module = self.module
             col = klass.rfind(".")
             if col >= 0:
                 module = klass[:col]
    -            klass = klass[col + 1 :]
    +            klass = klass[col + 1:]
     
             theClass = getattr(sys.modules.get(module), klass, None)
             if (theClass is None) and (col >= 0):
                 try:
    -                mod = __import__(module)
    -                for component in module.split(".")[1:]:
    -                    mod = getattr(mod, component)
    -
    +                mod = import_module(module)
                     theClass = getattr(mod, klass, None)
    -            except:
    +            except Exception:
                     pass
     
             return theClass
     
         def validate_failed(self, object, name, value):
    -
    +        """ Raise a TraitError if the class could not be resolved. """
             self.error(object, name, value)
     
     
    -def validate_implements(value, klass, unused=None):
    -    """ Checks to see if a specified value implements the instance class
    -        interface (if it is an interface).
    -    """
    -
    -    from .has_traits import isinterface
    -    from .interface_checker import check_implements
    -
    -    return isinterface(klass) and check_implements(value.__class__, klass)
    -
    -
    -#: Tell the C-base code about the 'validate_implements' function (used by the
    -#: 'fast_validate' code for Instance types):
    -from . import ctraits
    -
    -ctraits._validate_implements(validate_implements)
    -
    -
     class BaseInstance(BaseClass):
    -    """ Defines a trait whose value must be an instance of a specified class,
    -        or one of its subclasses.
    +    """ A trait type whose value is an instance of a class or its subclasses.
    +
    +    The default value is **None** if *klass* is an instance or if it is a
    +    class and *args* and *kw* are not specified. Otherwise, the default value
    +    is the instance obtained by calling ``klass(*args, **kw)``. Note that the
    +    constructor call is performed each time a default value is assigned, so
    +    each default value assigned is a unique instance.
    +
    +    Parameters
    +    ----------
    +    klass : class, str or instance
    +        The object that forms the basis for the trait; if it is an
    +        instance, then trait values must be instances of the same class or
    +        a subclass. This object is not the default value, even if it is an
    +        instance.  If the provided value is a string, it is expected to be
    +        a reference to a class that will be resolved at run-time.
    +    factory : callable
    +        A callable, typically a class, that when called with *args* and
    +        *kw*, returns the default value for the trait. If not specified,
    +        or *None*, *klass* is used as the factory.
    +    args : tuple
    +        Positional arguments for generating the default value.
    +    kw : dictionary
    +        Keyword arguments for generating the default value.
    +    allow_none : bool
    +        Indicates whether None is allowed as a value.
    +    adapt : str
    +        A string specifying how adaptation should be applied. The possible
    +        values are:
    +
    +        - 'no': Adaptation is not allowed.
    +        - 'yes': Adaptation is allowed. If adaptation fails, an
    +          exception should be raised.
    +        - 'default': Adaptation is allowed. If adaptation fails, the
    +          default value for the trait should be used.
    +
    +    Attributes
    +    ----------
    +    factory : callable
    +        A callable, typically a class, that when called with *args* and
    +        *kw*, returns the default value for the trait. If not specified,
    +        or *None*, *klass* is used as the factory.
    +    args : tuple
    +        Positional arguments for generating the default value.
    +    kw : dictionary
    +        Keyword arguments for generating the default value.
    +    allow_none : bool
    +        Indicates whether None is allowed as a value.
    +    adapt : str
    +        A string specifying how adaptation should be applied. The possible
    +        values are:
    +
    +        - 'no': Adaptation is not allowed.
    +        - 'yes': Adaptation is allowed. If adaptation fails, an
    +          exception should be raised.
    +        - 'default': Adaptation is allowed. If adaptation fails, the
    +          default value for the trait should be used.
         """
     
    +    #: Default adaptation behavior.
         adapt_default = "no"
     
         def __init__(
    @@ -3040,43 +3277,6 @@ 

    Source code for traits.trait_types

             module=None,
             **metadata
         ):
    -        """ Returns an Instance trait.
    -
    -        Parameters
    -        ----------
    -        klass : class or instance
    -            The object that forms the basis for the trait; if it is an
    -            instance, then trait values must be instances of the same class or
    -            a subclass. This object is not the default value, even if it is an
    -            instance.
    -        factory : callable
    -            A callable, typically a class, that when called with *args* and
    -            *kw*, returns the default value for the trait. If not specified,
    -            or *None*, *klass* is used as the factory.
    -        args : tuple
    -            Positional arguments for generating the default value.
    -        kw : dictionary
    -            Keyword arguments for generating the default value.
    -        allow_none : bool
    -            Indicates whether None is allowed as a value.
    -        adapt : str
    -            A string specifying how adaptation should be applied. The possible
    -            values are:
    -
    -                - 'no': Adaptation is not allowed.
    -                - 'yes': Adaptation is allowed. If adaptation fails, an
    -                    exception should be raised.
    -                - 'default': Adaptation is allowed. If adaptation fails, the
    -                    default value for the trait should be used.
    -
    -        Default Value
    -        -------------
    -        **None** if *klass* is an instance or if it is a class and *args* and
    -        *kw* are not specified. Otherwise, the default value is the instance
    -        obtained by calling ``klass(*args, **kw)``. Note that the constructor
    -        call is performed each time a default value is assigned, so each
    -        default value assigned is a unique instance.
    -        """
             if klass is None:
                 raise TraitError(
                     "A %s trait must have a class specified."
    @@ -3106,10 +3306,10 @@ 

    Source code for traits.trait_types

             self.adapt = AdaptMap[adapt]
             self.module = module or get_module_name()
     
    -        if isinstance(klass, six.string_types):
    +        if isinstance(klass, str):
                 self.klass = klass
             else:
    -            if not isinstance(klass, ClassTypes):
    +            if not isinstance(klass, type):
                     klass = klass.__class__
     
                 self.klass = klass
    @@ -3130,7 +3330,7 @@ 

    Source code for traits.trait_types

                     raise TraitError("The 'kw' argument must be a dictionary.")
     
                 if (not callable(factory)) and (
    -                not isinstance(factory, six.string_types)
    +                not isinstance(factory, str)
                 ):
                     if (len(args) > 0) or (len(kw) > 0):
                         raise TraitError("'factory' must be callable")
    @@ -3152,43 +3352,41 @@ 

    Source code for traits.trait_types

     
                 self.validate_failed(object, name, value)
     
    -        if isinstance(self.klass, six.string_types):
    +        if isinstance(self.klass, str):
                 self.resolve_class(object, name, value)
     
    +        # Adaptation mode 0: do a simple isinstance check.
             if self.adapt == 0:
    -            try:
    -                if value is adapt(value, self.klass):
    -                    return value
    -            except:
    -                if validate_implements(value, self.klass):
    -                    return value
    -
    -        elif self.adapt == 1:
    -            try:
    -                return adapt(value, self.klass)
    -            except:
    -                if validate_implements(value, self.klass):
    -                    return value
    -
    -        else:
    -            result = adapt(value, self.klass, None)
    -            if result is None:
    -                if validate_implements(value, self.klass):
    -                    return value
    -
    -                result = self.default_value
    -                if isinstance(result, _InstanceArgs):
    -                    result = result[0](*result[1], **result[2])
    +            if isinstance(value, self.klass):
    +                return value
    +            else:
    +                self.validate_failed(object, name, value)
     
    +        # Try adaptation; return adapted value on success.
    +        result = adapt(value, self.klass, None)
    +        if result is not None:
                 return result
     
    -        self.validate_failed(object, name, value)
    +        # Adaptation failed. Move on to an isinstance check.
    +        if isinstance(value, self.klass):
    +            return value
    +
    +        # Adaptation and isinstance both failed. In mode 1, fail.
    +        # Otherwise, return the default.
    +        if self.adapt == 1:
    +            self.validate_failed(object, name, value)
    +        else:
    +            result = self.default_value
    +            if isinstance(result, _InstanceArgs):
    +                return result[0](*result[1], **result[2])
    +            else:
    +                return result
     
         def info(self):
             """ Returns a description of the trait.
             """
             klass = self.klass
    -        if not isinstance(klass, six.string_types):
    +        if not isinstance(klass, str):
                 klass = klass.__name__
     
             if self.adapt == 0:
    @@ -3213,7 +3411,7 @@ 

    Source code for traits.trait_types

                 if not isinstance(dv, _InstanceArgs):
                     return super(BaseInstance, self).get_default_value()
     
    -            self.default_value_type = dvt = CALLABLE_AND_ARGS_DEFAULT_VALUE
    +            self.default_value_type = dvt = DefaultValue.callable_and_args
                 self.default_value = dv = (
                     self.create_default_value,
                     dv.args,
    @@ -3233,11 +3431,11 @@ 

    Source code for traits.trait_types

                 kind=self.kind or "live",
             )
     
    -    # -- Private Methods --------------------------------------------------------
    +    # -- Private Methods ------------------------------------------------------
     
         def create_default_value(self, *args, **kw):
             klass = args[0]
    -        if isinstance(klass, six.string_types):
    +        if isinstance(klass, str):
                 klass = self.validate_class(self.find_class(klass))
                 if klass is None:
                     raise TraitError("Unable to locate class: " + args[0])
    @@ -3251,7 +3449,7 @@ 

    Source code for traits.trait_types

     
         def init_fast_validate(self):
             """ Does nothing for the BaseInstance' class. Used by the 'Instance',
    -            'AdaptedTo' and 'AdaptsTo' classes to set up the C-level fast
    +            'Supports' and 'AdaptsTo' classes to set up the C-level fast
                 validator.
             """
             pass
    @@ -3259,9 +3457,9 @@ 

    Source code for traits.trait_types

         def resolve_class(self, object, name, value):
             super(BaseInstance, self).resolve_class(object, name, value)
     
    -        #: fixme: The following is quite ugly, because it wants to try and fix
    -        #: the trait referencing this handler to use the 'fast path' now that the
    -        #: actual class has been resolved. The problem is finding the trait,
    +        # fixme: The following is quite ugly, because it wants to try and fix
    +        # the trait referencing this handler to use the 'fast path' now that
    +        # the actual class has been resolved. The problem is finding the trait,
             # especially in the case of List(Instance('foo')), where the
             # object.base_trait(...) value is the List trait, not the Instance
             # trait, so we need to check for this and pull out the List
    @@ -3275,8 +3473,8 @@ 

    Source code for traits.trait_types

                 if set_validate is not None:
                     # The outer trait is a TraitCompound. Recompute its
                     # fast_validate table now that we have updated ours.
    -                # FIXME: there are probably still issues if the TraitCompound is
    -                # further nested.
    +                # FIXME: there are probably still issues if the TraitCompound
    +                # is further nested.
                     set_validate()
                 else:
                     item_trait = getattr(handler, "item_trait", None)
    @@ -3291,30 +3489,30 @@ 

    Source code for traits.trait_types

     
     
     class Instance(BaseInstance):
    -    """ Defines a trait whose value must be an instance of a specified class,
    -        or one of its subclasses using a C-level fast validator.
    +    """ A fast-validated trait type whose value is an instance of a class.
         """
     
         def init_fast_validate(self):
             """ Sets up the C-level fast validator. """
     
    -        from .has_traits import isinterface
    -
    -        if (self.adapt == 0) and (not isinterface(self.klass)):
    -            fast_validate = [1, self.klass]
    +        if self.adapt == 0:
    +            fast_validate = [ValidateTrait.instance, self.klass]
                 if self._allow_none:
    -                fast_validate = [1, None, self.klass]
    +                fast_validate = [ValidateTrait.instance, None, self.klass]
    +            else:
    +                fast_validate = [ValidateTrait.instance, self.klass]
     
                 if self.klass in TypeTypes:
    -                fast_validate[0] = 0
    +                fast_validate[0] = ValidateTrait.type
     
                 self.fast_validate = tuple(fast_validate)
             else:
    -            self.fast_validate = (19, self.klass, self.adapt, self._allow_none)
    +            self.fast_validate = (
    +                ValidateTrait.adapt, self.klass, self.adapt, self._allow_none)
     
     
     class Supports(Instance):
    -    """ A traits whose value must support a specified protocol.
    +    """ A trait type whose value is adapted to a specified protocol.
     
         In other words, the value of the trait directly provide, or can be adapted
         to, the given protocol (Interface or type).
    @@ -3338,21 +3536,18 @@ 

    Source code for traits.trait_types

         def as_ctrait(self):
             """ Returns a CTrait corresponding to the trait defined by this class.
             """
    -        return self.modify_ctrait(super(AdaptedTo, self).as_ctrait())
    +        return self.modify_ctrait(super(Supports, self).as_ctrait())
     
         def modify_ctrait(self, ctrait):
     
             # Tell the C code that the 'post_setattr' method wants the original,
             # unadapted value passed to 'setattr':
    -        return ctrait.post_setattr_original_value(True)
    -
    -
    -# Alias defined for backward compatibility with Traits 4.3.0
    -AdaptedTo = Supports
    +        ctrait.post_setattr_original_value = True
    +        return ctrait
     
     
     class AdaptsTo(Supports):
    -    """ A traits whose value must support a specified protocol.
    +    """ A trait type whose value must support a specified protocol.
     
         In other words, the value of the trait directly provide, or can be adapted
         to, the given protocol (Interface or type).
    @@ -3366,39 +3561,43 @@ 

    Source code for traits.trait_types

         def modify_ctrait(self, ctrait):
             # Tell the C code that 'setattr' should store the original, unadapted
             # value passed to it:
    -        return ctrait.setattr_original_value(True)
    -
    -
    -# -------------------------------------------------------------------------------
    -#  'Type' trait:
    -# -------------------------------------------------------------------------------
    +        ctrait.setattr_original_value = True
    +        return ctrait
     
     
     class Type(BaseClass):
    -    """ Defines a trait whose value must be a subclass of a specified class.
    +    """ A trait type whose value must be a subclass of a specified class.
    +
    +    Parameters
    +    ----------
    +    value : class or None
    +        The default value of the trait.
    +    klass : class, str or None
    +        The class that trait values must be subclasses of.  If None, then
    +        the default value is used instead.  If both are None, then the
    +        ``object`` type is used.  If it is a string, the first time that
    +        the validate method is called, the class will be imported and
    +        the value replaced with the class object.
    +    allow_none : bool
    +        Indicates whether None is allowed as an assignable value. Even if
    +        **False**, the default *value* may be **None**.
    +    **metadata
    +        Trait metadata for the trait.
    +
    +    Attributes
    +    ----------
    +    klass : class or str
    +        The class that trait values must be subclasses of.  If this is a
    +        string, the first time that the validate method is called, the
    +        class will be imported and the value replaced with the class object.
    +    module : str
    +        The name of the module where local class names (ie. class names
    +        with no module components) are presumed to be importable from.
    +        This is the caller's caller's module, as determined by the
    +        ``get_module_method``.
         """
     
         def __init__(self, value=None, klass=None, allow_none=True, **metadata):
    -        """ Returns an Type trait.
    -
    -        Parameters
    -        ----------
    -        value : class or None
    -
    -        klass : class or None
    -
    -        allow_none : bool
    -            Indicates whether None is allowed as an assignable value. Even if
    -            **False**, the default *value* may be **None**.
    -
    -        Default Value
    -        -------------
    -        **None** if *klass* is an instance or if it is a class and *args* and
    -        *kw* are not specified. Otherwise, the default value is the instance
    -        obtained by calling ``klass(*args, **kw)``. Note that the constructor
    -        call is performed each time a default value is assigned, so each
    -        default value assigned is a unique instance.
    -        """
             if value is None:
                 if klass is None:
                     klass = object
    @@ -3406,10 +3605,10 @@ 

    Source code for traits.trait_types

             elif klass is None:
                 klass = value
     
    -        if isinstance(klass, six.string_types):
    +        if isinstance(klass, str):
                 self.validate = self.resolve
     
    -        elif not isinstance(klass, ClassTypes):
    +        elif not isinstance(klass, type):
                 raise TraitError("A Type trait must specify a class.")
     
             self.klass = klass
    @@ -3432,10 +3631,10 @@ 

    Source code for traits.trait_types

     
         def resolve(self, object, name, value):
             """ Resolves a class originally specified as a string into an actual
    -            class, then resets the trait so that future calls will be handled by
    -            the normal validate method.
    +            class, then resets the trait so that future calls will be handled
    +            by the normal validate method.
             """
    -        if isinstance(self.klass, six.string_types):
    +        if isinstance(self.klass, str):
                 self.resolve_class(object, name, value)
                 del self.validate
     
    @@ -3445,7 +3644,7 @@ 

    Source code for traits.trait_types

             """ Returns a description of the trait.
             """
             klass = self.klass
    -        if not isinstance(klass, six.string_types):
    +        if not isinstance(klass, str):
                 klass = klass.__name__
     
             result = "a subclass of " + klass
    @@ -3457,13 +3656,13 @@ 

    Source code for traits.trait_types

     
         def get_default_value(self):
             """ Returns a tuple of the form: ( default_value_type, default_value )
    -            which describes the default value for this trait.
    +        which describes the default value for this trait.
             """
    -        if not isinstance(self.default_value, six.string_types):
    +        if not isinstance(self.default_value, str):
                 return super(Type, self).get_default_value()
     
             return (
    -            CALLABLE_AND_ARGS_DEFAULT_VALUE,
    +            DefaultValue.callable_and_args,
                 (self.resolve_default_value, (), None),
             )
     
    @@ -3471,7 +3670,7 @@ 

    Source code for traits.trait_types

             """ Resolves a class name into a class so that it can be used to
                 return the class as the default value of the trait.
             """
    -        if isinstance(self.klass, six.string_types):
    +        if isinstance(self.klass, str):
                 try:
                     self.resolve_class(None, None, None)
                     del self.validate
    @@ -3483,12 +3682,29 @@ 

    Source code for traits.trait_types

             return self.klass
     
     
    -# -------------------------------------------------------------------------------
    -#  'Event' trait:
    -# -------------------------------------------------------------------------------
    +#: An alias for the Type trait
    +Subclass = Type
     
     
     class Event(TraitType):
    +    """ A trait type that holds no value but can be set and listened to.
    +
    +    Event traits are write-only traits.  They do not hold any value, but
    +    they can be assigned to, and listeners to the trait will be notified
    +    of the assignment.  Since no value is held, trait change functions that
    +    ask for the ``old`` value of the trait will be given the Undefined
    +    special value.
    +
    +    Event traits can be given an optional trait type that is used to validate
    +    values assigned to the trait.  If the assigned value does not validate,
    +    then a TraitError will occur.
    +
    +    Parameters
    +    ----------
    +    trait : a trait
    +        The type of value that can be assigned to the event.
    +    """
    +
         def __init__(self, trait=None, **metadata):
             metadata["type"] = "event"
             metadata["transient"] = True
    @@ -3512,16 +3728,56 @@ 

    Source code for traits.trait_types

             return trait.full_info(object, name, value)
     
     
    -#  Handle circular module dependencies:
    -trait_handlers.Event = Event
    -
    -# -------------------------------------------------------------------------------
    -#  'Button' trait:
    -# -------------------------------------------------------------------------------
    -
    -
     class Button(Event):
    -    """ Defines a trait whose UI editor is a button.
    +    """ An Event trait type whose UI editor is a button.
    +
    +    Parameters
    +    ----------
    +    label : str
    +        The label for the button.
    +    image : pyface.ImageResource
    +        An image to display on the button.
    +    style : 'button', 'radio', 'toolbar' or 'checkbox'
    +        The style of button to display.
    +    values_trait : str
    +        For a "button" or "toolbar" style, the name of an enum
    +        trait whose values will populate a drop-down menu on the button.
    +        The selected value will replace the label on the button.
    +    orientation : 'horizontal' or 'vertical'
    +        The orientation of the label relative to the image.
    +    width_padding : integer between 0 and 31
    +        Extra padding (in pixels) added to the left and right sides of
    +        the button.
    +    height_padding : integer between 0 and 31
    +        Extra padding (in pixels) added to the top and bottom of the
    +        button.
    +    view : traitsui View, optional
    +        An optional View to display when the button is clicked.
    +    **metadata
    +        Trait metadata for the trait.
    +
    +    Attributes
    +    ----------
    +    label : str
    +        The label for the button.
    +    image : pyface.ImageResource
    +        An image to display on the button.
    +    style : 'button', 'radio', 'toolbar' or 'checkbox'
    +        The style of button to display.
    +    values_trait : str
    +        For a "button" or "toolbar" style, the name of an enum
    +        trait whose values will populate a drop-down menu on the button.
    +        The selected value will replace the label on the button.
    +    orientation : 'horizontal' or 'vertical'
    +        The orientation of the label relative to the image.
    +    width_padding : integer between 0 and 31
    +        Extra padding (in pixels) added to the left and right sides of
    +        the button.
    +    height_padding : integer between 0 and 31
    +        Extra padding (in pixels) added to the top and bottom of the
    +        button.
    +    view : traitsui View, optional
    +        An optional View to display when the button is clicked.
         """
     
         def __init__(
    @@ -3536,33 +3792,6 @@ 

    Source code for traits.trait_types

             view=None,
             **metadata
         ):
    -        """ Returns a trait event whose editor is a button.
    -
    -            Parameters
    -            ----------
    -            label : str
    -                The label for the button.
    -            image : pyface.ImageResource
    -                An image to display on the button.
    -            style : one of: 'button', 'radio', 'toolbar', 'checkbox'
    -                The style of button to display.
    -            values_trait : str
    -                For a "button" or "toolbar" style, the name of an enum
    -                trait whose values will populate a drop-down menu on the button.
    -                The selected value will replace the label on the button.
    -            orientation : one of: 'horizontal', 'vertical'
    -                The orientation of the label relative to the image.
    -            width_padding : integer between 0 and 31
    -                Extra padding (in pixels) added to the left and right sides of
    -                the button.
    -            height_padding : integer between 0 and 31
    -                Extra padding (in pixels) added to the top and bottom of the
    -                button.
    -
    -            Default Value
    -            -------------
    -            No default value because events do not store values.
    -        """
             self.label = label
             self.values_trait = values_trait
             self.image = image
    @@ -3589,14 +3818,53 @@ 

    Source code for traits.trait_types

             return editor
     
     
    -# -------------------------------------------------------------------------------
    -#  'ToolbarButton' trait:
    -# -------------------------------------------------------------------------------
    -
    -
     class ToolbarButton(Button):
    -    """ Defines a trait whose UI editor is a button that can be used on a
    -        toolbar.
    +    """ A Button trait type whose UI editor is a toolbar button.
    +
    +    This is just a Button trait with different defaults to style it like
    +    a toolbar button.
    +
    +    Parameters
    +    ----------
    +    label : str
    +        The label for the button.
    +    image : pyface.ImageResource
    +        An image to display on the button.
    +    style : 'button', 'radio', 'toolbar' or 'checkbox'
    +        The style of button to display.
    +    orientation : 'horizontal' or 'vertical'
    +        The orientation of the label relative to the image.
    +    width_padding : integer between 0 and 31
    +        Extra padding (in pixels) added to the left and right sides of
    +        the button.
    +    height_padding : integer between 0 and 31
    +        Extra padding (in pixels) added to the top and bottom of the
    +        button.
    +    **metadata
    +        Trait metadata for the trait.
    +
    +    Attributes
    +    ----------
    +    label : str
    +        The label for the button.
    +    image : pyface.ImageResource
    +        An image to display on the button.
    +    style : 'button', 'radio', 'toolbar' or 'checkbox'
    +        The style of button to display.
    +    values_trait : str
    +        For a "button" or "toolbar" style, the name of an enum
    +        trait whose values will populate a drop-down menu on the button.
    +        The selected value will replace the label on the button.
    +    orientation : 'horizontal' or 'vertical'
    +        The orientation of the label relative to the image.
    +    width_padding : integer between 0 and 31
    +        Extra padding (in pixels) added to the left and right sides of
    +        the button.
    +    height_padding : integer between 0 and 31
    +        Extra padding (in pixels) added to the top and bottom of the
    +        button.
    +    view : traitsui View, optional
    +        An optional View to display when the button is clicked.
         """
     
         def __init__(
    @@ -3609,30 +3877,6 @@ 

    Source code for traits.trait_types

             height_padding=2,
             **metadata
         ):
    -        """ Returns a trait event whose editor is a toolbar button.
    -
    -            Parameters
    -            ----------
    -            label : str
    -                The label for the button
    -            image : pyface.ImageResource
    -                An image to display on the button
    -            style : one of: 'button', 'radio', 'toolbar', 'checkbox'
    -                The style of button to display
    -            orientation : one of ['horizontal', 'vertical']
    -                The orientation of the label relative to the image
    -            width_padding : integer between 0 and 31
    -                Extra padding (in pixels) added to the left and right sides of
    -                the button
    -            height_padding : integer between 0 and 31
    -                Extra padding (in pixels) added to the top and bottom of the
    -                button
    -
    -            Default Value
    -            -------------
    -            No default value because events do not store values.
    -
    -        """
             super(ToolbarButton, self).__init__(
                 label,
                 image=image,
    @@ -3644,19 +3888,23 @@ 

    Source code for traits.trait_types

             )
     
     
    -# -------------------------------------------------------------------------------
    -#  'Either' trait:
    -# -------------------------------------------------------------------------------
    -
    -
     class Either(TraitType):
    -    """ Defines a trait whose value can be any of of a specified list of traits.
    +    """ A trait type whose value can be any of of a specified list of traits.
    +
    +    Parameters
    +    ----------
    +    *traits
    +        Arguments that define allowable trait values.
    +    **metadata
    +        Trait metadata for the trait.
    +
    +    Attributes
    +    ----------
    +    trait_maker : TraitHandler
    +        A TraitHandler generated by _TraitMaker from the arguments.
         """
     
         def __init__(self, *traits, **metadata):
    -        """ Creates a trait whose value can be any of of a specified list of
    -            traits.
    -        """
             self.trait_maker = _TraitMaker(
                 metadata.pop("default", None), *traits, **metadata
             )
    @@ -3667,12 +3915,123 @@ 

    Source code for traits.trait_types

             return self.trait_maker.as_ctrait()
     
     
    +class _NoneTrait(TraitType):
    +    """ Defines a trait that only accepts the None value
    +
    +    This is primarily used for supporting ``Union``.
    +    """
    +
    +    info_text = "None"
    +
    +    default_value = None
    +
    +    default_value_type = DefaultValue.constant
    +
    +    def __init__(self, **metadata):
    +        default_value = metadata.pop("default_value", None)
    +        if default_value is not None:
    +            raise ValueError("Cannot set default value {} "
    +                             "for _NoneTrait".format(default_value))
    +        super(_NoneTrait, self).__init__(**metadata)
    +
    +    def validate(self, obj, name, value):
    +        if value is None:
    +            return value
    +
    +        self.error(obj, name, value)
    +
    +
    +class Union(TraitType):
    +    """ Defines a trait whose value can be any of of a specified list of
    +    trait types or list of trait type instances or None
    +
    +    If the default value is not defined on Union, the default value from the
    +    first trait will be used.
    +    """
    +
    +    def __init__(self, *traits, **metadata):
    +        self.list_ctrait_instances = []
    +
    +        if not traits:
    +            traits = (_NoneTrait,)
    +
    +        for trait in traits:
    +            if trait is None:
    +                trait = _NoneTrait
    +            ctrait_instance = trait_cast(trait)
    +            if ctrait_instance is None:
    +                raise ValueError("Union trait declaration expects a trait "
    +                                 "type or an instance of trait type or None,"
    +                                 " but got {!r} instead".format(trait))
    +
    +            self.list_ctrait_instances.append(ctrait_instance)
    +
    +        # ``Either`` uses 'default' for defining static default values.
    +        # Raise if 'default' is found in order to help code migrate to Union
    +        if "default" in metadata:
    +            raise ValueError(
    +                "Union default value should be set via 'default_value', not "
    +                "'default'."
    +            )
    +
    +        default_value = None
    +        if 'default_value' in metadata:
    +            default_value = metadata.pop("default_value")
    +        elif self.list_ctrait_instances:
    +            default_value = self.list_ctrait_instances[0].default
    +
    +        self.default_value_type = _infer_default_value_type(default_value)
    +        super().__init__(default_value, **metadata)
    +
    +    def validate(self, obj, name, value):
    +        """ Return the value by the first trait in the list that can
    +        validate the assigned value, raise an error if none of them can.
    +        """
    +        for trait_type_instance in self.list_ctrait_instances:
    +            try:
    +                return trait_type_instance.validate(obj, name, value)
    +            except TraitError:
    +                pass
    +
    +        self.error(obj, name, value)
    +
    +    def info(self):
    +        return " or ".join([ctrait.info() for ctrait in
    +                            self.list_ctrait_instances])
    +
    +    def inner_traits(self):
    +        return tuple(self.list_ctrait_instances)
    +
    +    def get_editor(self, trait):
    +        from traitsui.api import TextEditor, CompoundEditor
    +
    +        the_editors = [x.get_editor() for x in self.list_ctrait_instances]
    +        text_editor = TextEditor()
    +        count = 0
    +        editors = []
    +        for editor in the_editors:
    +            if isinstance(text_editor, editor.__class__):
    +                count += 1
    +                if count > 1:
    +                    continue
    +            editors.append(editor)
    +
    +        return CompoundEditor(editors=editors)
    +
    +
     # -------------------------------------------------------------------------------
     #  'Symbol' trait:
     # -------------------------------------------------------------------------------
    +class Symbol(TraitType):
    +    """ A property trait type that refers to a Python object by name.
     
    +    The value set to the trait must be a value of the form
    +    ``'[package.package...package.]module[:symbol[([arg1,...,argn])]]'``
    +    which is imported and evaluated to get underlying value.
     
    -class Symbol(TraitType):
    +    The value returned by the trait is the actual object that this string
    +    refers to.  The value is cached, so any calls are only evaluated once.
    +    """
     
         #: A description of the type of value this trait accepts:
         info_text = (
    @@ -3691,7 +4050,7 @@ 

    Source code for traits.trait_types

                         name
                     ).default_value_for(object, name)
     
    -            if isinstance(ref, six.string_types):
    +            if isinstance(ref, str):
                     object.__dict__[name] = value = self._resolve(ref)
     
             return value
    @@ -3699,7 +4058,7 @@ 

    Source code for traits.trait_types

         def set(self, object, name, value):
             dict = object.__dict__
             old = dict.get(name, Undefined)
    -        if isinstance(value, six.string_types):
    +        if isinstance(value, str):
                 dict.pop(name, None)
                 dict[TraitsCache + name] = value
                 object.trait_property_changed(name, old)
    @@ -3709,16 +4068,8 @@ 

    Source code for traits.trait_types

     
         def _resolve(self, ref):
             try:
    -            path = ref.split(":", 1)
    -            module = __import__(path[0])
    -            for component in path[0].split(".")[1:]:
    -                module = getattr(module, component)
    -
    -            if len(path) == 1:
    -                return module
    -
    -            elements = path[1].split("(", 1)
    -            symbol = getattr(module, elements[0])
    +            elements = ref.split("(", 1)
    +            symbol = import_symbol(elements[0])
                 if len(elements) == 1:
                     return symbol
     
    @@ -3727,18 +4078,23 @@ 

    Source code for traits.trait_types

                     args = (args,)
     
                 return symbol(*args)
    -        except:
    +        except Exception:
                 raise TraitError(
                     "Could not resolve '%s' into a valid symbol." % ref
                 )
     
     
    -# ---------------------------------------------------------------------------
    -#  'UUID' trait:
    -# ---------------------------------------------------------------------------
    -
     class UUID(TraitType):
    -    """ Defines a trait whose value is a globally unique UUID (type 4).
    +    """ A read-only trait type whose value is a globally unique UUID (type 4).
    +
    +    Parameters
    +    ----------
    +    can_init : bool
    +        Whether the value can be set during object instantiation.  Otherwise
    +        the UUID is generated automatically.
    +
    +    Example
    +    -------
     
         Passing `can_init=True` allows the UUID value to be set during
         object instantiation, e.g.::
    @@ -3764,8 +4120,6 @@ 

    Source code for traits.trait_types

         info_text = "a read-only UUID"
     
         def __init__(self, can_init=False, **metadata):
    -        """ Returns a UUID trait.
    -        """
             super(UUID, self).__init__(None, **metadata)
             self.can_init = can_init
     
    @@ -3795,8 +4149,12 @@ 

    Source code for traits.trait_types

                 raise TraitError(msg.format(name, type(object).__name__, value))
     
         def get_default_value(self):
    +        """ Return a Traits default value tuple for the trait.
    +
    +        This uses the _create_uuid method to generate the defualt value.
    +        """
             return (
    -            CALLABLE_AND_ARGS_DEFAULT_VALUE,
    +            DefaultValue.callable_and_args,
                 (self._create_uuid, (), None),
             )
     
    @@ -3806,16 +4164,27 @@ 

    Source code for traits.trait_types

             return uuid.uuid4()
     
     
    -# -------------------------------------------------------------------------------
    -#  'WeakRef' trait:
    -# -------------------------------------------------------------------------------
    -
    -
     class WeakRef(Instance):
    -    """ Returns a trait whose value must be an instance of the same type
    -    (or a subclass) of the specified *klass*, which can be a class or an
    -    instance. Note that the trait only maintains a weak reference to the
    -    assigned value.
    +    """ A trait type holding a weak reference to an instance of a class.
    +
    +    Only a weak reference is maintained to any object assigned to a WeakRef
    +    trait. If no other references exist to the assigned value, the value
    +    may be garbage collected, in which case the value of the trait becomes
    +    None. In all other cases, the value returned by the trait is the
    +    original object.
    +
    +    Parameters
    +    ----------
    +    klass : class, str or instance
    +        The object that forms the basis for the trait. If *klass* is
    +        omitted, then values must be an instance of HasTraits.  If a string,
    +        the value will be resolved to a class object at runtime.
    +    allow_none : boolean
    +        Indicates whether None can be _assigned_.  The trait attribute may
    +        give a None value if the object referred to has been garbage collected
    +        even if allow_none is False.
    +    adapt : str
    +        How to use the adaptation infrastructure when setting the value.
         """
     
         def __init__(
    @@ -3825,27 +4194,6 @@ 

    Source code for traits.trait_types

             adapt="yes",
             **metadata
         ):
    -        """ Returns a WeakRef trait.
    -
    -        Only a weak reference is maintained to any object assigned to a WeakRef
    -        trait. If no other references exist to the assigned value, the value
    -        may be garbage collected, in which case the value of the trait becomes
    -        None. In all other cases, the value returned by the trait is the
    -        original object.
    -
    -        Parameters
    -        ----------
    -        klass : class or instance
    -            The object that forms the basis for the trait. If *klass* is
    -            omitted, then values must be an instance of HasTraits.
    -        allow_none : boolean
    -            Indicates whether None can be assigned.
    -
    -        Default Value
    -        -------------
    -        **None** (even if allow_none==False)
    -        """
    -
             metadata.setdefault("copy", "ref")
     
             super(WeakRef, self).__init__(
    @@ -3886,94 +4234,146 @@ 

    Source code for traits.trait_types

             self.klass = klass
     
     
    -# -- Date Trait definition ----------------------------------------------------
    +#: A trait type for datetime.date instances.
     Date = BaseInstance(datetime.date, editor=date_editor)
     
     
    -# -- Time Trait definition ----------------------------------------------------
    +#: A trait type for datetime.datetime instances.
    +Datetime = BaseInstance(datetime.datetime, editor=datetime_editor)
    +
    +
    +#: A trait type for datetime.time instances.
     Time = BaseInstance(datetime.time, editor=time_editor)
     
     
    -# -------------------------------------------------------------------------------
    -#  Create predefined, reusable trait instances:
    -# -------------------------------------------------------------------------------
    +# Predefined, reusable trait instances
    +
    +# Everything from this point onwards is deprecated, and has a simple
    +# drop-in replacement.
    +
    +#: A trait whose value must support a specified protocol. This is
    +#: an alias for :class:`Supports`. Use ``Supports`` instead.
    +AdaptedTo = Supports
    +
    +#: A trait whose value must be a (Unicode) string. This is an alias for
    +#: :class:`BaseStr`. Use ``BaseStr`` instead.
    +BaseUnicode = BaseStr
    +
    +#: A trait whose value must be a (Unicode) string, using a C-level
    +#: fast validator. This is an alias for :class:`Str`. Use ``Str`` instead.
    +Unicode = Str
    +
    +#: A trait whose value must be a (Unicode) string and which supports
    +#: coercions of non-string values to string. This is
    +#: an alias for :class:`BaseCStr`. Use ``BaseCStr`` instead.
    +BaseCUnicode = BaseCStr
    +
    +#: A trait whose value must be a (Unicode) string and which supports
    +#: coercions of non-string values to string, using a C-level fast validator.
    +#: This is an alias for :class:`CStr`. Use ``CStr`` instead.
    +CUnicode = CStr
     
    -# Synonym for Bool; default value is False.
    +#: A trait whose value must be an integer. This is an alias for
    +#: :class:`BaseInt`. Use ``BaseInt`` instead.
    +BaseLong = BaseInt
    +
    +#: A trait whose value must be an integer, using a C-level fast validator.
    +#: This is an alias for :class:`Int`. Use ``Int`` instead.
    +Long = Int
    +
    +#: A trait whose value must be an integer and which supports coercions
    +#: of non-integer values to integer. This is an alias for
    +#: :class:`BaseCInt`. Use ``BaseCInt`` instead.
    +BaseCLong = BaseCInt
    +
    +#: A trait whose value must be an integer and which supports coercions
    +#: of non-integer values to integer, using a C-level fast validator.
    +#: This is an alias for :class:`CInt`. Use ``CInt`` instead.
    +CLong = CInt
    +
    +#: Synonym for Bool; default value is ``False``. This trait type is
    +#: deprecated. Use ``Bool(False)`` or ``Bool()`` instead.
     false = Bool
     
    -# Boolean values only; default value is True.
    +#: Boolean values only; default value is ``True``. This trait type is
    +#: deprecated. Use ``Bool(True)`` instead.
     true = Bool(True)
     
    -# Allows any value to be assigned; no type-checking is performed.
    -# Default value is Undefined.
    +#: Allows any value to be assigned; no type-checking is performed.
    +#: Default value is ``Undefined``. This trait type is deprecated. Use
    +#: ``Any(Undefined)`` instead.
     undefined = Any(Undefined)
     
    -# -- List Traits ----------------------------------------------------------------
    +# -- List Traits --------------------------------------------------------------
     
    -#: List of integer values; default value is [].
    +#: List of integer values; default value is ``[]``. This trait type is
    +#: deprecated. Use ``List(Int)`` instead.
     ListInt = List(int)
     
    -#: List of float values; default value is [].
    +#: List of float values; default value is ``[]``. This trait type is
    +#: deprecated. Use ``List(Float)`` instead.
     ListFloat = List(float)
     
    -#: List of string values; default value is [].
    +#: List of string values; default value is ``[]``. This trait type is
    +#: deprecated. Use ``List(Str)`` instead.
     ListStr = List(str)
     
    -#: List of Unicode string values; default value is [].
    -ListUnicode = List(six.text_type)
    +#: List of string values; default value is ``[]``. This trait type is
    +#: deprecated. Use ``List(Str)`` instead.
    +ListUnicode = List(str)
     
    -#: List of complex values; default value is [].
    +#: List of complex values; default value is ``[]``. This trait type is
    +#: deprecated. Use ``List(Complex)`` instead.
     ListComplex = List(complex)
     
    -#: List of Boolean values; default value is [].
    +#: List of Boolean values; default value is ``[]``. This trait type is
    +#: deprecated. Use ``List(Bool)`` instead.
     ListBool = List(bool)
     
    -#: List of function values; default value is [].
    +#: List of function values; default value is ``[]``. This trait type is
    +#: deprecated. Use ``List(Instance(types.FunctionType, allow_none=False))``
    +#: instead.
     ListFunction = List(FunctionType)
     
    -#: List of method values; default value is [].
    +#: List of method values; default value is ``[]``. This trait type is
    +#: deprecated. Use ``List(Instance(types.MethodType, allow_none=False))``
    +#: instead.
     ListMethod = List(MethodType)
     
    -if six.PY2:
    -    from types import ClassType, InstanceType
    +#: List of container type values; default value is ``[]``. This trait type is
    +#: deprecated. Use ``List(This(allow_none=False))`` instead.
    +ListThis = List(This(allow_none=False))
     
    -    #: List of class values; default value is [].
    -    ListClass = List(ClassType)
    +# -- Dictionary Traits --------------------------------------------------------
     
    -    #: List of instance values; default value is [].
    -    ListInstance = List(InstanceType)
    -
    -#: List of container type values; default value is [].
    -ListThis = List(ThisClass)
    -
    -# -- Dictionary Traits ----------------------------------------------------------
    -
    -#: Only a dictionary of string:Any values can be assigned; only string keys can
    -#: be inserted. The default value is {}.
    +#: Only a dictionary with strings as keys can be assigned; only string keys
    +#: can be inserted. The default value is {}. This trait type is deprecated. Use
    +#: ``Dict(Str, Any)`` instead.
     DictStrAny = Dict(str, Any)
     
    -#: Only a dictionary of string:string values can be assigned; only string keys
    -#: with string values can be inserted. The default value is {}.
    +#: Only a dictionary mapping strings to strings can be assigned; only string
    +#: keys with string values can be inserted. The default value is {}. This trait
    +#: type is deprecated. Use ``Dict(Str, Str)`` instead.
     DictStrStr = Dict(str, str)
     
    -#: Only a dictionary of string:integer values can be assigned; only string keys
    -#: with integer values can be inserted. The default value is {}.
    +#: Only a dictionary mapping strings to integers can be assigned; only string
    +#: keys with integer values can be inserted. The default value is {}. This
    +#: trait type is deprecated. Use ``Dict(Str, Int)`` instead.
     DictStrInt = Dict(str, int)
     
    -#: Only a dictionary of string:long-integer values can be assigned; only string
    -#: keys with long-integer values can be inserted. The default value is {}.
    -DictStrLong = Dict(str, LONG_TYPE)
    -
    -#: Only a dictionary of string:float values can be assigned; only string keys
    -#: with float values can be inserted. The default value is {}.
    +#: Only a dictionary mapping strings to floats can be assigned; only string
    +#: keys with float values can be inserted. The default value is {}. This trait
    +#: type is deprecated. Use ``Dict(Str, Float)`` instead.
     DictStrFloat = Dict(str, float)
     
    -#: Only a dictionary of string:bool values can be assigned; only string keys
    -#: with boolean values can be inserted. The default value is {}.
    +#: Only a dictionary mapping strings to booleans can be assigned; only string
    +#: keys with boolean values can be inserted. The default value is {}. This
    +#: trait type is deprecated. Use ``Dict(Str, Bool)`` instead.
     DictStrBool = Dict(str, bool)
     
    -#: Only a dictionary of string:list values can be assigned; only string keys
    -#: with list values can be assigned. The default value is {}.
    +#: Only a dictionary mapping strings to lists can be assigned; only string keys
    +#: with list values can be inserted. The default value is {}. This trait type
    +#: is deprecated. Use ``Dict(Str, List)`` instead.
     DictStrList = Dict(str, list)
     
    @@ -3986,13 +4386,11 @@

    Source code for traits.trait_types

                   
                 

    @@ -4016,10 +4414,10 @@

    Quick search

    © Copyright 2008-2020, Enthought
  • - Last updated on Jun 12, 2020. + Last updated on Dec 17, 2020.
  • - Created using Sphinx 1.8.5. + Created using Sphinx 2.3.1.
  • diff --git a/_modules/traits/traits.html b/_modules/traits/traits.html index 344be21b4..4b1a7ea95 100644 --- a/_modules/traits/traits.html +++ b/_modules/traits/traits.html @@ -13,9 +13,11 @@ @@ -72,27 +74,18 @@
    -
    +

    Source code for traits.traits

    -# ------------------------------------------------------------------------------
    +# (C) Copyright 2005-2020 Enthought, Inc., Austin, TX
    +# All rights reserved.
     #
    -#  Copyright (c) 2005, Enthought, Inc.
    -#  All rights reserved.
    +# This software is provided without warranty under the terms of the BSD
    +# license included in LICENSE.txt and may be redistributed only under
    +# the conditions described in the aforementioned license. The license
    +# is also available online at http://www.enthought.com/licenses/BSD.txt
     #
    -#  This software is provided without warranty under the terms of the BSD
    -#  license included in enthought/LICENSE.txt and may be redistributed only
    -#  under the conditions described in the aforementioned license.  The license
    -#  is also available online at http://www.enthought.com/licenses/BSD.txt
    -#
    -#  Thanks for using Enthought open source!
    -#
    -#  Author:        David C. Morrill
    -#  Original Date: 06/21/2002
    -#
    -#  Rewritten as a C-based type extension: 06/21/2004
    -#
    -# ------------------------------------------------------------------------------
    +# Thanks for using Enthought open source!
     
     """
     Defines the 'core' traits for the Traits package. A trait is a type definition
    @@ -119,33 +112,33 @@ 

    Source code for traits.traits

         feature.
     """
     
    -# -------------------------------------------------------------------------------
    -#  Imports:
    -# -------------------------------------------------------------------------------
    -
    -from __future__ import absolute_import
    -
    -import sys
     from types import FunctionType, MethodType
    +import warnings
     
    -import six
    -
    -NoneType = type(None)  # Python 3's types does not include NoneType
    -
    -from . import trait_handlers
    -from .ctraits import cTrait
    +from .constants import (
    +    ComparisonMode,
    +    DefaultValue,
    +    TraitKind,
    +)
    +from .ctrait import CTrait
     from .trait_errors import TraitError
     from .trait_base import (
         SequenceTypes,
    -    Self,
    -    Undefined,
    -    Missing,
         TypeTypes,
         add_article,
     )
    +from .trait_converters import (
    +    trait_cast,
    +    check_trait as try_trait_cast,
    +)
     
    +from .trait_handler import TraitHandler
    +from .trait_type import (
    +    _infer_default_value_type,
    +    _read_only,
    +    _write_only,
    +)
     from .trait_handlers import (
    -    TraitHandler,
         TraitInstance,
         TraitFunction,
         TraitCoerceType,
    @@ -153,495 +146,23 @@ 

    Source code for traits.traits

         TraitEnum,
         TraitCompound,
         TraitMap,
    -    TraitString,
    -    ThisClass,
    -    TraitType,
    -    _arg_count,
    -    _read_only,
    -    _write_only,
         _undefined_get,
         _undefined_set,
    -    UNSPECIFIED_DEFAULT_VALUE,
    -    CALLABLE_AND_ARGS_DEFAULT_VALUE,
     )
    +from .trait_factory import (
    +    TraitFactory,
    +)
    +from .util.deprecated import deprecated
     
    +# Constants
     
    -from ._py2to3 import LONG_TYPE
    -
    -# -------------------------------------------------------------------------------
    -#  Constants:
    -# -------------------------------------------------------------------------------
    -
    -# Mapping from 'ctrait' default value types to a string representation:
    -KindMap = {
    -    0: "value",
    -    1: "value",
    -    2: "self",
    -    3: "list",
    -    4: "dict",
    -    5: "list",
    -    6: "dict",
    -    7: "factory",
    -    8: "method",
    -}
    -
    -# -------------------------------------------------------------------------------
    -#  Editor factory functions:
    -# -------------------------------------------------------------------------------
    -
    -PasswordEditor = None
    -MultilineTextEditors = {}
    -BytesEditors = {}
    -SourceCodeEditor = None
    -HTMLTextEditor = None
    -PythonShellEditor = None
    -DateEditor = None
    -TimeEditor = None
    -
    -
    -def password_editor(auto_set=True, enter_set=False):
    -    """ Factory function that returns an editor for passwords.
    -    """
    -    global PasswordEditor
    -
    -    if PasswordEditor is None:
    -        from traitsui.api import TextEditor
    -
    -        PasswordEditor = TextEditor(
    -            password=True, auto_set=auto_set, enter_set=enter_set
    -        )
    -
    -    return PasswordEditor
    -
    -
    -def multi_line_text_editor(auto_set=True, enter_set=False):
    -    """ Factory function that returns a text editor for multi-line strings.
    -    """
    -    if (auto_set, enter_set) not in MultilineTextEditors:
    -        from traitsui.api import TextEditor
    -
    -        MultilineTextEditors[auto_set, enter_set] = TextEditor(
    -            multi_line=True, auto_set=auto_set, enter_set=enter_set
    -        )
    -
    -    return MultilineTextEditors[auto_set, enter_set]
    -
    -
    -def bytes_editor(auto_set=True, enter_set=False, encoding=None):
    -    """ Factory function that returns a text editor for bytes.
    -    """
    -    if encoding is not None:
    -        if isinstance(encoding, str):
    -            import codecs
    -
    -            encoding = codecs.lookup(encoding)
    -
    -    if (auto_set, enter_set, encoding) not in BytesEditors:
    -        from traitsui.api import TextEditor
    -
    -        if encoding is None:
    -            # py3-compatible bytes <-> hex unicode string
    -            format = lambda b: b.encode("hex").decode("ascii")
    -            evaluate = lambda s: s.encode("ascii").decode("hex")
    -        else:
    -            format = encoding.decode
    -            evaluate = encoding.encode
    -
    -        BytesEditors[(auto_set, enter_set, encoding)] = TextEditor(
    -            multi_line=True,
    -            format_func=format,
    -            evaluate=evaluate,
    -            auto_set=auto_set,
    -            enter_set=enter_set,
    -        )
    -
    -    return BytesEditors[(auto_set, enter_set, encoding)]
    -
    -
    -def code_editor():
    -    """ Factory function that returns an editor that treats a multi-line string
    -    as source code.
    -    """
    -    global SourceCodeEditor
    -
    -    if SourceCodeEditor is None:
    -        from traitsui.api import CodeEditor
    -
    -        SourceCodeEditor = CodeEditor()
    -
    -    return SourceCodeEditor
    -
    -
    -def html_editor():
    -    """ Factory function for an "editor" that displays a multi-line string as
    -    interpreted HTML.
    -    """
    -    global HTMLTextEditor
    -
    -    if HTMLTextEditor is None:
    -        from traitsui.api import HTMLEditor
    -
    -        HTMLTextEditor = HTMLEditor()
    -
    -    return HTMLTextEditor
    -
    -
    -def shell_editor():
    -    """ Factory function that returns a Python shell for editing Python values.
    -    """
    -    global PythonShellEditor
    -
    -    if PythonShellEditor is None:
    -        from traitsui.api import ShellEditor
    -
    -        PythonShellEditor = ShellEditor()
    -
    -    return PythonShellEditor
    -
    -
    -def time_editor():
    -    """ Factory function that returns a Time editor for editing Time values.
    -    """
    -    global TimeEditor
    -
    -    if TimeEditor is None:
    -        from traitsui.api import TimeEditor
    -
    -        TimeEditor = TimeEditor()
    -
    -    return TimeEditor
    -
    -
    -def date_editor():
    -    """ Factory function that returns a Date editor for editing Date values.
    -    """
    -    global DateEditor
    -
    -    if DateEditor is None:
    -        from traitsui.api import DateEditor
    -
    -        DateEditor = DateEditor()
    -
    -    return DateEditor
    -
    -
    -def _expects_hastraits_instance(handler):
    -    """ Does a trait handler or type expect a HasTraits subclass instance?
    -    """
    -    from traits.api import HasTraits, BaseInstance, TraitInstance
    -
    -    if isinstance(handler, TraitInstance):
    -        cls = handler.aClass
    -    elif isinstance(handler, BaseInstance):
    -        cls = handler.klass
    -    else:
    -        return False
    -    return issubclass(cls, HasTraits)
    -
    -
    -def _instance_handler_factory(handler):
    -    """ Get the instance factory of an Instance or TraitInstance
    -    """
    -    from traits.api import BaseInstance, TraitInstance
    -
    -    if isinstance(handler, TraitInstance):
    -        return handler.aClass
    -    elif isinstance(handler, BaseInstance):
    -        return handler.default_value
    -    else:
    -        msg = "handler should be TraitInstance or BaseInstance, but got {}"
    -        raise ValueError(msg.format(repr(handler)))
    -
    -
    -def list_editor(trait, handler):
    -    """ Factory that constructs an appropriate editor for a list.
    -    """
    -    item_handler = handler.item_trait.handler
    -    if _expects_hastraits_instance(item_handler):
    -        from traitsui.table_column import ObjectColumn
    -        from traitsui.table_filter import (
    -            EvalFilterTemplate,
    -            RuleFilterTemplate,
    -            MenuFilterTemplate,
    -            EvalTableFilter,
    -        )
    -        from traitsui.api import TableEditor
    -
    -        return TableEditor(
    -            filters=[
    -                RuleFilterTemplate,
    -                MenuFilterTemplate,
    -                EvalFilterTemplate,
    -            ],
    -            edit_view="",
    -            orientation="vertical",
    -            search=EvalTableFilter(),
    -            deletable=True,
    -            show_toolbar=True,
    -            reorderable=True,
    -            row_factory=_instance_handler_factory(item_handler),
    -        )
    -    else:
    -        from traitsui.api import ListEditor
    -
    -        return ListEditor(
    -            trait_handler=handler,
    -            rows=trait.rows if trait.rows else 5,
    -            use_notebook=bool(trait.use_notebook),
    -            page_name=trait.page_name if trait.page_name else "",
    -        )
    -
    -
    -# -------------------------------------------------------------------------------
    -#  'CTrait' class (extends the underlying cTrait c-based type):
    -# -------------------------------------------------------------------------------
    -
    -
    -class CTrait(cTrait):
    -    """ Extends the underlying C-based cTrait type.
    -    """
    -
    -    # ---------------------------------------------------------------------------
    -    #  Allows a derivative trait to be defined from this one:
    -    # ---------------------------------------------------------------------------
    -
    -    def __call__(self, *args, **metadata):
    -        handler = self.handler
    -        if isinstance(handler, TraitType):
    -            dict = (self.__dict__ or {}).copy()
    -            dict.update(metadata)
    -
    -            return handler(*args, **dict)
    -
    -        metadata.setdefault("parent", self)
    -        return Trait(*(args + (self,)), **metadata)
    -
    -    # ---------------------------------------------------------------------------
    -    #  (Python) property definitions:
    -    # ---------------------------------------------------------------------------
    -
    -    def __get_default(self):
    -        kind, value = self.default_value()
    -        if kind in (2, 7, 8):
    -            return Undefined
    -
    -        if kind in (4, 6):
    -            return value.copy()
    -
    -        if kind in (3, 5):
    -            return value[:]
    -
    -        return value
    -
    -    default = property(__get_default)
    -
    -    def __get_default_kind(self):
    -        return KindMap[self.default_value()[0]]
    -
    -    default_kind = property(__get_default_kind)
    -
    -    def __get_trait_type(self):
    -        handler = self.handler
    -        if handler is not None:
    -            return handler
    -        else:
    -            from .trait_types import Any
    -
    -            return Any
    -
    -    trait_type = property(__get_trait_type)
    -
    -    def __get_inner_traits(self):
    -        handler = self.handler
    -        if handler is not None:
    -            return handler.inner_traits()
    -
    -        return ()
    -
    -    inner_traits = property(__get_inner_traits)
    -
    -    # ---------------------------------------------------------------------------
    -    #  Returns whether or not this trait is of a specified trait type:
    -    # ---------------------------------------------------------------------------
    -
    -    def is_trait_type(self, trait_type):
    -        """ Returns whether or not this trait is of a specified trait type.
    -        """
    -        return isinstance(self.trait_type, trait_type)
    -
    -    # ---------------------------------------------------------------------------
    -    #  Returns the user interface editor associated with the trait:
    -    # ---------------------------------------------------------------------------
    -
    -    def get_editor(self):
    -        """ Returns the user interface editor associated with the trait.
    -        """
    -        from traitsui.api import EditorFactory
    -
    -        # See if we have an editor:
    -        editor = self.editor
    -        if editor is None:
    -
    -            # Else see if the trait handler has an editor:
    -            handler = self.handler
    -            if handler is not None:
    -                editor = handler.get_editor(self)
    -
    -            # If not, give up and use a default text editor:
    -            if editor is None:
    -                from traitsui.api import TextEditor
    -
    -                editor = TextEditor
    -
    -        # If the result is not an EditorFactory:
    -        if not isinstance(editor, EditorFactory):
    -            # Then it should be a factory for creating them:
    -            args = ()
    -            traits = {}
    -            if type(editor) in SequenceTypes:
    -                for item in editor[:]:
    -                    if type(item) in SequenceTypes:
    -                        args = tuple(item)
    -                    elif isinstance(item, dict):
    -                        traits = item
    -                        if traits.get("trait", 0) is None:
    -                            traits = traits.copy()
    -                            traits["trait"] = self
    -                    else:
    -                        editor = item
    -            editor = editor(*args, **traits)
    -
    -        # Cache the result:
    -        self.editor = editor
    -
    -        # Return the resulting EditorFactory object:
    -        return editor
    -
    -    # ---------------------------------------------------------------------------
    -    #  Returns the help text for a trait:
    -    # ---------------------------------------------------------------------------
    -
    -    def get_help(self, full=True):
    -        """ Returns the help text for a trait.
    -
    -        Parameters
    -        ----------
    -        full : bool
    -            Indicates whether to return the value of the *help* attribute of
    -            the trait itself.
    -
    -        Description
    -        -----------
    -        If *full* is False or the trait does not have a **help** string,
    -        the returned string is constructed from the **desc** attribute on the
    -        trait and the **info** string on the trait's handler.
    -        """
    -        if full:
    -            help = self.help
    -            if help is not None:
    -                return help
    -
    -        handler = self.handler
    -        if handler is not None:
    -            info = "must be %s." % handler.info()
    -        else:
    -            info = "may be any value."
    -
    -        desc = self.desc
    -        if self.desc is None:
    -            return info.capitalize()
    -
    -        return "Specifies %s and %s" % (desc, info)
    -
    -    # ---------------------------------------------------------------------------
    -    #  Returns a description of the trait:
    -    # ---------------------------------------------------------------------------
    -
    -    def full_info(self, object, name, value):
    -        """ Returns a description of the trait.
    -        """
    -        handler = self.handler
    -        if handler is not None:
    -            return handler.full_info(object, name, value)
    -
    -        return "any value"
    -
    -    # ---------------------------------------------------------------------------
    -    #  Returns a description of the trait:
    -    # ---------------------------------------------------------------------------
    -
    -    def info(self):
    -        """ Returns a description of the trait.
    -        """
    -        handler = self.handler
    -        if handler is not None:
    -            return handler.info()
    -
    -        return "any value"
    -
    -    # ---------------------------------------------------------------------------
    -    #  Returns the pickleable form of a CTrait object:
    -    # ---------------------------------------------------------------------------
    -
    -    def __reduce_ex__(self, protocol):
    -        return (__newobj__, (self.__class__, 0), self.__getstate__())
    -
    -    # ---------------------------------------------------------------------------
    -    #  Registers listeners on an assigned 'TraitValue' object's 'value'
    -    #  property:
    -    # ---------------------------------------------------------------------------
    -
    -    def _register(self, object, name):
    -        """ Registers listeners on an assigned 'TraitValue' object's 'value'
    -            property.
    -        """
    -
    -        def handler():
    -            object.trait_property_changed(name, None)
    -
    -        tv = self._trait_value
    -        handlers = tv._handlers
    -        if handlers is None:
    -            tv._handlers = handlers = {}
    -        handlers[(id(object), name)] = handler
    -
    -        tv.on_trait_change(handler, "value")
    -
    -    # ---------------------------------------------------------------------------
    -    #  Unregisters listeners on an assigned 'TraitValue' object's 'value'
    -    #  property:
    -    # ---------------------------------------------------------------------------
    -
    -    def _unregister(self, object, name):
    -        """ Unregisters listeners on an assigned 'TraitValue' object's 'value'
    -            property.
    -        """
    -        tv = self._trait_value
    -        handlers = tv._handlers
    -        key = (id(object), name)
    -        handler = handlers.get(key)
    -        if handler is not None:
    -            del handlers[key]
    -            tv.on_trait_change(handler, "value", remove=True)
    -
    -
    -# Make sure the Python-level version of the trait class is known to all
    -# interested parties:
    -from . import ctraits
    -
    -ctraits._ctrait(CTrait)
    -
    -# -------------------------------------------------------------------------------
    -#  Constants:
    -# -------------------------------------------------------------------------------
    +NoneType = type(None)  # Python 3's types does not include NoneType
     
    -ConstantTypes = (NoneType, int, LONG_TYPE, float, complex, str, six.text_type)
    +ConstantTypes = (NoneType, int, float, complex, str)
     
     PythonTypes = (
         str,
    -    six.text_type,
         int,
    -    LONG_TYPE,
         float,
         complex,
         list,
    @@ -653,23 +174,13 @@ 

    Source code for traits.traits

         NoneType,
     )
     
    -if six.PY2:
    -    from types import InstanceType, ClassType
    -
    -    PythonTypes = (
    -        PythonTypes[:-2] + (InstanceType, ClassType) + PythonTypes[2:]
    -    )
    -
    -
     CallableTypes = (FunctionType, MethodType)
     
     TraitTypes = (TraitHandler, CTrait)
     
     DefaultValues = {
         str: "",
    -    six.text_type: "",
         int: 0,
    -    LONG_TYPE: LONG_TYPE(0),
         float: 0.0,
         complex: 0j,
         list: [],
    @@ -678,13 +189,11 @@ 

    Source code for traits.traits

         bool: False,
     }
     
    -DefaultValueSpecial = [Missing, Self]
    -DefaultValueTypes = [list, dict]
    -
    -# -------------------------------------------------------------------------------
    -#  Function used to unpickle new-style objects:
    -# -------------------------------------------------------------------------------
     
    +# This function is needed when unpickling historical pickles (pickles
    +# created on versions of Traits prior to 6.0). It can be removed when
    +# there's no longer any need to support pickles generated on older
    +# versions of Traits.
     
     def __newobj__(cls, *args):
         """ Unpickles new-style objects.
    @@ -692,152 +201,7 @@ 

    Source code for traits.traits

         return cls.__new__(cls, *args)
     
     
    -# -------------------------------------------------------------------------------
    -#  Returns the type of default value specified:
    -# -------------------------------------------------------------------------------
    -
    -
    -def _default_value_type(default_value):
    -    try:
    -        return DefaultValueSpecial.index(default_value) + 1
    -    except:
    -        try:
    -            return DefaultValueTypes.index(type(default_value)) + 3
    -        except:
    -            return 0
    -
    -
    -# -------------------------------------------------------------------------------
    -#  'TraitFactory' class:
    -# -------------------------------------------------------------------------------
    -
    -
    -class TraitFactory(object):
    -    ### Need a docstring here.
    -
    -    # ---------------------------------------------------------------------------
    -    #  Initializes the object:
    -    # ---------------------------------------------------------------------------
    -
    -    def __init__(self, maker_function=None):
    -        if maker_function is not None:
    -            self.maker_function = maker_function
    -            self.__doc__ = maker_function.__doc__
    -
    -    # ---------------------------------------------------------------------------
    -    #  Creates a CTrait instance:
    -    # ---------------------------------------------------------------------------
    -
    -    def __call__(self, *args, **metadata):
    -        return self.maker_function(*args, **metadata)
    -
    -
    -class TraitImportError(TraitFactory):
    -    """ Defines a factory class for deferring import problems until encountering
    -        code that actually tries to use the unimportable trait.
    -    """
    -
    -    # ---------------------------------------------------------------------------
    -    #  Initializes the object:
    -    # ---------------------------------------------------------------------------
    -
    -    def __init__(self, message):
    -        self.message = message
    -
    -    # ---------------------------------------------------------------------------
    -    #  Creates a CTrait instance:
    -    # ---------------------------------------------------------------------------
    -
    -    def __call__(self, *args, **metadata):
    -        raise TraitError(self.message)
    -
    -
    -# -------------------------------------------------------------------------------
    -#  Returns a trait created from a TraitFactory instance:
    -# -------------------------------------------------------------------------------
    -
    -_trait_factory_instances = {}
    -
    -
    -def trait_factory(trait):
    -    global _trait_factory_instances
    -
    -    tid = id(trait)
    -    if tid not in _trait_factory_instances:
    -        _trait_factory_instances[tid] = trait()
    -
    -    return _trait_factory_instances[tid]
    -
    -
    -# -------------------------------------------------------------------------------
    -#  Casts a CTrait or TraitFactory to a CTrait but returns None if it is neither:
    -# -------------------------------------------------------------------------------
    -
    -
    -def trait_cast(something):
    -    """ Casts a CTrait, TraitFactory or TraitType to a CTrait but returns None
    -        if it is none of those.
    -    """
    -    if isinstance(something, CTrait):
    -        return something
    -
    -    if isinstance(something, TraitFactory):
    -        return trait_factory(something)
    -
    -    if isinstance(something, type) and issubclass(something, TraitType):
    -        return something().as_ctrait()
    -
    -    if isinstance(something, TraitType):
    -        return something.as_ctrait()
    -
    -    return None
    -
    -
    -# -------------------------------------------------------------------------------
    -#  Attempts to cast a value to a trait. Returns either a trait or the original
    -#  value:
    -# -------------------------------------------------------------------------------
    -
    -
    -def try_trait_cast(something):
    -    """ Attempts to cast a value to a trait. Returns either a trait or the
    -        original value.
    -    """
    -    return trait_cast(something) or something
    -
    -
    -# -------------------------------------------------------------------------------
    -#  Returns a trait derived from its input:
    -# -------------------------------------------------------------------------------
    -
    -
    -def trait_from(something):
    -    """ Returns a trait derived from its input.
    -    """
    -    from .trait_types import Any
    -
    -    if isinstance(something, CTrait):
    -        return something
    -
    -    if something is None:
    -        something = Any
    -
    -    if isinstance(something, TraitFactory):
    -        return trait_factory(something)
    -
    -    if isinstance(something, type) and issubclass(something, TraitType):
    -        return something().as_ctrait()
    -
    -    if isinstance(something, TraitType):
    -        return something.as_ctrait()
    -
    -    return Trait(something)
    -
    -
    -# Patch the reference to 'trait_from' in 'trait_handlers.py':
    -trait_handlers.trait_from = trait_from
    -
    -# --- 'instance' traits ---------------------------------------------------------
    +# --- 'instance' traits -------------------------------------------------------
     
     
     class _InstanceArgs(object):
    @@ -846,7 +210,7 @@ 

    Source code for traits.traits

             self.kw = kw
     
     
    -# --- 'creates a run-time default value' ----------------------------------------
    +# --- 'creates a run-time default value' --------------------------------------
     
     
     class Default(object):
    @@ -860,16 +224,9 @@ 

    Source code for traits.traits

             self.default_value = (func, args, kw)
     
     
    -# -------------------------------------------------------------------------------
    -#  Factory function for creating C-based traits:
    -# -------------------------------------------------------------------------------
    -
    -
     def Trait(*value_type, **metadata):
         """ Creates a trait definition.
     
    -    Parameters
    -    ----------
         This function accepts a variety of forms of parameter lists:
     
         +-------------------+---------------+-------------------------------------+
    @@ -948,8 +305,6 @@ 

    Source code for traits.traits

     
         The following predefined keywords are accepted:
     
    -    Keywords
    -    --------
         desc : str
             Describes the intended meaning of the trait. It is used in
             exception messages and fly-over help in user interfaces.
    @@ -961,60 +316,34 @@ 

    Source code for traits.traits

             interface editor for the trait. See the "Traits UI User Guide" for
             more information on trait editors.
         comparison_mode : int
    -        Indicates when trait change notifications should be generated based upon
    -        the result of comparing the old and new values of a trait assignment:
    +        Indicates when trait change notifications should be generated based
    +        upon the result of comparing the old and new values of a trait
    +        assignment. Possible values come from the ``ComparisonMode`` enum:
     
    -        * 0 (NO_COMPARE): The values are not compared and a trait change
    +        * 0 (none): The values are not compared and a trait change
               notification is generated on each assignment.
    -        * 1 (OBJECT_IDENTITY_COMPARE): A trait change notification is
    +        * 1 (identity): A trait change notification is
               generated if the old and new values are not the same object.
    -        * 2 (RICH_COMPARE): A trait change notification is generated if the
    -          old and new values are not equal using Python's
    -          'rich comparison' operator. This is the default.
    -
    -    rich_compare : bool
    -        Indicates whether the basis for considering a trait attribute value to
    -        have changed is a "rich" comparison (True, the default), or simple
    -        object identity (False). This attribute can be useful in cases
    -        where a detailed comparison of two objects is very expensive, or where
    -        you do not care whether the details of an object change, as long as the
    -        same object is used.
    -
    -            .. deprecated:: 3.0.3
    -                Use ``comparison_mode`` instead
    -
    +        * 2 (equality): A trait change notification is generated if the
    +          old and new values are not equal using Python's standard equality
    +          testing. This is the default.
     
         """
         return _TraitMaker(*value_type, **metadata).as_ctrait()
     
     
    -#  Handle circular module dependencies:
    -trait_handlers.Trait = Trait
    -
    -# -------------------------------------------------------------------------------
    -#  '_TraitMaker' class:
    -# -------------------------------------------------------------------------------
    -
    -
     class _TraitMaker(object):
     
         # Ctrait type map for special trait types:
    -    type_map = {"event": 2, "constant": 7}
    -
    -    # ---------------------------------------------------------------------------
    -    #  Initialize the object:
    -    # ---------------------------------------------------------------------------
    +    type_map = {"event": TraitKind.event, "constant": TraitKind.constant}
     
         def __init__(self, *value_type, **metadata):
             metadata.setdefault("type", "trait")
             self.define(*value_type, **metadata)
     
    -    # ---------------------------------------------------------------------------
    -    #  Define the trait:
    -    # ---------------------------------------------------------------------------
    -
         def define(self, *value_type, **metadata):
    -        default_value_type = UNSPECIFIED_DEFAULT_VALUE
    +        """ Define the trait. """
    +        default_value_type = DefaultValue.unspecified
             default_value = handler = clone = None
     
             if len(value_type) > 0:
    @@ -1042,23 +371,9 @@ 

    Source code for traits.traits

                         handler = default_value
                         default_value = None
     
    -                elif default_value is ThisClass:
    -                    handler = ThisClass()
    -                    default_value = None
    -
                     else:
                         typeValue = type(default_value)
    -
    -                    if isinstance(default_value, six.string_types):
    -                        string_options = self.extract(
    -                            metadata, "min_len", "max_len", "regex"
    -                        )
    -                        if len(string_options) == 0:
    -                            handler = TraitCastType(typeValue)
    -                        else:
    -                            handler = TraitString(**string_options)
    -
    -                    elif typeValue in TypeTypes:
    +                    if typeValue in TypeTypes:
                             handler = TraitCastType(typeValue)
     
                         else:
    @@ -1112,7 +427,7 @@ 

    Source code for traits.traits

     
                             elif isinstance(default_value, _InstanceArgs):
                                 default_value_type = (
    -                                CALLABLE_AND_ARGS_DEFAULT_VALUE
    +                                DefaultValue.callable_and_args
                                 )
                                 default_value = (
                                     handler.create_default_value,
    @@ -1126,14 +441,14 @@ 

    Source code for traits.traits

     
                                 if typeValue is dict:
                                     default_value_type = (
    -                                    CALLABLE_AND_ARGS_DEFAULT_VALUE
    +                                    DefaultValue.callable_and_args
                                     )
                                     default_value = (aClass, (), default_value)
                                 elif not isinstance(default_value, aClass):
                                     if typeValue is not tuple:
                                         default_value = (default_value,)
                                     default_value_type = (
    -                                    CALLABLE_AND_ARGS_DEFAULT_VALUE
    +                                    DefaultValue.callable_and_args
                                     )
                                     default_value = (aClass, default_value, None)
                     else:
    @@ -1158,7 +473,7 @@ 

    Source code for traits.traits

     
             if default_value_type < 0:
                 if isinstance(default_value, Default):
    -                default_value_type = CALLABLE_AND_ARGS_DEFAULT_VALUE
    +                default_value_type = DefaultValue.callable_and_args
                     default_value = default_value.default_value
                 else:
                     if (handler is None) and (clone is not None):
    @@ -1175,17 +490,16 @@ 

    Source code for traits.traits

                                 pass
     
                     if default_value_type < 0:
    -                    default_value_type = _default_value_type(default_value)
    +                    default_value_type = _infer_default_value_type(
    +                        default_value
    +                    )
     
             self.default_value_type = default_value_type
             self.default_value = default_value
             self.metadata = metadata.copy()
     
    -    # ---------------------------------------------------------------------------
    -    #  Determine the correct TraitHandler for each item in a list:
    -    # ---------------------------------------------------------------------------
    -
         def do_list(self, list, enum, map, other):
    +        """ Determine the correct TraitHandler for each item in a list. """
             for item in list:
                 if item in PythonTypes:
                     other.append(TraitCoerceType(item))
    @@ -1205,29 +519,24 @@ 

    Source code for traits.traits

                     elif typeItem in CallableTypes:
                         other.append(TraitFunction(item))
     
    -                elif item is ThisClass:
    -                    other.append(ThisClass())
    -
                     elif isinstance(item, TraitTypes):
                         other.append(item)
     
                     else:
                         other.append(TraitInstance(item))
     
    -    # ---------------------------------------------------------------------------
    -    #  Returns a properly initialized 'CTrait' instance:
    -    # ---------------------------------------------------------------------------
    -
         def as_ctrait(self):
    +        """ Return a properly initialized 'CTrait' instance. """
             metadata = self.metadata
    -        trait = CTrait(self.type_map.get(metadata.get("type"), 0))
    +        trait = CTrait(
    +            self.type_map.get(metadata.get("type"), TraitKind.trait))
             clone = self.clone
             if clone is not None:
                 trait.clone(clone)
                 if clone.__dict__ is not None:
                     trait.__dict__ = clone.__dict__.copy()
     
    -        trait.default_value(self.default_value_type, self.default_value)
    +        trait.set_default_value(self.default_value_type, self.default_value)
     
             handler = self.handler
             if handler is not None:
    @@ -1240,19 +549,26 @@ 

    Source code for traits.traits

                 post_setattr = getattr(handler, "post_setattr", None)
                 if post_setattr is not None:
                     trait.post_setattr = post_setattr
    -                trait.is_mapped(handler.is_mapped)
    +                trait.is_mapped = handler.is_mapped
     
    -        # Note: The use of 'rich_compare' metadata is deprecated; use
    -        # 'comparison_mode' metadata instead:
             rich_compare = metadata.get("rich_compare")
             if rich_compare is not None:
    -            trait.rich_comparison(rich_compare is True)
    +            # Ref: enthought/traits#602
    +            warnings.warn(
    +                "The 'rich_compare' metadata has been deprecated. Please "
    +                "use the 'comparison_mode' metadata instead. In a future "
    +                "release, rich_compare will have no effect.",
    +                DeprecationWarning,
    +                stacklevel=4,
    +            )
    +            if rich_compare:
    +                trait.comparison_mode = ComparisonMode.equality
    +            else:
    +                trait.comparison_mode = ComparisonMode.identity
     
    -        comparison_mode = metadata.get("comparison_mode")
    +        comparison_mode = metadata.pop("comparison_mode", None)
             if comparison_mode is not None:
    -            trait.comparison_mode(comparison_mode)
    -
    -        trait.value_allowed(metadata.get("trait_value", False) is True)
    +            trait.comparison_mode = comparison_mode
     
             if len(metadata) > 0:
                 if trait.__dict__ is None:
    @@ -1262,23 +578,6 @@ 

    Source code for traits.traits

     
             return trait
     
    -    # ---------------------------------------------------------------------------
    -    #  Extract a set of keywords from a dictionary:
    -    # ---------------------------------------------------------------------------
    -
    -    def extract(self, from_dict, *keys):
    -        to_dict = {}
    -        for key in keys:
    -            if key in from_dict:
    -                to_dict[key] = from_dict[key]
    -                del from_dict[key]
    -        return to_dict
    -
    -
    -# -------------------------------------------------------------------------------
    -#  Factory function for creating C-based trait properties:
    -# -------------------------------------------------------------------------------
    -
     
     def Property(
         fget=None,
    @@ -1291,26 +590,6 @@ 

    Source code for traits.traits

     ):
         """ Returns a trait whose value is a Python property.
     
    -    Parameters
    -    ----------
    -    fget : function
    -        The "getter" function for the property.
    -    fset : function
    -        The "setter" function for the property.
    -    fvalidate : function
    -        The validation function for the property. The method should return the
    -        value to set or raise TraitError if the new value is not valid.
    -    force : bool
    -        Indicates whether to use only the function definitions specified by
    -        **fget** and **fset**, and not look elsewhere on the class.
    -    handler : function
    -        A trait handler function for the trait.
    -    trait : Trait or value
    -        A trait definition or a value that can be converted to a trait that
    -        constrains the values of the property trait.
    -
    -    Description
    -    -----------
         If no getter, setter or validate functions are specified (and **force** is
         not True), it is assumed that they are defined elsewhere on the class whose
         attribute this trait is assigned to. For example::
    @@ -1345,8 +624,26 @@ 

    Source code for traits.traits

                 axle     = Instanced( Axle )
                 position = Property( depends_on = 'axle.chassis.position' )
     
    -    For details of the extended trait name syntax, refer to the on_trait_change()
    -    method of the HasTraits class.
    +    For details of the extended trait name syntax, refer to the
    +    on_trait_change() method of the HasTraits class.
    +
    +    Parameters
    +    ----------
    +    fget : function
    +        The "getter" function for the property.
    +    fset : function
    +        The "setter" function for the property.
    +    fvalidate : function
    +        The validation function for the property. The method should return the
    +        value to set or raise TraitError if the new value is not valid.
    +    force : bool
    +        Indicates whether to use only the function definitions specified by
    +        **fget** and **fset**, and not look elsewhere on the class.
    +    handler : function
    +        A trait handler function for the trait.
    +    trait : Trait or value
    +        A trait definition or a value that can be converted to a trait that
    +        constrains the values of the property trait.
         """
         metadata["type"] = "property"
     
    @@ -1404,15 +701,9 @@ 

    Source code for traits.traits

         ):
             metadata.setdefault("cached", True)
     
    -    n = 0
    -    trait = CTrait(4)
    +    trait = CTrait(TraitKind.property)
         trait.__dict__ = metadata.copy()
    -    if fvalidate is not None:
    -        n = _arg_count(fvalidate)
    -
    -    trait.property(
    -        fget, _arg_count(fget), fset, _arg_count(fset), fvalidate, n
    -    )
    +    trait.property_fields = (fget, fset, fvalidate)
         trait.handler = handler
     
         return trait
    @@ -1432,59 +723,22 @@ 

    Source code for traits.traits

             self.handler = handler
     
     
    -# -------------------------------------------------------------------------------
    -#  Dictionary used to handle return type mapping special cases:
    -# -------------------------------------------------------------------------------
    -
    -SpecialNames = {
    -    ###   'int':     trait_factory( Int ),
    -    ###   'long':    trait_factory( Long ),
    -    ###   'float':   trait_factory( Float ),
    -    ###   'complex': trait_factory( Complex ),
    -    ###   'str':     trait_factory( Str ),
    -    ###   'unicode': trait_factory( Unicode ),
    -    ###   'bool':    trait_factory( Bool ),
    -    ###   'list':    trait_factory( List ),
    -    ###   'tuple':   trait_factory( Tuple ),
    -    ###   'dict':    trait_factory( Dict )
    -}
    -
    -
    -# -- Date Trait definition ----------------------------------------------------
    -# Date = Instance(datetime.date, metadata = { 'editor': date_editor })
    -
    -
    -# -- Time Trait definition ----------------------------------------------------
    -# Time = Instance(datetime.time, metadata = { 'editor': time_editor })
    -
    -
    -# -------------------------------------------------------------------------------
    -#  Create predefined, reusable trait instances:
    -# -------------------------------------------------------------------------------
    +# Predefined, reusable trait instances
     
     # Generic trait with 'object' behavior:
    -generic_trait = CTrait(8)
    +generic_trait = CTrait(TraitKind.generic)
     
    -# -------------------------------------------------------------------------------
    -#  User interface related color and font traits:
    -# -------------------------------------------------------------------------------
     
    +# User interface related color and font traits
     
    +@deprecated("'Color' in 'traits' package has been deprecated. "
    +            "Use 'Color' from 'traitsui' package instead.")
     def Color(*args, **metadata):
         """ Returns a trait whose value must be a GUI toolkit-specific color.
     
    -    Description
    -    -----------
    -    For wxPython, the returned trait accepts any of the following values:
    -
    -    * A wx.Colour instance
    -    * A wx.ColourPtr instance
    -    * an integer whose hexadecimal form is 0x*RRGGBB*, where *RR* is the red
    -      value, *GG* is the green value, and *BB* is the blue value
    -
    -    Default Value
    -    -------------
    -    For wxPython, 0xffffff (that is, white)
    +    .. deprecated:: 6.1.0
    +        ``Color`` trait in this package will be removed in the future. It is
    +        replaced by ``Color`` trait in TraitsUI package.
         """
         from traitsui.toolkit_traits import ColorTrait
     
    @@ -1494,23 +748,15 @@ 

    Source code for traits.traits

     Color = TraitFactory(Color)
     
     
    +@deprecated("'RGBColor' in 'traits' package has been deprecated. "
    +            "Use 'RGBColor' from 'traitsui' package instead.")
     def RGBColor(*args, **metadata):
         """ Returns a trait whose value must be a GUI toolkit-specific RGB-based
    -        color.
    +    color.
     
    -    Description
    -    -----------
    -    For wxPython, the returned trait accepts any of the following values:
    -
    -    * A tuple of the form (*r*, *g*, *b*), in which *r*, *g*, and *b* represent
    -      red, green, and blue values, respectively, and are floats in the range
    -      from 0.0 to 1.0
    -    * An integer whose hexadecimal form is 0x*RRGGBB*, where *RR* is the red
    -      value, *GG* is the green value, and *BB* is the blue value
    -
    -    Default Value
    -    -------------
    -    For wxPython, (1.0, 1.0, 1.0) (that is, white)
    +    .. deprecated:: 6.1.0
    +        ``RGBColor`` trait in this package will be removed in the future. It is
    +        replaced by ``RGBColor`` trait in TraitsUI package.
         """
         from traitsui.toolkit_traits import RGBColorTrait
     
    @@ -1520,21 +766,14 @@ 

    Source code for traits.traits

     RGBColor = TraitFactory(RGBColor)
     
     
    +@deprecated("'Font' in 'traits' package has been deprecated. "
    +            "Use 'Font' from 'traitsui' package instead.")
     def Font(*args, **metadata):
         """ Returns a trait whose value must be a GUI toolkit-specific font.
     
    -    Description
    -    -----------
    -    For wxPython, the returned trait accepts any of the following:
    -
    -    * a wx.Font instance
    -    * a wx.FontPtr instance
    -    * a string describing the font, including one or more of the font family,
    -      size, weight, style, and typeface name.
    -
    -    Default Value
    -    -------------
    -    For wxPython, 'Arial 10'
    +    .. deprecated:: 6.1.0
    +        ``Font`` trait in this package will be removed in the future. It is
    +        replaced by ``Font`` trait in TraitsUI package.
         """
         from traitsui.toolkit_traits import FontTrait
     
    @@ -1553,13 +792,11 @@ 

    Source code for traits.traits

                   
                 

    @@ -1583,10 +820,10 @@

    Quick search

    © Copyright 2008-2020, Enthought
  • - Last updated on Jun 12, 2020. + Last updated on Dec 17, 2020.
  • - Created using Sphinx 1.8.5. + Created using Sphinx 2.3.1.
  • diff --git a/_modules/traitsui/editors/code_editor.html b/_modules/traitsui/editors/code_editor.html index 8761b3bb4..ae28fc000 100644 --- a/_modules/traitsui/editors/code_editor.html +++ b/_modules/traitsui/editors/code_editor.html @@ -13,9 +13,11 @@ @@ -72,16 +74,16 @@
    -
    +

    Source code for traitsui.editors.code_editor

    -#------------------------------------------------------------------------------
    +# ------------------------------------------------------------------------------
     #
     #  Copyright (c) 2008, Enthought, Inc.
     #  All rights reserved.
     #
     #  This software is provided without warranty under the terms of the BSD
    -#  license included in enthought/LICENSE.txt and may be redistributed only
    +#  license included in LICENSE.txt and may be redistributed only
     #  under the conditions described in the aforementioned license.  The license
     #  is also available online at http://www.enthought.com/licenses/BSD.txt
     #
    @@ -90,110 +92,105 @@ 

    Source code for traitsui.editors.code_editor

    #  Author: David C. Morrill
     #  Date:   01/27/2006
     #
    -#------------------------------------------------------------------------------
    +# ------------------------------------------------------------------------------
     
     """ Defines the code editor factory for all traits toolkit backends,
     useful for tools such as debuggers.
     """
     
    -#-------------------------------------------------------------------------
    -#  Imports:
    -#-------------------------------------------------------------------------
     
    -from __future__ import absolute_import
     
    -from traits.api import Instance, Str, Color, Enum, Bool
    +from traits.api import Instance, Str, Enum, Bool
     
     from ..editor_factory import EditorFactory
    +from ..toolkit_traits import Color
     
    -#-------------------------------------------------------------------------
    +# -------------------------------------------------------------------------
     #  'ToolkitEditorFactory' class:
    -#-------------------------------------------------------------------------
    +# -------------------------------------------------------------------------
     
     
     class ToolkitEditorFactory(EditorFactory):
         """ Editor factory for code editors.
         """
     
    -    #-------------------------------------------------------------------------
    +    # -------------------------------------------------------------------------
         #  Trait definitions:
    -    #-------------------------------------------------------------------------
    +    # -------------------------------------------------------------------------
     
    -    # Object trait containing list of line numbers to mark (optional)
    -    mark_lines = Str
    +    #: Object trait containing list of line numbers to mark (optional)
    +    mark_lines = Str()
     
    -    # Background color for marking lines
    +    #: Background color for marking lines
         mark_color = Color(0xECE9D8)
     
    -    # Object trait containing the currently selected line (optional)
    -    selected_line = Str
    +    #: Object trait containing the currently selected line (optional)
    +    selected_line = Str()
     
    -    # Object trait containing the currently selected text (optional)
    -    selected_text = Str
    +    #: Object trait containing the currently selected text (optional)
    +    selected_text = Str()
     
    -    # Object trait containing the currently selected text start position
    -    # (optional)
    -    selected_start_pos = Str
    +    #: Object trait containing the currently selected text start position
    +    #: (optional)
    +    selected_start_pos = Str()
     
    -    # Object trait containing the currently selected text end position
    -    # (optional)
    -    selected_end_pos = Str
    +    #: Object trait containing the currently selected text end position
    +    #: (optional)
    +    selected_end_pos = Str()
     
    -    # Background color for selected lines
    +    #: Background color for selected lines
         selected_color = Color(0xA4FFFF)
     
    -    # Where should the search toolbar be placed?
    -    search = Enum('top', 'bottom', 'none')
    +    #: Where should the search toolbar be placed?
    +    search = Enum("top", "bottom", "none")
     
    -    # Background color for lines that match the current search
    +    #: Background color for lines that match the current search
         search_color = Color(0xFFFF94)
     
    -    # Current line
    -    line = Str
    +    #: Current line
    +    line = Str()
     
    -    # Current column
    -    column = Str
    +    #: Current column
    +    column = Str()
     
    -    # Should code folding be enabled?
    +    #: Should code folding be enabled?
         foldable = Bool(True)
     
    -    # Should line numbers be displayed in the margin?
    +    #: Should line numbers be displayed in the margin?
         show_line_numbers = Bool(True)
     
    -    # Is user input set on every change?
    +    #: Is user input set on every change?
         auto_set = Bool(True)
     
    -    # Should the editor auto-scroll when a new **selected_line** value is set?
    +    #: Should the editor auto-scroll when a new **selected_line** value is set?
         auto_scroll = Bool(True)
     
    -    # Optional key bindings associated with the editor
    -    key_bindings = Instance('traitsui.key_bindings.KeyBindings')
    +    #: Optional key bindings associated with the editor
    +    key_bindings = Instance("traitsui.key_bindings.KeyBindings")
     
    -    # Calltip clicked event
    -    calltip_clicked = Str
    +    #: Calltip clicked event
    +    calltip_clicked = Str()
     
    -    # The lexer to use. Default is 'python'; 'null' indicates no lexing.
    -    lexer = Str('python')
    +    #: The lexer to use. Default is 'python'; 'null' indicates no lexing.
    +    lexer = Str("python")
     
    -    # Object trait containing the list of line numbers to dim (optional)
    -    dim_lines = Str
    +    #: Object trait containing the list of line numbers to dim (optional)
    +    dim_lines = Str()
     
    -    # Object trait to dim lines to. Can be of form #rrggbb or a color spec. If
    -    # not specified, dark grey is used.
    -    dim_color = Str
    +    #: Object trait to dim lines to. Can be of form #rrggbb or a color spec. If
    +    #: not specified, dark grey is used.
    +    dim_color = Str()
     
    -    # Object trait containing the list of line numbers to put squiggles under
    -    # (optional)
    -    squiggle_lines = Str
    +    #: Object trait containing the list of line numbers to put squiggles under
    +    #: (optional)
    +    squiggle_lines = Str()
     
    -    # Object trait for the color of squiggles. If not specified, red is used.
    -    squiggle_color = Str
    +    #: Object trait for the color of squiggles. If not specified, red is used.
    +    squiggle_color = Str()
     
     
     # Define the Code Editor class.
     CodeEditor = ToolkitEditorFactory
    -
    -### EOF #######################################################################
     
    @@ -205,13 +202,11 @@

    Source code for traitsui.editors.code_editor

    diff --git a/_modules/traitsui/editors/tabular_editor.html b/_modules/traitsui/editors/tabular_editor.html index f58e43228..a6db5e448 100644 --- a/_modules/traitsui/editors/tabular_editor.html +++ b/_modules/traitsui/editors/tabular_editor.html @@ -13,9 +13,11 @@ @@ -72,16 +74,16 @@
    -
    +

    Source code for traitsui.editors.tabular_editor

    -#-------------------------------------------------------------------------
    +# -------------------------------------------------------------------------
     #
     #  Copyright (c) 2007, Enthought, Inc.
     #  All rights reserved.
     #
     #  This software is provided without warranty under the terms of the BSD
    -#  license included in enthought/LICENSE.txt and may be redistributed only
    +#  license included in LICENSE.txt and may be redistributed only
     #  under the conditions described in the aforementioned license.  The license
     #  is also available online at http://www.enthought.com/licenses/BSD.txt
     #
    @@ -90,17 +92,13 @@ 

    Source code for traitsui.editors.tabular_editor

    < # Author: David C. Morrill # Date: 05/20/2007 # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- """ A traits UI editor for editing tabular data (arrays, list of tuples, lists of objects, etc). """ -#------------------------------------------------------------------------- -# Imports: -#------------------------------------------------------------------------- -from __future__ import absolute_import from pyface.ui_traits import Image from traits.api import Str, Bool, Property, List, Enum, Instance @@ -109,141 +107,137 @@

    Source code for traitsui.editors.tabular_editor

    < from ..toolkit import toolkit_object -#------------------------------------------------------------------------- -# 'TabularEditor' editor factory class: -#------------------------------------------------------------------------- - class TabularEditor(BasicEditorFactory): """ Editor factory for tabular editors. """ - #-- Trait Definitions ---------------------------------------------------- + # -- Trait Definitions ---------------------------------------------------- - # The editor class to be created: - klass = Property + #: The editor class to be created: + klass = Property() - # Should column headers (i.e. titles) be displayed? + #: Should column headers (i.e. titles) be displayed? show_titles = Bool(True) - # Should row headers be displated (Qt4 only)? + #: Should row headers be displayed (Qt4 only)? show_row_titles = Bool(False) - # The optional extended name of the trait used to indicate that a complete - # table update is needed: - update = Str + #: The optional extended name of the trait used to indicate that a complete + #: table update is needed: + update = Str() - # The optional extended name of the trait used to indicate that the table - # just needs to be repainted. - refresh = Str + #: The optional extended name of the trait used to indicate that the table + #: just needs to be repainted. + refresh = Str() - # Should the table update automatically when the table item's contents - # change? Note that in order for this feature to work correctly, the editor - # trait should be a list of objects derived from HasTraits. Also, - # performance can be affected when very long lists are used, since enabling - # this feature adds and removed Traits listeners to each item in the list. + #: Should the table update automatically when the table item's contents + #: change? Note that in order for this feature to work correctly, the editor + #: trait should be a list of objects derived from HasTraits. Also, + #: performance can be affected when very long lists are used, since enabling + #: this feature adds and removed Traits listeners to each item in the list. auto_update = Bool(False) - # The optional extended name of the trait to synchronize the selection - # values with: - selected = Str + #: The optional extended name of the trait to synchronize the selection + #: values with: + selected = Str() - # The optional extended name of the trait to synchronize the selection rows - # with: - selected_row = Str + #: The optional extended name of the trait to synchronize the selection rows + #: with: + selected_row = Str() - # Whether or not to allow selection. + #: Whether or not to allow selection. selectable = Bool(True) - # The optional extended name of the trait to synchronize the activated value - # with: - activated = Str + #: The optional extended name of the trait to synchronize the activated value + #: with: + activated = Str() - # The optional extended name of the trait to synchronize the activated - # value's row with: - activated_row = Str + #: The optional extended name of the trait to synchronize the activated + #: value's row with: + activated_row = Str() - # The optional extended name of the trait to synchronize left click data - # with. The data is a TabularEditorEvent: - clicked = Str + #: The optional extended name of the trait to synchronize left click data + #: with. The data is a TabularEditorEvent: + clicked = Str() - # The optional extended name of the trait to synchronize left double click - # data with. The data is a TabularEditorEvent: - dclicked = Str + #: The optional extended name of the trait to synchronize left double click + #: data with. The data is a TabularEditorEvent: + dclicked = Str() - # The optional extended name of the trait to synchronize right click data - # with. The data is a TabularEditorEvent: - right_clicked = Str + #: The optional extended name of the trait to synchronize right click data + #: with. The data is a TabularEditorEvent: + right_clicked = Str() - # The optional extended name of the trait to synchronize right double - # clicked data with. The data is a TabularEditorEvent: - right_dclicked = Str + #: The optional extended name of the trait to synchronize right double + #: clicked data with. The data is a TabularEditorEvent: + right_dclicked = Str() - # The optional extended name of the trait to synchronize column - # clicked data with. The data is a TabularEditorEvent: - column_clicked = Str + #: The optional extended name of the trait to synchronize column + #: clicked data with. The data is a TabularEditorEvent: + column_clicked = Str() - # The optional extended name of the trait to synchronize column - # right clicked data with. The data is a TabularEditorEvent: - column_right_clicked = Str + #: The optional extended name of the trait to synchronize column + #: right clicked data with. The data is a TabularEditorEvent: + column_right_clicked = Str() - # The optional extended name of the Event trait that should be used to - # trigger a scroll-to command. The data is an integer giving the row. - scroll_to_row = Str + #: The optional extended name of the Event trait that should be used to + #: trigger a scroll-to command. The data is an integer giving the row. + scroll_to_row = Str() - # The optional extended name of the Event trait that should be used to - # trigger a scroll-to command. The data is an integer giving the column. - scroll_to_column = Str + #: The optional extended name of the Event trait that should be used to + #: trigger a scroll-to command. The data is an integer giving the column. + scroll_to_column = Str() - # Controls behavior of scroll to row + #: Controls behavior of scroll to row scroll_to_row_hint = Enum("center", "top", "bottom", "visible") - # Can the user edit the values? + #: Can the user edit the values? editable = Bool(True) - # Can the user edit the labels (i.e. the first column) + #: Can the user edit the labels (i.e. the first column) editable_labels = Bool(False) - # Are multiple selected items allowed? + #: Are multiple selected items allowed? multi_select = Bool(False) - # Should horizontal lines be drawn between items? + #: Should horizontal lines be drawn between items? horizontal_lines = Bool(True) - # Should vertical lines be drawn between items? + #: Should vertical lines be drawn between items? vertical_lines = Bool(True) - # Should the columns automatically resize? Don't allow this when the amount - # of data is large. + #: Should the columns automatically resize? Don't allow this when the amount + #: of data is large. auto_resize = Bool(False) - # Should the rows automatically resize (Qt4 only)? Don't allow - # this when the amount of data is large. + #: Should the rows automatically resize (Qt4 only)? Don't allow + #: this when the amount of data is large. auto_resize_rows = Bool(False) - # Whether to stretch the last column to fit the available space. + #: Whether to stretch the last column to fit the available space. stretch_last_section = Bool(True) - # The adapter from trait values to editor values: - adapter = Instance('traitsui.tabular_adapter.TabularAdapter', ()) + #: The adapter from trait values to editor values: + adapter = Instance("traitsui.tabular_adapter.TabularAdapter", ()) - # What type of operations are allowed on the list: - operations = List(Enum('delete', 'insert', 'append', 'edit', 'move'), - ['delete', 'insert', 'append', 'edit', 'move']) + #: What type of operations are allowed on the list: + operations = List( + Enum("delete", "insert", "append", "edit", "move"), + ["delete", "insert", "append", "edit", "move"], + ) - # Are 'drag_move' operations allowed (i.e. True), or should they always be - # treated as 'drag_copy' operations (i.e. False): + #: Are 'drag_move' operations allowed (i.e. True), or should they always be + #: treated as 'drag_copy' operations (i.e. False): drag_move = Bool(True) - # The set of images that can be used: + #: The set of images that can be used: images = List(Image) def _get_klass(self): """ Returns the toolkit-specific editor class to be instantiated. """ - return toolkit_object('tabular_editor:TabularEditor') - -### EOF ####################################################################### + return toolkit_object("tabular_editor:TabularEditor")
    @@ -255,13 +249,11 @@

    Source code for traitsui.editors.tabular_editor

    <

    @@ -285,10 +277,10 @@

    Quick search

    © Copyright 2008-2020, Enthought
  • - Last updated on Jun 12, 2020. + Last updated on Dec 17, 2020.
  • - Created using Sphinx 1.8.5. + Created using Sphinx 2.3.1.
  • diff --git a/_modules/traitsui/view.html b/_modules/traitsui/view.html index dfb0afec9..9ef548fe1 100644 --- a/_modules/traitsui/view.html +++ b/_modules/traitsui/view.html @@ -13,9 +13,11 @@ @@ -72,16 +74,16 @@
    -
    +

    Source code for traitsui.view

    -#------------------------------------------------------------------------------
    +# ------------------------------------------------------------------------------
     #
     #  Copyright (c) 2005, Enthought, Inc.
     #  All rights reserved.
     #
     #  This software is provided without warranty under the terms of the BSD
    -#  license included in enthought/LICENSE.txt and may be redistributed only
    +#  license included in LICENSE.txt and may be redistributed only
     #  under the conditions described in the aforementioned license.  The license
     #  is also available online at http://www.enthought.com/licenses/BSD.txt
     #
    @@ -90,17 +92,13 @@ 

    Source code for traitsui.view

     #  Author: David C. Morrill
     #  Date:   10/07/2004
     #
    -#------------------------------------------------------------------------------
    +# ------------------------------------------------------------------------------
     
     """ Defines the View class used to represent the structural content of a
         Traits-based user interface.
     """
     
    -#-------------------------------------------------------------------------
    -#  Imports:
    -#-------------------------------------------------------------------------
     
    -from __future__ import absolute_import
     
     from pyface.ui_traits import Image
     from traits.api import (
    @@ -114,7 +112,7 @@ 

    Source code for traitsui.view

         List,
         Str,
         Trait,
    -    TraitPrefixList)
    +)
     
     from .view_element import ViewElement, ViewSubElement
     
    @@ -130,7 +128,8 @@ 

    Source code for traitsui.view

         HelpId,
         Image,
         SequenceTypes,
    -    ViewStatus)
    +    ViewStatus,
    +)
     
     from .handler import Handler, default_handler
     
    @@ -139,28 +138,31 @@ 

    Source code for traitsui.view

     from .item import Item
     
     from .include import Include
    -import six
     
    -#-------------------------------------------------------------------------
    +from .helper import PrefixList
    +
    +# -------------------------------------------------------------------------
     #  Trait definitions:
    -#-------------------------------------------------------------------------
    +# -------------------------------------------------------------------------
     
     # Name of the view trait:
    -AnId = Str(desc='the name of the view')
    +AnId = Str(desc="the name of the view")
     
     # Contents of the view trait (i.e., a single Group object):
    -Content = Instance(Group, desc='the content of the view')
    +Content = Instance(Group, desc="the content of the view")
     
     # An optional model/view factory for converting the model into a viewable
     # 'model_view' object
    -AModelView = Callable(desc='the factory function for converting a model '
    -                      'into a model/view object')
    +AModelView = Callable(
    +    desc="the factory function for converting a model "
    +    "into a model/view object"
    +)
     
     # Reference to a Handler object trait:
    -AHandler = Any(desc='the handler for the view')
    +AHandler = Any(desc="the handler for the view")
     
     # Dialog window title trait:
    -ATitle = Str(desc='the window title for the view')
    +ATitle = Str(desc="the window title for the view")
     
     # User interface 'kind' trait. The values have the following meanings:
     #
    @@ -183,45 +185,61 @@ 

    Source code for traitsui.view

     #   pages, which can be accessed by clicking **Next** and **Back** buttons.
     #   Changes to attribute values are applied only when the user clicks the
     #   **Finish** button on the last page.
    -AKind = Trait('live', TraitPrefixList(
    -    'panel', 'subpanel', 'modal', 'nonmodal', 'livemodal',
    -    'live', 'popup', 'popover', 'info', 'wizard'),
    -    desc='the kind of view window to create',
    -    cols=4)
    +AKind = PrefixList(
    +    (
    +        "panel",
    +        "subpanel",
    +        "modal",
    +        "nonmodal",
    +        "livemodal",
    +        "live",
    +        "popup",
    +        "popover",
    +        "info",
    +        "wizard",
    +    ),
    +    default_value='live',
    +    desc="the kind of view window to create",
    +    cols=4,
    +)
     
     # Apply changes handler:
    -OnApply = Callable(desc='the routine to call when modal changes are applied '
    -                   'or reverted')
    +OnApply = Callable(
    +    desc="the routine to call when modal changes are applied " "or reverted"
    +)
     
     # Is the dialog window resizable?
    -IsResizable = Bool(False, desc='whether dialog can be resized or not')
    +IsResizable = Bool(False, desc="whether dialog can be resized or not")
     
     # Is the view scrollable?
    -IsScrollable = Bool(False, desc='whether view should be scrollable or not')
    +IsScrollable = Bool(False, desc="whether view should be scrollable or not")
     
     # The valid categories of imported elements that can be dragged into the view:
    -ImportTypes = List(Str, desc='the categories of elements that can be '
    -                   'dragged into the view')
    +ImportTypes = List(
    +    Str, desc="the categories of elements that can be " "dragged into the view"
    +)
     
     # The view position and size traits:
    -Width = Float(-1E6, desc='the width of the view window')
    -Height = Float(-1E6, desc='the height of the view window')
    -XCoordinate = Float(-1E6, desc='the x coordinate of the view window')
    -YCoordinate = Float(-1E6, desc='the y coordinate of the view window')
    +Width = Float(-1e6, desc="the width of the view window")
    +Height = Float(-1e6, desc="the height of the view window")
    +XCoordinate = Float(-1e6, desc="the x coordinate of the view window")
    +YCoordinate = Float(-1e6, desc="the y coordinate of the view window")
     
     # The result that should be returned if the user clicks the window or dialog
     # close button or icon
    -CloseResult = Enum(None, True, False,
    -                   desc='the result to return when the user clicks the '
    -                   'window or dialog close button or icon')
    +CloseResult = Enum(
    +    None,
    +    True,
    +    False,
    +    desc="the result to return when the user clicks the "
    +    "window or dialog close button or icon",
    +)
     
     # The KeyBindings trait:
    -AKeyBindings = Instance('traitsui.key_bindings.KeyBindings',
    -                        desc='the global key bindings for the view')
    -
    -#-------------------------------------------------------------------------
    -#  'View' class:
    -#-------------------------------------------------------------------------
    +AKeyBindings = Instance(
    +    "traitsui.key_bindings.KeyBindings",
    +    desc="the global key bindings for the view",
    +)
     
     
     class View(ViewElement):
    @@ -233,167 +251,167 @@ 

    Source code for traitsui.view

             object derived from HasTraits, or it can be a standalone object.
         """
     
    -    #-------------------------------------------------------------------------
    +    # -------------------------------------------------------------------------
         #  Trait definitions:
    -    #-------------------------------------------------------------------------
    +    # -------------------------------------------------------------------------
     
    -    # A unique identifier for the view:
    +    #: A unique identifier for the view:
         id = AnId
     
    -    # The top-level Group object for the view:
    +    #: The top-level Group object for the view:
         content = Content
     
    -    # The menu bar for the view. Usually requires a custom **handler**:
    +    #: The menu bar for the view. Usually requires a custom **handler**:
         menubar = Any  # Instance( pyface.action.MenuBarManager )
     
    -    # The toolbar for the view. Usually requires a custom **handler**:
    +    #: The toolbar for the view. Usually requires a custom **handler**:
         toolbar = Any  # Instance( pyface.action.ToolBarManager )
     
    -    # Status bar items to add to the view's status bar. The value can be:
    -    #
    -    #   - **None**: No status bar for the view (the default).
    -    #   - string: Same as [ StatusItem( name = string ) ].
    -    #   - StatusItem: Same as [ StatusItem ].
    -    #   - [ [StatusItem|string], ... ]: Create a status bar with one field for
    -    #     each StatusItem in the list (or tuple). The status bar fields are
    -    #     defined from left to right in the order specified. A string value is
    -    #     converted to: StatusItem( name = string ):
    +    #: Status bar items to add to the view's status bar. The value can be:
    +    #:
    +    #:   - **None**: No status bar for the view (the default).
    +    #:   - string: Same as [ StatusItem( name = string ) ].
    +    #:   - StatusItem: Same as [ StatusItem ].
    +    #:   - [ [StatusItem|string], ... ]: Create a status bar with one field for
    +    #:     each StatusItem in the list (or tuple). The status bar fields are
    +    #:     defined from left to right in the order specified. A string value is
    +    #:     converted to: StatusItem( name = string ):
         statusbar = ViewStatus
     
    -    # List of button actions to add to the view. The **traitsui.menu**
    -    # module defines standard buttons, such as **OKButton**, and standard sets
    -    # of buttons, such as **ModalButtons**, which can be used to define a value
    -    # for this attribute. This value can also be a list of button name strings,
    -    # such as ``['OK', 'Cancel', 'Help']``. If set to the empty list, the
    -    # view contains a default set of buttons (equivalent to **LiveButtons**:
    -    # Undo/Redo, Revert, OK, Cancel, Help). To suppress buttons in the view,
    -    # use the **NoButtons** variable, defined in **traitsui.menu**.
    +    #: List of button actions to add to the view. The **traitsui.menu**
    +    #: module defines standard buttons, such as **OKButton**, and standard sets
    +    #: of buttons, such as **ModalButtons**, which can be used to define a value
    +    #: for this attribute. This value can also be a list of button name strings,
    +    #: such as ``['OK', 'Cancel', 'Help']``. If set to the empty list, the
    +    #: view contains a default set of buttons (equivalent to **LiveButtons**:
    +    #: Undo/Redo, Revert, OK, Cancel, Help). To suppress buttons in the view,
    +    #: use the **NoButtons** variable, defined in **traitsui.menu**.
         buttons = Buttons
     
    -    # The default button to activate when Enter is pressed. If not specified,
    -    # pressing Enter will not activate any button.
    +    #: The default button to activate when Enter is pressed. If not specified,
    +    #: pressing Enter will not activate any button.
         default_button = AButton
     
    -    # The set of global key bindings for the view. Each time a key is pressed
    -    # while the view has keyboard focus, the key is checked to see if it is one
    -    # of the keys recognized by the KeyBindings object. If it is, the matching
    -    # KeyBinding's method name is checked to see if it is defined on any of the
    -    # object's in the view's context. If it is, the method is invoked. If the
    -    # result of the method is **False**, then the search continues with the
    -    # next object in the context. If any invoked method returns a non-False
    -    # value, processing stops and the key is marked as having been handled. If
    -    # all invoked methods return **False**, or no matching KeyBinding object is
    -    # found, the key is processed normally. If the view has a non-empty *id*
    -    # trait, the contents of the **KeyBindings** object will be saved as part
    -    # of the view's persistent data:
    +    #: The set of global key bindings for the view. Each time a key is pressed
    +    #: while the view has keyboard focus, the key is checked to see if it is one
    +    #: of the keys recognized by the KeyBindings object. If it is, the matching
    +    #: KeyBinding's method name is checked to see if it is defined on any of the
    +    #: object's in the view's context. If it is, the method is invoked. If the
    +    #: result of the method is **False**, then the search continues with the
    +    #: next object in the context. If any invoked method returns a non-False
    +    #: value, processing stops and the key is marked as having been handled. If
    +    #: all invoked methods return **False**, or no matching KeyBinding object is
    +    #: found, the key is processed normally. If the view has a non-empty *id*
    +    #: trait, the contents of the **KeyBindings** object will be saved as part
    +    #: of the view's persistent data:
         key_bindings = AKeyBindings
     
    -    # The Handler object that provides GUI logic for handling events in the
    -    # window. Set this attribute only if you are using a custom Handler. If
    -    # not set, the default Traits UI Handler is used.
    +    #: The Handler object that provides GUI logic for handling events in the
    +    #: window. Set this attribute only if you are using a custom Handler. If
    +    #: not set, the default Traits UI Handler is used.
         handler = AHandler
     
    -    # The factory function for converting a model into a model/view object:
    +    #: The factory function for converting a model into a model/view object:
         model_view = AModelView
     
    -    # Title for the view, displayed in the title bar when the view appears as a
    -    # secondary window (i.e., dialog or wizard). If not specified, "Edit
    -    # properties" is used as the title.
    +    #: Title for the view, displayed in the title bar when the view appears as a
    +    #: secondary window (i.e., dialog or wizard). If not specified, "Edit
    +    #: properties" is used as the title.
         title = ATitle
     
    -    # The name of the icon to display in the dialog window title bar:
    +    #: The name of the icon to display in the dialog window title bar:
         icon = Image
     
    -    # The kind of user interface to create:
    +    #: The kind of user interface to create:
         kind = AKind
     
    -    # The default object being edited:
    +    #: The default object being edited:
         object = AnObject
     
    -    # The default editor style of elements in the view:
    +    #: The default editor style of elements in the view:
         style = EditorStyle
     
    -    # The default docking style to use for sub-groups of the view. The following
    -    # values are possible:
    -    #
    -    # * 'fixed': No rearrangement of sub-groups is allowed.
    -    # * 'horizontal': Moveable elements have a visual "handle" to the left by
    -    #   which the element can be dragged.
    -    # * 'vertical': Moveable elements have a visual "handle" above them by
    -    #   which the element can be dragged.
    -    # * 'tabbed': Moveable elements appear as tabbed pages, which can be
    -    #   arranged within the window or "stacked" so that only one appears at
    -    #   at a time.
    +    #: The default docking style to use for sub-groups of the view. The following
    +    #: values are possible:
    +    #:
    +    #: * 'fixed': No rearrangement of sub-groups is allowed.
    +    #: * 'horizontal': Moveable elements have a visual "handle" to the left by
    +    #:   which the element can be dragged.
    +    #: * 'vertical': Moveable elements have a visual "handle" above them by
    +    #:   which the element can be dragged.
    +    #: * 'tabbed': Moveable elements appear as tabbed pages, which can be
    +    #:   arranged within the window or "stacked" so that only one appears at
    +    #:   at a time.
         dock = DockStyle
     
    -    # The image to display on notebook tabs:
    +    #: The image to display on notebook tabs:
         image = Image
     
    -    # Called when modal changes are applied or reverted:
    +    #: Called when modal changes are applied or reverted:
         on_apply = OnApply
     
    -    # Can the user resize the window?
    +    #: Can the user resize the window?
         resizable = IsResizable
     
    -    # Can the user scroll the view? If set to True, window-level scroll bars
    -    # appear whenever the window is too small to show all of its contents at
    -    # one time. If set to False, the window does not scroll, but individual
    -    # widgets might still contain scroll bars.
    +    #: Can the user scroll the view? If set to True, window-level scroll bars
    +    #: appear whenever the window is too small to show all of its contents at
    +    #: one time. If set to False, the window does not scroll, but individual
    +    #: widgets might still contain scroll bars.
         scrollable = IsScrollable
     
    -    # The category of exported elements:
    +    #: The category of exported elements:
         export = ExportType
     
    -    # The valid categories of imported elements:
    +    #: The valid categories of imported elements:
         imports = ImportTypes
     
    -    # External help context identifier, which can be used by a custom help
    -    # handler. This attribute is ignored by the default help handler.
    +    #: External help context identifier, which can be used by a custom help
    +    #: handler. This attribute is ignored by the default help handler.
         help_id = HelpId
     
    -    # Requested x-coordinate (horizontal position) for the view window. This
    -    # attribute can be specified in the following ways:
    -    #
    -    # * A positive integer: indicates the number of pixels from the left edge
    -    #   of the screen to the left edge of the window.
    -    # * A negative integer: indicates the number of pixels from the right edge
    -    #   of the screen to the right edge of the window.
    -    # * A floating point value between 0 and 1: indicates the fraction of the
    -    #   total screen width between the left edge of the screen and the left edge
    -    #   of the window.
    -    # * A floating point value between -1 and 0: indicates the fraction of the
    -    #   total screen width between the right edge of the screen and the right
    -    #   edge of the window.
    +    #: Requested x-coordinate (horizontal position) for the view window. This
    +    #: attribute can be specified in the following ways:
    +    #:
    +    #: * A positive integer: indicates the number of pixels from the left edge
    +    #:   of the screen to the left edge of the window.
    +    #: * A negative integer: indicates the number of pixels from the right edge
    +    #:   of the screen to the right edge of the window.
    +    #: * A floating point value between 0 and 1: indicates the fraction of the
    +    #:   total screen width between the left edge of the screen and the left edge
    +    #:   of the window.
    +    #: * A floating point value between -1 and 0: indicates the fraction of the
    +    #:   total screen width between the right edge of the screen and the right
    +    #:   edge of the window.
         x = XCoordinate
     
    -    # Requested y-coordinate (vertical position) for the view window. This
    -    # attribute behaves exactly like the **x** attribute, except that its value
    -    # indicates the position of the top or bottom of the view window relative
    -    # to the top or bottom of the screen.
    +    #: Requested y-coordinate (vertical position) for the view window. This
    +    #: attribute behaves exactly like the **x** attribute, except that its value
    +    #: indicates the position of the top or bottom of the view window relative
    +    #: to the top or bottom of the screen.
         y = YCoordinate
     
    -    # Requested width for the view window, as an (integer) number of pixels, or
    -    # as a (floating point) fraction of the screen width.
    +    #: Requested width for the view window, as an (integer) number of pixels, or
    +    #: as a (floating point) fraction of the screen width.
         width = Width
     
    -    # Requested height for the view window, as an (integer) number of pixels, or
    -    # as a (floating point) fraction of the screen height.
    +    #: Requested height for the view window, as an (integer) number of pixels, or
    +    #: as a (floating point) fraction of the screen height.
         height = Height
     
    -    # Class of dropped objects that can be added:
    -    drop_class = Any
    +    #: Class of dropped objects that can be added:
    +    drop_class = Any()
     
    -    # Event when the view has been updated:
    -    updated = Event
    +    #: Event when the view has been updated:
    +    updated = Event()
     
    -    # What result should be returned if the user clicks the window or dialog
    -    # close button or icon?
    +    #: What result should be returned if the user clicks the window or dialog
    +    #: close button or icon?
         close_result = CloseResult
     
    -    # Note: Group objects delegate their 'object' and 'style' traits to the
    -    # View
    +    #: Note: Group objects delegate their 'object' and 'style' traits to the
    +    #: View
     
    -    #-- Deprecated Traits (DO NOT USE) ---------------------------------------
    +    # -- Deprecated Traits (DO NOT USE) ---------------------------------------
     
         ok = Bool(False)
         cancel = Bool(False)
    @@ -403,20 +421,12 @@ 

    Source code for traitsui.view

         revert = Bool(False)
         help = Bool(False)
     
    -    #-------------------------------------------------------------------------
    -    #  Initializes the object:
    -    #-------------------------------------------------------------------------
    -
         def __init__(self, *values, **traits):
             """ Initializes the object.
             """
             ViewElement.__init__(self, **traits)
             self.set_content(*values)
     
    -    #-------------------------------------------------------------------------
    -    #  Sets the content of a view:
    -    #-------------------------------------------------------------------------
    -
         def set_content(self, *values):
             """ Sets the content of a view.
             """
    @@ -427,8 +437,11 @@ 

    Source code for traitsui.view

                     content.append(value)
                 elif type(value) in SequenceTypes:
                     content.append(Group(*value))
    -            elif (isinstance(value, six.string_types) and
    -                  (value[:1] == '<') and (value[-1:] == '>')):
    +            elif (
    +                isinstance(value, str)
    +                and (value[:1] == "<")
    +                and (value[-1:] == ">")
    +            ):
                     # Convert string to an Include value:
                     content.append(Include(value[1:-1].strip()))
                 else:
    @@ -444,14 +457,17 @@ 

    Source code for traitsui.view

             # Wrap all of the content up into a Group and save it as our content:
             self.content = Group(container=self, *content)
     
    -    #-------------------------------------------------------------------------
    -    #  Creates a UI user interface object:
    -    #-------------------------------------------------------------------------
    -
    -    def ui(self, context, parent=None, kind=None,
    -            view_elements=None, handler=None,
    -            id='', scrollable=None,
    -            args=None):
    +    def ui(
    +        self,
    +        context,
    +        parent=None,
    +        kind=None,
    +        view_elements=None,
    +        handler=None,
    +        id="",
    +        scrollable=None,
    +        args=None,
    +    ):
             """ Creates a **UI** object, which generates the actual GUI window or
             panel from a set of view elements.
     
    @@ -493,29 +509,31 @@ 

    Source code for traitsui.view

             if not isinstance(context, dict):
                 context = context.trait_context()
     
    -        context.setdefault('handler', handler)
    -        handler = context['handler']
    +        context.setdefault("handler", handler)
    +        handler = context["handler"]
     
             if self.model_view is not None:
    -            context['object'] = self.model_view(context['object'])
    +            context["object"] = self.model_view(context["object"])
     
             self_id = self.id
    -        if self_id != '':
    -            if id != '':
    -                id = '%s:%s' % (self_id, id)
    +        if self_id != "":
    +            if id != "":
    +                id = "%s:%s" % (self_id, id)
                 else:
                     id = self_id
     
             if scrollable is None:
                 scrollable = self.scrollable
     
    -        ui = UI(view=self,
    -                context=context,
    -                handler=handler,
    -                view_elements=view_elements,
    -                title=self.title,
    -                id=id,
    -                scrollable=scrollable)
    +        ui = UI(
    +            view=self,
    +            context=context,
    +            handler=handler,
    +            view_elements=view_elements,
    +            title=self.title,
    +            id=id,
    +            scrollable=scrollable,
    +        )
     
             if kind is None:
                 kind = self.kind
    @@ -524,12 +542,6 @@ 

    Source code for traitsui.view

     
             return ui
     
    -    #-------------------------------------------------------------------------
    -    #  Replaces any items which have an 'id' with an Include object with the
    -    #  same 'id', and puts the object with the 'id' into the specified
    -    #  ViewElements object:
    -    #-------------------------------------------------------------------------
    -
         def replace_include(self, view_elements):
             """ Replaces any items that have an ID with an Include object with
                 the same ID, and puts the object with the ID into the specified
    @@ -538,17 +550,14 @@ 

    Source code for traitsui.view

             if self.content is not None:
                 self.content.replace_include(view_elements)
     
    -    #-------------------------------------------------------------------------
    -    #  Returns a 'pretty print' version of the View:
    -    #-------------------------------------------------------------------------
    -
         def __repr__(self):
             """ Returns a "pretty print" version of the View.
             """
             if self.content is None:
    -            return '()'
    -        return "( %s )" % ', '.join(
    -               [item.__repr__() for item in self.content.content])
    +            return "()"
    +        return "( %s )" % ", ".join(
    +            [item.__repr__() for item in self.content.content]
    +        )
     
    @@ -560,13 +569,11 @@

    Source code for traitsui.view

                   
                 

    @@ -590,10 +597,10 @@

    Quick search

    © Copyright 2008-2020, Enthought
  • - Last updated on Jun 12, 2020. + Last updated on Dec 17, 2020.
  • - Created using Sphinx 1.8.5. + Created using Sphinx 2.3.1.
  • diff --git a/_sources/api.rst.txt b/_sources/api.rst.txt index 7972821bf..224ac6510 100644 --- a/_sources/api.rst.txt +++ b/_sources/api.rst.txt @@ -1,3 +1,5 @@ +.. _api-documentation: + API documentation ================= diff --git a/_sources/api/apptools.io.h5.rst.txt b/_sources/api/apptools.io.h5.rst.txt index 656910ff4..dea85f58a 100644 --- a/_sources/api/apptools.io.h5.rst.txt +++ b/_sources/api/apptools.io.h5.rst.txt @@ -8,39 +8,39 @@ apptools.io.h5.dict\_node module -------------------------------- .. automodule:: apptools.io.h5.dict_node - :members: - :undoc-members: - :show-inheritance: + :members: + :undoc-members: + :show-inheritance: apptools.io.h5.file module -------------------------- .. automodule:: apptools.io.h5.file - :members: - :undoc-members: - :show-inheritance: + :members: + :undoc-members: + :show-inheritance: apptools.io.h5.table\_node module --------------------------------- .. automodule:: apptools.io.h5.table_node - :members: - :undoc-members: - :show-inheritance: + :members: + :undoc-members: + :show-inheritance: apptools.io.h5.utils module --------------------------- .. automodule:: apptools.io.h5.utils - :members: - :undoc-members: - :show-inheritance: + :members: + :undoc-members: + :show-inheritance: Module contents --------------- .. automodule:: apptools.io.h5 - :members: - :undoc-members: - :show-inheritance: + :members: + :undoc-members: + :show-inheritance: diff --git a/_sources/api/apptools.io.rst.txt b/_sources/api/apptools.io.rst.txt index ba5232adb..0907ac23c 100644 --- a/_sources/api/apptools.io.rst.txt +++ b/_sources/api/apptools.io.rst.txt @@ -6,7 +6,7 @@ Subpackages .. toctree:: - apptools.io.h5 + apptools.io.h5 Submodules ---------- @@ -15,23 +15,23 @@ apptools.io.api module ---------------------- .. automodule:: apptools.io.api - :members: - :undoc-members: - :show-inheritance: + :members: + :undoc-members: + :show-inheritance: apptools.io.file module ----------------------- .. automodule:: apptools.io.file - :members: - :undoc-members: - :show-inheritance: + :members: + :undoc-members: + :show-inheritance: Module contents --------------- .. automodule:: apptools.io - :members: - :undoc-members: - :show-inheritance: + :members: + :undoc-members: + :show-inheritance: diff --git a/_sources/api/apptools.logger.agent.rst.txt b/_sources/api/apptools.logger.agent.rst.txt index 263c0440d..c25c0dcfb 100644 --- a/_sources/api/apptools.logger.agent.rst.txt +++ b/_sources/api/apptools.logger.agent.rst.txt @@ -8,31 +8,31 @@ apptools.logger.agent.attachments module ---------------------------------------- .. automodule:: apptools.logger.agent.attachments - :members: - :undoc-members: - :show-inheritance: + :members: + :undoc-members: + :show-inheritance: apptools.logger.agent.quality\_agent\_mailer module --------------------------------------------------- .. automodule:: apptools.logger.agent.quality_agent_mailer - :members: - :undoc-members: - :show-inheritance: + :members: + :undoc-members: + :show-inheritance: apptools.logger.agent.quality\_agent\_view module ------------------------------------------------- .. automodule:: apptools.logger.agent.quality_agent_view - :members: - :undoc-members: - :show-inheritance: + :members: + :undoc-members: + :show-inheritance: Module contents --------------- .. automodule:: apptools.logger.agent - :members: - :undoc-members: - :show-inheritance: + :members: + :undoc-members: + :show-inheritance: diff --git a/_sources/api/apptools.logger.plugin.rst.txt b/_sources/api/apptools.logger.plugin.rst.txt index a33510ddd..b607fdd4e 100644 --- a/_sources/api/apptools.logger.plugin.rst.txt +++ b/_sources/api/apptools.logger.plugin.rst.txt @@ -6,7 +6,7 @@ Subpackages .. toctree:: - apptools.logger.plugin.view + apptools.logger.plugin.view Submodules ---------- @@ -15,31 +15,31 @@ apptools.logger.plugin.logger\_plugin module -------------------------------------------- .. automodule:: apptools.logger.plugin.logger_plugin - :members: - :undoc-members: - :show-inheritance: + :members: + :undoc-members: + :show-inheritance: apptools.logger.plugin.logger\_preferences module ------------------------------------------------- .. automodule:: apptools.logger.plugin.logger_preferences - :members: - :undoc-members: - :show-inheritance: + :members: + :undoc-members: + :show-inheritance: apptools.logger.plugin.logger\_service module --------------------------------------------- .. automodule:: apptools.logger.plugin.logger_service - :members: - :undoc-members: - :show-inheritance: + :members: + :undoc-members: + :show-inheritance: Module contents --------------- .. automodule:: apptools.logger.plugin - :members: - :undoc-members: - :show-inheritance: + :members: + :undoc-members: + :show-inheritance: diff --git a/_sources/api/apptools.logger.plugin.view.rst.txt b/_sources/api/apptools.logger.plugin.view.rst.txt index 888ed7c6c..1d8dc0b3d 100644 --- a/_sources/api/apptools.logger.plugin.view.rst.txt +++ b/_sources/api/apptools.logger.plugin.view.rst.txt @@ -8,23 +8,23 @@ apptools.logger.plugin.view.logger\_preferences\_page module ------------------------------------------------------------ .. automodule:: apptools.logger.plugin.view.logger_preferences_page - :members: - :undoc-members: - :show-inheritance: + :members: + :undoc-members: + :show-inheritance: apptools.logger.plugin.view.logger\_view module ----------------------------------------------- .. automodule:: apptools.logger.plugin.view.logger_view - :members: - :undoc-members: - :show-inheritance: + :members: + :undoc-members: + :show-inheritance: Module contents --------------- .. automodule:: apptools.logger.plugin.view - :members: - :undoc-members: - :show-inheritance: + :members: + :undoc-members: + :show-inheritance: diff --git a/_sources/api/apptools.logger.rst.txt b/_sources/api/apptools.logger.rst.txt index e8444d74f..c49196f26 100644 --- a/_sources/api/apptools.logger.rst.txt +++ b/_sources/api/apptools.logger.rst.txt @@ -6,8 +6,8 @@ Subpackages .. toctree:: - apptools.logger.agent - apptools.logger.plugin + apptools.logger.agent + apptools.logger.plugin Submodules ---------- @@ -16,79 +16,55 @@ apptools.logger.api module -------------------------- .. automodule:: apptools.logger.api - :members: - :undoc-members: - :show-inheritance: + :members: + :undoc-members: + :show-inheritance: apptools.logger.custom\_excepthook module ----------------------------------------- .. automodule:: apptools.logger.custom_excepthook - :members: - :undoc-members: - :show-inheritance: - -apptools.logger.filtering\_handler module ------------------------------------------ - -.. automodule:: apptools.logger.filtering_handler - :members: - :undoc-members: - :show-inheritance: + :members: + :undoc-members: + :show-inheritance: apptools.logger.log\_point module --------------------------------- .. automodule:: apptools.logger.log_point - :members: - :undoc-members: - :show-inheritance: + :members: + :undoc-members: + :show-inheritance: apptools.logger.log\_queue\_handler module ------------------------------------------ .. automodule:: apptools.logger.log_queue_handler - :members: - :undoc-members: - :show-inheritance: + :members: + :undoc-members: + :show-inheritance: apptools.logger.logger module ----------------------------- .. automodule:: apptools.logger.logger - :members: - :undoc-members: - :show-inheritance: - -apptools.logger.null\_handler module ------------------------------------- - -.. automodule:: apptools.logger.null_handler - :members: - :undoc-members: - :show-inheritance: + :members: + :undoc-members: + :show-inheritance: apptools.logger.ring\_buffer module ----------------------------------- .. automodule:: apptools.logger.ring_buffer - :members: - :undoc-members: - :show-inheritance: - -apptools.logger.util module ---------------------------- - -.. automodule:: apptools.logger.util - :members: - :undoc-members: - :show-inheritance: + :members: + :undoc-members: + :show-inheritance: Module contents --------------- .. automodule:: apptools.logger - :members: - :undoc-members: - :show-inheritance: + :members: + :undoc-members: + :show-inheritance: diff --git a/_sources/api/apptools.naming.rst.txt b/_sources/api/apptools.naming.rst.txt index e3f233454..b4645f693 100644 --- a/_sources/api/apptools.naming.rst.txt +++ b/_sources/api/apptools.naming.rst.txt @@ -6,9 +6,7 @@ Subpackages .. toctree:: - apptools.naming.adapter - apptools.naming.trait_defs - apptools.naming.ui + apptools.naming.trait_defs Submodules ---------- @@ -17,223 +15,207 @@ apptools.naming.address module ------------------------------ .. automodule:: apptools.naming.address - :members: - :undoc-members: - :show-inheritance: + :members: + :undoc-members: + :show-inheritance: apptools.naming.api module -------------------------- .. automodule:: apptools.naming.api - :members: - :undoc-members: - :show-inheritance: + :members: + :undoc-members: + :show-inheritance: apptools.naming.binding module ------------------------------ .. automodule:: apptools.naming.binding - :members: - :undoc-members: - :show-inheritance: + :members: + :undoc-members: + :show-inheritance: apptools.naming.context module ------------------------------ .. automodule:: apptools.naming.context - :members: - :undoc-members: - :show-inheritance: - -apptools.naming.context\_adapter module ---------------------------------------- - -.. automodule:: apptools.naming.context_adapter - :members: - :undoc-members: - :show-inheritance: - -apptools.naming.context\_adapter\_factory module ------------------------------------------------- - -.. automodule:: apptools.naming.context_adapter_factory - :members: - :undoc-members: - :show-inheritance: + :members: + :undoc-members: + :show-inheritance: apptools.naming.dir\_context module ----------------------------------- .. automodule:: apptools.naming.dir_context - :members: - :undoc-members: - :show-inheritance: + :members: + :undoc-members: + :show-inheritance: apptools.naming.dynamic\_context module --------------------------------------- .. automodule:: apptools.naming.dynamic_context - :members: - :undoc-members: - :show-inheritance: + :members: + :undoc-members: + :show-inheritance: apptools.naming.exception module -------------------------------- .. automodule:: apptools.naming.exception - :members: - :undoc-members: - :show-inheritance: + :members: + :undoc-members: + :show-inheritance: apptools.naming.initial\_context module --------------------------------------- .. automodule:: apptools.naming.initial_context - :members: - :undoc-members: - :show-inheritance: + :members: + :undoc-members: + :show-inheritance: apptools.naming.initial\_context\_factory module ------------------------------------------------ .. automodule:: apptools.naming.initial_context_factory - :members: - :undoc-members: - :show-inheritance: + :members: + :undoc-members: + :show-inheritance: apptools.naming.naming\_event module ------------------------------------ .. automodule:: apptools.naming.naming_event - :members: - :undoc-members: - :show-inheritance: + :members: + :undoc-members: + :show-inheritance: apptools.naming.naming\_manager module -------------------------------------- .. automodule:: apptools.naming.naming_manager - :members: - :undoc-members: - :show-inheritance: + :members: + :undoc-members: + :show-inheritance: apptools.naming.object\_factory module -------------------------------------- .. automodule:: apptools.naming.object_factory - :members: - :undoc-members: - :show-inheritance: + :members: + :undoc-members: + :show-inheritance: apptools.naming.object\_serializer module ----------------------------------------- .. automodule:: apptools.naming.object_serializer - :members: - :undoc-members: - :show-inheritance: + :members: + :undoc-members: + :show-inheritance: apptools.naming.py\_context module ---------------------------------- .. automodule:: apptools.naming.py_context - :members: - :undoc-members: - :show-inheritance: + :members: + :undoc-members: + :show-inheritance: apptools.naming.py\_object\_factory module ------------------------------------------ .. automodule:: apptools.naming.py_object_factory - :members: - :undoc-members: - :show-inheritance: + :members: + :undoc-members: + :show-inheritance: apptools.naming.pyfs\_context module ------------------------------------ .. automodule:: apptools.naming.pyfs_context - :members: - :undoc-members: - :show-inheritance: + :members: + :undoc-members: + :show-inheritance: apptools.naming.pyfs\_context\_factory module --------------------------------------------- .. automodule:: apptools.naming.pyfs_context_factory - :members: - :undoc-members: - :show-inheritance: + :members: + :undoc-members: + :show-inheritance: apptools.naming.pyfs\_initial\_context\_factory module ------------------------------------------------------ .. automodule:: apptools.naming.pyfs_initial_context_factory - :members: - :undoc-members: - :show-inheritance: + :members: + :undoc-members: + :show-inheritance: apptools.naming.pyfs\_object\_factory module -------------------------------------------- .. automodule:: apptools.naming.pyfs_object_factory - :members: - :undoc-members: - :show-inheritance: + :members: + :undoc-members: + :show-inheritance: apptools.naming.pyfs\_state\_factory module ------------------------------------------- .. automodule:: apptools.naming.pyfs_state_factory - :members: - :undoc-members: - :show-inheritance: + :members: + :undoc-members: + :show-inheritance: apptools.naming.reference module -------------------------------- .. automodule:: apptools.naming.reference - :members: - :undoc-members: - :show-inheritance: + :members: + :undoc-members: + :show-inheritance: apptools.naming.referenceable module ------------------------------------ .. automodule:: apptools.naming.referenceable - :members: - :undoc-members: - :show-inheritance: + :members: + :undoc-members: + :show-inheritance: apptools.naming.referenceable\_state\_factory module ---------------------------------------------------- .. automodule:: apptools.naming.referenceable_state_factory - :members: - :undoc-members: - :show-inheritance: + :members: + :undoc-members: + :show-inheritance: apptools.naming.state\_factory module ------------------------------------- .. automodule:: apptools.naming.state_factory - :members: - :undoc-members: - :show-inheritance: + :members: + :undoc-members: + :show-inheritance: apptools.naming.unique\_name module ----------------------------------- .. automodule:: apptools.naming.unique_name - :members: - :undoc-members: - :show-inheritance: + :members: + :undoc-members: + :show-inheritance: Module contents --------------- .. automodule:: apptools.naming - :members: - :undoc-members: - :show-inheritance: + :members: + :undoc-members: + :show-inheritance: diff --git a/_sources/api/apptools.naming.trait_defs.rst.txt b/_sources/api/apptools.naming.trait_defs.rst.txt index b75680e73..e2281ea3d 100644 --- a/_sources/api/apptools.naming.trait_defs.rst.txt +++ b/_sources/api/apptools.naming.trait_defs.rst.txt @@ -8,23 +8,23 @@ apptools.naming.trait\_defs.api module -------------------------------------- .. automodule:: apptools.naming.trait_defs.api - :members: - :undoc-members: - :show-inheritance: + :members: + :undoc-members: + :show-inheritance: apptools.naming.trait\_defs.naming\_traits module ------------------------------------------------- .. automodule:: apptools.naming.trait_defs.naming_traits - :members: - :undoc-members: - :show-inheritance: + :members: + :undoc-members: + :show-inheritance: Module contents --------------- .. automodule:: apptools.naming.trait_defs - :members: - :undoc-members: - :show-inheritance: + :members: + :undoc-members: + :show-inheritance: diff --git a/_sources/api/apptools.persistence.rst.txt b/_sources/api/apptools.persistence.rst.txt index ce06acc08..4cda6c227 100644 --- a/_sources/api/apptools.persistence.rst.txt +++ b/_sources/api/apptools.persistence.rst.txt @@ -8,63 +8,55 @@ apptools.persistence.file\_path module -------------------------------------- .. automodule:: apptools.persistence.file_path - :members: - :undoc-members: - :show-inheritance: + :members: + :undoc-members: + :show-inheritance: apptools.persistence.project\_loader module ------------------------------------------- .. automodule:: apptools.persistence.project_loader - :members: - :undoc-members: - :show-inheritance: - -apptools.persistence.spickle module ------------------------------------ - -.. automodule:: apptools.persistence.spickle - :members: - :undoc-members: - :show-inheritance: + :members: + :undoc-members: + :show-inheritance: apptools.persistence.state\_pickler module ------------------------------------------ .. automodule:: apptools.persistence.state_pickler - :members: - :undoc-members: - :show-inheritance: + :members: + :undoc-members: + :show-inheritance: apptools.persistence.updater module ----------------------------------- .. automodule:: apptools.persistence.updater - :members: - :undoc-members: - :show-inheritance: + :members: + :undoc-members: + :show-inheritance: apptools.persistence.version\_registry module --------------------------------------------- .. automodule:: apptools.persistence.version_registry - :members: - :undoc-members: - :show-inheritance: + :members: + :undoc-members: + :show-inheritance: apptools.persistence.versioned\_unpickler module ------------------------------------------------ .. automodule:: apptools.persistence.versioned_unpickler - :members: - :undoc-members: - :show-inheritance: + :members: + :undoc-members: + :show-inheritance: Module contents --------------- .. automodule:: apptools.persistence - :members: - :undoc-members: - :show-inheritance: + :members: + :undoc-members: + :show-inheritance: diff --git a/_sources/api/apptools.preferences.rst.txt b/_sources/api/apptools.preferences.rst.txt index 69d06e7c9..cba31951c 100644 --- a/_sources/api/apptools.preferences.rst.txt +++ b/_sources/api/apptools.preferences.rst.txt @@ -6,7 +6,7 @@ Subpackages .. toctree:: - apptools.preferences.ui + apptools.preferences.ui Submodules ---------- @@ -15,63 +15,63 @@ apptools.preferences.api module ------------------------------- .. automodule:: apptools.preferences.api - :members: - :undoc-members: - :show-inheritance: + :members: + :undoc-members: + :show-inheritance: apptools.preferences.i\_preferences module ------------------------------------------ .. automodule:: apptools.preferences.i_preferences - :members: - :undoc-members: - :show-inheritance: + :members: + :undoc-members: + :show-inheritance: apptools.preferences.package\_globals module -------------------------------------------- .. automodule:: apptools.preferences.package_globals - :members: - :undoc-members: - :show-inheritance: + :members: + :undoc-members: + :show-inheritance: apptools.preferences.preference\_binding module ----------------------------------------------- .. automodule:: apptools.preferences.preference_binding - :members: - :undoc-members: - :show-inheritance: + :members: + :undoc-members: + :show-inheritance: apptools.preferences.preferences module --------------------------------------- .. automodule:: apptools.preferences.preferences - :members: - :undoc-members: - :show-inheritance: + :members: + :undoc-members: + :show-inheritance: apptools.preferences.preferences\_helper module ----------------------------------------------- .. automodule:: apptools.preferences.preferences_helper - :members: - :undoc-members: - :show-inheritance: + :members: + :undoc-members: + :show-inheritance: apptools.preferences.scoped\_preferences module ----------------------------------------------- .. automodule:: apptools.preferences.scoped_preferences - :members: - :undoc-members: - :show-inheritance: + :members: + :undoc-members: + :show-inheritance: Module contents --------------- .. automodule:: apptools.preferences - :members: - :undoc-members: - :show-inheritance: + :members: + :undoc-members: + :show-inheritance: diff --git a/_sources/api/apptools.preferences.ui.rst.txt b/_sources/api/apptools.preferences.ui.rst.txt index 75986c10a..59a451f0a 100644 --- a/_sources/api/apptools.preferences.ui.rst.txt +++ b/_sources/api/apptools.preferences.ui.rst.txt @@ -8,63 +8,63 @@ apptools.preferences.ui.api module ---------------------------------- .. automodule:: apptools.preferences.ui.api - :members: - :undoc-members: - :show-inheritance: + :members: + :undoc-members: + :show-inheritance: apptools.preferences.ui.i\_preferences\_page module --------------------------------------------------- .. automodule:: apptools.preferences.ui.i_preferences_page - :members: - :undoc-members: - :show-inheritance: + :members: + :undoc-members: + :show-inheritance: apptools.preferences.ui.preferences\_manager module --------------------------------------------------- .. automodule:: apptools.preferences.ui.preferences_manager - :members: - :undoc-members: - :show-inheritance: + :members: + :undoc-members: + :show-inheritance: apptools.preferences.ui.preferences\_node module ------------------------------------------------ .. automodule:: apptools.preferences.ui.preferences_node - :members: - :undoc-members: - :show-inheritance: + :members: + :undoc-members: + :show-inheritance: apptools.preferences.ui.preferences\_page module ------------------------------------------------ .. automodule:: apptools.preferences.ui.preferences_page - :members: - :undoc-members: - :show-inheritance: + :members: + :undoc-members: + :show-inheritance: apptools.preferences.ui.tree\_item module ----------------------------------------- .. automodule:: apptools.preferences.ui.tree_item - :members: - :undoc-members: - :show-inheritance: + :members: + :undoc-members: + :show-inheritance: apptools.preferences.ui.widget\_editor module --------------------------------------------- .. automodule:: apptools.preferences.ui.widget_editor - :members: - :undoc-members: - :show-inheritance: + :members: + :undoc-members: + :show-inheritance: Module contents --------------- .. automodule:: apptools.preferences.ui - :members: - :undoc-members: - :show-inheritance: + :members: + :undoc-members: + :show-inheritance: diff --git a/_sources/api/apptools.rst.txt b/_sources/api/apptools.rst.txt index 7dbaaeb30..d1e57ded9 100644 --- a/_sources/api/apptools.rst.txt +++ b/_sources/api/apptools.rst.txt @@ -6,27 +6,20 @@ Subpackages .. toctree:: - apptools.appscripting - apptools.help - apptools.io - apptools.logger - apptools.lru_cache - apptools.naming - apptools.permissions - apptools.persistence - apptools.preferences - apptools.scripting - apptools.selection - apptools.sweet_pickle - apptools.template - apptools.type_manager - apptools.type_registry - apptools.undo + apptools.io + apptools.logger + apptools.naming + apptools.persistence + apptools.preferences + apptools.scripting + apptools.selection + apptools.type_registry + apptools.undo Module contents --------------- .. automodule:: apptools - :members: - :undoc-members: - :show-inheritance: + :members: + :undoc-members: + :show-inheritance: diff --git a/_sources/api/apptools.scripting.rst.txt b/_sources/api/apptools.scripting.rst.txt index 7c2e0f04b..4a47c7054 100644 --- a/_sources/api/apptools.scripting.rst.txt +++ b/_sources/api/apptools.scripting.rst.txt @@ -8,55 +8,55 @@ apptools.scripting.api module ----------------------------- .. automodule:: apptools.scripting.api - :members: - :undoc-members: - :show-inheritance: + :members: + :undoc-members: + :show-inheritance: apptools.scripting.package\_globals module ------------------------------------------ .. automodule:: apptools.scripting.package_globals - :members: - :undoc-members: - :show-inheritance: + :members: + :undoc-members: + :show-inheritance: apptools.scripting.recordable module ------------------------------------ .. automodule:: apptools.scripting.recordable - :members: - :undoc-members: - :show-inheritance: + :members: + :undoc-members: + :show-inheritance: apptools.scripting.recorder module ---------------------------------- .. automodule:: apptools.scripting.recorder - :members: - :undoc-members: - :show-inheritance: + :members: + :undoc-members: + :show-inheritance: apptools.scripting.recorder\_with\_ui module -------------------------------------------- .. automodule:: apptools.scripting.recorder_with_ui - :members: - :undoc-members: - :show-inheritance: + :members: + :undoc-members: + :show-inheritance: apptools.scripting.util module ------------------------------ .. automodule:: apptools.scripting.util - :members: - :undoc-members: - :show-inheritance: + :members: + :undoc-members: + :show-inheritance: Module contents --------------- .. automodule:: apptools.scripting - :members: - :undoc-members: - :show-inheritance: + :members: + :undoc-members: + :show-inheritance: diff --git a/_sources/api/apptools.selection.rst.txt b/_sources/api/apptools.selection.rst.txt index c96838354..d64022443 100644 --- a/_sources/api/apptools.selection.rst.txt +++ b/_sources/api/apptools.selection.rst.txt @@ -8,55 +8,55 @@ apptools.selection.api module ----------------------------- .. automodule:: apptools.selection.api - :members: - :undoc-members: - :show-inheritance: + :members: + :undoc-members: + :show-inheritance: apptools.selection.errors module -------------------------------- .. automodule:: apptools.selection.errors - :members: - :undoc-members: - :show-inheritance: + :members: + :undoc-members: + :show-inheritance: apptools.selection.i\_selection module -------------------------------------- .. automodule:: apptools.selection.i_selection - :members: - :undoc-members: - :show-inheritance: + :members: + :undoc-members: + :show-inheritance: apptools.selection.i\_selection\_provider module ------------------------------------------------ .. automodule:: apptools.selection.i_selection_provider - :members: - :undoc-members: - :show-inheritance: + :members: + :undoc-members: + :show-inheritance: apptools.selection.list\_selection module ----------------------------------------- .. automodule:: apptools.selection.list_selection - :members: - :undoc-members: - :show-inheritance: + :members: + :undoc-members: + :show-inheritance: apptools.selection.selection\_service module -------------------------------------------- .. automodule:: apptools.selection.selection_service - :members: - :undoc-members: - :show-inheritance: + :members: + :undoc-members: + :show-inheritance: Module contents --------------- .. automodule:: apptools.selection - :members: - :undoc-members: - :show-inheritance: + :members: + :undoc-members: + :show-inheritance: diff --git a/_sources/api/apptools.type_registry.rst.txt b/_sources/api/apptools.type_registry.rst.txt index ec2f8182a..161af8365 100644 --- a/_sources/api/apptools.type_registry.rst.txt +++ b/_sources/api/apptools.type_registry.rst.txt @@ -8,23 +8,23 @@ apptools.type\_registry.api module ---------------------------------- .. automodule:: apptools.type_registry.api - :members: - :undoc-members: - :show-inheritance: + :members: + :undoc-members: + :show-inheritance: apptools.type\_registry.type\_registry module --------------------------------------------- .. automodule:: apptools.type_registry.type_registry - :members: - :undoc-members: - :show-inheritance: + :members: + :undoc-members: + :show-inheritance: Module contents --------------- .. automodule:: apptools.type_registry - :members: - :undoc-members: - :show-inheritance: + :members: + :undoc-members: + :show-inheritance: diff --git a/_sources/api/apptools.undo.action.rst.txt b/_sources/api/apptools.undo.action.rst.txt index b2e8fea8d..13985a67f 100644 --- a/_sources/api/apptools.undo.action.rst.txt +++ b/_sources/api/apptools.undo.action.rst.txt @@ -8,47 +8,47 @@ apptools.undo.action.abstract\_command\_stack\_action module ------------------------------------------------------------ .. automodule:: apptools.undo.action.abstract_command_stack_action - :members: - :undoc-members: - :show-inheritance: + :members: + :undoc-members: + :show-inheritance: apptools.undo.action.api module ------------------------------- .. automodule:: apptools.undo.action.api - :members: - :undoc-members: - :show-inheritance: + :members: + :undoc-members: + :show-inheritance: apptools.undo.action.command\_action module ------------------------------------------- .. automodule:: apptools.undo.action.command_action - :members: - :undoc-members: - :show-inheritance: + :members: + :undoc-members: + :show-inheritance: apptools.undo.action.redo\_action module ---------------------------------------- .. automodule:: apptools.undo.action.redo_action - :members: - :undoc-members: - :show-inheritance: + :members: + :undoc-members: + :show-inheritance: apptools.undo.action.undo\_action module ---------------------------------------- .. automodule:: apptools.undo.action.undo_action - :members: - :undoc-members: - :show-inheritance: + :members: + :undoc-members: + :show-inheritance: Module contents --------------- .. automodule:: apptools.undo.action - :members: - :undoc-members: - :show-inheritance: + :members: + :undoc-members: + :show-inheritance: diff --git a/_sources/api/apptools.undo.rst.txt b/_sources/api/apptools.undo.rst.txt index 62fabb592..477e1bf52 100644 --- a/_sources/api/apptools.undo.rst.txt +++ b/_sources/api/apptools.undo.rst.txt @@ -6,7 +6,7 @@ Subpackages .. toctree:: - apptools.undo.action + apptools.undo.action Submodules ---------- @@ -15,63 +15,63 @@ apptools.undo.abstract\_command module -------------------------------------- .. automodule:: apptools.undo.abstract_command - :members: - :undoc-members: - :show-inheritance: + :members: + :undoc-members: + :show-inheritance: apptools.undo.api module ------------------------ .. automodule:: apptools.undo.api - :members: - :undoc-members: - :show-inheritance: + :members: + :undoc-members: + :show-inheritance: apptools.undo.command\_stack module ----------------------------------- .. automodule:: apptools.undo.command_stack - :members: - :undoc-members: - :show-inheritance: + :members: + :undoc-members: + :show-inheritance: apptools.undo.i\_command module ------------------------------- .. automodule:: apptools.undo.i_command - :members: - :undoc-members: - :show-inheritance: + :members: + :undoc-members: + :show-inheritance: apptools.undo.i\_command\_stack module -------------------------------------- .. automodule:: apptools.undo.i_command_stack - :members: - :undoc-members: - :show-inheritance: + :members: + :undoc-members: + :show-inheritance: apptools.undo.i\_undo\_manager module ------------------------------------- .. automodule:: apptools.undo.i_undo_manager - :members: - :undoc-members: - :show-inheritance: + :members: + :undoc-members: + :show-inheritance: apptools.undo.undo\_manager module ---------------------------------- .. automodule:: apptools.undo.undo_manager - :members: - :undoc-members: - :show-inheritance: + :members: + :undoc-members: + :show-inheritance: Module contents --------------- .. automodule:: apptools.undo - :members: - :undoc-members: - :show-inheritance: + :members: + :undoc-members: + :show-inheritance: diff --git a/_sources/index.rst.txt b/_sources/index.rst.txt index 9f69ab94c..1891a5802 100644 --- a/_sources/index.rst.txt +++ b/_sources/index.rst.txt @@ -5,15 +5,12 @@ AppTools Documentation :maxdepth: 2 :glob: - appscripting/* - permissions/Introduction - permissions/ApplicationAPI - permissions/DefaultPolicyManagerDataAPI - permissions/DefaultUserManagerDataAPI preferences/* scripting/* undo/* selection/* + naming/* + io/* api * :ref:`search` diff --git a/_sources/io/introduction.rst.txt b/_sources/io/introduction.rst.txt new file mode 100644 index 000000000..6bdd04ef5 --- /dev/null +++ b/_sources/io/introduction.rst.txt @@ -0,0 +1,28 @@ +File I/O +======== + +The :mod:`apptools.io` package provides a traited |File| object provides +properties and methods for common file path manipulation operations. Much of +this functionality was implemented before Python 3 `pathlib`_ standard library +became available to provide similar support. For new code we encourage users +to investigate if `pathlib`_ can satisfy their use cases before they turn to +the `apptools.io` |File| object + +HDF5 File Support +----------------- + +The :mod:`apptools.io.h5` sub-package provides a wrapper around `PyTables`_ +with a dictionary-style mapping. + + +.. + external links + +.. _pathlib: https://docs.python.org/3/library/pathlib.html +.. _PyTables: https://www.pytables.org/ + + +.. + # substitutions + +.. |File| replace:: :class:`~apptools.io.file.File` diff --git a/_sources/naming/Introduction.rst.txt b/_sources/naming/Introduction.rst.txt new file mode 100644 index 000000000..736f4b92a --- /dev/null +++ b/_sources/naming/Introduction.rst.txt @@ -0,0 +1,7 @@ +Naming +====== + +:mod:`apptools.naming` package is a Python implementation of the Naming portion of the `Java +Naming and Directory Interface `_, +including specific implementations for a heirarchy of Python objects. You can +also find the Java JNDI tutorial `here `_. diff --git a/_sources/preferences/Preferences.rst.txt b/_sources/preferences/Preferences.rst.txt index 54148f110..51ee93fd8 100644 --- a/_sources/preferences/Preferences.rst.txt +++ b/_sources/preferences/Preferences.rst.txt @@ -8,16 +8,16 @@ mechanism and each layer on top providing more convenient ways to get and set preference values. The Basic Preferences Mechanism -=============================== +------------------------------- Lets start by taking a look at the lowest layer which consists of the -IPreferences_ interface and its default implementation in the Preferences_ +|IPreferences| interface and its default implementation in the |Preferences| class. This layer implements the basic preferences system which is a hierarchical arrangement of preferences 'nodes' (where each node is simply an -object that implements the IPreferences_ interface). Nodes in the hierarchy can +object that implements the |IPreferences| interface). Nodes in the hierarchy can contain preference settings and/or child nodes. This layer also provides a default way to read and write preferences from the filesystem using the -excellent ConfigObj_ package. +excellent `ConfigObj`_ package. This all sounds a bit complicated but, believe me, it isn't! To prove it (hopefully) lets look at an example. Say I have the following preferences in @@ -40,9 +40,9 @@ I can create a preferences hierarchy from this file by:: >>> preferences.dump() Node() {} - Node(acme) {} - Node(ui) {'bgcolor': 'blue', 'ratio': '1.0', 'width': '50', 'visible': 'True'} - Node(splash_screen) {'image': 'splash', 'fgcolor': 'red'} + Node(acme) {} + Node(ui) {'bgcolor': 'blue', 'width': '50', 'ratio': '1.0', 'visible': 'True'} + Node(splash_screen) {'image': 'splash', 'fgcolor': 'red'} The 'dump' method (useful for debugging etc) simply 'pretty prints' a preferences hierarchy. The dictionary next to each node contains the node's @@ -109,7 +109,7 @@ preferences:: 'bgcolor' Strings, Glorious Strings -------------------------- +~~~~~~~~~~~~~~~~~~~~~~~~~ At this point it is worth mentioning that preferences are *always* stored and returned as strings. This is because of the limitations of the traditional @@ -136,10 +136,10 @@ discusses how we associate type information with our preferences to make getting and setting them more natural. Preferences and Types -===================== +--------------------- As mentioned previously, we would like to be able to get and set non-string -preferences in a more convenient way. This is where the PreferencesHelper_ +preferences in a more convenient way. This is where the |PreferencesHelper| class comes in. Let's take another look at 'example.ini':: @@ -162,7 +162,7 @@ preferences helper as follows:: class SplashScreenPreferences(PreferencesHelper): """ A preferences helper for the splash screen. """ - PREFERENCES_PATH = 'acme.ui' + preferences_path = 'acme.ui' bgcolor = Str width = Int @@ -174,7 +174,7 @@ preferences helper as follows:: >>> helper.bgcolor 'blue' >>> helper.width - 100 + 50 >>> helper.ratio 1.0 >>> helper.visible @@ -202,30 +202,14 @@ preferences node directly:: >>> preferences.set('acme.ui.ratio', 0.33) ratio 0.75 0.33 -If you always use the same preference node as the root of your preferences you -can also set the class attribute 'PreferencesHelper.preferences' to be that -node and from then on in, you don't have to pass a preferences collection in -each time you create a helper:: - - >>> PreferencesHelper.preferences = Preferences(filename='example.ini') - >>> helper = SplashScreenPreferences() - >>> helper.bgcolor - 'blue' - >>> helper.width - 100 - >>> helper.ratio - 1.0 - >>> helper.visible - True - Scoped Preferences -================== +------------------ In many applications the idea of preferences scopes is useful. In a scoped system, an actual preference value can be stored in any scope and when a call is made to the 'get' method the scopes are searched in order of precedence. -The default implementation (in the ScopedPreferences_ class) provides two +The default implementation (in the |ScopedPreferences| class) provides two scopes by default: 1) The application scope @@ -245,14 +229,14 @@ preferences is just like using the plain old non-scoped version:: >>> from apptools.preferences.api import ScopedPreferences >>> preferences = ScopedPreferences(filename='example.ini') >>> preferences.load('example.ini') - >>> p.dump() + >>> preferences.dump() - Node() {} - Node(application) {} - Node(acme) {} - Node(ui) {'bgcolor': 'blue', 'ratio': '1.0', 'width': '50', 'visible': 'True'} - Node(splash_screen) {'image': 'splash', 'fgcolor': 'red'} - Node(default) {} + Node() {} + Node(application) {} + Node(acme) {} + Node(ui) {'bgcolor': 'blue', 'width': '50', 'ratio': '1.0', 'visible': 'True'} + Node(splash_screen) {'image': 'splash', 'fgcolor': 'red'} + Node(default) {} Here you can see that the root node now has a child node representing each scope. @@ -275,29 +259,28 @@ So usually, we just use the scoped preferences as before:: >>> preferences.set('acme.ui.bgcolor', 'red') >>> preferences.dump() - Node() {} - Node(application) {} - Node(acme) {} - Node(ui) {'bgcolor': 'red', 'ratio': '1.0', 'width': '50', 'visible': 'True'} - Node(splash_screen) {'image': 'splash', 'fgcolor': 'red'} - Node(default) {} + Node() {} + Node(application) {} + Node(acme) {} + Node(ui) {'bgcolor': 'red', 'width': '50', 'ratio': '1.0', 'visible': 'True'} + Node(splash_screen) {'image': 'splash', 'fgcolor': 'red'} + Node(default) {} And, conveniently, preference helpers work just the same with scoped preferences too:: - >>> PreferencesHelper.preferences = ScopedPreferences(filename='example.ini') - >>> helper = SplashScreenPreferences() + >>> helper = SplashScreenPreferences(preferences=preferences) >>> helper.bgcolor - 'blue' + 'red' >>> helper.width - 100 + 50 >>> helper.ratio 1.0 >>> helper.visible True Accessing a particular scope ----------------------------- +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Should you care about getting or setting a preference in a particular scope then you use the following syntax:: @@ -307,14 +290,14 @@ then you use the following syntax:: 'red' >>> preferences.dump() - Node() {} - Node(application) {} - Node(acme) {} - Node(ui) {'bgcolor': 'red', 'ratio': '1.0', 'width': '50', 'visible': 'True'} - Node(splash_screen) {'image': 'splash', 'fgcolor': 'red'} - Node(default) {} - Node(acme) {} - Node(ui) {'bgcolor': 'red'} + Node() {} + Node(application) {} + Node(acme) {} + Node(ui) {'bgcolor': 'red', 'width': '50', 'ratio': '1.0', 'visible': 'True'} + Node(splash_screen) {'image': 'splash', 'fgcolor': 'red'} + Node(default) {} + Node(acme) {} + Node(ui) {'bgcolor': 'red'} You can also get hold of a scope via:: @@ -323,18 +306,24 @@ You can also get hold of a scope via:: And then perform any of the usual operations on it. Further Reading -=============== +--------------- So that's a quick tour around the basic useage of the preferences API. For more -imformation about what is provided take a look at the API_ documentation. +information about what is provided take a look at the :ref:`api-documentation`. If you are using Envisage to build your applications then you might also be -interested in the `Preferences in Envisage`_ section. - -.. _API: api/index.html -.. _ConfigObj: http://www.voidspace.org.uk/python/configobj.html -.. _IPreferences: ../../enthought/preferences/i_preferences.py -.. _Preferences: ../../enthought/preferences/preferences.py -.. _PreferencesHelper: ../../enthought/preferences/preferences_helper.py -.. _ScopedPreferences: ../../enthought/preferences/scoped_preferences.py -.. _`Preferences in Envisage`: PreferencesInEnvisage.html +interested in the |Preferences in Envisage| section. + +.. + external links + +.. _ConfigObj: https://configobj.readthedocs.io/en/latest + +.. + # substitutions + +.. |ScopedPreferences| replace:: :class:`~apptools.preferences.scoped_preferences.ScopedPreferences` +.. |IPreferences| replace:: :class:`~apptools.preferences.i_preferences.IPreferences` +.. |Preferences| replace:: :class:`~apptools.preferences.preferences.Preferences` +.. |PreferencesHelper| replace:: :class:`~apptools.preferences.preferences_helper.PreferencesHelper` +.. |Preferences in Envisage| replace:: :ref:`preferences-in-envisage` diff --git a/_sources/preferences/PreferencesInEnvisage.rst.txt b/_sources/preferences/PreferencesInEnvisage.rst.txt index f317477d1..931897eb6 100644 --- a/_sources/preferences/PreferencesInEnvisage.rst.txt +++ b/_sources/preferences/PreferencesInEnvisage.rst.txt @@ -1,3 +1,5 @@ +.. _preferences-in-envisage: + Preferences in Envisage ======================= @@ -5,7 +7,7 @@ This section discusses how an Envisage application uses the preferences mechanism. Envisage tries not to dictate too much, and so this describes the default behaviour, but you are free to override it as desired. -Envisage uses the default implementation of the ScopedPreferences_ class which +Envisage uses the default implementation of the |ScopedPreferences| class which is made available via the application's 'preferences' trait:: >>> application = Application(id='myapplication') @@ -17,7 +19,7 @@ Hence, you use the Envisage preferences just like you would any other scoped preferences. It also registers itself as the default preferences node used by the -PreferencesHelper_ class. Hence you don't need to provide a preferences node +|PreferencesHelper| class. Hence you don't need to provide a preferences node explicitly to your helper:: >>> helper = SplashScreenPreferences() @@ -43,5 +45,8 @@ e.g. To contribute a preference file for my plugin I might use:: def get_preferences(self, application): return ['pkgfile://mypackage:preferences.ini'] -.. _PreferencesHelper: ../../enthought/preferences/preferences_helper.py -.. _ScopedPreferences: ../../enthought/preferences/scoped_preferences.py +.. + # substitutions + +.. |PreferencesHelper| replace:: :class:`~apptools.preferences.preferences_helper.PreferencesHelper` +.. |ScopedPreferences| replace:: :class:`~apptools.preferences.scoped_preferences.ScopedPreferences` diff --git a/_sources/scripting/introduction.rst.txt b/_sources/scripting/introduction.rst.txt index 6772b764f..724a2767d 100644 --- a/_sources/scripting/introduction.rst.txt +++ b/_sources/scripting/introduction.rst.txt @@ -16,8 +16,8 @@ This package is not just a toy framework and is powerful enough to provide full script recording to the Mayavi_ application. Mayavi is a powerful 3D visualization tool that is part of ETS_. -.. _Mayavi: http://code.enthought.com/projects/mayavi -.. _ETS: http://code.enthought.com/projects/tool-suite.php +.. _Mayavi: https://docs.enthought.com/mayavi/mayavi/ +.. _ETS: https://docs.enthought.com/ets/ .. _scripting-api: @@ -44,7 +44,7 @@ The following example is taken from the test suite. Consider a set of simple objects organized in a hierarchy:: from traits.api import (HasTraits, Float, Instance, - Str, List, Bool, HasStrictTraits, Tuple, Range, TraitPrefixMap, + Str, List, Bool, HasStrictTraits, Tuple, PrefixMap, Range, Trait) from apptools.scripting.api import (Recorder, recordable, set_recorder) @@ -52,10 +52,11 @@ simple objects organized in a hierarchy:: class Property(HasStrictTraits): color = Tuple(Range(0.0, 1.0), Range(0.0, 1.0), Range(0.0, 1.0)) opacity = Range(0.0, 1.0, 1.0) - representation = Trait('surface', - TraitPrefixMap({'surface':2, - 'wireframe': 1, - 'points': 0})) + representation = PrefixMap( + {"surface": 2, "wireframe": 1, "points": 0}, + default_value="surface" + ) + class Toy(HasTraits): color = Str type = Str diff --git a/_sources/selection/selection.rst.txt b/_sources/selection/selection.rst.txt index 975ed2f9c..a57d9179e 100644 --- a/_sources/selection/selection.rst.txt +++ b/_sources/selection/selection.rst.txt @@ -141,55 +141,4 @@ If the items specified in the arguments are not available in the provider, a :class:`~apptools.selection.errors.ProviderNotRegisteredError` is raised, unless the optional keyword argument :attr:`ignore_missing` is set to ``True``. - -API Reference -------------- - -:mod:`apptools.selection` Package -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Users of the :mod:`apptools.selection` package can access the objects that are -part of the public API through the convenience :mod:`apptools.selection.api`. - -:mod:`~apptools.selection.selection_service` Module -''''''''''''''''''''''''''''''''''''''''''''''''''' - -.. automodule:: apptools.selection.selection_service - :members: - :undoc-members: - :show-inheritance: - -:mod:`~apptools.selection.i_selection_provider` Module -'''''''''''''''''''''''''''''''''''''''''''''''''''''' - -.. automodule:: apptools.selection.i_selection_provider - :members: - :undoc-members: - :show-inheritance: - -:mod:`~apptools.selection.is_selection` Module -'''''''''''''''''''''''''''''''''''''''''''''' - -.. automodule:: apptools.selection.i_selection - :members: - :undoc-members: - :show-inheritance: - -:mod:`~apptools.selection.list_selection` Module -'''''''''''''''''''''''''''''''''''''''''''''''' - -.. automodule:: apptools.selection.list_selection - :members: - :undoc-members: - :show-inheritance: - -:mod:`~apptools.selection.errors` Module -'''''''''''''''''''''''''''''''''''''''''''''''' - -.. automodule:: apptools.selection.errors - :members: - :undoc-members: - :show-inheritance: - - .. _envisage: http://docs.enthought.com/envisage/ diff --git a/_sources/undo/Introduction.rst.txt b/_sources/undo/Introduction.rst.txt index d182f862d..89dee28d6 100644 --- a/_sources/undo/Introduction.rst.txt +++ b/_sources/undo/Introduction.rst.txt @@ -103,12 +103,12 @@ interface. be the currently active stack. ``undo_name`` - This Unicode trait is the name of the command that can be undone, and will + This Str trait is the name of the command that can be undone, and will be empty if there is no such command. It is maintained by the undo manager. ``redo_name`` - This Unicode trait is the name of the command that can be redone, and will + This Str trait is the name of the command that can be redone, and will be empty if there is no such command. It is maintained by the undo manager. @@ -143,12 +143,12 @@ The ``CommandStack`` class is the default implementation of the data is saved to disk for example). ``undo_name`` - This Unicode trait is the name of the command that can be undone, and will + This Str trait is the name of the command that can be undone, and will be empty if there is no such command. It is maintained by the command stack. ``redo_name`` - This Unicode trait is the name of the command that can be redone, and will + This Str trait is the name of the command that can be redone, and will be empty if there is no such command. It is maintained by the command stack. @@ -199,7 +199,7 @@ any undoable/redoable command. operates on. It is not used by the framework itself. ``name`` - This Unicode trait is the name of the command as it will appear in any GUI + This Str trait is the name of the command as it will appear in any GUI element (e.g. in the text of an undo and redo menu entry). It may include ``&`` to indicate a keyboard shortcut which will be automatically removed whenever it is inappropriate. diff --git a/_static/basic.css b/_static/basic.css index 0807176ec..b04360d69 100644 --- a/_static/basic.css +++ b/_static/basic.css @@ -231,6 +231,16 @@ a.headerlink { visibility: hidden; } +a.brackets:before, +span.brackets > a:before{ + content: "["; +} + +a.brackets:after, +span.brackets > a:after { + content: "]"; +} + h1:hover > a.headerlink, h2:hover > a.headerlink, h3:hover > a.headerlink, @@ -279,6 +289,12 @@ img.align-center, .figure.align-center, object.align-center { margin-right: auto; } +img.align-default, .figure.align-default { + display: block; + margin-left: auto; + margin-right: auto; +} + .align-left { text-align: left; } @@ -287,6 +303,10 @@ img.align-center, .figure.align-center, object.align-center { text-align: center; } +.align-default { + text-align: center; +} + .align-right { text-align: right; } @@ -358,6 +378,11 @@ table.align-center { margin-right: auto; } +table.align-default { + margin-left: auto; + margin-right: auto; +} + table caption span.caption-number { font-style: italic; } @@ -391,6 +416,16 @@ table.citation td { border-bottom: none; } +th > p:first-child, +td > p:first-child { + margin-top: 0px; +} + +th > p:last-child, +td > p:last-child { + margin-bottom: 0px; +} + /* -- figures --------------------------------------------------------------- */ div.figure { @@ -460,11 +495,58 @@ ol.upperroman { list-style: upper-roman; } +li > p:first-child { + margin-top: 0px; +} + +li > p:last-child { + margin-bottom: 0px; +} + +dl.footnote > dt, +dl.citation > dt { + float: left; +} + +dl.footnote > dd, +dl.citation > dd { + margin-bottom: 0em; +} + +dl.footnote > dd:after, +dl.citation > dd:after { + content: ""; + clear: both; +} + +dl.field-list { + display: grid; + grid-template-columns: fit-content(30%) auto; +} + +dl.field-list > dt { + font-weight: bold; + word-break: break-word; + padding-left: 0.5em; + padding-right: 5px; +} + +dl.field-list > dt:after { + content: ":"; +} + +dl.field-list > dd { + padding-left: 0.5em; + margin-top: 0em; + margin-left: 0em; + margin-bottom: 0em; +} + dl { margin-bottom: 15px; } -dd p { +dd > p:first-child { margin-top: 0px; } @@ -537,6 +619,12 @@ dl.glossary dt { font-style: oblique; } +.classifier:before { + font-style: normal; + margin: 0.5em; + content: ":"; +} + abbr, acronym { border-bottom: dotted 1px; cursor: help; @@ -584,6 +672,10 @@ div.code-block-caption + div > div.highlight > pre { margin-top: 0; } +div.doctest > div.highlight span.gp { /* gp: Generic.Prompt */ + user-select: none; +} + div.code-block-caption span.caption-number { padding: 0.1em 0.3em; font-style: italic; diff --git a/_static/doctools.js b/_static/doctools.js index 344db17dd..b33f87fcb 100644 --- a/_static/doctools.js +++ b/_static/doctools.js @@ -87,14 +87,13 @@ jQuery.fn.highlightText = function(text, className) { node.nextSibling)); node.nodeValue = val.substr(0, pos); if (isInSVG) { - var bbox = span.getBBox(); var rect = document.createElementNS("http://www.w3.org/2000/svg", "rect"); - rect.x.baseVal.value = bbox.x; + var bbox = node.parentElement.getBBox(); + rect.x.baseVal.value = bbox.x; rect.y.baseVal.value = bbox.y; rect.width.baseVal.value = bbox.width; rect.height.baseVal.value = bbox.height; rect.setAttribute('class', className); - var parentOfText = node.parentNode.parentNode; addItems.push({ "parent": node.parentNode, "target": rect}); diff --git a/_static/documentation_options.js b/_static/documentation_options.js index df8bd0767..3ceefbbee 100644 --- a/_static/documentation_options.js +++ b/_static/documentation_options.js @@ -1,10 +1,11 @@ var DOCUMENTATION_OPTIONS = { URL_ROOT: document.getElementById("documentation_options").getAttribute('data-url_root'), - VERSION: '4.6.0.dev77', + VERSION: 'unknown', LANGUAGE: 'None', COLLAPSE_INDEX: false, + BUILDER: 'html', FILE_SUFFIX: '.html', HAS_SOURCE: true, SOURCELINK_SUFFIX: '.txt', - NAVIGATION_WITH_KEYS: false, + NAVIGATION_WITH_KEYS: false }; \ No newline at end of file diff --git a/_static/jquery-3.4.1.js b/_static/jquery-3.4.1.js new file mode 100644 index 000000000..773ad95c5 --- /dev/null +++ b/_static/jquery-3.4.1.js @@ -0,0 +1,10598 @@ +/*! + * jQuery JavaScript Library v3.4.1 + * https://jquery.com/ + * + * Includes Sizzle.js + * https://sizzlejs.com/ + * + * Copyright JS Foundation and other contributors + * Released under the MIT license + * https://jquery.org/license + * + * Date: 2019-05-01T21:04Z + */ +( function( global, factory ) { + + "use strict"; + + if ( typeof module === "object" && typeof module.exports === "object" ) { + + // For CommonJS and CommonJS-like environments where a proper `window` + // is present, execute the factory and get jQuery. + // For environments that do not have a `window` with a `document` + // (such as Node.js), expose a factory as module.exports. + // This accentuates the need for the creation of a real `window`. + // e.g. var jQuery = require("jquery")(window); + // See ticket #14549 for more info. + module.exports = global.document ? + factory( global, true ) : + function( w ) { + if ( !w.document ) { + throw new Error( "jQuery requires a window with a document" ); + } + return factory( w ); + }; + } else { + factory( global ); + } + +// Pass this if window is not defined yet +} )( typeof window !== "undefined" ? window : this, function( window, noGlobal ) { + +// Edge <= 12 - 13+, Firefox <=18 - 45+, IE 10 - 11, Safari 5.1 - 9+, iOS 6 - 9.1 +// throw exceptions when non-strict code (e.g., ASP.NET 4.5) accesses strict mode +// arguments.callee.caller (trac-13335). But as of jQuery 3.0 (2016), strict mode should be common +// enough that all such attempts are guarded in a try block. +"use strict"; + +var arr = []; + +var document = window.document; + +var getProto = Object.getPrototypeOf; + +var slice = arr.slice; + +var concat = arr.concat; + +var push = arr.push; + +var indexOf = arr.indexOf; + +var class2type = {}; + +var toString = class2type.toString; + +var hasOwn = class2type.hasOwnProperty; + +var fnToString = hasOwn.toString; + +var ObjectFunctionString = fnToString.call( Object ); + +var support = {}; + +var isFunction = function isFunction( obj ) { + + // Support: Chrome <=57, Firefox <=52 + // In some browsers, typeof returns "function" for HTML elements + // (i.e., `typeof document.createElement( "object" ) === "function"`). + // We don't want to classify *any* DOM node as a function. + return typeof obj === "function" && typeof obj.nodeType !== "number"; + }; + + +var isWindow = function isWindow( obj ) { + return obj != null && obj === obj.window; + }; + + + + + var preservedScriptAttributes = { + type: true, + src: true, + nonce: true, + noModule: true + }; + + function DOMEval( code, node, doc ) { + doc = doc || document; + + var i, val, + script = doc.createElement( "script" ); + + script.text = code; + if ( node ) { + for ( i in preservedScriptAttributes ) { + + // Support: Firefox 64+, Edge 18+ + // Some browsers don't support the "nonce" property on scripts. + // On the other hand, just using `getAttribute` is not enough as + // the `nonce` attribute is reset to an empty string whenever it + // becomes browsing-context connected. + // See https://github.com/whatwg/html/issues/2369 + // See https://html.spec.whatwg.org/#nonce-attributes + // The `node.getAttribute` check was added for the sake of + // `jQuery.globalEval` so that it can fake a nonce-containing node + // via an object. + val = node[ i ] || node.getAttribute && node.getAttribute( i ); + if ( val ) { + script.setAttribute( i, val ); + } + } + } + doc.head.appendChild( script ).parentNode.removeChild( script ); + } + + +function toType( obj ) { + if ( obj == null ) { + return obj + ""; + } + + // Support: Android <=2.3 only (functionish RegExp) + return typeof obj === "object" || typeof obj === "function" ? + class2type[ toString.call( obj ) ] || "object" : + typeof obj; +} +/* global Symbol */ +// Defining this global in .eslintrc.json would create a danger of using the global +// unguarded in another place, it seems safer to define global only for this module + + + +var + version = "3.4.1", + + // Define a local copy of jQuery + jQuery = function( selector, context ) { + + // The jQuery object is actually just the init constructor 'enhanced' + // Need init if jQuery is called (just allow error to be thrown if not included) + return new jQuery.fn.init( selector, context ); + }, + + // Support: Android <=4.0 only + // Make sure we trim BOM and NBSP + rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g; + +jQuery.fn = jQuery.prototype = { + + // The current version of jQuery being used + jquery: version, + + constructor: jQuery, + + // The default length of a jQuery object is 0 + length: 0, + + toArray: function() { + return slice.call( this ); + }, + + // Get the Nth element in the matched element set OR + // Get the whole matched element set as a clean array + get: function( num ) { + + // Return all the elements in a clean array + if ( num == null ) { + return slice.call( this ); + } + + // Return just the one element from the set + return num < 0 ? this[ num + this.length ] : this[ num ]; + }, + + // Take an array of elements and push it onto the stack + // (returning the new matched element set) + pushStack: function( elems ) { + + // Build a new jQuery matched element set + var ret = jQuery.merge( this.constructor(), elems ); + + // Add the old object onto the stack (as a reference) + ret.prevObject = this; + + // Return the newly-formed element set + return ret; + }, + + // Execute a callback for every element in the matched set. + each: function( callback ) { + return jQuery.each( this, callback ); + }, + + map: function( callback ) { + return this.pushStack( jQuery.map( this, function( elem, i ) { + return callback.call( elem, i, elem ); + } ) ); + }, + + slice: function() { + return this.pushStack( slice.apply( this, arguments ) ); + }, + + first: function() { + return this.eq( 0 ); + }, + + last: function() { + return this.eq( -1 ); + }, + + eq: function( i ) { + var len = this.length, + j = +i + ( i < 0 ? len : 0 ); + return this.pushStack( j >= 0 && j < len ? [ this[ j ] ] : [] ); + }, + + end: function() { + return this.prevObject || this.constructor(); + }, + + // For internal use only. + // Behaves like an Array's method, not like a jQuery method. + push: push, + sort: arr.sort, + splice: arr.splice +}; + +jQuery.extend = jQuery.fn.extend = function() { + var options, name, src, copy, copyIsArray, clone, + target = arguments[ 0 ] || {}, + i = 1, + length = arguments.length, + deep = false; + + // Handle a deep copy situation + if ( typeof target === "boolean" ) { + deep = target; + + // Skip the boolean and the target + target = arguments[ i ] || {}; + i++; + } + + // Handle case when target is a string or something (possible in deep copy) + if ( typeof target !== "object" && !isFunction( target ) ) { + target = {}; + } + + // Extend jQuery itself if only one argument is passed + if ( i === length ) { + target = this; + i--; + } + + for ( ; i < length; i++ ) { + + // Only deal with non-null/undefined values + if ( ( options = arguments[ i ] ) != null ) { + + // Extend the base object + for ( name in options ) { + copy = options[ name ]; + + // Prevent Object.prototype pollution + // Prevent never-ending loop + if ( name === "__proto__" || target === copy ) { + continue; + } + + // Recurse if we're merging plain objects or arrays + if ( deep && copy && ( jQuery.isPlainObject( copy ) || + ( copyIsArray = Array.isArray( copy ) ) ) ) { + src = target[ name ]; + + // Ensure proper type for the source value + if ( copyIsArray && !Array.isArray( src ) ) { + clone = []; + } else if ( !copyIsArray && !jQuery.isPlainObject( src ) ) { + clone = {}; + } else { + clone = src; + } + copyIsArray = false; + + // Never move original objects, clone them + target[ name ] = jQuery.extend( deep, clone, copy ); + + // Don't bring in undefined values + } else if ( copy !== undefined ) { + target[ name ] = copy; + } + } + } + } + + // Return the modified object + return target; +}; + +jQuery.extend( { + + // Unique for each copy of jQuery on the page + expando: "jQuery" + ( version + Math.random() ).replace( /\D/g, "" ), + + // Assume jQuery is ready without the ready module + isReady: true, + + error: function( msg ) { + throw new Error( msg ); + }, + + noop: function() {}, + + isPlainObject: function( obj ) { + var proto, Ctor; + + // Detect obvious negatives + // Use toString instead of jQuery.type to catch host objects + if ( !obj || toString.call( obj ) !== "[object Object]" ) { + return false; + } + + proto = getProto( obj ); + + // Objects with no prototype (e.g., `Object.create( null )`) are plain + if ( !proto ) { + return true; + } + + // Objects with prototype are plain iff they were constructed by a global Object function + Ctor = hasOwn.call( proto, "constructor" ) && proto.constructor; + return typeof Ctor === "function" && fnToString.call( Ctor ) === ObjectFunctionString; + }, + + isEmptyObject: function( obj ) { + var name; + + for ( name in obj ) { + return false; + } + return true; + }, + + // Evaluates a script in a global context + globalEval: function( code, options ) { + DOMEval( code, { nonce: options && options.nonce } ); + }, + + each: function( obj, callback ) { + var length, i = 0; + + if ( isArrayLike( obj ) ) { + length = obj.length; + for ( ; i < length; i++ ) { + if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) { + break; + } + } + } else { + for ( i in obj ) { + if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) { + break; + } + } + } + + return obj; + }, + + // Support: Android <=4.0 only + trim: function( text ) { + return text == null ? + "" : + ( text + "" ).replace( rtrim, "" ); + }, + + // results is for internal usage only + makeArray: function( arr, results ) { + var ret = results || []; + + if ( arr != null ) { + if ( isArrayLike( Object( arr ) ) ) { + jQuery.merge( ret, + typeof arr === "string" ? + [ arr ] : arr + ); + } else { + push.call( ret, arr ); + } + } + + return ret; + }, + + inArray: function( elem, arr, i ) { + return arr == null ? -1 : indexOf.call( arr, elem, i ); + }, + + // Support: Android <=4.0 only, PhantomJS 1 only + // push.apply(_, arraylike) throws on ancient WebKit + merge: function( first, second ) { + var len = +second.length, + j = 0, + i = first.length; + + for ( ; j < len; j++ ) { + first[ i++ ] = second[ j ]; + } + + first.length = i; + + return first; + }, + + grep: function( elems, callback, invert ) { + var callbackInverse, + matches = [], + i = 0, + length = elems.length, + callbackExpect = !invert; + + // Go through the array, only saving the items + // that pass the validator function + for ( ; i < length; i++ ) { + callbackInverse = !callback( elems[ i ], i ); + if ( callbackInverse !== callbackExpect ) { + matches.push( elems[ i ] ); + } + } + + return matches; + }, + + // arg is for internal usage only + map: function( elems, callback, arg ) { + var length, value, + i = 0, + ret = []; + + // Go through the array, translating each of the items to their new values + if ( isArrayLike( elems ) ) { + length = elems.length; + for ( ; i < length; i++ ) { + value = callback( elems[ i ], i, arg ); + + if ( value != null ) { + ret.push( value ); + } + } + + // Go through every key on the object, + } else { + for ( i in elems ) { + value = callback( elems[ i ], i, arg ); + + if ( value != null ) { + ret.push( value ); + } + } + } + + // Flatten any nested arrays + return concat.apply( [], ret ); + }, + + // A global GUID counter for objects + guid: 1, + + // jQuery.support is not used in Core but other projects attach their + // properties to it so it needs to exist. + support: support +} ); + +if ( typeof Symbol === "function" ) { + jQuery.fn[ Symbol.iterator ] = arr[ Symbol.iterator ]; +} + +// Populate the class2type map +jQuery.each( "Boolean Number String Function Array Date RegExp Object Error Symbol".split( " " ), +function( i, name ) { + class2type[ "[object " + name + "]" ] = name.toLowerCase(); +} ); + +function isArrayLike( obj ) { + + // Support: real iOS 8.2 only (not reproducible in simulator) + // `in` check used to prevent JIT error (gh-2145) + // hasOwn isn't used here due to false negatives + // regarding Nodelist length in IE + var length = !!obj && "length" in obj && obj.length, + type = toType( obj ); + + if ( isFunction( obj ) || isWindow( obj ) ) { + return false; + } + + return type === "array" || length === 0 || + typeof length === "number" && length > 0 && ( length - 1 ) in obj; +} +var Sizzle = +/*! + * Sizzle CSS Selector Engine v2.3.4 + * https://sizzlejs.com/ + * + * Copyright JS Foundation and other contributors + * Released under the MIT license + * https://js.foundation/ + * + * Date: 2019-04-08 + */ +(function( window ) { + +var i, + support, + Expr, + getText, + isXML, + tokenize, + compile, + select, + outermostContext, + sortInput, + hasDuplicate, + + // Local document vars + setDocument, + document, + docElem, + documentIsHTML, + rbuggyQSA, + rbuggyMatches, + matches, + contains, + + // Instance-specific data + expando = "sizzle" + 1 * new Date(), + preferredDoc = window.document, + dirruns = 0, + done = 0, + classCache = createCache(), + tokenCache = createCache(), + compilerCache = createCache(), + nonnativeSelectorCache = createCache(), + sortOrder = function( a, b ) { + if ( a === b ) { + hasDuplicate = true; + } + return 0; + }, + + // Instance methods + hasOwn = ({}).hasOwnProperty, + arr = [], + pop = arr.pop, + push_native = arr.push, + push = arr.push, + slice = arr.slice, + // Use a stripped-down indexOf as it's faster than native + // https://jsperf.com/thor-indexof-vs-for/5 + indexOf = function( list, elem ) { + var i = 0, + len = list.length; + for ( ; i < len; i++ ) { + if ( list[i] === elem ) { + return i; + } + } + return -1; + }, + + booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped", + + // Regular expressions + + // http://www.w3.org/TR/css3-selectors/#whitespace + whitespace = "[\\x20\\t\\r\\n\\f]", + + // http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier + identifier = "(?:\\\\.|[\\w-]|[^\0-\\xa0])+", + + // Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors + attributes = "\\[" + whitespace + "*(" + identifier + ")(?:" + whitespace + + // Operator (capture 2) + "*([*^$|!~]?=)" + whitespace + + // "Attribute values must be CSS identifiers [capture 5] or strings [capture 3 or capture 4]" + "*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" + whitespace + + "*\\]", + + pseudos = ":(" + identifier + ")(?:\\((" + + // To reduce the number of selectors needing tokenize in the preFilter, prefer arguments: + // 1. quoted (capture 3; capture 4 or capture 5) + "('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" + + // 2. simple (capture 6) + "((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" + + // 3. anything else (capture 2) + ".*" + + ")\\)|)", + + // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter + rwhitespace = new RegExp( whitespace + "+", "g" ), + rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ), + + rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ), + rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + "*" ), + rdescend = new RegExp( whitespace + "|>" ), + + rpseudo = new RegExp( pseudos ), + ridentifier = new RegExp( "^" + identifier + "$" ), + + matchExpr = { + "ID": new RegExp( "^#(" + identifier + ")" ), + "CLASS": new RegExp( "^\\.(" + identifier + ")" ), + "TAG": new RegExp( "^(" + identifier + "|[*])" ), + "ATTR": new RegExp( "^" + attributes ), + "PSEUDO": new RegExp( "^" + pseudos ), + "CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + whitespace + + "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace + + "*(\\d+)|))" + whitespace + "*\\)|)", "i" ), + "bool": new RegExp( "^(?:" + booleans + ")$", "i" ), + // For use in libraries implementing .is() + // We use this for POS matching in `select` + "needsContext": new RegExp( "^" + whitespace + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" + + whitespace + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" ) + }, + + rhtml = /HTML$/i, + rinputs = /^(?:input|select|textarea|button)$/i, + rheader = /^h\d$/i, + + rnative = /^[^{]+\{\s*\[native \w/, + + // Easily-parseable/retrievable ID or TAG or CLASS selectors + rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/, + + rsibling = /[+~]/, + + // CSS escapes + // http://www.w3.org/TR/CSS21/syndata.html#escaped-characters + runescape = new RegExp( "\\\\([\\da-f]{1,6}" + whitespace + "?|(" + whitespace + ")|.)", "ig" ), + funescape = function( _, escaped, escapedWhitespace ) { + var high = "0x" + escaped - 0x10000; + // NaN means non-codepoint + // Support: Firefox<24 + // Workaround erroneous numeric interpretation of +"0x" + return high !== high || escapedWhitespace ? + escaped : + high < 0 ? + // BMP codepoint + String.fromCharCode( high + 0x10000 ) : + // Supplemental Plane codepoint (surrogate pair) + String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 ); + }, + + // CSS string/identifier serialization + // https://drafts.csswg.org/cssom/#common-serializing-idioms + rcssescape = /([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g, + fcssescape = function( ch, asCodePoint ) { + if ( asCodePoint ) { + + // U+0000 NULL becomes U+FFFD REPLACEMENT CHARACTER + if ( ch === "\0" ) { + return "\uFFFD"; + } + + // Control characters and (dependent upon position) numbers get escaped as code points + return ch.slice( 0, -1 ) + "\\" + ch.charCodeAt( ch.length - 1 ).toString( 16 ) + " "; + } + + // Other potentially-special ASCII characters get backslash-escaped + return "\\" + ch; + }, + + // Used for iframes + // See setDocument() + // Removing the function wrapper causes a "Permission Denied" + // error in IE + unloadHandler = function() { + setDocument(); + }, + + inDisabledFieldset = addCombinator( + function( elem ) { + return elem.disabled === true && elem.nodeName.toLowerCase() === "fieldset"; + }, + { dir: "parentNode", next: "legend" } + ); + +// Optimize for push.apply( _, NodeList ) +try { + push.apply( + (arr = slice.call( preferredDoc.childNodes )), + preferredDoc.childNodes + ); + // Support: Android<4.0 + // Detect silently failing push.apply + arr[ preferredDoc.childNodes.length ].nodeType; +} catch ( e ) { + push = { apply: arr.length ? + + // Leverage slice if possible + function( target, els ) { + push_native.apply( target, slice.call(els) ); + } : + + // Support: IE<9 + // Otherwise append directly + function( target, els ) { + var j = target.length, + i = 0; + // Can't trust NodeList.length + while ( (target[j++] = els[i++]) ) {} + target.length = j - 1; + } + }; +} + +function Sizzle( selector, context, results, seed ) { + var m, i, elem, nid, match, groups, newSelector, + newContext = context && context.ownerDocument, + + // nodeType defaults to 9, since context defaults to document + nodeType = context ? context.nodeType : 9; + + results = results || []; + + // Return early from calls with invalid selector or context + if ( typeof selector !== "string" || !selector || + nodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) { + + return results; + } + + // Try to shortcut find operations (as opposed to filters) in HTML documents + if ( !seed ) { + + if ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) { + setDocument( context ); + } + context = context || document; + + if ( documentIsHTML ) { + + // If the selector is sufficiently simple, try using a "get*By*" DOM method + // (excepting DocumentFragment context, where the methods don't exist) + if ( nodeType !== 11 && (match = rquickExpr.exec( selector )) ) { + + // ID selector + if ( (m = match[1]) ) { + + // Document context + if ( nodeType === 9 ) { + if ( (elem = context.getElementById( m )) ) { + + // Support: IE, Opera, Webkit + // TODO: identify versions + // getElementById can match elements by name instead of ID + if ( elem.id === m ) { + results.push( elem ); + return results; + } + } else { + return results; + } + + // Element context + } else { + + // Support: IE, Opera, Webkit + // TODO: identify versions + // getElementById can match elements by name instead of ID + if ( newContext && (elem = newContext.getElementById( m )) && + contains( context, elem ) && + elem.id === m ) { + + results.push( elem ); + return results; + } + } + + // Type selector + } else if ( match[2] ) { + push.apply( results, context.getElementsByTagName( selector ) ); + return results; + + // Class selector + } else if ( (m = match[3]) && support.getElementsByClassName && + context.getElementsByClassName ) { + + push.apply( results, context.getElementsByClassName( m ) ); + return results; + } + } + + // Take advantage of querySelectorAll + if ( support.qsa && + !nonnativeSelectorCache[ selector + " " ] && + (!rbuggyQSA || !rbuggyQSA.test( selector )) && + + // Support: IE 8 only + // Exclude object elements + (nodeType !== 1 || context.nodeName.toLowerCase() !== "object") ) { + + newSelector = selector; + newContext = context; + + // qSA considers elements outside a scoping root when evaluating child or + // descendant combinators, which is not what we want. + // In such cases, we work around the behavior by prefixing every selector in the + // list with an ID selector referencing the scope context. + // Thanks to Andrew Dupont for this technique. + if ( nodeType === 1 && rdescend.test( selector ) ) { + + // Capture the context ID, setting it first if necessary + if ( (nid = context.getAttribute( "id" )) ) { + nid = nid.replace( rcssescape, fcssescape ); + } else { + context.setAttribute( "id", (nid = expando) ); + } + + // Prefix every selector in the list + groups = tokenize( selector ); + i = groups.length; + while ( i-- ) { + groups[i] = "#" + nid + " " + toSelector( groups[i] ); + } + newSelector = groups.join( "," ); + + // Expand context for sibling selectors + newContext = rsibling.test( selector ) && testContext( context.parentNode ) || + context; + } + + try { + push.apply( results, + newContext.querySelectorAll( newSelector ) + ); + return results; + } catch ( qsaError ) { + nonnativeSelectorCache( selector, true ); + } finally { + if ( nid === expando ) { + context.removeAttribute( "id" ); + } + } + } + } + } + + // All others + return select( selector.replace( rtrim, "$1" ), context, results, seed ); +} + +/** + * Create key-value caches of limited size + * @returns {function(string, object)} Returns the Object data after storing it on itself with + * property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength) + * deleting the oldest entry + */ +function createCache() { + var keys = []; + + function cache( key, value ) { + // Use (key + " ") to avoid collision with native prototype properties (see Issue #157) + if ( keys.push( key + " " ) > Expr.cacheLength ) { + // Only keep the most recent entries + delete cache[ keys.shift() ]; + } + return (cache[ key + " " ] = value); + } + return cache; +} + +/** + * Mark a function for special use by Sizzle + * @param {Function} fn The function to mark + */ +function markFunction( fn ) { + fn[ expando ] = true; + return fn; +} + +/** + * Support testing using an element + * @param {Function} fn Passed the created element and returns a boolean result + */ +function assert( fn ) { + var el = document.createElement("fieldset"); + + try { + return !!fn( el ); + } catch (e) { + return false; + } finally { + // Remove from its parent by default + if ( el.parentNode ) { + el.parentNode.removeChild( el ); + } + // release memory in IE + el = null; + } +} + +/** + * Adds the same handler for all of the specified attrs + * @param {String} attrs Pipe-separated list of attributes + * @param {Function} handler The method that will be applied + */ +function addHandle( attrs, handler ) { + var arr = attrs.split("|"), + i = arr.length; + + while ( i-- ) { + Expr.attrHandle[ arr[i] ] = handler; + } +} + +/** + * Checks document order of two siblings + * @param {Element} a + * @param {Element} b + * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b + */ +function siblingCheck( a, b ) { + var cur = b && a, + diff = cur && a.nodeType === 1 && b.nodeType === 1 && + a.sourceIndex - b.sourceIndex; + + // Use IE sourceIndex if available on both nodes + if ( diff ) { + return diff; + } + + // Check if b follows a + if ( cur ) { + while ( (cur = cur.nextSibling) ) { + if ( cur === b ) { + return -1; + } + } + } + + return a ? 1 : -1; +} + +/** + * Returns a function to use in pseudos for input types + * @param {String} type + */ +function createInputPseudo( type ) { + return function( elem ) { + var name = elem.nodeName.toLowerCase(); + return name === "input" && elem.type === type; + }; +} + +/** + * Returns a function to use in pseudos for buttons + * @param {String} type + */ +function createButtonPseudo( type ) { + return function( elem ) { + var name = elem.nodeName.toLowerCase(); + return (name === "input" || name === "button") && elem.type === type; + }; +} + +/** + * Returns a function to use in pseudos for :enabled/:disabled + * @param {Boolean} disabled true for :disabled; false for :enabled + */ +function createDisabledPseudo( disabled ) { + + // Known :disabled false positives: fieldset[disabled] > legend:nth-of-type(n+2) :can-disable + return function( elem ) { + + // Only certain elements can match :enabled or :disabled + // https://html.spec.whatwg.org/multipage/scripting.html#selector-enabled + // https://html.spec.whatwg.org/multipage/scripting.html#selector-disabled + if ( "form" in elem ) { + + // Check for inherited disabledness on relevant non-disabled elements: + // * listed form-associated elements in a disabled fieldset + // https://html.spec.whatwg.org/multipage/forms.html#category-listed + // https://html.spec.whatwg.org/multipage/forms.html#concept-fe-disabled + // * option elements in a disabled optgroup + // https://html.spec.whatwg.org/multipage/forms.html#concept-option-disabled + // All such elements have a "form" property. + if ( elem.parentNode && elem.disabled === false ) { + + // Option elements defer to a parent optgroup if present + if ( "label" in elem ) { + if ( "label" in elem.parentNode ) { + return elem.parentNode.disabled === disabled; + } else { + return elem.disabled === disabled; + } + } + + // Support: IE 6 - 11 + // Use the isDisabled shortcut property to check for disabled fieldset ancestors + return elem.isDisabled === disabled || + + // Where there is no isDisabled, check manually + /* jshint -W018 */ + elem.isDisabled !== !disabled && + inDisabledFieldset( elem ) === disabled; + } + + return elem.disabled === disabled; + + // Try to winnow out elements that can't be disabled before trusting the disabled property. + // Some victims get caught in our net (label, legend, menu, track), but it shouldn't + // even exist on them, let alone have a boolean value. + } else if ( "label" in elem ) { + return elem.disabled === disabled; + } + + // Remaining elements are neither :enabled nor :disabled + return false; + }; +} + +/** + * Returns a function to use in pseudos for positionals + * @param {Function} fn + */ +function createPositionalPseudo( fn ) { + return markFunction(function( argument ) { + argument = +argument; + return markFunction(function( seed, matches ) { + var j, + matchIndexes = fn( [], seed.length, argument ), + i = matchIndexes.length; + + // Match elements found at the specified indexes + while ( i-- ) { + if ( seed[ (j = matchIndexes[i]) ] ) { + seed[j] = !(matches[j] = seed[j]); + } + } + }); + }); +} + +/** + * Checks a node for validity as a Sizzle context + * @param {Element|Object=} context + * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value + */ +function testContext( context ) { + return context && typeof context.getElementsByTagName !== "undefined" && context; +} + +// Expose support vars for convenience +support = Sizzle.support = {}; + +/** + * Detects XML nodes + * @param {Element|Object} elem An element or a document + * @returns {Boolean} True iff elem is a non-HTML XML node + */ +isXML = Sizzle.isXML = function( elem ) { + var namespace = elem.namespaceURI, + docElem = (elem.ownerDocument || elem).documentElement; + + // Support: IE <=8 + // Assume HTML when documentElement doesn't yet exist, such as inside loading iframes + // https://bugs.jquery.com/ticket/4833 + return !rhtml.test( namespace || docElem && docElem.nodeName || "HTML" ); +}; + +/** + * Sets document-related variables once based on the current document + * @param {Element|Object} [doc] An element or document object to use to set the document + * @returns {Object} Returns the current document + */ +setDocument = Sizzle.setDocument = function( node ) { + var hasCompare, subWindow, + doc = node ? node.ownerDocument || node : preferredDoc; + + // Return early if doc is invalid or already selected + if ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) { + return document; + } + + // Update global variables + document = doc; + docElem = document.documentElement; + documentIsHTML = !isXML( document ); + + // Support: IE 9-11, Edge + // Accessing iframe documents after unload throws "permission denied" errors (jQuery #13936) + if ( preferredDoc !== document && + (subWindow = document.defaultView) && subWindow.top !== subWindow ) { + + // Support: IE 11, Edge + if ( subWindow.addEventListener ) { + subWindow.addEventListener( "unload", unloadHandler, false ); + + // Support: IE 9 - 10 only + } else if ( subWindow.attachEvent ) { + subWindow.attachEvent( "onunload", unloadHandler ); + } + } + + /* Attributes + ---------------------------------------------------------------------- */ + + // Support: IE<8 + // Verify that getAttribute really returns attributes and not properties + // (excepting IE8 booleans) + support.attributes = assert(function( el ) { + el.className = "i"; + return !el.getAttribute("className"); + }); + + /* getElement(s)By* + ---------------------------------------------------------------------- */ + + // Check if getElementsByTagName("*") returns only elements + support.getElementsByTagName = assert(function( el ) { + el.appendChild( document.createComment("") ); + return !el.getElementsByTagName("*").length; + }); + + // Support: IE<9 + support.getElementsByClassName = rnative.test( document.getElementsByClassName ); + + // Support: IE<10 + // Check if getElementById returns elements by name + // The broken getElementById methods don't pick up programmatically-set names, + // so use a roundabout getElementsByName test + support.getById = assert(function( el ) { + docElem.appendChild( el ).id = expando; + return !document.getElementsByName || !document.getElementsByName( expando ).length; + }); + + // ID filter and find + if ( support.getById ) { + Expr.filter["ID"] = function( id ) { + var attrId = id.replace( runescape, funescape ); + return function( elem ) { + return elem.getAttribute("id") === attrId; + }; + }; + Expr.find["ID"] = function( id, context ) { + if ( typeof context.getElementById !== "undefined" && documentIsHTML ) { + var elem = context.getElementById( id ); + return elem ? [ elem ] : []; + } + }; + } else { + Expr.filter["ID"] = function( id ) { + var attrId = id.replace( runescape, funescape ); + return function( elem ) { + var node = typeof elem.getAttributeNode !== "undefined" && + elem.getAttributeNode("id"); + return node && node.value === attrId; + }; + }; + + // Support: IE 6 - 7 only + // getElementById is not reliable as a find shortcut + Expr.find["ID"] = function( id, context ) { + if ( typeof context.getElementById !== "undefined" && documentIsHTML ) { + var node, i, elems, + elem = context.getElementById( id ); + + if ( elem ) { + + // Verify the id attribute + node = elem.getAttributeNode("id"); + if ( node && node.value === id ) { + return [ elem ]; + } + + // Fall back on getElementsByName + elems = context.getElementsByName( id ); + i = 0; + while ( (elem = elems[i++]) ) { + node = elem.getAttributeNode("id"); + if ( node && node.value === id ) { + return [ elem ]; + } + } + } + + return []; + } + }; + } + + // Tag + Expr.find["TAG"] = support.getElementsByTagName ? + function( tag, context ) { + if ( typeof context.getElementsByTagName !== "undefined" ) { + return context.getElementsByTagName( tag ); + + // DocumentFragment nodes don't have gEBTN + } else if ( support.qsa ) { + return context.querySelectorAll( tag ); + } + } : + + function( tag, context ) { + var elem, + tmp = [], + i = 0, + // By happy coincidence, a (broken) gEBTN appears on DocumentFragment nodes too + results = context.getElementsByTagName( tag ); + + // Filter out possible comments + if ( tag === "*" ) { + while ( (elem = results[i++]) ) { + if ( elem.nodeType === 1 ) { + tmp.push( elem ); + } + } + + return tmp; + } + return results; + }; + + // Class + Expr.find["CLASS"] = support.getElementsByClassName && function( className, context ) { + if ( typeof context.getElementsByClassName !== "undefined" && documentIsHTML ) { + return context.getElementsByClassName( className ); + } + }; + + /* QSA/matchesSelector + ---------------------------------------------------------------------- */ + + // QSA and matchesSelector support + + // matchesSelector(:active) reports false when true (IE9/Opera 11.5) + rbuggyMatches = []; + + // qSa(:focus) reports false when true (Chrome 21) + // We allow this because of a bug in IE8/9 that throws an error + // whenever `document.activeElement` is accessed on an iframe + // So, we allow :focus to pass through QSA all the time to avoid the IE error + // See https://bugs.jquery.com/ticket/13378 + rbuggyQSA = []; + + if ( (support.qsa = rnative.test( document.querySelectorAll )) ) { + // Build QSA regex + // Regex strategy adopted from Diego Perini + assert(function( el ) { + // Select is set to empty string on purpose + // This is to test IE's treatment of not explicitly + // setting a boolean content attribute, + // since its presence should be enough + // https://bugs.jquery.com/ticket/12359 + docElem.appendChild( el ).innerHTML = "" + + ""; + + // Support: IE8, Opera 11-12.16 + // Nothing should be selected when empty strings follow ^= or $= or *= + // The test attribute must be unknown in Opera but "safe" for WinRT + // https://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section + if ( el.querySelectorAll("[msallowcapture^='']").length ) { + rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" ); + } + + // Support: IE8 + // Boolean attributes and "value" are not treated correctly + if ( !el.querySelectorAll("[selected]").length ) { + rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" ); + } + + // Support: Chrome<29, Android<4.4, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.8+ + if ( !el.querySelectorAll( "[id~=" + expando + "-]" ).length ) { + rbuggyQSA.push("~="); + } + + // Webkit/Opera - :checked should return selected option elements + // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked + // IE8 throws error here and will not see later tests + if ( !el.querySelectorAll(":checked").length ) { + rbuggyQSA.push(":checked"); + } + + // Support: Safari 8+, iOS 8+ + // https://bugs.webkit.org/show_bug.cgi?id=136851 + // In-page `selector#id sibling-combinator selector` fails + if ( !el.querySelectorAll( "a#" + expando + "+*" ).length ) { + rbuggyQSA.push(".#.+[+~]"); + } + }); + + assert(function( el ) { + el.innerHTML = "" + + ""; + + // Support: Windows 8 Native Apps + // The type and name attributes are restricted during .innerHTML assignment + var input = document.createElement("input"); + input.setAttribute( "type", "hidden" ); + el.appendChild( input ).setAttribute( "name", "D" ); + + // Support: IE8 + // Enforce case-sensitivity of name attribute + if ( el.querySelectorAll("[name=d]").length ) { + rbuggyQSA.push( "name" + whitespace + "*[*^$|!~]?=" ); + } + + // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled) + // IE8 throws error here and will not see later tests + if ( el.querySelectorAll(":enabled").length !== 2 ) { + rbuggyQSA.push( ":enabled", ":disabled" ); + } + + // Support: IE9-11+ + // IE's :disabled selector does not pick up the children of disabled fieldsets + docElem.appendChild( el ).disabled = true; + if ( el.querySelectorAll(":disabled").length !== 2 ) { + rbuggyQSA.push( ":enabled", ":disabled" ); + } + + // Opera 10-11 does not throw on post-comma invalid pseudos + el.querySelectorAll("*,:x"); + rbuggyQSA.push(",.*:"); + }); + } + + if ( (support.matchesSelector = rnative.test( (matches = docElem.matches || + docElem.webkitMatchesSelector || + docElem.mozMatchesSelector || + docElem.oMatchesSelector || + docElem.msMatchesSelector) )) ) { + + assert(function( el ) { + // Check to see if it's possible to do matchesSelector + // on a disconnected node (IE 9) + support.disconnectedMatch = matches.call( el, "*" ); + + // This should fail with an exception + // Gecko does not error, returns false instead + matches.call( el, "[s!='']:x" ); + rbuggyMatches.push( "!=", pseudos ); + }); + } + + rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join("|") ); + rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join("|") ); + + /* Contains + ---------------------------------------------------------------------- */ + hasCompare = rnative.test( docElem.compareDocumentPosition ); + + // Element contains another + // Purposefully self-exclusive + // As in, an element does not contain itself + contains = hasCompare || rnative.test( docElem.contains ) ? + function( a, b ) { + var adown = a.nodeType === 9 ? a.documentElement : a, + bup = b && b.parentNode; + return a === bup || !!( bup && bup.nodeType === 1 && ( + adown.contains ? + adown.contains( bup ) : + a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16 + )); + } : + function( a, b ) { + if ( b ) { + while ( (b = b.parentNode) ) { + if ( b === a ) { + return true; + } + } + } + return false; + }; + + /* Sorting + ---------------------------------------------------------------------- */ + + // Document order sorting + sortOrder = hasCompare ? + function( a, b ) { + + // Flag for duplicate removal + if ( a === b ) { + hasDuplicate = true; + return 0; + } + + // Sort on method existence if only one input has compareDocumentPosition + var compare = !a.compareDocumentPosition - !b.compareDocumentPosition; + if ( compare ) { + return compare; + } + + // Calculate position if both inputs belong to the same document + compare = ( a.ownerDocument || a ) === ( b.ownerDocument || b ) ? + a.compareDocumentPosition( b ) : + + // Otherwise we know they are disconnected + 1; + + // Disconnected nodes + if ( compare & 1 || + (!support.sortDetached && b.compareDocumentPosition( a ) === compare) ) { + + // Choose the first element that is related to our preferred document + if ( a === document || a.ownerDocument === preferredDoc && contains(preferredDoc, a) ) { + return -1; + } + if ( b === document || b.ownerDocument === preferredDoc && contains(preferredDoc, b) ) { + return 1; + } + + // Maintain original order + return sortInput ? + ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) : + 0; + } + + return compare & 4 ? -1 : 1; + } : + function( a, b ) { + // Exit early if the nodes are identical + if ( a === b ) { + hasDuplicate = true; + return 0; + } + + var cur, + i = 0, + aup = a.parentNode, + bup = b.parentNode, + ap = [ a ], + bp = [ b ]; + + // Parentless nodes are either documents or disconnected + if ( !aup || !bup ) { + return a === document ? -1 : + b === document ? 1 : + aup ? -1 : + bup ? 1 : + sortInput ? + ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) : + 0; + + // If the nodes are siblings, we can do a quick check + } else if ( aup === bup ) { + return siblingCheck( a, b ); + } + + // Otherwise we need full lists of their ancestors for comparison + cur = a; + while ( (cur = cur.parentNode) ) { + ap.unshift( cur ); + } + cur = b; + while ( (cur = cur.parentNode) ) { + bp.unshift( cur ); + } + + // Walk down the tree looking for a discrepancy + while ( ap[i] === bp[i] ) { + i++; + } + + return i ? + // Do a sibling check if the nodes have a common ancestor + siblingCheck( ap[i], bp[i] ) : + + // Otherwise nodes in our document sort first + ap[i] === preferredDoc ? -1 : + bp[i] === preferredDoc ? 1 : + 0; + }; + + return document; +}; + +Sizzle.matches = function( expr, elements ) { + return Sizzle( expr, null, null, elements ); +}; + +Sizzle.matchesSelector = function( elem, expr ) { + // Set document vars if needed + if ( ( elem.ownerDocument || elem ) !== document ) { + setDocument( elem ); + } + + if ( support.matchesSelector && documentIsHTML && + !nonnativeSelectorCache[ expr + " " ] && + ( !rbuggyMatches || !rbuggyMatches.test( expr ) ) && + ( !rbuggyQSA || !rbuggyQSA.test( expr ) ) ) { + + try { + var ret = matches.call( elem, expr ); + + // IE 9's matchesSelector returns false on disconnected nodes + if ( ret || support.disconnectedMatch || + // As well, disconnected nodes are said to be in a document + // fragment in IE 9 + elem.document && elem.document.nodeType !== 11 ) { + return ret; + } + } catch (e) { + nonnativeSelectorCache( expr, true ); + } + } + + return Sizzle( expr, document, null, [ elem ] ).length > 0; +}; + +Sizzle.contains = function( context, elem ) { + // Set document vars if needed + if ( ( context.ownerDocument || context ) !== document ) { + setDocument( context ); + } + return contains( context, elem ); +}; + +Sizzle.attr = function( elem, name ) { + // Set document vars if needed + if ( ( elem.ownerDocument || elem ) !== document ) { + setDocument( elem ); + } + + var fn = Expr.attrHandle[ name.toLowerCase() ], + // Don't get fooled by Object.prototype properties (jQuery #13807) + val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ? + fn( elem, name, !documentIsHTML ) : + undefined; + + return val !== undefined ? + val : + support.attributes || !documentIsHTML ? + elem.getAttribute( name ) : + (val = elem.getAttributeNode(name)) && val.specified ? + val.value : + null; +}; + +Sizzle.escape = function( sel ) { + return (sel + "").replace( rcssescape, fcssescape ); +}; + +Sizzle.error = function( msg ) { + throw new Error( "Syntax error, unrecognized expression: " + msg ); +}; + +/** + * Document sorting and removing duplicates + * @param {ArrayLike} results + */ +Sizzle.uniqueSort = function( results ) { + var elem, + duplicates = [], + j = 0, + i = 0; + + // Unless we *know* we can detect duplicates, assume their presence + hasDuplicate = !support.detectDuplicates; + sortInput = !support.sortStable && results.slice( 0 ); + results.sort( sortOrder ); + + if ( hasDuplicate ) { + while ( (elem = results[i++]) ) { + if ( elem === results[ i ] ) { + j = duplicates.push( i ); + } + } + while ( j-- ) { + results.splice( duplicates[ j ], 1 ); + } + } + + // Clear input after sorting to release objects + // See https://github.com/jquery/sizzle/pull/225 + sortInput = null; + + return results; +}; + +/** + * Utility function for retrieving the text value of an array of DOM nodes + * @param {Array|Element} elem + */ +getText = Sizzle.getText = function( elem ) { + var node, + ret = "", + i = 0, + nodeType = elem.nodeType; + + if ( !nodeType ) { + // If no nodeType, this is expected to be an array + while ( (node = elem[i++]) ) { + // Do not traverse comment nodes + ret += getText( node ); + } + } else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) { + // Use textContent for elements + // innerText usage removed for consistency of new lines (jQuery #11153) + if ( typeof elem.textContent === "string" ) { + return elem.textContent; + } else { + // Traverse its children + for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { + ret += getText( elem ); + } + } + } else if ( nodeType === 3 || nodeType === 4 ) { + return elem.nodeValue; + } + // Do not include comment or processing instruction nodes + + return ret; +}; + +Expr = Sizzle.selectors = { + + // Can be adjusted by the user + cacheLength: 50, + + createPseudo: markFunction, + + match: matchExpr, + + attrHandle: {}, + + find: {}, + + relative: { + ">": { dir: "parentNode", first: true }, + " ": { dir: "parentNode" }, + "+": { dir: "previousSibling", first: true }, + "~": { dir: "previousSibling" } + }, + + preFilter: { + "ATTR": function( match ) { + match[1] = match[1].replace( runescape, funescape ); + + // Move the given value to match[3] whether quoted or unquoted + match[3] = ( match[3] || match[4] || match[5] || "" ).replace( runescape, funescape ); + + if ( match[2] === "~=" ) { + match[3] = " " + match[3] + " "; + } + + return match.slice( 0, 4 ); + }, + + "CHILD": function( match ) { + /* matches from matchExpr["CHILD"] + 1 type (only|nth|...) + 2 what (child|of-type) + 3 argument (even|odd|\d*|\d*n([+-]\d+)?|...) + 4 xn-component of xn+y argument ([+-]?\d*n|) + 5 sign of xn-component + 6 x of xn-component + 7 sign of y-component + 8 y of y-component + */ + match[1] = match[1].toLowerCase(); + + if ( match[1].slice( 0, 3 ) === "nth" ) { + // nth-* requires argument + if ( !match[3] ) { + Sizzle.error( match[0] ); + } + + // numeric x and y parameters for Expr.filter.CHILD + // remember that false/true cast respectively to 0/1 + match[4] = +( match[4] ? match[5] + (match[6] || 1) : 2 * ( match[3] === "even" || match[3] === "odd" ) ); + match[5] = +( ( match[7] + match[8] ) || match[3] === "odd" ); + + // other types prohibit arguments + } else if ( match[3] ) { + Sizzle.error( match[0] ); + } + + return match; + }, + + "PSEUDO": function( match ) { + var excess, + unquoted = !match[6] && match[2]; + + if ( matchExpr["CHILD"].test( match[0] ) ) { + return null; + } + + // Accept quoted arguments as-is + if ( match[3] ) { + match[2] = match[4] || match[5] || ""; + + // Strip excess characters from unquoted arguments + } else if ( unquoted && rpseudo.test( unquoted ) && + // Get excess from tokenize (recursively) + (excess = tokenize( unquoted, true )) && + // advance to the next closing parenthesis + (excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length) ) { + + // excess is a negative index + match[0] = match[0].slice( 0, excess ); + match[2] = unquoted.slice( 0, excess ); + } + + // Return only captures needed by the pseudo filter method (type and argument) + return match.slice( 0, 3 ); + } + }, + + filter: { + + "TAG": function( nodeNameSelector ) { + var nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase(); + return nodeNameSelector === "*" ? + function() { return true; } : + function( elem ) { + return elem.nodeName && elem.nodeName.toLowerCase() === nodeName; + }; + }, + + "CLASS": function( className ) { + var pattern = classCache[ className + " " ]; + + return pattern || + (pattern = new RegExp( "(^|" + whitespace + ")" + className + "(" + whitespace + "|$)" )) && + classCache( className, function( elem ) { + return pattern.test( typeof elem.className === "string" && elem.className || typeof elem.getAttribute !== "undefined" && elem.getAttribute("class") || "" ); + }); + }, + + "ATTR": function( name, operator, check ) { + return function( elem ) { + var result = Sizzle.attr( elem, name ); + + if ( result == null ) { + return operator === "!="; + } + if ( !operator ) { + return true; + } + + result += ""; + + return operator === "=" ? result === check : + operator === "!=" ? result !== check : + operator === "^=" ? check && result.indexOf( check ) === 0 : + operator === "*=" ? check && result.indexOf( check ) > -1 : + operator === "$=" ? check && result.slice( -check.length ) === check : + operator === "~=" ? ( " " + result.replace( rwhitespace, " " ) + " " ).indexOf( check ) > -1 : + operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" : + false; + }; + }, + + "CHILD": function( type, what, argument, first, last ) { + var simple = type.slice( 0, 3 ) !== "nth", + forward = type.slice( -4 ) !== "last", + ofType = what === "of-type"; + + return first === 1 && last === 0 ? + + // Shortcut for :nth-*(n) + function( elem ) { + return !!elem.parentNode; + } : + + function( elem, context, xml ) { + var cache, uniqueCache, outerCache, node, nodeIndex, start, + dir = simple !== forward ? "nextSibling" : "previousSibling", + parent = elem.parentNode, + name = ofType && elem.nodeName.toLowerCase(), + useCache = !xml && !ofType, + diff = false; + + if ( parent ) { + + // :(first|last|only)-(child|of-type) + if ( simple ) { + while ( dir ) { + node = elem; + while ( (node = node[ dir ]) ) { + if ( ofType ? + node.nodeName.toLowerCase() === name : + node.nodeType === 1 ) { + + return false; + } + } + // Reverse direction for :only-* (if we haven't yet done so) + start = dir = type === "only" && !start && "nextSibling"; + } + return true; + } + + start = [ forward ? parent.firstChild : parent.lastChild ]; + + // non-xml :nth-child(...) stores cache data on `parent` + if ( forward && useCache ) { + + // Seek `elem` from a previously-cached index + + // ...in a gzip-friendly way + node = parent; + outerCache = node[ expando ] || (node[ expando ] = {}); + + // Support: IE <9 only + // Defend against cloned attroperties (jQuery gh-1709) + uniqueCache = outerCache[ node.uniqueID ] || + (outerCache[ node.uniqueID ] = {}); + + cache = uniqueCache[ type ] || []; + nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ]; + diff = nodeIndex && cache[ 2 ]; + node = nodeIndex && parent.childNodes[ nodeIndex ]; + + while ( (node = ++nodeIndex && node && node[ dir ] || + + // Fallback to seeking `elem` from the start + (diff = nodeIndex = 0) || start.pop()) ) { + + // When found, cache indexes on `parent` and break + if ( node.nodeType === 1 && ++diff && node === elem ) { + uniqueCache[ type ] = [ dirruns, nodeIndex, diff ]; + break; + } + } + + } else { + // Use previously-cached element index if available + if ( useCache ) { + // ...in a gzip-friendly way + node = elem; + outerCache = node[ expando ] || (node[ expando ] = {}); + + // Support: IE <9 only + // Defend against cloned attroperties (jQuery gh-1709) + uniqueCache = outerCache[ node.uniqueID ] || + (outerCache[ node.uniqueID ] = {}); + + cache = uniqueCache[ type ] || []; + nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ]; + diff = nodeIndex; + } + + // xml :nth-child(...) + // or :nth-last-child(...) or :nth(-last)?-of-type(...) + if ( diff === false ) { + // Use the same loop as above to seek `elem` from the start + while ( (node = ++nodeIndex && node && node[ dir ] || + (diff = nodeIndex = 0) || start.pop()) ) { + + if ( ( ofType ? + node.nodeName.toLowerCase() === name : + node.nodeType === 1 ) && + ++diff ) { + + // Cache the index of each encountered element + if ( useCache ) { + outerCache = node[ expando ] || (node[ expando ] = {}); + + // Support: IE <9 only + // Defend against cloned attroperties (jQuery gh-1709) + uniqueCache = outerCache[ node.uniqueID ] || + (outerCache[ node.uniqueID ] = {}); + + uniqueCache[ type ] = [ dirruns, diff ]; + } + + if ( node === elem ) { + break; + } + } + } + } + } + + // Incorporate the offset, then check against cycle size + diff -= last; + return diff === first || ( diff % first === 0 && diff / first >= 0 ); + } + }; + }, + + "PSEUDO": function( pseudo, argument ) { + // pseudo-class names are case-insensitive + // http://www.w3.org/TR/selectors/#pseudo-classes + // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters + // Remember that setFilters inherits from pseudos + var args, + fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] || + Sizzle.error( "unsupported pseudo: " + pseudo ); + + // The user may use createPseudo to indicate that + // arguments are needed to create the filter function + // just as Sizzle does + if ( fn[ expando ] ) { + return fn( argument ); + } + + // But maintain support for old signatures + if ( fn.length > 1 ) { + args = [ pseudo, pseudo, "", argument ]; + return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ? + markFunction(function( seed, matches ) { + var idx, + matched = fn( seed, argument ), + i = matched.length; + while ( i-- ) { + idx = indexOf( seed, matched[i] ); + seed[ idx ] = !( matches[ idx ] = matched[i] ); + } + }) : + function( elem ) { + return fn( elem, 0, args ); + }; + } + + return fn; + } + }, + + pseudos: { + // Potentially complex pseudos + "not": markFunction(function( selector ) { + // Trim the selector passed to compile + // to avoid treating leading and trailing + // spaces as combinators + var input = [], + results = [], + matcher = compile( selector.replace( rtrim, "$1" ) ); + + return matcher[ expando ] ? + markFunction(function( seed, matches, context, xml ) { + var elem, + unmatched = matcher( seed, null, xml, [] ), + i = seed.length; + + // Match elements unmatched by `matcher` + while ( i-- ) { + if ( (elem = unmatched[i]) ) { + seed[i] = !(matches[i] = elem); + } + } + }) : + function( elem, context, xml ) { + input[0] = elem; + matcher( input, null, xml, results ); + // Don't keep the element (issue #299) + input[0] = null; + return !results.pop(); + }; + }), + + "has": markFunction(function( selector ) { + return function( elem ) { + return Sizzle( selector, elem ).length > 0; + }; + }), + + "contains": markFunction(function( text ) { + text = text.replace( runescape, funescape ); + return function( elem ) { + return ( elem.textContent || getText( elem ) ).indexOf( text ) > -1; + }; + }), + + // "Whether an element is represented by a :lang() selector + // is based solely on the element's language value + // being equal to the identifier C, + // or beginning with the identifier C immediately followed by "-". + // The matching of C against the element's language value is performed case-insensitively. + // The identifier C does not have to be a valid language name." + // http://www.w3.org/TR/selectors/#lang-pseudo + "lang": markFunction( function( lang ) { + // lang value must be a valid identifier + if ( !ridentifier.test(lang || "") ) { + Sizzle.error( "unsupported lang: " + lang ); + } + lang = lang.replace( runescape, funescape ).toLowerCase(); + return function( elem ) { + var elemLang; + do { + if ( (elemLang = documentIsHTML ? + elem.lang : + elem.getAttribute("xml:lang") || elem.getAttribute("lang")) ) { + + elemLang = elemLang.toLowerCase(); + return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0; + } + } while ( (elem = elem.parentNode) && elem.nodeType === 1 ); + return false; + }; + }), + + // Miscellaneous + "target": function( elem ) { + var hash = window.location && window.location.hash; + return hash && hash.slice( 1 ) === elem.id; + }, + + "root": function( elem ) { + return elem === docElem; + }, + + "focus": function( elem ) { + return elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex); + }, + + // Boolean properties + "enabled": createDisabledPseudo( false ), + "disabled": createDisabledPseudo( true ), + + "checked": function( elem ) { + // In CSS3, :checked should return both checked and selected elements + // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked + var nodeName = elem.nodeName.toLowerCase(); + return (nodeName === "input" && !!elem.checked) || (nodeName === "option" && !!elem.selected); + }, + + "selected": function( elem ) { + // Accessing this property makes selected-by-default + // options in Safari work properly + if ( elem.parentNode ) { + elem.parentNode.selectedIndex; + } + + return elem.selected === true; + }, + + // Contents + "empty": function( elem ) { + // http://www.w3.org/TR/selectors/#empty-pseudo + // :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5), + // but not by others (comment: 8; processing instruction: 7; etc.) + // nodeType < 6 works because attributes (2) do not appear as children + for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { + if ( elem.nodeType < 6 ) { + return false; + } + } + return true; + }, + + "parent": function( elem ) { + return !Expr.pseudos["empty"]( elem ); + }, + + // Element/input types + "header": function( elem ) { + return rheader.test( elem.nodeName ); + }, + + "input": function( elem ) { + return rinputs.test( elem.nodeName ); + }, + + "button": function( elem ) { + var name = elem.nodeName.toLowerCase(); + return name === "input" && elem.type === "button" || name === "button"; + }, + + "text": function( elem ) { + var attr; + return elem.nodeName.toLowerCase() === "input" && + elem.type === "text" && + + // Support: IE<8 + // New HTML5 attribute values (e.g., "search") appear with elem.type === "text" + ( (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === "text" ); + }, + + // Position-in-collection + "first": createPositionalPseudo(function() { + return [ 0 ]; + }), + + "last": createPositionalPseudo(function( matchIndexes, length ) { + return [ length - 1 ]; + }), + + "eq": createPositionalPseudo(function( matchIndexes, length, argument ) { + return [ argument < 0 ? argument + length : argument ]; + }), + + "even": createPositionalPseudo(function( matchIndexes, length ) { + var i = 0; + for ( ; i < length; i += 2 ) { + matchIndexes.push( i ); + } + return matchIndexes; + }), + + "odd": createPositionalPseudo(function( matchIndexes, length ) { + var i = 1; + for ( ; i < length; i += 2 ) { + matchIndexes.push( i ); + } + return matchIndexes; + }), + + "lt": createPositionalPseudo(function( matchIndexes, length, argument ) { + var i = argument < 0 ? + argument + length : + argument > length ? + length : + argument; + for ( ; --i >= 0; ) { + matchIndexes.push( i ); + } + return matchIndexes; + }), + + "gt": createPositionalPseudo(function( matchIndexes, length, argument ) { + var i = argument < 0 ? argument + length : argument; + for ( ; ++i < length; ) { + matchIndexes.push( i ); + } + return matchIndexes; + }) + } +}; + +Expr.pseudos["nth"] = Expr.pseudos["eq"]; + +// Add button/input type pseudos +for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) { + Expr.pseudos[ i ] = createInputPseudo( i ); +} +for ( i in { submit: true, reset: true } ) { + Expr.pseudos[ i ] = createButtonPseudo( i ); +} + +// Easy API for creating new setFilters +function setFilters() {} +setFilters.prototype = Expr.filters = Expr.pseudos; +Expr.setFilters = new setFilters(); + +tokenize = Sizzle.tokenize = function( selector, parseOnly ) { + var matched, match, tokens, type, + soFar, groups, preFilters, + cached = tokenCache[ selector + " " ]; + + if ( cached ) { + return parseOnly ? 0 : cached.slice( 0 ); + } + + soFar = selector; + groups = []; + preFilters = Expr.preFilter; + + while ( soFar ) { + + // Comma and first run + if ( !matched || (match = rcomma.exec( soFar )) ) { + if ( match ) { + // Don't consume trailing commas as valid + soFar = soFar.slice( match[0].length ) || soFar; + } + groups.push( (tokens = []) ); + } + + matched = false; + + // Combinators + if ( (match = rcombinators.exec( soFar )) ) { + matched = match.shift(); + tokens.push({ + value: matched, + // Cast descendant combinators to space + type: match[0].replace( rtrim, " " ) + }); + soFar = soFar.slice( matched.length ); + } + + // Filters + for ( type in Expr.filter ) { + if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] || + (match = preFilters[ type ]( match ))) ) { + matched = match.shift(); + tokens.push({ + value: matched, + type: type, + matches: match + }); + soFar = soFar.slice( matched.length ); + } + } + + if ( !matched ) { + break; + } + } + + // Return the length of the invalid excess + // if we're just parsing + // Otherwise, throw an error or return tokens + return parseOnly ? + soFar.length : + soFar ? + Sizzle.error( selector ) : + // Cache the tokens + tokenCache( selector, groups ).slice( 0 ); +}; + +function toSelector( tokens ) { + var i = 0, + len = tokens.length, + selector = ""; + for ( ; i < len; i++ ) { + selector += tokens[i].value; + } + return selector; +} + +function addCombinator( matcher, combinator, base ) { + var dir = combinator.dir, + skip = combinator.next, + key = skip || dir, + checkNonElements = base && key === "parentNode", + doneName = done++; + + return combinator.first ? + // Check against closest ancestor/preceding element + function( elem, context, xml ) { + while ( (elem = elem[ dir ]) ) { + if ( elem.nodeType === 1 || checkNonElements ) { + return matcher( elem, context, xml ); + } + } + return false; + } : + + // Check against all ancestor/preceding elements + function( elem, context, xml ) { + var oldCache, uniqueCache, outerCache, + newCache = [ dirruns, doneName ]; + + // We can't set arbitrary data on XML nodes, so they don't benefit from combinator caching + if ( xml ) { + while ( (elem = elem[ dir ]) ) { + if ( elem.nodeType === 1 || checkNonElements ) { + if ( matcher( elem, context, xml ) ) { + return true; + } + } + } + } else { + while ( (elem = elem[ dir ]) ) { + if ( elem.nodeType === 1 || checkNonElements ) { + outerCache = elem[ expando ] || (elem[ expando ] = {}); + + // Support: IE <9 only + // Defend against cloned attroperties (jQuery gh-1709) + uniqueCache = outerCache[ elem.uniqueID ] || (outerCache[ elem.uniqueID ] = {}); + + if ( skip && skip === elem.nodeName.toLowerCase() ) { + elem = elem[ dir ] || elem; + } else if ( (oldCache = uniqueCache[ key ]) && + oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) { + + // Assign to newCache so results back-propagate to previous elements + return (newCache[ 2 ] = oldCache[ 2 ]); + } else { + // Reuse newcache so results back-propagate to previous elements + uniqueCache[ key ] = newCache; + + // A match means we're done; a fail means we have to keep checking + if ( (newCache[ 2 ] = matcher( elem, context, xml )) ) { + return true; + } + } + } + } + } + return false; + }; +} + +function elementMatcher( matchers ) { + return matchers.length > 1 ? + function( elem, context, xml ) { + var i = matchers.length; + while ( i-- ) { + if ( !matchers[i]( elem, context, xml ) ) { + return false; + } + } + return true; + } : + matchers[0]; +} + +function multipleContexts( selector, contexts, results ) { + var i = 0, + len = contexts.length; + for ( ; i < len; i++ ) { + Sizzle( selector, contexts[i], results ); + } + return results; +} + +function condense( unmatched, map, filter, context, xml ) { + var elem, + newUnmatched = [], + i = 0, + len = unmatched.length, + mapped = map != null; + + for ( ; i < len; i++ ) { + if ( (elem = unmatched[i]) ) { + if ( !filter || filter( elem, context, xml ) ) { + newUnmatched.push( elem ); + if ( mapped ) { + map.push( i ); + } + } + } + } + + return newUnmatched; +} + +function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) { + if ( postFilter && !postFilter[ expando ] ) { + postFilter = setMatcher( postFilter ); + } + if ( postFinder && !postFinder[ expando ] ) { + postFinder = setMatcher( postFinder, postSelector ); + } + return markFunction(function( seed, results, context, xml ) { + var temp, i, elem, + preMap = [], + postMap = [], + preexisting = results.length, + + // Get initial elements from seed or context + elems = seed || multipleContexts( selector || "*", context.nodeType ? [ context ] : context, [] ), + + // Prefilter to get matcher input, preserving a map for seed-results synchronization + matcherIn = preFilter && ( seed || !selector ) ? + condense( elems, preMap, preFilter, context, xml ) : + elems, + + matcherOut = matcher ? + // If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results, + postFinder || ( seed ? preFilter : preexisting || postFilter ) ? + + // ...intermediate processing is necessary + [] : + + // ...otherwise use results directly + results : + matcherIn; + + // Find primary matches + if ( matcher ) { + matcher( matcherIn, matcherOut, context, xml ); + } + + // Apply postFilter + if ( postFilter ) { + temp = condense( matcherOut, postMap ); + postFilter( temp, [], context, xml ); + + // Un-match failing elements by moving them back to matcherIn + i = temp.length; + while ( i-- ) { + if ( (elem = temp[i]) ) { + matcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem); + } + } + } + + if ( seed ) { + if ( postFinder || preFilter ) { + if ( postFinder ) { + // Get the final matcherOut by condensing this intermediate into postFinder contexts + temp = []; + i = matcherOut.length; + while ( i-- ) { + if ( (elem = matcherOut[i]) ) { + // Restore matcherIn since elem is not yet a final match + temp.push( (matcherIn[i] = elem) ); + } + } + postFinder( null, (matcherOut = []), temp, xml ); + } + + // Move matched elements from seed to results to keep them synchronized + i = matcherOut.length; + while ( i-- ) { + if ( (elem = matcherOut[i]) && + (temp = postFinder ? indexOf( seed, elem ) : preMap[i]) > -1 ) { + + seed[temp] = !(results[temp] = elem); + } + } + } + + // Add elements to results, through postFinder if defined + } else { + matcherOut = condense( + matcherOut === results ? + matcherOut.splice( preexisting, matcherOut.length ) : + matcherOut + ); + if ( postFinder ) { + postFinder( null, results, matcherOut, xml ); + } else { + push.apply( results, matcherOut ); + } + } + }); +} + +function matcherFromTokens( tokens ) { + var checkContext, matcher, j, + len = tokens.length, + leadingRelative = Expr.relative[ tokens[0].type ], + implicitRelative = leadingRelative || Expr.relative[" "], + i = leadingRelative ? 1 : 0, + + // The foundational matcher ensures that elements are reachable from top-level context(s) + matchContext = addCombinator( function( elem ) { + return elem === checkContext; + }, implicitRelative, true ), + matchAnyContext = addCombinator( function( elem ) { + return indexOf( checkContext, elem ) > -1; + }, implicitRelative, true ), + matchers = [ function( elem, context, xml ) { + var ret = ( !leadingRelative && ( xml || context !== outermostContext ) ) || ( + (checkContext = context).nodeType ? + matchContext( elem, context, xml ) : + matchAnyContext( elem, context, xml ) ); + // Avoid hanging onto element (issue #299) + checkContext = null; + return ret; + } ]; + + for ( ; i < len; i++ ) { + if ( (matcher = Expr.relative[ tokens[i].type ]) ) { + matchers = [ addCombinator(elementMatcher( matchers ), matcher) ]; + } else { + matcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches ); + + // Return special upon seeing a positional matcher + if ( matcher[ expando ] ) { + // Find the next relative operator (if any) for proper handling + j = ++i; + for ( ; j < len; j++ ) { + if ( Expr.relative[ tokens[j].type ] ) { + break; + } + } + return setMatcher( + i > 1 && elementMatcher( matchers ), + i > 1 && toSelector( + // If the preceding token was a descendant combinator, insert an implicit any-element `*` + tokens.slice( 0, i - 1 ).concat({ value: tokens[ i - 2 ].type === " " ? "*" : "" }) + ).replace( rtrim, "$1" ), + matcher, + i < j && matcherFromTokens( tokens.slice( i, j ) ), + j < len && matcherFromTokens( (tokens = tokens.slice( j )) ), + j < len && toSelector( tokens ) + ); + } + matchers.push( matcher ); + } + } + + return elementMatcher( matchers ); +} + +function matcherFromGroupMatchers( elementMatchers, setMatchers ) { + var bySet = setMatchers.length > 0, + byElement = elementMatchers.length > 0, + superMatcher = function( seed, context, xml, results, outermost ) { + var elem, j, matcher, + matchedCount = 0, + i = "0", + unmatched = seed && [], + setMatched = [], + contextBackup = outermostContext, + // We must always have either seed elements or outermost context + elems = seed || byElement && Expr.find["TAG"]( "*", outermost ), + // Use integer dirruns iff this is the outermost matcher + dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1), + len = elems.length; + + if ( outermost ) { + outermostContext = context === document || context || outermost; + } + + // Add elements passing elementMatchers directly to results + // Support: IE<9, Safari + // Tolerate NodeList properties (IE: "length"; Safari: ) matching elements by id + for ( ; i !== len && (elem = elems[i]) != null; i++ ) { + if ( byElement && elem ) { + j = 0; + if ( !context && elem.ownerDocument !== document ) { + setDocument( elem ); + xml = !documentIsHTML; + } + while ( (matcher = elementMatchers[j++]) ) { + if ( matcher( elem, context || document, xml) ) { + results.push( elem ); + break; + } + } + if ( outermost ) { + dirruns = dirrunsUnique; + } + } + + // Track unmatched elements for set filters + if ( bySet ) { + // They will have gone through all possible matchers + if ( (elem = !matcher && elem) ) { + matchedCount--; + } + + // Lengthen the array for every element, matched or not + if ( seed ) { + unmatched.push( elem ); + } + } + } + + // `i` is now the count of elements visited above, and adding it to `matchedCount` + // makes the latter nonnegative. + matchedCount += i; + + // Apply set filters to unmatched elements + // NOTE: This can be skipped if there are no unmatched elements (i.e., `matchedCount` + // equals `i`), unless we didn't visit _any_ elements in the above loop because we have + // no element matchers and no seed. + // Incrementing an initially-string "0" `i` allows `i` to remain a string only in that + // case, which will result in a "00" `matchedCount` that differs from `i` but is also + // numerically zero. + if ( bySet && i !== matchedCount ) { + j = 0; + while ( (matcher = setMatchers[j++]) ) { + matcher( unmatched, setMatched, context, xml ); + } + + if ( seed ) { + // Reintegrate element matches to eliminate the need for sorting + if ( matchedCount > 0 ) { + while ( i-- ) { + if ( !(unmatched[i] || setMatched[i]) ) { + setMatched[i] = pop.call( results ); + } + } + } + + // Discard index placeholder values to get only actual matches + setMatched = condense( setMatched ); + } + + // Add matches to results + push.apply( results, setMatched ); + + // Seedless set matches succeeding multiple successful matchers stipulate sorting + if ( outermost && !seed && setMatched.length > 0 && + ( matchedCount + setMatchers.length ) > 1 ) { + + Sizzle.uniqueSort( results ); + } + } + + // Override manipulation of globals by nested matchers + if ( outermost ) { + dirruns = dirrunsUnique; + outermostContext = contextBackup; + } + + return unmatched; + }; + + return bySet ? + markFunction( superMatcher ) : + superMatcher; +} + +compile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) { + var i, + setMatchers = [], + elementMatchers = [], + cached = compilerCache[ selector + " " ]; + + if ( !cached ) { + // Generate a function of recursive functions that can be used to check each element + if ( !match ) { + match = tokenize( selector ); + } + i = match.length; + while ( i-- ) { + cached = matcherFromTokens( match[i] ); + if ( cached[ expando ] ) { + setMatchers.push( cached ); + } else { + elementMatchers.push( cached ); + } + } + + // Cache the compiled function + cached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) ); + + // Save selector and tokenization + cached.selector = selector; + } + return cached; +}; + +/** + * A low-level selection function that works with Sizzle's compiled + * selector functions + * @param {String|Function} selector A selector or a pre-compiled + * selector function built with Sizzle.compile + * @param {Element} context + * @param {Array} [results] + * @param {Array} [seed] A set of elements to match against + */ +select = Sizzle.select = function( selector, context, results, seed ) { + var i, tokens, token, type, find, + compiled = typeof selector === "function" && selector, + match = !seed && tokenize( (selector = compiled.selector || selector) ); + + results = results || []; + + // Try to minimize operations if there is only one selector in the list and no seed + // (the latter of which guarantees us context) + if ( match.length === 1 ) { + + // Reduce context if the leading compound selector is an ID + tokens = match[0] = match[0].slice( 0 ); + if ( tokens.length > 2 && (token = tokens[0]).type === "ID" && + context.nodeType === 9 && documentIsHTML && Expr.relative[ tokens[1].type ] ) { + + context = ( Expr.find["ID"]( token.matches[0].replace(runescape, funescape), context ) || [] )[0]; + if ( !context ) { + return results; + + // Precompiled matchers will still verify ancestry, so step up a level + } else if ( compiled ) { + context = context.parentNode; + } + + selector = selector.slice( tokens.shift().value.length ); + } + + // Fetch a seed set for right-to-left matching + i = matchExpr["needsContext"].test( selector ) ? 0 : tokens.length; + while ( i-- ) { + token = tokens[i]; + + // Abort if we hit a combinator + if ( Expr.relative[ (type = token.type) ] ) { + break; + } + if ( (find = Expr.find[ type ]) ) { + // Search, expanding context for leading sibling combinators + if ( (seed = find( + token.matches[0].replace( runescape, funescape ), + rsibling.test( tokens[0].type ) && testContext( context.parentNode ) || context + )) ) { + + // If seed is empty or no tokens remain, we can return early + tokens.splice( i, 1 ); + selector = seed.length && toSelector( tokens ); + if ( !selector ) { + push.apply( results, seed ); + return results; + } + + break; + } + } + } + } + + // Compile and execute a filtering function if one is not provided + // Provide `match` to avoid retokenization if we modified the selector above + ( compiled || compile( selector, match ) )( + seed, + context, + !documentIsHTML, + results, + !context || rsibling.test( selector ) && testContext( context.parentNode ) || context + ); + return results; +}; + +// One-time assignments + +// Sort stability +support.sortStable = expando.split("").sort( sortOrder ).join("") === expando; + +// Support: Chrome 14-35+ +// Always assume duplicates if they aren't passed to the comparison function +support.detectDuplicates = !!hasDuplicate; + +// Initialize against the default document +setDocument(); + +// Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27) +// Detached nodes confoundingly follow *each other* +support.sortDetached = assert(function( el ) { + // Should return 1, but returns 4 (following) + return el.compareDocumentPosition( document.createElement("fieldset") ) & 1; +}); + +// Support: IE<8 +// Prevent attribute/property "interpolation" +// https://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx +if ( !assert(function( el ) { + el.innerHTML = ""; + return el.firstChild.getAttribute("href") === "#" ; +}) ) { + addHandle( "type|href|height|width", function( elem, name, isXML ) { + if ( !isXML ) { + return elem.getAttribute( name, name.toLowerCase() === "type" ? 1 : 2 ); + } + }); +} + +// Support: IE<9 +// Use defaultValue in place of getAttribute("value") +if ( !support.attributes || !assert(function( el ) { + el.innerHTML = ""; + el.firstChild.setAttribute( "value", "" ); + return el.firstChild.getAttribute( "value" ) === ""; +}) ) { + addHandle( "value", function( elem, name, isXML ) { + if ( !isXML && elem.nodeName.toLowerCase() === "input" ) { + return elem.defaultValue; + } + }); +} + +// Support: IE<9 +// Use getAttributeNode to fetch booleans when getAttribute lies +if ( !assert(function( el ) { + return el.getAttribute("disabled") == null; +}) ) { + addHandle( booleans, function( elem, name, isXML ) { + var val; + if ( !isXML ) { + return elem[ name ] === true ? name.toLowerCase() : + (val = elem.getAttributeNode( name )) && val.specified ? + val.value : + null; + } + }); +} + +return Sizzle; + +})( window ); + + + +jQuery.find = Sizzle; +jQuery.expr = Sizzle.selectors; + +// Deprecated +jQuery.expr[ ":" ] = jQuery.expr.pseudos; +jQuery.uniqueSort = jQuery.unique = Sizzle.uniqueSort; +jQuery.text = Sizzle.getText; +jQuery.isXMLDoc = Sizzle.isXML; +jQuery.contains = Sizzle.contains; +jQuery.escapeSelector = Sizzle.escape; + + + + +var dir = function( elem, dir, until ) { + var matched = [], + truncate = until !== undefined; + + while ( ( elem = elem[ dir ] ) && elem.nodeType !== 9 ) { + if ( elem.nodeType === 1 ) { + if ( truncate && jQuery( elem ).is( until ) ) { + break; + } + matched.push( elem ); + } + } + return matched; +}; + + +var siblings = function( n, elem ) { + var matched = []; + + for ( ; n; n = n.nextSibling ) { + if ( n.nodeType === 1 && n !== elem ) { + matched.push( n ); + } + } + + return matched; +}; + + +var rneedsContext = jQuery.expr.match.needsContext; + + + +function nodeName( elem, name ) { + + return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase(); + +}; +var rsingleTag = ( /^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i ); + + + +// Implement the identical functionality for filter and not +function winnow( elements, qualifier, not ) { + if ( isFunction( qualifier ) ) { + return jQuery.grep( elements, function( elem, i ) { + return !!qualifier.call( elem, i, elem ) !== not; + } ); + } + + // Single element + if ( qualifier.nodeType ) { + return jQuery.grep( elements, function( elem ) { + return ( elem === qualifier ) !== not; + } ); + } + + // Arraylike of elements (jQuery, arguments, Array) + if ( typeof qualifier !== "string" ) { + return jQuery.grep( elements, function( elem ) { + return ( indexOf.call( qualifier, elem ) > -1 ) !== not; + } ); + } + + // Filtered directly for both simple and complex selectors + return jQuery.filter( qualifier, elements, not ); +} + +jQuery.filter = function( expr, elems, not ) { + var elem = elems[ 0 ]; + + if ( not ) { + expr = ":not(" + expr + ")"; + } + + if ( elems.length === 1 && elem.nodeType === 1 ) { + return jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : []; + } + + return jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) { + return elem.nodeType === 1; + } ) ); +}; + +jQuery.fn.extend( { + find: function( selector ) { + var i, ret, + len = this.length, + self = this; + + if ( typeof selector !== "string" ) { + return this.pushStack( jQuery( selector ).filter( function() { + for ( i = 0; i < len; i++ ) { + if ( jQuery.contains( self[ i ], this ) ) { + return true; + } + } + } ) ); + } + + ret = this.pushStack( [] ); + + for ( i = 0; i < len; i++ ) { + jQuery.find( selector, self[ i ], ret ); + } + + return len > 1 ? jQuery.uniqueSort( ret ) : ret; + }, + filter: function( selector ) { + return this.pushStack( winnow( this, selector || [], false ) ); + }, + not: function( selector ) { + return this.pushStack( winnow( this, selector || [], true ) ); + }, + is: function( selector ) { + return !!winnow( + this, + + // If this is a positional/relative selector, check membership in the returned set + // so $("p:first").is("p:last") won't return true for a doc with two "p". + typeof selector === "string" && rneedsContext.test( selector ) ? + jQuery( selector ) : + selector || [], + false + ).length; + } +} ); + + +// Initialize a jQuery object + + +// A central reference to the root jQuery(document) +var rootjQuery, + + // A simple way to check for HTML strings + // Prioritize #id over to avoid XSS via location.hash (#9521) + // Strict HTML recognition (#11290: must start with <) + // Shortcut simple #id case for speed + rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/, + + init = jQuery.fn.init = function( selector, context, root ) { + var match, elem; + + // HANDLE: $(""), $(null), $(undefined), $(false) + if ( !selector ) { + return this; + } + + // Method init() accepts an alternate rootjQuery + // so migrate can support jQuery.sub (gh-2101) + root = root || rootjQuery; + + // Handle HTML strings + if ( typeof selector === "string" ) { + if ( selector[ 0 ] === "<" && + selector[ selector.length - 1 ] === ">" && + selector.length >= 3 ) { + + // Assume that strings that start and end with <> are HTML and skip the regex check + match = [ null, selector, null ]; + + } else { + match = rquickExpr.exec( selector ); + } + + // Match html or make sure no context is specified for #id + if ( match && ( match[ 1 ] || !context ) ) { + + // HANDLE: $(html) -> $(array) + if ( match[ 1 ] ) { + context = context instanceof jQuery ? context[ 0 ] : context; + + // Option to run scripts is true for back-compat + // Intentionally let the error be thrown if parseHTML is not present + jQuery.merge( this, jQuery.parseHTML( + match[ 1 ], + context && context.nodeType ? context.ownerDocument || context : document, + true + ) ); + + // HANDLE: $(html, props) + if ( rsingleTag.test( match[ 1 ] ) && jQuery.isPlainObject( context ) ) { + for ( match in context ) { + + // Properties of context are called as methods if possible + if ( isFunction( this[ match ] ) ) { + this[ match ]( context[ match ] ); + + // ...and otherwise set as attributes + } else { + this.attr( match, context[ match ] ); + } + } + } + + return this; + + // HANDLE: $(#id) + } else { + elem = document.getElementById( match[ 2 ] ); + + if ( elem ) { + + // Inject the element directly into the jQuery object + this[ 0 ] = elem; + this.length = 1; + } + return this; + } + + // HANDLE: $(expr, $(...)) + } else if ( !context || context.jquery ) { + return ( context || root ).find( selector ); + + // HANDLE: $(expr, context) + // (which is just equivalent to: $(context).find(expr) + } else { + return this.constructor( context ).find( selector ); + } + + // HANDLE: $(DOMElement) + } else if ( selector.nodeType ) { + this[ 0 ] = selector; + this.length = 1; + return this; + + // HANDLE: $(function) + // Shortcut for document ready + } else if ( isFunction( selector ) ) { + return root.ready !== undefined ? + root.ready( selector ) : + + // Execute immediately if ready is not present + selector( jQuery ); + } + + return jQuery.makeArray( selector, this ); + }; + +// Give the init function the jQuery prototype for later instantiation +init.prototype = jQuery.fn; + +// Initialize central reference +rootjQuery = jQuery( document ); + + +var rparentsprev = /^(?:parents|prev(?:Until|All))/, + + // Methods guaranteed to produce a unique set when starting from a unique set + guaranteedUnique = { + children: true, + contents: true, + next: true, + prev: true + }; + +jQuery.fn.extend( { + has: function( target ) { + var targets = jQuery( target, this ), + l = targets.length; + + return this.filter( function() { + var i = 0; + for ( ; i < l; i++ ) { + if ( jQuery.contains( this, targets[ i ] ) ) { + return true; + } + } + } ); + }, + + closest: function( selectors, context ) { + var cur, + i = 0, + l = this.length, + matched = [], + targets = typeof selectors !== "string" && jQuery( selectors ); + + // Positional selectors never match, since there's no _selection_ context + if ( !rneedsContext.test( selectors ) ) { + for ( ; i < l; i++ ) { + for ( cur = this[ i ]; cur && cur !== context; cur = cur.parentNode ) { + + // Always skip document fragments + if ( cur.nodeType < 11 && ( targets ? + targets.index( cur ) > -1 : + + // Don't pass non-elements to Sizzle + cur.nodeType === 1 && + jQuery.find.matchesSelector( cur, selectors ) ) ) { + + matched.push( cur ); + break; + } + } + } + } + + return this.pushStack( matched.length > 1 ? jQuery.uniqueSort( matched ) : matched ); + }, + + // Determine the position of an element within the set + index: function( elem ) { + + // No argument, return index in parent + if ( !elem ) { + return ( this[ 0 ] && this[ 0 ].parentNode ) ? this.first().prevAll().length : -1; + } + + // Index in selector + if ( typeof elem === "string" ) { + return indexOf.call( jQuery( elem ), this[ 0 ] ); + } + + // Locate the position of the desired element + return indexOf.call( this, + + // If it receives a jQuery object, the first element is used + elem.jquery ? elem[ 0 ] : elem + ); + }, + + add: function( selector, context ) { + return this.pushStack( + jQuery.uniqueSort( + jQuery.merge( this.get(), jQuery( selector, context ) ) + ) + ); + }, + + addBack: function( selector ) { + return this.add( selector == null ? + this.prevObject : this.prevObject.filter( selector ) + ); + } +} ); + +function sibling( cur, dir ) { + while ( ( cur = cur[ dir ] ) && cur.nodeType !== 1 ) {} + return cur; +} + +jQuery.each( { + parent: function( elem ) { + var parent = elem.parentNode; + return parent && parent.nodeType !== 11 ? parent : null; + }, + parents: function( elem ) { + return dir( elem, "parentNode" ); + }, + parentsUntil: function( elem, i, until ) { + return dir( elem, "parentNode", until ); + }, + next: function( elem ) { + return sibling( elem, "nextSibling" ); + }, + prev: function( elem ) { + return sibling( elem, "previousSibling" ); + }, + nextAll: function( elem ) { + return dir( elem, "nextSibling" ); + }, + prevAll: function( elem ) { + return dir( elem, "previousSibling" ); + }, + nextUntil: function( elem, i, until ) { + return dir( elem, "nextSibling", until ); + }, + prevUntil: function( elem, i, until ) { + return dir( elem, "previousSibling", until ); + }, + siblings: function( elem ) { + return siblings( ( elem.parentNode || {} ).firstChild, elem ); + }, + children: function( elem ) { + return siblings( elem.firstChild ); + }, + contents: function( elem ) { + if ( typeof elem.contentDocument !== "undefined" ) { + return elem.contentDocument; + } + + // Support: IE 9 - 11 only, iOS 7 only, Android Browser <=4.3 only + // Treat the template element as a regular one in browsers that + // don't support it. + if ( nodeName( elem, "template" ) ) { + elem = elem.content || elem; + } + + return jQuery.merge( [], elem.childNodes ); + } +}, function( name, fn ) { + jQuery.fn[ name ] = function( until, selector ) { + var matched = jQuery.map( this, fn, until ); + + if ( name.slice( -5 ) !== "Until" ) { + selector = until; + } + + if ( selector && typeof selector === "string" ) { + matched = jQuery.filter( selector, matched ); + } + + if ( this.length > 1 ) { + + // Remove duplicates + if ( !guaranteedUnique[ name ] ) { + jQuery.uniqueSort( matched ); + } + + // Reverse order for parents* and prev-derivatives + if ( rparentsprev.test( name ) ) { + matched.reverse(); + } + } + + return this.pushStack( matched ); + }; +} ); +var rnothtmlwhite = ( /[^\x20\t\r\n\f]+/g ); + + + +// Convert String-formatted options into Object-formatted ones +function createOptions( options ) { + var object = {}; + jQuery.each( options.match( rnothtmlwhite ) || [], function( _, flag ) { + object[ flag ] = true; + } ); + return object; +} + +/* + * Create a callback list using the following parameters: + * + * options: an optional list of space-separated options that will change how + * the callback list behaves or a more traditional option object + * + * By default a callback list will act like an event callback list and can be + * "fired" multiple times. + * + * Possible options: + * + * once: will ensure the callback list can only be fired once (like a Deferred) + * + * memory: will keep track of previous values and will call any callback added + * after the list has been fired right away with the latest "memorized" + * values (like a Deferred) + * + * unique: will ensure a callback can only be added once (no duplicate in the list) + * + * stopOnFalse: interrupt callings when a callback returns false + * + */ +jQuery.Callbacks = function( options ) { + + // Convert options from String-formatted to Object-formatted if needed + // (we check in cache first) + options = typeof options === "string" ? + createOptions( options ) : + jQuery.extend( {}, options ); + + var // Flag to know if list is currently firing + firing, + + // Last fire value for non-forgettable lists + memory, + + // Flag to know if list was already fired + fired, + + // Flag to prevent firing + locked, + + // Actual callback list + list = [], + + // Queue of execution data for repeatable lists + queue = [], + + // Index of currently firing callback (modified by add/remove as needed) + firingIndex = -1, + + // Fire callbacks + fire = function() { + + // Enforce single-firing + locked = locked || options.once; + + // Execute callbacks for all pending executions, + // respecting firingIndex overrides and runtime changes + fired = firing = true; + for ( ; queue.length; firingIndex = -1 ) { + memory = queue.shift(); + while ( ++firingIndex < list.length ) { + + // Run callback and check for early termination + if ( list[ firingIndex ].apply( memory[ 0 ], memory[ 1 ] ) === false && + options.stopOnFalse ) { + + // Jump to end and forget the data so .add doesn't re-fire + firingIndex = list.length; + memory = false; + } + } + } + + // Forget the data if we're done with it + if ( !options.memory ) { + memory = false; + } + + firing = false; + + // Clean up if we're done firing for good + if ( locked ) { + + // Keep an empty list if we have data for future add calls + if ( memory ) { + list = []; + + // Otherwise, this object is spent + } else { + list = ""; + } + } + }, + + // Actual Callbacks object + self = { + + // Add a callback or a collection of callbacks to the list + add: function() { + if ( list ) { + + // If we have memory from a past run, we should fire after adding + if ( memory && !firing ) { + firingIndex = list.length - 1; + queue.push( memory ); + } + + ( function add( args ) { + jQuery.each( args, function( _, arg ) { + if ( isFunction( arg ) ) { + if ( !options.unique || !self.has( arg ) ) { + list.push( arg ); + } + } else if ( arg && arg.length && toType( arg ) !== "string" ) { + + // Inspect recursively + add( arg ); + } + } ); + } )( arguments ); + + if ( memory && !firing ) { + fire(); + } + } + return this; + }, + + // Remove a callback from the list + remove: function() { + jQuery.each( arguments, function( _, arg ) { + var index; + while ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) { + list.splice( index, 1 ); + + // Handle firing indexes + if ( index <= firingIndex ) { + firingIndex--; + } + } + } ); + return this; + }, + + // Check if a given callback is in the list. + // If no argument is given, return whether or not list has callbacks attached. + has: function( fn ) { + return fn ? + jQuery.inArray( fn, list ) > -1 : + list.length > 0; + }, + + // Remove all callbacks from the list + empty: function() { + if ( list ) { + list = []; + } + return this; + }, + + // Disable .fire and .add + // Abort any current/pending executions + // Clear all callbacks and values + disable: function() { + locked = queue = []; + list = memory = ""; + return this; + }, + disabled: function() { + return !list; + }, + + // Disable .fire + // Also disable .add unless we have memory (since it would have no effect) + // Abort any pending executions + lock: function() { + locked = queue = []; + if ( !memory && !firing ) { + list = memory = ""; + } + return this; + }, + locked: function() { + return !!locked; + }, + + // Call all callbacks with the given context and arguments + fireWith: function( context, args ) { + if ( !locked ) { + args = args || []; + args = [ context, args.slice ? args.slice() : args ]; + queue.push( args ); + if ( !firing ) { + fire(); + } + } + return this; + }, + + // Call all the callbacks with the given arguments + fire: function() { + self.fireWith( this, arguments ); + return this; + }, + + // To know if the callbacks have already been called at least once + fired: function() { + return !!fired; + } + }; + + return self; +}; + + +function Identity( v ) { + return v; +} +function Thrower( ex ) { + throw ex; +} + +function adoptValue( value, resolve, reject, noValue ) { + var method; + + try { + + // Check for promise aspect first to privilege synchronous behavior + if ( value && isFunction( ( method = value.promise ) ) ) { + method.call( value ).done( resolve ).fail( reject ); + + // Other thenables + } else if ( value && isFunction( ( method = value.then ) ) ) { + method.call( value, resolve, reject ); + + // Other non-thenables + } else { + + // Control `resolve` arguments by letting Array#slice cast boolean `noValue` to integer: + // * false: [ value ].slice( 0 ) => resolve( value ) + // * true: [ value ].slice( 1 ) => resolve() + resolve.apply( undefined, [ value ].slice( noValue ) ); + } + + // For Promises/A+, convert exceptions into rejections + // Since jQuery.when doesn't unwrap thenables, we can skip the extra checks appearing in + // Deferred#then to conditionally suppress rejection. + } catch ( value ) { + + // Support: Android 4.0 only + // Strict mode functions invoked without .call/.apply get global-object context + reject.apply( undefined, [ value ] ); + } +} + +jQuery.extend( { + + Deferred: function( func ) { + var tuples = [ + + // action, add listener, callbacks, + // ... .then handlers, argument index, [final state] + [ "notify", "progress", jQuery.Callbacks( "memory" ), + jQuery.Callbacks( "memory" ), 2 ], + [ "resolve", "done", jQuery.Callbacks( "once memory" ), + jQuery.Callbacks( "once memory" ), 0, "resolved" ], + [ "reject", "fail", jQuery.Callbacks( "once memory" ), + jQuery.Callbacks( "once memory" ), 1, "rejected" ] + ], + state = "pending", + promise = { + state: function() { + return state; + }, + always: function() { + deferred.done( arguments ).fail( arguments ); + return this; + }, + "catch": function( fn ) { + return promise.then( null, fn ); + }, + + // Keep pipe for back-compat + pipe: function( /* fnDone, fnFail, fnProgress */ ) { + var fns = arguments; + + return jQuery.Deferred( function( newDefer ) { + jQuery.each( tuples, function( i, tuple ) { + + // Map tuples (progress, done, fail) to arguments (done, fail, progress) + var fn = isFunction( fns[ tuple[ 4 ] ] ) && fns[ tuple[ 4 ] ]; + + // deferred.progress(function() { bind to newDefer or newDefer.notify }) + // deferred.done(function() { bind to newDefer or newDefer.resolve }) + // deferred.fail(function() { bind to newDefer or newDefer.reject }) + deferred[ tuple[ 1 ] ]( function() { + var returned = fn && fn.apply( this, arguments ); + if ( returned && isFunction( returned.promise ) ) { + returned.promise() + .progress( newDefer.notify ) + .done( newDefer.resolve ) + .fail( newDefer.reject ); + } else { + newDefer[ tuple[ 0 ] + "With" ]( + this, + fn ? [ returned ] : arguments + ); + } + } ); + } ); + fns = null; + } ).promise(); + }, + then: function( onFulfilled, onRejected, onProgress ) { + var maxDepth = 0; + function resolve( depth, deferred, handler, special ) { + return function() { + var that = this, + args = arguments, + mightThrow = function() { + var returned, then; + + // Support: Promises/A+ section 2.3.3.3.3 + // https://promisesaplus.com/#point-59 + // Ignore double-resolution attempts + if ( depth < maxDepth ) { + return; + } + + returned = handler.apply( that, args ); + + // Support: Promises/A+ section 2.3.1 + // https://promisesaplus.com/#point-48 + if ( returned === deferred.promise() ) { + throw new TypeError( "Thenable self-resolution" ); + } + + // Support: Promises/A+ sections 2.3.3.1, 3.5 + // https://promisesaplus.com/#point-54 + // https://promisesaplus.com/#point-75 + // Retrieve `then` only once + then = returned && + + // Support: Promises/A+ section 2.3.4 + // https://promisesaplus.com/#point-64 + // Only check objects and functions for thenability + ( typeof returned === "object" || + typeof returned === "function" ) && + returned.then; + + // Handle a returned thenable + if ( isFunction( then ) ) { + + // Special processors (notify) just wait for resolution + if ( special ) { + then.call( + returned, + resolve( maxDepth, deferred, Identity, special ), + resolve( maxDepth, deferred, Thrower, special ) + ); + + // Normal processors (resolve) also hook into progress + } else { + + // ...and disregard older resolution values + maxDepth++; + + then.call( + returned, + resolve( maxDepth, deferred, Identity, special ), + resolve( maxDepth, deferred, Thrower, special ), + resolve( maxDepth, deferred, Identity, + deferred.notifyWith ) + ); + } + + // Handle all other returned values + } else { + + // Only substitute handlers pass on context + // and multiple values (non-spec behavior) + if ( handler !== Identity ) { + that = undefined; + args = [ returned ]; + } + + // Process the value(s) + // Default process is resolve + ( special || deferred.resolveWith )( that, args ); + } + }, + + // Only normal processors (resolve) catch and reject exceptions + process = special ? + mightThrow : + function() { + try { + mightThrow(); + } catch ( e ) { + + if ( jQuery.Deferred.exceptionHook ) { + jQuery.Deferred.exceptionHook( e, + process.stackTrace ); + } + + // Support: Promises/A+ section 2.3.3.3.4.1 + // https://promisesaplus.com/#point-61 + // Ignore post-resolution exceptions + if ( depth + 1 >= maxDepth ) { + + // Only substitute handlers pass on context + // and multiple values (non-spec behavior) + if ( handler !== Thrower ) { + that = undefined; + args = [ e ]; + } + + deferred.rejectWith( that, args ); + } + } + }; + + // Support: Promises/A+ section 2.3.3.3.1 + // https://promisesaplus.com/#point-57 + // Re-resolve promises immediately to dodge false rejection from + // subsequent errors + if ( depth ) { + process(); + } else { + + // Call an optional hook to record the stack, in case of exception + // since it's otherwise lost when execution goes async + if ( jQuery.Deferred.getStackHook ) { + process.stackTrace = jQuery.Deferred.getStackHook(); + } + window.setTimeout( process ); + } + }; + } + + return jQuery.Deferred( function( newDefer ) { + + // progress_handlers.add( ... ) + tuples[ 0 ][ 3 ].add( + resolve( + 0, + newDefer, + isFunction( onProgress ) ? + onProgress : + Identity, + newDefer.notifyWith + ) + ); + + // fulfilled_handlers.add( ... ) + tuples[ 1 ][ 3 ].add( + resolve( + 0, + newDefer, + isFunction( onFulfilled ) ? + onFulfilled : + Identity + ) + ); + + // rejected_handlers.add( ... ) + tuples[ 2 ][ 3 ].add( + resolve( + 0, + newDefer, + isFunction( onRejected ) ? + onRejected : + Thrower + ) + ); + } ).promise(); + }, + + // Get a promise for this deferred + // If obj is provided, the promise aspect is added to the object + promise: function( obj ) { + return obj != null ? jQuery.extend( obj, promise ) : promise; + } + }, + deferred = {}; + + // Add list-specific methods + jQuery.each( tuples, function( i, tuple ) { + var list = tuple[ 2 ], + stateString = tuple[ 5 ]; + + // promise.progress = list.add + // promise.done = list.add + // promise.fail = list.add + promise[ tuple[ 1 ] ] = list.add; + + // Handle state + if ( stateString ) { + list.add( + function() { + + // state = "resolved" (i.e., fulfilled) + // state = "rejected" + state = stateString; + }, + + // rejected_callbacks.disable + // fulfilled_callbacks.disable + tuples[ 3 - i ][ 2 ].disable, + + // rejected_handlers.disable + // fulfilled_handlers.disable + tuples[ 3 - i ][ 3 ].disable, + + // progress_callbacks.lock + tuples[ 0 ][ 2 ].lock, + + // progress_handlers.lock + tuples[ 0 ][ 3 ].lock + ); + } + + // progress_handlers.fire + // fulfilled_handlers.fire + // rejected_handlers.fire + list.add( tuple[ 3 ].fire ); + + // deferred.notify = function() { deferred.notifyWith(...) } + // deferred.resolve = function() { deferred.resolveWith(...) } + // deferred.reject = function() { deferred.rejectWith(...) } + deferred[ tuple[ 0 ] ] = function() { + deferred[ tuple[ 0 ] + "With" ]( this === deferred ? undefined : this, arguments ); + return this; + }; + + // deferred.notifyWith = list.fireWith + // deferred.resolveWith = list.fireWith + // deferred.rejectWith = list.fireWith + deferred[ tuple[ 0 ] + "With" ] = list.fireWith; + } ); + + // Make the deferred a promise + promise.promise( deferred ); + + // Call given func if any + if ( func ) { + func.call( deferred, deferred ); + } + + // All done! + return deferred; + }, + + // Deferred helper + when: function( singleValue ) { + var + + // count of uncompleted subordinates + remaining = arguments.length, + + // count of unprocessed arguments + i = remaining, + + // subordinate fulfillment data + resolveContexts = Array( i ), + resolveValues = slice.call( arguments ), + + // the master Deferred + master = jQuery.Deferred(), + + // subordinate callback factory + updateFunc = function( i ) { + return function( value ) { + resolveContexts[ i ] = this; + resolveValues[ i ] = arguments.length > 1 ? slice.call( arguments ) : value; + if ( !( --remaining ) ) { + master.resolveWith( resolveContexts, resolveValues ); + } + }; + }; + + // Single- and empty arguments are adopted like Promise.resolve + if ( remaining <= 1 ) { + adoptValue( singleValue, master.done( updateFunc( i ) ).resolve, master.reject, + !remaining ); + + // Use .then() to unwrap secondary thenables (cf. gh-3000) + if ( master.state() === "pending" || + isFunction( resolveValues[ i ] && resolveValues[ i ].then ) ) { + + return master.then(); + } + } + + // Multiple arguments are aggregated like Promise.all array elements + while ( i-- ) { + adoptValue( resolveValues[ i ], updateFunc( i ), master.reject ); + } + + return master.promise(); + } +} ); + + +// These usually indicate a programmer mistake during development, +// warn about them ASAP rather than swallowing them by default. +var rerrorNames = /^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/; + +jQuery.Deferred.exceptionHook = function( error, stack ) { + + // Support: IE 8 - 9 only + // Console exists when dev tools are open, which can happen at any time + if ( window.console && window.console.warn && error && rerrorNames.test( error.name ) ) { + window.console.warn( "jQuery.Deferred exception: " + error.message, error.stack, stack ); + } +}; + + + + +jQuery.readyException = function( error ) { + window.setTimeout( function() { + throw error; + } ); +}; + + + + +// The deferred used on DOM ready +var readyList = jQuery.Deferred(); + +jQuery.fn.ready = function( fn ) { + + readyList + .then( fn ) + + // Wrap jQuery.readyException in a function so that the lookup + // happens at the time of error handling instead of callback + // registration. + .catch( function( error ) { + jQuery.readyException( error ); + } ); + + return this; +}; + +jQuery.extend( { + + // Is the DOM ready to be used? Set to true once it occurs. + isReady: false, + + // A counter to track how many items to wait for before + // the ready event fires. See #6781 + readyWait: 1, + + // Handle when the DOM is ready + ready: function( wait ) { + + // Abort if there are pending holds or we're already ready + if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) { + return; + } + + // Remember that the DOM is ready + jQuery.isReady = true; + + // If a normal DOM Ready event fired, decrement, and wait if need be + if ( wait !== true && --jQuery.readyWait > 0 ) { + return; + } + + // If there are functions bound, to execute + readyList.resolveWith( document, [ jQuery ] ); + } +} ); + +jQuery.ready.then = readyList.then; + +// The ready event handler and self cleanup method +function completed() { + document.removeEventListener( "DOMContentLoaded", completed ); + window.removeEventListener( "load", completed ); + jQuery.ready(); +} + +// Catch cases where $(document).ready() is called +// after the browser event has already occurred. +// Support: IE <=9 - 10 only +// Older IE sometimes signals "interactive" too soon +if ( document.readyState === "complete" || + ( document.readyState !== "loading" && !document.documentElement.doScroll ) ) { + + // Handle it asynchronously to allow scripts the opportunity to delay ready + window.setTimeout( jQuery.ready ); + +} else { + + // Use the handy event callback + document.addEventListener( "DOMContentLoaded", completed ); + + // A fallback to window.onload, that will always work + window.addEventListener( "load", completed ); +} + + + + +// Multifunctional method to get and set values of a collection +// The value/s can optionally be executed if it's a function +var access = function( elems, fn, key, value, chainable, emptyGet, raw ) { + var i = 0, + len = elems.length, + bulk = key == null; + + // Sets many values + if ( toType( key ) === "object" ) { + chainable = true; + for ( i in key ) { + access( elems, fn, i, key[ i ], true, emptyGet, raw ); + } + + // Sets one value + } else if ( value !== undefined ) { + chainable = true; + + if ( !isFunction( value ) ) { + raw = true; + } + + if ( bulk ) { + + // Bulk operations run against the entire set + if ( raw ) { + fn.call( elems, value ); + fn = null; + + // ...except when executing function values + } else { + bulk = fn; + fn = function( elem, key, value ) { + return bulk.call( jQuery( elem ), value ); + }; + } + } + + if ( fn ) { + for ( ; i < len; i++ ) { + fn( + elems[ i ], key, raw ? + value : + value.call( elems[ i ], i, fn( elems[ i ], key ) ) + ); + } + } + } + + if ( chainable ) { + return elems; + } + + // Gets + if ( bulk ) { + return fn.call( elems ); + } + + return len ? fn( elems[ 0 ], key ) : emptyGet; +}; + + +// Matches dashed string for camelizing +var rmsPrefix = /^-ms-/, + rdashAlpha = /-([a-z])/g; + +// Used by camelCase as callback to replace() +function fcamelCase( all, letter ) { + return letter.toUpperCase(); +} + +// Convert dashed to camelCase; used by the css and data modules +// Support: IE <=9 - 11, Edge 12 - 15 +// Microsoft forgot to hump their vendor prefix (#9572) +function camelCase( string ) { + return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase ); +} +var acceptData = function( owner ) { + + // Accepts only: + // - Node + // - Node.ELEMENT_NODE + // - Node.DOCUMENT_NODE + // - Object + // - Any + return owner.nodeType === 1 || owner.nodeType === 9 || !( +owner.nodeType ); +}; + + + + +function Data() { + this.expando = jQuery.expando + Data.uid++; +} + +Data.uid = 1; + +Data.prototype = { + + cache: function( owner ) { + + // Check if the owner object already has a cache + var value = owner[ this.expando ]; + + // If not, create one + if ( !value ) { + value = {}; + + // We can accept data for non-element nodes in modern browsers, + // but we should not, see #8335. + // Always return an empty object. + if ( acceptData( owner ) ) { + + // If it is a node unlikely to be stringify-ed or looped over + // use plain assignment + if ( owner.nodeType ) { + owner[ this.expando ] = value; + + // Otherwise secure it in a non-enumerable property + // configurable must be true to allow the property to be + // deleted when data is removed + } else { + Object.defineProperty( owner, this.expando, { + value: value, + configurable: true + } ); + } + } + } + + return value; + }, + set: function( owner, data, value ) { + var prop, + cache = this.cache( owner ); + + // Handle: [ owner, key, value ] args + // Always use camelCase key (gh-2257) + if ( typeof data === "string" ) { + cache[ camelCase( data ) ] = value; + + // Handle: [ owner, { properties } ] args + } else { + + // Copy the properties one-by-one to the cache object + for ( prop in data ) { + cache[ camelCase( prop ) ] = data[ prop ]; + } + } + return cache; + }, + get: function( owner, key ) { + return key === undefined ? + this.cache( owner ) : + + // Always use camelCase key (gh-2257) + owner[ this.expando ] && owner[ this.expando ][ camelCase( key ) ]; + }, + access: function( owner, key, value ) { + + // In cases where either: + // + // 1. No key was specified + // 2. A string key was specified, but no value provided + // + // Take the "read" path and allow the get method to determine + // which value to return, respectively either: + // + // 1. The entire cache object + // 2. The data stored at the key + // + if ( key === undefined || + ( ( key && typeof key === "string" ) && value === undefined ) ) { + + return this.get( owner, key ); + } + + // When the key is not a string, or both a key and value + // are specified, set or extend (existing objects) with either: + // + // 1. An object of properties + // 2. A key and value + // + this.set( owner, key, value ); + + // Since the "set" path can have two possible entry points + // return the expected data based on which path was taken[*] + return value !== undefined ? value : key; + }, + remove: function( owner, key ) { + var i, + cache = owner[ this.expando ]; + + if ( cache === undefined ) { + return; + } + + if ( key !== undefined ) { + + // Support array or space separated string of keys + if ( Array.isArray( key ) ) { + + // If key is an array of keys... + // We always set camelCase keys, so remove that. + key = key.map( camelCase ); + } else { + key = camelCase( key ); + + // If a key with the spaces exists, use it. + // Otherwise, create an array by matching non-whitespace + key = key in cache ? + [ key ] : + ( key.match( rnothtmlwhite ) || [] ); + } + + i = key.length; + + while ( i-- ) { + delete cache[ key[ i ] ]; + } + } + + // Remove the expando if there's no more data + if ( key === undefined || jQuery.isEmptyObject( cache ) ) { + + // Support: Chrome <=35 - 45 + // Webkit & Blink performance suffers when deleting properties + // from DOM nodes, so set to undefined instead + // https://bugs.chromium.org/p/chromium/issues/detail?id=378607 (bug restricted) + if ( owner.nodeType ) { + owner[ this.expando ] = undefined; + } else { + delete owner[ this.expando ]; + } + } + }, + hasData: function( owner ) { + var cache = owner[ this.expando ]; + return cache !== undefined && !jQuery.isEmptyObject( cache ); + } +}; +var dataPriv = new Data(); + +var dataUser = new Data(); + + + +// Implementation Summary +// +// 1. Enforce API surface and semantic compatibility with 1.9.x branch +// 2. Improve the module's maintainability by reducing the storage +// paths to a single mechanism. +// 3. Use the same single mechanism to support "private" and "user" data. +// 4. _Never_ expose "private" data to user code (TODO: Drop _data, _removeData) +// 5. Avoid exposing implementation details on user objects (eg. expando properties) +// 6. Provide a clear path for implementation upgrade to WeakMap in 2014 + +var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/, + rmultiDash = /[A-Z]/g; + +function getData( data ) { + if ( data === "true" ) { + return true; + } + + if ( data === "false" ) { + return false; + } + + if ( data === "null" ) { + return null; + } + + // Only convert to a number if it doesn't change the string + if ( data === +data + "" ) { + return +data; + } + + if ( rbrace.test( data ) ) { + return JSON.parse( data ); + } + + return data; +} + +function dataAttr( elem, key, data ) { + var name; + + // If nothing was found internally, try to fetch any + // data from the HTML5 data-* attribute + if ( data === undefined && elem.nodeType === 1 ) { + name = "data-" + key.replace( rmultiDash, "-$&" ).toLowerCase(); + data = elem.getAttribute( name ); + + if ( typeof data === "string" ) { + try { + data = getData( data ); + } catch ( e ) {} + + // Make sure we set the data so it isn't changed later + dataUser.set( elem, key, data ); + } else { + data = undefined; + } + } + return data; +} + +jQuery.extend( { + hasData: function( elem ) { + return dataUser.hasData( elem ) || dataPriv.hasData( elem ); + }, + + data: function( elem, name, data ) { + return dataUser.access( elem, name, data ); + }, + + removeData: function( elem, name ) { + dataUser.remove( elem, name ); + }, + + // TODO: Now that all calls to _data and _removeData have been replaced + // with direct calls to dataPriv methods, these can be deprecated. + _data: function( elem, name, data ) { + return dataPriv.access( elem, name, data ); + }, + + _removeData: function( elem, name ) { + dataPriv.remove( elem, name ); + } +} ); + +jQuery.fn.extend( { + data: function( key, value ) { + var i, name, data, + elem = this[ 0 ], + attrs = elem && elem.attributes; + + // Gets all values + if ( key === undefined ) { + if ( this.length ) { + data = dataUser.get( elem ); + + if ( elem.nodeType === 1 && !dataPriv.get( elem, "hasDataAttrs" ) ) { + i = attrs.length; + while ( i-- ) { + + // Support: IE 11 only + // The attrs elements can be null (#14894) + if ( attrs[ i ] ) { + name = attrs[ i ].name; + if ( name.indexOf( "data-" ) === 0 ) { + name = camelCase( name.slice( 5 ) ); + dataAttr( elem, name, data[ name ] ); + } + } + } + dataPriv.set( elem, "hasDataAttrs", true ); + } + } + + return data; + } + + // Sets multiple values + if ( typeof key === "object" ) { + return this.each( function() { + dataUser.set( this, key ); + } ); + } + + return access( this, function( value ) { + var data; + + // The calling jQuery object (element matches) is not empty + // (and therefore has an element appears at this[ 0 ]) and the + // `value` parameter was not undefined. An empty jQuery object + // will result in `undefined` for elem = this[ 0 ] which will + // throw an exception if an attempt to read a data cache is made. + if ( elem && value === undefined ) { + + // Attempt to get data from the cache + // The key will always be camelCased in Data + data = dataUser.get( elem, key ); + if ( data !== undefined ) { + return data; + } + + // Attempt to "discover" the data in + // HTML5 custom data-* attrs + data = dataAttr( elem, key ); + if ( data !== undefined ) { + return data; + } + + // We tried really hard, but the data doesn't exist. + return; + } + + // Set the data... + this.each( function() { + + // We always store the camelCased key + dataUser.set( this, key, value ); + } ); + }, null, value, arguments.length > 1, null, true ); + }, + + removeData: function( key ) { + return this.each( function() { + dataUser.remove( this, key ); + } ); + } +} ); + + +jQuery.extend( { + queue: function( elem, type, data ) { + var queue; + + if ( elem ) { + type = ( type || "fx" ) + "queue"; + queue = dataPriv.get( elem, type ); + + // Speed up dequeue by getting out quickly if this is just a lookup + if ( data ) { + if ( !queue || Array.isArray( data ) ) { + queue = dataPriv.access( elem, type, jQuery.makeArray( data ) ); + } else { + queue.push( data ); + } + } + return queue || []; + } + }, + + dequeue: function( elem, type ) { + type = type || "fx"; + + var queue = jQuery.queue( elem, type ), + startLength = queue.length, + fn = queue.shift(), + hooks = jQuery._queueHooks( elem, type ), + next = function() { + jQuery.dequeue( elem, type ); + }; + + // If the fx queue is dequeued, always remove the progress sentinel + if ( fn === "inprogress" ) { + fn = queue.shift(); + startLength--; + } + + if ( fn ) { + + // Add a progress sentinel to prevent the fx queue from being + // automatically dequeued + if ( type === "fx" ) { + queue.unshift( "inprogress" ); + } + + // Clear up the last queue stop function + delete hooks.stop; + fn.call( elem, next, hooks ); + } + + if ( !startLength && hooks ) { + hooks.empty.fire(); + } + }, + + // Not public - generate a queueHooks object, or return the current one + _queueHooks: function( elem, type ) { + var key = type + "queueHooks"; + return dataPriv.get( elem, key ) || dataPriv.access( elem, key, { + empty: jQuery.Callbacks( "once memory" ).add( function() { + dataPriv.remove( elem, [ type + "queue", key ] ); + } ) + } ); + } +} ); + +jQuery.fn.extend( { + queue: function( type, data ) { + var setter = 2; + + if ( typeof type !== "string" ) { + data = type; + type = "fx"; + setter--; + } + + if ( arguments.length < setter ) { + return jQuery.queue( this[ 0 ], type ); + } + + return data === undefined ? + this : + this.each( function() { + var queue = jQuery.queue( this, type, data ); + + // Ensure a hooks for this queue + jQuery._queueHooks( this, type ); + + if ( type === "fx" && queue[ 0 ] !== "inprogress" ) { + jQuery.dequeue( this, type ); + } + } ); + }, + dequeue: function( type ) { + return this.each( function() { + jQuery.dequeue( this, type ); + } ); + }, + clearQueue: function( type ) { + return this.queue( type || "fx", [] ); + }, + + // Get a promise resolved when queues of a certain type + // are emptied (fx is the type by default) + promise: function( type, obj ) { + var tmp, + count = 1, + defer = jQuery.Deferred(), + elements = this, + i = this.length, + resolve = function() { + if ( !( --count ) ) { + defer.resolveWith( elements, [ elements ] ); + } + }; + + if ( typeof type !== "string" ) { + obj = type; + type = undefined; + } + type = type || "fx"; + + while ( i-- ) { + tmp = dataPriv.get( elements[ i ], type + "queueHooks" ); + if ( tmp && tmp.empty ) { + count++; + tmp.empty.add( resolve ); + } + } + resolve(); + return defer.promise( obj ); + } +} ); +var pnum = ( /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/ ).source; + +var rcssNum = new RegExp( "^(?:([+-])=|)(" + pnum + ")([a-z%]*)$", "i" ); + + +var cssExpand = [ "Top", "Right", "Bottom", "Left" ]; + +var documentElement = document.documentElement; + + + + var isAttached = function( elem ) { + return jQuery.contains( elem.ownerDocument, elem ); + }, + composed = { composed: true }; + + // Support: IE 9 - 11+, Edge 12 - 18+, iOS 10.0 - 10.2 only + // Check attachment across shadow DOM boundaries when possible (gh-3504) + // Support: iOS 10.0-10.2 only + // Early iOS 10 versions support `attachShadow` but not `getRootNode`, + // leading to errors. We need to check for `getRootNode`. + if ( documentElement.getRootNode ) { + isAttached = function( elem ) { + return jQuery.contains( elem.ownerDocument, elem ) || + elem.getRootNode( composed ) === elem.ownerDocument; + }; + } +var isHiddenWithinTree = function( elem, el ) { + + // isHiddenWithinTree might be called from jQuery#filter function; + // in that case, element will be second argument + elem = el || elem; + + // Inline style trumps all + return elem.style.display === "none" || + elem.style.display === "" && + + // Otherwise, check computed style + // Support: Firefox <=43 - 45 + // Disconnected elements can have computed display: none, so first confirm that elem is + // in the document. + isAttached( elem ) && + + jQuery.css( elem, "display" ) === "none"; + }; + +var swap = function( elem, options, callback, args ) { + var ret, name, + old = {}; + + // Remember the old values, and insert the new ones + for ( name in options ) { + old[ name ] = elem.style[ name ]; + elem.style[ name ] = options[ name ]; + } + + ret = callback.apply( elem, args || [] ); + + // Revert the old values + for ( name in options ) { + elem.style[ name ] = old[ name ]; + } + + return ret; +}; + + + + +function adjustCSS( elem, prop, valueParts, tween ) { + var adjusted, scale, + maxIterations = 20, + currentValue = tween ? + function() { + return tween.cur(); + } : + function() { + return jQuery.css( elem, prop, "" ); + }, + initial = currentValue(), + unit = valueParts && valueParts[ 3 ] || ( jQuery.cssNumber[ prop ] ? "" : "px" ), + + // Starting value computation is required for potential unit mismatches + initialInUnit = elem.nodeType && + ( jQuery.cssNumber[ prop ] || unit !== "px" && +initial ) && + rcssNum.exec( jQuery.css( elem, prop ) ); + + if ( initialInUnit && initialInUnit[ 3 ] !== unit ) { + + // Support: Firefox <=54 + // Halve the iteration target value to prevent interference from CSS upper bounds (gh-2144) + initial = initial / 2; + + // Trust units reported by jQuery.css + unit = unit || initialInUnit[ 3 ]; + + // Iteratively approximate from a nonzero starting point + initialInUnit = +initial || 1; + + while ( maxIterations-- ) { + + // Evaluate and update our best guess (doubling guesses that zero out). + // Finish if the scale equals or crosses 1 (making the old*new product non-positive). + jQuery.style( elem, prop, initialInUnit + unit ); + if ( ( 1 - scale ) * ( 1 - ( scale = currentValue() / initial || 0.5 ) ) <= 0 ) { + maxIterations = 0; + } + initialInUnit = initialInUnit / scale; + + } + + initialInUnit = initialInUnit * 2; + jQuery.style( elem, prop, initialInUnit + unit ); + + // Make sure we update the tween properties later on + valueParts = valueParts || []; + } + + if ( valueParts ) { + initialInUnit = +initialInUnit || +initial || 0; + + // Apply relative offset (+=/-=) if specified + adjusted = valueParts[ 1 ] ? + initialInUnit + ( valueParts[ 1 ] + 1 ) * valueParts[ 2 ] : + +valueParts[ 2 ]; + if ( tween ) { + tween.unit = unit; + tween.start = initialInUnit; + tween.end = adjusted; + } + } + return adjusted; +} + + +var defaultDisplayMap = {}; + +function getDefaultDisplay( elem ) { + var temp, + doc = elem.ownerDocument, + nodeName = elem.nodeName, + display = defaultDisplayMap[ nodeName ]; + + if ( display ) { + return display; + } + + temp = doc.body.appendChild( doc.createElement( nodeName ) ); + display = jQuery.css( temp, "display" ); + + temp.parentNode.removeChild( temp ); + + if ( display === "none" ) { + display = "block"; + } + defaultDisplayMap[ nodeName ] = display; + + return display; +} + +function showHide( elements, show ) { + var display, elem, + values = [], + index = 0, + length = elements.length; + + // Determine new display value for elements that need to change + for ( ; index < length; index++ ) { + elem = elements[ index ]; + if ( !elem.style ) { + continue; + } + + display = elem.style.display; + if ( show ) { + + // Since we force visibility upon cascade-hidden elements, an immediate (and slow) + // check is required in this first loop unless we have a nonempty display value (either + // inline or about-to-be-restored) + if ( display === "none" ) { + values[ index ] = dataPriv.get( elem, "display" ) || null; + if ( !values[ index ] ) { + elem.style.display = ""; + } + } + if ( elem.style.display === "" && isHiddenWithinTree( elem ) ) { + values[ index ] = getDefaultDisplay( elem ); + } + } else { + if ( display !== "none" ) { + values[ index ] = "none"; + + // Remember what we're overwriting + dataPriv.set( elem, "display", display ); + } + } + } + + // Set the display of the elements in a second loop to avoid constant reflow + for ( index = 0; index < length; index++ ) { + if ( values[ index ] != null ) { + elements[ index ].style.display = values[ index ]; + } + } + + return elements; +} + +jQuery.fn.extend( { + show: function() { + return showHide( this, true ); + }, + hide: function() { + return showHide( this ); + }, + toggle: function( state ) { + if ( typeof state === "boolean" ) { + return state ? this.show() : this.hide(); + } + + return this.each( function() { + if ( isHiddenWithinTree( this ) ) { + jQuery( this ).show(); + } else { + jQuery( this ).hide(); + } + } ); + } +} ); +var rcheckableType = ( /^(?:checkbox|radio)$/i ); + +var rtagName = ( /<([a-z][^\/\0>\x20\t\r\n\f]*)/i ); + +var rscriptType = ( /^$|^module$|\/(?:java|ecma)script/i ); + + + +// We have to close these tags to support XHTML (#13200) +var wrapMap = { + + // Support: IE <=9 only + option: [ 1, "" ], + + // XHTML parsers do not magically insert elements in the + // same way that tag soup parsers do. So we cannot shorten + // this by omitting or other required elements. + thead: [ 1, "", "
    " ], + col: [ 2, "", "
    " ], + tr: [ 2, "", "
    " ], + td: [ 3, "", "
    " ], + + _default: [ 0, "", "" ] +}; + +// Support: IE <=9 only +wrapMap.optgroup = wrapMap.option; + +wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead; +wrapMap.th = wrapMap.td; + + +function getAll( context, tag ) { + + // Support: IE <=9 - 11 only + // Use typeof to avoid zero-argument method invocation on host objects (#15151) + var ret; + + if ( typeof context.getElementsByTagName !== "undefined" ) { + ret = context.getElementsByTagName( tag || "*" ); + + } else if ( typeof context.querySelectorAll !== "undefined" ) { + ret = context.querySelectorAll( tag || "*" ); + + } else { + ret = []; + } + + if ( tag === undefined || tag && nodeName( context, tag ) ) { + return jQuery.merge( [ context ], ret ); + } + + return ret; +} + + +// Mark scripts as having already been evaluated +function setGlobalEval( elems, refElements ) { + var i = 0, + l = elems.length; + + for ( ; i < l; i++ ) { + dataPriv.set( + elems[ i ], + "globalEval", + !refElements || dataPriv.get( refElements[ i ], "globalEval" ) + ); + } +} + + +var rhtml = /<|&#?\w+;/; + +function buildFragment( elems, context, scripts, selection, ignored ) { + var elem, tmp, tag, wrap, attached, j, + fragment = context.createDocumentFragment(), + nodes = [], + i = 0, + l = elems.length; + + for ( ; i < l; i++ ) { + elem = elems[ i ]; + + if ( elem || elem === 0 ) { + + // Add nodes directly + if ( toType( elem ) === "object" ) { + + // Support: Android <=4.0 only, PhantomJS 1 only + // push.apply(_, arraylike) throws on ancient WebKit + jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem ); + + // Convert non-html into a text node + } else if ( !rhtml.test( elem ) ) { + nodes.push( context.createTextNode( elem ) ); + + // Convert html into DOM nodes + } else { + tmp = tmp || fragment.appendChild( context.createElement( "div" ) ); + + // Deserialize a standard representation + tag = ( rtagName.exec( elem ) || [ "", "" ] )[ 1 ].toLowerCase(); + wrap = wrapMap[ tag ] || wrapMap._default; + tmp.innerHTML = wrap[ 1 ] + jQuery.htmlPrefilter( elem ) + wrap[ 2 ]; + + // Descend through wrappers to the right content + j = wrap[ 0 ]; + while ( j-- ) { + tmp = tmp.lastChild; + } + + // Support: Android <=4.0 only, PhantomJS 1 only + // push.apply(_, arraylike) throws on ancient WebKit + jQuery.merge( nodes, tmp.childNodes ); + + // Remember the top-level container + tmp = fragment.firstChild; + + // Ensure the created nodes are orphaned (#12392) + tmp.textContent = ""; + } + } + } + + // Remove wrapper from fragment + fragment.textContent = ""; + + i = 0; + while ( ( elem = nodes[ i++ ] ) ) { + + // Skip elements already in the context collection (trac-4087) + if ( selection && jQuery.inArray( elem, selection ) > -1 ) { + if ( ignored ) { + ignored.push( elem ); + } + continue; + } + + attached = isAttached( elem ); + + // Append to fragment + tmp = getAll( fragment.appendChild( elem ), "script" ); + + // Preserve script evaluation history + if ( attached ) { + setGlobalEval( tmp ); + } + + // Capture executables + if ( scripts ) { + j = 0; + while ( ( elem = tmp[ j++ ] ) ) { + if ( rscriptType.test( elem.type || "" ) ) { + scripts.push( elem ); + } + } + } + } + + return fragment; +} + + +( function() { + var fragment = document.createDocumentFragment(), + div = fragment.appendChild( document.createElement( "div" ) ), + input = document.createElement( "input" ); + + // Support: Android 4.0 - 4.3 only + // Check state lost if the name is set (#11217) + // Support: Windows Web Apps (WWA) + // `name` and `type` must use .setAttribute for WWA (#14901) + input.setAttribute( "type", "radio" ); + input.setAttribute( "checked", "checked" ); + input.setAttribute( "name", "t" ); + + div.appendChild( input ); + + // Support: Android <=4.1 only + // Older WebKit doesn't clone checked state correctly in fragments + support.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked; + + // Support: IE <=11 only + // Make sure textarea (and checkbox) defaultValue is properly cloned + div.innerHTML = ""; + support.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue; +} )(); + + +var + rkeyEvent = /^key/, + rmouseEvent = /^(?:mouse|pointer|contextmenu|drag|drop)|click/, + rtypenamespace = /^([^.]*)(?:\.(.+)|)/; + +function returnTrue() { + return true; +} + +function returnFalse() { + return false; +} + +// Support: IE <=9 - 11+ +// focus() and blur() are asynchronous, except when they are no-op. +// So expect focus to be synchronous when the element is already active, +// and blur to be synchronous when the element is not already active. +// (focus and blur are always synchronous in other supported browsers, +// this just defines when we can count on it). +function expectSync( elem, type ) { + return ( elem === safeActiveElement() ) === ( type === "focus" ); +} + +// Support: IE <=9 only +// Accessing document.activeElement can throw unexpectedly +// https://bugs.jquery.com/ticket/13393 +function safeActiveElement() { + try { + return document.activeElement; + } catch ( err ) { } +} + +function on( elem, types, selector, data, fn, one ) { + var origFn, type; + + // Types can be a map of types/handlers + if ( typeof types === "object" ) { + + // ( types-Object, selector, data ) + if ( typeof selector !== "string" ) { + + // ( types-Object, data ) + data = data || selector; + selector = undefined; + } + for ( type in types ) { + on( elem, type, selector, data, types[ type ], one ); + } + return elem; + } + + if ( data == null && fn == null ) { + + // ( types, fn ) + fn = selector; + data = selector = undefined; + } else if ( fn == null ) { + if ( typeof selector === "string" ) { + + // ( types, selector, fn ) + fn = data; + data = undefined; + } else { + + // ( types, data, fn ) + fn = data; + data = selector; + selector = undefined; + } + } + if ( fn === false ) { + fn = returnFalse; + } else if ( !fn ) { + return elem; + } + + if ( one === 1 ) { + origFn = fn; + fn = function( event ) { + + // Can use an empty set, since event contains the info + jQuery().off( event ); + return origFn.apply( this, arguments ); + }; + + // Use same guid so caller can remove using origFn + fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ ); + } + return elem.each( function() { + jQuery.event.add( this, types, fn, data, selector ); + } ); +} + +/* + * Helper functions for managing events -- not part of the public interface. + * Props to Dean Edwards' addEvent library for many of the ideas. + */ +jQuery.event = { + + global: {}, + + add: function( elem, types, handler, data, selector ) { + + var handleObjIn, eventHandle, tmp, + events, t, handleObj, + special, handlers, type, namespaces, origType, + elemData = dataPriv.get( elem ); + + // Don't attach events to noData or text/comment nodes (but allow plain objects) + if ( !elemData ) { + return; + } + + // Caller can pass in an object of custom data in lieu of the handler + if ( handler.handler ) { + handleObjIn = handler; + handler = handleObjIn.handler; + selector = handleObjIn.selector; + } + + // Ensure that invalid selectors throw exceptions at attach time + // Evaluate against documentElement in case elem is a non-element node (e.g., document) + if ( selector ) { + jQuery.find.matchesSelector( documentElement, selector ); + } + + // Make sure that the handler has a unique ID, used to find/remove it later + if ( !handler.guid ) { + handler.guid = jQuery.guid++; + } + + // Init the element's event structure and main handler, if this is the first + if ( !( events = elemData.events ) ) { + events = elemData.events = {}; + } + if ( !( eventHandle = elemData.handle ) ) { + eventHandle = elemData.handle = function( e ) { + + // Discard the second event of a jQuery.event.trigger() and + // when an event is called after a page has unloaded + return typeof jQuery !== "undefined" && jQuery.event.triggered !== e.type ? + jQuery.event.dispatch.apply( elem, arguments ) : undefined; + }; + } + + // Handle multiple events separated by a space + types = ( types || "" ).match( rnothtmlwhite ) || [ "" ]; + t = types.length; + while ( t-- ) { + tmp = rtypenamespace.exec( types[ t ] ) || []; + type = origType = tmp[ 1 ]; + namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort(); + + // There *must* be a type, no attaching namespace-only handlers + if ( !type ) { + continue; + } + + // If event changes its type, use the special event handlers for the changed type + special = jQuery.event.special[ type ] || {}; + + // If selector defined, determine special event api type, otherwise given type + type = ( selector ? special.delegateType : special.bindType ) || type; + + // Update special based on newly reset type + special = jQuery.event.special[ type ] || {}; + + // handleObj is passed to all event handlers + handleObj = jQuery.extend( { + type: type, + origType: origType, + data: data, + handler: handler, + guid: handler.guid, + selector: selector, + needsContext: selector && jQuery.expr.match.needsContext.test( selector ), + namespace: namespaces.join( "." ) + }, handleObjIn ); + + // Init the event handler queue if we're the first + if ( !( handlers = events[ type ] ) ) { + handlers = events[ type ] = []; + handlers.delegateCount = 0; + + // Only use addEventListener if the special events handler returns false + if ( !special.setup || + special.setup.call( elem, data, namespaces, eventHandle ) === false ) { + + if ( elem.addEventListener ) { + elem.addEventListener( type, eventHandle ); + } + } + } + + if ( special.add ) { + special.add.call( elem, handleObj ); + + if ( !handleObj.handler.guid ) { + handleObj.handler.guid = handler.guid; + } + } + + // Add to the element's handler list, delegates in front + if ( selector ) { + handlers.splice( handlers.delegateCount++, 0, handleObj ); + } else { + handlers.push( handleObj ); + } + + // Keep track of which events have ever been used, for event optimization + jQuery.event.global[ type ] = true; + } + + }, + + // Detach an event or set of events from an element + remove: function( elem, types, handler, selector, mappedTypes ) { + + var j, origCount, tmp, + events, t, handleObj, + special, handlers, type, namespaces, origType, + elemData = dataPriv.hasData( elem ) && dataPriv.get( elem ); + + if ( !elemData || !( events = elemData.events ) ) { + return; + } + + // Once for each type.namespace in types; type may be omitted + types = ( types || "" ).match( rnothtmlwhite ) || [ "" ]; + t = types.length; + while ( t-- ) { + tmp = rtypenamespace.exec( types[ t ] ) || []; + type = origType = tmp[ 1 ]; + namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort(); + + // Unbind all events (on this namespace, if provided) for the element + if ( !type ) { + for ( type in events ) { + jQuery.event.remove( elem, type + types[ t ], handler, selector, true ); + } + continue; + } + + special = jQuery.event.special[ type ] || {}; + type = ( selector ? special.delegateType : special.bindType ) || type; + handlers = events[ type ] || []; + tmp = tmp[ 2 ] && + new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" ); + + // Remove matching events + origCount = j = handlers.length; + while ( j-- ) { + handleObj = handlers[ j ]; + + if ( ( mappedTypes || origType === handleObj.origType ) && + ( !handler || handler.guid === handleObj.guid ) && + ( !tmp || tmp.test( handleObj.namespace ) ) && + ( !selector || selector === handleObj.selector || + selector === "**" && handleObj.selector ) ) { + handlers.splice( j, 1 ); + + if ( handleObj.selector ) { + handlers.delegateCount--; + } + if ( special.remove ) { + special.remove.call( elem, handleObj ); + } + } + } + + // Remove generic event handler if we removed something and no more handlers exist + // (avoids potential for endless recursion during removal of special event handlers) + if ( origCount && !handlers.length ) { + if ( !special.teardown || + special.teardown.call( elem, namespaces, elemData.handle ) === false ) { + + jQuery.removeEvent( elem, type, elemData.handle ); + } + + delete events[ type ]; + } + } + + // Remove data and the expando if it's no longer used + if ( jQuery.isEmptyObject( events ) ) { + dataPriv.remove( elem, "handle events" ); + } + }, + + dispatch: function( nativeEvent ) { + + // Make a writable jQuery.Event from the native event object + var event = jQuery.event.fix( nativeEvent ); + + var i, j, ret, matched, handleObj, handlerQueue, + args = new Array( arguments.length ), + handlers = ( dataPriv.get( this, "events" ) || {} )[ event.type ] || [], + special = jQuery.event.special[ event.type ] || {}; + + // Use the fix-ed jQuery.Event rather than the (read-only) native event + args[ 0 ] = event; + + for ( i = 1; i < arguments.length; i++ ) { + args[ i ] = arguments[ i ]; + } + + event.delegateTarget = this; + + // Call the preDispatch hook for the mapped type, and let it bail if desired + if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) { + return; + } + + // Determine handlers + handlerQueue = jQuery.event.handlers.call( this, event, handlers ); + + // Run delegates first; they may want to stop propagation beneath us + i = 0; + while ( ( matched = handlerQueue[ i++ ] ) && !event.isPropagationStopped() ) { + event.currentTarget = matched.elem; + + j = 0; + while ( ( handleObj = matched.handlers[ j++ ] ) && + !event.isImmediatePropagationStopped() ) { + + // If the event is namespaced, then each handler is only invoked if it is + // specially universal or its namespaces are a superset of the event's. + if ( !event.rnamespace || handleObj.namespace === false || + event.rnamespace.test( handleObj.namespace ) ) { + + event.handleObj = handleObj; + event.data = handleObj.data; + + ret = ( ( jQuery.event.special[ handleObj.origType ] || {} ).handle || + handleObj.handler ).apply( matched.elem, args ); + + if ( ret !== undefined ) { + if ( ( event.result = ret ) === false ) { + event.preventDefault(); + event.stopPropagation(); + } + } + } + } + } + + // Call the postDispatch hook for the mapped type + if ( special.postDispatch ) { + special.postDispatch.call( this, event ); + } + + return event.result; + }, + + handlers: function( event, handlers ) { + var i, handleObj, sel, matchedHandlers, matchedSelectors, + handlerQueue = [], + delegateCount = handlers.delegateCount, + cur = event.target; + + // Find delegate handlers + if ( delegateCount && + + // Support: IE <=9 + // Black-hole SVG instance trees (trac-13180) + cur.nodeType && + + // Support: Firefox <=42 + // Suppress spec-violating clicks indicating a non-primary pointer button (trac-3861) + // https://www.w3.org/TR/DOM-Level-3-Events/#event-type-click + // Support: IE 11 only + // ...but not arrow key "clicks" of radio inputs, which can have `button` -1 (gh-2343) + !( event.type === "click" && event.button >= 1 ) ) { + + for ( ; cur !== this; cur = cur.parentNode || this ) { + + // Don't check non-elements (#13208) + // Don't process clicks on disabled elements (#6911, #8165, #11382, #11764) + if ( cur.nodeType === 1 && !( event.type === "click" && cur.disabled === true ) ) { + matchedHandlers = []; + matchedSelectors = {}; + for ( i = 0; i < delegateCount; i++ ) { + handleObj = handlers[ i ]; + + // Don't conflict with Object.prototype properties (#13203) + sel = handleObj.selector + " "; + + if ( matchedSelectors[ sel ] === undefined ) { + matchedSelectors[ sel ] = handleObj.needsContext ? + jQuery( sel, this ).index( cur ) > -1 : + jQuery.find( sel, this, null, [ cur ] ).length; + } + if ( matchedSelectors[ sel ] ) { + matchedHandlers.push( handleObj ); + } + } + if ( matchedHandlers.length ) { + handlerQueue.push( { elem: cur, handlers: matchedHandlers } ); + } + } + } + } + + // Add the remaining (directly-bound) handlers + cur = this; + if ( delegateCount < handlers.length ) { + handlerQueue.push( { elem: cur, handlers: handlers.slice( delegateCount ) } ); + } + + return handlerQueue; + }, + + addProp: function( name, hook ) { + Object.defineProperty( jQuery.Event.prototype, name, { + enumerable: true, + configurable: true, + + get: isFunction( hook ) ? + function() { + if ( this.originalEvent ) { + return hook( this.originalEvent ); + } + } : + function() { + if ( this.originalEvent ) { + return this.originalEvent[ name ]; + } + }, + + set: function( value ) { + Object.defineProperty( this, name, { + enumerable: true, + configurable: true, + writable: true, + value: value + } ); + } + } ); + }, + + fix: function( originalEvent ) { + return originalEvent[ jQuery.expando ] ? + originalEvent : + new jQuery.Event( originalEvent ); + }, + + special: { + load: { + + // Prevent triggered image.load events from bubbling to window.load + noBubble: true + }, + click: { + + // Utilize native event to ensure correct state for checkable inputs + setup: function( data ) { + + // For mutual compressibility with _default, replace `this` access with a local var. + // `|| data` is dead code meant only to preserve the variable through minification. + var el = this || data; + + // Claim the first handler + if ( rcheckableType.test( el.type ) && + el.click && nodeName( el, "input" ) ) { + + // dataPriv.set( el, "click", ... ) + leverageNative( el, "click", returnTrue ); + } + + // Return false to allow normal processing in the caller + return false; + }, + trigger: function( data ) { + + // For mutual compressibility with _default, replace `this` access with a local var. + // `|| data` is dead code meant only to preserve the variable through minification. + var el = this || data; + + // Force setup before triggering a click + if ( rcheckableType.test( el.type ) && + el.click && nodeName( el, "input" ) ) { + + leverageNative( el, "click" ); + } + + // Return non-false to allow normal event-path propagation + return true; + }, + + // For cross-browser consistency, suppress native .click() on links + // Also prevent it if we're currently inside a leveraged native-event stack + _default: function( event ) { + var target = event.target; + return rcheckableType.test( target.type ) && + target.click && nodeName( target, "input" ) && + dataPriv.get( target, "click" ) || + nodeName( target, "a" ); + } + }, + + beforeunload: { + postDispatch: function( event ) { + + // Support: Firefox 20+ + // Firefox doesn't alert if the returnValue field is not set. + if ( event.result !== undefined && event.originalEvent ) { + event.originalEvent.returnValue = event.result; + } + } + } + } +}; + +// Ensure the presence of an event listener that handles manually-triggered +// synthetic events by interrupting progress until reinvoked in response to +// *native* events that it fires directly, ensuring that state changes have +// already occurred before other listeners are invoked. +function leverageNative( el, type, expectSync ) { + + // Missing expectSync indicates a trigger call, which must force setup through jQuery.event.add + if ( !expectSync ) { + if ( dataPriv.get( el, type ) === undefined ) { + jQuery.event.add( el, type, returnTrue ); + } + return; + } + + // Register the controller as a special universal handler for all event namespaces + dataPriv.set( el, type, false ); + jQuery.event.add( el, type, { + namespace: false, + handler: function( event ) { + var notAsync, result, + saved = dataPriv.get( this, type ); + + if ( ( event.isTrigger & 1 ) && this[ type ] ) { + + // Interrupt processing of the outer synthetic .trigger()ed event + // Saved data should be false in such cases, but might be a leftover capture object + // from an async native handler (gh-4350) + if ( !saved.length ) { + + // Store arguments for use when handling the inner native event + // There will always be at least one argument (an event object), so this array + // will not be confused with a leftover capture object. + saved = slice.call( arguments ); + dataPriv.set( this, type, saved ); + + // Trigger the native event and capture its result + // Support: IE <=9 - 11+ + // focus() and blur() are asynchronous + notAsync = expectSync( this, type ); + this[ type ](); + result = dataPriv.get( this, type ); + if ( saved !== result || notAsync ) { + dataPriv.set( this, type, false ); + } else { + result = {}; + } + if ( saved !== result ) { + + // Cancel the outer synthetic event + event.stopImmediatePropagation(); + event.preventDefault(); + return result.value; + } + + // If this is an inner synthetic event for an event with a bubbling surrogate + // (focus or blur), assume that the surrogate already propagated from triggering the + // native event and prevent that from happening again here. + // This technically gets the ordering wrong w.r.t. to `.trigger()` (in which the + // bubbling surrogate propagates *after* the non-bubbling base), but that seems + // less bad than duplication. + } else if ( ( jQuery.event.special[ type ] || {} ).delegateType ) { + event.stopPropagation(); + } + + // If this is a native event triggered above, everything is now in order + // Fire an inner synthetic event with the original arguments + } else if ( saved.length ) { + + // ...and capture the result + dataPriv.set( this, type, { + value: jQuery.event.trigger( + + // Support: IE <=9 - 11+ + // Extend with the prototype to reset the above stopImmediatePropagation() + jQuery.extend( saved[ 0 ], jQuery.Event.prototype ), + saved.slice( 1 ), + this + ) + } ); + + // Abort handling of the native event + event.stopImmediatePropagation(); + } + } + } ); +} + +jQuery.removeEvent = function( elem, type, handle ) { + + // This "if" is needed for plain objects + if ( elem.removeEventListener ) { + elem.removeEventListener( type, handle ); + } +}; + +jQuery.Event = function( src, props ) { + + // Allow instantiation without the 'new' keyword + if ( !( this instanceof jQuery.Event ) ) { + return new jQuery.Event( src, props ); + } + + // Event object + if ( src && src.type ) { + this.originalEvent = src; + this.type = src.type; + + // Events bubbling up the document may have been marked as prevented + // by a handler lower down the tree; reflect the correct value. + this.isDefaultPrevented = src.defaultPrevented || + src.defaultPrevented === undefined && + + // Support: Android <=2.3 only + src.returnValue === false ? + returnTrue : + returnFalse; + + // Create target properties + // Support: Safari <=6 - 7 only + // Target should not be a text node (#504, #13143) + this.target = ( src.target && src.target.nodeType === 3 ) ? + src.target.parentNode : + src.target; + + this.currentTarget = src.currentTarget; + this.relatedTarget = src.relatedTarget; + + // Event type + } else { + this.type = src; + } + + // Put explicitly provided properties onto the event object + if ( props ) { + jQuery.extend( this, props ); + } + + // Create a timestamp if incoming event doesn't have one + this.timeStamp = src && src.timeStamp || Date.now(); + + // Mark it as fixed + this[ jQuery.expando ] = true; +}; + +// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding +// https://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html +jQuery.Event.prototype = { + constructor: jQuery.Event, + isDefaultPrevented: returnFalse, + isPropagationStopped: returnFalse, + isImmediatePropagationStopped: returnFalse, + isSimulated: false, + + preventDefault: function() { + var e = this.originalEvent; + + this.isDefaultPrevented = returnTrue; + + if ( e && !this.isSimulated ) { + e.preventDefault(); + } + }, + stopPropagation: function() { + var e = this.originalEvent; + + this.isPropagationStopped = returnTrue; + + if ( e && !this.isSimulated ) { + e.stopPropagation(); + } + }, + stopImmediatePropagation: function() { + var e = this.originalEvent; + + this.isImmediatePropagationStopped = returnTrue; + + if ( e && !this.isSimulated ) { + e.stopImmediatePropagation(); + } + + this.stopPropagation(); + } +}; + +// Includes all common event props including KeyEvent and MouseEvent specific props +jQuery.each( { + altKey: true, + bubbles: true, + cancelable: true, + changedTouches: true, + ctrlKey: true, + detail: true, + eventPhase: true, + metaKey: true, + pageX: true, + pageY: true, + shiftKey: true, + view: true, + "char": true, + code: true, + charCode: true, + key: true, + keyCode: true, + button: true, + buttons: true, + clientX: true, + clientY: true, + offsetX: true, + offsetY: true, + pointerId: true, + pointerType: true, + screenX: true, + screenY: true, + targetTouches: true, + toElement: true, + touches: true, + + which: function( event ) { + var button = event.button; + + // Add which for key events + if ( event.which == null && rkeyEvent.test( event.type ) ) { + return event.charCode != null ? event.charCode : event.keyCode; + } + + // Add which for click: 1 === left; 2 === middle; 3 === right + if ( !event.which && button !== undefined && rmouseEvent.test( event.type ) ) { + if ( button & 1 ) { + return 1; + } + + if ( button & 2 ) { + return 3; + } + + if ( button & 4 ) { + return 2; + } + + return 0; + } + + return event.which; + } +}, jQuery.event.addProp ); + +jQuery.each( { focus: "focusin", blur: "focusout" }, function( type, delegateType ) { + jQuery.event.special[ type ] = { + + // Utilize native event if possible so blur/focus sequence is correct + setup: function() { + + // Claim the first handler + // dataPriv.set( this, "focus", ... ) + // dataPriv.set( this, "blur", ... ) + leverageNative( this, type, expectSync ); + + // Return false to allow normal processing in the caller + return false; + }, + trigger: function() { + + // Force setup before trigger + leverageNative( this, type ); + + // Return non-false to allow normal event-path propagation + return true; + }, + + delegateType: delegateType + }; +} ); + +// Create mouseenter/leave events using mouseover/out and event-time checks +// so that event delegation works in jQuery. +// Do the same for pointerenter/pointerleave and pointerover/pointerout +// +// Support: Safari 7 only +// Safari sends mouseenter too often; see: +// https://bugs.chromium.org/p/chromium/issues/detail?id=470258 +// for the description of the bug (it existed in older Chrome versions as well). +jQuery.each( { + mouseenter: "mouseover", + mouseleave: "mouseout", + pointerenter: "pointerover", + pointerleave: "pointerout" +}, function( orig, fix ) { + jQuery.event.special[ orig ] = { + delegateType: fix, + bindType: fix, + + handle: function( event ) { + var ret, + target = this, + related = event.relatedTarget, + handleObj = event.handleObj; + + // For mouseenter/leave call the handler if related is outside the target. + // NB: No relatedTarget if the mouse left/entered the browser window + if ( !related || ( related !== target && !jQuery.contains( target, related ) ) ) { + event.type = handleObj.origType; + ret = handleObj.handler.apply( this, arguments ); + event.type = fix; + } + return ret; + } + }; +} ); + +jQuery.fn.extend( { + + on: function( types, selector, data, fn ) { + return on( this, types, selector, data, fn ); + }, + one: function( types, selector, data, fn ) { + return on( this, types, selector, data, fn, 1 ); + }, + off: function( types, selector, fn ) { + var handleObj, type; + if ( types && types.preventDefault && types.handleObj ) { + + // ( event ) dispatched jQuery.Event + handleObj = types.handleObj; + jQuery( types.delegateTarget ).off( + handleObj.namespace ? + handleObj.origType + "." + handleObj.namespace : + handleObj.origType, + handleObj.selector, + handleObj.handler + ); + return this; + } + if ( typeof types === "object" ) { + + // ( types-object [, selector] ) + for ( type in types ) { + this.off( type, selector, types[ type ] ); + } + return this; + } + if ( selector === false || typeof selector === "function" ) { + + // ( types [, fn] ) + fn = selector; + selector = undefined; + } + if ( fn === false ) { + fn = returnFalse; + } + return this.each( function() { + jQuery.event.remove( this, types, fn, selector ); + } ); + } +} ); + + +var + + /* eslint-disable max-len */ + + // See https://github.com/eslint/eslint/issues/3229 + rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([a-z][^\/\0>\x20\t\r\n\f]*)[^>]*)\/>/gi, + + /* eslint-enable */ + + // Support: IE <=10 - 11, Edge 12 - 13 only + // In IE/Edge using regex groups here causes severe slowdowns. + // See https://connect.microsoft.com/IE/feedback/details/1736512/ + rnoInnerhtml = /\s*$/g; + +// Prefer a tbody over its parent table for containing new rows +function manipulationTarget( elem, content ) { + if ( nodeName( elem, "table" ) && + nodeName( content.nodeType !== 11 ? content : content.firstChild, "tr" ) ) { + + return jQuery( elem ).children( "tbody" )[ 0 ] || elem; + } + + return elem; +} + +// Replace/restore the type attribute of script elements for safe DOM manipulation +function disableScript( elem ) { + elem.type = ( elem.getAttribute( "type" ) !== null ) + "/" + elem.type; + return elem; +} +function restoreScript( elem ) { + if ( ( elem.type || "" ).slice( 0, 5 ) === "true/" ) { + elem.type = elem.type.slice( 5 ); + } else { + elem.removeAttribute( "type" ); + } + + return elem; +} + +function cloneCopyEvent( src, dest ) { + var i, l, type, pdataOld, pdataCur, udataOld, udataCur, events; + + if ( dest.nodeType !== 1 ) { + return; + } + + // 1. Copy private data: events, handlers, etc. + if ( dataPriv.hasData( src ) ) { + pdataOld = dataPriv.access( src ); + pdataCur = dataPriv.set( dest, pdataOld ); + events = pdataOld.events; + + if ( events ) { + delete pdataCur.handle; + pdataCur.events = {}; + + for ( type in events ) { + for ( i = 0, l = events[ type ].length; i < l; i++ ) { + jQuery.event.add( dest, type, events[ type ][ i ] ); + } + } + } + } + + // 2. Copy user data + if ( dataUser.hasData( src ) ) { + udataOld = dataUser.access( src ); + udataCur = jQuery.extend( {}, udataOld ); + + dataUser.set( dest, udataCur ); + } +} + +// Fix IE bugs, see support tests +function fixInput( src, dest ) { + var nodeName = dest.nodeName.toLowerCase(); + + // Fails to persist the checked state of a cloned checkbox or radio button. + if ( nodeName === "input" && rcheckableType.test( src.type ) ) { + dest.checked = src.checked; + + // Fails to return the selected option to the default selected state when cloning options + } else if ( nodeName === "input" || nodeName === "textarea" ) { + dest.defaultValue = src.defaultValue; + } +} + +function domManip( collection, args, callback, ignored ) { + + // Flatten any nested arrays + args = concat.apply( [], args ); + + var fragment, first, scripts, hasScripts, node, doc, + i = 0, + l = collection.length, + iNoClone = l - 1, + value = args[ 0 ], + valueIsFunction = isFunction( value ); + + // We can't cloneNode fragments that contain checked, in WebKit + if ( valueIsFunction || + ( l > 1 && typeof value === "string" && + !support.checkClone && rchecked.test( value ) ) ) { + return collection.each( function( index ) { + var self = collection.eq( index ); + if ( valueIsFunction ) { + args[ 0 ] = value.call( this, index, self.html() ); + } + domManip( self, args, callback, ignored ); + } ); + } + + if ( l ) { + fragment = buildFragment( args, collection[ 0 ].ownerDocument, false, collection, ignored ); + first = fragment.firstChild; + + if ( fragment.childNodes.length === 1 ) { + fragment = first; + } + + // Require either new content or an interest in ignored elements to invoke the callback + if ( first || ignored ) { + scripts = jQuery.map( getAll( fragment, "script" ), disableScript ); + hasScripts = scripts.length; + + // Use the original fragment for the last item + // instead of the first because it can end up + // being emptied incorrectly in certain situations (#8070). + for ( ; i < l; i++ ) { + node = fragment; + + if ( i !== iNoClone ) { + node = jQuery.clone( node, true, true ); + + // Keep references to cloned scripts for later restoration + if ( hasScripts ) { + + // Support: Android <=4.0 only, PhantomJS 1 only + // push.apply(_, arraylike) throws on ancient WebKit + jQuery.merge( scripts, getAll( node, "script" ) ); + } + } + + callback.call( collection[ i ], node, i ); + } + + if ( hasScripts ) { + doc = scripts[ scripts.length - 1 ].ownerDocument; + + // Reenable scripts + jQuery.map( scripts, restoreScript ); + + // Evaluate executable scripts on first document insertion + for ( i = 0; i < hasScripts; i++ ) { + node = scripts[ i ]; + if ( rscriptType.test( node.type || "" ) && + !dataPriv.access( node, "globalEval" ) && + jQuery.contains( doc, node ) ) { + + if ( node.src && ( node.type || "" ).toLowerCase() !== "module" ) { + + // Optional AJAX dependency, but won't run scripts if not present + if ( jQuery._evalUrl && !node.noModule ) { + jQuery._evalUrl( node.src, { + nonce: node.nonce || node.getAttribute( "nonce" ) + } ); + } + } else { + DOMEval( node.textContent.replace( rcleanScript, "" ), node, doc ); + } + } + } + } + } + } + + return collection; +} + +function remove( elem, selector, keepData ) { + var node, + nodes = selector ? jQuery.filter( selector, elem ) : elem, + i = 0; + + for ( ; ( node = nodes[ i ] ) != null; i++ ) { + if ( !keepData && node.nodeType === 1 ) { + jQuery.cleanData( getAll( node ) ); + } + + if ( node.parentNode ) { + if ( keepData && isAttached( node ) ) { + setGlobalEval( getAll( node, "script" ) ); + } + node.parentNode.removeChild( node ); + } + } + + return elem; +} + +jQuery.extend( { + htmlPrefilter: function( html ) { + return html.replace( rxhtmlTag, "<$1>" ); + }, + + clone: function( elem, dataAndEvents, deepDataAndEvents ) { + var i, l, srcElements, destElements, + clone = elem.cloneNode( true ), + inPage = isAttached( elem ); + + // Fix IE cloning issues + if ( !support.noCloneChecked && ( elem.nodeType === 1 || elem.nodeType === 11 ) && + !jQuery.isXMLDoc( elem ) ) { + + // We eschew Sizzle here for performance reasons: https://jsperf.com/getall-vs-sizzle/2 + destElements = getAll( clone ); + srcElements = getAll( elem ); + + for ( i = 0, l = srcElements.length; i < l; i++ ) { + fixInput( srcElements[ i ], destElements[ i ] ); + } + } + + // Copy the events from the original to the clone + if ( dataAndEvents ) { + if ( deepDataAndEvents ) { + srcElements = srcElements || getAll( elem ); + destElements = destElements || getAll( clone ); + + for ( i = 0, l = srcElements.length; i < l; i++ ) { + cloneCopyEvent( srcElements[ i ], destElements[ i ] ); + } + } else { + cloneCopyEvent( elem, clone ); + } + } + + // Preserve script evaluation history + destElements = getAll( clone, "script" ); + if ( destElements.length > 0 ) { + setGlobalEval( destElements, !inPage && getAll( elem, "script" ) ); + } + + // Return the cloned set + return clone; + }, + + cleanData: function( elems ) { + var data, elem, type, + special = jQuery.event.special, + i = 0; + + for ( ; ( elem = elems[ i ] ) !== undefined; i++ ) { + if ( acceptData( elem ) ) { + if ( ( data = elem[ dataPriv.expando ] ) ) { + if ( data.events ) { + for ( type in data.events ) { + if ( special[ type ] ) { + jQuery.event.remove( elem, type ); + + // This is a shortcut to avoid jQuery.event.remove's overhead + } else { + jQuery.removeEvent( elem, type, data.handle ); + } + } + } + + // Support: Chrome <=35 - 45+ + // Assign undefined instead of using delete, see Data#remove + elem[ dataPriv.expando ] = undefined; + } + if ( elem[ dataUser.expando ] ) { + + // Support: Chrome <=35 - 45+ + // Assign undefined instead of using delete, see Data#remove + elem[ dataUser.expando ] = undefined; + } + } + } + } +} ); + +jQuery.fn.extend( { + detach: function( selector ) { + return remove( this, selector, true ); + }, + + remove: function( selector ) { + return remove( this, selector ); + }, + + text: function( value ) { + return access( this, function( value ) { + return value === undefined ? + jQuery.text( this ) : + this.empty().each( function() { + if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { + this.textContent = value; + } + } ); + }, null, value, arguments.length ); + }, + + append: function() { + return domManip( this, arguments, function( elem ) { + if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { + var target = manipulationTarget( this, elem ); + target.appendChild( elem ); + } + } ); + }, + + prepend: function() { + return domManip( this, arguments, function( elem ) { + if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { + var target = manipulationTarget( this, elem ); + target.insertBefore( elem, target.firstChild ); + } + } ); + }, + + before: function() { + return domManip( this, arguments, function( elem ) { + if ( this.parentNode ) { + this.parentNode.insertBefore( elem, this ); + } + } ); + }, + + after: function() { + return domManip( this, arguments, function( elem ) { + if ( this.parentNode ) { + this.parentNode.insertBefore( elem, this.nextSibling ); + } + } ); + }, + + empty: function() { + var elem, + i = 0; + + for ( ; ( elem = this[ i ] ) != null; i++ ) { + if ( elem.nodeType === 1 ) { + + // Prevent memory leaks + jQuery.cleanData( getAll( elem, false ) ); + + // Remove any remaining nodes + elem.textContent = ""; + } + } + + return this; + }, + + clone: function( dataAndEvents, deepDataAndEvents ) { + dataAndEvents = dataAndEvents == null ? false : dataAndEvents; + deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents; + + return this.map( function() { + return jQuery.clone( this, dataAndEvents, deepDataAndEvents ); + } ); + }, + + html: function( value ) { + return access( this, function( value ) { + var elem = this[ 0 ] || {}, + i = 0, + l = this.length; + + if ( value === undefined && elem.nodeType === 1 ) { + return elem.innerHTML; + } + + // See if we can take a shortcut and just use innerHTML + if ( typeof value === "string" && !rnoInnerhtml.test( value ) && + !wrapMap[ ( rtagName.exec( value ) || [ "", "" ] )[ 1 ].toLowerCase() ] ) { + + value = jQuery.htmlPrefilter( value ); + + try { + for ( ; i < l; i++ ) { + elem = this[ i ] || {}; + + // Remove element nodes and prevent memory leaks + if ( elem.nodeType === 1 ) { + jQuery.cleanData( getAll( elem, false ) ); + elem.innerHTML = value; + } + } + + elem = 0; + + // If using innerHTML throws an exception, use the fallback method + } catch ( e ) {} + } + + if ( elem ) { + this.empty().append( value ); + } + }, null, value, arguments.length ); + }, + + replaceWith: function() { + var ignored = []; + + // Make the changes, replacing each non-ignored context element with the new content + return domManip( this, arguments, function( elem ) { + var parent = this.parentNode; + + if ( jQuery.inArray( this, ignored ) < 0 ) { + jQuery.cleanData( getAll( this ) ); + if ( parent ) { + parent.replaceChild( elem, this ); + } + } + + // Force callback invocation + }, ignored ); + } +} ); + +jQuery.each( { + appendTo: "append", + prependTo: "prepend", + insertBefore: "before", + insertAfter: "after", + replaceAll: "replaceWith" +}, function( name, original ) { + jQuery.fn[ name ] = function( selector ) { + var elems, + ret = [], + insert = jQuery( selector ), + last = insert.length - 1, + i = 0; + + for ( ; i <= last; i++ ) { + elems = i === last ? this : this.clone( true ); + jQuery( insert[ i ] )[ original ]( elems ); + + // Support: Android <=4.0 only, PhantomJS 1 only + // .get() because push.apply(_, arraylike) throws on ancient WebKit + push.apply( ret, elems.get() ); + } + + return this.pushStack( ret ); + }; +} ); +var rnumnonpx = new RegExp( "^(" + pnum + ")(?!px)[a-z%]+$", "i" ); + +var getStyles = function( elem ) { + + // Support: IE <=11 only, Firefox <=30 (#15098, #14150) + // IE throws on elements created in popups + // FF meanwhile throws on frame elements through "defaultView.getComputedStyle" + var view = elem.ownerDocument.defaultView; + + if ( !view || !view.opener ) { + view = window; + } + + return view.getComputedStyle( elem ); + }; + +var rboxStyle = new RegExp( cssExpand.join( "|" ), "i" ); + + + +( function() { + + // Executing both pixelPosition & boxSizingReliable tests require only one layout + // so they're executed at the same time to save the second computation. + function computeStyleTests() { + + // This is a singleton, we need to execute it only once + if ( !div ) { + return; + } + + container.style.cssText = "position:absolute;left:-11111px;width:60px;" + + "margin-top:1px;padding:0;border:0"; + div.style.cssText = + "position:relative;display:block;box-sizing:border-box;overflow:scroll;" + + "margin:auto;border:1px;padding:1px;" + + "width:60%;top:1%"; + documentElement.appendChild( container ).appendChild( div ); + + var divStyle = window.getComputedStyle( div ); + pixelPositionVal = divStyle.top !== "1%"; + + // Support: Android 4.0 - 4.3 only, Firefox <=3 - 44 + reliableMarginLeftVal = roundPixelMeasures( divStyle.marginLeft ) === 12; + + // Support: Android 4.0 - 4.3 only, Safari <=9.1 - 10.1, iOS <=7.0 - 9.3 + // Some styles come back with percentage values, even though they shouldn't + div.style.right = "60%"; + pixelBoxStylesVal = roundPixelMeasures( divStyle.right ) === 36; + + // Support: IE 9 - 11 only + // Detect misreporting of content dimensions for box-sizing:border-box elements + boxSizingReliableVal = roundPixelMeasures( divStyle.width ) === 36; + + // Support: IE 9 only + // Detect overflow:scroll screwiness (gh-3699) + // Support: Chrome <=64 + // Don't get tricked when zoom affects offsetWidth (gh-4029) + div.style.position = "absolute"; + scrollboxSizeVal = roundPixelMeasures( div.offsetWidth / 3 ) === 12; + + documentElement.removeChild( container ); + + // Nullify the div so it wouldn't be stored in the memory and + // it will also be a sign that checks already performed + div = null; + } + + function roundPixelMeasures( measure ) { + return Math.round( parseFloat( measure ) ); + } + + var pixelPositionVal, boxSizingReliableVal, scrollboxSizeVal, pixelBoxStylesVal, + reliableMarginLeftVal, + container = document.createElement( "div" ), + div = document.createElement( "div" ); + + // Finish early in limited (non-browser) environments + if ( !div.style ) { + return; + } + + // Support: IE <=9 - 11 only + // Style of cloned element affects source element cloned (#8908) + div.style.backgroundClip = "content-box"; + div.cloneNode( true ).style.backgroundClip = ""; + support.clearCloneStyle = div.style.backgroundClip === "content-box"; + + jQuery.extend( support, { + boxSizingReliable: function() { + computeStyleTests(); + return boxSizingReliableVal; + }, + pixelBoxStyles: function() { + computeStyleTests(); + return pixelBoxStylesVal; + }, + pixelPosition: function() { + computeStyleTests(); + return pixelPositionVal; + }, + reliableMarginLeft: function() { + computeStyleTests(); + return reliableMarginLeftVal; + }, + scrollboxSize: function() { + computeStyleTests(); + return scrollboxSizeVal; + } + } ); +} )(); + + +function curCSS( elem, name, computed ) { + var width, minWidth, maxWidth, ret, + + // Support: Firefox 51+ + // Retrieving style before computed somehow + // fixes an issue with getting wrong values + // on detached elements + style = elem.style; + + computed = computed || getStyles( elem ); + + // getPropertyValue is needed for: + // .css('filter') (IE 9 only, #12537) + // .css('--customProperty) (#3144) + if ( computed ) { + ret = computed.getPropertyValue( name ) || computed[ name ]; + + if ( ret === "" && !isAttached( elem ) ) { + ret = jQuery.style( elem, name ); + } + + // A tribute to the "awesome hack by Dean Edwards" + // Android Browser returns percentage for some values, + // but width seems to be reliably pixels. + // This is against the CSSOM draft spec: + // https://drafts.csswg.org/cssom/#resolved-values + if ( !support.pixelBoxStyles() && rnumnonpx.test( ret ) && rboxStyle.test( name ) ) { + + // Remember the original values + width = style.width; + minWidth = style.minWidth; + maxWidth = style.maxWidth; + + // Put in the new values to get a computed value out + style.minWidth = style.maxWidth = style.width = ret; + ret = computed.width; + + // Revert the changed values + style.width = width; + style.minWidth = minWidth; + style.maxWidth = maxWidth; + } + } + + return ret !== undefined ? + + // Support: IE <=9 - 11 only + // IE returns zIndex value as an integer. + ret + "" : + ret; +} + + +function addGetHookIf( conditionFn, hookFn ) { + + // Define the hook, we'll check on the first run if it's really needed. + return { + get: function() { + if ( conditionFn() ) { + + // Hook not needed (or it's not possible to use it due + // to missing dependency), remove it. + delete this.get; + return; + } + + // Hook needed; redefine it so that the support test is not executed again. + return ( this.get = hookFn ).apply( this, arguments ); + } + }; +} + + +var cssPrefixes = [ "Webkit", "Moz", "ms" ], + emptyStyle = document.createElement( "div" ).style, + vendorProps = {}; + +// Return a vendor-prefixed property or undefined +function vendorPropName( name ) { + + // Check for vendor prefixed names + var capName = name[ 0 ].toUpperCase() + name.slice( 1 ), + i = cssPrefixes.length; + + while ( i-- ) { + name = cssPrefixes[ i ] + capName; + if ( name in emptyStyle ) { + return name; + } + } +} + +// Return a potentially-mapped jQuery.cssProps or vendor prefixed property +function finalPropName( name ) { + var final = jQuery.cssProps[ name ] || vendorProps[ name ]; + + if ( final ) { + return final; + } + if ( name in emptyStyle ) { + return name; + } + return vendorProps[ name ] = vendorPropName( name ) || name; +} + + +var + + // Swappable if display is none or starts with table + // except "table", "table-cell", or "table-caption" + // See here for display values: https://developer.mozilla.org/en-US/docs/CSS/display + rdisplayswap = /^(none|table(?!-c[ea]).+)/, + rcustomProp = /^--/, + cssShow = { position: "absolute", visibility: "hidden", display: "block" }, + cssNormalTransform = { + letterSpacing: "0", + fontWeight: "400" + }; + +function setPositiveNumber( elem, value, subtract ) { + + // Any relative (+/-) values have already been + // normalized at this point + var matches = rcssNum.exec( value ); + return matches ? + + // Guard against undefined "subtract", e.g., when used as in cssHooks + Math.max( 0, matches[ 2 ] - ( subtract || 0 ) ) + ( matches[ 3 ] || "px" ) : + value; +} + +function boxModelAdjustment( elem, dimension, box, isBorderBox, styles, computedVal ) { + var i = dimension === "width" ? 1 : 0, + extra = 0, + delta = 0; + + // Adjustment may not be necessary + if ( box === ( isBorderBox ? "border" : "content" ) ) { + return 0; + } + + for ( ; i < 4; i += 2 ) { + + // Both box models exclude margin + if ( box === "margin" ) { + delta += jQuery.css( elem, box + cssExpand[ i ], true, styles ); + } + + // If we get here with a content-box, we're seeking "padding" or "border" or "margin" + if ( !isBorderBox ) { + + // Add padding + delta += jQuery.css( elem, "padding" + cssExpand[ i ], true, styles ); + + // For "border" or "margin", add border + if ( box !== "padding" ) { + delta += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); + + // But still keep track of it otherwise + } else { + extra += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); + } + + // If we get here with a border-box (content + padding + border), we're seeking "content" or + // "padding" or "margin" + } else { + + // For "content", subtract padding + if ( box === "content" ) { + delta -= jQuery.css( elem, "padding" + cssExpand[ i ], true, styles ); + } + + // For "content" or "padding", subtract border + if ( box !== "margin" ) { + delta -= jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); + } + } + } + + // Account for positive content-box scroll gutter when requested by providing computedVal + if ( !isBorderBox && computedVal >= 0 ) { + + // offsetWidth/offsetHeight is a rounded sum of content, padding, scroll gutter, and border + // Assuming integer scroll gutter, subtract the rest and round down + delta += Math.max( 0, Math.ceil( + elem[ "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ] - + computedVal - + delta - + extra - + 0.5 + + // If offsetWidth/offsetHeight is unknown, then we can't determine content-box scroll gutter + // Use an explicit zero to avoid NaN (gh-3964) + ) ) || 0; + } + + return delta; +} + +function getWidthOrHeight( elem, dimension, extra ) { + + // Start with computed style + var styles = getStyles( elem ), + + // To avoid forcing a reflow, only fetch boxSizing if we need it (gh-4322). + // Fake content-box until we know it's needed to know the true value. + boxSizingNeeded = !support.boxSizingReliable() || extra, + isBorderBox = boxSizingNeeded && + jQuery.css( elem, "boxSizing", false, styles ) === "border-box", + valueIsBorderBox = isBorderBox, + + val = curCSS( elem, dimension, styles ), + offsetProp = "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ); + + // Support: Firefox <=54 + // Return a confounding non-pixel value or feign ignorance, as appropriate. + if ( rnumnonpx.test( val ) ) { + if ( !extra ) { + return val; + } + val = "auto"; + } + + + // Fall back to offsetWidth/offsetHeight when value is "auto" + // This happens for inline elements with no explicit setting (gh-3571) + // Support: Android <=4.1 - 4.3 only + // Also use offsetWidth/offsetHeight for misreported inline dimensions (gh-3602) + // Support: IE 9-11 only + // Also use offsetWidth/offsetHeight for when box sizing is unreliable + // We use getClientRects() to check for hidden/disconnected. + // In those cases, the computed value can be trusted to be border-box + if ( ( !support.boxSizingReliable() && isBorderBox || + val === "auto" || + !parseFloat( val ) && jQuery.css( elem, "display", false, styles ) === "inline" ) && + elem.getClientRects().length ) { + + isBorderBox = jQuery.css( elem, "boxSizing", false, styles ) === "border-box"; + + // Where available, offsetWidth/offsetHeight approximate border box dimensions. + // Where not available (e.g., SVG), assume unreliable box-sizing and interpret the + // retrieved value as a content box dimension. + valueIsBorderBox = offsetProp in elem; + if ( valueIsBorderBox ) { + val = elem[ offsetProp ]; + } + } + + // Normalize "" and auto + val = parseFloat( val ) || 0; + + // Adjust for the element's box model + return ( val + + boxModelAdjustment( + elem, + dimension, + extra || ( isBorderBox ? "border" : "content" ), + valueIsBorderBox, + styles, + + // Provide the current computed size to request scroll gutter calculation (gh-3589) + val + ) + ) + "px"; +} + +jQuery.extend( { + + // Add in style property hooks for overriding the default + // behavior of getting and setting a style property + cssHooks: { + opacity: { + get: function( elem, computed ) { + if ( computed ) { + + // We should always get a number back from opacity + var ret = curCSS( elem, "opacity" ); + return ret === "" ? "1" : ret; + } + } + } + }, + + // Don't automatically add "px" to these possibly-unitless properties + cssNumber: { + "animationIterationCount": true, + "columnCount": true, + "fillOpacity": true, + "flexGrow": true, + "flexShrink": true, + "fontWeight": true, + "gridArea": true, + "gridColumn": true, + "gridColumnEnd": true, + "gridColumnStart": true, + "gridRow": true, + "gridRowEnd": true, + "gridRowStart": true, + "lineHeight": true, + "opacity": true, + "order": true, + "orphans": true, + "widows": true, + "zIndex": true, + "zoom": true + }, + + // Add in properties whose names you wish to fix before + // setting or getting the value + cssProps: {}, + + // Get and set the style property on a DOM Node + style: function( elem, name, value, extra ) { + + // Don't set styles on text and comment nodes + if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) { + return; + } + + // Make sure that we're working with the right name + var ret, type, hooks, + origName = camelCase( name ), + isCustomProp = rcustomProp.test( name ), + style = elem.style; + + // Make sure that we're working with the right name. We don't + // want to query the value if it is a CSS custom property + // since they are user-defined. + if ( !isCustomProp ) { + name = finalPropName( origName ); + } + + // Gets hook for the prefixed version, then unprefixed version + hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; + + // Check if we're setting a value + if ( value !== undefined ) { + type = typeof value; + + // Convert "+=" or "-=" to relative numbers (#7345) + if ( type === "string" && ( ret = rcssNum.exec( value ) ) && ret[ 1 ] ) { + value = adjustCSS( elem, name, ret ); + + // Fixes bug #9237 + type = "number"; + } + + // Make sure that null and NaN values aren't set (#7116) + if ( value == null || value !== value ) { + return; + } + + // If a number was passed in, add the unit (except for certain CSS properties) + // The isCustomProp check can be removed in jQuery 4.0 when we only auto-append + // "px" to a few hardcoded values. + if ( type === "number" && !isCustomProp ) { + value += ret && ret[ 3 ] || ( jQuery.cssNumber[ origName ] ? "" : "px" ); + } + + // background-* props affect original clone's values + if ( !support.clearCloneStyle && value === "" && name.indexOf( "background" ) === 0 ) { + style[ name ] = "inherit"; + } + + // If a hook was provided, use that value, otherwise just set the specified value + if ( !hooks || !( "set" in hooks ) || + ( value = hooks.set( elem, value, extra ) ) !== undefined ) { + + if ( isCustomProp ) { + style.setProperty( name, value ); + } else { + style[ name ] = value; + } + } + + } else { + + // If a hook was provided get the non-computed value from there + if ( hooks && "get" in hooks && + ( ret = hooks.get( elem, false, extra ) ) !== undefined ) { + + return ret; + } + + // Otherwise just get the value from the style object + return style[ name ]; + } + }, + + css: function( elem, name, extra, styles ) { + var val, num, hooks, + origName = camelCase( name ), + isCustomProp = rcustomProp.test( name ); + + // Make sure that we're working with the right name. We don't + // want to modify the value if it is a CSS custom property + // since they are user-defined. + if ( !isCustomProp ) { + name = finalPropName( origName ); + } + + // Try prefixed name followed by the unprefixed name + hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; + + // If a hook was provided get the computed value from there + if ( hooks && "get" in hooks ) { + val = hooks.get( elem, true, extra ); + } + + // Otherwise, if a way to get the computed value exists, use that + if ( val === undefined ) { + val = curCSS( elem, name, styles ); + } + + // Convert "normal" to computed value + if ( val === "normal" && name in cssNormalTransform ) { + val = cssNormalTransform[ name ]; + } + + // Make numeric if forced or a qualifier was provided and val looks numeric + if ( extra === "" || extra ) { + num = parseFloat( val ); + return extra === true || isFinite( num ) ? num || 0 : val; + } + + return val; + } +} ); + +jQuery.each( [ "height", "width" ], function( i, dimension ) { + jQuery.cssHooks[ dimension ] = { + get: function( elem, computed, extra ) { + if ( computed ) { + + // Certain elements can have dimension info if we invisibly show them + // but it must have a current display style that would benefit + return rdisplayswap.test( jQuery.css( elem, "display" ) ) && + + // Support: Safari 8+ + // Table columns in Safari have non-zero offsetWidth & zero + // getBoundingClientRect().width unless display is changed. + // Support: IE <=11 only + // Running getBoundingClientRect on a disconnected node + // in IE throws an error. + ( !elem.getClientRects().length || !elem.getBoundingClientRect().width ) ? + swap( elem, cssShow, function() { + return getWidthOrHeight( elem, dimension, extra ); + } ) : + getWidthOrHeight( elem, dimension, extra ); + } + }, + + set: function( elem, value, extra ) { + var matches, + styles = getStyles( elem ), + + // Only read styles.position if the test has a chance to fail + // to avoid forcing a reflow. + scrollboxSizeBuggy = !support.scrollboxSize() && + styles.position === "absolute", + + // To avoid forcing a reflow, only fetch boxSizing if we need it (gh-3991) + boxSizingNeeded = scrollboxSizeBuggy || extra, + isBorderBox = boxSizingNeeded && + jQuery.css( elem, "boxSizing", false, styles ) === "border-box", + subtract = extra ? + boxModelAdjustment( + elem, + dimension, + extra, + isBorderBox, + styles + ) : + 0; + + // Account for unreliable border-box dimensions by comparing offset* to computed and + // faking a content-box to get border and padding (gh-3699) + if ( isBorderBox && scrollboxSizeBuggy ) { + subtract -= Math.ceil( + elem[ "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ] - + parseFloat( styles[ dimension ] ) - + boxModelAdjustment( elem, dimension, "border", false, styles ) - + 0.5 + ); + } + + // Convert to pixels if value adjustment is needed + if ( subtract && ( matches = rcssNum.exec( value ) ) && + ( matches[ 3 ] || "px" ) !== "px" ) { + + elem.style[ dimension ] = value; + value = jQuery.css( elem, dimension ); + } + + return setPositiveNumber( elem, value, subtract ); + } + }; +} ); + +jQuery.cssHooks.marginLeft = addGetHookIf( support.reliableMarginLeft, + function( elem, computed ) { + if ( computed ) { + return ( parseFloat( curCSS( elem, "marginLeft" ) ) || + elem.getBoundingClientRect().left - + swap( elem, { marginLeft: 0 }, function() { + return elem.getBoundingClientRect().left; + } ) + ) + "px"; + } + } +); + +// These hooks are used by animate to expand properties +jQuery.each( { + margin: "", + padding: "", + border: "Width" +}, function( prefix, suffix ) { + jQuery.cssHooks[ prefix + suffix ] = { + expand: function( value ) { + var i = 0, + expanded = {}, + + // Assumes a single number if not a string + parts = typeof value === "string" ? value.split( " " ) : [ value ]; + + for ( ; i < 4; i++ ) { + expanded[ prefix + cssExpand[ i ] + suffix ] = + parts[ i ] || parts[ i - 2 ] || parts[ 0 ]; + } + + return expanded; + } + }; + + if ( prefix !== "margin" ) { + jQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber; + } +} ); + +jQuery.fn.extend( { + css: function( name, value ) { + return access( this, function( elem, name, value ) { + var styles, len, + map = {}, + i = 0; + + if ( Array.isArray( name ) ) { + styles = getStyles( elem ); + len = name.length; + + for ( ; i < len; i++ ) { + map[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles ); + } + + return map; + } + + return value !== undefined ? + jQuery.style( elem, name, value ) : + jQuery.css( elem, name ); + }, name, value, arguments.length > 1 ); + } +} ); + + +function Tween( elem, options, prop, end, easing ) { + return new Tween.prototype.init( elem, options, prop, end, easing ); +} +jQuery.Tween = Tween; + +Tween.prototype = { + constructor: Tween, + init: function( elem, options, prop, end, easing, unit ) { + this.elem = elem; + this.prop = prop; + this.easing = easing || jQuery.easing._default; + this.options = options; + this.start = this.now = this.cur(); + this.end = end; + this.unit = unit || ( jQuery.cssNumber[ prop ] ? "" : "px" ); + }, + cur: function() { + var hooks = Tween.propHooks[ this.prop ]; + + return hooks && hooks.get ? + hooks.get( this ) : + Tween.propHooks._default.get( this ); + }, + run: function( percent ) { + var eased, + hooks = Tween.propHooks[ this.prop ]; + + if ( this.options.duration ) { + this.pos = eased = jQuery.easing[ this.easing ]( + percent, this.options.duration * percent, 0, 1, this.options.duration + ); + } else { + this.pos = eased = percent; + } + this.now = ( this.end - this.start ) * eased + this.start; + + if ( this.options.step ) { + this.options.step.call( this.elem, this.now, this ); + } + + if ( hooks && hooks.set ) { + hooks.set( this ); + } else { + Tween.propHooks._default.set( this ); + } + return this; + } +}; + +Tween.prototype.init.prototype = Tween.prototype; + +Tween.propHooks = { + _default: { + get: function( tween ) { + var result; + + // Use a property on the element directly when it is not a DOM element, + // or when there is no matching style property that exists. + if ( tween.elem.nodeType !== 1 || + tween.elem[ tween.prop ] != null && tween.elem.style[ tween.prop ] == null ) { + return tween.elem[ tween.prop ]; + } + + // Passing an empty string as a 3rd parameter to .css will automatically + // attempt a parseFloat and fallback to a string if the parse fails. + // Simple values such as "10px" are parsed to Float; + // complex values such as "rotate(1rad)" are returned as-is. + result = jQuery.css( tween.elem, tween.prop, "" ); + + // Empty strings, null, undefined and "auto" are converted to 0. + return !result || result === "auto" ? 0 : result; + }, + set: function( tween ) { + + // Use step hook for back compat. + // Use cssHook if its there. + // Use .style if available and use plain properties where available. + if ( jQuery.fx.step[ tween.prop ] ) { + jQuery.fx.step[ tween.prop ]( tween ); + } else if ( tween.elem.nodeType === 1 && ( + jQuery.cssHooks[ tween.prop ] || + tween.elem.style[ finalPropName( tween.prop ) ] != null ) ) { + jQuery.style( tween.elem, tween.prop, tween.now + tween.unit ); + } else { + tween.elem[ tween.prop ] = tween.now; + } + } + } +}; + +// Support: IE <=9 only +// Panic based approach to setting things on disconnected nodes +Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = { + set: function( tween ) { + if ( tween.elem.nodeType && tween.elem.parentNode ) { + tween.elem[ tween.prop ] = tween.now; + } + } +}; + +jQuery.easing = { + linear: function( p ) { + return p; + }, + swing: function( p ) { + return 0.5 - Math.cos( p * Math.PI ) / 2; + }, + _default: "swing" +}; + +jQuery.fx = Tween.prototype.init; + +// Back compat <1.8 extension point +jQuery.fx.step = {}; + + + + +var + fxNow, inProgress, + rfxtypes = /^(?:toggle|show|hide)$/, + rrun = /queueHooks$/; + +function schedule() { + if ( inProgress ) { + if ( document.hidden === false && window.requestAnimationFrame ) { + window.requestAnimationFrame( schedule ); + } else { + window.setTimeout( schedule, jQuery.fx.interval ); + } + + jQuery.fx.tick(); + } +} + +// Animations created synchronously will run synchronously +function createFxNow() { + window.setTimeout( function() { + fxNow = undefined; + } ); + return ( fxNow = Date.now() ); +} + +// Generate parameters to create a standard animation +function genFx( type, includeWidth ) { + var which, + i = 0, + attrs = { height: type }; + + // If we include width, step value is 1 to do all cssExpand values, + // otherwise step value is 2 to skip over Left and Right + includeWidth = includeWidth ? 1 : 0; + for ( ; i < 4; i += 2 - includeWidth ) { + which = cssExpand[ i ]; + attrs[ "margin" + which ] = attrs[ "padding" + which ] = type; + } + + if ( includeWidth ) { + attrs.opacity = attrs.width = type; + } + + return attrs; +} + +function createTween( value, prop, animation ) { + var tween, + collection = ( Animation.tweeners[ prop ] || [] ).concat( Animation.tweeners[ "*" ] ), + index = 0, + length = collection.length; + for ( ; index < length; index++ ) { + if ( ( tween = collection[ index ].call( animation, prop, value ) ) ) { + + // We're done with this property + return tween; + } + } +} + +function defaultPrefilter( elem, props, opts ) { + var prop, value, toggle, hooks, oldfire, propTween, restoreDisplay, display, + isBox = "width" in props || "height" in props, + anim = this, + orig = {}, + style = elem.style, + hidden = elem.nodeType && isHiddenWithinTree( elem ), + dataShow = dataPriv.get( elem, "fxshow" ); + + // Queue-skipping animations hijack the fx hooks + if ( !opts.queue ) { + hooks = jQuery._queueHooks( elem, "fx" ); + if ( hooks.unqueued == null ) { + hooks.unqueued = 0; + oldfire = hooks.empty.fire; + hooks.empty.fire = function() { + if ( !hooks.unqueued ) { + oldfire(); + } + }; + } + hooks.unqueued++; + + anim.always( function() { + + // Ensure the complete handler is called before this completes + anim.always( function() { + hooks.unqueued--; + if ( !jQuery.queue( elem, "fx" ).length ) { + hooks.empty.fire(); + } + } ); + } ); + } + + // Detect show/hide animations + for ( prop in props ) { + value = props[ prop ]; + if ( rfxtypes.test( value ) ) { + delete props[ prop ]; + toggle = toggle || value === "toggle"; + if ( value === ( hidden ? "hide" : "show" ) ) { + + // Pretend to be hidden if this is a "show" and + // there is still data from a stopped show/hide + if ( value === "show" && dataShow && dataShow[ prop ] !== undefined ) { + hidden = true; + + // Ignore all other no-op show/hide data + } else { + continue; + } + } + orig[ prop ] = dataShow && dataShow[ prop ] || jQuery.style( elem, prop ); + } + } + + // Bail out if this is a no-op like .hide().hide() + propTween = !jQuery.isEmptyObject( props ); + if ( !propTween && jQuery.isEmptyObject( orig ) ) { + return; + } + + // Restrict "overflow" and "display" styles during box animations + if ( isBox && elem.nodeType === 1 ) { + + // Support: IE <=9 - 11, Edge 12 - 15 + // Record all 3 overflow attributes because IE does not infer the shorthand + // from identically-valued overflowX and overflowY and Edge just mirrors + // the overflowX value there. + opts.overflow = [ style.overflow, style.overflowX, style.overflowY ]; + + // Identify a display type, preferring old show/hide data over the CSS cascade + restoreDisplay = dataShow && dataShow.display; + if ( restoreDisplay == null ) { + restoreDisplay = dataPriv.get( elem, "display" ); + } + display = jQuery.css( elem, "display" ); + if ( display === "none" ) { + if ( restoreDisplay ) { + display = restoreDisplay; + } else { + + // Get nonempty value(s) by temporarily forcing visibility + showHide( [ elem ], true ); + restoreDisplay = elem.style.display || restoreDisplay; + display = jQuery.css( elem, "display" ); + showHide( [ elem ] ); + } + } + + // Animate inline elements as inline-block + if ( display === "inline" || display === "inline-block" && restoreDisplay != null ) { + if ( jQuery.css( elem, "float" ) === "none" ) { + + // Restore the original display value at the end of pure show/hide animations + if ( !propTween ) { + anim.done( function() { + style.display = restoreDisplay; + } ); + if ( restoreDisplay == null ) { + display = style.display; + restoreDisplay = display === "none" ? "" : display; + } + } + style.display = "inline-block"; + } + } + } + + if ( opts.overflow ) { + style.overflow = "hidden"; + anim.always( function() { + style.overflow = opts.overflow[ 0 ]; + style.overflowX = opts.overflow[ 1 ]; + style.overflowY = opts.overflow[ 2 ]; + } ); + } + + // Implement show/hide animations + propTween = false; + for ( prop in orig ) { + + // General show/hide setup for this element animation + if ( !propTween ) { + if ( dataShow ) { + if ( "hidden" in dataShow ) { + hidden = dataShow.hidden; + } + } else { + dataShow = dataPriv.access( elem, "fxshow", { display: restoreDisplay } ); + } + + // Store hidden/visible for toggle so `.stop().toggle()` "reverses" + if ( toggle ) { + dataShow.hidden = !hidden; + } + + // Show elements before animating them + if ( hidden ) { + showHide( [ elem ], true ); + } + + /* eslint-disable no-loop-func */ + + anim.done( function() { + + /* eslint-enable no-loop-func */ + + // The final step of a "hide" animation is actually hiding the element + if ( !hidden ) { + showHide( [ elem ] ); + } + dataPriv.remove( elem, "fxshow" ); + for ( prop in orig ) { + jQuery.style( elem, prop, orig[ prop ] ); + } + } ); + } + + // Per-property setup + propTween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim ); + if ( !( prop in dataShow ) ) { + dataShow[ prop ] = propTween.start; + if ( hidden ) { + propTween.end = propTween.start; + propTween.start = 0; + } + } + } +} + +function propFilter( props, specialEasing ) { + var index, name, easing, value, hooks; + + // camelCase, specialEasing and expand cssHook pass + for ( index in props ) { + name = camelCase( index ); + easing = specialEasing[ name ]; + value = props[ index ]; + if ( Array.isArray( value ) ) { + easing = value[ 1 ]; + value = props[ index ] = value[ 0 ]; + } + + if ( index !== name ) { + props[ name ] = value; + delete props[ index ]; + } + + hooks = jQuery.cssHooks[ name ]; + if ( hooks && "expand" in hooks ) { + value = hooks.expand( value ); + delete props[ name ]; + + // Not quite $.extend, this won't overwrite existing keys. + // Reusing 'index' because we have the correct "name" + for ( index in value ) { + if ( !( index in props ) ) { + props[ index ] = value[ index ]; + specialEasing[ index ] = easing; + } + } + } else { + specialEasing[ name ] = easing; + } + } +} + +function Animation( elem, properties, options ) { + var result, + stopped, + index = 0, + length = Animation.prefilters.length, + deferred = jQuery.Deferred().always( function() { + + // Don't match elem in the :animated selector + delete tick.elem; + } ), + tick = function() { + if ( stopped ) { + return false; + } + var currentTime = fxNow || createFxNow(), + remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ), + + // Support: Android 2.3 only + // Archaic crash bug won't allow us to use `1 - ( 0.5 || 0 )` (#12497) + temp = remaining / animation.duration || 0, + percent = 1 - temp, + index = 0, + length = animation.tweens.length; + + for ( ; index < length; index++ ) { + animation.tweens[ index ].run( percent ); + } + + deferred.notifyWith( elem, [ animation, percent, remaining ] ); + + // If there's more to do, yield + if ( percent < 1 && length ) { + return remaining; + } + + // If this was an empty animation, synthesize a final progress notification + if ( !length ) { + deferred.notifyWith( elem, [ animation, 1, 0 ] ); + } + + // Resolve the animation and report its conclusion + deferred.resolveWith( elem, [ animation ] ); + return false; + }, + animation = deferred.promise( { + elem: elem, + props: jQuery.extend( {}, properties ), + opts: jQuery.extend( true, { + specialEasing: {}, + easing: jQuery.easing._default + }, options ), + originalProperties: properties, + originalOptions: options, + startTime: fxNow || createFxNow(), + duration: options.duration, + tweens: [], + createTween: function( prop, end ) { + var tween = jQuery.Tween( elem, animation.opts, prop, end, + animation.opts.specialEasing[ prop ] || animation.opts.easing ); + animation.tweens.push( tween ); + return tween; + }, + stop: function( gotoEnd ) { + var index = 0, + + // If we are going to the end, we want to run all the tweens + // otherwise we skip this part + length = gotoEnd ? animation.tweens.length : 0; + if ( stopped ) { + return this; + } + stopped = true; + for ( ; index < length; index++ ) { + animation.tweens[ index ].run( 1 ); + } + + // Resolve when we played the last frame; otherwise, reject + if ( gotoEnd ) { + deferred.notifyWith( elem, [ animation, 1, 0 ] ); + deferred.resolveWith( elem, [ animation, gotoEnd ] ); + } else { + deferred.rejectWith( elem, [ animation, gotoEnd ] ); + } + return this; + } + } ), + props = animation.props; + + propFilter( props, animation.opts.specialEasing ); + + for ( ; index < length; index++ ) { + result = Animation.prefilters[ index ].call( animation, elem, props, animation.opts ); + if ( result ) { + if ( isFunction( result.stop ) ) { + jQuery._queueHooks( animation.elem, animation.opts.queue ).stop = + result.stop.bind( result ); + } + return result; + } + } + + jQuery.map( props, createTween, animation ); + + if ( isFunction( animation.opts.start ) ) { + animation.opts.start.call( elem, animation ); + } + + // Attach callbacks from options + animation + .progress( animation.opts.progress ) + .done( animation.opts.done, animation.opts.complete ) + .fail( animation.opts.fail ) + .always( animation.opts.always ); + + jQuery.fx.timer( + jQuery.extend( tick, { + elem: elem, + anim: animation, + queue: animation.opts.queue + } ) + ); + + return animation; +} + +jQuery.Animation = jQuery.extend( Animation, { + + tweeners: { + "*": [ function( prop, value ) { + var tween = this.createTween( prop, value ); + adjustCSS( tween.elem, prop, rcssNum.exec( value ), tween ); + return tween; + } ] + }, + + tweener: function( props, callback ) { + if ( isFunction( props ) ) { + callback = props; + props = [ "*" ]; + } else { + props = props.match( rnothtmlwhite ); + } + + var prop, + index = 0, + length = props.length; + + for ( ; index < length; index++ ) { + prop = props[ index ]; + Animation.tweeners[ prop ] = Animation.tweeners[ prop ] || []; + Animation.tweeners[ prop ].unshift( callback ); + } + }, + + prefilters: [ defaultPrefilter ], + + prefilter: function( callback, prepend ) { + if ( prepend ) { + Animation.prefilters.unshift( callback ); + } else { + Animation.prefilters.push( callback ); + } + } +} ); + +jQuery.speed = function( speed, easing, fn ) { + var opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed ) : { + complete: fn || !fn && easing || + isFunction( speed ) && speed, + duration: speed, + easing: fn && easing || easing && !isFunction( easing ) && easing + }; + + // Go to the end state if fx are off + if ( jQuery.fx.off ) { + opt.duration = 0; + + } else { + if ( typeof opt.duration !== "number" ) { + if ( opt.duration in jQuery.fx.speeds ) { + opt.duration = jQuery.fx.speeds[ opt.duration ]; + + } else { + opt.duration = jQuery.fx.speeds._default; + } + } + } + + // Normalize opt.queue - true/undefined/null -> "fx" + if ( opt.queue == null || opt.queue === true ) { + opt.queue = "fx"; + } + + // Queueing + opt.old = opt.complete; + + opt.complete = function() { + if ( isFunction( opt.old ) ) { + opt.old.call( this ); + } + + if ( opt.queue ) { + jQuery.dequeue( this, opt.queue ); + } + }; + + return opt; +}; + +jQuery.fn.extend( { + fadeTo: function( speed, to, easing, callback ) { + + // Show any hidden elements after setting opacity to 0 + return this.filter( isHiddenWithinTree ).css( "opacity", 0 ).show() + + // Animate to the value specified + .end().animate( { opacity: to }, speed, easing, callback ); + }, + animate: function( prop, speed, easing, callback ) { + var empty = jQuery.isEmptyObject( prop ), + optall = jQuery.speed( speed, easing, callback ), + doAnimation = function() { + + // Operate on a copy of prop so per-property easing won't be lost + var anim = Animation( this, jQuery.extend( {}, prop ), optall ); + + // Empty animations, or finishing resolves immediately + if ( empty || dataPriv.get( this, "finish" ) ) { + anim.stop( true ); + } + }; + doAnimation.finish = doAnimation; + + return empty || optall.queue === false ? + this.each( doAnimation ) : + this.queue( optall.queue, doAnimation ); + }, + stop: function( type, clearQueue, gotoEnd ) { + var stopQueue = function( hooks ) { + var stop = hooks.stop; + delete hooks.stop; + stop( gotoEnd ); + }; + + if ( typeof type !== "string" ) { + gotoEnd = clearQueue; + clearQueue = type; + type = undefined; + } + if ( clearQueue && type !== false ) { + this.queue( type || "fx", [] ); + } + + return this.each( function() { + var dequeue = true, + index = type != null && type + "queueHooks", + timers = jQuery.timers, + data = dataPriv.get( this ); + + if ( index ) { + if ( data[ index ] && data[ index ].stop ) { + stopQueue( data[ index ] ); + } + } else { + for ( index in data ) { + if ( data[ index ] && data[ index ].stop && rrun.test( index ) ) { + stopQueue( data[ index ] ); + } + } + } + + for ( index = timers.length; index--; ) { + if ( timers[ index ].elem === this && + ( type == null || timers[ index ].queue === type ) ) { + + timers[ index ].anim.stop( gotoEnd ); + dequeue = false; + timers.splice( index, 1 ); + } + } + + // Start the next in the queue if the last step wasn't forced. + // Timers currently will call their complete callbacks, which + // will dequeue but only if they were gotoEnd. + if ( dequeue || !gotoEnd ) { + jQuery.dequeue( this, type ); + } + } ); + }, + finish: function( type ) { + if ( type !== false ) { + type = type || "fx"; + } + return this.each( function() { + var index, + data = dataPriv.get( this ), + queue = data[ type + "queue" ], + hooks = data[ type + "queueHooks" ], + timers = jQuery.timers, + length = queue ? queue.length : 0; + + // Enable finishing flag on private data + data.finish = true; + + // Empty the queue first + jQuery.queue( this, type, [] ); + + if ( hooks && hooks.stop ) { + hooks.stop.call( this, true ); + } + + // Look for any active animations, and finish them + for ( index = timers.length; index--; ) { + if ( timers[ index ].elem === this && timers[ index ].queue === type ) { + timers[ index ].anim.stop( true ); + timers.splice( index, 1 ); + } + } + + // Look for any animations in the old queue and finish them + for ( index = 0; index < length; index++ ) { + if ( queue[ index ] && queue[ index ].finish ) { + queue[ index ].finish.call( this ); + } + } + + // Turn off finishing flag + delete data.finish; + } ); + } +} ); + +jQuery.each( [ "toggle", "show", "hide" ], function( i, name ) { + var cssFn = jQuery.fn[ name ]; + jQuery.fn[ name ] = function( speed, easing, callback ) { + return speed == null || typeof speed === "boolean" ? + cssFn.apply( this, arguments ) : + this.animate( genFx( name, true ), speed, easing, callback ); + }; +} ); + +// Generate shortcuts for custom animations +jQuery.each( { + slideDown: genFx( "show" ), + slideUp: genFx( "hide" ), + slideToggle: genFx( "toggle" ), + fadeIn: { opacity: "show" }, + fadeOut: { opacity: "hide" }, + fadeToggle: { opacity: "toggle" } +}, function( name, props ) { + jQuery.fn[ name ] = function( speed, easing, callback ) { + return this.animate( props, speed, easing, callback ); + }; +} ); + +jQuery.timers = []; +jQuery.fx.tick = function() { + var timer, + i = 0, + timers = jQuery.timers; + + fxNow = Date.now(); + + for ( ; i < timers.length; i++ ) { + timer = timers[ i ]; + + // Run the timer and safely remove it when done (allowing for external removal) + if ( !timer() && timers[ i ] === timer ) { + timers.splice( i--, 1 ); + } + } + + if ( !timers.length ) { + jQuery.fx.stop(); + } + fxNow = undefined; +}; + +jQuery.fx.timer = function( timer ) { + jQuery.timers.push( timer ); + jQuery.fx.start(); +}; + +jQuery.fx.interval = 13; +jQuery.fx.start = function() { + if ( inProgress ) { + return; + } + + inProgress = true; + schedule(); +}; + +jQuery.fx.stop = function() { + inProgress = null; +}; + +jQuery.fx.speeds = { + slow: 600, + fast: 200, + + // Default speed + _default: 400 +}; + + +// Based off of the plugin by Clint Helfers, with permission. +// https://web.archive.org/web/20100324014747/http://blindsignals.com/index.php/2009/07/jquery-delay/ +jQuery.fn.delay = function( time, type ) { + time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time; + type = type || "fx"; + + return this.queue( type, function( next, hooks ) { + var timeout = window.setTimeout( next, time ); + hooks.stop = function() { + window.clearTimeout( timeout ); + }; + } ); +}; + + +( function() { + var input = document.createElement( "input" ), + select = document.createElement( "select" ), + opt = select.appendChild( document.createElement( "option" ) ); + + input.type = "checkbox"; + + // Support: Android <=4.3 only + // Default value for a checkbox should be "on" + support.checkOn = input.value !== ""; + + // Support: IE <=11 only + // Must access selectedIndex to make default options select + support.optSelected = opt.selected; + + // Support: IE <=11 only + // An input loses its value after becoming a radio + input = document.createElement( "input" ); + input.value = "t"; + input.type = "radio"; + support.radioValue = input.value === "t"; +} )(); + + +var boolHook, + attrHandle = jQuery.expr.attrHandle; + +jQuery.fn.extend( { + attr: function( name, value ) { + return access( this, jQuery.attr, name, value, arguments.length > 1 ); + }, + + removeAttr: function( name ) { + return this.each( function() { + jQuery.removeAttr( this, name ); + } ); + } +} ); + +jQuery.extend( { + attr: function( elem, name, value ) { + var ret, hooks, + nType = elem.nodeType; + + // Don't get/set attributes on text, comment and attribute nodes + if ( nType === 3 || nType === 8 || nType === 2 ) { + return; + } + + // Fallback to prop when attributes are not supported + if ( typeof elem.getAttribute === "undefined" ) { + return jQuery.prop( elem, name, value ); + } + + // Attribute hooks are determined by the lowercase version + // Grab necessary hook if one is defined + if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) { + hooks = jQuery.attrHooks[ name.toLowerCase() ] || + ( jQuery.expr.match.bool.test( name ) ? boolHook : undefined ); + } + + if ( value !== undefined ) { + if ( value === null ) { + jQuery.removeAttr( elem, name ); + return; + } + + if ( hooks && "set" in hooks && + ( ret = hooks.set( elem, value, name ) ) !== undefined ) { + return ret; + } + + elem.setAttribute( name, value + "" ); + return value; + } + + if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) { + return ret; + } + + ret = jQuery.find.attr( elem, name ); + + // Non-existent attributes return null, we normalize to undefined + return ret == null ? undefined : ret; + }, + + attrHooks: { + type: { + set: function( elem, value ) { + if ( !support.radioValue && value === "radio" && + nodeName( elem, "input" ) ) { + var val = elem.value; + elem.setAttribute( "type", value ); + if ( val ) { + elem.value = val; + } + return value; + } + } + } + }, + + removeAttr: function( elem, value ) { + var name, + i = 0, + + // Attribute names can contain non-HTML whitespace characters + // https://html.spec.whatwg.org/multipage/syntax.html#attributes-2 + attrNames = value && value.match( rnothtmlwhite ); + + if ( attrNames && elem.nodeType === 1 ) { + while ( ( name = attrNames[ i++ ] ) ) { + elem.removeAttribute( name ); + } + } + } +} ); + +// Hooks for boolean attributes +boolHook = { + set: function( elem, value, name ) { + if ( value === false ) { + + // Remove boolean attributes when set to false + jQuery.removeAttr( elem, name ); + } else { + elem.setAttribute( name, name ); + } + return name; + } +}; + +jQuery.each( jQuery.expr.match.bool.source.match( /\w+/g ), function( i, name ) { + var getter = attrHandle[ name ] || jQuery.find.attr; + + attrHandle[ name ] = function( elem, name, isXML ) { + var ret, handle, + lowercaseName = name.toLowerCase(); + + if ( !isXML ) { + + // Avoid an infinite loop by temporarily removing this function from the getter + handle = attrHandle[ lowercaseName ]; + attrHandle[ lowercaseName ] = ret; + ret = getter( elem, name, isXML ) != null ? + lowercaseName : + null; + attrHandle[ lowercaseName ] = handle; + } + return ret; + }; +} ); + + + + +var rfocusable = /^(?:input|select|textarea|button)$/i, + rclickable = /^(?:a|area)$/i; + +jQuery.fn.extend( { + prop: function( name, value ) { + return access( this, jQuery.prop, name, value, arguments.length > 1 ); + }, + + removeProp: function( name ) { + return this.each( function() { + delete this[ jQuery.propFix[ name ] || name ]; + } ); + } +} ); + +jQuery.extend( { + prop: function( elem, name, value ) { + var ret, hooks, + nType = elem.nodeType; + + // Don't get/set properties on text, comment and attribute nodes + if ( nType === 3 || nType === 8 || nType === 2 ) { + return; + } + + if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) { + + // Fix name and attach hooks + name = jQuery.propFix[ name ] || name; + hooks = jQuery.propHooks[ name ]; + } + + if ( value !== undefined ) { + if ( hooks && "set" in hooks && + ( ret = hooks.set( elem, value, name ) ) !== undefined ) { + return ret; + } + + return ( elem[ name ] = value ); + } + + if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) { + return ret; + } + + return elem[ name ]; + }, + + propHooks: { + tabIndex: { + get: function( elem ) { + + // Support: IE <=9 - 11 only + // elem.tabIndex doesn't always return the + // correct value when it hasn't been explicitly set + // https://web.archive.org/web/20141116233347/http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/ + // Use proper attribute retrieval(#12072) + var tabindex = jQuery.find.attr( elem, "tabindex" ); + + if ( tabindex ) { + return parseInt( tabindex, 10 ); + } + + if ( + rfocusable.test( elem.nodeName ) || + rclickable.test( elem.nodeName ) && + elem.href + ) { + return 0; + } + + return -1; + } + } + }, + + propFix: { + "for": "htmlFor", + "class": "className" + } +} ); + +// Support: IE <=11 only +// Accessing the selectedIndex property +// forces the browser to respect setting selected +// on the option +// The getter ensures a default option is selected +// when in an optgroup +// eslint rule "no-unused-expressions" is disabled for this code +// since it considers such accessions noop +if ( !support.optSelected ) { + jQuery.propHooks.selected = { + get: function( elem ) { + + /* eslint no-unused-expressions: "off" */ + + var parent = elem.parentNode; + if ( parent && parent.parentNode ) { + parent.parentNode.selectedIndex; + } + return null; + }, + set: function( elem ) { + + /* eslint no-unused-expressions: "off" */ + + var parent = elem.parentNode; + if ( parent ) { + parent.selectedIndex; + + if ( parent.parentNode ) { + parent.parentNode.selectedIndex; + } + } + } + }; +} + +jQuery.each( [ + "tabIndex", + "readOnly", + "maxLength", + "cellSpacing", + "cellPadding", + "rowSpan", + "colSpan", + "useMap", + "frameBorder", + "contentEditable" +], function() { + jQuery.propFix[ this.toLowerCase() ] = this; +} ); + + + + + // Strip and collapse whitespace according to HTML spec + // https://infra.spec.whatwg.org/#strip-and-collapse-ascii-whitespace + function stripAndCollapse( value ) { + var tokens = value.match( rnothtmlwhite ) || []; + return tokens.join( " " ); + } + + +function getClass( elem ) { + return elem.getAttribute && elem.getAttribute( "class" ) || ""; +} + +function classesToArray( value ) { + if ( Array.isArray( value ) ) { + return value; + } + if ( typeof value === "string" ) { + return value.match( rnothtmlwhite ) || []; + } + return []; +} + +jQuery.fn.extend( { + addClass: function( value ) { + var classes, elem, cur, curValue, clazz, j, finalValue, + i = 0; + + if ( isFunction( value ) ) { + return this.each( function( j ) { + jQuery( this ).addClass( value.call( this, j, getClass( this ) ) ); + } ); + } + + classes = classesToArray( value ); + + if ( classes.length ) { + while ( ( elem = this[ i++ ] ) ) { + curValue = getClass( elem ); + cur = elem.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " ); + + if ( cur ) { + j = 0; + while ( ( clazz = classes[ j++ ] ) ) { + if ( cur.indexOf( " " + clazz + " " ) < 0 ) { + cur += clazz + " "; + } + } + + // Only assign if different to avoid unneeded rendering. + finalValue = stripAndCollapse( cur ); + if ( curValue !== finalValue ) { + elem.setAttribute( "class", finalValue ); + } + } + } + } + + return this; + }, + + removeClass: function( value ) { + var classes, elem, cur, curValue, clazz, j, finalValue, + i = 0; + + if ( isFunction( value ) ) { + return this.each( function( j ) { + jQuery( this ).removeClass( value.call( this, j, getClass( this ) ) ); + } ); + } + + if ( !arguments.length ) { + return this.attr( "class", "" ); + } + + classes = classesToArray( value ); + + if ( classes.length ) { + while ( ( elem = this[ i++ ] ) ) { + curValue = getClass( elem ); + + // This expression is here for better compressibility (see addClass) + cur = elem.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " ); + + if ( cur ) { + j = 0; + while ( ( clazz = classes[ j++ ] ) ) { + + // Remove *all* instances + while ( cur.indexOf( " " + clazz + " " ) > -1 ) { + cur = cur.replace( " " + clazz + " ", " " ); + } + } + + // Only assign if different to avoid unneeded rendering. + finalValue = stripAndCollapse( cur ); + if ( curValue !== finalValue ) { + elem.setAttribute( "class", finalValue ); + } + } + } + } + + return this; + }, + + toggleClass: function( value, stateVal ) { + var type = typeof value, + isValidValue = type === "string" || Array.isArray( value ); + + if ( typeof stateVal === "boolean" && isValidValue ) { + return stateVal ? this.addClass( value ) : this.removeClass( value ); + } + + if ( isFunction( value ) ) { + return this.each( function( i ) { + jQuery( this ).toggleClass( + value.call( this, i, getClass( this ), stateVal ), + stateVal + ); + } ); + } + + return this.each( function() { + var className, i, self, classNames; + + if ( isValidValue ) { + + // Toggle individual class names + i = 0; + self = jQuery( this ); + classNames = classesToArray( value ); + + while ( ( className = classNames[ i++ ] ) ) { + + // Check each className given, space separated list + if ( self.hasClass( className ) ) { + self.removeClass( className ); + } else { + self.addClass( className ); + } + } + + // Toggle whole class name + } else if ( value === undefined || type === "boolean" ) { + className = getClass( this ); + if ( className ) { + + // Store className if set + dataPriv.set( this, "__className__", className ); + } + + // If the element has a class name or if we're passed `false`, + // then remove the whole classname (if there was one, the above saved it). + // Otherwise bring back whatever was previously saved (if anything), + // falling back to the empty string if nothing was stored. + if ( this.setAttribute ) { + this.setAttribute( "class", + className || value === false ? + "" : + dataPriv.get( this, "__className__" ) || "" + ); + } + } + } ); + }, + + hasClass: function( selector ) { + var className, elem, + i = 0; + + className = " " + selector + " "; + while ( ( elem = this[ i++ ] ) ) { + if ( elem.nodeType === 1 && + ( " " + stripAndCollapse( getClass( elem ) ) + " " ).indexOf( className ) > -1 ) { + return true; + } + } + + return false; + } +} ); + + + + +var rreturn = /\r/g; + +jQuery.fn.extend( { + val: function( value ) { + var hooks, ret, valueIsFunction, + elem = this[ 0 ]; + + if ( !arguments.length ) { + if ( elem ) { + hooks = jQuery.valHooks[ elem.type ] || + jQuery.valHooks[ elem.nodeName.toLowerCase() ]; + + if ( hooks && + "get" in hooks && + ( ret = hooks.get( elem, "value" ) ) !== undefined + ) { + return ret; + } + + ret = elem.value; + + // Handle most common string cases + if ( typeof ret === "string" ) { + return ret.replace( rreturn, "" ); + } + + // Handle cases where value is null/undef or number + return ret == null ? "" : ret; + } + + return; + } + + valueIsFunction = isFunction( value ); + + return this.each( function( i ) { + var val; + + if ( this.nodeType !== 1 ) { + return; + } + + if ( valueIsFunction ) { + val = value.call( this, i, jQuery( this ).val() ); + } else { + val = value; + } + + // Treat null/undefined as ""; convert numbers to string + if ( val == null ) { + val = ""; + + } else if ( typeof val === "number" ) { + val += ""; + + } else if ( Array.isArray( val ) ) { + val = jQuery.map( val, function( value ) { + return value == null ? "" : value + ""; + } ); + } + + hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ]; + + // If set returns undefined, fall back to normal setting + if ( !hooks || !( "set" in hooks ) || hooks.set( this, val, "value" ) === undefined ) { + this.value = val; + } + } ); + } +} ); + +jQuery.extend( { + valHooks: { + option: { + get: function( elem ) { + + var val = jQuery.find.attr( elem, "value" ); + return val != null ? + val : + + // Support: IE <=10 - 11 only + // option.text throws exceptions (#14686, #14858) + // Strip and collapse whitespace + // https://html.spec.whatwg.org/#strip-and-collapse-whitespace + stripAndCollapse( jQuery.text( elem ) ); + } + }, + select: { + get: function( elem ) { + var value, option, i, + options = elem.options, + index = elem.selectedIndex, + one = elem.type === "select-one", + values = one ? null : [], + max = one ? index + 1 : options.length; + + if ( index < 0 ) { + i = max; + + } else { + i = one ? index : 0; + } + + // Loop through all the selected options + for ( ; i < max; i++ ) { + option = options[ i ]; + + // Support: IE <=9 only + // IE8-9 doesn't update selected after form reset (#2551) + if ( ( option.selected || i === index ) && + + // Don't return options that are disabled or in a disabled optgroup + !option.disabled && + ( !option.parentNode.disabled || + !nodeName( option.parentNode, "optgroup" ) ) ) { + + // Get the specific value for the option + value = jQuery( option ).val(); + + // We don't need an array for one selects + if ( one ) { + return value; + } + + // Multi-Selects return an array + values.push( value ); + } + } + + return values; + }, + + set: function( elem, value ) { + var optionSet, option, + options = elem.options, + values = jQuery.makeArray( value ), + i = options.length; + + while ( i-- ) { + option = options[ i ]; + + /* eslint-disable no-cond-assign */ + + if ( option.selected = + jQuery.inArray( jQuery.valHooks.option.get( option ), values ) > -1 + ) { + optionSet = true; + } + + /* eslint-enable no-cond-assign */ + } + + // Force browsers to behave consistently when non-matching value is set + if ( !optionSet ) { + elem.selectedIndex = -1; + } + return values; + } + } + } +} ); + +// Radios and checkboxes getter/setter +jQuery.each( [ "radio", "checkbox" ], function() { + jQuery.valHooks[ this ] = { + set: function( elem, value ) { + if ( Array.isArray( value ) ) { + return ( elem.checked = jQuery.inArray( jQuery( elem ).val(), value ) > -1 ); + } + } + }; + if ( !support.checkOn ) { + jQuery.valHooks[ this ].get = function( elem ) { + return elem.getAttribute( "value" ) === null ? "on" : elem.value; + }; + } +} ); + + + + +// Return jQuery for attributes-only inclusion + + +support.focusin = "onfocusin" in window; + + +var rfocusMorph = /^(?:focusinfocus|focusoutblur)$/, + stopPropagationCallback = function( e ) { + e.stopPropagation(); + }; + +jQuery.extend( jQuery.event, { + + trigger: function( event, data, elem, onlyHandlers ) { + + var i, cur, tmp, bubbleType, ontype, handle, special, lastElement, + eventPath = [ elem || document ], + type = hasOwn.call( event, "type" ) ? event.type : event, + namespaces = hasOwn.call( event, "namespace" ) ? event.namespace.split( "." ) : []; + + cur = lastElement = tmp = elem = elem || document; + + // Don't do events on text and comment nodes + if ( elem.nodeType === 3 || elem.nodeType === 8 ) { + return; + } + + // focus/blur morphs to focusin/out; ensure we're not firing them right now + if ( rfocusMorph.test( type + jQuery.event.triggered ) ) { + return; + } + + if ( type.indexOf( "." ) > -1 ) { + + // Namespaced trigger; create a regexp to match event type in handle() + namespaces = type.split( "." ); + type = namespaces.shift(); + namespaces.sort(); + } + ontype = type.indexOf( ":" ) < 0 && "on" + type; + + // Caller can pass in a jQuery.Event object, Object, or just an event type string + event = event[ jQuery.expando ] ? + event : + new jQuery.Event( type, typeof event === "object" && event ); + + // Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true) + event.isTrigger = onlyHandlers ? 2 : 3; + event.namespace = namespaces.join( "." ); + event.rnamespace = event.namespace ? + new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" ) : + null; + + // Clean up the event in case it is being reused + event.result = undefined; + if ( !event.target ) { + event.target = elem; + } + + // Clone any incoming data and prepend the event, creating the handler arg list + data = data == null ? + [ event ] : + jQuery.makeArray( data, [ event ] ); + + // Allow special events to draw outside the lines + special = jQuery.event.special[ type ] || {}; + if ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) { + return; + } + + // Determine event propagation path in advance, per W3C events spec (#9951) + // Bubble up to document, then to window; watch for a global ownerDocument var (#9724) + if ( !onlyHandlers && !special.noBubble && !isWindow( elem ) ) { + + bubbleType = special.delegateType || type; + if ( !rfocusMorph.test( bubbleType + type ) ) { + cur = cur.parentNode; + } + for ( ; cur; cur = cur.parentNode ) { + eventPath.push( cur ); + tmp = cur; + } + + // Only add window if we got to document (e.g., not plain obj or detached DOM) + if ( tmp === ( elem.ownerDocument || document ) ) { + eventPath.push( tmp.defaultView || tmp.parentWindow || window ); + } + } + + // Fire handlers on the event path + i = 0; + while ( ( cur = eventPath[ i++ ] ) && !event.isPropagationStopped() ) { + lastElement = cur; + event.type = i > 1 ? + bubbleType : + special.bindType || type; + + // jQuery handler + handle = ( dataPriv.get( cur, "events" ) || {} )[ event.type ] && + dataPriv.get( cur, "handle" ); + if ( handle ) { + handle.apply( cur, data ); + } + + // Native handler + handle = ontype && cur[ ontype ]; + if ( handle && handle.apply && acceptData( cur ) ) { + event.result = handle.apply( cur, data ); + if ( event.result === false ) { + event.preventDefault(); + } + } + } + event.type = type; + + // If nobody prevented the default action, do it now + if ( !onlyHandlers && !event.isDefaultPrevented() ) { + + if ( ( !special._default || + special._default.apply( eventPath.pop(), data ) === false ) && + acceptData( elem ) ) { + + // Call a native DOM method on the target with the same name as the event. + // Don't do default actions on window, that's where global variables be (#6170) + if ( ontype && isFunction( elem[ type ] ) && !isWindow( elem ) ) { + + // Don't re-trigger an onFOO event when we call its FOO() method + tmp = elem[ ontype ]; + + if ( tmp ) { + elem[ ontype ] = null; + } + + // Prevent re-triggering of the same event, since we already bubbled it above + jQuery.event.triggered = type; + + if ( event.isPropagationStopped() ) { + lastElement.addEventListener( type, stopPropagationCallback ); + } + + elem[ type ](); + + if ( event.isPropagationStopped() ) { + lastElement.removeEventListener( type, stopPropagationCallback ); + } + + jQuery.event.triggered = undefined; + + if ( tmp ) { + elem[ ontype ] = tmp; + } + } + } + } + + return event.result; + }, + + // Piggyback on a donor event to simulate a different one + // Used only for `focus(in | out)` events + simulate: function( type, elem, event ) { + var e = jQuery.extend( + new jQuery.Event(), + event, + { + type: type, + isSimulated: true + } + ); + + jQuery.event.trigger( e, null, elem ); + } + +} ); + +jQuery.fn.extend( { + + trigger: function( type, data ) { + return this.each( function() { + jQuery.event.trigger( type, data, this ); + } ); + }, + triggerHandler: function( type, data ) { + var elem = this[ 0 ]; + if ( elem ) { + return jQuery.event.trigger( type, data, elem, true ); + } + } +} ); + + +// Support: Firefox <=44 +// Firefox doesn't have focus(in | out) events +// Related ticket - https://bugzilla.mozilla.org/show_bug.cgi?id=687787 +// +// Support: Chrome <=48 - 49, Safari <=9.0 - 9.1 +// focus(in | out) events fire after focus & blur events, +// which is spec violation - http://www.w3.org/TR/DOM-Level-3-Events/#events-focusevent-event-order +// Related ticket - https://bugs.chromium.org/p/chromium/issues/detail?id=449857 +if ( !support.focusin ) { + jQuery.each( { focus: "focusin", blur: "focusout" }, function( orig, fix ) { + + // Attach a single capturing handler on the document while someone wants focusin/focusout + var handler = function( event ) { + jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ) ); + }; + + jQuery.event.special[ fix ] = { + setup: function() { + var doc = this.ownerDocument || this, + attaches = dataPriv.access( doc, fix ); + + if ( !attaches ) { + doc.addEventListener( orig, handler, true ); + } + dataPriv.access( doc, fix, ( attaches || 0 ) + 1 ); + }, + teardown: function() { + var doc = this.ownerDocument || this, + attaches = dataPriv.access( doc, fix ) - 1; + + if ( !attaches ) { + doc.removeEventListener( orig, handler, true ); + dataPriv.remove( doc, fix ); + + } else { + dataPriv.access( doc, fix, attaches ); + } + } + }; + } ); +} +var location = window.location; + +var nonce = Date.now(); + +var rquery = ( /\?/ ); + + + +// Cross-browser xml parsing +jQuery.parseXML = function( data ) { + var xml; + if ( !data || typeof data !== "string" ) { + return null; + } + + // Support: IE 9 - 11 only + // IE throws on parseFromString with invalid input. + try { + xml = ( new window.DOMParser() ).parseFromString( data, "text/xml" ); + } catch ( e ) { + xml = undefined; + } + + if ( !xml || xml.getElementsByTagName( "parsererror" ).length ) { + jQuery.error( "Invalid XML: " + data ); + } + return xml; +}; + + +var + rbracket = /\[\]$/, + rCRLF = /\r?\n/g, + rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i, + rsubmittable = /^(?:input|select|textarea|keygen)/i; + +function buildParams( prefix, obj, traditional, add ) { + var name; + + if ( Array.isArray( obj ) ) { + + // Serialize array item. + jQuery.each( obj, function( i, v ) { + if ( traditional || rbracket.test( prefix ) ) { + + // Treat each array item as a scalar. + add( prefix, v ); + + } else { + + // Item is non-scalar (array or object), encode its numeric index. + buildParams( + prefix + "[" + ( typeof v === "object" && v != null ? i : "" ) + "]", + v, + traditional, + add + ); + } + } ); + + } else if ( !traditional && toType( obj ) === "object" ) { + + // Serialize object item. + for ( name in obj ) { + buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add ); + } + + } else { + + // Serialize scalar item. + add( prefix, obj ); + } +} + +// Serialize an array of form elements or a set of +// key/values into a query string +jQuery.param = function( a, traditional ) { + var prefix, + s = [], + add = function( key, valueOrFunction ) { + + // If value is a function, invoke it and use its return value + var value = isFunction( valueOrFunction ) ? + valueOrFunction() : + valueOrFunction; + + s[ s.length ] = encodeURIComponent( key ) + "=" + + encodeURIComponent( value == null ? "" : value ); + }; + + if ( a == null ) { + return ""; + } + + // If an array was passed in, assume that it is an array of form elements. + if ( Array.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) { + + // Serialize the form elements + jQuery.each( a, function() { + add( this.name, this.value ); + } ); + + } else { + + // If traditional, encode the "old" way (the way 1.3.2 or older + // did it), otherwise encode params recursively. + for ( prefix in a ) { + buildParams( prefix, a[ prefix ], traditional, add ); + } + } + + // Return the resulting serialization + return s.join( "&" ); +}; + +jQuery.fn.extend( { + serialize: function() { + return jQuery.param( this.serializeArray() ); + }, + serializeArray: function() { + return this.map( function() { + + // Can add propHook for "elements" to filter or add form elements + var elements = jQuery.prop( this, "elements" ); + return elements ? jQuery.makeArray( elements ) : this; + } ) + .filter( function() { + var type = this.type; + + // Use .is( ":disabled" ) so that fieldset[disabled] works + return this.name && !jQuery( this ).is( ":disabled" ) && + rsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) && + ( this.checked || !rcheckableType.test( type ) ); + } ) + .map( function( i, elem ) { + var val = jQuery( this ).val(); + + if ( val == null ) { + return null; + } + + if ( Array.isArray( val ) ) { + return jQuery.map( val, function( val ) { + return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) }; + } ); + } + + return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) }; + } ).get(); + } +} ); + + +var + r20 = /%20/g, + rhash = /#.*$/, + rantiCache = /([?&])_=[^&]*/, + rheaders = /^(.*?):[ \t]*([^\r\n]*)$/mg, + + // #7653, #8125, #8152: local protocol detection + rlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/, + rnoContent = /^(?:GET|HEAD)$/, + rprotocol = /^\/\//, + + /* Prefilters + * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example) + * 2) These are called: + * - BEFORE asking for a transport + * - AFTER param serialization (s.data is a string if s.processData is true) + * 3) key is the dataType + * 4) the catchall symbol "*" can be used + * 5) execution will start with transport dataType and THEN continue down to "*" if needed + */ + prefilters = {}, + + /* Transports bindings + * 1) key is the dataType + * 2) the catchall symbol "*" can be used + * 3) selection will start with transport dataType and THEN go to "*" if needed + */ + transports = {}, + + // Avoid comment-prolog char sequence (#10098); must appease lint and evade compression + allTypes = "*/".concat( "*" ), + + // Anchor tag for parsing the document origin + originAnchor = document.createElement( "a" ); + originAnchor.href = location.href; + +// Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport +function addToPrefiltersOrTransports( structure ) { + + // dataTypeExpression is optional and defaults to "*" + return function( dataTypeExpression, func ) { + + if ( typeof dataTypeExpression !== "string" ) { + func = dataTypeExpression; + dataTypeExpression = "*"; + } + + var dataType, + i = 0, + dataTypes = dataTypeExpression.toLowerCase().match( rnothtmlwhite ) || []; + + if ( isFunction( func ) ) { + + // For each dataType in the dataTypeExpression + while ( ( dataType = dataTypes[ i++ ] ) ) { + + // Prepend if requested + if ( dataType[ 0 ] === "+" ) { + dataType = dataType.slice( 1 ) || "*"; + ( structure[ dataType ] = structure[ dataType ] || [] ).unshift( func ); + + // Otherwise append + } else { + ( structure[ dataType ] = structure[ dataType ] || [] ).push( func ); + } + } + } + }; +} + +// Base inspection function for prefilters and transports +function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR ) { + + var inspected = {}, + seekingTransport = ( structure === transports ); + + function inspect( dataType ) { + var selected; + inspected[ dataType ] = true; + jQuery.each( structure[ dataType ] || [], function( _, prefilterOrFactory ) { + var dataTypeOrTransport = prefilterOrFactory( options, originalOptions, jqXHR ); + if ( typeof dataTypeOrTransport === "string" && + !seekingTransport && !inspected[ dataTypeOrTransport ] ) { + + options.dataTypes.unshift( dataTypeOrTransport ); + inspect( dataTypeOrTransport ); + return false; + } else if ( seekingTransport ) { + return !( selected = dataTypeOrTransport ); + } + } ); + return selected; + } + + return inspect( options.dataTypes[ 0 ] ) || !inspected[ "*" ] && inspect( "*" ); +} + +// A special extend for ajax options +// that takes "flat" options (not to be deep extended) +// Fixes #9887 +function ajaxExtend( target, src ) { + var key, deep, + flatOptions = jQuery.ajaxSettings.flatOptions || {}; + + for ( key in src ) { + if ( src[ key ] !== undefined ) { + ( flatOptions[ key ] ? target : ( deep || ( deep = {} ) ) )[ key ] = src[ key ]; + } + } + if ( deep ) { + jQuery.extend( true, target, deep ); + } + + return target; +} + +/* Handles responses to an ajax request: + * - finds the right dataType (mediates between content-type and expected dataType) + * - returns the corresponding response + */ +function ajaxHandleResponses( s, jqXHR, responses ) { + + var ct, type, finalDataType, firstDataType, + contents = s.contents, + dataTypes = s.dataTypes; + + // Remove auto dataType and get content-type in the process + while ( dataTypes[ 0 ] === "*" ) { + dataTypes.shift(); + if ( ct === undefined ) { + ct = s.mimeType || jqXHR.getResponseHeader( "Content-Type" ); + } + } + + // Check if we're dealing with a known content-type + if ( ct ) { + for ( type in contents ) { + if ( contents[ type ] && contents[ type ].test( ct ) ) { + dataTypes.unshift( type ); + break; + } + } + } + + // Check to see if we have a response for the expected dataType + if ( dataTypes[ 0 ] in responses ) { + finalDataType = dataTypes[ 0 ]; + } else { + + // Try convertible dataTypes + for ( type in responses ) { + if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[ 0 ] ] ) { + finalDataType = type; + break; + } + if ( !firstDataType ) { + firstDataType = type; + } + } + + // Or just use first one + finalDataType = finalDataType || firstDataType; + } + + // If we found a dataType + // We add the dataType to the list if needed + // and return the corresponding response + if ( finalDataType ) { + if ( finalDataType !== dataTypes[ 0 ] ) { + dataTypes.unshift( finalDataType ); + } + return responses[ finalDataType ]; + } +} + +/* Chain conversions given the request and the original response + * Also sets the responseXXX fields on the jqXHR instance + */ +function ajaxConvert( s, response, jqXHR, isSuccess ) { + var conv2, current, conv, tmp, prev, + converters = {}, + + // Work with a copy of dataTypes in case we need to modify it for conversion + dataTypes = s.dataTypes.slice(); + + // Create converters map with lowercased keys + if ( dataTypes[ 1 ] ) { + for ( conv in s.converters ) { + converters[ conv.toLowerCase() ] = s.converters[ conv ]; + } + } + + current = dataTypes.shift(); + + // Convert to each sequential dataType + while ( current ) { + + if ( s.responseFields[ current ] ) { + jqXHR[ s.responseFields[ current ] ] = response; + } + + // Apply the dataFilter if provided + if ( !prev && isSuccess && s.dataFilter ) { + response = s.dataFilter( response, s.dataType ); + } + + prev = current; + current = dataTypes.shift(); + + if ( current ) { + + // There's only work to do if current dataType is non-auto + if ( current === "*" ) { + + current = prev; + + // Convert response if prev dataType is non-auto and differs from current + } else if ( prev !== "*" && prev !== current ) { + + // Seek a direct converter + conv = converters[ prev + " " + current ] || converters[ "* " + current ]; + + // If none found, seek a pair + if ( !conv ) { + for ( conv2 in converters ) { + + // If conv2 outputs current + tmp = conv2.split( " " ); + if ( tmp[ 1 ] === current ) { + + // If prev can be converted to accepted input + conv = converters[ prev + " " + tmp[ 0 ] ] || + converters[ "* " + tmp[ 0 ] ]; + if ( conv ) { + + // Condense equivalence converters + if ( conv === true ) { + conv = converters[ conv2 ]; + + // Otherwise, insert the intermediate dataType + } else if ( converters[ conv2 ] !== true ) { + current = tmp[ 0 ]; + dataTypes.unshift( tmp[ 1 ] ); + } + break; + } + } + } + } + + // Apply converter (if not an equivalence) + if ( conv !== true ) { + + // Unless errors are allowed to bubble, catch and return them + if ( conv && s.throws ) { + response = conv( response ); + } else { + try { + response = conv( response ); + } catch ( e ) { + return { + state: "parsererror", + error: conv ? e : "No conversion from " + prev + " to " + current + }; + } + } + } + } + } + } + + return { state: "success", data: response }; +} + +jQuery.extend( { + + // Counter for holding the number of active queries + active: 0, + + // Last-Modified header cache for next request + lastModified: {}, + etag: {}, + + ajaxSettings: { + url: location.href, + type: "GET", + isLocal: rlocalProtocol.test( location.protocol ), + global: true, + processData: true, + async: true, + contentType: "application/x-www-form-urlencoded; charset=UTF-8", + + /* + timeout: 0, + data: null, + dataType: null, + username: null, + password: null, + cache: null, + throws: false, + traditional: false, + headers: {}, + */ + + accepts: { + "*": allTypes, + text: "text/plain", + html: "text/html", + xml: "application/xml, text/xml", + json: "application/json, text/javascript" + }, + + contents: { + xml: /\bxml\b/, + html: /\bhtml/, + json: /\bjson\b/ + }, + + responseFields: { + xml: "responseXML", + text: "responseText", + json: "responseJSON" + }, + + // Data converters + // Keys separate source (or catchall "*") and destination types with a single space + converters: { + + // Convert anything to text + "* text": String, + + // Text to html (true = no transformation) + "text html": true, + + // Evaluate text as a json expression + "text json": JSON.parse, + + // Parse text as xml + "text xml": jQuery.parseXML + }, + + // For options that shouldn't be deep extended: + // you can add your own custom options here if + // and when you create one that shouldn't be + // deep extended (see ajaxExtend) + flatOptions: { + url: true, + context: true + } + }, + + // Creates a full fledged settings object into target + // with both ajaxSettings and settings fields. + // If target is omitted, writes into ajaxSettings. + ajaxSetup: function( target, settings ) { + return settings ? + + // Building a settings object + ajaxExtend( ajaxExtend( target, jQuery.ajaxSettings ), settings ) : + + // Extending ajaxSettings + ajaxExtend( jQuery.ajaxSettings, target ); + }, + + ajaxPrefilter: addToPrefiltersOrTransports( prefilters ), + ajaxTransport: addToPrefiltersOrTransports( transports ), + + // Main method + ajax: function( url, options ) { + + // If url is an object, simulate pre-1.5 signature + if ( typeof url === "object" ) { + options = url; + url = undefined; + } + + // Force options to be an object + options = options || {}; + + var transport, + + // URL without anti-cache param + cacheURL, + + // Response headers + responseHeadersString, + responseHeaders, + + // timeout handle + timeoutTimer, + + // Url cleanup var + urlAnchor, + + // Request state (becomes false upon send and true upon completion) + completed, + + // To know if global events are to be dispatched + fireGlobals, + + // Loop variable + i, + + // uncached part of the url + uncached, + + // Create the final options object + s = jQuery.ajaxSetup( {}, options ), + + // Callbacks context + callbackContext = s.context || s, + + // Context for global events is callbackContext if it is a DOM node or jQuery collection + globalEventContext = s.context && + ( callbackContext.nodeType || callbackContext.jquery ) ? + jQuery( callbackContext ) : + jQuery.event, + + // Deferreds + deferred = jQuery.Deferred(), + completeDeferred = jQuery.Callbacks( "once memory" ), + + // Status-dependent callbacks + statusCode = s.statusCode || {}, + + // Headers (they are sent all at once) + requestHeaders = {}, + requestHeadersNames = {}, + + // Default abort message + strAbort = "canceled", + + // Fake xhr + jqXHR = { + readyState: 0, + + // Builds headers hashtable if needed + getResponseHeader: function( key ) { + var match; + if ( completed ) { + if ( !responseHeaders ) { + responseHeaders = {}; + while ( ( match = rheaders.exec( responseHeadersString ) ) ) { + responseHeaders[ match[ 1 ].toLowerCase() + " " ] = + ( responseHeaders[ match[ 1 ].toLowerCase() + " " ] || [] ) + .concat( match[ 2 ] ); + } + } + match = responseHeaders[ key.toLowerCase() + " " ]; + } + return match == null ? null : match.join( ", " ); + }, + + // Raw string + getAllResponseHeaders: function() { + return completed ? responseHeadersString : null; + }, + + // Caches the header + setRequestHeader: function( name, value ) { + if ( completed == null ) { + name = requestHeadersNames[ name.toLowerCase() ] = + requestHeadersNames[ name.toLowerCase() ] || name; + requestHeaders[ name ] = value; + } + return this; + }, + + // Overrides response content-type header + overrideMimeType: function( type ) { + if ( completed == null ) { + s.mimeType = type; + } + return this; + }, + + // Status-dependent callbacks + statusCode: function( map ) { + var code; + if ( map ) { + if ( completed ) { + + // Execute the appropriate callbacks + jqXHR.always( map[ jqXHR.status ] ); + } else { + + // Lazy-add the new callbacks in a way that preserves old ones + for ( code in map ) { + statusCode[ code ] = [ statusCode[ code ], map[ code ] ]; + } + } + } + return this; + }, + + // Cancel the request + abort: function( statusText ) { + var finalText = statusText || strAbort; + if ( transport ) { + transport.abort( finalText ); + } + done( 0, finalText ); + return this; + } + }; + + // Attach deferreds + deferred.promise( jqXHR ); + + // Add protocol if not provided (prefilters might expect it) + // Handle falsy url in the settings object (#10093: consistency with old signature) + // We also use the url parameter if available + s.url = ( ( url || s.url || location.href ) + "" ) + .replace( rprotocol, location.protocol + "//" ); + + // Alias method option to type as per ticket #12004 + s.type = options.method || options.type || s.method || s.type; + + // Extract dataTypes list + s.dataTypes = ( s.dataType || "*" ).toLowerCase().match( rnothtmlwhite ) || [ "" ]; + + // A cross-domain request is in order when the origin doesn't match the current origin. + if ( s.crossDomain == null ) { + urlAnchor = document.createElement( "a" ); + + // Support: IE <=8 - 11, Edge 12 - 15 + // IE throws exception on accessing the href property if url is malformed, + // e.g. http://example.com:80x/ + try { + urlAnchor.href = s.url; + + // Support: IE <=8 - 11 only + // Anchor's host property isn't correctly set when s.url is relative + urlAnchor.href = urlAnchor.href; + s.crossDomain = originAnchor.protocol + "//" + originAnchor.host !== + urlAnchor.protocol + "//" + urlAnchor.host; + } catch ( e ) { + + // If there is an error parsing the URL, assume it is crossDomain, + // it can be rejected by the transport if it is invalid + s.crossDomain = true; + } + } + + // Convert data if not already a string + if ( s.data && s.processData && typeof s.data !== "string" ) { + s.data = jQuery.param( s.data, s.traditional ); + } + + // Apply prefilters + inspectPrefiltersOrTransports( prefilters, s, options, jqXHR ); + + // If request was aborted inside a prefilter, stop there + if ( completed ) { + return jqXHR; + } + + // We can fire global events as of now if asked to + // Don't fire events if jQuery.event is undefined in an AMD-usage scenario (#15118) + fireGlobals = jQuery.event && s.global; + + // Watch for a new set of requests + if ( fireGlobals && jQuery.active++ === 0 ) { + jQuery.event.trigger( "ajaxStart" ); + } + + // Uppercase the type + s.type = s.type.toUpperCase(); + + // Determine if request has content + s.hasContent = !rnoContent.test( s.type ); + + // Save the URL in case we're toying with the If-Modified-Since + // and/or If-None-Match header later on + // Remove hash to simplify url manipulation + cacheURL = s.url.replace( rhash, "" ); + + // More options handling for requests with no content + if ( !s.hasContent ) { + + // Remember the hash so we can put it back + uncached = s.url.slice( cacheURL.length ); + + // If data is available and should be processed, append data to url + if ( s.data && ( s.processData || typeof s.data === "string" ) ) { + cacheURL += ( rquery.test( cacheURL ) ? "&" : "?" ) + s.data; + + // #9682: remove data so that it's not used in an eventual retry + delete s.data; + } + + // Add or update anti-cache param if needed + if ( s.cache === false ) { + cacheURL = cacheURL.replace( rantiCache, "$1" ); + uncached = ( rquery.test( cacheURL ) ? "&" : "?" ) + "_=" + ( nonce++ ) + uncached; + } + + // Put hash and anti-cache on the URL that will be requested (gh-1732) + s.url = cacheURL + uncached; + + // Change '%20' to '+' if this is encoded form body content (gh-2658) + } else if ( s.data && s.processData && + ( s.contentType || "" ).indexOf( "application/x-www-form-urlencoded" ) === 0 ) { + s.data = s.data.replace( r20, "+" ); + } + + // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. + if ( s.ifModified ) { + if ( jQuery.lastModified[ cacheURL ] ) { + jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ cacheURL ] ); + } + if ( jQuery.etag[ cacheURL ] ) { + jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ cacheURL ] ); + } + } + + // Set the correct header, if data is being sent + if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) { + jqXHR.setRequestHeader( "Content-Type", s.contentType ); + } + + // Set the Accepts header for the server, depending on the dataType + jqXHR.setRequestHeader( + "Accept", + s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[ 0 ] ] ? + s.accepts[ s.dataTypes[ 0 ] ] + + ( s.dataTypes[ 0 ] !== "*" ? ", " + allTypes + "; q=0.01" : "" ) : + s.accepts[ "*" ] + ); + + // Check for headers option + for ( i in s.headers ) { + jqXHR.setRequestHeader( i, s.headers[ i ] ); + } + + // Allow custom headers/mimetypes and early abort + if ( s.beforeSend && + ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || completed ) ) { + + // Abort if not done already and return + return jqXHR.abort(); + } + + // Aborting is no longer a cancellation + strAbort = "abort"; + + // Install callbacks on deferreds + completeDeferred.add( s.complete ); + jqXHR.done( s.success ); + jqXHR.fail( s.error ); + + // Get transport + transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR ); + + // If no transport, we auto-abort + if ( !transport ) { + done( -1, "No Transport" ); + } else { + jqXHR.readyState = 1; + + // Send global event + if ( fireGlobals ) { + globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] ); + } + + // If request was aborted inside ajaxSend, stop there + if ( completed ) { + return jqXHR; + } + + // Timeout + if ( s.async && s.timeout > 0 ) { + timeoutTimer = window.setTimeout( function() { + jqXHR.abort( "timeout" ); + }, s.timeout ); + } + + try { + completed = false; + transport.send( requestHeaders, done ); + } catch ( e ) { + + // Rethrow post-completion exceptions + if ( completed ) { + throw e; + } + + // Propagate others as results + done( -1, e ); + } + } + + // Callback for when everything is done + function done( status, nativeStatusText, responses, headers ) { + var isSuccess, success, error, response, modified, + statusText = nativeStatusText; + + // Ignore repeat invocations + if ( completed ) { + return; + } + + completed = true; + + // Clear timeout if it exists + if ( timeoutTimer ) { + window.clearTimeout( timeoutTimer ); + } + + // Dereference transport for early garbage collection + // (no matter how long the jqXHR object will be used) + transport = undefined; + + // Cache response headers + responseHeadersString = headers || ""; + + // Set readyState + jqXHR.readyState = status > 0 ? 4 : 0; + + // Determine if successful + isSuccess = status >= 200 && status < 300 || status === 304; + + // Get response data + if ( responses ) { + response = ajaxHandleResponses( s, jqXHR, responses ); + } + + // Convert no matter what (that way responseXXX fields are always set) + response = ajaxConvert( s, response, jqXHR, isSuccess ); + + // If successful, handle type chaining + if ( isSuccess ) { + + // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. + if ( s.ifModified ) { + modified = jqXHR.getResponseHeader( "Last-Modified" ); + if ( modified ) { + jQuery.lastModified[ cacheURL ] = modified; + } + modified = jqXHR.getResponseHeader( "etag" ); + if ( modified ) { + jQuery.etag[ cacheURL ] = modified; + } + } + + // if no content + if ( status === 204 || s.type === "HEAD" ) { + statusText = "nocontent"; + + // if not modified + } else if ( status === 304 ) { + statusText = "notmodified"; + + // If we have data, let's convert it + } else { + statusText = response.state; + success = response.data; + error = response.error; + isSuccess = !error; + } + } else { + + // Extract error from statusText and normalize for non-aborts + error = statusText; + if ( status || !statusText ) { + statusText = "error"; + if ( status < 0 ) { + status = 0; + } + } + } + + // Set data for the fake xhr object + jqXHR.status = status; + jqXHR.statusText = ( nativeStatusText || statusText ) + ""; + + // Success/Error + if ( isSuccess ) { + deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] ); + } else { + deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] ); + } + + // Status-dependent callbacks + jqXHR.statusCode( statusCode ); + statusCode = undefined; + + if ( fireGlobals ) { + globalEventContext.trigger( isSuccess ? "ajaxSuccess" : "ajaxError", + [ jqXHR, s, isSuccess ? success : error ] ); + } + + // Complete + completeDeferred.fireWith( callbackContext, [ jqXHR, statusText ] ); + + if ( fireGlobals ) { + globalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] ); + + // Handle the global AJAX counter + if ( !( --jQuery.active ) ) { + jQuery.event.trigger( "ajaxStop" ); + } + } + } + + return jqXHR; + }, + + getJSON: function( url, data, callback ) { + return jQuery.get( url, data, callback, "json" ); + }, + + getScript: function( url, callback ) { + return jQuery.get( url, undefined, callback, "script" ); + } +} ); + +jQuery.each( [ "get", "post" ], function( i, method ) { + jQuery[ method ] = function( url, data, callback, type ) { + + // Shift arguments if data argument was omitted + if ( isFunction( data ) ) { + type = type || callback; + callback = data; + data = undefined; + } + + // The url can be an options object (which then must have .url) + return jQuery.ajax( jQuery.extend( { + url: url, + type: method, + dataType: type, + data: data, + success: callback + }, jQuery.isPlainObject( url ) && url ) ); + }; +} ); + + +jQuery._evalUrl = function( url, options ) { + return jQuery.ajax( { + url: url, + + // Make this explicit, since user can override this through ajaxSetup (#11264) + type: "GET", + dataType: "script", + cache: true, + async: false, + global: false, + + // Only evaluate the response if it is successful (gh-4126) + // dataFilter is not invoked for failure responses, so using it instead + // of the default converter is kludgy but it works. + converters: { + "text script": function() {} + }, + dataFilter: function( response ) { + jQuery.globalEval( response, options ); + } + } ); +}; + + +jQuery.fn.extend( { + wrapAll: function( html ) { + var wrap; + + if ( this[ 0 ] ) { + if ( isFunction( html ) ) { + html = html.call( this[ 0 ] ); + } + + // The elements to wrap the target around + wrap = jQuery( html, this[ 0 ].ownerDocument ).eq( 0 ).clone( true ); + + if ( this[ 0 ].parentNode ) { + wrap.insertBefore( this[ 0 ] ); + } + + wrap.map( function() { + var elem = this; + + while ( elem.firstElementChild ) { + elem = elem.firstElementChild; + } + + return elem; + } ).append( this ); + } + + return this; + }, + + wrapInner: function( html ) { + if ( isFunction( html ) ) { + return this.each( function( i ) { + jQuery( this ).wrapInner( html.call( this, i ) ); + } ); + } + + return this.each( function() { + var self = jQuery( this ), + contents = self.contents(); + + if ( contents.length ) { + contents.wrapAll( html ); + + } else { + self.append( html ); + } + } ); + }, + + wrap: function( html ) { + var htmlIsFunction = isFunction( html ); + + return this.each( function( i ) { + jQuery( this ).wrapAll( htmlIsFunction ? html.call( this, i ) : html ); + } ); + }, + + unwrap: function( selector ) { + this.parent( selector ).not( "body" ).each( function() { + jQuery( this ).replaceWith( this.childNodes ); + } ); + return this; + } +} ); + + +jQuery.expr.pseudos.hidden = function( elem ) { + return !jQuery.expr.pseudos.visible( elem ); +}; +jQuery.expr.pseudos.visible = function( elem ) { + return !!( elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length ); +}; + + + + +jQuery.ajaxSettings.xhr = function() { + try { + return new window.XMLHttpRequest(); + } catch ( e ) {} +}; + +var xhrSuccessStatus = { + + // File protocol always yields status code 0, assume 200 + 0: 200, + + // Support: IE <=9 only + // #1450: sometimes IE returns 1223 when it should be 204 + 1223: 204 + }, + xhrSupported = jQuery.ajaxSettings.xhr(); + +support.cors = !!xhrSupported && ( "withCredentials" in xhrSupported ); +support.ajax = xhrSupported = !!xhrSupported; + +jQuery.ajaxTransport( function( options ) { + var callback, errorCallback; + + // Cross domain only allowed if supported through XMLHttpRequest + if ( support.cors || xhrSupported && !options.crossDomain ) { + return { + send: function( headers, complete ) { + var i, + xhr = options.xhr(); + + xhr.open( + options.type, + options.url, + options.async, + options.username, + options.password + ); + + // Apply custom fields if provided + if ( options.xhrFields ) { + for ( i in options.xhrFields ) { + xhr[ i ] = options.xhrFields[ i ]; + } + } + + // Override mime type if needed + if ( options.mimeType && xhr.overrideMimeType ) { + xhr.overrideMimeType( options.mimeType ); + } + + // X-Requested-With header + // For cross-domain requests, seeing as conditions for a preflight are + // akin to a jigsaw puzzle, we simply never set it to be sure. + // (it can always be set on a per-request basis or even using ajaxSetup) + // For same-domain requests, won't change header if already provided. + if ( !options.crossDomain && !headers[ "X-Requested-With" ] ) { + headers[ "X-Requested-With" ] = "XMLHttpRequest"; + } + + // Set headers + for ( i in headers ) { + xhr.setRequestHeader( i, headers[ i ] ); + } + + // Callback + callback = function( type ) { + return function() { + if ( callback ) { + callback = errorCallback = xhr.onload = + xhr.onerror = xhr.onabort = xhr.ontimeout = + xhr.onreadystatechange = null; + + if ( type === "abort" ) { + xhr.abort(); + } else if ( type === "error" ) { + + // Support: IE <=9 only + // On a manual native abort, IE9 throws + // errors on any property access that is not readyState + if ( typeof xhr.status !== "number" ) { + complete( 0, "error" ); + } else { + complete( + + // File: protocol always yields status 0; see #8605, #14207 + xhr.status, + xhr.statusText + ); + } + } else { + complete( + xhrSuccessStatus[ xhr.status ] || xhr.status, + xhr.statusText, + + // Support: IE <=9 only + // IE9 has no XHR2 but throws on binary (trac-11426) + // For XHR2 non-text, let the caller handle it (gh-2498) + ( xhr.responseType || "text" ) !== "text" || + typeof xhr.responseText !== "string" ? + { binary: xhr.response } : + { text: xhr.responseText }, + xhr.getAllResponseHeaders() + ); + } + } + }; + }; + + // Listen to events + xhr.onload = callback(); + errorCallback = xhr.onerror = xhr.ontimeout = callback( "error" ); + + // Support: IE 9 only + // Use onreadystatechange to replace onabort + // to handle uncaught aborts + if ( xhr.onabort !== undefined ) { + xhr.onabort = errorCallback; + } else { + xhr.onreadystatechange = function() { + + // Check readyState before timeout as it changes + if ( xhr.readyState === 4 ) { + + // Allow onerror to be called first, + // but that will not handle a native abort + // Also, save errorCallback to a variable + // as xhr.onerror cannot be accessed + window.setTimeout( function() { + if ( callback ) { + errorCallback(); + } + } ); + } + }; + } + + // Create the abort callback + callback = callback( "abort" ); + + try { + + // Do send the request (this may raise an exception) + xhr.send( options.hasContent && options.data || null ); + } catch ( e ) { + + // #14683: Only rethrow if this hasn't been notified as an error yet + if ( callback ) { + throw e; + } + } + }, + + abort: function() { + if ( callback ) { + callback(); + } + } + }; + } +} ); + + + + +// Prevent auto-execution of scripts when no explicit dataType was provided (See gh-2432) +jQuery.ajaxPrefilter( function( s ) { + if ( s.crossDomain ) { + s.contents.script = false; + } +} ); + +// Install script dataType +jQuery.ajaxSetup( { + accepts: { + script: "text/javascript, application/javascript, " + + "application/ecmascript, application/x-ecmascript" + }, + contents: { + script: /\b(?:java|ecma)script\b/ + }, + converters: { + "text script": function( text ) { + jQuery.globalEval( text ); + return text; + } + } +} ); + +// Handle cache's special case and crossDomain +jQuery.ajaxPrefilter( "script", function( s ) { + if ( s.cache === undefined ) { + s.cache = false; + } + if ( s.crossDomain ) { + s.type = "GET"; + } +} ); + +// Bind script tag hack transport +jQuery.ajaxTransport( "script", function( s ) { + + // This transport only deals with cross domain or forced-by-attrs requests + if ( s.crossDomain || s.scriptAttrs ) { + var script, callback; + return { + send: function( _, complete ) { + script = jQuery( " @@ -30,7 +32,7 @@ - +
    @@ -66,7 +68,7 @@ accesskey="N">next
  • - previous
  • @@ -80,10 +82,10 @@
    -
    +
    -

    API documentation

    +

    API documentation

    This section contains auto-generated API documentation for AppTools.

    @@ -146,10 +146,10 @@

    Quick search

    © Copyright 2008-2020, Enthought
  • - Last updated on Jun 12, 2020. + Last updated on Dec 17, 2020.
  • - Created using Sphinx 1.8.5. + Created using Sphinx 2.3.1.
  • diff --git a/api/apptools.html b/api/apptools.html index b29d38a87..1bf597fd6 100644 --- a/api/apptools.html +++ b/api/apptools.html @@ -13,9 +13,11 @@ @@ -30,7 +32,7 @@ - + @@ -65,7 +67,7 @@ >modules
  • - next
  • @@ -83,7 +85,7 @@
    -
    +

    apptools package

    @@ -91,65 +93,6 @@

    apptools package

    diff --git a/api/apptools.io.h5.html b/api/apptools.io.h5.html index 163444cf8..4a6f98d18 100644 --- a/api/apptools.io.h5.html +++ b/api/apptools.io.h5.html @@ -13,9 +13,11 @@ @@ -85,7 +87,7 @@
    -
    +

    apptools.io.h5 package

    @@ -96,13 +98,13 @@

    Submodules

    apptools.io.h5.dict_node module

    -apptools.io.h5.dict_node.ARRAY_PROXY_KEY = '__array__'
    +apptools.io.h5.dict_node.ARRAY_PROXY_KEY = '__array__'

    The key name which identifies array objects in the JSON dict.

    -class apptools.io.h5.dict_node.H5DictNode(h5_group, auto_flush=True)[source]
    +class apptools.io.h5.dict_node.H5DictNode(h5_group, auto_flush=True)[source]

    Bases: object

    Dictionary-like node interface.

    Data for the dict is stored as a JSON file in a PyTables FileNode. This @@ -110,52 +112,44 @@

    Submodules - - - -Parameters:

    -
    +
    -data
    +property data
    -flush()[source]
    +flush()[source]

    Write buffered data to disk.

    -
    +
    -classmethod is_dict_node(pytables_node)[source]
    +classmethod is_dict_node(pytables_node)[source]

    Return True if PyTables node looks like an H5DictNode.

    NOTE: That this returns False if the node is an H5DictNode instance, since the input node should be a normal PyTables Group node.

    @@ -163,7 +157,7 @@

    Submodules
    -keys()[source]
    +keys()[source]

    @@ -173,7 +167,7 @@

    Submodules

    apptools.io.h5.file module

    -class apptools.io.h5.file.H5Attrs(node_attrs)[source]
    +class apptools.io.h5.file.H5Attrs(node_attrs)[source]

    Bases: collections.abc.MutableMapping

    An attributes dictionary for an h5 node.

    This intercepts __setitem__ so that python sequences can be converted to @@ -181,409 +175,360 @@

    Submodules
    -get(k[, d]) → D[k] if k in D, else d. d defaults to None.[source]
    +get(k[, d]) → D[k] if k in D, else d. d defaults to None.[source]

    -items() → a set-like object providing a view on D's items[source]
    +items() → a set-like object providing a view on D's items[source]
    -keys() → a set-like object providing a view on D's keys[source]
    +keys() → a set-like object providing a view on D's keys[source]
    -values() → an object providing a view on D's values[source]
    +values() → an object providing a view on D's values[source]

    -class apptools.io.h5.file.H5File(filename, mode='r+', delete_existing=False, auto_groups=True, auto_open=True, h5filters=None)[source]
    +class apptools.io.h5.file.H5File(filename, mode='r+', delete_existing=False, auto_groups=True, auto_open=True, h5filters=None)[source]

    Bases: collections.abc.Mapping

    File object for HDF5 files.

    This class wraps PyTables to provide a cleaner, but only implements an interface for accessing arrays.

    - --- - - - -
    Parameters:
      -
    • filename (str or a tables.File instance) – Filename for an HDF5 file, or a PyTables File object.
    • -
    • mode (str) –

      Mode to open the file:

      +
      +
      Parameters
      +
        +
      • filename (str or a tables.File instance) – Filename for an HDF5 file, or a PyTables File object.

      • +
      • mode (str) –

        Mode to open the file:

        -
        ’r’ : Read-only +

        ’r’ : Read-only ‘w’ : Write; create new file (an existing file would be deleted). ‘a’ : Read and write to file; create if not existing -‘r+’: Read and write to file; must already exist

        -
      • -
      • delete_existing (bool) – If True, an existing node will be deleted when a create_* method is -called. Otherwise, a ValueError will be raise.
      • -
      • auto_groups (bool) – If True, create_array will automatically create parent groups.
      • -
      • auto_open (bool) – If True, open the file automatically on initialization. Otherwise, -you can call H5File.open() explicitly after initialization.
      • -
      • chunked (bool) – If True, the default behavior of create_array will be a chunked -array (see PyTables create_carray).
      • +‘r+’: Read and write to file; must already exist

        + +

        +
      • delete_existing (bool) – If True, an existing node will be deleted when a create_* method is +called. Otherwise, a ValueError will be raise.

      • +
      • auto_groups (bool) – If True, create_array will automatically create parent groups.

      • +
      • auto_open (bool) – If True, open the file automatically on initialization. Otherwise, +you can call H5File.open() explicitly after initialization.

      • +
      • chunked (bool) – If True, the default behavior of create_array will be a chunked +array (see PyTables create_carray).

      -
    +
    +
    -close()[source]
    +close()[source]
    -create_array(node_path, array_or_shape, dtype=None, chunked=False, extendable=False, **kwargs)[source]
    +create_array(node_path, array_or_shape, dtype=None, chunked=False, extendable=False, **kwargs)[source]

    Create node to store an array.

    - --- - - - -
    Parameters:
      -
    • node_path (str) – PyTable node path; e.g. ‘/path/to/node’.
    • -
    • array_or_shape (array or shape tuple) – Array or shape tuple for an array. If given a shape tuple, the -dtype parameter must also specified.
    • -
    • dtype (str or numpy.dtype) – Data type of array. Only necessary if array_or_shape is a shape.
    • -
    • chunked (bool) – Controls whether the array is chunked.
    • -
    • extendable ({None | bool}) – Controls whether the array is extendable.
    • -
    • kwargs (key/value pairs) – Keyword args passed to PyTables File.create_(c|e)array.
    • +
      +
      Parameters
      +
        +
      • node_path (str) – PyTable node path; e.g. ‘/path/to/node’.

      • +
      • array_or_shape (array or shape tuple) – Array or shape tuple for an array. If given a shape tuple, the +dtype parameter must also specified.

      • +
      • dtype (str or numpy.dtype) – Data type of array. Only necessary if array_or_shape is a shape.

      • +
      • chunked (bool) – Controls whether the array is chunked.

      • +
      • extendable ({None | bool}) – Controls whether the array is extendable.

      • +
      • kwargs (key/value pairs) – Keyword args passed to PyTables File.create_(c|e)array.

      -
    +
    +
    -create_dict(node_path, data=None, **kwargs)[source]
    +create_dict(node_path, data=None, **kwargs)[source]

    Create dict node at the specified path.

    - --- - - - -
    Parameters:
      -
    • node_path (str) – Path to node where data is stored (e.g. ‘/path/to/my_dict’)
    • -
    • data (dict) – Data for initialization, if desired.
    • +
      +
      Parameters
      +
        +
      • node_path (str) – Path to node where data is stored (e.g. ‘/path/to/my_dict’)

      • +
      • data (dict) – Data for initialization, if desired.

      -
    +
    +
    -create_group(group_path, **kwargs)[source]
    +create_group(group_path, **kwargs)[source]

    Create group.

    - --- - - - -
    Parameters:
      -
    • group_path (str) – PyTable group path; e.g. ‘/path/to/group’.
    • -
    • kwargs (key/value pairs) – Keyword args passed to PyTables File.create_group.
    • +
      +
      Parameters
      +
        +
      • group_path (str) – PyTable group path; e.g. ‘/path/to/group’.

      • +
      • kwargs (key/value pairs) – Keyword args passed to PyTables File.create_group.

      -
    +
    +
    -create_table(node_path, description, **kwargs)[source]
    +create_table(node_path, description, **kwargs)[source]

    Create table node at the specified path.

    - --- - - - -
    Parameters:
      -
    • node_path (str) – Path to node where data is stored (e.g. ‘/path/to/my_dict’)
    • -
    • description (dict or numpy dtype object) – The description of the columns in the table. This is either a dict +
      +
      Parameters
      +
        +
      • node_path (str) – Path to node where data is stored (e.g. ‘/path/to/my_dict’)

      • +
      • description (dict or numpy dtype object) – The description of the columns in the table. This is either a dict of column name -> dtype items or a numpy record array dtype. For -more information, see the documentation for Table in pytables.

      • +more information, see the documentation for Table in pytables.

      -
    +
    +
    -exists_error = "'{}' exists in '{}'; set `delete_existing` attribute to True to overwrite existing calculations."
    +exists_error = "'{}' exists in '{}'; set `delete_existing` attribute to True to overwrite existing calculations."
    -
    +
    -is_open
    +property is_open
    -iteritems(path='/')[source]
    +iteritems(path='/')[source]

    Iterate over node paths and nodes of the h5 file.

    -
    +
    -classmethod join_path(*args)[source]
    +classmethod join_path(*args)[source]

    Join parts of an h5 path.

    For example, the 3 argmuments ‘path’, ‘to’, ‘node’ will return ‘/path/to/node’.

    - --- - - - -
    Parameters:args (str) – Parts of path to be joined.
    +
    +
    Parameters
    +

    args (str) – Parts of path to be joined.

    +
    +
    -open()[source]
    +open()[source]
    -remove_group(group_path, **kwargs)[source]
    +remove_group(group_path, **kwargs)[source]

    Remove group

    - --- - - - -
    Parameters:group_path (str) – PyTable group path; e.g. ‘/path/to/group’.
    +
    +
    Parameters
    +

    group_path (str) – PyTable group path; e.g. ‘/path/to/group’.

    +
    +
    -remove_node(node_path)[source]
    +remove_node(node_path)[source]

    Remove node

    - --- - - - -
    Parameters:node_path (str) – PyTable node path; e.g. ‘/path/to/node’.
    +
    +
    Parameters
    +

    node_path (str) – PyTable node path; e.g. ‘/path/to/node’.

    +
    +
    -
    +
    -root
    +property root
    -
    +
    -classmethod split_path(node_path)[source]
    +classmethod split_path(node_path)[source]

    Split node path returning the base path and node name.

    For example: ‘/path/to/node’ will return ‘/path/to’ and ‘node’

    - --- - - - -
    Parameters:node_path (str) – PyTable node path; e.g. ‘/path/to/node’.
    +
    +
    Parameters
    +

    node_path (str) – PyTable node path; e.g. ‘/path/to/node’.

    +
    +
    -class apptools.io.h5.file.H5Group(pytables_group)[source]
    +class apptools.io.h5.file.H5Group(pytables_group)[source]

    Bases: collections.abc.Mapping

    A group node in an H5File.

    This is a thin wrapper around PyTables’ Group object to expose attributes and maintain the dict interface of H5File.

    -
    +
    -children_names
    +property children_names
    -create_array(node_subpath, array_or_shape, dtype=None, chunked=False, extendable=False, **kwargs)[source]
    +create_array(node_subpath, array_or_shape, dtype=None, chunked=False, extendable=False, **kwargs)[source]

    ** H5Group wrapper for H5File.create_array: ** Note that the first argument is a nodepath relative to the group, rather than an absolute path. Below is the original docstring:

    -
    -

    Create node to store an array.

    -
    -
    -
    node_path : str
    -
    PyTable node path; e.g. ‘/path/to/node’.
    -
    array_or_shape : array or shape tuple
    -
    Array or shape tuple for an array. If given a shape tuple, the -dtype parameter must also specified.
    -
    dtype : str or numpy.dtype
    -
    Data type of array. Only necessary if array_or_shape is a shape.
    -
    chunked : bool
    -
    Controls whether the array is chunked.
    -
    extendable : {None | bool}
    -
    Controls whether the array is extendable.
    -
    kwargs : key/value pairs
    -
    Keyword args passed to PyTables File.create_(c|e)array.
    +

    Create node to store an array.

    +
    +
    Parameters
    +
      +
    • node_path (str) – PyTable node path; e.g. ‘/path/to/node’.

    • +
    • array_or_shape (array or shape tuple) – Array or shape tuple for an array. If given a shape tuple, the +dtype parameter must also specified.

    • +
    • dtype (str or numpy.dtype) – Data type of array. Only necessary if array_or_shape is a shape.

    • +
    • chunked (bool) – Controls whether the array is chunked.

    • +
    • extendable ({None | bool}) – Controls whether the array is extendable.

    • +
    • kwargs (key/value pairs) – Keyword args passed to PyTables File.create_(c|e)array.

    • +
    +
    -
    -
    -create_dict(node_subpath, data=None, **kwargs)[source]
    +create_dict(node_subpath, data=None, **kwargs)[source]

    ** H5Group wrapper for H5File.create_dict: ** Note that the first argument is a nodepath relative to the group, rather than an absolute path. Below is the original docstring:

    -
    -

    Create dict node at the specified path.

    -
    -
    -
    node_path : str
    -
    Path to node where data is stored (e.g. ‘/path/to/my_dict’)
    -
    data : dict
    -
    Data for initialization, if desired.
    +

    Create dict node at the specified path.

    +
    +
    Parameters
    +
      +
    • node_path (str) – Path to node where data is stored (e.g. ‘/path/to/my_dict’)

    • +
    • data (dict) – Data for initialization, if desired.

    • +
    +
    -
    -
    -create_group(group_subpath, delete_existing=False, **kwargs)[source]
    +create_group(group_subpath, delete_existing=False, **kwargs)[source]

    ** H5Group wrapper for H5File.create_group: ** Note that the first argument is a nodepath relative to the group, rather than an absolute path. Below is the original docstring:

    -
    -

    Create group.

    -
    -
    -
    group_path : str
    -
    PyTable group path; e.g. ‘/path/to/group’.
    -
    kwargs : key/value pairs
    -
    Keyword args passed to PyTables File.create_group.
    +

    Create group.

    +
    +
    Parameters
    +
      +
    • group_path (str) – PyTable group path; e.g. ‘/path/to/group’.

    • +
    • kwargs (key/value pairs) – Keyword args passed to PyTables File.create_group.

    • +
    +
    -
    -
    -create_table(node_subpath, description, *args, **kwargs)[source]
    +create_table(node_subpath, description, *args, **kwargs)[source]

    ** H5Group wrapper for H5File.create_table: ** Note that the first argument is a nodepath relative to the group, rather than an absolute path. Below is the original docstring:

    -
    -

    Create table node at the specified path.

    -
    -
    -
    node_path : str
    -
    Path to node where data is stored (e.g. ‘/path/to/my_dict’)
    -
    description : dict or numpy dtype object
    -
    The description of the columns in the table. This is either a dict +

    Create table node at the specified path.

    +
    +
    Parameters
    +
      +
    • node_path (str) – Path to node where data is stored (e.g. ‘/path/to/my_dict’)

    • +
    • description (dict or numpy dtype object) – The description of the columns in the table. This is either a dict of column name -> dtype items or a numpy record array dtype. For -more information, see the documentation for Table in pytables.

    +more information, see the documentation for Table in pytables.

  • + + -
    -
    -
    +
    -filename
    +property filename
    -iter_groups()[source]
    +iter_groups()[source]

    Iterate over H5Group nodes that are children of this group.

    -
    +
    -name
    +property name
    -
    +
    -pathname
    +property pathname
    -remove_group(group_subpath, **kwargs)[source]
    +remove_group(group_subpath, **kwargs)[source]

    ** H5Group wrapper for H5File.remove_group: ** Note that the first argument is a nodepath relative to the group, rather than an absolute path. Below is the original docstring:

    -
    -

    Remove group

    -
    -
    -
    group_path : str
    -
    PyTable group path; e.g. ‘/path/to/group’.
    +

    Remove group

    +
    +
    Parameters
    +

    group_path (str) – PyTable group path; e.g. ‘/path/to/group’.

    +
    -
    -
    -remove_node(node_subpath, **kwargs)[source]
    +remove_node(node_subpath, **kwargs)[source]

    ** H5Group wrapper for H5File.remove_node: ** Note that the first argument is a nodepath relative to the group, rather than an absolute path. Below is the original docstring:

    -
    -

    Remove node

    -
    -
    -
    node_path : str
    -
    PyTable node path; e.g. ‘/path/to/node’.
    +

    Remove node

    +
    +
    Parameters
    +

    node_path (str) – PyTable node path; e.g. ‘/path/to/node’.

    +
    -
    -
    -
    +
    -root
    +property root
    -
    +
    -subgroup_names
    +property subgroup_names
    -apptools.io.h5.file.get_atom(dtype)[source]
    +apptools.io.h5.file.get_atom(dtype)[source]

    Return a PyTables Atom for the given dtype or dtype string.

    -apptools.io.h5.file.h5_group_wrapper(original)[source]
    +apptools.io.h5.file.h5_group_wrapper(original)[source]
    -apptools.io.h5.file.iterator_length(iterator)[source]
    +apptools.io.h5.file.iterator_length(iterator)[source]
    @@ -591,76 +536,67 @@

    Submodules

    apptools.io.h5.table_node module

    -class apptools.io.h5.table_node.H5TableNode(node)[source]
    +class apptools.io.h5.table_node.H5TableNode(node)[source]

    Bases: object

    A wrapper for PyTables Table nodes.

    - --- - - - -
    Parameters:node (tables.Table instance) – An H5 node which is a pytables.Table or H5TableNode instance
    -
    +
    +
    Parameters
    +

    node (tables.Table instance) – An H5 node which is a pytables.Table or H5TableNode instance

    +
    +
    +
    -classmethod add_to_h5file(h5, node_path, description, **kwargs)[source]
    +classmethod add_to_h5file(h5, node_path, description, **kwargs)[source]

    Add table node to an H5 file at the specified path.

    - --- - - - -
    Parameters:
      -
    • h5 (H5File) – The H5 file where the table node will be stored.
    • -
    • node_path (str) – Path to node where data is stored (e.g. ‘/path/to/my_table’)
    • -
    • description (list of tuples or numpy dtype object) – The description of the columns in the table. This is either a list +
      +
      Parameters
      +
        +
      • h5 (H5File) – The H5 file where the table node will be stored.

      • +
      • node_path (str) – Path to node where data is stored (e.g. ‘/path/to/my_table’)

      • +
      • description (list of tuples or numpy dtype object) – The description of the columns in the table. This is either a list of (column name, dtype, [, shape or itemsize]) tuples or a numpy record array dtype. For more information, see the documentation for -Table in PyTables.

      • -
      • **kwargs (dict) – Additional keyword arguments to pass to pytables.File.create_table
      • +Table in PyTables.

        +
      • **kwargs (dict) – Additional keyword arguments to pass to pytables.File.create_table

      -
    +
    +
    -append(data)[source]
    +append(data)[source]

    Add some data to the table.

    - --- - - - -
    Parameters:data (dict) – A dictionary of column name -> values items
    +
    +
    Parameters
    +

    data (dict) – A dictionary of column name -> values items

    +
    +
    -
    +
    -classmethod is_table_node(pytables_node)[source]
    +classmethod is_table_node(pytables_node)[source]

    Return True if pytables_node is a pytables.Table or a H5TableNode.

    -
    +
    -ix
    +property ix

    Return an object which provides access to row data.

    -keys()[source]
    +keys()[source]
    -to_dataframe()[source]
    +to_dataframe()[source]

    Return table data as a pandas DataFrame.

    XXX: This does not work if the table contains a multidimensional column

    +

    This method requires pandas to have been installed in the environment.

    @@ -670,26 +606,22 @@

    Submodules

    apptools.io.h5.utils module

    -apptools.io.h5.utils.open_h5file(filename, mode='r+', **kwargs)[source]
    +apptools.io.h5.utils.open_h5file(filename, mode='r+', **kwargs)[source]

    Context manager for reading an HDF5 file as an H5File object.

    - --- - - - -
    Parameters:
      -
    • filename (str) – HDF5 file name.
    • -
    • mode (str) –

      Mode to open the file:

      +
      +
      Parameters
      +
        +
      • filename (str) – HDF5 file name.

      • +
      • mode (str) –

        Mode to open the file:

        ’r’ : Read-only ‘w’ : Write; create new file (an existing file would be deleted). ‘a’ : Read and write to file; create if not existing ‘r+’: Read and write to file; must already exist

        -
      • -
      • H5File for additional keyword arguments. (See) –
      • +

        +
      • H5File for additional keyword arguments. (See) –

      -
    +
    +

    @@ -732,13 +664,11 @@

    This Page

    rel="nofollow">Show Source
    @@ -762,10 +692,10 @@

    Quick search

    © Copyright 2008-2020, Enthought
  • - Last updated on Jun 12, 2020. + Last updated on Dec 17, 2020.
  • - Created using Sphinx 1.8.5. + Created using Sphinx 2.3.1.
  • diff --git a/api/apptools.io.html b/api/apptools.io.html index 7bcdea83d..fa1514e92 100644 --- a/api/apptools.io.html +++ b/api/apptools.io.html @@ -13,9 +13,11 @@ @@ -31,7 +33,7 @@ - +
    @@ -70,7 +72,7 @@ accesskey="N">next
  • - previous
  • @@ -84,7 +86,7 @@
    -
    +

    apptools.io package

    @@ -115,58 +117,58 @@

    Submodules
    -class apptools.io.file.File(path, **traits)[source]
    +class apptools.io.file.File(path, **traits)[source]

    Bases: traits.has_traits.HasPrivateTraits

    A representation of files and folders in a file system.

    -copy(destination)[source]
    +copy(destination)[source]

    Copies this file/folder.

    -create_file(contents='')[source]
    +create_file(contents='')[source]

    Creates a file at this path.

    -create_folder()[source]
    +create_folder()[source]

    Creates a folder at this path.

    All intermediate folders MUST already exist.

    -create_folders()[source]
    +create_folders()[source]

    Creates a folder at this path.

    This will attempt to create any missing intermediate folders.

    -create_package()[source]
    +create_package()[source]

    Creates a package at this path.

    All intermediate folders/packages MUST already exist.

    -delete()[source]
    +delete()[source]

    Deletes this file/folder.

    Does nothing if the file/folder does not exist.

    -make_writeable()[source]
    +make_writeable()[source]

    Attempt to make the file/folder writeable.

    -move(destination)[source]
    +move(destination)[source]

    Moves this file/folder.

    @@ -202,8 +204,8 @@

    Table of Contents

    Previous topic

    -

    apptools.help.help_plugin.action package

    +

    apptools package

    Next topic

    apptools.io.h5 package

    @@ -213,13 +215,11 @@

    This Page

    rel="nofollow">Show Source

    @@ -243,10 +243,10 @@

    Quick search

    © Copyright 2008-2020, Enthought
  • - Last updated on Jun 12, 2020. + Last updated on Dec 17, 2020.
  • - Created using Sphinx 1.8.5. + Created using Sphinx 2.3.1.
  • diff --git a/api/apptools.logger.agent.html b/api/apptools.logger.agent.html index 32534d42e..109f12f4f 100644 --- a/api/apptools.logger.agent.html +++ b/api/apptools.logger.agent.html @@ -13,9 +13,11 @@ @@ -85,7 +87,7 @@
    -
    +

    apptools.logger.agent package

    @@ -101,21 +103,21 @@

    Submodules
    -class apptools.logger.agent.attachments.Attachments(message, **traits)[source]
    +class apptools.logger.agent.attachments.Attachments(message, **traits)[source]

    Bases: traits.has_traits.HasTraits

    -package_any_relevant_files()[source]
    +package_any_relevant_files()[source]
    -package_single_project()[source]
    +package_single_project()[source]
    -package_workspace()[source]
    +package_workspace()[source]
    @@ -125,7 +127,7 @@

    Submodules

    apptools.logger.agent.quality_agent_mailer module

    -apptools.logger.agent.quality_agent_mailer.create_email_message(fromaddr, toaddrs, ccaddrs, subject, priority, include_project=False, stack_trace='', comments='')[source]
    +apptools.logger.agent.quality_agent_mailer.create_email_message(fromaddr, toaddrs, ccaddrs, subject, priority, include_project=False, stack_trace='', comments='')[source]

    @@ -133,72 +135,72 @@

    Submodules

    apptools.logger.agent.quality_agent_view module

    -class apptools.logger.agent.quality_agent_view.QualityAgentView(*args, **kwargs)[source]
    +class apptools.logger.agent.quality_agent_view.QualityAgentView(*args, **kwargs)[source]

    Bases: pyface.base_toolkit.Unimplemented

    -cc_address = <traits.trait_types.Str object>
    +cc_address = <traits.trait_types.Str object>
    -comments = <traits.trait_types.Str object>
    +comments = <traits.trait_types.Str object>
    -from_address = <traits.trait_types.Str object>
    +from_address = <traits.trait_types.Str object>
    -help_id = 'enlib|HID_Quality_Agent_Dlg'
    +help_id = 'enlib|HID_Quality_Agent_Dlg'
    -include_userdata
    +include_userdata

    alias of traits.trait_types.Any

    -msg = <traits.trait_types.Str object>
    +msg = <traits.trait_types.Str object>
    -priority = <traits.trait_types.Str object>
    +priority = <traits.trait_types.Str object>
    -service = <traits.trait_types.Any object>
    +service = <traits.trait_types.Any object>
    -size = <traits.trait_types.Tuple object>
    +size = <traits.trait_types.Tuple object>
    -smtp_server = <traits.trait_types.Str object>
    +smtp_server = <traits.trait_types.Str object>
    -subject = <traits.trait_types.Str object>
    +subject = <traits.trait_types.Str object>
    -title = <traits.trait_types.Str object>
    +title = <traits.trait_types.Str object>
    -to_address = <traits.trait_types.Str object>
    +to_address = <traits.trait_types.Str object>
    @@ -243,13 +245,11 @@

    This Page

    rel="nofollow">Show Source
    @@ -273,10 +273,10 @@

    Quick search

    © Copyright 2008-2020, Enthought
  • - Last updated on Jun 12, 2020. + Last updated on Dec 17, 2020.
  • - Created using Sphinx 1.8.5. + Created using Sphinx 2.3.1.
  • diff --git a/api/apptools.logger.html b/api/apptools.logger.html index 754b0e181..454905560 100644 --- a/api/apptools.logger.html +++ b/api/apptools.logger.html @@ -13,9 +13,11 @@ @@ -84,7 +86,7 @@
    -
    +

    apptools.logger package

    @@ -131,56 +133,10 @@

    Submodules

    apptools.logger.custom_excepthook module

    -apptools.logger.custom_excepthook.custom_excepthook(type, value, traceback)[source]
    +apptools.logger.custom_excepthook.custom_excepthook(type, value, traceback)[source]

    Pass on the exception to the logging system.

    -

    -
    -

    apptools.logger.filtering_handler module

    -

    A log handler that allows filtering of messages by origin.

    -
    -
    -class apptools.logger.filtering_handler.FilteringHandler(include=None, exclude=None)[source]
    -

    Bases: logging.Handler

    -

    A log handler that allows filtering of messages by origin.

    -

    Example

    -
    from apptools.logger.api import DebugHandler, logger
    -
    -handler = FilteringHandler(
    -    include = {
    -        'envisage.core' : True
    -    },
    -
    -    exclude = {
    -        'envisage.core.application' : False
    -    }
    -)
    -
    -logger.addHandler(handler)
    -
    -
    -

    Notes

    -

    The boolean value specified for each name in the include and exclude -dictionaries indicates whether or not the include or exclude should pertain -to any sub-packages and modules.

    -

    The above example includes all log messages from anything contained in, or -under the ‘envisage.core’ package, EXCEPT for any log messages -from the ‘envisage.core.application’ module.

    -
    -
    -emit(record)[source]
    -

    Emits a log record.

    -
    - -
    -
    -filtered_emit(record)[source]
    -

    Emits a log record if it has not been filtered.

    -
    - -
    -

    apptools.logger.log_point module

    @@ -189,7 +145,7 @@

    Submodules
    -apptools.logger.log_point.log_point(msg='\n')[source]
    +apptools.logger.log_point.log_point(msg='\n')[source]

    @@ -197,7 +153,7 @@

    Submodules

    apptools.logger.log_queue_handler module

    -class apptools.logger.log_queue_handler.LogQueueHandler(size=1000)[source]
    +class apptools.logger.log_queue_handler.LogQueueHandler(size=1000)[source]

    Bases: logging.Handler

    Buffers up the log messages so that we can display them later. This is important on startup when log messages are generated before @@ -205,23 +161,23 @@

    Submodules
    -emit(record)[source]
    +emit(record)[source]

    Actually this is more like an enqueue than an emit().

    -get()[source]
    +get()[source]
    -has_new_records()[source]
    +has_new_records()[source]
    -reset()[source]
    +reset()[source]
    @@ -232,65 +188,34 @@

    Submodules
    -class apptools.logger.logger.LogFileHandler(path, maxBytes=1000000, backupCount=3, level=None, formatter=None)[source]
    +class apptools.logger.logger.LogFileHandler(path, maxBytes=1000000, backupCount=3, level=None, formatter=None)[source]

    Bases: logging.handlers.RotatingFileHandler

    The default log file handler.

    -apptools.logger.logger.add_log_queue_handler(logger, level=None, formatter=None)[source]
    +apptools.logger.logger.add_log_queue_handler(logger, level=None, formatter=None)[source]

    Adds a queueing log handler to a logger.

    -
    -
    -apptools.logger.logger.create_log_file_handler(path, maxBytes=1000000, backupCount=3, level=None, formatter=None)[source]
    -

    Creates a log file handler.

    -

    This is just a convenience function to make it easy to create the same -kind of handlers across applications.

    -

    It sets the handler’s formatter to the default formatter, and its logging -level to the default logging level.

    -
    - -

    -
    -

    apptools.logger.null_handler module

    -

    A null log handler.

    -
    -
    -class apptools.logger.null_handler.NullHandler(level=0)[source]
    -

    Bases: logging.Handler

    -

    A null log handler.

    -

    This is a quick hack so that we can start to refactor the ‘logger’ -module since it used to add actual handlers at module load time.

    -

    Now we only add this handler so that people using just the ETS library and -not one of our applications won’t see the warning about ‘no handlers’.

    -
    -
    -emit(record)[source]
    -

    Emits a log record.

    -
    - -
    -

    apptools.logger.ring_buffer module

    Copied from Python Cookbook.

    -class apptools.logger.ring_buffer.RingBuffer(size_max)[source]
    +class apptools.logger.ring_buffer.RingBuffer(size_max)[source]

    Bases: object

    -append(x)[source]
    +append(x)[source]

    append an element at the end of the buffer

    -get()[source]
    +get()[source]

    return a list of elements from the oldest to the newest

    @@ -298,59 +223,20 @@

    Submodules
    -class apptools.logger.ring_buffer.RingBufferFull(n)[source]
    +class apptools.logger.ring_buffer.RingBufferFull(n)[source]

    Bases: object

    -append(x)[source]
    +append(x)[source]
    -get()[source]
    +get()[source]

    -
    -
    -

    apptools.logger.util module

    -

    Utility functions.

    -

    fixme: I don’t like random collections of utility functions! Where should -this go?

    -
    -
    -apptools.logger.util.get_module_name(filename)[source]
    -

    Get the fully qualified module name for a filename.

    -

    For example, if the filename is

    -

    /enthought/envisage/core/core_plugin_definition.py

    -

    this method would return

    -

    envisage.core.core_plugin_definition

    -
    - -
    -
    -apptools.logger.util.get_module_name_from_zip(filename)[source]
    -
    - -
    -
    -apptools.logger.util.get_zip_path(filename)[source]
    -

    Returns the path to the zip file contained in the filename.

    -

    fixme: An example here would help.

    -
    - -
    -
    -apptools.logger.util.is_zip_path(path)[source]
    -

    Returns True if the path refers to a zip file.

    -
    - -
    -
    -apptools.logger.util.path_exists_in_zip(zfile, path)[source]
    -
    -
    @@ -429,10 +310,10 @@

    Quick search

    © Copyright 2008-2020, Enthought
  • - Last updated on Jun 12, 2020. + Last updated on Dec 17, 2020.
  • - Created using Sphinx 1.8.5. + Created using Sphinx 2.3.1.
  • diff --git a/api/apptools.logger.plugin.html b/api/apptools.logger.plugin.html index 247f5e15c..0f53db074 100644 --- a/api/apptools.logger.plugin.html +++ b/api/apptools.logger.plugin.html @@ -13,9 +13,11 @@ @@ -85,7 +87,7 @@
    -
    +

    apptools.logger.plugin package

    @@ -111,41 +113,71 @@

    Submodules
    -class apptools.logger.plugin.logger_plugin.LoggerPlugin[source]
    -

    Bases: envisage.plugin.Plugin

    +class apptools.logger.plugin.logger_plugin.LoggerPlugin(*args, **kwargs)[source] +

    Bases: envisage.api.Plugin

    Logger plugin.

    -MAIL_FILES = 'apptools.logger.plugin.mail_files'
    +MAIL_FILES = 'apptools.logger.plugin.mail_files'
    -PREFERENCES = 'envisage.preferences'
    +PREFERENCES = 'envisage.preferences'
    -PREFERENCES_PAGES = 'envisage.ui.workbench.preferences_pages'
    +PREFERENCES_PAGES = 'envisage.ui.workbench.preferences_pages'
    -VIEWS = 'envisage.ui.workbench.views'
    +VIEWS = 'envisage.ui.workbench.views' +
    + +
    +
    +id = 'apptools.logger'
    +
    + +
    +
    +mail_files
    +
    + +
    +
    +name = 'Logger plugin'
    +
    + +
    +
    +preferences = <traits.trait_types.List object>
    +
    + +
    +
    +preferences_pages = <traits.trait_types.List object>
    -start()[source]
    +start()[source]

    Starts the plugin.

    -stop()[source]
    +stop()[source]

    Stops the plugin.

    +
    +
    +views = <traits.trait_types.List object>
    +
    +

    @@ -153,7 +185,7 @@

    Submodules

    apptools.logger.plugin.logger_preferences module

    -class apptools.logger.plugin.logger_preferences.LoggerPreferences(**traits)[source]
    +class apptools.logger.plugin.logger_preferences.LoggerPreferences(**traits)[source]

    Bases: apptools.preferences.preferences_helper.PreferencesHelper

    The persistent service exposing the Logger plugin’s API.

    @@ -163,30 +195,30 @@

    Submodules

    apptools.logger.plugin.logger_service module

    -class apptools.logger.plugin.logger_service.LoggerService[source]
    +class apptools.logger.plugin.logger_service.LoggerService[source]

    Bases: traits.has_traits.HasTraits

    The persistent service exposing the Logger plugin’s API.

    -create_email_message(fromaddr, toaddrs, ccaddrs, subject, priority, include_userdata=False, stack_trace='', comments='', include_environment=True)[source]
    +create_email_message(fromaddr, toaddrs, ccaddrs, subject, priority, include_userdata=False, stack_trace='', comments='', include_environment=True)[source]

    Format a bug report email from the log files.

    -save_preferences()[source]
    +save_preferences()[source]

    Save the preferences.

    -send_bug_report(smtp_server, fromaddr, toaddrs, ccaddrs, message)[source]
    +send_bug_report(smtp_server, fromaddr, toaddrs, ccaddrs, message)[source]

    Send a bug report email.

    -whole_log_text()[source]
    +whole_log_text()[source]

    Return all of the logged data as formatted text.

    @@ -232,13 +264,11 @@

    This Page

    rel="nofollow">Show Source

    @@ -262,10 +292,10 @@

    Quick search

    © Copyright 2008-2020, Enthought
  • - Last updated on Jun 12, 2020. + Last updated on Dec 17, 2020.
  • - Created using Sphinx 1.8.5. + Created using Sphinx 2.3.1.
  • diff --git a/api/apptools.logger.plugin.view.html b/api/apptools.logger.plugin.view.html index 2d797113e..6cc16d720 100644 --- a/api/apptools.logger.plugin.view.html +++ b/api/apptools.logger.plugin.view.html @@ -13,9 +13,11 @@ @@ -30,7 +32,7 @@ - + @@ -68,7 +70,7 @@ >modules
  • - next
  • @@ -86,7 +88,7 @@
    -
    +

    apptools.logger.plugin.view package

    @@ -97,7 +99,7 @@

    Submodules

    apptools.logger.plugin.view.logger_preferences_page module

    -class apptools.logger.plugin.view.logger_preferences_page.LoggerPreferencesPage(**traits)[source]
    +class apptools.logger.plugin.view.logger_preferences_page.LoggerPreferencesPage(**traits)[source]

    Bases: apptools.preferences.ui.preferences_page.PreferencesPage

    A preference page for the logger plugin.

    @@ -107,17 +109,17 @@

    Submodules

    apptools.logger.plugin.view.logger_view module

    -class apptools.logger.plugin.view.logger_view.LogRecordAdapter[source]
    +class apptools.logger.plugin.view.logger_view.LogRecordAdapter[source]

    Bases: traitsui.tabular_adapter.TabularAdapter

    A TabularEditor adapter for logging.LogRecord objects.

    -column_widths = [80, 100, 120, -1]
    +column_widths = [80, 100, 120, -1]
    -get_width(object, trait, column)[source]
    +get_width(object, trait, column)[source]

    Returns the width to use for a specified column.

    If the value is <= 0, the column will have a default width, which is the same as specifying a width of 0.1.

    @@ -145,77 +147,77 @@

    Submodules
    -class apptools.logger.plugin.view.logger_view.LoggerView(*args, **kwargs)[source]
    +class apptools.logger.plugin.view.logger_view.LoggerView(*args, **kwargs)[source]

    Bases: pyface.workbench.traits_ui_view.TraitsUIView

    The Workbench View showing the list of log items.

    -activated = <traits.trait_types.Instance object>
    +activated = <traits.trait_types.Instance object>
    -activated_text = <traits.traits.ForwardProperty object>
    +activated_text = <traits.traits.ForwardProperty object>
    -code_editor = <traitsui.editors.code_editor.ToolkitEditorFactory object>
    +code_editor = <traitsui.editors.code_editor.ToolkitEditorFactory object>
    -copy_button = <traits.trait_types.Button object>
    +copy_button = <traits.trait_types.Button object>
    -formatted_records = <traits.traits.ForwardProperty object>
    +formatted_records = <traits.traits.ForwardProperty object>
    -id = <traits.trait_types.Str object>
    +id = <traits.trait_types.Str object>
    -log_records = <traits.trait_types.List object>
    +log_records = <traits.trait_types.List object>
    -log_records_editor = <traitsui.editors.tabular_editor.TabularEditor object>
    +log_records_editor = <traitsui.editors.tabular_editor.TabularEditor object>
    -name = <traits.trait_types.Str object>
    +name = <traits.trait_types.Str object>
    -reset_button = <traits.trait_types.Button object>
    +reset_button = <traits.trait_types.Button object>
    -service = <traits.trait_types.Instance object>
    +service = <traits.trait_types.Instance object>
    -show_button = <traits.trait_types.Button object>
    +show_button = <traits.trait_types.Button object>
    -trait_view = ( Group( Item( 'log_records' object = 'object', style = 'simple', show_label = False ), Group( Item( 'reset_button' object = 'object', style = 'simple', show_label = False ), Item( 'trait_modified' object = 'object', style = 'simple' ), Item( 'show_button' object = 'object', style = 'simple', show_label = False ), Item( 'copy_button' object = 'object', style = 'simple', show_label = False ), orientation = 'horizontal', show_labels = False, object = 'object', style = 'simple' ), show_labels = False, object = 'object', style = 'simple' ) )
    +trait_view = ( Group( Item( 'log_records' object = 'object', style = 'simple', show_label = False ), Group( Item( 'reset_button' object = 'object', style = 'simple', show_label = False ), Item( 'trait_modified' object = 'object', style = 'simple' ), Item( 'show_button' object = 'object', style = 'simple', show_label = False ), Item( 'copy_button' object = 'object', style = 'simple', show_label = False ), orientation = 'horizontal', show_labels = False, object = 'object', style = 'simple' ), show_labels = False, object = 'object', style = 'simple' ) )
    -update(force=False)[source]
    +update(force=False)[source]

    Update ‘log_records’ if our handler has new records or ‘force’ is set.

    @@ -252,21 +254,19 @@

    Previous topic

    apptools.logger.plugin package

    Next topic

    -

    apptools.lru_cache package

    +

    apptools.naming package

    This Page

    @@ -290,10 +290,10 @@

    Quick search

    © Copyright 2008-2020, Enthought

  • - Last updated on Jun 12, 2020. + Last updated on Dec 17, 2020.
  • - Created using Sphinx 1.8.5. + Created using Sphinx 2.3.1.
  • diff --git a/api/apptools.naming.html b/api/apptools.naming.html index ed313f58a..8879ceee8 100644 --- a/api/apptools.naming.html +++ b/api/apptools.naming.html @@ -13,9 +13,11 @@ @@ -30,8 +32,8 @@ - - + +
    @@ -66,11 +68,11 @@ >modules
  • - next
  • - previous
  • @@ -84,7 +86,7 @@
    -
    +
    @@ -141,7 +112,7 @@

    Submodules
    -class apptools.naming.address.Address[source]
    +class apptools.naming.address.Address[source]

    Bases: traits.has_traits.HasTraits

    The address of a communications end-point.

    It contains a type that describes the communication mechanism, and the @@ -157,7 +128,7 @@

    Submodules
    -class apptools.naming.binding.Binding[source]
    +class apptools.naming.binding.Binding[source]

    Bases: traits.has_traits.HasTraits

    The representation of a name-to-object binding in a context.

    @@ -168,32 +139,27 @@

    Submodules
    -class apptools.naming.context.Context[source]
    +class apptools.naming.context.Context[source]

    Bases: traits.has_traits.HasTraits

    The base class for all naming contexts.

    -INITIAL_CONTEXT_FACTORY = 'apptools.naming.factory.initial'
    +INITIAL_CONTEXT_FACTORY = 'apptools.naming.factory.initial'
    -OBJECT_FACTORIES = 'apptools.naming.factory.object'
    +OBJECT_FACTORIES = 'apptools.naming.factory.object'
    -STATE_FACTORIES = 'apptools.naming.factory.state'
    -
    - -
    -
    -TYPE_MANAGER = 'apptools.naming.factory.type.manager'
    +STATE_FACTORIES = 'apptools.naming.factory.state'
    -bind(name, obj, make_contexts=False)[source]
    +bind(name, obj, make_contexts=False)[source]

    Binds a name to an object.

    If ‘make_contexts’ is True then any missing intermediate contexts are created automatically.

    @@ -201,64 +167,63 @@

    Submodules
    -create_subcontext(name)[source]
    +create_subcontext(name)[source]

    Creates a sub-context.

    -destroy_subcontext(name)[source]
    +destroy_subcontext(name)[source]

    Destroys a sub-context.

    -get_unique_name(prefix)[source]
    +get_unique_name(prefix)[source]

    Returns a name that is unique within the context.

    The name returned will start with the specified prefix.

    -is_context(name)[source]
    +is_context(name)[source]

    Returns True if the name is bound to a context.

    -list_bindings(name='')[source]
    +list_bindings(name='')[source]

    Lists the bindings in a context.

    -list_names(name='')[source]
    +list_names(name='')[source]

    Lists the names bound in a context.

    -lookup(name)[source]
    +lookup(name)[source]

    Resolves a name relative to this context.

    -lookup_binding(name)[source]
    +lookup_binding(name)[source]

    Looks up the binding for a name relative to this context.

    -lookup_context(name)[source]
    +lookup_context(name)[source]

    Resolves a name relative to this context.

    -

    The name MUST resolve to a context. This method is useful to return -context adapters.

    +

    The name MUST resolve to a context.

    -rebind(name, obj, make_contexts=False)[source]
    +rebind(name, obj, make_contexts=False)[source]

    Binds an object to a name that may already be bound.

    If ‘make_contexts’ is True then any missing intermediate contexts are created automatically.

    @@ -270,58 +235,36 @@

    Submodules
    -rename(old_name, new_name)[source]
    +rename(old_name, new_name)[source]

    Binds a new name to an object.

    -search(obj)[source]
    +search(obj)[source]

    Returns a list of namespace names that are bound to obj.

    -unbind(name)[source]
    +unbind(name)[source]

    Unbinds a name.

    -

    -
    -

    apptools.naming.context_adapter module

    -

    The base class for all context adapters.

    -
    -
    -class apptools.naming.context_adapter.ContextAdapter[source]
    -

    Bases: apptools.naming.context.Context

    -

    The base class for all context adapters.

    -
    - -
    -
    -

    apptools.naming.context_adapter_factory module

    -

    The base class for all context adapter factories.

    -
    -
    -class apptools.naming.context_adapter_factory.ContextAdapterFactory[source]
    -

    Bases: apptools.type_manager.adapter_factory.AdapterFactory

    -

    The base class for all context adapter factories.

    -
    -

    apptools.naming.dir_context module

    The base class for all directory contexts.

    -class apptools.naming.dir_context.DirContext[source]
    +class apptools.naming.dir_context.DirContext[source]

    Bases: apptools.naming.context.Context

    The base class for all directory contexts.

    -find_bindings(visitor)[source]
    +find_bindings(visitor)[source]

    Find bindings with attributes matching criteria in visitor.

    Visitor is a function that is passed the bindings for each level of the heirarchy and the attribute dictionary for those bindings. The visitor @@ -331,13 +274,13 @@

    Submodules
    -get_attributes(name)[source]
    +get_attributes(name)[source]

    Returns the attributes associated with a named object.

    -set_attributes(name, attributes)[source]
    +set_attributes(name, attributes)[source]

    Sets the attributes associated with a named object.

    @@ -353,10 +296,10 @@

    Submodules -
  • Extendable by contributions from somewhere other than the original -code writer
  • -
  • Dynamic in that the elements it is composed of can change each time -someone interacts with the contents of the context.
  • +
  • Extendable by contributions from somewhere other than the original +code writer

  • +
  • Dynamic in that the elements it is composed of can change each time +someone interacts with the contents of the context.

  • It should be noted that this capability is explicitly different from contexts that look at another container to determine their contents, such @@ -366,21 +309,21 @@

    Submodules -
    context_name: A non-empty string
    -
    Represents the name of the item within this context. This must be +
    +
    context_name: A non-empty string

    Represents the name of the item within this context. This must be present for the trait to show up as a context item though the value -may change over time as the item gets bound to different names.

    -
    context_order: A float value
    -
    Indicates the position for the item within this context. All +may change over time as the item gets bound to different names.

    +
    +
    context_order: A float value

    Indicates the position for the item within this context. All dynamically contributed context items are sorted by ascending order -of this value using the standard list sort function.

    -
    is_context: A boolean value
    -
    True if the item is itself a context.
    +of this value using the standard list sort function.

    +
    +
    is_context: A boolean value

    True if the item is itself a context.

    +

    -class apptools.naming.dynamic_context.DynamicContext[source]
    +class apptools.naming.dynamic_context.DynamicContext[source]

    Bases: apptools.naming.context.Context

    A framework that dynamically determines the contents of a context at the time of interaction with the contents rather than at the time a @@ -396,7 +339,7 @@

    Submodules
    -exception apptools.naming.exception.InvalidNameError[source]
    +exception apptools.naming.exception.InvalidNameError[source]

    Bases: apptools.naming.exception.NamingError

    Invalid name.

    This exception is thrown when the name passed to a naming operation does @@ -405,7 +348,7 @@

    Submodules
    -exception apptools.naming.exception.NameAlreadyBoundError[source]
    +exception apptools.naming.exception.NameAlreadyBoundError[source]

    Bases: apptools.naming.exception.NamingError

    Name already bound.

    This exception is thrown when an attempt is made to bind a name that is @@ -414,7 +357,7 @@

    Submodules
    -exception apptools.naming.exception.NameNotFoundError[source]
    +exception apptools.naming.exception.NameNotFoundError[source]

    Bases: apptools.naming.exception.NamingError

    Name not found.

    This exception is thrown when a component of a name cannot be resolved @@ -423,14 +366,14 @@

    Submodules
    -exception apptools.naming.exception.NamingError[source]
    +exception apptools.naming.exception.NamingError[source]

    Bases: Exception

    Base class for all naming exceptions.

    -exception apptools.naming.exception.NotContextError[source]
    +exception apptools.naming.exception.NotContextError[source]

    Bases: apptools.naming.exception.NamingError

    Not a context.

    This exception is thrown when a naming operation has reached a point where @@ -440,7 +383,7 @@

    Submodules
    -exception apptools.naming.exception.OperationNotSupportedError[source]
    +exception apptools.naming.exception.OperationNotSupportedError[source]

    Bases: apptools.naming.exception.NamingError

    The context does support the requested operation.

    @@ -451,7 +394,7 @@

    Submodules
    -apptools.naming.initial_context.InitialContext(environment)[source]
    +apptools.naming.initial_context.InitialContext(environment)[source]

    Creates an initial context for beginning name resolution.

    @@ -461,12 +404,12 @@

    Submodules
    -class apptools.naming.initial_context_factory.InitialContextFactory[source]
    +class apptools.naming.initial_context_factory.InitialContextFactory[source]

    Bases: traits.has_traits.HasTraits

    The base class for all initial context factories.

    -get_initial_context(environment)[source]
    +get_initial_context(environment)[source]

    Creates an initial context for beginning name resolution.

    @@ -478,7 +421,7 @@

    Submodules
    -class apptools.naming.naming_event.NamingEvent[source]
    +class apptools.naming.naming_event.NamingEvent[source]

    Bases: traits.has_traits.HasTraits

    Information about tree model changes.

    @@ -489,12 +432,12 @@

    Submodules
    -class apptools.naming.naming_manager.NamingManager[source]
    +class apptools.naming.naming_manager.NamingManager[source]

    Bases: traits.has_traits.HasTraits

    The naming manager.

    -get_object_instance(info, name, context)[source]
    +get_object_instance(info, name, context)[source]

    Creates an object using the specified state information.

    The naming manager asks the context for its list of OBJECT factories and calls them one by one until it gets a non-None result, indicating @@ -506,7 +449,7 @@

    Submodules
    -get_state_to_bind(obj, name, context)[source]
    +get_state_to_bind(obj, name, context)[source]

    Returns the state of an object for binding.

    The naming manager asks the context for its list of STATE factories and then calls them one by one until it gets a non-None result @@ -524,14 +467,14 @@

    Submodules
    -class apptools.naming.object_factory.ObjectFactory[source]
    +class apptools.naming.object_factory.ObjectFactory[source]

    Bases: traits.has_traits.HasTraits

    The base class for all object factories.

    An object factory accepts some information about how to create an object (such as a reference) and returns an instance of that object.

    -get_object_instance(state, name, context)[source]
    +get_object_instance(state, name, context)[source]

    Creates an object using the specified state information.

    Returns None if the factory cannot create the object (ie. it does not recognise the state passed to it).

    @@ -545,30 +488,30 @@

    Submodules
    -class apptools.naming.object_serializer.ObjectSerializer[source]
    +class apptools.naming.object_serializer.ObjectSerializer[source]

    Bases: traits.has_traits.HasTraits

    The base class for all object serializers.

    -can_load(path)[source]
    +can_load(path)[source]

    Returns True if the serializer can load a file.

    -can_save(obj)[source]
    +can_save(obj)[source]

    Returns True if the serializer can save an object.

    -load(path)[source]
    +load(path)[source]

    Loads an object from a file.

    -save(path, obj)[source]
    +save(path, obj)[source]

    Saves an object to a file.

    @@ -580,7 +523,7 @@

    Submodules
    -class apptools.naming.py_context.PyContext(**traits)[source]
    +class apptools.naming.py_context.PyContext(**traits)[source]

    Bases: apptools.naming.context.Context, apptools.naming.referenceable.Referenceable

    A naming context for a Python namespace.

    @@ -591,12 +534,12 @@

    Submodules
    -class apptools.naming.py_object_factory.PyObjectFactory[source]
    +class apptools.naming.py_object_factory.PyObjectFactory[source]

    Bases: apptools.naming.object_factory.ObjectFactory

    Object factory for Python namespace contexts.

    -get_object_instance(state, name, context)[source]
    +get_object_instance(state, name, context)[source]

    Creates an object using the specified state information.

    @@ -608,35 +551,35 @@

    Submodules
    -class apptools.naming.pyfs_context.PyFSContext(**traits)[source]
    +class apptools.naming.pyfs_context.PyFSContext(**traits)[source]

    Bases: apptools.naming.dir_context.DirContext, apptools.naming.referenceable.Referenceable

    A Python File System context.

    This context represents a directory on a local file system.

    -ATTRIBUTES_FILE = '__attributes__'
    +ATTRIBUTES_FILE = '__attributes__'
    -FILTERS = 'apptools.naming.pyfs.filters'
    +FILTERS = 'apptools.naming.pyfs.filters'
    -OBJECT_SERIALIZERS = 'apptools.naming.pyfs.object.serializers'
    +OBJECT_SERIALIZERS = 'apptools.naming.pyfs.object.serializers'
    -get_unique_name(name)[source]
    +get_unique_name(name)[source]

    Returns a name that is unique within the context.

    The name returned will start with the specified prefix.

    -refresh()[source]
    +refresh()[source]

    Refresh the context to reflect changes in the file system.

    @@ -648,12 +591,12 @@

    Submodules
    -class apptools.naming.pyfs_context_factory.PyFSContextFactory[source]
    +class apptools.naming.pyfs_context_factory.PyFSContextFactory[source]

    Bases: apptools.naming.object_factory.ObjectFactory

    Object factory for Python File System contexts.

    -get_object_instance(state, name, context)[source]
    +get_object_instance(state, name, context)[source]

    Creates an object using the specified state information.

    @@ -665,12 +608,12 @@

    Submodules
    -class apptools.naming.pyfs_initial_context_factory.PyFSInitialContextFactory[source]
    +class apptools.naming.pyfs_initial_context_factory.PyFSInitialContextFactory[source]

    Bases: apptools.naming.initial_context_factory.InitialContextFactory

    The initial context factory for Python file system contexts.

    -get_initial_context(environment)[source]
    +get_initial_context(environment)[source]

    Creates an initial context for beginning name resolution.

    @@ -682,12 +625,12 @@

    Submodules
    -class apptools.naming.pyfs_object_factory.PyFSObjectFactory[source]
    +class apptools.naming.pyfs_object_factory.PyFSObjectFactory[source]

    Bases: apptools.naming.object_factory.ObjectFactory

    Object factory for Python File System contexts.

    -get_object_instance(state, name, context)[source]
    +get_object_instance(state, name, context)[source]

    Creates an object using the specified state information.

    @@ -699,12 +642,12 @@

    Submodules
    -class apptools.naming.pyfs_state_factory.PyFSStateFactory[source]
    +class apptools.naming.pyfs_state_factory.PyFSStateFactory[source]

    Bases: apptools.naming.state_factory.StateFactory

    State factory for Python File System contexts.

    -get_state_to_bind(obj, name, context)[source]
    +get_state_to_bind(obj, name, context)[source]

    Returns the state of an object for binding.

    @@ -716,7 +659,7 @@

    Submodules
    -class apptools.naming.reference.Reference[source]
    +class apptools.naming.reference.Reference[source]

    Bases: traits.has_traits.HasPrivateTraits

    A reference to an object that lives outside of the naming system.

    References provide a way to store the address(s) of objects that live @@ -735,7 +678,7 @@

    Submodules
    -class apptools.naming.referenceable.Referenceable[source]
    +class apptools.naming.referenceable.Referenceable[source]

    Bases: traits.has_traits.HasPrivateTraits

    Base class for classes that can produce a reference to themselves.

    @@ -746,12 +689,12 @@

    Submodules
    -class apptools.naming.referenceable_state_factory.ReferenceableStateFactory[source]
    +class apptools.naming.referenceable_state_factory.ReferenceableStateFactory[source]

    Bases: apptools.naming.state_factory.StateFactory

    State factory for referenceable objects.

    -get_state_to_bind(obj, name, context)[source]
    +get_state_to_bind(obj, name, context)[source]

    Returns the state of an object for binding.

    @@ -763,14 +706,14 @@

    Submodules
    -class apptools.naming.state_factory.StateFactory[source]
    +class apptools.naming.state_factory.StateFactory[source]

    Bases: traits.has_traits.HasPrivateTraits

    The base class for all state factories.

    A state factory accepts an object and returns some data representing the object that is suitable for storing in a particular context.

    -get_state_to_bind(obj, name, context)[source]
    +get_state_to_bind(obj, name, context)[source]

    Returns the state of an object for binding.

    Returns None if the factory cannot create the state (ie. it does not recognise the object passed to it).

    @@ -785,7 +728,7 @@

    Submodules
    -apptools.naming.unique_name.make_unique_name(base, existing=[], format='%s_%s')[source]
    +apptools.naming.unique_name.make_unique_name(base, existing=[], format='%s_%s')[source]

    Return a name, unique within a context, based on the specified name.

    base: the desired base name of the generated unique name. existing: a sequence of the existing names to avoid returning. @@ -818,8 +761,6 @@

    Table of Contents

  • apptools.naming.api module
  • apptools.naming.binding module
  • apptools.naming.context module
  • -
  • apptools.naming.context_adapter module
  • -
  • apptools.naming.context_adapter_factory module
  • apptools.naming.dir_context module
  • apptools.naming.dynamic_context module
  • apptools.naming.exception module
  • @@ -847,24 +788,22 @@

    Table of Contents

    Previous topic

    -

    apptools.lru_cache package

    +

    apptools.logger.plugin.view package

    Next topic

    -

    apptools.naming.adapter package

    +

    apptools.naming.trait_defs package

    This Page

    @@ -888,10 +827,10 @@

    Quick search

    © Copyright 2008-2020, Enthought
  • - Last updated on Jun 12, 2020. + Last updated on Dec 17, 2020.
  • - Created using Sphinx 1.8.5. + Created using Sphinx 2.3.1.
  • diff --git a/api/apptools.naming.trait_defs.html b/api/apptools.naming.trait_defs.html index d1ad34696..6938f18d2 100644 --- a/api/apptools.naming.trait_defs.html +++ b/api/apptools.naming.trait_defs.html @@ -13,9 +13,11 @@ @@ -30,8 +32,8 @@ - - + +
    @@ -67,11 +69,11 @@ >modules
  • - next
  • - previous
  • @@ -85,7 +87,7 @@
    -
    +

    apptools.naming.trait_defs package

    @@ -99,109 +101,93 @@

    Submodules

    apptools.naming.trait_defs.naming_traits module

    -class apptools.naming.trait_defs.naming_traits.NamingTraitHandler(aClass, or_none, module)[source]
    -

    Bases: traits.trait_handlers.TraitHandler

    +class apptools.naming.trait_defs.naming_traits.NamingTraitHandler(aClass, or_none, module)[source] +

    Bases: traits.trait_handler.TraitHandler

    -find_class()[source]
    +find_class()[source]
    -get_editor(trait)[source]
    +get_editor(trait)[source]

    Returns a trait editor that allows the user to modify the trait -trait.

    - --- - - - -
    Parameters:
      -
    • trait (Trait) – The trait to be edited.
    • -
    • Description
    • -
    • -----------
    • -
    • method only needs to be specified if traits defined using this (This) –
    • -
    • handler require a non-default trait editor in trait user (trait) –
    • -
    • The default implementation of this method returns a trait (interfaces.) –
    • -
    • that allows the user to type an arbitrary string as the value. (editor) –
    • -
    • more information on trait user interfaces, refer to the *Traits UI (For) –
    • -
    • Guide*. (User) –
    • -
    -
    +trait. +This method only needs to be specified if traits defined using this +trait handler require a non-default trait editor in trait user +interfaces. The default implementation of this method returns a trait +editor that allows the user to type an arbitrary string as the value.

    +

    For more information on trait user interfaces, refer to the Traits UI +User Guide.

    +
    +
    Parameters
    +

    trait (Trait) – The trait to be edited.

    +
    +
    -info()[source]
    +info()[source]

    Must return a string describing the type of value accepted by the trait handler.

    The string should be a phrase describing the type defined by the -TraitHandler subclass, rather than a complete sentence. For example, use -the phrase, “a square sprocket” instead of the sentence, “The value must -be a square sprocket.” The value returned by info() is combined with -other information whenever an error occurs and therefore makes more -sense to the user if the result is a phrase. The info() method is +TraitHandler subclass, rather than a complete sentence. For example, +use the phrase, “a square sprocket” instead of the sentence, “The value +must be a square sprocket.” The value returned by info() is combined +with other information whenever an error occurs and therefore makes +more sense to the user if the result is a phrase. The info() method is similar in purpose and use to the info attribute of a validator function.

    Note that the result can include information specific to the particular -trait handler instance. For example, TraitRange instances return a -string indicating the range of values acceptable to the handler (e.g., -“an integer in the range from 1 to 9”). If the info() method is not -overridden, the default method returns the value of the ‘info_text’ -attribute.

    +trait handler instance. If the info() method is not overridden, the +default method returns the value of the ‘info_text’ attribute.

    -post_setattr(object, name, value)[source]
    +post_setattr(object, name, value)[source]
    -resolve_class(object, name, value)[source]
    +resolve_class(object, name, value)[source]
    -validate(object, name, value)[source]
    -

    Verifies whether a new value assigned to a trait attribute is valid.

    - --- - - - - - -
    Parameters:
      -
    • object (object) – The object whose attribute is being assigned.
    • -
    • name (str) – The name of the attribute being assigned.
    • -
    • value – The proposed new value for the attribute.
    • -
    -
    Returns:

      -
    • If the new value is valid, this method must return either the original
    • -
    • value passed to it, or an alternate value to be assigned in place of the
    • -
    • original value. Whatever value this method returns is the actual value
    • -
    • assigned to *object.name.*
    • -
    • Description
    • -
    • ———–
    • -
    • This method *must be implemented by subclasses of TraitHandler. It is*
    • -
    • called whenever a new value is assigned to a trait attribute defined
    • -
    • using this trait handler.
    • -
    • If the value received by validate() is not valid for the trait
    • -
    • attribute, the method must called the predefined error() method to
    • -
    • raise a TraitError exception
    • +validate(object, name, value)[source] +

      Verifies whether a new value assigned to a trait attribute is +valid.

      +

      This method must be implemented by subclasses of TraitHandler. It is +called whenever a new value is assigned to a trait attribute defined +using this trait handler.

      +

      If the value received by validate() is not valid for the trait +attribute, the method must called the predefined error() method to +raise a TraitError exception

      +
      +
      Parameters
      +
        +
      • object (HasTraits instance) – The object whose attribute is being assigned.

      • +
      • name (str) – The name of the attribute being assigned.

      • +
      • value (any) – The proposed new value for the attribute.

      -

      -
    +
    +
    Returns
    +

    If the new value is valid, this method must return either the +original value passed to it, or an alternate value to be assigned +in place of the original value. Whatever value this method returns +is the actual value assigned to object.name.

    +
    +
    Return type
    +

    any

    +
    +
    -validate_failed(object, name, value)[source]
    +validate_failed(object, name, value)[source]
    @@ -233,24 +219,22 @@

    Table of Contents

    Previous topic

    -

    apptools.naming.adapter package

    +

    apptools.naming package

    Next topic

    -

    apptools.naming.ui package

    +

    apptools.persistence package

    This Page

    @@ -274,10 +258,10 @@

    Quick search

    © Copyright 2008-2020, Enthought
  • - Last updated on Jun 12, 2020. + Last updated on Dec 17, 2020.
  • - Created using Sphinx 1.8.5. + Created using Sphinx 2.3.1.
  • diff --git a/api/apptools.persistence.html b/api/apptools.persistence.html index ea6967ed4..8640a7d0b 100644 --- a/api/apptools.persistence.html +++ b/api/apptools.persistence.html @@ -13,9 +13,11 @@ @@ -31,7 +33,7 @@ - +
    @@ -70,7 +72,7 @@ accesskey="N">next
  • - previous
  • @@ -84,7 +86,7 @@
    -
    +

    apptools.persistence package

    @@ -97,7 +99,7 @@

    Submodules
    -class apptools.persistence.file_path.FilePath(value='')[source]
    +class apptools.persistence.file_path.FilePath(value='')[source]

    Bases: object

    This class stores two paths to the file. A relative path and an absolute one. The absolute path is used by the end user. When @@ -107,26 +109,26 @@

    Submodules
    -get()[source]
    +get()[source]

    Get the path.

    -set(value)[source]
    +set(value)[source]

    Sets the value of the path.

    -set_absolute(base_f_name)[source]
    +set_absolute(base_f_name)[source]

    Sets the absolute file name for the current relative file name with respect to the given base_f_name.

    -set_relative(base_f_name)[source]
    +set_relative(base_f_name)[source]

    Sets the path relative to base_f_name. Note that base_f_name and self.rel_pth should be valid file names correct on the current os. The set name is a file name that @@ -140,14 +142,14 @@

    Submodules

    apptools.persistence.project_loader module

    -apptools.persistence.project_loader.load_project(pickle_filename, updater_path, application_version, protocol, max_pass=-1)[source]
    +apptools.persistence.project_loader.load_project(pickle_filename, updater_path, application_version, protocol, max_pass=-1)[source]

    Reads a project from a pickle file and if necessary will update it to the latest version of the application.

    -apptools.persistence.project_loader.upgrade_project(pickle_filename, updater_path, project_version, application_version, protocol, max_pass=-1)[source]
    +apptools.persistence.project_loader.upgrade_project(pickle_filename, updater_path, project_version, application_version, protocol, max_pass=-1)[source]

    Repeatedly read and write the project to disk updating it one version at a time.

    Example the p5.project is at version 0 @@ -159,9 +161,6 @@

    Submodules -

    apptools.persistence.spickle module

    apptools.persistence.state_pickler module

    @@ -227,10 +226,10 @@

    apptools.persistence.spickle module

      -
    • The output is a plain old dictionary so is easy to parse, edit etc.
    • -
    • Handles references to avoid duplication.
    • -
    • Gzips Numeric arrays when dumping them.
    • -
    • Support for versioning.
    • +
    • The output is a plain old dictionary so is easy to parse, edit etc.

    • +
    • Handles references to avoid duplication.

    • +
    • Gzips Numeric arrays when dumping them.

    • +
    • Support for versioning.

    @@ -238,12 +237,12 @@

    Features

      -
    • Does not pickle a whole bunch of stuff including code objects and -functions.
    • -
    • The output is a pure dictionary and does not contain instances. So +
    • Does not pickle a whole bunch of stuff including code objects and +functions.

    • +
    • The output is a pure dictionary and does not contain instances. So using this as it is in __setstate__ will not work. Instead define a __set_pure_state__ and use the StateSetter class or -the set_state function provided by this module.

    • +the set_state function provided by this module.

    Notes

    @@ -251,7 +250,7 @@

    Caveats
    -class apptools.persistence.state_pickler.State(**kw)[source]
    +class apptools.persistence.state_pickler.State(**kw)[source]

    Bases: dict

    Used to encapsulate the state of an instance in a very convenient form. The ‘__metadata__’ attribute/key is a dictionary @@ -261,7 +260,7 @@

    Caveats
    -class apptools.persistence.state_pickler.StateDict(**kw)[source]
    +class apptools.persistence.state_pickler.StateDict(**kw)[source]

    Bases: dict

    Used to encapsulate a dictionary stored in a State instance. The has_instance attribute specifies if the dict has an instance @@ -270,7 +269,7 @@

    Caveats
    -class apptools.persistence.state_pickler.StateList(seq=None)[source]
    +class apptools.persistence.state_pickler.StateList(seq=None)[source]

    Bases: list

    Used to encapsulate a list stored in a State instance. The has_instance attribute specifies if the list has an instance @@ -279,14 +278,14 @@

    Caveats
    -class apptools.persistence.state_pickler.StatePickler[source]
    +class apptools.persistence.state_pickler.StatePickler[source]

    Bases: object

    Pickles the state of an object into a dictionary. The dictionary is itself either saved as a pickled file (dump) or pickled string (dumps). Alternatively, the dump_state method will return the dictionary that is pickled.

    The format of the state dict is quite strightfoward. Basic types -(bool, int, long, float, complex, None, string and unicode) are +(bool, int, long, float, complex, None, string) are represented as they are. Everything else is stored as a dictionary containing metadata information on the object’s type etc. and also the actual object in the ‘data’ key. For example:

    @@ -324,14 +323,14 @@

    Caveats
    -dump(value, file)[source]
    +dump(value, file)[source]

    Pickles the state of the object (value) into the passed file.

    -dump_state(value)[source]
    +dump_state(value)[source]

    Returns a dictionary or a basic type representing the complete state of the object (value).

    This value is pickled by the dump and dumps methods.

    @@ -339,7 +338,7 @@

    Caveats
    -dumps(value)[source]
    +dumps(value)[source]

    Pickles the state of the object (value) and returns a string.

    @@ -348,13 +347,13 @@

    Caveats
    -exception apptools.persistence.state_pickler.StatePicklerError[source]
    +exception apptools.persistence.state_pickler.StatePicklerError[source]

    Bases: Exception

    -class apptools.persistence.state_pickler.StateSetter[source]
    +class apptools.persistence.state_pickler.StateSetter[source]

    Bases: object

    This is a convenience class that helps a user set the attributes of an object given its saved state. For instances it @@ -362,7 +361,7 @@

    Caveats
    -set(obj, state, ignore=None, first=None, last=None)[source]
    +set(obj, state, ignore=None, first=None, last=None)[source]

    Sets the state of the object.

    This is to be used as a means to simplify loading the state of an object from its __setstate__ method using the dictionary @@ -370,41 +369,37 @@

    Caveats - - - -Parameters:
      -
    • obj (-) – The object whose state is to be set. If this is None -(default) then the object is created.
    • -
    • state (-) – The dictionary representing the state of the object.
    • -
    • ignore (-) – The list of attributes specified in this list are ignored +
      +
      Parameters
      +
        +
      • obj (-) – The object whose state is to be set. If this is None +(default) then the object is created.

      • +
      • state (-) – The dictionary representing the state of the object.

      • +
      • ignore (-) – The list of attributes specified in this list are ignored and the state of these attributes are not set (this excludes the ones specified in first and last). If one specifies a ‘*’ then all attributes are ignored except the ones -specified in first and last.

      • -
      • first (-) – The list of attributes specified in this list are set first (in -order), before any other attributes are set.
      • -
      • last (-) – The list of attributes specified in this list are set last (in -order), after all other attributes are set.
      • +specified in first and last.

        +
      • first (-) – The list of attributes specified in this list are set first (in +order), before any other attributes are set.

      • +
      • last (-) – The list of attributes specified in this list are set last (in +order), after all other attributes are set.

      - - - - +
      +

    -exception apptools.persistence.state_pickler.StateSetterError[source]
    +exception apptools.persistence.state_pickler.StateSetterError[source]

    Bases: Exception

    -class apptools.persistence.state_pickler.StateTuple[source]
    +class apptools.persistence.state_pickler.StateTuple[source]

    Bases: tuple

    Used to encapsulate a tuple stored in a State instance. The has_instance attribute specifies if the tuple has an instance @@ -413,7 +408,7 @@

    Caveats
    -class apptools.persistence.state_pickler.StateUnpickler[source]
    +class apptools.persistence.state_pickler.StateUnpickler[source]

    Bases: object

    Unpickles the state of an object saved using StatePickler.

    Please note that unlike the standard Unpickler, no instances of @@ -451,14 +446,14 @@

    Caveats
    -load_state(file)[source]
    +load_state(file)[source]

    Returns the state of an object loaded from the pickled data in the given file.

    -loads_state(string)[source]
    +loads_state(string)[source]

    Returns the state of an object loaded from the pickled data in the given string.

    @@ -467,32 +462,32 @@

    Caveats
    -exception apptools.persistence.state_pickler.StateUnpicklerError[source]
    +exception apptools.persistence.state_pickler.StateUnpicklerError[source]

    Bases: Exception

    -apptools.persistence.state_pickler.create_instance(state)[source]
    +apptools.persistence.state_pickler.create_instance(state)[source]

    Create an instance from the state if possible.

    -apptools.persistence.state_pickler.dump(value, file)[source]
    +apptools.persistence.state_pickler.dump(value, file)[source]

    Pickles the state of the object (value) into the passed file (or file name).

    -apptools.persistence.state_pickler.dumps(value)[source]
    +apptools.persistence.state_pickler.dumps(value)[source]

    Pickles the state of the object (value) and returns a string.

    -apptools.persistence.state_pickler.get_state(obj)[source]
    +apptools.persistence.state_pickler.get_state(obj)[source]

    Returns the state of the object (usually as a dictionary). The returned state may be used directy to set the state of the object via set_state.

    @@ -500,34 +495,34 @@

    Caveats
    -apptools.persistence.state_pickler.gunzip_string(data)[source]
    +apptools.persistence.state_pickler.gunzip_string(data)[source]

    Given a gzipped string (data) this unzips the string and returns it.

    -apptools.persistence.state_pickler.gzip_string(data)[source]
    +apptools.persistence.state_pickler.gzip_string(data)[source]

    Given a string (data) this gzips the string and returns it.

    -apptools.persistence.state_pickler.load_state(file)[source]
    +apptools.persistence.state_pickler.load_state(file)[source]

    Returns the state of an object loaded from the pickled data in the given file (or file name).

    -apptools.persistence.state_pickler.loads_state(string)[source]
    +apptools.persistence.state_pickler.loads_state(string)[source]

    Returns the state of an object loaded from the pickled data in the given string.

    -apptools.persistence.state_pickler.set_state(obj, state, ignore=None, first=None, last=None)[source]
    +apptools.persistence.state_pickler.set_state(obj, state, ignore=None, first=None, last=None)[source]

    Sets the state of the object.

    This is to be used as a means to simplify loading the state of an object from its __setstate__ method using the dictionary @@ -535,33 +530,29 @@

    Caveats - - - -Parameters:
      -
    • obj (-) – The object whose state is to be set. If this is None -(default) then the object is created.
    • -
    • state (-) – The dictionary representing the state of the object.
    • -
    • ignore (-) – The list of attributes specified in this list are ignored +
      +
      Parameters
      +
        +
      • obj (-) – The object whose state is to be set. If this is None +(default) then the object is created.

      • +
      • state (-) – The dictionary representing the state of the object.

      • +
      • ignore (-) – The list of attributes specified in this list are ignored and the state of these attributes are not set (this excludes the ones specified in first and last). If one specifies a ‘*’ then all attributes are ignored except the ones -specified in first and last.

      • -
      • first (-) – The list of attributes specified in this list are set first (in -order), before any other attributes are set.
      • -
      • last (-) – The list of attributes specified in this list are set last (in -order), after all other attributes are set.
      • +specified in first and last.

        +
      • first (-) – The list of attributes specified in this list are set first (in +order), before any other attributes are set.

      • +
      • last (-) – The list of attributes specified in this list are set last (in +order), after all other attributes are set.

      - - - - +
      +

    -apptools.persistence.state_pickler.update_state(state)[source]
    +apptools.persistence.state_pickler.update_state(state)[source]

    Given the state of an object, this updates the state to the latest version using the handlers given in the version registry. The state is modified in-place.

    @@ -573,12 +564,12 @@

    Caveats

    apptools.persistence.updater module

    -class apptools.persistence.updater.Updater[source]
    +class apptools.persistence.updater.Updater[source]

    Bases: object

    An abstract class to provide functionality common to the updaters.

    -get_latest(module, name)[source]
    +get_latest(module, name)[source]

    The refactorings dictionary contains mappings between old and new module names. Since we only bump the version number one increment there is only one possible answer.

    @@ -586,7 +577,7 @@

    Caveats
    -strip(string)[source]
    +strip(string)[source]

    @@ -598,7 +589,7 @@

    Caveats
    -class apptools.persistence.version_registry.HandlerRegistry[source]
    +class apptools.persistence.version_registry.HandlerRegistry[source]

    Bases: object

    A simple version conversion handler registry. Classes register handlers in order to convert the state version to the latest @@ -609,7 +600,7 @@

    Caveats
    -register(class_name, module, handler)[source]
    +register(class_name, module, handler)[source]

    Register handler that handles versioning for class having class name (class_name) and module name (module). The handler function will be passed the state and its version to fix.

    @@ -617,13 +608,13 @@

    Caveats
    -unregister(class_name, module)[source]
    +unregister(class_name, module)[source]

    Unregisters any handlers for a class and module.

    -update(state)[source]
    +update(state)[source]

    Updates the given state using the handlers. Note that the state is modified in-place.

    @@ -632,7 +623,7 @@

    Caveats
    -apptools.persistence.version_registry.get_version(obj)[source]
    +apptools.persistence.version_registry.get_version(obj)[source]

    Walks the class hierarchy and obtains the versions of the various classes and returns a list of tuples of the form ((class_name, module), version) in reverse order of the MRO.

    @@ -643,34 +634,34 @@

    Caveats

    apptools.persistence.versioned_unpickler module

    -class apptools.persistence.versioned_unpickler.NewUnpickler[source]
    -

    Bases: _pickle.Unpickler

    +class apptools.persistence.versioned_unpickler.NewUnpickler(file, *, fix_imports=True, encoding='ASCII', errors='strict')[source] +

    Bases: pickle._Unpickler

    An unpickler that implements a two-stage pickling process to make it possible to unpickle complicated Python object hierarchies where the unserialized state of an object depends on the state of other objects in the same pickle.

    -initialize(max_pass)[source]
    +initialize(max_pass)[source]
    -load(max_pass=-1)[source]
    +load(max_pass=-1)[source]

    Read a pickled object representation from the open file.

    Return the reconstituted object hierarchy specified in the file.

    -
    +
    -classmethod load_build(obj)[source]
    +classmethod load_build(obj)[source]
    -class apptools.persistence.versioned_unpickler.VersionedUnpickler(file, updater=None)[source]
    +class apptools.persistence.versioned_unpickler.VersionedUnpickler(file, updater=None)[source]

    Bases: apptools.persistence.versioned_unpickler.NewUnpickler

    This class reads in a pickled file created at revision version ‘n’ and then applies the transforms specified in the updater class to @@ -682,27 +673,27 @@

    Caveats
    -add_updater(module, name, klass)[source]
    +add_updater(module, name, klass)[source]

    If there is an updater defined for this class we will add it to the class as the __setstate__ method.

    -backup_setstate(module, klass)[source]
    +backup_setstate(module, klass)[source]

    If the class has a user defined __setstate__ we back it up.

    -find_class(module, name)[source]
    +find_class(module, name)[source]

    Overridden method from Unpickler.

    NB __setstate__ is not called until later.

    -import_name(module, name)[source]
    +import_name(module, name)[source]

    If the class is needed for the latest version of the application then it should presumably exist.

    If the class no longer exists then we should perhaps return @@ -737,7 +728,6 @@

    Table of Contents

  • Submodules
  • apptools.persistence.file_path module
  • apptools.persistence.project_loader module
  • -
  • apptools.persistence.spickle module
  • apptools.persistence.state_pickler module

    Previous topic

    -

    apptools.permissions.default package

    +

    apptools.naming.trait_defs package

    Next topic

    apptools.preferences package

    @@ -763,13 +753,11 @@

    This Page

    rel="nofollow">Show Source
  • @@ -793,10 +781,10 @@

    Quick search

    © Copyright 2008-2020, Enthought
  • - Last updated on Jun 12, 2020. + Last updated on Dec 17, 2020.
  • - Created using Sphinx 1.8.5. + Created using Sphinx 2.3.1.
  • diff --git a/api/apptools.preferences.html b/api/apptools.preferences.html index f3ddadb12..e7f3cde28 100644 --- a/api/apptools.preferences.html +++ b/api/apptools.preferences.html @@ -13,9 +13,11 @@ @@ -84,7 +86,7 @@
    -
    +

    apptools.preferences package

    @@ -100,7 +102,7 @@

    Subpackagesapptools.preferences.ui.preferences_node module
  • apptools.preferences.ui.preferences_page module
  • apptools.preferences.ui.tree_item module
  • -
  • apptools.preferences.ui.widget_editor module
  • +
  • apptools.preferences.ui.widget_editor module
  • Module contents
  • @@ -118,12 +120,12 @@

    Submodules
    -class apptools.preferences.i_preferences.IPreferences[source]
    +class apptools.preferences.i_preferences.IPreferences[source]

    Bases: traits.has_traits.Interface

    The interface for a node in a preferences hierarchy.

    -clear(path='')[source]
    +clear(path='')[source]

    Remove all preference from the node at the specified path.

    If the path is the empty string (the default) then remove the preferences in this node.

    @@ -140,14 +142,14 @@

    Submodules
    -flush()[source]
    +flush()[source]

    Force any changes in the node to the backing store.

    This includes any changes to the node’s descendants.

    -get(path, default=None, inherit=False)[source]
    +get(path, default=None, inherit=False)[source]

    Get the value of the preference at the specified path.

    If no value exists for the path (or any part of the path does not exist) then return the default value.

    @@ -179,7 +181,7 @@

    Submodules
    -keys(path='')[source]
    +keys(path='')[source]

    Return the preference keys of the node at the specified path.

    If the path is the empty string (the default) then return the preference keys of this node.

    @@ -191,7 +193,7 @@

    Submodules
    -node(path='')[source]
    +node(path='')[source]

    Return the node at the specified path.

    If the path is the empty string (the default) then return this node.

    Any missing nodes are created automatically.

    @@ -204,7 +206,7 @@

    Submodules
    -node_exists(path='')[source]
    +node_exists(path='')[source]

    Return True if the node at the specified path exists

    If the path is the empty string (the default) then return True.

    e.g:

    @@ -215,7 +217,7 @@

    Submodules
    -node_names(path='')[source]
    +node_names(path='')[source]

    Return the names of the children of the node at the specified path.

    If the path is the empty string (the default) then return the names of the children of this node.

    @@ -227,7 +229,7 @@

    Submodules
    -remove(path)[source]
    +remove(path)[source]

    Remove the preference at the specified path.

    Does nothing if no value exists for the path (or any part of the path does not exist.

    @@ -240,7 +242,7 @@

    Submodules
    -set(path, value)[source]
    +set(path, value)[source]

    Set the value of the preference at the specified path.

    Any missing nodes are created automatically.

    Primitive Python types can be set, but preferences are always @@ -271,13 +273,13 @@

    Submodules
    -apptools.preferences.package_globals.get_default_preferences()[source]
    +apptools.preferences.package_globals.get_default_preferences()[source]

    Get the default preferences node.

    -apptools.preferences.package_globals.set_default_preferences(default_preferences)[source]
    +apptools.preferences.package_globals.set_default_preferences(default_preferences)[source]

    Set the default preferences node.

    @@ -287,14 +289,14 @@

    Submodules
    -class apptools.preferences.preference_binding.PreferenceBinding(**traits)[source]
    +class apptools.preferences.preference_binding.PreferenceBinding(**traits)[source]

    Bases: traits.has_traits.HasTraits

    A binding between a trait on an object and a preference value.

    -apptools.preferences.preference_binding.bind_preference(obj, trait_name, preference_path, preferences=None)[source]
    +apptools.preferences.preference_binding.bind_preference(obj, trait_name, preference_path, preferences=None)[source]

    Create a new preference binding.

    @@ -304,49 +306,49 @@

    Submodules
    -class apptools.preferences.preferences.Preferences(**traits)[source]
    +class apptools.preferences.preferences.Preferences(**traits)[source]

    Bases: traits.has_traits.HasTraits

    The default implementation of a node in a preferences hierarchy.

    -add_preferences_listener(listener, path='')[source]
    +add_preferences_listener(listener, path='')[source]

    Add a listener for changes to a node’s preferences.

    -clear(path='')[source]
    +clear(path='')[source]

    Remove all preferences from the node at the specified path.

    -dump(indent='')[source]
    +dump(indent='')[source]

    Dump the preferences hierarchy to stdout.

    -flush()[source]
    +flush()[source]

    Force any changes in the node to the backing store.

    This includes any changes to the node’s descendants.

    -get(path, default=None, inherit=False)[source]
    +get(path, default=None, inherit=False)[source]

    Get the value of the preference at the specified path.

    -keys(path='')[source]
    +keys(path='')[source]

    Return the preference keys of the node at the specified path.

    -load(file_or_filename=None)[source]
    +load(file_or_filename=None)[source]

    Load preferences from a file.

    This is a merge operation i.e. the contents of the file are added to the node.

    @@ -355,44 +357,44 @@

    Submodules
    -node(path='')[source]
    +node(path='')[source]

    Return the node at the specified path.

    -node_exists(path='')[source]
    +node_exists(path='')[source]

    Return True if the node at the specified path exists.

    -node_names(path='')[source]
    +node_names(path='')[source]

    Return the names of the children of the node at the specified path.

    -remove(path)[source]
    +remove(path)[source]

    Remove the preference at the specified path.

    -remove_preferences_listener(listener, path='')[source]
    +remove_preferences_listener(listener, path='')[source]

    Remove a listener for changes to a node’s preferences.

    -save(file_or_filename=None)[source]
    +save(file_or_filename=None)[source]

    Save the node’s preferences to a file.

    This implementation uses ‘ConfigObj’ files.

    -set(path, value)[source]
    +set(path, value)[source]

    Set the value of the preference at the specified path.

    @@ -404,9 +406,14 @@

    Submodules
    -class apptools.preferences.preferences_helper.PreferencesHelper(**traits)[source]
    +class apptools.preferences.preferences_helper.PreferencesHelper(**traits)[source]

    Bases: traits.has_traits.HasTraits

    -

    An object that can be initialized from a preferences node.

    +

    A base class for objects that can be initialized from a preferences +node.

    +

    Additional traits defined on subclasses will be listened to. Changes +are then synchronized with the preferences. Note that mutations on nested +containers e.g. List(List(Str)) cannot be synchronized and should be +avoided.

    @@ -415,7 +422,7 @@

    Submodules
    -class apptools.preferences.scoped_preferences.ScopedPreferences(**traits)[source]
    +class apptools.preferences.scoped_preferences.ScopedPreferences(**traits)[source]

    Bases: apptools.preferences.preferences.Preferences

    A preferences node that adds the notion of preferences scopes.

    Scopes provide a way to access preferences in a precedence order, usually @@ -425,25 +432,23 @@

    Submodules -
  • a preference path as used in a standard ‘Preferences’ node, e.g:

    -
    'acme.widget.bgcolor'.
    -
    -
    -

    In this case the operation either takes place in the primary scope -(for operations such as ‘set’ etc), or on all scopes in precedence order -(for operations such as ‘get’ etc).

    -
  • - -

    or

    -
      -
    1. a preference path that refers to a specific scope e.g:

      -
      'default/acme.widget.bgcolor'
      +
      a) a preference path as used in a standard 'Preferences' node, e.g::
      +
      +'acme.widget.bgcolor'.
      +
      +In this case the operation either takes place in the primary scope
      +(for operations such as 'set' etc), or on all scopes in precedence
      +order (for operations such as 'get' etc).
      +
      +or
      +
      +b) a preference path that refers to a specific scope e.g::
      +
      +'default/acme.widget.bgcolor'
      +
      +In this case the operation takes place *only* in the specified scope.
       
      -

      In this case the operation takes place only in the specified scope.

      -
    2. -

    There is one drawback to this scheme. If you want to access a scope node itself via the ‘clear’, ‘keys’, ‘node’, ‘node_exists’ or ‘node_names’ methods then you have to append a trailing ‘/’ to the path. Without that, @@ -469,44 +474,44 @@

    Submodules
    -add_preferences_listener(listener, path='')[source]
    +add_preferences_listener(listener, path='')[source]

    Add a listener for changes to a node’s preferences.

    -clear(path='')[source]
    +clear(path='')[source]

    Remove all preference from the node at the specified path.

    -dump(indent='')[source]
    +dump(indent='')[source]

    Dump the preferences hierarchy to stdout.

    -get(path, default=None, inherit=False)[source]
    +get(path, default=None, inherit=False)[source]

    Get the value of the preference at the specified path.

    -get_scope(scope_name)[source]
    +get_scope(scope_name)[source]

    Return the scope with the specified name.

    Return None if no such scope exists.

    -keys(path='')[source]
    +keys(path='')[source]

    Return the preference keys of the node at the specified path.

    -load(file_or_filename=None)[source]
    +load(file_or_filename=None)[source]

    Load preferences from a file.

    This loads the preferences into the primary scope.

    fixme: I’m not sure it is worth providing an implentation here. I @@ -516,37 +521,37 @@

    Submodules
    -node(path='')[source]
    +node(path='')[source]

    Return the node at the specified path.

    -node_exists(path='')[source]
    +node_exists(path='')[source]

    Return True if the node at the specified path exists.

    -node_names(path='')[source]
    +node_names(path='')[source]

    Return the names of the children of the node at the specified path.

    -remove(path)[source]
    +remove(path)[source]

    Remove the preference at the specified path.

    -remove_preferences_listener(listener, path='')[source]
    +remove_preferences_listener(listener, path='')[source]

    Remove a listener for changes to a node’s preferences.

    -save(file_or_filename=None)[source]
    +save(file_or_filename=None)[source]

    Save the node’s preferences to a file.

    This asks each scope in turn to save its preferences.

    If a file or filename is specified then it is only passed to the @@ -555,7 +560,7 @@

    Submodules
    -set(path, value)[source]
    +set(path, value)[source]

    Set the value of the preference at the specified path.

    @@ -607,13 +612,11 @@

    This Page

    rel="nofollow">Show Source

    @@ -637,10 +640,10 @@

    Quick search

    © Copyright 2008-2020, Enthought
  • - Last updated on Jun 12, 2020. + Last updated on Dec 17, 2020.
  • - Created using Sphinx 1.8.5. + Created using Sphinx 2.3.1.
  • diff --git a/api/apptools.preferences.ui.html b/api/apptools.preferences.ui.html index 237700746..fa72bce2b 100644 --- a/api/apptools.preferences.ui.html +++ b/api/apptools.preferences.ui.html @@ -13,9 +13,11 @@ @@ -85,7 +87,7 @@
    -
    +

    apptools.preferences.ui package

    @@ -100,12 +102,12 @@

    Submodules
    -class apptools.preferences.ui.i_preferences_page.IPreferencesPage[source]
    +class apptools.preferences.ui.i_preferences_page.IPreferencesPage[source]

    Bases: traits.has_traits.Interface

    The interface for pages in a preferences dialog.

    -apply()[source]
    +apply()[source]

    Apply the page’s preferences.

    @@ -117,12 +119,12 @@

    Submodules
    -class apptools.preferences.ui.preferences_manager.PreferencesHelpWindow[source]
    +class apptools.preferences.ui.preferences_manager.PreferencesHelpWindow[source]

    Bases: traits.has_traits.HasTraits

    Container class to present a view with string info.

    -traits_view()[source]
    +traits_view()[source]

    Default view to show for this class.

    @@ -130,18 +132,18 @@

    Submodules
    -class apptools.preferences.ui.preferences_manager.PreferencesManager[source]
    +class apptools.preferences.ui.preferences_manager.PreferencesManager[source]

    Bases: traits.has_traits.HasTraits

    The preferences manager.

    -apply()[source]
    +apply()[source]

    Apply all changes made in the manager.

    -traits_view()[source]
    +traits_view()[source]

    Default traits view for this class.

    @@ -149,30 +151,30 @@

    Submodules
    -class apptools.preferences.ui.preferences_manager.PreferencesManagerHandler[source]
    +class apptools.preferences.ui.preferences_manager.PreferencesManagerHandler[source]

    Bases: traitsui.handler.Handler

    The traits UI handler for the preferences manager.

    -apply(info)[source]
    +apply(info)[source]

    Handle the Apply button being clicked.

    -close(info, is_ok)[source]
    +close(info, is_ok)[source]

    Close a dialog-based user interface.

    -init(info)[source]
    +init(info)[source]

    Initialize the controls of a user interface.

    -preferences_help(info)[source]
    +preferences_help(info)[source]

    Custom preferences help panel. The Traits help doesn’t work.

    @@ -184,26 +186,26 @@

    Submodules
    -class apptools.preferences.ui.preferences_node.PreferencesNode[source]
    +class apptools.preferences.ui.preferences_node.PreferencesNode[source]

    Bases: apptools.preferences.ui.tree_item.TreeItem

    Abstract base class for a node in a preferences dialog.

    A preferences node has a name and an image which are used to represent the node in a preferences dialog (usually in the form of a tree).

    -create_page(parent)[source]
    +create_page(parent)[source]

    Creates the preference page for this node.

    -dump(indent='')[source]
    +dump(indent='')[source]

    Pretty-print the node to stdout.

    -lookup(name)[source]
    +lookup(name)[source]

    Returns the child of this node with the specified Id.

    Returns None if no such child exists.

    @@ -216,12 +218,12 @@

    Submodules
    -class apptools.preferences.ui.preferences_page.PreferencesPage(**traits)[source]
    +class apptools.preferences.ui.preferences_page.PreferencesPage(**traits)[source]

    Bases: apptools.preferences.preferences_helper.PreferencesHelper

    A page in a preferences dialog.

    -apply()[source]
    +apply()[source]

    Apply the page’s preferences.

    @@ -245,48 +247,80 @@

    Submodules
    -class apptools.preferences.ui.tree_item.TreeItem[source]
    +class apptools.preferences.ui.tree_item.TreeItem[source]

    Bases: traits.has_traits.HasTraits

    A generic base-class for items in a tree data structure.

    -append(child)[source]
    +append(child)[source]

    Appends a child to this item.

    This removes the child from its current parent (if it has one).

    -insert(index, child)[source]
    +insert(index, child)[source]

    Inserts a child into this item at the specified index.

    This removes the child from its current parent (if it has one).

    -insert_after(after, child)[source]
    +insert_after(after, child)[source]

    Inserts a child into this item after the specified item.

    This removes the child from its current parent (if it has one).

    -insert_before(before, child)[source]
    +insert_before(before, child)[source]

    Inserts a child into this item before the specified item.

    This removes the child from its current parent (if it has one).

    -remove(child)[source]
    +remove(child)[source]

    Removes a child from this item.

    -
    -

    apptools.preferences.ui.widget_editor module

    +
    +

    apptools.preferences.ui.widget_editor module

    +

    An instance editor that allows total control over widget creation.

    +
    +
    +class apptools.preferences.ui.widget_editor.WidgetEditor(*args, **traits)[source]
    +

    Bases: traitsui.editor_factory.EditorFactory

    +

    A factory widget editors.

    +
    +
    +custom_editor(ui, object, name, description, parent)
    +

    Create a simple editor.

    +
    + +
    +
    +readonly_editor(ui, object, name, description, parent)
    +

    Create a simple editor.

    +
    + +
    +
    +simple_editor(ui, object, name, description, parent)[source]
    +

    Create a simple editor.

    +
    + +
    +
    +text_editor(ui, object, name, description, parent)
    +

    Create a simple editor.

    +
    + +
    +
    @@ -360,10 +392,10 @@

    Quick search

    © Copyright 2008-2020, Enthought
  • - Last updated on Jun 12, 2020. + Last updated on Dec 17, 2020.
  • - Created using Sphinx 1.8.5. + Created using Sphinx 2.3.1.
  • diff --git a/api/apptools.scripting.html b/api/apptools.scripting.html index ec7c7b92d..8ec515512 100644 --- a/api/apptools.scripting.html +++ b/api/apptools.scripting.html @@ -13,9 +13,11 @@ @@ -84,7 +86,7 @@
    -
    +

    apptools.scripting package

    @@ -100,14 +102,14 @@

    Submodules
    -apptools.scripting.package_globals.get_recorder()[source]
    +apptools.scripting.package_globals.get_recorder()[source]

    Return the global recorder. Does not create a new one if none exists.

    -apptools.scripting.package_globals.set_recorder(rec)[source]
    +apptools.scripting.package_globals.set_recorder(rec)[source]

    Set the global recorder instance.

    @@ -117,73 +119,81 @@

    Submodules
    -apptools.scripting.recordable.recordable(func)[source]
    +apptools.scripting.recordable.recordable(func)[source]

    A decorator that wraps a function into one that is recordable.

    This will record the function only if the global recorder has been set via a set_recorder function call.

    -

    This is almost entirely copied from the -apptools.appscripting.scriptable.scriptable decorator.

    apptools.scripting.recorder module

    Code to support recording to a readable and executable Python script.

    +
    +
    FIXME:
      +
    • Support for dictionaries?

    • +
    +
    +
    -class apptools.scripting.recorder.Recorder[source]
    +class apptools.scripting.recorder.Recorder[source]

    Bases: traits.has_traits.HasTraits

    -clear()[source]
    +clear()[source]

    Clears all previous recorded state and unregisters all registered objects.

    -get_code()[source]
    +get_code()[source]

    Returns the recorded lines as a string of printable code.

    -get_object_path(object)[source]
    +get_object_path(object)[source]

    Returns the path in the object hierarchy of a registered object. Useful for debugging.

    -get_script_id(object)[source]
    +get_script_id(object)[source]

    Returns the script_id of a registered object. Useful when you want to manually add a record statement.

    -is_registered(object)[source]
    +is_registered(object)[source]

    Returns True if the given object is registered with the recorder.

    -record(code)[source]
    +record(code)[source]

    Record a string to be stored to the output file.

    -

    code - A string of text.

    +
    +
    Parameters
    +

    code (str) – A string of text.

    +
    +
    -record_function(func, args, kw)[source]
    +record_function(func, args, kw)[source]

    Record a function call given the function and its arguments.

    -register(object, parent=None, trait_name_on_parent='', ignore=None, known=False, script_id=None)[source]
    +register(object, parent=None, trait_name_on_parent='', ignore=None, known=False, script_id=None)[source]

    Register an object with the recorder. This sets up the object for recording.

    By default all traits (except those starting and ending with @@ -191,61 +201,59 @@

    Submodules -
  • If metadata record=False is set, the nested object will not be -recorded.
  • -
  • If record=True, then that object is also recorded if it is -not None.
  • +
  • If metadata record=False is set, the nested object will not be +recorded.

  • +
  • If record=True, then that object is also recorded if it is +not None.

  • If the object is a list or dict that is marked with record=True, the list is itself not listened to for changes but all its contents are registered.

    If the object has a trait named recorder then this recorder instance will be set to it if possible.

    -
    -
    object : Instance(HasTraits)
    -
    The object to register in the registry.
    -
    parent : Instance(HasTraits)
    -
    An optional parent object in which object is contained
    -
    trait_name_on_parent : str
    -
    An optional trait name of the object in the parent.
    -
    ignore : list(str)
    -
    An optional list of trait names on the object to be -ignored.
    -
    known : bool
    -
    Optional specification if the object id is known on the +
    +
    Parameters
    +
      +
    • object (Instance(HasTraits)) – The object to register in the registry.

    • +
    • parent (Instance(HasTraits)) – An optional parent object in which object is contained

    • +
    • trait_name_on_parent (str) – An optional trait name of the object in the parent.

    • +
    • ignore (list(str)) – An optional list of trait names on the object to be +ignored.

    • +
    • known (bool) – Optional specification if the object id is known on the interpreter. This is needed if you are manually injecting -code to define/create an object.

    -
    script_id : str
    -
    Optionally specify a script_id to use for this object. It +code to define/create an object.

    +
  • script_id (str) – Optionally specify a script_id to use for this object. It is not guaranteed that this ID will be used since it may -already be in use.

  • +already be in use.

    + +

    -save(file)[source]
    +save(file)[source]

    Save the recorded lines to the given file. It does not close the file.

    -ui_save()[source]
    +ui_save()[source]

    Save recording to file, pop up a UI dialog to find out where and close the file when done.

    -unregister(object)[source]
    +unregister(object)[source]

    Unregister the given object from the recorder. This inverts the logic of the register(…) method.

    -write_script_id_in_namespace(script_id)[source]
    +write_script_id_in_namespace(script_id)[source]

    If a script_id is not known in the current script’s namespace, this sets it using the path of the object or actually instantiating it. If this is not possible (since the script_id @@ -259,7 +267,7 @@

    Submodules
    -exception apptools.scripting.recorder.RecorderError[source]
    +exception apptools.scripting.recorder.RecorderError[source]

    Bases: Exception

    @@ -269,12 +277,12 @@

    Submodules
    -class apptools.scripting.recorder_with_ui.CloseHandler[source]
    +class apptools.scripting.recorder_with_ui.CloseHandler[source]

    Bases: traitsui.handler.Handler

    This class cleans up after the UI for the recorder is closed.

    -close(info, is_ok)[source]
    +close(info, is_ok)[source]

    This method is invoked when the user closes the UI.

    @@ -282,12 +290,12 @@

    Submodules
    -class apptools.scripting.recorder_with_ui.RecorderWithUI[source]
    +class apptools.scripting.recorder_with_ui.RecorderWithUI[source]

    Bases: apptools.scripting.recorder.Recorder

    This class represents a Recorder but with a simple user interface.

    -on_ui_close()[source]
    +on_ui_close()[source]

    Called from the CloseHandler when the UI is closed. This method basically stops the recording.

    @@ -300,17 +308,23 @@

    Submodules
    -apptools.scripting.util.start_recording(object, ui=True, **kw)[source]
    +apptools.scripting.util.start_recording(object, ui=True, **kw)[source]

    Convenience function to start recording. Returns the recorder.

    -

    object : object to record.

    -

    ui : bool specifying if a UI is to be shown or not

    -

    kw : Keyword arguments to pass to the register function of the -recorder.

    +
    +
    Parameters
    +
      +
    • object (object to record.) –

    • +
    • ui (bool specifying if a UI is to be shown or not) –

    • +
    • kw (Keyword arguments to pass to the register function of the) –

    • +
    • recorder.

    • +
    +
    +

    -apptools.scripting.util.stop_recording(object, save=True)[source]
    +apptools.scripting.util.stop_recording(object, save=True)[source]

    Stop recording the object. If save is True, this will pop up a UI to ask where to save the script.

    @@ -359,13 +373,11 @@

    This Page

    rel="nofollow">Show Source
    @@ -389,10 +401,10 @@

    Quick search

    © Copyright 2008-2020, Enthought
  • - Last updated on Jun 12, 2020. + Last updated on Dec 17, 2020.
  • - Created using Sphinx 1.8.5. + Created using Sphinx 2.3.1.
  • diff --git a/api/apptools.selection.html b/api/apptools.selection.html index 234176a75..a8950c469 100644 --- a/api/apptools.selection.html +++ b/api/apptools.selection.html @@ -13,9 +13,11 @@ @@ -30,7 +32,7 @@ - + @@ -66,7 +68,7 @@ >modules
  • - next
  • @@ -84,7 +86,7 @@
    -
    +

    apptools.selection package

    @@ -98,21 +100,21 @@

    Submodules

    apptools.selection.errors module

    -exception apptools.selection.errors.IDConflictError(provider_id)[source]
    +exception apptools.selection.errors.IDConflictError(provider_id)[source]

    Bases: Exception

    Raised when a provider is added and its ID is already registered.

    -exception apptools.selection.errors.ListenerNotConnectedError(provider_id, listener)[source]
    +exception apptools.selection.errors.ListenerNotConnectedError(provider_id, listener)[source]

    Bases: Exception

    Raised when a listener that was never connected is disconnected.

    -exception apptools.selection.errors.ProviderNotRegisteredError(provider_id)[source]
    +exception apptools.selection.errors.ProviderNotRegisteredError(provider_id)[source]

    Bases: Exception

    Raised when a provider is requested by ID and not found.

    @@ -122,18 +124,18 @@

    Submodules

    apptools.selection.i_selection module

    -class apptools.selection.i_selection.IListSelection[source]
    -

    Bases: apptools.selection.i_selection.ISelection

    +class apptools.selection.i_selection.IListSelection[source] +

    Bases: apptools.selection.i_selection.ISelection

    Selection for ordered sequences of items.

    -indices = List
    +indices = List

    Indices of the selected objects in the selection provider.

    -items = List
    +items = List

    Selected objects.

    @@ -141,18 +143,18 @@

    Submodules
    -class apptools.selection.i_selection.ISelection[source]
    +class apptools.selection.i_selection.ISelection[source]

    Bases: traits.has_traits.Interface

    Collection of selected items.

    -is_empty()[source]
    +is_empty()[source]

    Is the selection empty?

    -provider_id = Str
    +provider_id = Str

    ID of the selection provider that created this selection object.

    @@ -163,62 +165,55 @@

    Submodules

    apptools.selection.i_selection_provider module

    -class apptools.selection.i_selection_provider.ISelectionProvider[source]
    +class apptools.selection.i_selection_provider.ISelectionProvider[source]

    Bases: traits.has_traits.Interface

    Source of selections.

    -get_selection()[source]
    +get_selection()[source]

    Return the current selection.

    - --- - - - -
    Returns:
    -
    selection – ISelection
    -
    Object representing the current selection.
    +
    +
    Returns
    +

    +
    selection – ISelection

    Object representing the current selection.

    +
    +
    +

    +
    -
    -provider_id = Str()
    +provider_id = Str()

    Unique ID identifying the provider.

    -selection = Event
    +selection = Event

    Event triggered when the selection changes. -The content of the event is an ISelection instance.

    +The content of the event is an ISelection instance.

    -set_selection(items, ignore_missing=False)[source]
    +set_selection(items, ignore_missing=False)[source]

    Set the current selection to the given items.

    If ignore_missing is True, items that are not available in the selection provider are silently ignored. If it is False (default), an ValueError should be raised.

    - --- - - - -
    Parameters:
      -
    • -- list (items) – List of items to be selected.
    • -
    • -- bool (ignore_missing) – If False (default), the provider raises an exception if any +
      +
      Parameters
      +
        +
      • -- list (items) – List of items to be selected.

      • +
      • -- bool (ignore_missing) – If False (default), the provider raises an exception if any of the items in items is not available to be selected. Otherwise, missing elements are silently ignored, and the rest -is selected.

      • +is selected.

      -
    +
    +

    @@ -228,48 +223,48 @@

    Submodules

    apptools.selection.list_selection module

    -class apptools.selection.list_selection.ListSelection[source]
    +class apptools.selection.list_selection.ListSelection[source]

    Bases: traits.has_traits.HasTraits

    Selection for ordered sequences of items.

    -

    This is the default implementation of the IListSelection +

    This is the default implementation of the IListSelection interface.

    -
    +
    -classmethod from_available_items(provider_id, selected, all_items)[source]
    +classmethod from_available_items(provider_id, selected, all_items)[source]

    Create a list selection given a list of all available items.

    Fills in the required information (in particular, the indices) based on a list of selected items and a list of all available items.

    -

    Note

    -
      -
    • The list of available items must not contain any duplicate items.
    • -
    • It is expected that selected is populated by items in -all_items.
    • +

      Note

      +
        +
      • The list of available items must not contain any duplicate items.

      • +
      • It is expected that selected is populated by items in +all_items.

    -indices = List
    +indices = List

    Indices of the selected objects in the selection provider.

    -is_empty()[source]
    +is_empty()[source]

    Is the selection empty?

    -items = List
    +items = List

    Selected objects.

    -provider_id = Str
    +provider_id = Str

    ID of the selection provider that created this selection object.

    @@ -280,7 +275,7 @@

    Submodules

    apptools.selection.selection_service module

    -class apptools.selection.selection_service.SelectionService[source]
    +class apptools.selection.selection_service.SelectionService[source]

    Bases: traits.has_traits.HasTraits

    The selection service connects selection providers and listeners.

    The selection service is a register of selection providers, i.e., objects @@ -290,136 +285,116 @@

    Submodules
    -add_selection_provider(provider)[source]
    +add_selection_provider(provider)[source]

    Add a selection provider.

    The provider is identified by its ID. If a provider with the same -ID has been already registered, an IDConflictError +ID has been already registered, an IDConflictError is raised.

    - --- - - - -
    Parameters:-- ISelectionProvider (provider) – The selection provider added to the internal registry.
    +
    +
    Parameters
    +

    -- ISelectionProvider (provider) – The selection provider added to the internal registry.

    +
    +

    -connect_selection_listener(provider_id, func)[source]
    +connect_selection_listener(provider_id, func)[source]

    Connect a listener to selection events from a specific provider.

    The signature if the listener callback is func(i_selection). The listener is called:

      -
    1. When a provider with the given ID is registered, with its initial -selection as argument, or
    2. -
    3. whenever the provider fires a selection event.
    4. +
    5. When a provider with the given ID is registered, with its initial +selection as argument, or

    6. +
    7. whenever the provider fires a selection event.

    It is perfectly valid to connect a listener before a provider with the given ID is registered. The listener will remain connected even if the provider is repeatedly connected and disconnected.

    - --- - - - -
    Parameters:
      -
    • -- str (provider_id) – The selection provider ID.
    • -
    • -- callable (func) – A callable object that is notified when the selection changes.
    • +
      +
      Parameters
      +
        +
      • -- str (provider_id) – The selection provider ID.

      • +
      • -- callable (func) – A callable object that is notified when the selection changes.

      -
    +
    +

    -disconnect_selection_listener(provider_id, func)[source]
    +disconnect_selection_listener(provider_id, func)[source]

    Disconnect a listener from a specific provider.

    - --- - - - -
    Parameters:
      -
    • -- str (provider_id) – The selection provider ID.
    • -
    • -- callable (func) – A callable object that is notified when the selection changes.
    • +
      +
      Parameters
      +
        +
      • -- str (provider_id) – The selection provider ID.

      • +
      • -- callable (func) – A callable object that is notified when the selection changes.

      -
    +
    +
    -get_selection(provider_id)[source]
    +get_selection(provider_id)[source]

    Return the current selection of the provider with the given ID.

    If a provider with that ID has not been registered, a -ProviderNotRegisteredError is raised.

    - --- - - - - - -
    Parameters:-- str (provider_id) – The selection provider ID.
    Returns:
    -
    selection – ISelection
    -
    The current selection of the provider.
    +ProviderNotRegisteredError is raised.

    +
    +
    Parameters
    +

    -- str (provider_id) – The selection provider ID.

    +
    +
    Returns
    +

    +
    selection – ISelection

    The current selection of the provider.

    +
    +
    +

    +
    -
    -has_selection_provider(provider_id)[source]
    +has_selection_provider(provider_id)[source]

    Has a provider with the given ID been registered?

    -remove_selection_provider(provider)[source]
    +remove_selection_provider(provider)[source]

    Remove a selection provider.

    If the provider has not been registered, a -ProviderNotRegisteredError is raised.

    - --- - - - -
    Parameters:-- ISelectionProvider (provider) – The selection provider added to the internal registry.
    +ProviderNotRegisteredError is raised.

    +
    +
    Parameters
    +

    -- ISelectionProvider (provider) – The selection provider added to the internal registry.

    +
    +
    -set_selection(provider_id, items, ignore_missing=False)[source]
    +set_selection(provider_id, items, ignore_missing=False)[source]

    Set the current selection in a provider to the given items.

    If a provider with the given ID has not been registered, a -ProviderNotRegisteredError is raised.

    +ProviderNotRegisteredError is raised.

    If ignore_missing is True, items that are not available in the selection provider are silently ignored. If it is False (default), a ValueError should be raised.

    - --- - - - -
    Parameters:
      -
    • -- str (provider_id) – The selection provider ID.
    • -
    • -- list (items) – List of items to be selected.
    • -
    • -- bool (ignore_missing) – If False (default), the provider raises an exception if any +
      +
      Parameters
      +
        +
      • -- str (provider_id) – The selection provider ID.

      • +
      • -- list (items) – List of items to be selected.

      • +
      • -- bool (ignore_missing) – If False (default), the provider raises an exception if any of the items in items is not available to be selected. Otherwise, missing elements are silently ignored, and the rest -is selected.

      • +is selected.

      -
    +
    +
    @@ -458,21 +433,19 @@

    Previous topic

    apptools.scripting package

    Next topic

    -

    apptools.sweet_pickle package

    +

    apptools.type_registry package

    This Page

    @@ -496,10 +469,10 @@

    Quick search

    © Copyright 2008-2020, Enthought
  • - Last updated on Jun 12, 2020. + Last updated on Dec 17, 2020.
  • - Created using Sphinx 1.8.5. + Created using Sphinx 2.3.1.
  • diff --git a/api/apptools.type_registry.html b/api/apptools.type_registry.html index acc76f891..276d40e0b 100644 --- a/api/apptools.type_registry.html +++ b/api/apptools.type_registry.html @@ -13,9 +13,11 @@ @@ -31,7 +33,7 @@ - +
    @@ -70,7 +72,7 @@ accesskey="N">next
  • - previous
  • @@ -84,7 +86,7 @@
    -
    +

    apptools.type_registry package

    @@ -98,7 +100,7 @@

    Submodules

    apptools.type_registry.type_registry module

    -class apptools.type_registry.type_registry.LazyRegistry[source]
    +class apptools.type_registry.type_registry.LazyRegistry[source]

    Bases: apptools.type_registry.type_registry.TypeRegistry

    A type registry that will lazily import the registered objects.

    Register ‘__module__:__name__’ strings for the lazily imported objects. @@ -107,7 +109,7 @@

    Submodules
    -lookup_by_type(typ)[source]
    +lookup_by_type(typ)[source]

    Look up the registered object for a type.

    @@ -115,158 +117,150 @@

    Submodules
    -class apptools.type_registry.type_registry.TypeRegistry[source]
    +class apptools.type_registry.type_registry.TypeRegistry[source]

    Bases: object

    Register objects for types.

    Each type maintains a stack of registered objects that can be pushed and popped.

    -lookup(instance)[source]
    +lookup(instance)[source]

    Look up the registered object for the given instance.

    - --- - - - - - - - - - -
    Parameters:instance (object) – An instance of a possibly registered type.
    Returns:obj – The registered object for the type of the instance, one of the -type’s superclasses, or else one of the ABCs the type implements.
    Return type:object
    Raises:KeyError if the instance’s type has not been registered.
    +
    +
    Parameters
    +

    instance (object) – An instance of a possibly registered type.

    +
    +
    Returns
    +

    obj – The registered object for the type of the instance, one of the +type’s superclasses, or else one of the ABCs the type implements.

    +
    +
    Return type
    +

    object

    +
    +
    Raises
    +

    KeyError if the instance's type has not been registered.

    +
    +
    -lookup_all(instance)[source]
    +lookup_all(instance)[source]

    Look up all the registered objects for the given instance.

    - --- - - - - - - - - - -
    Parameters:instance (object) – An instance of a possibly registered type.
    Returns:objs – The list of registered objects for the instance. If the given +
    +
    Parameters
    +

    instance (object) – An instance of a possibly registered type.

    +
    +
    Returns
    +

    objs – The list of registered objects for the instance. If the given instance is not registered, its superclasses are searched. If none -of the superclasses are registered, search the possible ABCs.

    Return type:list of objects
    Raises:KeyError if the instance’s type has not been registered.
    +of the superclasses are registered, search the possible ABCs.

    +
    +
    Return type
    +

    list of objects

    +
    +
    Raises
    +

    KeyError if the instance's type has not been registered.

    +
    +
    -lookup_all_by_type(typ)[source]
    +lookup_all_by_type(typ)[source]

    Look up all the registered objects for a type.

    - --- - - - - - - - - - -
    Parameters:typ (type) –
    Returns:objs – The list of registered objects for the type. If the given type is +
    +
    Parameters
    +

    typ (type) –

    +
    +
    Returns
    +

    objs – The list of registered objects for the type. If the given type is not registered, its superclasses are searched. If none of the -superclasses are registered, search the possible ABCs.

    Return type:list of objects
    Raises:KeyError if the type has not been registered.
    +superclasses are registered, search the possible ABCs.

    +
    +
    Return type
    +

    list of objects

    +
    +
    Raises
    +

    KeyError if the type has not been registered.

    +
    +
    -lookup_by_type(typ)[source]
    +lookup_by_type(typ)[source]

    Look up the registered object for a type.

    - --- - - - - - - - - - -
    Parameters:typ (type) –
    Returns:obj – The registered object for the type, one of its superclasses, or -else one of the ABCs it implements.
    Return type:object
    Raises:KeyError if the type has not been registered.
    +
    +
    Parameters
    +

    typ (type) –

    +
    +
    Returns
    +

    obj – The registered object for the type, one of its superclasses, or +else one of the ABCs it implements.

    +
    +
    Return type
    +

    object

    +
    +
    Raises
    +

    KeyError if the type has not been registered.

    +
    +
    -pop(typ)[source]
    +pop(typ)[source]

    Pop a registered object for the given type.

    - --- - - - - - - - - - -
    Parameters:typ (type or '__module__:__name__' string for a type) –
    Returns:obj – The last registered object for the type.
    Return type:object
    Raises:KeyError if the type is not registered.
    +
    +
    Parameters
    +

    typ (type or '__module__:__name__' string for a type) –

    +
    +
    Returns
    +

    obj – The last registered object for the type.

    +
    +
    Return type
    +

    object

    +
    +
    Raises
    +

    KeyError if the type is not registered.

    +
    +
    -push(typ, obj)[source]
    +push(typ, obj)[source]

    Push an object onto the stack for the given type.

    - --- - - - -
    Parameters:
      -
    • typ (type or '__module__:__name__' string for a type) –
    • -
    • obj (object) – The object to register.
    • +
      +
      Parameters
      +
        +
      • typ (type or '__module__:__name__' string for a type) –

      • +
      • obj (object) – The object to register.

      -
    +
    +
    -push_abc(typ, obj)[source]
    +push_abc(typ, obj)[source]

    Push an object onto the stack for the given ABC.

    - --- - - - -
    Parameters:
      -
    • typ (abc.ABCMeta) –
    • -
    • obj (object) –
    • +
      +
      Parameters
      +
        +
      • typ (abc.ABCMeta) –

      • +
      • obj (object) –

      -
    +
    +
    -apptools.type_registry.type_registry.get_mro(obj_class)[source]
    +apptools.type_registry.type_registry.get_mro(obj_class)[source]

    Get a reasonable method resolution order of a class and its superclasses for both old-style and new-style classes.

    @@ -298,8 +292,8 @@

    Table of Contents

    Previous topic

    -

    apptools.type_manager package

    +

    apptools.selection package

    Next topic

    apptools.undo package

    @@ -309,13 +303,11 @@

    This Page

    rel="nofollow">Show Source
    @@ -339,10 +331,10 @@

    Quick search

    © Copyright 2008-2020, Enthought
  • - Last updated on Jun 12, 2020. + Last updated on Dec 17, 2020.
  • - Created using Sphinx 1.8.5. + Created using Sphinx 2.3.1.
  • diff --git a/api/apptools.undo.action.html b/api/apptools.undo.action.html index 131590f77..375395026 100644 --- a/api/apptools.undo.action.html +++ b/api/apptools.undo.action.html @@ -13,9 +13,11 @@ @@ -80,7 +82,7 @@
    -
    +

    apptools.undo.action package

    @@ -91,13 +93,13 @@

    Submodules

    apptools.undo.action.abstract_command_stack_action module

    -class apptools.undo.action.abstract_command_stack_action.AbstractCommandStackAction(**traits)[source]
    +class apptools.undo.action.abstract_command_stack_action.AbstractCommandStackAction(**traits)[source]

    Bases: pyface.action.action.Action

    The abstract base class for all actions that operate on a command stack.

    -destroy()[source]
    +destroy()[source]

    Called when the action is no longer required.

    By default this method does nothing, but this would be a great place to unhook trait listeners etc.

    @@ -113,14 +115,14 @@

    Submodules

    apptools.undo.action.command_action module

    -class apptools.undo.action.command_action.CommandAction[source]
    +class apptools.undo.action.command_action.CommandAction[source]

    Bases: pyface.action.action.Action

    The CommandAction class is an Action class that wraps undo/redo commands. It is only useful for commands that do not take any arguments or return any result.

    -perform(event)[source]
    +perform(event)[source]

    This is reimplemented to push a new command instance onto the command stack.

    @@ -132,13 +134,13 @@

    Submodules

    apptools.undo.action.redo_action module

    -class apptools.undo.action.redo_action.RedoAction(**traits)[source]
    +class apptools.undo.action.redo_action.RedoAction(**traits)[source]

    Bases: apptools.undo.action.abstract_command_stack_action.AbstractCommandStackAction

    An action that redos the last command undone of the active command stack.

    -perform(event)[source]
    +perform(event)[source]

    Perform the action.

    @@ -149,12 +151,12 @@

    Submodules

    apptools.undo.action.undo_action module

    -class apptools.undo.action.undo_action.UndoAction(**traits)[source]
    +class apptools.undo.action.undo_action.UndoAction(**traits)[source]

    Bases: apptools.undo.action.abstract_command_stack_action.AbstractCommandStackAction

    An action that undos the last command of the active command stack.

    -perform(event)[source]
    +perform(event)[source]

    Perform the action.

    @@ -198,13 +200,11 @@

    This Page

    rel="nofollow">Show Source

    @@ -228,10 +228,10 @@

    Quick search

    © Copyright 2008-2020, Enthought
  • - Last updated on Jun 12, 2020. + Last updated on Dec 17, 2020.
  • - Created using Sphinx 1.8.5. + Created using Sphinx 2.3.1.
  • diff --git a/api/apptools.undo.html b/api/apptools.undo.html index 1adf77962..e78c602c1 100644 --- a/api/apptools.undo.html +++ b/api/apptools.undo.html @@ -13,9 +13,11 @@ @@ -84,7 +86,7 @@
    -
    +

    apptools.undo package

    @@ -112,13 +114,13 @@

    Submodules

    apptools.undo.abstract_command module

    -class apptools.undo.abstract_command.AbstractCommand[source]
    +class apptools.undo.abstract_command.AbstractCommand[source]

    Bases: traits.has_traits.HasTraits

    The AbstractCommand class is an abstract base class that implements the ICommand interface.

    -do()[source]
    +do()[source]

    This is called by the command stack to do the command and to return any value. The command must save any state necessary for the ‘redo()’ and ‘undo()’ methods to work. The class’s __init__() must also ensure @@ -129,7 +131,7 @@

    Submodules
    -merge(other)[source]
    +merge(other)[source]

    This is called by the command stack to try and merge another command with this one. True is returned if the commands were merged. ‘other’ is the command that is about to be executed. If the commands @@ -140,7 +142,7 @@

    Submodules
    -redo()[source]
    +redo()[source]

    This is called by the command stack to redo the command. Any returned value will replace the value that the command stack references from the original call to ‘do()’ or previous call to ‘redo()’.

    @@ -148,7 +150,7 @@

    Submodules
    -undo()[source]
    +undo()[source]

    This is called by the command stack to undo the command.

    @@ -162,13 +164,13 @@

    Submodules

    apptools.undo.command_stack module

    -class apptools.undo.command_stack.CommandStack[source]
    +class apptools.undo.command_stack.CommandStack[source]

    Bases: traits.has_traits.HasTraits

    The CommandStack class is the default implementation of the ICommandStack interface.

    -begin_macro(name)[source]
    +begin_macro(name)[source]

    This begins a macro by creating an empty command with the given ‘name’. All subsequent calls to ‘push()’ create commands that will be children of the empty command until the next call to ‘end_macro()’. @@ -179,7 +181,7 @@

    Submodules
    -clear()[source]
    +clear()[source]

    This clears the stack, without undoing or redoing any commands, and leaves the stack in a clean state. It is typically used when all changes to the data have been abandoned.

    @@ -187,13 +189,13 @@

    Submodules
    -end_macro()[source]
    +end_macro()[source]

    This ends a macro.

    -push(command)[source]
    +push(command)[source]

    This executes a command and saves it on the command stack so that it can be subsequently undone and redone. ‘command’ is an instance that implements the ICommand interface. Its ‘do()’ method is called @@ -203,7 +205,7 @@

    Submodules
    -redo(sequence_nr=0)[source]
    +redo(sequence_nr=0)[source]

    If ‘sequence_nr’ is 0 then the last command that was undone is redone and any result returned. Otherwise commands are redone up to and including the given ‘sequence_nr’ and any result of the last of @@ -212,7 +214,7 @@

    Submodules
    -undo(sequence_nr=0)[source]
    +undo(sequence_nr=0)[source]

    If ‘sequence_nr’ is 0 then the last command is undone. Otherwise commands are undone up to and including the given ‘sequence_nr’.

    @@ -224,14 +226,14 @@

    Submodules

    apptools.undo.i_command module

    -class apptools.undo.i_command.ICommand[source]
    +class apptools.undo.i_command.ICommand[source]

    Bases: traits.has_traits.Interface

    The command interface. The state of the data can be changed by passing an instance that implements this interface to the ‘push()’ method of a command stack along with any arguments.

    -do()[source]
    +do()[source]

    This is called by the command stack to do the command and to return any value. The command must save any state necessary for the ‘redo()’ and ‘undo()’ methods to work. The class’s __init__() must also ensure @@ -242,7 +244,7 @@

    Submodules
    -merge(other)[source]
    +merge(other)[source]

    This is called by the command stack to try and merge another command with this one. True is returned if the commands were merged. ‘other’ is the command that is about to be executed. If the commands @@ -253,7 +255,7 @@

    Submodules
    -redo()[source]
    +redo()[source]

    This is called by the command stack to redo the command. Any returned value will replace the value that the command stack references from the original call to ‘do()’ or previous call to ‘redo()’.

    @@ -261,7 +263,7 @@

    Submodules
    -undo()[source]
    +undo()[source]

    This is called by the command stack to undo the command.

    @@ -272,14 +274,14 @@

    Submodules

    apptools.undo.i_command_stack module

    -class apptools.undo.i_command_stack.ICommandStack[source]
    +class apptools.undo.i_command_stack.ICommandStack[source]

    Bases: traits.has_traits.Interface

    The command stack interface. A command stack is responsible for managing the changes to a data model and recording those changes so that they can be undone or redone.

    -begin_macro(name)[source]
    +begin_macro(name)[source]

    This begins a macro by creating an empty command with the given ‘name’. The commands passed to all subsequent calls to ‘push()’ will be contained in the macro until the next call to ‘end_macro()’. Macros @@ -290,7 +292,7 @@

    Submodules
    -clear()[source]
    +clear()[source]

    This clears the stack, without undoing or redoing any commands, and leaves the stack in a clean state. It is typically used when all changes to the data have been abandoned.

    @@ -298,13 +300,13 @@

    Submodules
    -end_macro()[source]
    +end_macro()[source]

    This ends a macro.

    -push(command)[source]
    +push(command)[source]

    This executes a command and saves it on the command stack so that it can be subsequently undone and redone. ‘command’ is an instance that implements the ICommand interface. Its ‘do()’ method is called @@ -316,7 +318,7 @@

    Submodules
    -redo(sequence_nr=0)[source]
    +redo(sequence_nr=0)[source]

    If ‘sequence_nr’ is 0 then the last command that was undone is redone and any result returned. Otherwise commands are redone up to and including the given ‘sequence_nr’ and any result of the last of @@ -325,7 +327,7 @@

    Submodules
    -undo(sequence_nr=0)[source]
    +undo(sequence_nr=0)[source]

    If ‘sequence_nr’ is 0 then the last command is undone. Otherwise commands are undone up to and including the given ‘sequence_nr’.

    @@ -337,20 +339,20 @@

    Submodules

    apptools.undo.i_undo_manager module

    -class apptools.undo.i_undo_manager.IUndoManager[source]
    +class apptools.undo.i_undo_manager.IUndoManager[source]

    Bases: traits.has_traits.Interface

    The undo manager interface. An undo manager is responsible for one or more command stacks. Typically an application would have a single undo manager.

    -redo()[source]
    +redo()[source]

    Redo the last undone command of the active command stack.

    -undo()[source]
    +undo()[source]

    Undo the last command of the active command stack.

    @@ -361,19 +363,19 @@

    Submodules

    apptools.undo.undo_manager module

    -class apptools.undo.undo_manager.UndoManager[source]
    +class apptools.undo.undo_manager.UndoManager[source]

    Bases: traits.has_traits.HasTraits

    The UndoManager class is the default implementation of the IUndoManager interface.

    -redo()[source]
    +redo()[source]

    Redo the last undone command of the active command stack.

    -undo()[source]
    +undo()[source]

    Undo the last command of the active command stack.

    @@ -425,13 +427,11 @@

    This Page

    rel="nofollow">Show Source

    @@ -455,10 +455,10 @@

    Quick search

    © Copyright 2008-2020, Enthought
  • - Last updated on Jun 12, 2020. + Last updated on Dec 17, 2020.
  • - Created using Sphinx 1.8.5. + Created using Sphinx 2.3.1.
  • diff --git a/api/modules.html b/api/modules.html index dd10caaf1..2cef3b579 100644 --- a/api/modules.html +++ b/api/modules.html @@ -13,9 +13,11 @@ @@ -82,7 +84,7 @@
    -
    +

    apptools

    @@ -90,26 +92,6 @@

    apptoolsapptools package

    @@ -360,10 +267,10 @@

    Quick search

    © Copyright 2008-2020, Enthought
  • - Last updated on Jun 12, 2020. + Last updated on Dec 17, 2020.
  • - Created using Sphinx 1.8.5. + Created using Sphinx 2.3.1.
  • diff --git a/genindex.html b/genindex.html index 7470f3e5e..abcc35441 100644 --- a/genindex.html +++ b/genindex.html @@ -14,9 +14,11 @@ @@ -71,7 +73,7 @@
    -
    +

    Index

    @@ -105,87 +107,23 @@

    Index

    A

    -
  • add_to_namespace() (in module apptools.appscripting.lazy_namespace) -
  • add_updater() (apptools.persistence.versioned_unpickler.VersionedUnpickler method)
  • -
  • add_user() (apptools.permissions.default.i_user_database.IUserDatabase method) - -
  • Address (class in apptools.naming.address) -
  • -
  • all_roles() (apptools.permissions.default.i_policy_storage.IPolicyStorage method) - -
  • -
  • allows_children() (apptools.naming.ui.context_node_type.ContextNodeType method) - -
  • -
  • AnyContextDataNameItem (class in apptools.template.impl.any_context_data_name_item) -
  • -
  • AnyDataNameItem (class in apptools.template.impl.any_data_name_item)
  • append() (apptools.io.h5.table_node.H5TableNode method) @@ -246,68 +156,6 @@

    A

  • apptools (module) -
  • -
  • apptools.appscripting (module) -
  • -
  • apptools.appscripting.action (module) -
  • -
  • apptools.appscripting.action.api (module) -
  • -
  • apptools.appscripting.action.start_recording_action (module) -
  • -
  • apptools.appscripting.action.stop_recording_action (module) -
  • -
  • apptools.appscripting.api (module) -
  • -
  • apptools.appscripting.bind_event (module) -
  • -
  • apptools.appscripting.i_bind_event (module) -
  • -
  • apptools.appscripting.i_script_manager (module) -
  • -
  • apptools.appscripting.lazy_namespace (module) -
  • -
  • apptools.appscripting.package_globals (module) -
  • -
  • apptools.appscripting.script_manager (module) -
  • -
  • apptools.appscripting.scriptable (module) -
  • -
  • apptools.appscripting.scriptable_type (module) -
  • -
  • apptools.help (module) -
  • -
  • apptools.help.help_plugin (module) -
  • -
  • apptools.help.help_plugin.action (module) -
  • -
  • apptools.help.help_plugin.action.demo_action (module) -
  • -
  • apptools.help.help_plugin.action.doc_action (module) -
  • -
  • apptools.help.help_plugin.action.example_action (module) -
  • -
  • apptools.help.help_plugin.action.load_url_action (module) -
  • -
  • apptools.help.help_plugin.action.util (module) -
  • -
  • apptools.help.help_plugin.api (module) -
  • -
  • apptools.help.help_plugin.examples_preferences (module) -
  • -
  • apptools.help.help_plugin.help_code (module) -
  • -
  • apptools.help.help_plugin.help_doc (module) -
  • -
  • apptools.help.help_plugin.help_plugin (module) -
  • -
  • apptools.help.help_plugin.help_submenu_manager (module) -
  • -
  • apptools.help.help_plugin.i_help_code (module) -
  • -
  • apptools.help.help_plugin.i_help_doc (module) -
  • -
  • apptools.help.help_plugin.preferences_pages (module)
  • apptools.io (module)
  • @@ -338,16 +186,12 @@

    A

  • apptools.logger.api (module)
  • apptools.logger.custom_excepthook (module) -
  • -
  • apptools.logger.filtering_handler (module)
  • apptools.logger.log_point (module)
  • apptools.logger.log_queue_handler (module)
  • apptools.logger.logger (module) -
  • -
  • apptools.logger.null_handler (module)
  • apptools.logger.plugin (module)
  • @@ -364,42 +208,8 @@

    A

  • apptools.logger.plugin.view.logger_view (module)
  • apptools.logger.ring_buffer (module) -
  • -
  • apptools.logger.util (module) -
  • -
  • apptools.lru_cache (module) -
  • -
  • apptools.lru_cache.lru_cache (module)
  • apptools.naming (module) -
  • -
  • apptools.naming.adapter (module) -
  • -
  • apptools.naming.adapter.api (module) -
  • -
  • apptools.naming.adapter.dict_context_adapter (module) -
  • -
  • apptools.naming.adapter.dict_context_adapter_factory (module) -
  • -
  • apptools.naming.adapter.instance_context_adapter (module) -
  • -
  • apptools.naming.adapter.instance_context_adapter_factory (module) -
  • -
  • apptools.naming.adapter.list_context_adapter (module) -
  • -
  • apptools.naming.adapter.list_context_adapter_factory (module) -
  • -
  • apptools.naming.adapter.trait_dict_context_adapter (module) -
  • -
  • apptools.naming.adapter.trait_dict_context_adapter_factory (module) -
  • -
  • apptools.naming.adapter.trait_list_context_adapter (module) -
  • -
  • apptools.naming.adapter.trait_list_context_adapter_factory (module) -
  • -
  • apptools.naming.adapter.tuple_context_adapter (module) -
  • -
  • apptools.naming.adapter.tuple_context_adapter_factory (module)
  • apptools.naming.address (module)
  • @@ -408,10 +218,6 @@

    A

  • apptools.naming.binding (module)
  • apptools.naming.context (module) -
  • -
  • apptools.naming.context_adapter (module) -
  • -
  • apptools.naming.context_adapter_factory (module)
  • apptools.naming.dir_context (module)
  • @@ -440,11 +246,11 @@

    A

  • apptools.naming.pyfs_context_factory (module)
  • apptools.naming.pyfs_initial_context_factory (module) -
  • -
  • apptools.naming.pyfs_object_factory (module)
  • @@ -775,81 +395,33 @@

    B

    -
  • bind() (apptools.appscripting.i_script_manager.IScriptManager method) - -
  • -
  • bind_factory() (apptools.appscripting.i_script_manager.IScriptManager method) - -
  • C

    @@ -965,53 +517,17 @@

    C

    D

    +
  • custom_editor() (apptools.preferences.ui.widget_editor.WidgetEditor method) +
  • custom_excepthook() (in module apptools.logger.custom_excepthook)
  • - + - + + -
    -
  • DocAction (class in apptools.help.help_plugin.action.doc_action) -
  • -
  • DocImageResource (class in apptools.help.help_plugin.action.doc_action) -
  • -
  • DocumentsMenuManager (class in apptools.help.help_plugin.help_submenu_manager) -
  • -
  • DocumentsPreferencesPage (class in apptools.help.help_plugin.preferences_pages) -
  • -
  • DownloadsMenuManager (class in apptools.help.help_plugin.help_submenu_manager) -
  • +
    -
  • get_assignment() (apptools.permissions.default.i_policy_storage.IPolicyStorage method) - -
  • get_atom() (in module apptools.io.h5.file)
  • get_attributes() (apptools.naming.dir_context.DirContext method) -
  • -
  • get_children() (apptools.naming.ui.context_node_type.ContextNodeType method) -
  • -
  • get_classes() (in module apptools.type_manager.util)
  • get_code() (apptools.scripting.recorder.Recorder method)
  • -
  • get_data_context() (apptools.template.impl.template_data_context.TemplateDataContext method) - -
  • -
  • get_data_context_value() (apptools.template.impl.template_data_context.TemplateDataContext method) - -
  • get_default_preferences() (in module apptools.preferences.package_globals)
  • -
  • get_drag_value() (apptools.naming.ui.context_node_type.ContextNodeType method) - -
  • get_editor() (apptools.naming.trait_defs.naming_traits.NamingTraitHandler method) -
  • -
  • get_enabled() (apptools.permissions.adapter_base.AdapterBase method) - -
  • -
  • get_global_registry() (in module apptools.sweet_pickle.global_registry)
  • get_initial_context() (apptools.naming.initial_context_factory.InitialContextFactory method) @@ -1235,26 +655,10 @@

    G

  • (apptools.naming.pyfs_initial_context_factory.PyFSInitialContextFactory method)
  • -
  • get_key() (apptools.naming.ui.naming_node_manager.NamingNodeManager method) -
  • get_latest() (apptools.persistence.updater.Updater method)
  • -
  • get_module_name() (in module apptools.logger.util) +
  • get_mro() (in module apptools.type_registry.type_registry)
  • -
  • get_module_name_from_zip() (in module apptools.logger.util) -
  • -
  • get_monitor() (apptools.naming.ui.context_node_type.ContextNodeType method) -
  • -
    -
  • get_sys_prefix_relative_filename() (in module apptools.help.help_plugin.action.util) -
  • -
  • get_text() (apptools.naming.ui.context_node_type.ContextNodeType method) - -
  • get_unique_name() (apptools.naming.context.Context method) @@ -1319,17 +707,7 @@

    G

  • get_version() (in module apptools.persistence.version_registry)
  • -
  • get_version_attribute() (apptools.sweet_pickle.updater.Updater method) -
  • -
  • get_visible() (apptools.permissions.adapter_base.AdapterBase method) - -
  • get_width() (apptools.logger.plugin.view.logger_view.LogRecordAdapter method) -
  • -
  • get_zip_path() (in module apptools.logger.util)
  • gunzip_string() (in module apptools.persistence.state_pickler)
  • @@ -1351,47 +729,17 @@

    H

  • H5Group (class in apptools.io.h5.file)
  • +
    @@ -1399,39 +747,33 @@

    H

    I

    + -
    @@ -1589,8 +855,6 @@

    K

  • (apptools.io.h5.file.H5Attrs method)
  • (apptools.io.h5.table_node.H5TableNode method) -
  • -
  • (apptools.lru_cache.lru_cache.LRUCache method)
  • (apptools.preferences.i_preferences.IPreferences method)
  • @@ -1605,21 +869,15 @@

    K

    L

    - +
  • load_build() (apptools.persistence.versioned_unpickler.NewUnpickler class method) - -
  • -
  • load_build_with_meta_data() (in module apptools.sweet_pickle.versioned_unpickler) -
  • -
  • load_policy() (apptools.permissions.default.policy_manager.PolicyManager method)
  • load_project() (in module apptools.persistence.project_loader)
  • @@ -1653,26 +899,18 @@

    L

  • (in module apptools.persistence.state_pickler)
  • -
  • load_user() (apptools.permissions.i_policy_manager.IPolicyManager method) -
  • -
  • loads() (in module apptools.sweet_pickle) -
  • loads_state() (apptools.persistence.state_pickler.StateUnpickler method)
  • -
  • lookup_context() (apptools.naming.context.Context method) -
  • -
  • LRUCache (class in apptools.lru_cache.lru_cache)
  • @@ -1725,75 +957,25 @@

    L

    M

    - +
    @@ -1801,52 +983,30 @@

    M

    N

    @@ -1881,26 +1039,16 @@

    N

    O

    - + - +
    @@ -2057,21 +1161,13 @@

    Q

    R

    @@ -2238,30 +1276,12 @@

    S

  • save_preferences() (apptools.logger.plugin.logger_service.LoggerService method)
  • ScopedPreferences (class in apptools.preferences.scoped_preferences) -
  • -
  • Scriptable() (in module apptools.appscripting.scriptable) -
  • -
  • scriptable() (in module apptools.appscripting.scriptable) -
  • -
  • ScriptManager (class in apptools.appscripting.script_manager)
  • search() (apptools.naming.context.Context method)
  • -
  • SecureHandler (class in apptools.permissions.secure_proxy) -
  • -
  • SecureProxy (class in apptools.permissions.secure_proxy) -
  • -
  • select_role() (in module apptools.permissions.default.select_role) -
  • -
  • select_user() (apptools.permissions.i_user_manager.IUserManager method) - -
  • -
  • selection (apptools.selection.i_selection_provider.ISelectionProvider attribute), [1] +
  • selection (apptools.selection.i_selection_provider.ISelectionProvider attribute)
  • -
  • SelectionService (class in apptools.selection.selection_service), [1] +
  • SelectionService (class in apptools.selection.selection_service)
  • send_bug_report() (apptools.logger.plugin.logger_service.LoggerService method)
  • @@ -2281,89 +1301,41 @@

    S

  • (apptools.preferences.preferences.Preferences method)
  • (apptools.preferences.scoped_preferences.ScopedPreferences method) -
  • -
  • (apptools.template.template_traits.TDerived method)
  • set_absolute() (apptools.persistence.file_path.FilePath method)
  • -
  • set_assignment() (apptools.permissions.default.i_policy_storage.IPolicyStorage method) - -
  • set_attributes() (apptools.naming.dir_context.DirContext method)
  • set_default_preferences() (in module apptools.preferences.package_globals) -
  • -
  • set_enabled() (apptools.permissions.adapter_base.AdapterBase method) - -
  • -
  • set_permissions_manager() (in module apptools.permissions.package_globals)
  • set_recorder() (in module apptools.scripting.package_globals)
  • set_relative() (apptools.persistence.file_path.FilePath method)
  • -
  • set_script_manager() (in module apptools.appscripting.package_globals) -
  • -
  • set_selection() (apptools.selection.i_selection_provider.ISelectionProvider method), [1] +
  • set_selection() (apptools.selection.i_selection_provider.ISelectionProvider method)
  • @@ -2646,12 +1474,10 @@

    W

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -995,237 +532,27 @@

    Python Module Index

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -1324,13 +651,11 @@

    Python Module Index

    @@ -1354,10 +679,10 @@

    Quick search

    © Copyright 2008-2020, Enthought
  • - Last updated on Jun 12, 2020. + Last updated on Dec 17, 2020.
  • - Created using Sphinx 1.8.5. + Created using Sphinx 2.3.1.
  • diff --git a/scripting/introduction.html b/scripting/introduction.html index cfb8e1bf4..add6b06ce 100644 --- a/scripting/introduction.html +++ b/scripting/introduction.html @@ -13,9 +13,11 @@ @@ -80,7 +82,7 @@
    -
    +

    Automatic script recording

    @@ -88,15 +90,15 @@ facility. This can be used to:

      -
    • record all actions performed on a traits based UI into a human +
    • record all actions performed on a traits based UI into a human readable, Python script that should be able to recreate your UI -actions.

    • -
    • easily learn the scripting API of an application.
    • +actions.

      +
    • easily learn the scripting API of an application.

    This package is not just a toy framework and is powerful enough to -provide full script recording to the Mayavi application. Mayavi is a -powerful 3D visualization tool that is part of ETS.

    +provide full script recording to the Mayavi application. Mayavi is a +powerful 3D visualization tool that is part of ETS.

    The scripting API

    The scripting API primarily allows you to record UI actions for objects @@ -111,7 +113,7 @@

    The following example is taken from the test suite. Consider a set of simple objects organized in a hierarchy:

    from traits.api import (HasTraits, Float, Instance,
    -        Str, List, Bool, HasStrictTraits, Tuple, Range, TraitPrefixMap,
    +        Str, List, Bool, HasStrictTraits, Tuple, PrefixMap, Range,
             Trait)
     from apptools.scripting.api import (Recorder, recordable,
         set_recorder)
    @@ -119,10 +121,11 @@
     class Property(HasStrictTraits):
         color = Tuple(Range(0.0, 1.0), Range(0.0, 1.0), Range(0.0, 1.0))
         opacity = Range(0.0, 1.0, 1.0)
    -    representation = Trait('surface',
    -                           TraitPrefixMap({'surface':2,
    -                                           'wireframe': 1,
    -                                           'points': 0}))
    +    representation = PrefixMap(
    +        {"surface": 2, "wireframe": 1, "points": 0},
    +        default_value="surface"
    +    )
    +
     class Toy(HasTraits):
         color = Str
         type = Str
    @@ -215,13 +218,13 @@
     functions are not recorded and trait changes are also not recorded if
     done inside a recordable function.

    -

    Note

    -
      -
    1. It is very important to note that the global recorder must be set +

      Note

      +
        +
      1. It is very important to note that the global recorder must be set via the set_recorder method. The recordable decorator -relies on this being set to work.

      2. -
      3. The recordable decorator will work with plain Python classes -and with functions too.
      4. +relies on this being set to work.

        +
      5. The recordable decorator will work with plain Python classes +and with functions too.

    To stop recording do this:

    @@ -237,19 +240,19 @@

    Here are a few advanced use cases.

      -
    • The API also provides a RecorderWithUI class that provides a +
    • The API also provides a RecorderWithUI class that provides a simple user interface that prints the recorded script and allows the -user to save the script.

    • -
    • Sometimes it is not enough to just record trait changes, one may want +user to save the script.

    • +
    • Sometimes it is not enough to just record trait changes, one may want to pass an arbitrary string or command when recording is occurring. To allow for this, if one defines a recorder trait on the object, it is set to the current recorder. One can then use this recorder to -do whatever one wants. This is very convenient.

    • -
    • To ignore specific traits one must specify either a record=False +do whatever one wants. This is very convenient.

    • +
    • To ignore specific traits one must specify either a record=False metadata to the trait definition or specify a list of strings to the -register method in the ignore keyword argument.

    • -
    • If you want to use a specific name for an object on the script you -can pass the script_id parameter to the register function.
    • +register method in the ignore keyword argument.

      +
    • If you want to use a specific name for an object on the script you +can pass the script_id parameter to the register function.

    For more details on the recorder itself we suggest reading the module @@ -292,13 +295,11 @@

    This Page

    rel="nofollow">Show Source
    @@ -322,10 +323,10 @@

    Quick search

    © Copyright 2008-2020, Enthought
  • - Last updated on Jun 12, 2020. + Last updated on Dec 17, 2020.
  • - Created using Sphinx 1.8.5. + Created using Sphinx 2.3.1.
  • diff --git a/search.html b/search.html index 6c532ed43..fb3726636 100644 --- a/search.html +++ b/search.html @@ -14,9 +14,11 @@ @@ -31,11 +33,7 @@ - - - + @@ -79,7 +77,7 @@
    -
    +

    Search

    @@ -96,7 +94,7 @@

    Search

    containing fewer words won't appear in the result list.

    - + @@ -132,10 +130,10 @@

    Search

    © Copyright 2008-2020, Enthought
  • - Last updated on Jun 12, 2020. + Last updated on Dec 17, 2020.
  • - Created using Sphinx 1.8.5. + Created using Sphinx 2.3.1.
  • diff --git a/searchindex.js b/searchindex.js index 69be7e726..2f5fef6a4 100644 --- a/searchindex.js +++ b/searchindex.js @@ -1 +1 @@ -Search.setIndex({docnames:["api","api/apptools","api/apptools.appscripting","api/apptools.appscripting.action","api/apptools.help","api/apptools.help.help_plugin","api/apptools.help.help_plugin.action","api/apptools.io","api/apptools.io.h5","api/apptools.logger","api/apptools.logger.agent","api/apptools.logger.plugin","api/apptools.logger.plugin.view","api/apptools.lru_cache","api/apptools.naming","api/apptools.naming.adapter","api/apptools.naming.trait_defs","api/apptools.naming.ui","api/apptools.permissions","api/apptools.permissions.action","api/apptools.permissions.adapters","api/apptools.permissions.default","api/apptools.persistence","api/apptools.preferences","api/apptools.preferences.ui","api/apptools.scripting","api/apptools.selection","api/apptools.sweet_pickle","api/apptools.template","api/apptools.template.impl","api/apptools.template.test","api/apptools.type_manager","api/apptools.type_registry","api/apptools.undo","api/apptools.undo.action","api/modules","appscripting/Introduction","index","permissions/ApplicationAPI","permissions/DefaultPolicyManagerDataAPI","permissions/DefaultUserManagerDataAPI","permissions/Introduction","preferences/Preferences","preferences/PreferencesInEnvisage","scripting/introduction","selection/selection","undo/Introduction"],envversion:{"sphinx.domains.c":1,"sphinx.domains.changeset":1,"sphinx.domains.cpp":1,"sphinx.domains.javascript":1,"sphinx.domains.math":2,"sphinx.domains.python":1,"sphinx.domains.rst":1,"sphinx.domains.std":1,"sphinx.ext.viewcode":1,sphinx:55},filenames:["api.rst","api/apptools.rst","api/apptools.appscripting.rst","api/apptools.appscripting.action.rst","api/apptools.help.rst","api/apptools.help.help_plugin.rst","api/apptools.help.help_plugin.action.rst","api/apptools.io.rst","api/apptools.io.h5.rst","api/apptools.logger.rst","api/apptools.logger.agent.rst","api/apptools.logger.plugin.rst","api/apptools.logger.plugin.view.rst","api/apptools.lru_cache.rst","api/apptools.naming.rst","api/apptools.naming.adapter.rst","api/apptools.naming.trait_defs.rst","api/apptools.naming.ui.rst","api/apptools.permissions.rst","api/apptools.permissions.action.rst","api/apptools.permissions.adapters.rst","api/apptools.permissions.default.rst","api/apptools.persistence.rst","api/apptools.preferences.rst","api/apptools.preferences.ui.rst","api/apptools.scripting.rst","api/apptools.selection.rst","api/apptools.sweet_pickle.rst","api/apptools.template.rst","api/apptools.template.impl.rst","api/apptools.template.test.rst","api/apptools.type_manager.rst","api/apptools.type_registry.rst","api/apptools.undo.rst","api/apptools.undo.action.rst","api/modules.rst","appscripting/Introduction.rst","index.rst","permissions/ApplicationAPI.rst","permissions/DefaultPolicyManagerDataAPI.rst","permissions/DefaultUserManagerDataAPI.rst","permissions/Introduction.rst","preferences/Preferences.rst","preferences/PreferencesInEnvisage.rst","scripting/introduction.rst","selection/selection.rst","undo/Introduction.rst"],objects:{"":{apptools:[1,0,0,"-"]},"apptools.appscripting":{action:[3,0,0,"-"],api:[2,0,0,"-"],bind_event:[2,0,0,"-"],i_bind_event:[2,0,0,"-"],i_script_manager:[2,0,0,"-"],lazy_namespace:[2,0,0,"-"],package_globals:[2,0,0,"-"],script_manager:[2,0,0,"-"],scriptable:[2,0,0,"-"],scriptable_type:[2,0,0,"-"]},"apptools.appscripting.action":{api:[3,0,0,"-"],start_recording_action:[3,0,0,"-"],stop_recording_action:[3,0,0,"-"]},"apptools.appscripting.action.start_recording_action":{StartRecordingAction:[3,1,1,""]},"apptools.appscripting.action.start_recording_action.StartRecordingAction":{perform:[3,2,1,""]},"apptools.appscripting.action.stop_recording_action":{StopRecordingAction:[3,1,1,""]},"apptools.appscripting.action.stop_recording_action.StopRecordingAction":{perform:[3,2,1,""]},"apptools.appscripting.bind_event":{BindEvent:[2,1,1,""]},"apptools.appscripting.i_bind_event":{IBindEvent:[2,1,1,""]},"apptools.appscripting.i_script_manager":{IScriptManager:[2,1,1,""]},"apptools.appscripting.i_script_manager.IScriptManager":{bind:[2,2,1,""],bind_factory:[2,2,1,""],run:[2,2,1,""],run_file:[2,2,1,""],start_recording:[2,2,1,""],stop_recording:[2,2,1,""]},"apptools.appscripting.lazy_namespace":{FactoryWrapper:[2,1,1,""],LazyNamespace:[2,1,1,""],add_to_namespace:[2,3,1,""]},"apptools.appscripting.lazy_namespace.FactoryWrapper":{create_scriptable_object:[2,2,1,""]},"apptools.appscripting.package_globals":{get_script_manager:[2,3,1,""],set_script_manager:[2,3,1,""]},"apptools.appscripting.script_manager":{ScriptManager:[2,1,1,""]},"apptools.appscripting.script_manager.ScriptManager":{arg_as_string:[2,4,1,""],args_as_string_list:[2,4,1,""],bind:[2,2,1,""],bind_factory:[2,2,1,""],new_object:[2,2,1,""],record_method:[2,2,1,""],record_trait_get:[2,2,1,""],record_trait_set:[2,2,1,""],run:[2,2,1,""],run_file:[2,2,1,""],start_recording:[2,2,1,""],stop_recording:[2,2,1,""]},"apptools.appscripting.scriptable":{Scriptable:[2,3,1,""],scriptable:[2,3,1,""]},"apptools.appscripting.scriptable_type":{create_scriptable_type:[2,3,1,""],make_object_scriptable:[2,3,1,""]},"apptools.help":{help_plugin:[5,0,0,"-"]},"apptools.help.help_plugin":{action:[6,0,0,"-"],api:[5,0,0,"-"],examples_preferences:[5,0,0,"-"],help_code:[5,0,0,"-"],help_doc:[5,0,0,"-"],help_plugin:[5,0,0,"-"],help_submenu_manager:[5,0,0,"-"],i_help_code:[5,0,0,"-"],i_help_doc:[5,0,0,"-"],preferences_pages:[5,0,0,"-"]},"apptools.help.help_plugin.action":{demo_action:[6,0,0,"-"],doc_action:[6,0,0,"-"],example_action:[6,0,0,"-"],load_url_action:[6,0,0,"-"],util:[6,0,0,"-"]},"apptools.help.help_plugin.action.demo_action":{DemoAction:[6,1,1,""],DemoImageResource:[6,1,1,""]},"apptools.help.help_plugin.action.demo_action.DemoAction":{perform:[6,2,1,""]},"apptools.help.help_plugin.action.doc_action":{DocAction:[6,1,1,""],DocImageResource:[6,1,1,""]},"apptools.help.help_plugin.action.doc_action.DocAction":{perform:[6,2,1,""]},"apptools.help.help_plugin.action.example_action":{ExampleAction:[6,1,1,""]},"apptools.help.help_plugin.action.example_action.ExampleAction":{perform:[6,2,1,""]},"apptools.help.help_plugin.action.load_url_action":{LoadURLAction:[6,1,1,""]},"apptools.help.help_plugin.action.util":{get_sys_prefix_relative_filename:[6,3,1,""]},"apptools.help.help_plugin.examples_preferences":{ExamplesPreferences:[5,1,1,""]},"apptools.help.help_plugin.help_code":{HelpCode:[5,1,1,""]},"apptools.help.help_plugin.help_doc":{HelpDoc:[5,1,1,""]},"apptools.help.help_plugin.help_plugin":{HelpPlugin:[5,1,1,""]},"apptools.help.help_plugin.help_plugin.HelpPlugin":{HELP_DEMOS:[5,5,1,""],HELP_DOCS:[5,5,1,""],HELP_DOWNLOADS:[5,5,1,""],HELP_EXAMPLES:[5,5,1,""],PREFERENCES:[5,5,1,""],PREFERENCES_PAGES:[5,5,1,""],WORKBENCH_ACTION_SETS:[5,5,1,""]},"apptools.help.help_plugin.help_submenu_manager":{DemosMenuManager:[5,1,1,""],DocumentsMenuManager:[5,1,1,""],DownloadsMenuManager:[5,1,1,""],ExamplesMenuManager:[5,1,1,""],HelpSubmenuManager:[5,1,1,""]},"apptools.help.help_plugin.i_help_code":{IHelpCode:[5,1,1,""]},"apptools.help.help_plugin.i_help_doc":{IHelpDoc:[5,1,1,""]},"apptools.help.help_plugin.preferences_pages":{DemosPreferencesPage:[5,1,1,""],DocumentsPreferencesPage:[5,1,1,""],ExamplesPreferencesPage:[5,1,1,""],HelpDemoPreferencesPage:[5,1,1,""],HelpDocPreferencesPage:[5,1,1,""],HelpExamplePreferencesPage:[5,1,1,""],HelpPreferencesPage:[5,1,1,""]},"apptools.io":{api:[7,0,0,"-"],file:[7,0,0,"-"],h5:[8,0,0,"-"]},"apptools.io.file":{File:[7,1,1,""]},"apptools.io.file.File":{"delete":[7,2,1,""],copy:[7,2,1,""],create_file:[7,2,1,""],create_folder:[7,2,1,""],create_folders:[7,2,1,""],create_package:[7,2,1,""],make_writeable:[7,2,1,""],move:[7,2,1,""]},"apptools.io.h5":{dict_node:[8,0,0,"-"],file:[8,0,0,"-"],table_node:[8,0,0,"-"],utils:[8,0,0,"-"]},"apptools.io.h5.dict_node":{ARRAY_PROXY_KEY:[8,6,1,""],H5DictNode:[8,1,1,""]},"apptools.io.h5.dict_node.H5DictNode":{add_to_h5file:[8,7,1,""],data:[8,5,1,""],flush:[8,2,1,""],is_dict_node:[8,7,1,""],keys:[8,2,1,""]},"apptools.io.h5.file":{H5Attrs:[8,1,1,""],H5File:[8,1,1,""],H5Group:[8,1,1,""],get_atom:[8,3,1,""],h5_group_wrapper:[8,3,1,""],iterator_length:[8,3,1,""]},"apptools.io.h5.file.H5Attrs":{get:[8,2,1,""],items:[8,2,1,""],keys:[8,2,1,""],values:[8,2,1,""]},"apptools.io.h5.file.H5File":{close:[8,2,1,""],create_array:[8,2,1,""],create_dict:[8,2,1,""],create_group:[8,2,1,""],create_table:[8,2,1,""],exists_error:[8,5,1,""],is_open:[8,5,1,""],iteritems:[8,2,1,""],join_path:[8,7,1,""],open:[8,2,1,""],remove_group:[8,2,1,""],remove_node:[8,2,1,""],root:[8,5,1,""],split_path:[8,7,1,""]},"apptools.io.h5.file.H5Group":{children_names:[8,5,1,""],create_array:[8,2,1,""],create_dict:[8,2,1,""],create_group:[8,2,1,""],create_table:[8,2,1,""],filename:[8,5,1,""],iter_groups:[8,2,1,""],name:[8,5,1,""],pathname:[8,5,1,""],remove_group:[8,2,1,""],remove_node:[8,2,1,""],root:[8,5,1,""],subgroup_names:[8,5,1,""]},"apptools.io.h5.table_node":{H5TableNode:[8,1,1,""]},"apptools.io.h5.table_node.H5TableNode":{add_to_h5file:[8,7,1,""],append:[8,2,1,""],is_table_node:[8,7,1,""],ix:[8,5,1,""],keys:[8,2,1,""],to_dataframe:[8,2,1,""]},"apptools.io.h5.utils":{open_h5file:[8,3,1,""]},"apptools.logger":{agent:[10,0,0,"-"],api:[9,0,0,"-"],custom_excepthook:[9,0,0,"-"],filtering_handler:[9,0,0,"-"],log_point:[9,0,0,"-"],log_queue_handler:[9,0,0,"-"],logger:[9,0,0,"-"],null_handler:[9,0,0,"-"],plugin:[11,0,0,"-"],ring_buffer:[9,0,0,"-"],util:[9,0,0,"-"]},"apptools.logger.agent":{attachments:[10,0,0,"-"],quality_agent_mailer:[10,0,0,"-"],quality_agent_view:[10,0,0,"-"]},"apptools.logger.agent.attachments":{Attachments:[10,1,1,""]},"apptools.logger.agent.attachments.Attachments":{package_any_relevant_files:[10,2,1,""],package_single_project:[10,2,1,""],package_workspace:[10,2,1,""]},"apptools.logger.agent.quality_agent_mailer":{create_email_message:[10,3,1,""]},"apptools.logger.agent.quality_agent_view":{QualityAgentView:[10,1,1,""]},"apptools.logger.agent.quality_agent_view.QualityAgentView":{cc_address:[10,5,1,""],comments:[10,5,1,""],from_address:[10,5,1,""],help_id:[10,5,1,""],include_userdata:[10,5,1,""],msg:[10,5,1,""],priority:[10,5,1,""],service:[10,5,1,""],size:[10,5,1,""],smtp_server:[10,5,1,""],subject:[10,5,1,""],title:[10,5,1,""],to_address:[10,5,1,""]},"apptools.logger.custom_excepthook":{custom_excepthook:[9,3,1,""]},"apptools.logger.filtering_handler":{FilteringHandler:[9,1,1,""]},"apptools.logger.filtering_handler.FilteringHandler":{emit:[9,2,1,""],filtered_emit:[9,2,1,""]},"apptools.logger.log_point":{log_point:[9,3,1,""]},"apptools.logger.log_queue_handler":{LogQueueHandler:[9,1,1,""]},"apptools.logger.log_queue_handler.LogQueueHandler":{emit:[9,2,1,""],get:[9,2,1,""],has_new_records:[9,2,1,""],reset:[9,2,1,""]},"apptools.logger.logger":{LogFileHandler:[9,1,1,""],add_log_queue_handler:[9,3,1,""],create_log_file_handler:[9,3,1,""]},"apptools.logger.null_handler":{NullHandler:[9,1,1,""]},"apptools.logger.null_handler.NullHandler":{emit:[9,2,1,""]},"apptools.logger.plugin":{logger_plugin:[11,0,0,"-"],logger_preferences:[11,0,0,"-"],logger_service:[11,0,0,"-"],view:[12,0,0,"-"]},"apptools.logger.plugin.logger_plugin":{LoggerPlugin:[11,1,1,""]},"apptools.logger.plugin.logger_plugin.LoggerPlugin":{MAIL_FILES:[11,5,1,""],PREFERENCES:[11,5,1,""],PREFERENCES_PAGES:[11,5,1,""],VIEWS:[11,5,1,""],start:[11,2,1,""],stop:[11,2,1,""]},"apptools.logger.plugin.logger_preferences":{LoggerPreferences:[11,1,1,""]},"apptools.logger.plugin.logger_service":{LoggerService:[11,1,1,""]},"apptools.logger.plugin.logger_service.LoggerService":{create_email_message:[11,2,1,""],save_preferences:[11,2,1,""],send_bug_report:[11,2,1,""],whole_log_text:[11,2,1,""]},"apptools.logger.plugin.view":{logger_preferences_page:[12,0,0,"-"],logger_view:[12,0,0,"-"]},"apptools.logger.plugin.view.logger_preferences_page":{LoggerPreferencesPage:[12,1,1,""]},"apptools.logger.plugin.view.logger_view":{LogRecordAdapter:[12,1,1,""],LoggerView:[12,1,1,""]},"apptools.logger.plugin.view.logger_view.LogRecordAdapter":{column_widths:[12,5,1,""],get_width:[12,2,1,""]},"apptools.logger.plugin.view.logger_view.LoggerView":{activated:[12,5,1,""],activated_text:[12,5,1,""],code_editor:[12,5,1,""],copy_button:[12,5,1,""],formatted_records:[12,5,1,""],id:[12,5,1,""],log_records:[12,5,1,""],log_records_editor:[12,5,1,""],name:[12,5,1,""],reset_button:[12,5,1,""],service:[12,5,1,""],show_button:[12,5,1,""],trait_view:[12,5,1,""],update:[12,2,1,""]},"apptools.logger.ring_buffer":{RingBuffer:[9,1,1,""],RingBufferFull:[9,1,1,""]},"apptools.logger.ring_buffer.RingBuffer":{append:[9,2,1,""],get:[9,2,1,""]},"apptools.logger.ring_buffer.RingBufferFull":{append:[9,2,1,""],get:[9,2,1,""]},"apptools.logger.util":{get_module_name:[9,3,1,""],get_module_name_from_zip:[9,3,1,""],get_zip_path:[9,3,1,""],is_zip_path:[9,3,1,""],path_exists_in_zip:[9,3,1,""]},"apptools.lru_cache":{lru_cache:[13,0,0,"-"]},"apptools.lru_cache.lru_cache":{LRUCache:[13,1,1,""]},"apptools.lru_cache.lru_cache.LRUCache":{clear:[13,2,1,""],get:[13,2,1,""],items:[13,2,1,""],keys:[13,2,1,""],values:[13,2,1,""]},"apptools.naming":{adapter:[15,0,0,"-"],address:[14,0,0,"-"],api:[14,0,0,"-"],binding:[14,0,0,"-"],context:[14,0,0,"-"],context_adapter:[14,0,0,"-"],context_adapter_factory:[14,0,0,"-"],dir_context:[14,0,0,"-"],dynamic_context:[14,0,0,"-"],exception:[14,0,0,"-"],initial_context:[14,0,0,"-"],initial_context_factory:[14,0,0,"-"],naming_event:[14,0,0,"-"],naming_manager:[14,0,0,"-"],object_factory:[14,0,0,"-"],object_serializer:[14,0,0,"-"],py_context:[14,0,0,"-"],py_object_factory:[14,0,0,"-"],pyfs_context:[14,0,0,"-"],pyfs_context_factory:[14,0,0,"-"],pyfs_initial_context_factory:[14,0,0,"-"],pyfs_object_factory:[14,0,0,"-"],pyfs_state_factory:[14,0,0,"-"],reference:[14,0,0,"-"],referenceable:[14,0,0,"-"],referenceable_state_factory:[14,0,0,"-"],state_factory:[14,0,0,"-"],trait_defs:[16,0,0,"-"],ui:[17,0,0,"-"],unique_name:[14,0,0,"-"]},"apptools.naming.adapter":{api:[15,0,0,"-"],dict_context_adapter:[15,0,0,"-"],dict_context_adapter_factory:[15,0,0,"-"],instance_context_adapter:[15,0,0,"-"],instance_context_adapter_factory:[15,0,0,"-"],list_context_adapter:[15,0,0,"-"],list_context_adapter_factory:[15,0,0,"-"],trait_dict_context_adapter:[15,0,0,"-"],trait_dict_context_adapter_factory:[15,0,0,"-"],trait_list_context_adapter:[15,0,0,"-"],trait_list_context_adapter_factory:[15,0,0,"-"],tuple_context_adapter:[15,0,0,"-"],tuple_context_adapter_factory:[15,0,0,"-"]},"apptools.naming.adapter.dict_context_adapter":{DictContextAdapter:[15,1,1,""]},"apptools.naming.adapter.dict_context_adapter_factory":{DictContextAdapterFactory:[15,1,1,""]},"apptools.naming.adapter.instance_context_adapter":{InstanceContextAdapter:[15,1,1,""]},"apptools.naming.adapter.instance_context_adapter_factory":{InstanceContextAdapterFactory:[15,1,1,""]},"apptools.naming.adapter.list_context_adapter":{ListContextAdapter:[15,1,1,""]},"apptools.naming.adapter.list_context_adapter_factory":{ListContextAdapterFactory:[15,1,1,""]},"apptools.naming.adapter.trait_dict_context_adapter":{TraitDictContextAdapter:[15,1,1,""]},"apptools.naming.adapter.trait_dict_context_adapter_factory":{TraitDictContextAdapterFactory:[15,1,1,""]},"apptools.naming.adapter.trait_list_context_adapter":{TraitListContextAdapter:[15,1,1,""]},"apptools.naming.adapter.trait_list_context_adapter_factory":{TraitListContextAdapterFactory:[15,1,1,""]},"apptools.naming.adapter.tuple_context_adapter":{TupleContextAdapter:[15,1,1,""]},"apptools.naming.adapter.tuple_context_adapter_factory":{TupleContextAdapterFactory:[15,1,1,""]},"apptools.naming.address":{Address:[14,1,1,""]},"apptools.naming.binding":{Binding:[14,1,1,""]},"apptools.naming.context":{Context:[14,1,1,""]},"apptools.naming.context.Context":{INITIAL_CONTEXT_FACTORY:[14,5,1,""],OBJECT_FACTORIES:[14,5,1,""],STATE_FACTORIES:[14,5,1,""],TYPE_MANAGER:[14,5,1,""],bind:[14,2,1,""],create_subcontext:[14,2,1,""],destroy_subcontext:[14,2,1,""],get_unique_name:[14,2,1,""],is_context:[14,2,1,""],list_bindings:[14,2,1,""],list_names:[14,2,1,""],lookup:[14,2,1,""],lookup_binding:[14,2,1,""],lookup_context:[14,2,1,""],rebind:[14,2,1,""],rename:[14,2,1,""],search:[14,2,1,""],unbind:[14,2,1,""]},"apptools.naming.context_adapter":{ContextAdapter:[14,1,1,""]},"apptools.naming.context_adapter_factory":{ContextAdapterFactory:[14,1,1,""]},"apptools.naming.dir_context":{DirContext:[14,1,1,""]},"apptools.naming.dir_context.DirContext":{find_bindings:[14,2,1,""],get_attributes:[14,2,1,""],set_attributes:[14,2,1,""]},"apptools.naming.dynamic_context":{DynamicContext:[14,1,1,""]},"apptools.naming.exception":{InvalidNameError:[14,8,1,""],NameAlreadyBoundError:[14,8,1,""],NameNotFoundError:[14,8,1,""],NamingError:[14,8,1,""],NotContextError:[14,8,1,""],OperationNotSupportedError:[14,8,1,""]},"apptools.naming.initial_context":{InitialContext:[14,3,1,""]},"apptools.naming.initial_context_factory":{InitialContextFactory:[14,1,1,""]},"apptools.naming.initial_context_factory.InitialContextFactory":{get_initial_context:[14,2,1,""]},"apptools.naming.naming_event":{NamingEvent:[14,1,1,""]},"apptools.naming.naming_manager":{NamingManager:[14,1,1,""]},"apptools.naming.naming_manager.NamingManager":{get_object_instance:[14,2,1,""],get_state_to_bind:[14,2,1,""]},"apptools.naming.object_factory":{ObjectFactory:[14,1,1,""]},"apptools.naming.object_factory.ObjectFactory":{get_object_instance:[14,2,1,""]},"apptools.naming.object_serializer":{ObjectSerializer:[14,1,1,""]},"apptools.naming.object_serializer.ObjectSerializer":{can_load:[14,2,1,""],can_save:[14,2,1,""],load:[14,2,1,""],save:[14,2,1,""]},"apptools.naming.py_context":{PyContext:[14,1,1,""]},"apptools.naming.py_object_factory":{PyObjectFactory:[14,1,1,""]},"apptools.naming.py_object_factory.PyObjectFactory":{get_object_instance:[14,2,1,""]},"apptools.naming.pyfs_context":{PyFSContext:[14,1,1,""]},"apptools.naming.pyfs_context.PyFSContext":{ATTRIBUTES_FILE:[14,5,1,""],FILTERS:[14,5,1,""],OBJECT_SERIALIZERS:[14,5,1,""],get_unique_name:[14,2,1,""],refresh:[14,2,1,""]},"apptools.naming.pyfs_context_factory":{PyFSContextFactory:[14,1,1,""]},"apptools.naming.pyfs_context_factory.PyFSContextFactory":{get_object_instance:[14,2,1,""]},"apptools.naming.pyfs_initial_context_factory":{PyFSInitialContextFactory:[14,1,1,""]},"apptools.naming.pyfs_initial_context_factory.PyFSInitialContextFactory":{get_initial_context:[14,2,1,""]},"apptools.naming.pyfs_object_factory":{PyFSObjectFactory:[14,1,1,""]},"apptools.naming.pyfs_object_factory.PyFSObjectFactory":{get_object_instance:[14,2,1,""]},"apptools.naming.pyfs_state_factory":{PyFSStateFactory:[14,1,1,""]},"apptools.naming.pyfs_state_factory.PyFSStateFactory":{get_state_to_bind:[14,2,1,""]},"apptools.naming.reference":{Reference:[14,1,1,""]},"apptools.naming.referenceable":{Referenceable:[14,1,1,""]},"apptools.naming.referenceable_state_factory":{ReferenceableStateFactory:[14,1,1,""]},"apptools.naming.referenceable_state_factory.ReferenceableStateFactory":{get_state_to_bind:[14,2,1,""]},"apptools.naming.state_factory":{StateFactory:[14,1,1,""]},"apptools.naming.state_factory.StateFactory":{get_state_to_bind:[14,2,1,""]},"apptools.naming.trait_defs":{api:[16,0,0,"-"],naming_traits:[16,0,0,"-"]},"apptools.naming.trait_defs.naming_traits":{NamingTraitHandler:[16,1,1,""]},"apptools.naming.trait_defs.naming_traits.NamingTraitHandler":{find_class:[16,2,1,""],get_editor:[16,2,1,""],info:[16,2,1,""],post_setattr:[16,2,1,""],resolve_class:[16,2,1,""],validate:[16,2,1,""],validate_failed:[16,2,1,""]},"apptools.naming.ui":{api:[17,0,0,"-"],context_monitor:[17,0,0,"-"],context_node_type:[17,0,0,"-"],explorer:[17,0,0,"-"],naming_node_manager:[17,0,0,"-"],naming_tree:[17,0,0,"-"],naming_tree_model:[17,0,0,"-"],object_node_type:[17,0,0,"-"]},"apptools.naming.ui.context_monitor":{ContextMonitor:[17,1,1,""]},"apptools.naming.ui.context_monitor.ContextMonitor":{start:[17,2,1,""],stop:[17,2,1,""]},"apptools.naming.ui.context_node_type":{ContextNodeType:[17,1,1,""]},"apptools.naming.ui.context_node_type.ContextNodeType":{allows_children:[17,2,1,""],can_set_text:[17,2,1,""],get_children:[17,2,1,""],get_drag_value:[17,2,1,""],get_monitor:[17,2,1,""],get_text:[17,2,1,""],has_children:[17,2,1,""],is_editable:[17,2,1,""],is_type_for:[17,2,1,""],set_text:[17,2,1,""]},"apptools.naming.ui.explorer":{Explorer:[17,1,1,""],explore:[17,3,1,""]},"apptools.naming.ui.explorer.Explorer":{direction:[17,5,1,""],ratio:[17,5,1,""],root:[17,5,1,""],title:[17,5,1,""]},"apptools.naming.ui.naming_node_manager":{NamingNodeManager:[17,1,1,""]},"apptools.naming.ui.naming_node_manager.NamingNodeManager":{get_key:[17,2,1,""]},"apptools.naming.ui.naming_tree":{NamingTree:[17,1,1,""]},"apptools.naming.ui.naming_tree.NamingTree":{ensure_visible:[17,2,1,""],model:[17,5,1,""]},"apptools.naming.ui.naming_tree_model":{NamingTreeModel:[17,1,1,""]},"apptools.naming.ui.object_node_type":{ObjectNodeType:[17,1,1,""]},"apptools.naming.ui.object_node_type.ObjectNodeType":{allows_children:[17,2,1,""],can_set_text:[17,2,1,""],get_drag_value:[17,2,1,""],get_text:[17,2,1,""],is_editable:[17,2,1,""],is_type_for:[17,2,1,""],set_text:[17,2,1,""]},"apptools.naming.unique_name":{make_unique_name:[14,3,1,""]},"apptools.permissions":{"default":[21,0,0,"-"],action:[19,0,0,"-"],adapter_base:[18,0,0,"-"],adapters:[20,0,0,"-"],api:[18,0,0,"-"],i_policy_manager:[18,0,0,"-"],i_user:[18,0,0,"-"],i_user_manager:[18,0,0,"-"],package_globals:[18,0,0,"-"],permission:[18,0,0,"-"],permissions_manager:[18,0,0,"-"],secure_proxy:[18,0,0,"-"]},"apptools.permissions.action":{api:[19,0,0,"-"],login_action:[19,0,0,"-"],logout_action:[19,0,0,"-"],user_menu_manager:[19,0,0,"-"]},"apptools.permissions.action.login_action":{LoginAction:[19,1,1,""]},"apptools.permissions.action.login_action.LoginAction":{perform:[19,2,1,""]},"apptools.permissions.action.logout_action":{LogoutAction:[19,1,1,""]},"apptools.permissions.action.logout_action.LogoutAction":{perform:[19,2,1,""]},"apptools.permissions.action.user_menu_manager":{UserMenuManager:[19,1,1,""]},"apptools.permissions.adapter_base":{AdapterBase:[18,1,1,""]},"apptools.permissions.adapter_base.AdapterBase":{adapt:[18,2,1,""],factory:[18,7,1,""],get_enabled:[18,2,1,""],get_visible:[18,2,1,""],register_adapter:[18,7,1,""],set_enabled:[18,2,1,""],set_visible:[18,2,1,""],setattr:[18,2,1,""],update_enabled:[18,2,1,""],update_visible:[18,2,1,""]},"apptools.permissions.adapters":{pyface_action:[20,0,0,"-"]},"apptools.permissions.adapters.pyface_action":{ActionAdapter:[20,1,1,""]},"apptools.permissions.adapters.pyface_action.ActionAdapter":{get_enabled:[20,2,1,""],get_visible:[20,2,1,""],set_enabled:[20,2,1,""],set_visible:[20,2,1,""],setattr:[20,2,1,""]},"apptools.permissions.default":{api:[21,0,0,"-"],i_policy_storage:[21,0,0,"-"],i_user_database:[21,0,0,"-"],i_user_storage:[21,0,0,"-"],persistent:[21,0,0,"-"],policy_data:[21,0,0,"-"],policy_manager:[21,0,0,"-"],policy_storage:[21,0,0,"-"],role_assignment:[21,0,0,"-"],role_definition:[21,0,0,"-"],select_role:[21,0,0,"-"],select_user:[21,0,0,"-"],user_database:[21,0,0,"-"],user_manager:[21,0,0,"-"],user_storage:[21,0,0,"-"]},"apptools.permissions.default.i_policy_storage":{IPolicyStorage:[21,1,1,""],PolicyStorageError:[21,8,1,""]},"apptools.permissions.default.i_policy_storage.IPolicyStorage":{add_role:[21,2,1,""],all_roles:[21,2,1,""],delete_role:[21,2,1,""],get_assignment:[21,2,1,""],get_policy:[21,2,1,""],is_empty:[21,2,1,""],matching_roles:[21,2,1,""],modify_role:[21,2,1,""],set_assignment:[21,2,1,""]},"apptools.permissions.default.i_user_database":{IUserDatabase:[21,1,1,""]},"apptools.permissions.default.i_user_database.IUserDatabase":{add_user:[21,2,1,""],authenticate_user:[21,2,1,""],bootstrapping:[21,2,1,""],change_password:[21,2,1,""],delete_user:[21,2,1,""],matching_user:[21,2,1,""],modify_user:[21,2,1,""],unauthenticate_user:[21,2,1,""],user_factory:[21,2,1,""]},"apptools.permissions.default.i_user_storage":{IUserStorage:[21,1,1,""],UserStorageError:[21,8,1,""]},"apptools.permissions.default.i_user_storage.IUserStorage":{add_user:[21,2,1,""],authenticate_user:[21,2,1,""],delete_user:[21,2,1,""],is_empty:[21,2,1,""],matching_users:[21,2,1,""],modify_user:[21,2,1,""],unauthenticate_user:[21,2,1,""],update_blob:[21,2,1,""],update_password:[21,2,1,""]},"apptools.permissions.default.persistent":{Persistent:[21,1,1,""],PersistentError:[21,8,1,""]},"apptools.permissions.default.persistent.Persistent":{lock:[21,2,1,""],read:[21,2,1,""],unlock:[21,2,1,""],write:[21,2,1,""]},"apptools.permissions.default.policy_data":{Assignment:[21,1,1,""],Role:[21,1,1,""]},"apptools.permissions.default.policy_manager":{PolicyManager:[21,1,1,""]},"apptools.permissions.default.policy_manager.PolicyManager":{bootstrapping:[21,2,1,""],load_policy:[21,2,1,""],register_permission:[21,2,1,""]},"apptools.permissions.default.policy_storage":{PolicyStorage:[21,1,1,""]},"apptools.permissions.default.policy_storage.PolicyStorage":{add_role:[21,2,1,""],all_roles:[21,2,1,""],delete_role:[21,2,1,""],get_assignment:[21,2,1,""],get_policy:[21,2,1,""],is_empty:[21,2,1,""],matching_roles:[21,2,1,""],modify_role:[21,2,1,""],set_assignment:[21,2,1,""]},"apptools.permissions.default.role_assignment":{role_assignment:[21,3,1,""]},"apptools.permissions.default.role_definition":{role_definition:[21,3,1,""]},"apptools.permissions.default.select_role":{select_role:[21,3,1,""]},"apptools.permissions.default.select_user":{select_user:[21,3,1,""]},"apptools.permissions.default.user_database":{User:[21,1,1,""],UserDatabase:[21,1,1,""]},"apptools.permissions.default.user_database.UserDatabase":{add_user:[21,2,1,""],authenticate_user:[21,2,1,""],bootstrapping:[21,2,1,""],change_password:[21,2,1,""],delete_user:[21,2,1,""],matching_user:[21,2,1,""],modify_user:[21,2,1,""],unauthenticate_user:[21,2,1,""],user_factory:[21,2,1,""]},"apptools.permissions.default.user_manager":{UserManager:[21,1,1,""]},"apptools.permissions.default.user_manager.UserManager":{authenticate_user:[21,2,1,""],bootstrapping:[21,2,1,""],matching_user:[21,2,1,""],unauthenticate_user:[21,2,1,""]},"apptools.permissions.default.user_storage":{UserStorage:[21,1,1,""]},"apptools.permissions.default.user_storage.UserStorage":{add_user:[21,2,1,""],authenticate_user:[21,2,1,""],capabilities:[21,5,1,""],delete_user:[21,2,1,""],is_empty:[21,2,1,""],matching_users:[21,2,1,""],modify_user:[21,2,1,""],unauthenticate_user:[21,2,1,""],update_blob:[21,2,1,""],update_password:[21,2,1,""]},"apptools.permissions.i_policy_manager":{IPolicyManager:[18,1,1,""]},"apptools.permissions.i_policy_manager.IPolicyManager":{bootstrapping:[18,2,1,""],load_user:[18,2,1,""],register_permission:[18,2,1,""]},"apptools.permissions.i_user":{IUser:[18,1,1,""]},"apptools.permissions.i_user_manager":{IUserManager:[18,1,1,""]},"apptools.permissions.i_user_manager.IUserManager":{authenticate_user:[18,2,1,""],bootstrapping:[18,2,1,""],select_user:[18,2,1,""],unauthenticate_user:[18,2,1,""]},"apptools.permissions.package_globals":{get_permissions_manager:[18,3,1,""],set_permissions_manager:[18,3,1,""]},"apptools.permissions.permission":{ManagePolicyPermission:[18,1,1,""],ManageUsersPermission:[18,1,1,""],Permission:[18,1,1,""]},"apptools.permissions.permissions_manager":{PermissionsManager:[18,1,1,""]},"apptools.permissions.permissions_manager.PermissionsManager":{check_permissions:[18,2,1,""]},"apptools.permissions.secure_proxy":{SecureHandler:[18,1,1,""],SecureProxy:[18,1,1,""]},"apptools.permissions.secure_proxy.SecureHandler":{init_info:[18,2,1,""]},"apptools.persistence":{file_path:[22,0,0,"-"],project_loader:[22,0,0,"-"],state_pickler:[22,0,0,"-"],updater:[22,0,0,"-"],version_registry:[22,0,0,"-"],versioned_unpickler:[22,0,0,"-"]},"apptools.persistence.file_path":{FilePath:[22,1,1,""]},"apptools.persistence.file_path.FilePath":{get:[22,2,1,""],set:[22,2,1,""],set_absolute:[22,2,1,""],set_relative:[22,2,1,""]},"apptools.persistence.project_loader":{load_project:[22,3,1,""],upgrade_project:[22,3,1,""]},"apptools.persistence.state_pickler":{State:[22,1,1,""],StateDict:[22,1,1,""],StateList:[22,1,1,""],StatePickler:[22,1,1,""],StatePicklerError:[22,8,1,""],StateSetter:[22,1,1,""],StateSetterError:[22,8,1,""],StateTuple:[22,1,1,""],StateUnpickler:[22,1,1,""],StateUnpicklerError:[22,8,1,""],create_instance:[22,3,1,""],dump:[22,3,1,""],dumps:[22,3,1,""],get_state:[22,3,1,""],gunzip_string:[22,3,1,""],gzip_string:[22,3,1,""],load_state:[22,3,1,""],loads_state:[22,3,1,""],set_state:[22,3,1,""],update_state:[22,3,1,""]},"apptools.persistence.state_pickler.StatePickler":{dump:[22,2,1,""],dump_state:[22,2,1,""],dumps:[22,2,1,""]},"apptools.persistence.state_pickler.StateSetter":{set:[22,2,1,""]},"apptools.persistence.state_pickler.StateUnpickler":{load_state:[22,2,1,""],loads_state:[22,2,1,""]},"apptools.persistence.updater":{Updater:[22,1,1,""]},"apptools.persistence.updater.Updater":{get_latest:[22,2,1,""],strip:[22,2,1,""]},"apptools.persistence.version_registry":{HandlerRegistry:[22,1,1,""],get_version:[22,3,1,""]},"apptools.persistence.version_registry.HandlerRegistry":{register:[22,2,1,""],unregister:[22,2,1,""],update:[22,2,1,""]},"apptools.persistence.versioned_unpickler":{NewUnpickler:[22,1,1,""],VersionedUnpickler:[22,1,1,""]},"apptools.persistence.versioned_unpickler.NewUnpickler":{initialize:[22,2,1,""],load:[22,2,1,""],load_build:[22,7,1,""]},"apptools.persistence.versioned_unpickler.VersionedUnpickler":{add_updater:[22,2,1,""],backup_setstate:[22,2,1,""],find_class:[22,2,1,""],import_name:[22,2,1,""]},"apptools.preferences":{api:[23,0,0,"-"],i_preferences:[23,0,0,"-"],package_globals:[23,0,0,"-"],preference_binding:[23,0,0,"-"],preferences:[23,0,0,"-"],preferences_helper:[23,0,0,"-"],scoped_preferences:[23,0,0,"-"],ui:[24,0,0,"-"]},"apptools.preferences.i_preferences":{IPreferences:[23,1,1,""]},"apptools.preferences.i_preferences.IPreferences":{clear:[23,2,1,""],flush:[23,2,1,""],get:[23,2,1,""],keys:[23,2,1,""],node:[23,2,1,""],node_exists:[23,2,1,""],node_names:[23,2,1,""],remove:[23,2,1,""],set:[23,2,1,""]},"apptools.preferences.package_globals":{get_default_preferences:[23,3,1,""],set_default_preferences:[23,3,1,""]},"apptools.preferences.preference_binding":{PreferenceBinding:[23,1,1,""],bind_preference:[23,3,1,""]},"apptools.preferences.preferences":{Preferences:[23,1,1,""]},"apptools.preferences.preferences.Preferences":{add_preferences_listener:[23,2,1,""],clear:[23,2,1,""],dump:[23,2,1,""],flush:[23,2,1,""],get:[23,2,1,""],keys:[23,2,1,""],load:[23,2,1,""],node:[23,2,1,""],node_exists:[23,2,1,""],node_names:[23,2,1,""],remove:[23,2,1,""],remove_preferences_listener:[23,2,1,""],save:[23,2,1,""],set:[23,2,1,""]},"apptools.preferences.preferences_helper":{PreferencesHelper:[23,1,1,""]},"apptools.preferences.scoped_preferences":{ScopedPreferences:[23,1,1,""]},"apptools.preferences.scoped_preferences.ScopedPreferences":{add_preferences_listener:[23,2,1,""],clear:[23,2,1,""],dump:[23,2,1,""],get:[23,2,1,""],get_scope:[23,2,1,""],keys:[23,2,1,""],load:[23,2,1,""],node:[23,2,1,""],node_exists:[23,2,1,""],node_names:[23,2,1,""],remove:[23,2,1,""],remove_preferences_listener:[23,2,1,""],save:[23,2,1,""],set:[23,2,1,""]},"apptools.preferences.ui":{api:[24,0,0,"-"],i_preferences_page:[24,0,0,"-"],preferences_manager:[24,0,0,"-"],preferences_node:[24,0,0,"-"],preferences_page:[24,0,0,"-"],tree_item:[24,0,0,"-"]},"apptools.preferences.ui.i_preferences_page":{IPreferencesPage:[24,1,1,""]},"apptools.preferences.ui.i_preferences_page.IPreferencesPage":{apply:[24,2,1,""]},"apptools.preferences.ui.preferences_manager":{PreferencesHelpWindow:[24,1,1,""],PreferencesManager:[24,1,1,""],PreferencesManagerHandler:[24,1,1,""]},"apptools.preferences.ui.preferences_manager.PreferencesHelpWindow":{traits_view:[24,2,1,""]},"apptools.preferences.ui.preferences_manager.PreferencesManager":{apply:[24,2,1,""],traits_view:[24,2,1,""]},"apptools.preferences.ui.preferences_manager.PreferencesManagerHandler":{apply:[24,2,1,""],close:[24,2,1,""],init:[24,2,1,""],preferences_help:[24,2,1,""]},"apptools.preferences.ui.preferences_node":{PreferencesNode:[24,1,1,""]},"apptools.preferences.ui.preferences_node.PreferencesNode":{create_page:[24,2,1,""],dump:[24,2,1,""],lookup:[24,2,1,""]},"apptools.preferences.ui.preferences_page":{PreferencesPage:[24,1,1,""]},"apptools.preferences.ui.preferences_page.PreferencesPage":{apply:[24,2,1,""]},"apptools.preferences.ui.tree_item":{TreeItem:[24,1,1,""]},"apptools.preferences.ui.tree_item.TreeItem":{append:[24,2,1,""],insert:[24,2,1,""],insert_after:[24,2,1,""],insert_before:[24,2,1,""],remove:[24,2,1,""]},"apptools.scripting":{api:[25,0,0,"-"],package_globals:[25,0,0,"-"],recordable:[25,0,0,"-"],recorder:[25,0,0,"-"],recorder_with_ui:[25,0,0,"-"],util:[25,0,0,"-"]},"apptools.scripting.package_globals":{get_recorder:[25,3,1,""],set_recorder:[25,3,1,""]},"apptools.scripting.recordable":{recordable:[25,3,1,""]},"apptools.scripting.recorder":{Recorder:[25,1,1,""],RecorderError:[25,8,1,""]},"apptools.scripting.recorder.Recorder":{clear:[25,2,1,""],get_code:[25,2,1,""],get_object_path:[25,2,1,""],get_script_id:[25,2,1,""],is_registered:[25,2,1,""],record:[25,2,1,""],record_function:[25,2,1,""],register:[25,2,1,""],save:[25,2,1,""],ui_save:[25,2,1,""],unregister:[25,2,1,""],write_script_id_in_namespace:[25,2,1,""]},"apptools.scripting.recorder_with_ui":{CloseHandler:[25,1,1,""],RecorderWithUI:[25,1,1,""]},"apptools.scripting.recorder_with_ui.CloseHandler":{close:[25,2,1,""]},"apptools.scripting.recorder_with_ui.RecorderWithUI":{on_ui_close:[25,2,1,""]},"apptools.scripting.util":{start_recording:[25,3,1,""],stop_recording:[25,3,1,""]},"apptools.selection":{api:[26,0,0,"-"],errors:[45,0,0,"-"],i_selection:[45,0,0,"-"],i_selection_provider:[45,0,0,"-"],list_selection:[45,0,0,"-"],selection_service:[45,0,0,"-"]},"apptools.selection.errors":{IDConflictError:[45,8,1,""],ListenerNotConnectedError:[45,8,1,""],ProviderNotRegisteredError:[45,8,1,""]},"apptools.selection.i_selection":{IListSelection:[45,1,1,""],ISelection:[45,1,1,""]},"apptools.selection.i_selection.IListSelection":{indices:[45,5,1,""],items:[45,5,1,""]},"apptools.selection.i_selection.ISelection":{is_empty:[45,2,1,""],provider_id:[45,5,1,""]},"apptools.selection.i_selection_provider":{ISelectionProvider:[45,1,1,""]},"apptools.selection.i_selection_provider.ISelectionProvider":{get_selection:[45,2,1,""],provider_id:[45,5,1,""],selection:[45,5,1,""],set_selection:[45,2,1,""]},"apptools.selection.list_selection":{ListSelection:[45,1,1,""]},"apptools.selection.list_selection.ListSelection":{from_available_items:[45,7,1,""],indices:[45,5,1,""],is_empty:[45,2,1,""],items:[45,5,1,""],provider_id:[45,5,1,""]},"apptools.selection.selection_service":{SelectionService:[45,1,1,""]},"apptools.selection.selection_service.SelectionService":{add_selection_provider:[45,2,1,""],connect_selection_listener:[45,2,1,""],disconnect_selection_listener:[45,2,1,""],get_selection:[45,2,1,""],has_selection_provider:[45,2,1,""],remove_selection_provider:[45,2,1,""],set_selection:[45,2,1,""]},"apptools.sweet_pickle":{dump:[27,3,1,""],dumps:[27,3,1,""],global_registry:[27,0,0,"-"],load:[27,3,1,""],loads:[27,3,1,""],placeholder:[27,0,0,"-"],updater:[27,0,0,"-"],versioned_unpickler:[27,0,0,"-"]},"apptools.sweet_pickle.global_registry":{get_global_registry:[27,3,1,""]},"apptools.sweet_pickle.placeholder":{PlaceHolder:[27,1,1,""]},"apptools.sweet_pickle.updater":{Updater:[27,1,1,""]},"apptools.sweet_pickle.updater.Updater":{add_mapping:[27,2,1,""],add_mapping_to_class:[27,2,1,""],add_mappings:[27,2,1,""],add_state_function:[27,2,1,""],add_state_function_for_class:[27,2,1,""],declare_version_attribute:[27,2,1,""],declare_version_attribute_for_class:[27,2,1,""],get_version_attribute:[27,2,1,""],has_class_mapping:[27,2,1,""],has_state_function:[27,2,1,""],merge_updater:[27,2,1,""]},"apptools.sweet_pickle.versioned_unpickler":{NewUnpickler:[27,1,1,""],VersionedUnpickler:[27,1,1,""],load_build_with_meta_data:[27,3,1,""]},"apptools.sweet_pickle.versioned_unpickler.NewUnpickler":{initialize:[27,2,1,""],load:[27,2,1,""],load_build:[27,7,1,""]},"apptools.sweet_pickle.versioned_unpickler.VersionedUnpickler":{find_class:[27,2,1,""],modify_state:[27,2,1,""]},"apptools.template":{impl:[29,0,0,"-"],imutable_template:[28,0,0,"-"],itemplate:[28,0,0,"-"],itemplate_choice:[28,0,0,"-"],itemplate_data_context:[28,0,0,"-"],itemplate_data_name_item:[28,0,0,"-"],itemplate_data_source:[28,0,0,"-"],mutable_template:[28,0,0,"-"],template_choice:[28,0,0,"-"],template_data_name:[28,0,0,"-"],template_impl:[28,0,0,"-"],template_traits:[28,0,0,"-"],test:[30,0,0,"-"]},"apptools.template.impl":{any_context_data_name_item:[29,0,0,"-"],any_data_name_item:[29,0,0,"-"],api:[29,0,0,"-"],context_data_name_item:[29,0,0,"-"],helper:[29,0,0,"-"],template_data_context:[29,0,0,"-"],template_data_source:[29,0,0,"-"],value_data_name_item:[29,0,0,"-"],value_nd_data_name_item:[29,0,0,"-"]},"apptools.template.impl.any_context_data_name_item":{AnyContextDataNameItem:[29,1,1,""]},"apptools.template.impl.any_context_data_name_item.AnyContextDataNameItem":{filter:[29,2,1,""],inputs_changed:[29,2,1,""]},"apptools.template.impl.any_data_name_item":{AnyDataNameItem:[29,1,1,""]},"apptools.template.impl.any_data_name_item.AnyDataNameItem":{filter:[29,2,1,""],inputs_changed:[29,2,1,""]},"apptools.template.impl.context_data_name_item":{ContextDataNameItem:[29,1,1,""]},"apptools.template.impl.context_data_name_item.ContextDataNameItem":{filter:[29,2,1,""]},"apptools.template.impl.helper":{parse_name:[29,3,1,""],path_for:[29,3,1,""]},"apptools.template.impl.template_data_context":{TemplateDataContext:[29,1,1,""]},"apptools.template.impl.template_data_context.TemplateDataContext":{get_data_context:[29,2,1,""],get_data_context_value:[29,2,1,""]},"apptools.template.impl.template_data_source":{TemplateDataSource:[29,1,1,""]},"apptools.template.impl.template_data_source.TemplateDataSource":{name_from_data_source:[29,2,1,""]},"apptools.template.impl.value_data_name_item":{ValueDataNameItem:[29,1,1,""]},"apptools.template.impl.value_data_name_item.ValueDataNameItem":{filter:[29,2,1,""]},"apptools.template.impl.value_nd_data_name_item":{Value1DDataNameItem:[29,1,1,""],Value2DDataNameItem:[29,1,1,""],Value3DDataNameItem:[29,1,1,""],ValueNDDataNameItem:[29,1,1,""]},"apptools.template.impl.value_nd_data_name_item.ValueNDDataNameItem":{filter:[29,2,1,""]},"apptools.template.imutable_template":{IMutableTemplate:[28,1,1,""]},"apptools.template.itemplate":{ITemplate:[28,1,1,""]},"apptools.template.itemplate.ITemplate":{activate_template:[28,2,1,""],names_from_template:[28,2,1,""],object_from_template:[28,2,1,""],template_from_object:[28,2,1,""]},"apptools.template.itemplate_choice":{ITemplateChoice:[28,1,1,""]},"apptools.template.itemplate_data_context":{ITemplateDataContext:[28,1,1,""],ITemplateDataContextError:[28,8,1,""]},"apptools.template.itemplate_data_context.ITemplateDataContext":{get_data_context:[28,2,1,""],get_data_context_value:[28,2,1,""]},"apptools.template.itemplate_data_name_item":{ITemplateDataNameItem:[28,1,1,""]},"apptools.template.itemplate_data_source":{ITemplateDataSource:[28,1,1,""]},"apptools.template.itemplate_data_source.ITemplateDataSource":{name_from_data_source:[28,2,1,""]},"apptools.template.mutable_template":{MutableTemplate:[28,1,1,""]},"apptools.template.template_choice":{TemplateChoice:[28,1,1,""]},"apptools.template.template_data_name":{TemplateDataName:[28,1,1,""]},"apptools.template.template_impl":{Template:[28,1,1,""],instance_or_datasource:[28,3,1,""],is_none:[28,3,1,""]},"apptools.template.template_impl.Template":{activate_template:[28,2,1,""],names_from_template:[28,2,1,""],object_from_template:[28,2,1,""],template_from_object:[28,2,1,""]},"apptools.template.template_traits":{TDerived:[28,1,1,""],TEnum:[28,3,1,""],TInstance:[28,3,1,""],TList:[28,3,1,""],TRange:[28,3,1,""]},"apptools.template.template_traits.TDerived":{get:[28,2,1,""],metadata:[28,5,1,""],set:[28,2,1,""]},"apptools.type_manager":{abstract_adapter_factory:[31,0,0,"-"],abstract_factory:[31,0,0,"-"],abstract_type_system:[31,0,0,"-"],adaptable:[31,0,0,"-"],adapter:[31,0,0,"-"],adapter_factory:[31,0,0,"-"],adapter_manager:[31,0,0,"-"],api:[31,0,0,"-"],factory:[31,0,0,"-"],hook:[31,0,0,"-"],python_type_system:[31,0,0,"-"],type_manager:[31,0,0,"-"],util:[31,0,0,"-"]},"apptools.type_manager.abstract_adapter_factory":{AbstractAdapterFactory:[31,1,1,""]},"apptools.type_manager.abstract_adapter_factory.AbstractAdapterFactory":{adapt:[31,2,1,""]},"apptools.type_manager.abstract_factory":{AbstractFactory:[31,1,1,""]},"apptools.type_manager.abstract_factory.AbstractFactory":{create:[31,2,1,""]},"apptools.type_manager.abstract_type_system":{AbstractTypeSystem:[31,1,1,""]},"apptools.type_manager.abstract_type_system.AbstractTypeSystem":{get_mro:[31,2,1,""],is_a:[31,2,1,""]},"apptools.type_manager.adaptable":{Adaptable:[31,1,1,""]},"apptools.type_manager.adaptable.Adaptable":{adapt:[31,2,1,""]},"apptools.type_manager.adapter":{Adapter:[31,1,1,""]},"apptools.type_manager.adapter_factory":{AdapterFactory:[31,1,1,""]},"apptools.type_manager.adapter_manager":{AdapterManager:[31,1,1,""]},"apptools.type_manager.adapter_manager.AdapterManager":{adapt:[31,2,1,""],register_adapters:[31,2,1,""],register_instance_adapters:[31,2,1,""],register_type_adapters:[31,2,1,""],unregister_adapters:[31,2,1,""],unregister_instance_adapters:[31,2,1,""],unregister_type_adapters:[31,2,1,""]},"apptools.type_manager.factory":{Factory:[31,1,1,""]},"apptools.type_manager.factory.Factory":{can_create:[31,2,1,""],create:[31,2,1,""]},"apptools.type_manager.hook":{add_post:[31,3,1,""],add_pre:[31,3,1,""],remove_post:[31,3,1,""],remove_pre:[31,3,1,""]},"apptools.type_manager.python_type_system":{PythonObject:[31,1,1,""],PythonTypeSystem:[31,1,1,""]},"apptools.type_manager.python_type_system.PythonTypeSystem":{get_mro:[31,2,1,""],is_a:[31,2,1,""]},"apptools.type_manager.type_manager":{TypeManager:[31,1,1,""]},"apptools.type_manager.type_manager.TypeManager":{add_category:[31,2,1,""],add_post:[31,2,1,""],add_pre:[31,2,1,""],object_as:[31,2,1,""],register_adapters:[31,2,1,""],register_instance_adapters:[31,2,1,""],register_type_adapters:[31,2,1,""],remove_post:[31,2,1,""],remove_pre:[31,2,1,""],unregister_adapters:[31,2,1,""],unregister_instance_adapters:[31,2,1,""],unregister_type_adapters:[31,2,1,""]},"apptools.type_manager.util":{get_classes:[31,3,1,""],sort_by_class_tree:[31,3,1,""]},"apptools.type_registry":{api:[32,0,0,"-"],type_registry:[32,0,0,"-"]},"apptools.type_registry.type_registry":{LazyRegistry:[32,1,1,""],TypeRegistry:[32,1,1,""],get_mro:[32,3,1,""]},"apptools.type_registry.type_registry.LazyRegistry":{lookup_by_type:[32,2,1,""]},"apptools.type_registry.type_registry.TypeRegistry":{lookup:[32,2,1,""],lookup_all:[32,2,1,""],lookup_all_by_type:[32,2,1,""],lookup_by_type:[32,2,1,""],pop:[32,2,1,""],push:[32,2,1,""],push_abc:[32,2,1,""]},"apptools.undo":{abstract_command:[33,0,0,"-"],action:[34,0,0,"-"],api:[33,0,0,"-"],command_stack:[33,0,0,"-"],i_command:[33,0,0,"-"],i_command_stack:[33,0,0,"-"],i_undo_manager:[33,0,0,"-"],undo_manager:[33,0,0,"-"]},"apptools.undo.abstract_command":{AbstractCommand:[33,1,1,""]},"apptools.undo.abstract_command.AbstractCommand":{"do":[33,2,1,""],merge:[33,2,1,""],redo:[33,2,1,""],undo:[33,2,1,""]},"apptools.undo.action":{abstract_command_stack_action:[34,0,0,"-"],api:[34,0,0,"-"],command_action:[34,0,0,"-"],redo_action:[34,0,0,"-"],undo_action:[34,0,0,"-"]},"apptools.undo.action.abstract_command_stack_action":{AbstractCommandStackAction:[34,1,1,""]},"apptools.undo.action.abstract_command_stack_action.AbstractCommandStackAction":{destroy:[34,2,1,""]},"apptools.undo.action.command_action":{CommandAction:[34,1,1,""]},"apptools.undo.action.command_action.CommandAction":{perform:[34,2,1,""]},"apptools.undo.action.redo_action":{RedoAction:[34,1,1,""]},"apptools.undo.action.redo_action.RedoAction":{perform:[34,2,1,""]},"apptools.undo.action.undo_action":{UndoAction:[34,1,1,""]},"apptools.undo.action.undo_action.UndoAction":{perform:[34,2,1,""]},"apptools.undo.command_stack":{CommandStack:[33,1,1,""]},"apptools.undo.command_stack.CommandStack":{begin_macro:[33,2,1,""],clear:[33,2,1,""],end_macro:[33,2,1,""],push:[33,2,1,""],redo:[33,2,1,""],undo:[33,2,1,""]},"apptools.undo.i_command":{ICommand:[33,1,1,""]},"apptools.undo.i_command.ICommand":{"do":[33,2,1,""],merge:[33,2,1,""],redo:[33,2,1,""],undo:[33,2,1,""]},"apptools.undo.i_command_stack":{ICommandStack:[33,1,1,""]},"apptools.undo.i_command_stack.ICommandStack":{begin_macro:[33,2,1,""],clear:[33,2,1,""],end_macro:[33,2,1,""],push:[33,2,1,""],redo:[33,2,1,""],undo:[33,2,1,""]},"apptools.undo.i_undo_manager":{IUndoManager:[33,1,1,""]},"apptools.undo.i_undo_manager.IUndoManager":{redo:[33,2,1,""],undo:[33,2,1,""]},"apptools.undo.undo_manager":{UndoManager:[33,1,1,""]},"apptools.undo.undo_manager.UndoManager":{redo:[33,2,1,""],undo:[33,2,1,""]},apptools:{appscripting:[2,0,0,"-"],help:[4,0,0,"-"],io:[7,0,0,"-"],logger:[9,0,0,"-"],lru_cache:[13,0,0,"-"],naming:[14,0,0,"-"],permissions:[18,0,0,"-"],persistence:[22,0,0,"-"],preferences:[23,0,0,"-"],scripting:[25,0,0,"-"],selection:[26,0,0,"-"],sweet_pickle:[27,0,0,"-"],template:[28,0,0,"-"],type_manager:[31,0,0,"-"],type_registry:[32,0,0,"-"],undo:[33,0,0,"-"]}},objnames:{"0":["py","module","Python module"],"1":["py","class","Python class"],"2":["py","method","Python method"],"3":["py","function","Python function"],"4":["py","staticmethod","Python static method"],"5":["py","attribute","Python attribute"],"6":["py","data","Python data"],"7":["py","classmethod","Python class method"],"8":["py","exception","Python exception"]},objtypes:{"0":"py:module","1":"py:class","2":"py:method","3":"py:function","4":"py:staticmethod","5":"py:attribute","6":"py:data","7":"py:classmethod","8":"py:exception"},terms:{"abstract":[7,22,24,29,31,33,34,46],"boolean":[9,14,42,46],"break":27,"case":[2,10,22,23,27,28,31,36,40,42,45],"class":[2,3,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,31,32,33,34,36,38,41,42,43,44,45,46],"default":[1,2,8,9,12,13,16,18,22,23,24,25,26,27,28,31,33,34,36,37,38,42,43,45,46],"final":[27,45],"float":[12,14,17,22,42,44],"function":[2,6,9,14,16,22,25,27,31,38,44,45],"import":[9,22,27,32,36,38,41,42,44,45],"int":[22,36,38,42],"long":[22,42,46],"new":[2,8,12,14,16,18,21,22,23,25,27,28,31,32,34,36,38,40,42,45],"null":[5,6,9,19],"public":[2,10,25,36,45],"return":[2,8,9,11,12,13,14,16,17,18,21,22,23,24,25,26,27,28,29,31,32,33,34,36,38,41,42,43,45,46],"static":[2,14],"transient":[28,42],"true":[2,8,9,11,14,17,18,21,22,23,25,26,27,28,29,31,33,36,40,42,43,44,45,46],"try":[18,23,33,41,42,46],"while":[12,22,33,38,45,46],AND:27,Adding:36,Age:38,And:42,But:[27,42],ETS:[9,38,39,40,44],For:[8,9,16,22,25,27,36,38,40,42,44,45],Has:[26,45],Ids:38,Its:[21,22,33,46],NOT:27,Not:14,One:[36,44],That:[8,27,28],The:[2,5,8,9,10,11,12,14,16,17,18,21,22,23,24,25,26,27,28,29,31,32,33,34,36,37,38,39,40,41,43,46],Then:23,There:23,These:[32,36,38],Used:22,Useful:[25,31],Using:[37,42,44,46],With:36,__array__:8,__attributes__:14,__class__:22,__dict__:22,__getstate__:22,__init__:[2,22,33,46],__main__:22,__metadata__:22,__module__:32,__name__:[22,32],__set_pure_state__:22,__setitem__:8,__setstate__:[22,27],__version__:22,_image_not_found:6,_new_person:38,_new_person_action_default:38,_pickl:22,_unpickl:27,aaa:36,abandon:[33,46],abc:[2,8,32],abcmeta:32,abil:[28,40,41],abl:[40,42,44],about:[9,14,22,27,33,41,42,44,45],abov:[9,27,36,44],absolut:[8,22,32],abstract_adapter_factori:[1,35],abstract_command:[1,35],abstract_command_stack_act:[1,33],abstract_factori:[1,35],abstract_type_system:[1,35],abstractadapterfactori:31,abstractcommand:33,abstractcommandstackact:34,abstractfactori:31,abstracttypesystem:31,accept:[14,16,27,38],access:[8,13,18,21,23,28,37,38,40,41,45],accord:[18,38,41],account:[21,41],aclass:16,acm:[23,42,43],across:9,act:[14,27,38,45],action:[1,2,4,5,18,20,28,33,36,37,41,44,45,46],action_set:5,actionadapt:20,activ:[12,26,28,33,34,46],activate_templ:28,activated_text:12,active_stack:46,active_stack_clean:46,actual:[9,12,14,16,21,22,25,27,38,42],adapt:[1,5,12,14,18,35,37],adapte:31,adaptee_class:31,adapter_bas:[1,20,35,38],adapter_factori:[1,14,35],adapter_manag:[1,35],adapterbas:[18,20,38],adapterfactori:[14,31],adaptermanag:31,add:[2,8,9,12,21,22,23,25,26,27,31,38,40,41,42,45,46],add_categori:31,add_log_queue_handl:9,add_map:27,add_mapping_to_class:27,add_post:31,add_pr:31,add_preferences_listen:23,add_rol:21,add_selection_provid:[26,45],add_state_funct:27,add_state_function_for_class:27,add_to_h5fil:8,add_to_namespac:2,add_updat:22,add_us:[21,40],added:[2,23,26,27,36,38,45],addhandl:9,adding:[14,27],addit:[8,14,27,28,38,40],addition:[22,27],address:[1,35],administr:41,adpter:31,advanc:27,advantag:36,affect:23,after:[8,18,22,24,25],again:41,age:[38,44],age_perm:38,agent:[1,9],alia:10,all:[2,5,7,9,11,12,13,14,18,19,21,22,23,24,25,26,27,28,29,31,32,33,34,36,38,40,41,42,44,45,46],all_item:[26,45],all_rol:21,alloc:46,allow:[8,9,12,14,16,17,18,22,23,27,28,29,31,33,36,38,40,41,42,43,44,46],allows_children:[17,24],almost:[22,25],along:[22,33,36],alreadi:[2,7,8,14,25,26,36,45],also:[8,14,22,23,25,27,28,33,36,38,41,42,43,44,45,46],alter:8,altern:[16,22,28,36,37,39,40,46],although:29,alwai:[2,23,36,42,44],amount:12,ani:[2,7,9,10,12,13,14,21,22,23,26,27,28,29,33,34,36,38,41,42,43,44,45,46],annot:2,anoth:[2,14,27,33,36,40,42],answer:[22,41],any_context_data_name_item:[1,28],any_data_name_item:[1,28],anycontextdatanameitem:29,anydatanameitem:29,anymor:45,anyth:9,anywher:42,api:[1,4,11,27,35,37,42],app:22,appear:[22,46],append:[8,9,23,24,44],appl:24,appli:[2,22,24,27,37],applic:[2,5,9,14,17,18,22,23,28,29,33,37,41,42,43,44,45,46],application_hom:[41,42],application_scop:23,application_vers:22,approach:[36,42],appropri:[2,22,27,31,33,36,38,41,46],appscript:[1,25,35,36],apptool:[0,36,38,41,42,44],arbitrari:[16,41,44],architectur:41,arg:[2,5,8,10,12,17,25,28,31,46],arg_as_str:2,argmument:8,args_as_string_list:2,argument:[2,8,13,25,26,27,33,34,36,38,44,45,46],around:[2,8,42,46],arrai:[8,22,29],arrang:42,array_or_shap:8,array_proxy_kei:8,arriv:12,ascend:14,ascii:27,ask:[14,23,25],assert:22,assign:[12,16,18,21,28,38,39,41],assist:14,associ:[14,21,28,29,41,42],assum:[2,5,8,22,27,28],atom:8,attach:[1,9,18,38,41,44],attempt:[7,14,27],attribut:[2,8,13,14,16,18,20,21,22,25,27,28,38,42,44],attribute_nam:27,attributes_fil:14,authent:[18,19,21,37,41],authenticate_us:[18,21,38],author:[5,6],authoris:[18,21,40,41],auto:[0,2,36],auto_flush:8,auto_group:8,auto_open:8,automat:[2,8,14,23,25,36,37,38,42,46],avail:[12,25,26,31,36,38,41,43,45,46],avoid:[14,22],back:[22,23,42],background:44,backup_setst:22,backupcount:9,bad:38,bar:[27,36],base64:22,base:[2,3,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,31,32,33,34,36,38,40,41,44,45,46],base_f_nam:22,base_toolkit:10,basic:[21,22,25,27,37,41],baz:[27,36],bbb:36,bear:36,becaus:[10,14,22,27,36,42,45],becom:[27,38,41,45,46],been:[2,9,18,21,25,26,27,28,32,33,38,40,44,45,46],befor:[9,22,24,26,33,42,45,46],begin:[2,14,27,33,36,40,46],begin_macro:[33,46],behav:[18,38],behavior:8,behaviour:[31,42,43],behest:27,being:[2,5,14,16,22,24,27,29,33,36,38,40,44,46],believ:42,below:[8,27,38],benefit:27,best:[22,44],better:[23,36],between:[18,22,23,41,44,45],beyond:27,bgcolor:[23,42,43],binari:38,bind:[1,2,23,28,29,35,36],bind_ev:[1,35,36],bind_factori:[2,36],bind_polici:[2,36],bind_prefer:23,bindabl:28,bindev:2,biometr:40,bit:[31,42],black:42,blank:5,blob:[21,38,40,41],blog:9,blue:[23,42,43],bogu:42,bool:[8,22,25,26,36,40,42,44,45],bootstrap:[18,21,40],both:[32,38,41,46],bound:[2,14,28,36],brief:[38,46],broken:31,broker:45,brows:22,browser:6,bsd:[5,6],buffer:[8,9],bug:11,build:42,builtin:22,bump:22,bunch:22,button:[12,24,42,45],bypass:36,cach:13,calcul:[8,12,14],call:[2,8,9,14,16,21,22,23,25,26,27,29,33,34,36,38,40,41,42,44,45,46],callabl:[26,31,45,46],callback:[26,44,45],came:23,can:[2,8,9,10,14,16,17,18,22,23,26,27,28,31,32,33,36,38,40,41,42,44,45,46],can_:40,can_add_us:[21,40],can_change_password:21,can_creat:31,can_delete_us:21,can_load:14,can_modify_us:21,can_sav:14,can_set_text:17,cannot:[14,28,31,36],capabl:[14,21,27,40],care:[22,42,46],carrot:24,categori:[14,27,31],category_class:31,cauliflow:24,caus:[27,38],caveat:1,cc_address:10,ccaddr:[10,11],ccc:36,central:45,certain:36,chain:27,chang:[2,3,14,17,18,21,23,24,25,26,27,28,29,33,36,38,42,44,45,46],change_password:21,charact:[2,36,46],check:[18,22],check_permiss:18,child:[23,24,42,44],children:[8,17,23,33,44],children_nam:8,choos:[27,36],chunk:8,clarifi:41,class_nam:[22,27],classmethod:[8,18,22,26,27,45],clean:[25,33,46],cleaner:8,clear:[2,13,23,25,33,46],click:24,close:[8,24,25,45],closehandl:25,code:[5,10,14,22,25,27,38,40,44],code_editor:12,collaps:46,collect:[8,9,26,28,31,42,45],color:44,column:[8,12],column_width:12,combin:16,come:[31,42],command:[23,33,34,44,46],command_act:[1,33],command_stack:[1,35,46],commandact:34,commandstack:33,comment:[10,11],common:[22,27,31,45,46],commuic:14,commun:[14,45],complet:[2,16,22,27,36,38,41,46],complex:[22,36,42,45],complic:[22,27,42],compon:[14,36,41,45,46],compos:14,compound:29,compris:41,concept:[37,38],concern:22,concret:[28,29],configobj:[23,42],configur:[36,41,46],conform:14,confus:46,connect:[26,45],connect_selection_listen:[26,45],consequ:41,consid:44,consist:[14,27,36,42],constitut:36,construct:27,consumpt:45,contain:[0,8,9,13,14,19,21,22,24,25,26,27,28,29,33,36,38,41,42,45,46],content:[35,45],context:[1,8,15,17,22,28,29,35],context_adapt:[1,15,35],context_adapter_factori:[1,15,35],context_data_name_item:[1,28],context_monitor:[1,14],context_nam:14,context_node_typ:[1,14],context_ord:14,contextadapt:[14,15],contextadapterfactori:[14,15],contextdatanameitem:29,contextmonitor:17,contextnodetyp:17,continu:14,contribut:[5,14,43],contributes_to:43,contributor:27,control:[5,8,24,41,45],conveni:[9,22,25,27,38,42,44,45,46],convent:38,convention:38,convers:[2,22],convert:[8,12,22,27,28,42],cookbook:[9,18],cooper:41,copi:[7,9,25,33,46],copy_button:12,copyright:[5,6],core:[9,44],core_plugin_definit:9,corpor:41,correct:22,correctli:[22,38],correspond:[2,13,27,36,38,40,41,45],could:[36,40,45],couldn:46,cours:23,coveni:27,cover:41,cpickl:27,creat:[2,7,8,9,12,14,18,21,22,23,24,25,26,28,29,31,33,36,38,40,42,44,45,46],create_:8,create_arrai:8,create_carrai:8,create_dict:8,create_email_messag:[10,11],create_fil:7,create_fold:7,create_group:8,create_inst:22,create_log_file_handl:9,create_packag:7,create_pag:24,create_scriptable_object:2,create_scriptable_typ:[2,36],create_subcontext:14,create_t:8,creation:[14,27,36],criteria:14,current:[14,18,19,21,22,23,24,25,26,27,31,36,38,41,42,44,45,46],custom:[24,27],custom_excepthook:[1,35],data:[8,11,14,21,22,24,27,28,29,33,36,37,41,46],databas:[21,39,40,41],datafram:8,datamodel:36,date:38,debug:[25,42],debughandl:9,decid:22,declare_version_attribut:27,declare_version_attribute_for_class:27,decor:[2,25,36,44],decreas:12,deep:[33,46],def:[2,22,36,38,42,43,44],default_prefer:23,default_valu:28,defin:[2,5,12,13,16,18,21,22,25,28,29,31,36,37,39,40,41,44,45,46],definit:[5,14,21,23,27,28,41,44],delai:2,deleg:40,delet:[7,8,21,27,38,41],delete_exist:8,delete_rol:21,delete_us:21,demo:[5,6],demo_act:[1,4,5],demoact:6,demoimageresourc:6,demonstr:[36,38,46],demosmenumanag:5,demospreferencespag:5,deni:[38,41],depend:[22,23,27,28,29,36,38,41,45],deploi:37,deriv:28,desc:21,descend:23,describ:[14,16,22,28,29,40,43],descript:[2,8,13,16,21,28,29,36,38],design:[27,36,39,40],desir:[8,14,38,43],destin:7,destroi:[14,34,45],destroy_subcontext:14,detail:[21,22,27,41,44],detect:17,determin:[2,14,18,21,22,31,36,38,40,41],develop:[23,36,38,39,40,41,45,46],dialog:[24,25,38,45],dict:[2,8,13,15,22,25,36],dict_context_adapt:[1,14],dict_context_adapter_factori:[1,14],dict_nod:[1,7],dictat:43,dictcontextadapt:15,dictcontextadapterfactori:15,dictionari:[8,9,13,14,15,22,27,42],did:[23,42],differ:[8,14,22,27,36,38,41],difficult:[36,38],dimension:29,dir_context:[1,35],dircontext:14,direct:[17,45],directi:22,directli:[21,23,36,42,45],directori:[14,38,41,42],disabl:[18,33,38,41,46],disadvantag:36,disappear:45,discard:[2,33],disconnect:[26,45],disconnect_selection_listen:[26,45],discuss:[42,43],disk:[8,22,42,46],displai:[5,6,9,21,38,39,40,45],distinct:45,divid:12,doc:[5,6],doc_act:[1,4,5],docact:6,docimageresourc:6,docstr:8,document:[2,5,6,8,36,41,42,44,46],documentsmenumanag:5,documentspreferencespag:5,doe:[2,7,8,9,13,14,17,22,23,25,34,36,41,42,43],doesn:[24,42],doing:27,don:[9,21,31,42,43],done:[25,27,38,41,44,45,46],dot:[2,36,38],download:5,downloadsmenumanag:5,drag:17,drawback:23,drop:[13,27],dtype:8,dual:31,due:27,dump:[22,23,24,27,42],dump_stat:22,duplic:[22,26,27,45],dure:[22,27],dynam:[12,14],dynamic_context:[1,35],dynamiccontext:14,each:[9,12,13,14,21,22,23,27,28,31,32,36,40,41,42,44,46],easi:[8,9,22,23],easier:[39,41],easili:[22,44],edit:[16,17,22,46],editor:[12,16,22,45,46],effect:[33,36,46],egg:41,either:[2,8,16,22,23,31,41,42,44],element:[9,14,21,26,28,29,45,46],elimin:22,els:[8,22,27,32],email:11,embed:[22,36],emit:9,empti:[14,21,23,26,27,33,36,40,45,46],enabl:[18,20,27,38,41],enable_editor:[1,28],enabled_when:38,encapsul:22,encod:[22,27],encount:27,encourag:23,end:[9,14,22,25,33,36,44,46],end_macro:[33,46],endo:[36,41,46],endpoint:14,enforc:[21,40],enlib:10,enough:44,enqueu:9,ensur:[18,22,27,33,36,38,46],ensure_vis:17,enterpris:38,enthought:[2,4,5,6,7,9,14,18,22,23,25,27,28,31,33,36,41,46],enthoughtbas:9,entir:[22,25],entri:46,environ:[14,41],envisag:[4,5,9,10,11,14,27,37,42,45],equal:12,error:[1,16,21,27,35,39,40],especi:45,etc:[9,14,22,23,28,34,42],ets:38,ets_perms_data_dir:41,ets_perms_policydb:41,ets_perms_userdb:41,etsconfig:[41,42],evalu:38,even:[26,27,45],event:[2,3,6,14,19,26,34,36,39,40,45,46],ever:[21,33,46],everi:[9,27],everyth:22,exactli:[18,31,42],examin:14,exampl:[5,6,8,9,16,22,23,24,27,36,38,40,41,42,45,46],example_act:[1,4,5],exampleact:6,examples_prefer:[1,4],examplesmenumanag:5,examplesprefer:5,examplespreferencespag:5,excel:42,except:[1,2,9,16,21,22,23,25,26,28,35,36,39,40,45],exclud:[2,9,22,36],exec:36,execut:[2,9,25,27,33,44,46],exist:[7,8,14,21,22,23,24,25,31,36,41,42],exists_error:8,expect:[21,26,31,41,45],explan:[12,36],explicit:[27,36,42],explicitli:[2,8,14,23,26,27,36,43,45,46],explor:[1,14],expos:[8,11,27,36,45],express:[18,21],extend:[8,14,28,40],extens:[10,31,43,45],extern:[40,41,45],extra:[21,43],extract:38,extrem:27,facil:[41,44],fact:27,factori:[1,2,14,15,18,21,35,36,46],factoryfor:15,factorywrapp:2,fail:21,fairli:44,fake:31,fallback:38,fals:[2,8,9,10,11,12,14,17,23,24,25,26,29,38,42,44,45],featur:[1,36,46],few:44,fgcolor:42,file:[1,2,9,10,11,14,17,21,22,23,25,27,35,36,39,40,41,42,43],file_nam:[2,21,36],file_or_filenam:23,file_path:[1,35],filenam:[5,6,8,9,23,42],filenod:8,filepath:22,filesystem:[41,42],filiba:18,fill:[26,45],filter:[9,14,29],filtered_emit:9,filtering_handl:[1,35],filteringhandl:9,find:[14,23,25,44],find_bind:14,find_class:[16,22,27],fire:[2,14,26,36,45,46],first:[2,8,22,36,41,42,44,45],fix:[12,22],fix_import:27,fixm:[9,10,23,31,38],flexibl:[22,39,40],flush:[8,23,42],folder:[7,17],follow:[25,36,38,41,42,44,46],foo:[27,36],forc:[2,12,23,36],form:[22,24],format:[11,14,22,42],formatt:9,formatted_record:12,forwardproperti:12,found:[14,26,29,41,45],fraction:12,fragment:38,framework:[2,14,25,27,37,38,39,40,44],fred:42,free:43,friend:[22,44],from:[2,5,9,11,13,14,16,21,22,23,24,25,26,27,28,31,33,36,38,41,42,44,45],from_address:10,from_available_item:[26,45],fromaddr:[10,11],fruit:24,full:[21,44],fulli:[9,27,28,32,39,40],func:[2,25,26,45],fundament:36,further:[37,38,41],gather:27,gener:[0,9,14,17,22,24,27,31,36,38,41,42,46],get:[2,8,9,13,14,17,18,20,22,23,27,28,32,37,41,42,43,44,45],get_assign:21,get_atom:8,get_attribut:14,get_children:17,get_class:31,get_cod:25,get_data_context:[28,29],get_data_context_valu:[28,29],get_default_prefer:23,get_drag_valu:17,get_editor:16,get_en:[18,20,38],get_global_registri:27,get_initial_context:14,get_kei:17,get_latest:22,get_module_nam:9,get_module_name_from_zip:9,get_monitor:17,get_mro:[31,32],get_object_inst:14,get_object_path:25,get_permissions_manag:[18,38],get_polici:21,get_prefer:43,get_record:25,get_scop:[23,42],get_script_id:25,get_script_manag:[2,36],get_select:[26,45],get_stat:22,get_state_to_bind:14,get_sys_prefix_relative_filenam:6,get_text:17,get_unique_nam:14,get_vers:22,get_version_attribut:27,get_vis:[18,20,38],get_width:12,get_zip_path:9,getter:2,give:[22,36,38,46],given:[2,8,12,14,18,21,22,23,25,26,27,32,33,38,44,45,46],global:[23,25,27,44],global_registri:[1,35],gloriou:37,goal:27,going:[22,44],gone:27,grant:[38,41],great:34,group:[8,12,41],group_path:8,group_subpath:8,grow:44,guarante:[25,33,46],gui:[38,40,41,45,46],guid:16,gunzip_str:22,gzip:22,gzip_str:22,h5_group:8,h5_group_wrapp:8,h5attr:8,h5dictnod:8,h5file:8,h5filter:8,h5group:8,h5tablenod:8,hack:9,halt:9,handi:[31,44],handl:[2,21,22,24,27,28,29,38,45,46],handler:[9,12,16,18,22,24,25,38],handlerregistri:22,happen:[2,14,36],happi:42,hard:10,has:[2,9,12,14,17,18,22,24,25,26,27,28,31,32,36,38,40,41,42,45,46],has_children:17,has_class_map:27,has_inst:22,has_new_record:9,has_selection_provid:[26,45],has_side_effect:[2,36],has_state_funct:27,has_trait:[2,5,7,10,11,13,14,18,21,23,24,25,26,27,28,29,31,33,45],hasprivatetrait:[7,14,27,28,29],hasstricttrait:[13,44],hastrait:[2,10,11,14,18,21,23,24,25,26,27,31,33,36,38,44,45],have:[2,12,18,21,22,23,27,28,31,33,36,38,40,41,42,44,45,46],hdf5:8,heirarchi:14,help:[1,8,9,22,24,27,35],help_cod:[1,4],help_demo:5,help_doc:[1,4],help_download:5,help_exampl:5,help_id:10,help_plugin:[1,4],help_submenu_manag:[1,4],helpcod:5,helpdemopreferencespag:5,helpdoc:5,helpdocpreferencespag:5,helper:[1,28,42,43],helpexamplepreferencespag:5,helpplugin:5,helppreferencespag:5,helpsubmenumanag:5,henc:[42,43],here:[2,9,10,22,23,27,42,44],hid_quality_agent_dlg:10,hidden:[38,41],hide:38,hierarch:42,hierarchi:[22,23,25,27,28,31,42,44],high:44,highli:[22,23],hold:[38,42],home:41,hook:[1,27,35],hopefulli:[41,42],horizont:12,how:[14,18,21,27,36,38,41,42,43,46],howev:[22,27,28,38,46],html:[36,41,46],human:[38,44],i_bind_ev:[1,35],i_command:[1,35],i_command_stack:[1,35],i_context_adapt:[1,28],i_help_cod:[1,4],i_help_doc:[1,4],i_policy_manag:[1,35],i_policy_storag:[1,18],i_prefer:[1,35],i_preferences_pag:[1,23],i_script_manag:[1,35],i_select:[1,35,45],i_selection_provid:[1,35],i_undo_manag:[1,35],i_us:[1,35],i_user_databas:[1,18],i_user_manag:[1,35],i_user_storag:[1,18],ibindev:2,icommand:33,icommandstack:[33,46],idconflicterror:[26,45],idea:[22,38,42],ideal:[22,45],ident:41,identifi:[8,26,27,41,45,46],ids:38,ignor:[2,22,25,26,36,44,45,46],ignore_miss:[26,45],ihelpcod:5,ihelpdoc:5,ilistselect:[26,45],imag:[24,42],image_resourc:6,imageresourc:6,imform:42,immedi:46,immut:28,impl:[1,28],implement:[2,5,6,8,16,18,21,22,23,26,27,28,29,31,32,33,37,38,39,40,42,43,45,46],implent:23,import_nam:22,improv:27,imutable_templ:[1,35],imutabletempl:28,inadequ:22,inappropri:[39,46],inc:[5,6],includ:[2,9,13,16,22,23,27,29,31,33,36,38,41,46],include_environ:11,include_project:10,include_userdata:[10,11],increas:[12,44],increment:[22,27,46],indent:[23,24],independ:[36,46],index:[24,46],indic:[9,14,16,26,45,46],individu:31,info:[14,16,18,24,25],info_text:16,inform:[8,14,16,21,22,26,27,41,42,44,45],infrastructur:[41,44],inherit:[23,31,42],ini:[42,43],init:24,init_info:18,initarg:22,initi:[8,14,22,23,24,26,27,38,40,45],initial_context:[1,35],initial_context_factori:[1,35],initialcontext:14,initialcontextfactori:14,inject:25,input:[8,28,29],input_data_context:28,inputs_chang:29,insecur:21,insert:24,insert_aft:24,insert_befor:24,insid:44,instac:27,instanc:[2,8,12,14,15,16,17,18,21,22,23,25,26,27,31,32,33,34,36,38,44,45,46],instance_context_adapt:[1,14],instance_context_adapter_factori:[1,14],instance_or_datasourc:28,instancecontextadapt:15,instancecontextadapterfactori:15,instanti:[25,27,44],instead:[16,22,36,41,45],insuffici:[22,40],integ:[12,16,46],integr:[37,41],intend:[2,29,46],intent:23,interact:[14,27],intercept:[8,20,38],interdepend:36,interest:[14,42],interfac:[2,5,8,12,16,18,21,23,24,25,26,28,29,31,33,36,38,39,40,41,42,44,45,46],intermedi:[7,14,27,36],intermediari:2,intern:[26,44,45],interpret:[18,21,22,25,36],intervent:2,introduct:37,invalid:14,invalidnameerror:14,invert:25,invok:[2,25,36,38,46],ipermissionsmanag:18,ipolicymanag:[18,41],ipolicystorag:[21,37,41],iprefer:[23,42],ipreferencespag:24,irrelev:38,irrespect:[2,36,46],is_a:31,is_context:14,is_dict_nod:8,is_edit:17,is_empti:[21,26,45],is_non:28,is_ok:[24,25],is_open:8,is_regist:25,is_table_nod:8,is_type_for:17,is_zip_path:9,iscriptabledatamodel:36,iscriptmanag:[2,36],iselect:[26,45],iselectionprovid:[26,45],ish:31,isn:[2,21,36,39,40,41,42],issu:22,item:[5,8,12,13,14,18,24,26,31,41,45,46],itempl:[1,35],itemplate_choic:[1,35],itemplate_data_context:[1,35],itemplate_data_name_item:[1,35],itemplate_data_sourc:[1,35],itemplatechoic:28,itemplatedatacontext:[28,29],itemplatedatacontexterror:[28,29],itemplatedatanameitem:[28,29],itemplatedatasourc:[28,29],items:8,iter:8,iter_group:8,iterator_length:8,iteritem:8,its:[2,9,12,14,17,21,22,23,24,25,26,27,28,29,32,41,42,44,45,46],itself:[5,14,22,23,25,28,36,38,42,43,44,46],iundomanag:[33,46],iuser:[18,21,38,40,41],iuserdatabas:[21,37,41],iusermanag:[18,41],iuserstorag:[21,37,41],janet:[5,6],join:[8,29],join_path:8,json:8,jump:27,just:[9,22,23,38,42,43,44],keep:[22,33,45],kei:[8,13,17,22,23,36,44],kept:27,keyboard:46,keyerror:32,keyword:[2,8,25,44,45],kind:9,klass:[22,27,31],know:[22,27],knowledg:22,known:[21,22,25,27],kwarg:[2,8,10,12,17],kws:27,label:[5,17],larg:22,last:[22,32,33,34,36,46],later:[2,9,22,33,38],latest:22,latter:27,layer:[41,42],lazi:[2,27,46],lazili:32,lazy_namespac:[1,35],lazynamespac:2,lazyregistri:32,ldap:41,learn:44,least:[13,31,38],leav:[12,21,33,46],let:[42,44],level:[9,14,21,44],lib:10,librari:[9,44],licens:[5,6],like:[2,8,9,18,22,23,31,36,38,42,43,44],limit:[18,37,41,42],line:[23,25,44],link:[18,46],list:[2,8,9,12,13,14,15,18,21,22,25,26,27,28,31,32,36,38,44,45],list_bind:14,list_context_adapt:[1,14],list_context_adapter_factori:[1,14],list_nam:14,list_select:[1,35],listcontextadapt:15,listcontextadapterfactori:15,listen:[17,23,25,26,34,37,42,44],listenernotconnectederror:[26,45],listselect:[26,45],littl:12,live:[14,28],load:[9,14,18,21,22,23,27,42,43,46],load_build:[22,27],load_build_with_meta_data:27,load_polici:21,load_project:22,load_stat:22,load_url_act:[1,4,5],load_us:18,loads_stat:22,loadurlact:6,local:[14,21,39,40,41],locat:[14,39,40,41,44],lock:21,log:[9,11,12],log_point:[1,35],log_queue_handl:[1,35],log_record:12,log_records_editor:12,logfilehandl:9,logger:[1,35],logger_plugin:[1,9],logger_prefer:[1,9],logger_preferences_pag:[1,9,11],logger_servic:[1,9],logger_view:[1,9,11],loggerplugin:11,loggerprefer:11,loggerpreferencespag:12,loggerservic:11,loggerview:12,logic:25,login:[18,38],login_act:[1,18],loginact:[19,38],logout:[18,38],logout_act:[1,18],logoutact:[19,38],logqueuehandl:9,logrecord:12,logrecordadapt:12,longer:[22,34,45],look:[8,13,14,23,29,32,41,42,44],lookup:[14,24,32],lookup_al:32,lookup_all_by_typ:32,lookup_bind:14,lookup_by_typ:32,lookup_context:14,lose:27,lot:22,low:21,lower:[2,36],lowest:42,lru_cach:[1,35],lrucach:13,macro:[33,46],made:[2,14,24,33,36,42,43,46],mai:[2,5,14,18,21,22,25,27,28,29,33,36,38,41,44,46],mail_fil:11,main:[17,45],maintain:[8,32,41,44,46],major:[22,36,41,46],make:[2,7,9,16,17,22,23,27,36,38,39,41,42,45],make_context:14,make_object_script:[2,36],make_unique_nam:14,make_writ:7,manag:[2,5,8,14,17,18,21,22,23,24,27,31,33,36,37,42,45,46],management_act:38,managepolicypermiss:18,manageuserspermiss:18,mani:[22,27,36,42,46],manipul:46,manner:[27,44],manual:25,map:[8,22,27,44],mark:[2,25,28,36,44,46],match:[14,21,25,28,29,32],matching_rol:21,matching_us:21,matter:27,max_pass:[22,27],maxbyt:9,maximum:12,mayavi:44,mean:[12,22,27,28,36,42],mechan:[14,37,43],meet:41,mention:42,menu:[5,19,38,46],menu_manag:[5,19],menumanag:[5,19],merg:[23,27,33,46],merge_updat:27,messag:[9,10,11,21,39,40],meta:27,metadata:[2,14,22,25,28,44],method:[2,8,9,14,16,22,23,25,27,28,29,31,32,33,34,36,38,39,40,42,44,45,46],method_nam:31,might:[22,41,42,43,45],minu:12,miss:[7,14,23,26,42,45],mode:8,model:[14,17,33,36,38],modif:27,modifi:[16,21,22,27,28,33,38,46],modify_rol:21,modify_st:27,modify_us:21,modul:[35,38,44],monitor:17,more:[8,9,16,18,21,23,27,29,33,36,38,39,40,41,42,44,45,46],most:[27,31,38,40],motiv:22,move:[7,46],mro:[22,31],msg:[9,10],much:43,multidimension:8,multipl:[27,45,46],multipli:12,must:[7,8,14,16,26,27,28,32,33,36,38,39,40,41,44,45,46],mutable_templ:[1,35],mutablemap:8,mutabletempl:28,my_dict:8,my_tabl:8,myapplic:43,mypackag:43,myplugin:43,name:[1,2,6,8,9,12,13,18,20,21,22,23,24,25,27,28,29,31,32,33,35,36,38,40,41,42,44,46],name_from_data_sourc:[28,29],namealreadybounderror:14,namenotfounderror:14,names_from_templ:28,namespac:[2,14,25,27,36,41],naming_ev:[1,35],naming_manag:[1,35],naming_node_manag:[1,14],naming_trait:[1,14],naming_tre:[1,14],naming_tree_model:[1,14],namingerror:14,namingev:14,namingmanag:14,namingnodemanag:17,namingtraithandl:16,namingtre:17,namingtreemodel:17,natur:42,navig:22,necessari:[2,8,22,33,36,41,46],need:[2,16,21,22,25,27,33,36,37,38,40,43,45,46],nest:[25,33,44,46],never:[14,26,27,45],new_nam:14,new_object:2,newest:9,newpersonperm:38,newunpickl:[22,27],next:[33,42,46],node:[2,5,8,17,23,24,42,43],node_attr:8,node_exist:23,node_manag:17,node_monitor:17,node_nam:23,node_path:8,node_subpath:8,node_tre:17,node_tree_model:17,node_typ:17,nodefaultspecifi:28,nodemanag:17,nodemonitor:17,nodepath:8,nodetre:17,nodetreemodel:17,nodetyp:17,non:[8,14,16,17,36,42],none:[2,6,8,9,13,14,18,21,22,23,24,25,28,31,32,36,42,46],normal:[8,12,38,41],notat:38,notcontexterror:14,note:[8,9,12,14,16,21,22,27,28,36,41,44],noth:[7,23,25,33,34,46],notic:42,notif:45,notifi:[25,26,42,45],notion:23,now:[9,22,36,42,44],nspace:2,null_handl:[1,35],nullhandl:9,number:[22,39,40,42,43,46],numer:[2,22,36],numpi:8,obj1:36,obj2:36,obj:[2,14,17,22,23,27,31,32,36,42],obj_class:32,object:[2,3,8,9,10,12,13,14,16,17,18,20,21,22,23,25,26,27,28,29,31,32,37,38,40,41,42,44,46],object_a:31,object_factori:[1,35],object_from_templ:28,object_node_typ:[1,14],object_seri:[1,35],objectfactori:14,objectnodetyp:17,objectseri:14,obtain:[21,22],obvious:42,occur:[16,21,28,44],often:22,ogbuji:9,old:[22,27,31,32,42],old_nam:14,older:13,oldest:9,omit:28,on_perform:38,on_trait_chang:42,on_ui_clos:25,onc:[9,21,28,33,38,46],one:[2,9,14,18,21,22,23,24,25,27,28,29,31,32,33,36,38,41,42,44,45,46],ones:22,onli:[2,8,9,16,18,21,22,23,25,27,28,29,32,33,34,36,38,40,41,43,45,46],onlin:[4,5],onto:[32,34,46],opac:44,open:[8,22,27,45],open_h5fil:8,oper:[14,23,34,36,41,42,46],operationnotsupportederror:14,opportun:22,option:[2,22,25,28,29,41,45,46],or_non:16,orang:24,order:[14,22,23,26,31,32,38,41,42,45],ordinari:40,organ:[44,45],organis:[41,46],orient:12,origin:[8,9,14,16,22,27,28,33,38,46],other:[2,5,8,14,16,18,21,22,27,33,36,38,40,41,43,45,46],otherwis:[2,8,17,26,27,29,33,36,38,41,45,46],our:[8,9,12,27,42],out:[22,23,25,27,44],output:[22,25,28,29],output_data_context:[28,29],outsid:[14,44],outstand:[33,46],over:[8,14],overrid:[6,43],overridden:[16,22,27,28],overview:[37,38,44],overwrit:8,own:[27,41],packag:[0,35,41,42,44],package_any_relevant_fil:10,package_glob:[1,35],package_single_project:10,package_workspac:10,page:[5,12,24,37],pair:[8,13],panda:8,panel:24,panick:42,paramet:[8,13,16,22,26,28,29,32,44,45],parent:[8,24,25,32,44],pars:[22,29],parse_nam:29,part:[2,4,7,8,9,14,18,22,23,25,27,28,31,33,36,38,39,40,41,44,45],particular:[14,16,22,23,25,26,31,36,37,40,41,44,45,46],particularli:[14,46],pass:[2,8,9,13,14,16,22,23,25,33,36,42,44,46],passiv:26,password:[21,38,40,41],patch:38,path:[7,8,9,14,22,23,25,29,44],path_exists_in_zip:9,path_for:29,pathnam:8,pattern:46,pear:24,peopl:[9,23],perfectli:[26,45],perform:[3,6,12,14,18,19,23,27,34,42,44],perhap:22,perm_id:21,permiss:[1,35,37,39,40],permissions_manag:[1,35],permissionsmanag:18,persist:[1,11,18,23,35,39,40,41,42],persistenterror:21,person:38,personsalaryperm:38,pertain:9,phrase:16,pickl:[21,22,27,39,40,41],pickle_filenam:22,pickler:22,piec:41,pixel:12,pkgfile:43,place:[16,22,23,27,33,34,44,46],placehold:[1,22,35],plain:[22,42,44],playback:36,pleas:22,plot:28,plug:14,plugin:[1,5,6,9,10,22,27,36,38,43,45,46],point:[10,14,27,42,43,44,46],polici:[2,18,21,37,38,41],policy_data:[1,18],policy_manag:[1,18,41],policy_storag:[1,18,41],policymanag:[21,41],policystorag:[21,41],policystorageerror:[21,39],pop:[25,32],popul:[26,28,38,41,45],posit:[2,14,46],posix:22,possibl:[18,22,25,27,28,29,32,36,38,41,45,46],post:31,post_setattr:16,potenti:46,power:44,pprint:22,pre:31,preced:[23,42],predefin:[16,42],prefer:[1,5,11,12,14,35,37,40,41],preference_bind:[1,35],preference_path:23,preferencebind:23,preferences_help:[1,5,11,24,35],preferences_manag:[1,23],preferences_nod:[1,23],preferences_pag:[1,4,11,12,23],preferences_path:42,preferencesbind:23,preferenceshelp:[5,11,23,24,42,43],preferenceshelpwindow:24,preferencesmanag:24,preferencesmanagerhandl:24,preferencesnod:24,preferencespag:[5,12,24],prefix:[14,38,40],present:[14,24,25],preserv:8,presum:22,pretti:[24,42],previou:[2,25,33,46],previous:[27,42],primari:23,primarili:44,prime:27,primit:23,princip:18,print:[9,24,42,44],printabl:25,prior:27,prioriti:[10,11],probabl:38,problem:22,process:[22,27],produc:[14,31,36,44],profil:41,program:[5,8],project:[2,4,7,9,10,14,18,22,23,25,27,28,31,33],project_load:[1,35],project_vers:22,properli:[29,33],properti:[28,44],propos:16,protect:41,protocol:[22,27],prove:[22,36,40,42],provid:[2,7,8,14,18,22,23,25,26,27,28,29,31,36,37,38,39,40,41,42,43,44,46],provider_id:[26,45],providernotregisterederror:[26,45],proxi:[18,20,22,38],publish:[26,45],pure:22,purpos:16,push:[32,33,34,46],push_abc:32,put:9,py_context:[1,35],py_object_factori:[1,35],pycontext:14,pyf:14,pyfac:[3,5,6,10,12,17,19,20,34,36,38,41,46],pyface_act:[1,18],pyfs_context:[1,35],pyfs_context_factori:[1,35],pyfs_initial_context_factori:[1,35],pyfs_object_factori:[1,35],pyfs_state_factori:[1,35],pyfscontext:14,pyfscontextfactori:14,pyfsinitialcontextfactori:14,pyfsobjectfactori:14,pyfsstatefactori:14,pyobjectfactori:14,pyqt:38,pytabl:8,pytables_group:8,pytables_nod:8,python:[8,9,14,15,17,22,23,25,27,31,36,38,41,44],python_type_system:[1,35],pythonobject:31,pythontypesystem:31,qt4_widget:[1,18],qualifi:[9,32],quality_agent_mail:[1,9],quality_agent_view:[1,9],qualityagentview:10,question:41,queue:9,quick:[9,42],quickest:44,quit:[22,45],rais:[2,8,14,16,21,23,26,28,29,32,36,39,40,45],random:9,rang:[16,44],rare:41,rather:[8,14,16,21,27,36],ratio:[17,42,43],raw:42,rdbm:[40,41],reach:14,react:45,read:[2,8,21,22,27,28,36,37,38,39,40,44],readabl:[8,25,38,44],readi:9,real:[22,28],realli:[22,31,42],reason:[32,44],rebind:[2,14,36],rec:25,receiv:[16,27,45],recent:13,recip:18,recogn:[14,17],recognis:[14,33],recommend:[23,27],reconstitut:[22,27],record:[1,2,3,8,9,12,27,33,35,36,37,41],record_funct:25,record_method:2,record_trait_get:2,record_trait_set:2,recorder_with_ui:[1,35],recordererror:25,recorderwithui:[25,44],recreat:[22,44],red:42,redirect:27,redo:[33,34,46],redo_act:[1,33],redo_nam:46,redoabl:46,redoact:34,redon:[33,46],refactor:[9,22,27],refer:[1,2,9,12,16,22,23,27,33,35,36,37,38,44,46],referenc:[1,2,35],referenceable_state_factori:[1,35],referenceablestatefactori:14,reflect:[14,27,38,46],refresh:14,regard:[14,45],regist:[2,18,21,22,25,26,27,31,32,38,43,44,45],register_adapt:[18,31,38],register_instance_adapt:31,register_permiss:[18,21],register_type_adapt:31,registi:22,registri:[22,25,26,27,32,45],regular:[18,21],reimplement:[18,20,21,34,37,38],rel:[8,14,22],rel_pth:22,relat:[19,21,36,40],relationship:41,relax:40,releas:[21,22],relev:[10,22,38],reli:44,remain:[2,10,22,26,28,45],remot:[39,40,41],remov:[8,23,24,26,27,31,45,46],remove_group:8,remove_nod:8,remove_post:31,remove_pr:31,remove_preferences_listen:23,remove_selection_provid:[26,45],renam:14,repeat:46,repeatedli:[22,26,45],replac:[18,27,33,36],replai:36,report:11,repositori:27,repres:[14,21,22,24,25,26,27,36,42,45],represent:[2,7,14,21,22,27,39,40,44],request:[13,14,26,45],requir:[2,12,14,16,22,26,27,28,29,31,34,38,40,41,45,46],reset:9,reset_button:12,resiz:12,resolut:[14,32],resolv:[14,28],resolve_class:16,respect:[18,22,38,41],respons:[2,31,33,36,38,41,46],rest:[26,45],restat:41,restor:46,restrict:41,result:[2,12,13,14,16,27,33,34,46],reus:[10,27],revers:[22,44],revert:46,revis:22,rewrit:10,ring_buff:[1,35],ringbuff:9,ringbufferful:9,roam:41,role:[21,38,39,41],role_assign:[1,18],role_definit:[1,18],role_nam:21,root:[5,8,17,23,24,31,42],rotatingfilehandl:9,row:8,rpc:41,run:[2,5,6,36],run_fil:[2,36],safe:[27,28],safer:14,saferepr:22,sai:[22,42],salari:38,salary_perm:38,same:[2,9,12,14,22,26,27,28,33,36,38,40,42,45,46],save:[11,14,18,21,22,23,25,33,42,44,46],save_prefer:11,scan:22,scatter_plot:[1,28],scatter_plot_2:[1,28],scatter_plot_nm:[1,28],scenario:31,scheme:23,scope:[14,23,31,37,43],scope_nam:23,scoped_prefer:[1,35],scopedprefer:[23,42,43],scratch:36,screen:42,script:[1,2,3,33,35,37],script_id:[25,44],script_init:[2,36],script_manag:[1,35,36],script_typ:36,script_upd:36,scriptabl:[1,3,25,35,36],scriptable_typ:[1,35],scriptabledatamodel:36,scriptableobject:2,scripted_typ:2,scriptmanag:2,search:[14,32,37,42],search_path:6,second:22,section:[0,36,38,39,40,42,43,46],secur:[18,38,39,40,41],secure_proxi:[1,35],securehandl:[18,38],secureproxi:[18,37],see:[2,8,9,21,22,27,31,36,38,41,42,44],select:[1,18,21,35,37],select_rol:[1,18],select_us:[1,18],selection_servic:[1,35],selectionservic:[26,37],self:[22,27,36,38,43,44],semant:31,send:[11,45],send_bug_report:11,sens:16,sensit:[40,41],sentenc:16,separ:[29,38],seq:22,sequenc:[8,14,26,45,46],sequence_nr:[33,46],serial:[14,28],serv:27,server:[39,40,41],servic:[10,11,12,26,37,38,41],set:[2,8,9,12,14,17,18,20,21,22,23,25,26,28,36,37,40,41,42,43,44,46],set_absolut:22,set_assign:21,set_attribut:14,set_default_prefer:23,set_en:[18,20,38],set_permissions_manag:18,set_record:[25,44],set_rel:22,set_script_manag:[2,36],set_select:[26,45],set_stat:22,set_text:17,set_vis:[18,20,38],setattr:[18,20,38],setstat:27,setup:[22,44],sever:41,shape:8,share:21,shell:36,shiva:44,shortcut:[13,46],should:[8,9,10,14,16,18,22,26,27,28,29,31,38,39,40,41,42,44,45,46],shouldn:40,show:[12,14,18,24,38,45],show_button:12,show_label:12,shown:25,signatur:[26,45],silent:[26,45],similar:[16,46],similarli:22,simpl:[12,22,25,36,38,39,40,41,42,44],simpli:[22,27,38,42,44],simplifi:22,sinc:[8,9,14,22,25,27,44,46],singl:[2,21,27,33,36,38,46],singleton:[18,27,41],situat:[27,40],size:[9,10,12,13],size_max:9,small:44,smallest:27,smtp_server:[10,11],so_need:2,some:[8,14,36,42,46],someon:[14,22,27],someth:36,sometim:44,somewher:14,soon:45,sophist:36,sort:[14,21,31,46],sort_by_class_tre:31,sound:42,sourc:[2,3,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,31,32,33,34,44,45],source_modul:27,source_nam:27,space:12,special:[22,40],specif:[14,16,18,22,23,25,26,31,38,41,44,45],specifi:[8,9,12,13,14,16,17,22,23,24,25,27,28,29,31,32,36,41,42,44,45],spickl:[1,35],splash:42,splash_screen:42,splashscreenprefer:[42,43],split:[8,41],split_application_window:17,split_path:8,splitapplicationwindow:17,sprocket:16,sprout:24,sql:[39,40],squar:16,srinivasan:6,stack:[9,32,33,34,46],stack_trac:[10,11],stack_upd:46,stage:[22,27],standard:[14,18,22,23,27,31,36,38,46],start:[2,3,9,11,14,17,25,36,42,43,44],start_record:[2,25,36],start_recording_act:[1,2],startrecordingact:3,startup:9,state:[14,18,20,22,25,27,33,38,46],state_factori:[1,35],state_pickl:[1,35],statedict:22,statefactori:14,statelist:22,statement:[25,36,39,40],statepickl:22,statepicklererror:22,statesett:22,statesettererror:22,statetupl:22,stateunpickl:22,stateunpicklererror:22,statu:46,stdout:[23,24],stop:[2,3,11,17,25,36,44],stop_record:[2,25,36],stop_recording_act:[1,2],stoprecordingact:3,storag:[8,21,22,37,40],store:[8,14,18,21,22,23,25,38,39,40,41,42,44],str:[8,10,12,16,17,25,26,27,36,42,44,45],strict:27,strightfoward:22,string:[2,8,13,14,16,21,22,23,24,25,28,29,32,36,37,38,39,40,44],strip:22,strongli:27,structur:[24,38,41],stuff:[10,22],style:[12,31,32,38],sub:[9,14,18,29,36,38,44,46],subclass:[16,25,28,29],subgroup_nam:8,subject:[10,11],submenu:5,submodul:[1,4,35],subpackag:35,subsequ:[2,33,36,38,44,46],substitut:28,success:[18,21],successfulli:[18,21],suffici:[39,40,46],suffix:[2,36],suggest:44,suit:[2,4,7,14,18,22,23,25,27,28,31,33,36,41,44,46],suitabl:14,superclass:32,suppli:[40,41],support:[4,14,18,21,22,25,27,28,33,36,38,40,41,45,46],sure:[2,17,23,31,42,45],surfac:44,sweet_pickl:[1,35],swisher:[5,6],synchron:45,synchronis:46,syntax:[14,42],system:[7,9,14,17,31,40,41,42],tabl:[8,12],table_nod:[1,7],tabular_adapt:12,tabular_editor:12,tabularadapt:12,tabulareditor:12,take:[23,28,34,36,42,45,46],taken:[22,44],target:[27,31],target_class:[27,31],target_modul:27,target_nam:27,target_vers:27,tderiv:28,technic:44,tediou:44,tell:46,templat:[1,35],template_choic:[1,35],template_data_context:[1,28],template_data_nam:[1,29,35],template_data_sourc:[1,28],template_from_object:28,template_impl:[1,29,35],template_trait:[1,35],template_view:[1,28],templatechoic:28,templatedatacontext:29,templatedatanam:[28,29],templatedatasourc:29,templatiz:28,tend:38,tenum:28,term:[36,38],terribl:42,test:[1,28,44],text:[11,17,22,25,36,46],than:[8,9,13,14,16,21,27,29,36,38,39,40,41],thei:[18,21,22,23,27,28,29,33,36,38,41,42,44,45,46],them:[2,9,14,22,23,28,31,38,41,42,46],themselv:[14,25,36,38,41],therefor:[16,41],thi:[0,2,5,7,8,9,10,12,14,16,17,18,20,21,22,23,24,25,26,27,28,29,31,33,34,36,38,39,40,41,42,43,44,45,46],thin:8,thing:43,think:[14,22,23],those:[2,14,18,25,27,29,33,36,41,46],though:[14,22,27],thought:46,through:[14,27,44,45],thrown:14,thu:[12,27],time:[2,9,12,14,22,27,42,45,46],tinstanc:28,titl:[10,17],tlist:28,to_address:10,to_datafram:8,toaddr:[10,11],todo:38,togeth:12,toi:44,toler:27,tomer:18,too:[22,42,43,44],tool:[2,4,7,14,18,22,23,25,27,28,31,33,36,41,44,46],toolbar:45,toolkit:[38,41],toolkiteditorfactori:12,top:42,total:12,tour:42,trace:9,traceback:9,tradit:42,trail:23,trait:[2,3,4,5,6,7,10,11,12,13,14,15,16,17,18,19,21,23,24,25,26,27,28,29,31,33,34,36,38,40,42,43,44,45,46],trait_def:[1,14],trait_dict_context_adapt:[1,14],trait_dict_context_adapter_factori:[1,14],trait_handl:[16,28],trait_list_context_adapt:[1,14],trait_list_context_adapter_factori:[1,14],trait_modifi:12,trait_nam:[23,42],trait_name_on_par:25,trait_typ:[2,10,12,17],trait_view:12,traitdictcontextadapt:15,traitdictcontextadapterfactori:15,traiterror:16,traithandl:16,traitlistcontextadapt:15,traitlistcontextadapterfactori:15,traitprefixmap:44,traitrang:16,traits_ui_view:12,traits_view:[24,38],traitsui:[12,18,24,25,41],traitsuiview:12,traittyp:28,trang:28,transform:[22,27],treat:[12,14,27,40,46],tree:[5,14,17,24,31,45],tree_item:[1,23],treeitem:24,tri:[43,44],trigger:[26,45],tupl:[8,10,15,21,22,44],tuple_context_adapt:[1,14],tuple_context_adapter_factori:[1,14],tuplecontextadapt:15,tuplecontextadapterfactori:15,turn:[22,23,44],two:[22,23,27,33,38,40,42,45,46],typ:32,type:[2,8,9,12,14,16,17,18,22,23,27,28,29,31,32,36,37,38,44,46],type_manag:[1,14,35],type_registri:[1,35],typemanag:31,typeregistri:32,typic:[2,18,21,22,33,36,38,40,41,45,46],uch:9,ui_sav:25,uiinfo:18,unauthent:[18,19,21],unauthenticate_us:[18,21,38],unauthoris:[38,41],unbind:14,unbound:[2,36],unchang:12,under:9,underscor:[2,36],understand:27,undo:[1,35,37],undo_act:[1,33],undo_manag:[1,35,46],undo_nam:46,undoabl:46,undoact:34,undomanag:33,undon:[33,34,46],unhook:34,unicod:[22,38,46],unifi:31,unimpl:10,uniqu:[2,14,17,26,36,38,44,45,46],unique_nam:[1,35],unless:[36,41,45],unlik:22,unload:18,unlock:21,unnorm:12,unpickl:[22,27],unregist:[22,25,31,44],unregister_adapt:31,unregister_instance_adapt:31,unregister_type_adapt:31,unresolv:28,unscript:36,unseri:[22,27],until:[14,22,33,46],unzip:22,updat:[1,2,12,18,21,35,36,38,46],update1:22,update2:22,update3:22,update_blob:21,update_en:[18,38],update_password:21,update_st:22,update_vis:[18,38],updatepersonageperm:38,updater_path:22,upgrad:22,upgrade_project:22,upon:28,url:6,usabl:14,usag:46,use:[2,12,14,16,18,21,22,23,25,27,29,36,38,41,42,43,45],useag:42,used:[2,5,6,8,9,13,14,21,22,23,24,25,27,28,29,31,33,36,38,39,40,41,42,43,44,45,46],useful:[14,22,25,27,28,34,41,42],user:[2,12,14,16,18,19,21,22,23,24,25,27,37,39,41,42,44,45,46],user_act:38,user_add:21,user_databas:[1,18,41],user_delet:21,user_factori:[21,40],user_manag:[1,18,38,41],user_menu_manag:[1,18],user_modifi:21,user_nam:21,user_password:21,user_storag:[1,18,41],userdatabas:[21,40,41],usermanag:[21,41],usermenumanag:[19,38],userstorag:[21,41],userstorageerror:[21,40],uses:[2,23,31,36,38,39,40,41,43],using:[8,9,14,16,18,21,22,25,27,28,31,36,38,39,40,41,42,44,45],usual:[22,23,24,42],util:[1,4,5,7,10,35],valid:[8,16,22,26,38,45],validate_fail:16,valu:[2,8,9,12,13,14,16,17,18,20,22,23,27,28,29,33,36,38,41,42,46],value1ddatanameitem:29,value2ddatanameitem:29,value3ddatanameitem:29,value_data_name_item:[1,28],value_nd_data_name_item:[1,28],valuedatanameitem:29,valueerror:[8,23,26,45],valuenddatanameitem:29,variabl:[27,41],variou:[22,27,38,46],veg:24,veri:[22,41,44],verifi:16,version:[14,22,27,28,42],version_registri:[1,35],versioned_unpickl:[1,35],versionedunpickl:[22,27],via:[10,17,22,23,25,38,42,43,44],vibha:6,view:[1,8,9,11,17,18,22,24,41,45],view_menu_manag:5,viewer:5,viewmenumanag:5,visibl:[17,18,20,23,38,42,43],visible_when:38,visitor:14,visual:44,wai:[14,23,27,36,42,44],walk:[22,31,44],want:[22,23,25,31,38,39,40,41,42,44,45],warn:9,web:6,weebl:36,well:[22,44],were:[2,33,46],what:[2,12,22,27,36,37,42,44,45],whatev:[16,23,44],when:[2,8,9,14,18,21,22,25,26,27,28,29,31,32,33,34,36,38,40,41,42,43,44,45,46],whenev:[8,16,26,36,38,45,46],where:[8,9,14,21,22,23,25,27,31,38,42,45],wherea:41,whether:[8,9,16,31,36,38],which:[8,12,14,21,22,23,24,25,27,28,33,36,38,39,40,41,42,43,44,45,46],white:42,who:[27,39,40,41],whole:22,whole_log_text:11,whose:[13,16,18,22,28,36],wide:23,widget:[23,38,41],widget_editor:[1,23],width:[12,23,42,43],win:42,window:[17,45],wire:44,wirefram:44,wish:45,within:[14,27,28,36],without:[2,23,27,33,46],won:[9,36],word:[41,46],work:[8,22,24,27,33,36,41,42,44,46],workbench:[5,6,11,12,46],workbench_act:6,workbench_action_set:5,workbenchact:6,worth:[22,23,42],would:[2,8,9,22,23,27,33,34,38,42,43,45],wrap:[2,8,25,34,36,46],wrapper:[2,8,18,36,46],write:[8,21,22,37,39,40,42],write_script_id_in_namespac:25,writeabl:[7,41],writer:14,written:[14,36,38],wx_window:[1,18],xmarshal:22,xml:41,xxx:8,xyz:2,year:[38,44],yellow:43,yes:41,yet:[10,40],you:[8,22,23,25,27,36,38,41,42,43,44],your:[27,36,38,41,42,43,44],yourself:42,zfile:9,zip:[9,10]},titles:["API documentation","apptools package","apptools.appscripting package","apptools.appscripting.action package","apptools.help package","apptools.help.help_plugin package","apptools.help.help_plugin.action package","apptools.io package","apptools.io.h5 package","apptools.logger package","apptools.logger.agent package","apptools.logger.plugin package","apptools.logger.plugin.view package","apptools.lru_cache package","apptools.naming package","apptools.naming.adapter package","apptools.naming.trait_defs package","apptools.naming.ui package","apptools.permissions package","apptools.permissions.action package","apptools.permissions.adapters package","apptools.permissions.default package","apptools.persistence package","apptools.preferences package","apptools.preferences.ui package","apptools.scripting package","apptools.selection package","apptools.sweet_pickle package","apptools.template package","apptools.template.impl package","apptools.template.test package","apptools.type_manager package","apptools.type_registry package","apptools.undo package","apptools.undo.action package","apptools","Application Scripting Framework","AppTools Documentation","Application API","Default Policy Manager Data API","Default User Manager Data API","Permissions Framework - Introduction","Preferences","Preferences in Envisage","Automatic script recording","The selection service","Undo Framework"],titleterms:{"case":44,"default":[21,39,40,41],"static":36,The:[42,44,45],Using:41,__init__:36,abstract_adapter_factori:31,abstract_command:33,abstract_command_stack_act:34,abstract_factori:31,abstract_type_system:31,abstractcommand:46,access:42,action:[3,6,19,34,38],activ:45,adapt:[15,20,31,38],adapter_bas:18,adapter_factori:31,adapter_manag:31,address:14,advanc:44,agent:10,altern:41,any_context_data_name_item:29,any_data_name_item:29,api:[0,2,3,5,7,9,14,15,16,17,18,19,21,23,24,25,26,28,29,31,32,33,34,36,38,39,40,41,44,45,46],appli:38,applic:[36,38],appscript:[2,3],apptool:[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,37,45],attach:10,authent:38,automat:44,basic:42,bind:14,bind_ev:2,caveat:22,command_act:34,command_stack:33,commandact:46,commandstack:46,concept:[36,41,46],content:[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],context:14,context_adapt:14,context_adapter_factori:14,context_data_name_item:29,context_monitor:17,context_node_typ:17,custom_excepthook:9,data:[38,39,40],defin:38,demo_act:6,deploi:41,dict_context_adapt:15,dict_context_adapter_factori:15,dict_nod:8,dir_context:14,doc_act:6,document:[0,37],dynam:36,dynamic_context:14,enable_editor:30,envisag:43,error:[26,45],exampl:44,example_act:6,examples_prefer:5,except:14,explor:17,factori:31,featur:22,file:[7,8],file_path:22,filtering_handl:9,framework:[36,41,46],further:42,get:38,global_registri:27,gloriou:42,help:[4,5,6],help_cod:5,help_doc:5,help_plugin:[5,6],help_submenu_manag:5,helper:29,hook:31,i_bind_ev:2,i_command:33,i_command_stack:33,i_context_adapt:29,i_help_cod:5,i_help_doc:5,i_policy_manag:18,i_policy_storag:21,i_prefer:23,i_preferences_pag:24,i_script_manag:2,i_select:26,i_selection_provid:[26,45],i_undo_manag:33,i_us:18,i_user_databas:21,i_user_manag:18,i_user_storag:21,ibindev:36,icommand:46,impl:29,implement:[36,41],imutable_templ:28,initial_context:14,initial_context_factori:14,instance_context_adapt:15,instance_context_adapter_factori:15,integr:38,introduct:41,ipolicystorag:39,is_select:45,item:38,itempl:28,itemplate_choic:28,itemplate_data_context:28,itemplate_data_name_item:28,itemplate_data_sourc:28,iuserdatabas:40,iuserstorag:40,lazy_namespac:2,level:36,limit:36,list_context_adapt:15,list_context_adapter_factori:15,list_select:[26,45],listen:45,load_url_act:6,log_point:9,log_queue_handl:9,logger:[9,10,11,12],logger_plugin:11,logger_prefer:11,logger_preferences_pag:12,logger_servic:11,logger_view:12,login_act:19,logout_act:19,lru_cach:13,manag:[38,39,40,41],mechan:42,modul:[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,36,45],mutable_templ:28,name:[14,15,16,17],naming_ev:14,naming_manag:14,naming_node_manag:17,naming_trait:16,naming_tre:17,naming_tree_model:17,need:41,null_handl:9,object:[36,45],object_factori:14,object_node_typ:17,object_seri:14,overview:[36,39,40,46],packag:[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,45],package_glob:[2,18,23,25],particular:42,passiv:45,permiss:[18,19,20,21,38,41],permissions_manag:18,persist:[21,22],placehold:27,plugin:[11,12],polici:39,policy_data:21,policy_manag:21,policy_storag:21,prefer:[23,24,42,43],preference_bind:23,preferences_help:23,preferences_manag:24,preferences_nod:24,preferences_pag:[5,24],project_load:22,provid:45,py_context:14,py_object_factori:14,pyface_act:20,pyfs_context:14,pyfs_context_factori:14,pyfs_initial_context_factori:14,pyfs_object_factori:14,pyfs_state_factori:14,python_type_system:31,qt4_widget:20,quality_agent_mail:10,quality_agent_view:10,queri:45,read:42,record:[25,44],recorder_with_ui:25,redo_act:34,redoact:46,refer:[14,45],referenc:14,referenceable_state_factori:14,registr:45,reimplement:41,ring_buff:9,role_assign:21,role_definit:21,scatter_plot:30,scatter_plot_2:30,scatter_plot_nm:30,scope:42,scoped_prefer:23,script:[25,36,44],script_manag:2,scriptabl:2,scriptable_typ:2,scriptmanag:36,secure_proxi:18,secureproxi:38,select:[26,45],select_rol:21,select_us:21,selection_servic:[26,45],selectionservic:45,servic:45,set:[38,45],specif:36,spickl:22,start_recording_act:3,startrecordingact:36,state_factori:14,state_pickl:22,stop_recording_act:3,stoprecordingact:36,storag:41,string:42,submodul:[2,3,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],subpackag:[1,2,4,5,7,9,11,14,18,23,28,33],sweet_pickl:27,table_nod:8,templat:[28,29,30],template_choic:28,template_data_context:29,template_data_nam:28,template_data_sourc:29,template_impl:28,template_trait:28,template_view:30,test:30,tour:44,trait_def:16,trait_dict_context_adapt:15,trait_dict_context_adapter_factori:15,trait_list_context_adapt:15,trait_list_context_adapter_factori:15,traitsui:38,tree_item:24,tuple_context_adapt:15,tuple_context_adapter_factori:15,type:42,type_manag:31,type_registri:32,undo:[33,34,46],undo_act:34,undo_manag:33,undoact:46,undomanag:46,unique_nam:14,updat:[22,27],use:44,user:[38,40],user_databas:21,user_manag:21,user_menu_manag:19,user_storag:21,util:[6,8,9,25,31],value_data_name_item:29,value_nd_data_name_item:29,version_registri:22,versioned_unpickl:[22,27],view:[12,38],what:41,widget_editor:24,wrap:38,write:38,wx_window:20}}) \ No newline at end of file +Search.setIndex({docnames:["api","api/apptools","api/apptools.io","api/apptools.io.h5","api/apptools.logger","api/apptools.logger.agent","api/apptools.logger.plugin","api/apptools.logger.plugin.view","api/apptools.naming","api/apptools.naming.trait_defs","api/apptools.persistence","api/apptools.preferences","api/apptools.preferences.ui","api/apptools.scripting","api/apptools.selection","api/apptools.type_registry","api/apptools.undo","api/apptools.undo.action","api/modules","index","io/introduction","naming/Introduction","preferences/Preferences","preferences/PreferencesInEnvisage","scripting/introduction","selection/selection","undo/Introduction"],envversion:{"sphinx.domains.c":1,"sphinx.domains.changeset":1,"sphinx.domains.citation":1,"sphinx.domains.cpp":1,"sphinx.domains.javascript":1,"sphinx.domains.math":2,"sphinx.domains.python":1,"sphinx.domains.rst":1,"sphinx.domains.std":1,"sphinx.ext.viewcode":1,sphinx:56},filenames:["api.rst","api/apptools.rst","api/apptools.io.rst","api/apptools.io.h5.rst","api/apptools.logger.rst","api/apptools.logger.agent.rst","api/apptools.logger.plugin.rst","api/apptools.logger.plugin.view.rst","api/apptools.naming.rst","api/apptools.naming.trait_defs.rst","api/apptools.persistence.rst","api/apptools.preferences.rst","api/apptools.preferences.ui.rst","api/apptools.scripting.rst","api/apptools.selection.rst","api/apptools.type_registry.rst","api/apptools.undo.rst","api/apptools.undo.action.rst","api/modules.rst","index.rst","io/introduction.rst","naming/Introduction.rst","preferences/Preferences.rst","preferences/PreferencesInEnvisage.rst","scripting/introduction.rst","selection/selection.rst","undo/Introduction.rst"],objects:{"":{apptools:[1,0,0,"-"]},"apptools.io":{api:[2,0,0,"-"],file:[2,0,0,"-"],h5:[3,0,0,"-"]},"apptools.io.file":{File:[2,1,1,""]},"apptools.io.file.File":{"delete":[2,2,1,""],copy:[2,2,1,""],create_file:[2,2,1,""],create_folder:[2,2,1,""],create_folders:[2,2,1,""],create_package:[2,2,1,""],make_writeable:[2,2,1,""],move:[2,2,1,""]},"apptools.io.h5":{dict_node:[3,0,0,"-"],file:[3,0,0,"-"],table_node:[3,0,0,"-"],utils:[3,0,0,"-"]},"apptools.io.h5.dict_node":{ARRAY_PROXY_KEY:[3,3,1,""],H5DictNode:[3,1,1,""]},"apptools.io.h5.dict_node.H5DictNode":{add_to_h5file:[3,2,1,""],data:[3,2,1,""],flush:[3,2,1,""],is_dict_node:[3,2,1,""],keys:[3,2,1,""]},"apptools.io.h5.file":{H5Attrs:[3,1,1,""],H5File:[3,1,1,""],H5Group:[3,1,1,""],get_atom:[3,5,1,""],h5_group_wrapper:[3,5,1,""],iterator_length:[3,5,1,""]},"apptools.io.h5.file.H5Attrs":{get:[3,2,1,""],items:[3,2,1,""],keys:[3,2,1,""],values:[3,2,1,""]},"apptools.io.h5.file.H5File":{close:[3,2,1,""],create_array:[3,2,1,""],create_dict:[3,2,1,""],create_group:[3,2,1,""],create_table:[3,2,1,""],exists_error:[3,4,1,""],is_open:[3,2,1,""],iteritems:[3,2,1,""],join_path:[3,2,1,""],open:[3,2,1,""],remove_group:[3,2,1,""],remove_node:[3,2,1,""],root:[3,2,1,""],split_path:[3,2,1,""]},"apptools.io.h5.file.H5Group":{children_names:[3,2,1,""],create_array:[3,2,1,""],create_dict:[3,2,1,""],create_group:[3,2,1,""],create_table:[3,2,1,""],filename:[3,2,1,""],iter_groups:[3,2,1,""],name:[3,2,1,""],pathname:[3,2,1,""],remove_group:[3,2,1,""],remove_node:[3,2,1,""],root:[3,2,1,""],subgroup_names:[3,2,1,""]},"apptools.io.h5.table_node":{H5TableNode:[3,1,1,""]},"apptools.io.h5.table_node.H5TableNode":{add_to_h5file:[3,2,1,""],append:[3,2,1,""],is_table_node:[3,2,1,""],ix:[3,2,1,""],keys:[3,2,1,""],to_dataframe:[3,2,1,""]},"apptools.io.h5.utils":{open_h5file:[3,5,1,""]},"apptools.logger":{agent:[5,0,0,"-"],api:[4,0,0,"-"],custom_excepthook:[4,0,0,"-"],log_point:[4,0,0,"-"],log_queue_handler:[4,0,0,"-"],logger:[4,0,0,"-"],plugin:[6,0,0,"-"],ring_buffer:[4,0,0,"-"]},"apptools.logger.agent":{attachments:[5,0,0,"-"],quality_agent_mailer:[5,0,0,"-"],quality_agent_view:[5,0,0,"-"]},"apptools.logger.agent.attachments":{Attachments:[5,1,1,""]},"apptools.logger.agent.attachments.Attachments":{package_any_relevant_files:[5,2,1,""],package_single_project:[5,2,1,""],package_workspace:[5,2,1,""]},"apptools.logger.agent.quality_agent_mailer":{create_email_message:[5,5,1,""]},"apptools.logger.agent.quality_agent_view":{QualityAgentView:[5,1,1,""]},"apptools.logger.agent.quality_agent_view.QualityAgentView":{cc_address:[5,4,1,""],comments:[5,4,1,""],from_address:[5,4,1,""],help_id:[5,4,1,""],include_userdata:[5,4,1,""],msg:[5,4,1,""],priority:[5,4,1,""],service:[5,4,1,""],size:[5,4,1,""],smtp_server:[5,4,1,""],subject:[5,4,1,""],title:[5,4,1,""],to_address:[5,4,1,""]},"apptools.logger.custom_excepthook":{custom_excepthook:[4,5,1,""]},"apptools.logger.log_point":{log_point:[4,5,1,""]},"apptools.logger.log_queue_handler":{LogQueueHandler:[4,1,1,""]},"apptools.logger.log_queue_handler.LogQueueHandler":{emit:[4,2,1,""],get:[4,2,1,""],has_new_records:[4,2,1,""],reset:[4,2,1,""]},"apptools.logger.logger":{LogFileHandler:[4,1,1,""],add_log_queue_handler:[4,5,1,""]},"apptools.logger.plugin":{logger_plugin:[6,0,0,"-"],logger_preferences:[6,0,0,"-"],logger_service:[6,0,0,"-"],view:[7,0,0,"-"]},"apptools.logger.plugin.logger_plugin":{LoggerPlugin:[6,1,1,""]},"apptools.logger.plugin.logger_plugin.LoggerPlugin":{MAIL_FILES:[6,4,1,""],PREFERENCES:[6,4,1,""],PREFERENCES_PAGES:[6,4,1,""],VIEWS:[6,4,1,""],id:[6,4,1,""],mail_files:[6,4,1,""],name:[6,4,1,""],preferences:[6,4,1,""],preferences_pages:[6,4,1,""],start:[6,2,1,""],stop:[6,2,1,""],views:[6,4,1,""]},"apptools.logger.plugin.logger_preferences":{LoggerPreferences:[6,1,1,""]},"apptools.logger.plugin.logger_service":{LoggerService:[6,1,1,""]},"apptools.logger.plugin.logger_service.LoggerService":{create_email_message:[6,2,1,""],save_preferences:[6,2,1,""],send_bug_report:[6,2,1,""],whole_log_text:[6,2,1,""]},"apptools.logger.plugin.view":{logger_preferences_page:[7,0,0,"-"],logger_view:[7,0,0,"-"]},"apptools.logger.plugin.view.logger_preferences_page":{LoggerPreferencesPage:[7,1,1,""]},"apptools.logger.plugin.view.logger_view":{LogRecordAdapter:[7,1,1,""],LoggerView:[7,1,1,""]},"apptools.logger.plugin.view.logger_view.LogRecordAdapter":{column_widths:[7,4,1,""],get_width:[7,2,1,""]},"apptools.logger.plugin.view.logger_view.LoggerView":{activated:[7,4,1,""],activated_text:[7,4,1,""],code_editor:[7,4,1,""],copy_button:[7,4,1,""],formatted_records:[7,4,1,""],id:[7,4,1,""],log_records:[7,4,1,""],log_records_editor:[7,4,1,""],name:[7,4,1,""],reset_button:[7,4,1,""],service:[7,4,1,""],show_button:[7,4,1,""],trait_view:[7,4,1,""],update:[7,2,1,""]},"apptools.logger.ring_buffer":{RingBuffer:[4,1,1,""],RingBufferFull:[4,1,1,""]},"apptools.logger.ring_buffer.RingBuffer":{append:[4,2,1,""],get:[4,2,1,""]},"apptools.logger.ring_buffer.RingBufferFull":{append:[4,2,1,""],get:[4,2,1,""]},"apptools.naming":{address:[8,0,0,"-"],api:[8,0,0,"-"],binding:[8,0,0,"-"],context:[8,0,0,"-"],dir_context:[8,0,0,"-"],dynamic_context:[8,0,0,"-"],exception:[8,0,0,"-"],initial_context:[8,0,0,"-"],initial_context_factory:[8,0,0,"-"],naming_event:[8,0,0,"-"],naming_manager:[8,0,0,"-"],object_factory:[8,0,0,"-"],object_serializer:[8,0,0,"-"],py_context:[8,0,0,"-"],py_object_factory:[8,0,0,"-"],pyfs_context:[8,0,0,"-"],pyfs_context_factory:[8,0,0,"-"],pyfs_initial_context_factory:[8,0,0,"-"],pyfs_object_factory:[8,0,0,"-"],pyfs_state_factory:[8,0,0,"-"],reference:[8,0,0,"-"],referenceable:[8,0,0,"-"],referenceable_state_factory:[8,0,0,"-"],state_factory:[8,0,0,"-"],trait_defs:[9,0,0,"-"],unique_name:[8,0,0,"-"]},"apptools.naming.address":{Address:[8,1,1,""]},"apptools.naming.binding":{Binding:[8,1,1,""]},"apptools.naming.context":{Context:[8,1,1,""]},"apptools.naming.context.Context":{INITIAL_CONTEXT_FACTORY:[8,4,1,""],OBJECT_FACTORIES:[8,4,1,""],STATE_FACTORIES:[8,4,1,""],bind:[8,2,1,""],create_subcontext:[8,2,1,""],destroy_subcontext:[8,2,1,""],get_unique_name:[8,2,1,""],is_context:[8,2,1,""],list_bindings:[8,2,1,""],list_names:[8,2,1,""],lookup:[8,2,1,""],lookup_binding:[8,2,1,""],lookup_context:[8,2,1,""],rebind:[8,2,1,""],rename:[8,2,1,""],search:[8,2,1,""],unbind:[8,2,1,""]},"apptools.naming.dir_context":{DirContext:[8,1,1,""]},"apptools.naming.dir_context.DirContext":{find_bindings:[8,2,1,""],get_attributes:[8,2,1,""],set_attributes:[8,2,1,""]},"apptools.naming.dynamic_context":{DynamicContext:[8,1,1,""]},"apptools.naming.exception":{InvalidNameError:[8,6,1,""],NameAlreadyBoundError:[8,6,1,""],NameNotFoundError:[8,6,1,""],NamingError:[8,6,1,""],NotContextError:[8,6,1,""],OperationNotSupportedError:[8,6,1,""]},"apptools.naming.initial_context":{InitialContext:[8,5,1,""]},"apptools.naming.initial_context_factory":{InitialContextFactory:[8,1,1,""]},"apptools.naming.initial_context_factory.InitialContextFactory":{get_initial_context:[8,2,1,""]},"apptools.naming.naming_event":{NamingEvent:[8,1,1,""]},"apptools.naming.naming_manager":{NamingManager:[8,1,1,""]},"apptools.naming.naming_manager.NamingManager":{get_object_instance:[8,2,1,""],get_state_to_bind:[8,2,1,""]},"apptools.naming.object_factory":{ObjectFactory:[8,1,1,""]},"apptools.naming.object_factory.ObjectFactory":{get_object_instance:[8,2,1,""]},"apptools.naming.object_serializer":{ObjectSerializer:[8,1,1,""]},"apptools.naming.object_serializer.ObjectSerializer":{can_load:[8,2,1,""],can_save:[8,2,1,""],load:[8,2,1,""],save:[8,2,1,""]},"apptools.naming.py_context":{PyContext:[8,1,1,""]},"apptools.naming.py_object_factory":{PyObjectFactory:[8,1,1,""]},"apptools.naming.py_object_factory.PyObjectFactory":{get_object_instance:[8,2,1,""]},"apptools.naming.pyfs_context":{PyFSContext:[8,1,1,""]},"apptools.naming.pyfs_context.PyFSContext":{ATTRIBUTES_FILE:[8,4,1,""],FILTERS:[8,4,1,""],OBJECT_SERIALIZERS:[8,4,1,""],get_unique_name:[8,2,1,""],refresh:[8,2,1,""]},"apptools.naming.pyfs_context_factory":{PyFSContextFactory:[8,1,1,""]},"apptools.naming.pyfs_context_factory.PyFSContextFactory":{get_object_instance:[8,2,1,""]},"apptools.naming.pyfs_initial_context_factory":{PyFSInitialContextFactory:[8,1,1,""]},"apptools.naming.pyfs_initial_context_factory.PyFSInitialContextFactory":{get_initial_context:[8,2,1,""]},"apptools.naming.pyfs_object_factory":{PyFSObjectFactory:[8,1,1,""]},"apptools.naming.pyfs_object_factory.PyFSObjectFactory":{get_object_instance:[8,2,1,""]},"apptools.naming.pyfs_state_factory":{PyFSStateFactory:[8,1,1,""]},"apptools.naming.pyfs_state_factory.PyFSStateFactory":{get_state_to_bind:[8,2,1,""]},"apptools.naming.reference":{Reference:[8,1,1,""]},"apptools.naming.referenceable":{Referenceable:[8,1,1,""]},"apptools.naming.referenceable_state_factory":{ReferenceableStateFactory:[8,1,1,""]},"apptools.naming.referenceable_state_factory.ReferenceableStateFactory":{get_state_to_bind:[8,2,1,""]},"apptools.naming.state_factory":{StateFactory:[8,1,1,""]},"apptools.naming.state_factory.StateFactory":{get_state_to_bind:[8,2,1,""]},"apptools.naming.trait_defs":{api:[9,0,0,"-"],naming_traits:[9,0,0,"-"]},"apptools.naming.trait_defs.naming_traits":{NamingTraitHandler:[9,1,1,""]},"apptools.naming.trait_defs.naming_traits.NamingTraitHandler":{find_class:[9,2,1,""],get_editor:[9,2,1,""],info:[9,2,1,""],post_setattr:[9,2,1,""],resolve_class:[9,2,1,""],validate:[9,2,1,""],validate_failed:[9,2,1,""]},"apptools.naming.unique_name":{make_unique_name:[8,5,1,""]},"apptools.persistence":{file_path:[10,0,0,"-"],project_loader:[10,0,0,"-"],state_pickler:[10,0,0,"-"],updater:[10,0,0,"-"],version_registry:[10,0,0,"-"],versioned_unpickler:[10,0,0,"-"]},"apptools.persistence.file_path":{FilePath:[10,1,1,""]},"apptools.persistence.file_path.FilePath":{get:[10,2,1,""],set:[10,2,1,""],set_absolute:[10,2,1,""],set_relative:[10,2,1,""]},"apptools.persistence.project_loader":{load_project:[10,5,1,""],upgrade_project:[10,5,1,""]},"apptools.persistence.state_pickler":{State:[10,1,1,""],StateDict:[10,1,1,""],StateList:[10,1,1,""],StatePickler:[10,1,1,""],StatePicklerError:[10,6,1,""],StateSetter:[10,1,1,""],StateSetterError:[10,6,1,""],StateTuple:[10,1,1,""],StateUnpickler:[10,1,1,""],StateUnpicklerError:[10,6,1,""],create_instance:[10,5,1,""],dump:[10,5,1,""],dumps:[10,5,1,""],get_state:[10,5,1,""],gunzip_string:[10,5,1,""],gzip_string:[10,5,1,""],load_state:[10,5,1,""],loads_state:[10,5,1,""],set_state:[10,5,1,""],update_state:[10,5,1,""]},"apptools.persistence.state_pickler.StatePickler":{dump:[10,2,1,""],dump_state:[10,2,1,""],dumps:[10,2,1,""]},"apptools.persistence.state_pickler.StateSetter":{set:[10,2,1,""]},"apptools.persistence.state_pickler.StateUnpickler":{load_state:[10,2,1,""],loads_state:[10,2,1,""]},"apptools.persistence.updater":{Updater:[10,1,1,""]},"apptools.persistence.updater.Updater":{get_latest:[10,2,1,""],strip:[10,2,1,""]},"apptools.persistence.version_registry":{HandlerRegistry:[10,1,1,""],get_version:[10,5,1,""]},"apptools.persistence.version_registry.HandlerRegistry":{register:[10,2,1,""],unregister:[10,2,1,""],update:[10,2,1,""]},"apptools.persistence.versioned_unpickler":{NewUnpickler:[10,1,1,""],VersionedUnpickler:[10,1,1,""]},"apptools.persistence.versioned_unpickler.NewUnpickler":{initialize:[10,2,1,""],load:[10,2,1,""],load_build:[10,2,1,""]},"apptools.persistence.versioned_unpickler.VersionedUnpickler":{add_updater:[10,2,1,""],backup_setstate:[10,2,1,""],find_class:[10,2,1,""],import_name:[10,2,1,""]},"apptools.preferences":{api:[11,0,0,"-"],i_preferences:[11,0,0,"-"],package_globals:[11,0,0,"-"],preference_binding:[11,0,0,"-"],preferences:[11,0,0,"-"],preferences_helper:[11,0,0,"-"],scoped_preferences:[11,0,0,"-"],ui:[12,0,0,"-"]},"apptools.preferences.i_preferences":{IPreferences:[11,1,1,""]},"apptools.preferences.i_preferences.IPreferences":{clear:[11,2,1,""],flush:[11,2,1,""],get:[11,2,1,""],keys:[11,2,1,""],node:[11,2,1,""],node_exists:[11,2,1,""],node_names:[11,2,1,""],remove:[11,2,1,""],set:[11,2,1,""]},"apptools.preferences.package_globals":{get_default_preferences:[11,5,1,""],set_default_preferences:[11,5,1,""]},"apptools.preferences.preference_binding":{PreferenceBinding:[11,1,1,""],bind_preference:[11,5,1,""]},"apptools.preferences.preferences":{Preferences:[11,1,1,""]},"apptools.preferences.preferences.Preferences":{add_preferences_listener:[11,2,1,""],clear:[11,2,1,""],dump:[11,2,1,""],flush:[11,2,1,""],get:[11,2,1,""],keys:[11,2,1,""],load:[11,2,1,""],node:[11,2,1,""],node_exists:[11,2,1,""],node_names:[11,2,1,""],remove:[11,2,1,""],remove_preferences_listener:[11,2,1,""],save:[11,2,1,""],set:[11,2,1,""]},"apptools.preferences.preferences_helper":{PreferencesHelper:[11,1,1,""]},"apptools.preferences.scoped_preferences":{ScopedPreferences:[11,1,1,""]},"apptools.preferences.scoped_preferences.ScopedPreferences":{add_preferences_listener:[11,2,1,""],clear:[11,2,1,""],dump:[11,2,1,""],get:[11,2,1,""],get_scope:[11,2,1,""],keys:[11,2,1,""],load:[11,2,1,""],node:[11,2,1,""],node_exists:[11,2,1,""],node_names:[11,2,1,""],remove:[11,2,1,""],remove_preferences_listener:[11,2,1,""],save:[11,2,1,""],set:[11,2,1,""]},"apptools.preferences.ui":{api:[12,0,0,"-"],i_preferences_page:[12,0,0,"-"],preferences_manager:[12,0,0,"-"],preferences_node:[12,0,0,"-"],preferences_page:[12,0,0,"-"],tree_item:[12,0,0,"-"],widget_editor:[12,0,0,"-"]},"apptools.preferences.ui.i_preferences_page":{IPreferencesPage:[12,1,1,""]},"apptools.preferences.ui.i_preferences_page.IPreferencesPage":{apply:[12,2,1,""]},"apptools.preferences.ui.preferences_manager":{PreferencesHelpWindow:[12,1,1,""],PreferencesManager:[12,1,1,""],PreferencesManagerHandler:[12,1,1,""]},"apptools.preferences.ui.preferences_manager.PreferencesHelpWindow":{traits_view:[12,2,1,""]},"apptools.preferences.ui.preferences_manager.PreferencesManager":{apply:[12,2,1,""],traits_view:[12,2,1,""]},"apptools.preferences.ui.preferences_manager.PreferencesManagerHandler":{apply:[12,2,1,""],close:[12,2,1,""],init:[12,2,1,""],preferences_help:[12,2,1,""]},"apptools.preferences.ui.preferences_node":{PreferencesNode:[12,1,1,""]},"apptools.preferences.ui.preferences_node.PreferencesNode":{create_page:[12,2,1,""],dump:[12,2,1,""],lookup:[12,2,1,""]},"apptools.preferences.ui.preferences_page":{PreferencesPage:[12,1,1,""]},"apptools.preferences.ui.preferences_page.PreferencesPage":{apply:[12,2,1,""]},"apptools.preferences.ui.tree_item":{TreeItem:[12,1,1,""]},"apptools.preferences.ui.tree_item.TreeItem":{append:[12,2,1,""],insert:[12,2,1,""],insert_after:[12,2,1,""],insert_before:[12,2,1,""],remove:[12,2,1,""]},"apptools.preferences.ui.widget_editor":{WidgetEditor:[12,1,1,""]},"apptools.preferences.ui.widget_editor.WidgetEditor":{custom_editor:[12,2,1,""],readonly_editor:[12,2,1,""],simple_editor:[12,2,1,""],text_editor:[12,2,1,""]},"apptools.scripting":{api:[13,0,0,"-"],package_globals:[13,0,0,"-"],recordable:[13,0,0,"-"],recorder:[13,0,0,"-"],recorder_with_ui:[13,0,0,"-"],util:[13,0,0,"-"]},"apptools.scripting.package_globals":{get_recorder:[13,5,1,""],set_recorder:[13,5,1,""]},"apptools.scripting.recordable":{recordable:[13,5,1,""]},"apptools.scripting.recorder":{Recorder:[13,1,1,""],RecorderError:[13,6,1,""]},"apptools.scripting.recorder.Recorder":{clear:[13,2,1,""],get_code:[13,2,1,""],get_object_path:[13,2,1,""],get_script_id:[13,2,1,""],is_registered:[13,2,1,""],record:[13,2,1,""],record_function:[13,2,1,""],register:[13,2,1,""],save:[13,2,1,""],ui_save:[13,2,1,""],unregister:[13,2,1,""],write_script_id_in_namespace:[13,2,1,""]},"apptools.scripting.recorder_with_ui":{CloseHandler:[13,1,1,""],RecorderWithUI:[13,1,1,""]},"apptools.scripting.recorder_with_ui.CloseHandler":{close:[13,2,1,""]},"apptools.scripting.recorder_with_ui.RecorderWithUI":{on_ui_close:[13,2,1,""]},"apptools.scripting.util":{start_recording:[13,5,1,""],stop_recording:[13,5,1,""]},"apptools.selection":{api:[14,0,0,"-"],errors:[14,0,0,"-"],i_selection:[14,0,0,"-"],i_selection_provider:[14,0,0,"-"],list_selection:[14,0,0,"-"],selection_service:[14,0,0,"-"]},"apptools.selection.errors":{IDConflictError:[14,6,1,""],ListenerNotConnectedError:[14,6,1,""],ProviderNotRegisteredError:[14,6,1,""]},"apptools.selection.i_selection":{IListSelection:[14,1,1,""],ISelection:[14,1,1,""]},"apptools.selection.i_selection.IListSelection":{indices:[14,4,1,""],items:[14,4,1,""]},"apptools.selection.i_selection.ISelection":{is_empty:[14,2,1,""],provider_id:[14,4,1,""]},"apptools.selection.i_selection_provider":{ISelectionProvider:[14,1,1,""]},"apptools.selection.i_selection_provider.ISelectionProvider":{get_selection:[14,2,1,""],provider_id:[14,4,1,""],selection:[14,4,1,""],set_selection:[14,2,1,""]},"apptools.selection.list_selection":{ListSelection:[14,1,1,""]},"apptools.selection.list_selection.ListSelection":{from_available_items:[14,2,1,""],indices:[14,4,1,""],is_empty:[14,2,1,""],items:[14,4,1,""],provider_id:[14,4,1,""]},"apptools.selection.selection_service":{SelectionService:[14,1,1,""]},"apptools.selection.selection_service.SelectionService":{add_selection_provider:[14,2,1,""],connect_selection_listener:[14,2,1,""],disconnect_selection_listener:[14,2,1,""],get_selection:[14,2,1,""],has_selection_provider:[14,2,1,""],remove_selection_provider:[14,2,1,""],set_selection:[14,2,1,""]},"apptools.type_registry":{api:[15,0,0,"-"],type_registry:[15,0,0,"-"]},"apptools.type_registry.type_registry":{LazyRegistry:[15,1,1,""],TypeRegistry:[15,1,1,""],get_mro:[15,5,1,""]},"apptools.type_registry.type_registry.LazyRegistry":{lookup_by_type:[15,2,1,""]},"apptools.type_registry.type_registry.TypeRegistry":{lookup:[15,2,1,""],lookup_all:[15,2,1,""],lookup_all_by_type:[15,2,1,""],lookup_by_type:[15,2,1,""],pop:[15,2,1,""],push:[15,2,1,""],push_abc:[15,2,1,""]},"apptools.undo":{abstract_command:[16,0,0,"-"],action:[17,0,0,"-"],api:[16,0,0,"-"],command_stack:[16,0,0,"-"],i_command:[16,0,0,"-"],i_command_stack:[16,0,0,"-"],i_undo_manager:[16,0,0,"-"],undo_manager:[16,0,0,"-"]},"apptools.undo.abstract_command":{AbstractCommand:[16,1,1,""]},"apptools.undo.abstract_command.AbstractCommand":{"do":[16,2,1,""],merge:[16,2,1,""],redo:[16,2,1,""],undo:[16,2,1,""]},"apptools.undo.action":{abstract_command_stack_action:[17,0,0,"-"],api:[17,0,0,"-"],command_action:[17,0,0,"-"],redo_action:[17,0,0,"-"],undo_action:[17,0,0,"-"]},"apptools.undo.action.abstract_command_stack_action":{AbstractCommandStackAction:[17,1,1,""]},"apptools.undo.action.abstract_command_stack_action.AbstractCommandStackAction":{destroy:[17,2,1,""]},"apptools.undo.action.command_action":{CommandAction:[17,1,1,""]},"apptools.undo.action.command_action.CommandAction":{perform:[17,2,1,""]},"apptools.undo.action.redo_action":{RedoAction:[17,1,1,""]},"apptools.undo.action.redo_action.RedoAction":{perform:[17,2,1,""]},"apptools.undo.action.undo_action":{UndoAction:[17,1,1,""]},"apptools.undo.action.undo_action.UndoAction":{perform:[17,2,1,""]},"apptools.undo.command_stack":{CommandStack:[16,1,1,""]},"apptools.undo.command_stack.CommandStack":{begin_macro:[16,2,1,""],clear:[16,2,1,""],end_macro:[16,2,1,""],push:[16,2,1,""],redo:[16,2,1,""],undo:[16,2,1,""]},"apptools.undo.i_command":{ICommand:[16,1,1,""]},"apptools.undo.i_command.ICommand":{"do":[16,2,1,""],merge:[16,2,1,""],redo:[16,2,1,""],undo:[16,2,1,""]},"apptools.undo.i_command_stack":{ICommandStack:[16,1,1,""]},"apptools.undo.i_command_stack.ICommandStack":{begin_macro:[16,2,1,""],clear:[16,2,1,""],end_macro:[16,2,1,""],push:[16,2,1,""],redo:[16,2,1,""],undo:[16,2,1,""]},"apptools.undo.i_undo_manager":{IUndoManager:[16,1,1,""]},"apptools.undo.i_undo_manager.IUndoManager":{redo:[16,2,1,""],undo:[16,2,1,""]},"apptools.undo.undo_manager":{UndoManager:[16,1,1,""]},"apptools.undo.undo_manager.UndoManager":{redo:[16,2,1,""],undo:[16,2,1,""]},apptools:{io:[2,0,0,"-"],logger:[4,0,0,"-"],naming:[8,0,0,"-"],persistence:[10,0,0,"-"],preferences:[11,0,0,"-"],scripting:[13,0,0,"-"],selection:[14,0,0,"-"],type_registry:[15,0,0,"-"],undo:[16,0,0,"-"]}},objnames:{"0":["py","module","Python module"],"1":["py","class","Python class"],"2":["py","method","Python method"],"3":["py","data","Python data"],"4":["py","attribute","Python attribute"],"5":["py","function","Python function"],"6":["py","exception","Python exception"]},objtypes:{"0":"py:module","1":"py:class","2":"py:method","3":"py:data","4":"py:attribute","5":"py:function","6":"py:exception"},terms:{"abstract":[2,10,12,16,17,26],"boolean":[8,22,26],"case":[5,10,11,20,22,25],"class":[2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,22,23,24,26],"default":[3,4,7,9,10,11,12,13,14,16,17,22,23,26],"final":25,"float":[7,8,10,22,24],"function":[4,8,9,10,13,20,24,25],"import":[4,10,15,22,24,25],"int":[10,22],"long":[10,22,26],"new":[3,7,8,9,10,11,13,15,17,20,22,25],"public":[5,13,25],"return":[3,4,6,7,8,9,10,11,12,13,14,15,16,17,22,23,25,26],"static":8,"transient":22,"true":[3,6,8,10,11,13,14,16,22,23,24,25,26],"try":[11,16,22,26],"while":[7,10,16,25,26],And:22,But:22,ETS:24,For:[3,9,10,13,20,22,24,25],Has:14,Its:[10,16,26],Not:8,One:24,That:3,The:[3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,19,20,23,26],Then:11,There:11,These:15,Used:10,Useful:13,Using:[22,24,26],__array__:3,__attributes__:8,__class__:10,__dict__:10,__getstate__:10,__init__:[10,16,26],__main__:10,__metadata__:10,__module__:15,__name__:[10,15],__set_pure_state__:10,__setitem__:3,__setstate__:10,__version__:10,_unpickl:10,abandon:[16,26],abc:[3,15],abcmeta:15,abl:[22,24],about:[8,10,16,22,24,25],abov:24,absolut:[3,10,15],abstract_command:[1,18],abstract_command_stack_act:[1,16],abstractcommand:16,abstractcommandstackact:17,accept:[8,9],access:[3,11],aclass:9,acm:[11,22,23],act:[8,25],action:[1,16,24,25,26],activ:[7,14,16,17,26],activated_text:7,active_stack:26,active_stack_clean:26,actual:[4,7,8,9,10,13,22],adapt:7,add:[3,4,7,10,11,13,14,22,26],add_log_queue_handl:4,add_preferences_listen:11,add_selection_provid:[14,25],add_to_h5fil:3,add_updat:10,added:[11,14],adding:8,addit:[3,8,11],addition:10,address:[1,18],affect:11,after:[3,10,12,13],age:24,agent:[1,4],alia:5,all:[2,6,7,8,10,11,12,13,14,15,16,17,22,24,26],all_item:14,alloc:26,allow:[3,7,8,9,10,11,12,16,22,23,24,26],allows_children:12,almost:10,along:[10,16],alreadi:[2,3,8,13,14],also:[3,8,10,11,13,16,21,22,23,24,25,26],alter:3,altern:[9,10,26],alwai:[11,22,24],amount:7,ani:[2,5,7,8,9,10,11,14,16,17,22,23,24,25,26],anoth:[8,16,22],answer:10,anymor:25,anywher:22,api:[1,6,18,19,22],app:10,appear:[10,26],append:[3,4,11,12,24],appl:12,appli:[10,12],applic:[4,8,10,11,16,22,23,24,25,26],application_hom:22,application_scop:11,application_vers:10,approach:22,appropri:[10,16,26],apptool:[0,20,21,22,24],arbitrari:[9,24],arg:[3,5,6,7,12,13,26],argmument:3,argument:[3,13,14,16,17,24,25,26],around:[3,20,22,26],arrai:[3,10],arrang:22,array_or_shap:3,array_proxy_kei:3,arriv:7,ascend:8,ascii:10,ask:[8,11,13],assert:10,assign:[7,9],assist:8,associ:[8,22],assum:[3,10],atom:3,attach:[1,4,24],attempt:[2,8],attribut:[3,8,9,10,13,24],attributes_fil:8,auto:0,auto_flush:3,auto_group:3,auto_open:3,automat:[3,8,11,13,19,22,26],avail:[7,13,14,20,23,25,26],avoid:[8,10,11],back:[10,11,22],background:24,backup_setst:10,backupcount:4,base64:10,base:[2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,24,25,26],base_f_nam:10,base_toolkit:5,basic:[10,13,19],becam:20,becaus:[5,8,10,22,25],becom:[25,26],been:[3,13,14,15,16,24,25,26],befor:[4,10,12,14,16,20,22,25,26],begin:[8,16,26],begin_macro:[16,26],behavior:3,behaviour:[22,23],being:[8,9,10,12,16,24,26],believ:22,below:3,best:[10,24],better:11,between:[10,11,24,25],bgcolor:[11,22,23],bind:[1,11,18],bind_prefer:11,bit:22,black:22,blog:4,blue:[11,22,23],bogu:22,bool:[3,10,13,14,22,24],both:[15,26],bound:8,brief:26,broker:25,brows:10,buffer:[3,4],bug:6,build:22,builtin:10,bump:10,bunch:10,button:[7,12,22,25],calcul:[3,7,8],call:[3,4,8,9,10,11,13,14,16,17,22,24,25,26],callabl:[14,25,26],callback:[14,24,25],came:11,can:[3,4,5,8,9,10,11,14,15,16,20,21,22,24,25,26],can_load:8,can_sav:8,cannot:[8,11],capabl:8,care:[10,22,26],carrot:12,categori:8,cauliflow:12,caveat:1,cc_address:5,ccaddr:[5,6],central:25,chang:[8,11,12,13,14,16,22,24,25,26],charact:26,check:10,child:[11,12,22,24],children:[3,11,16,24],children_nam:3,chunk:3,class_nam:10,classmethod:[3,10,14],clean:[13,16,26],cleaner:3,clear:[11,13,16,26],click:12,close:[3,12,13,25],closehandl:13,code:[5,8,10,13,20,24],code_editor:7,collaps:26,collect:[3,14,25],color:24,column:[3,7],column_width:7,combin:9,come:22,command:[11,16,17,24,26],command_act:[1,16],command_stack:[1,18,26],commandact:17,commandstack:16,comment:[5,6],common:[10,20,25,26],commuic:8,commun:[8,25],complet:[9,10,26],complex:[10,22,25],complic:[10,22],compon:[8,25,26],compos:8,concept:19,concern:10,configobj:[11,22],configur:26,conform:8,confus:26,connect:[14,25],connect_selection_listen:[14,25],consid:24,consist:[8,22],consumpt:25,contain:[0,3,8,10,11,12,13,14,16,22,25,26],content:[18,25],context:[1,3,10,18],context_nam:8,context_ord:8,continu:8,contribut:[8,23],contributes_to:23,control:[3,12,25],conveni:[4,10,13,22,24,26],convers:10,convert:[3,7,10,22],cookbook:4,copi:[2,4,16,26],copy_button:7,core:24,correct:10,correctli:10,correspond:25,could:25,couldn:26,cours:11,creat:[2,3,4,7,8,10,11,12,13,14,16,22,24,26],create_:3,create_arrai:3,create_carrai:3,create_dict:3,create_email_messag:[5,6],create_fil:2,create_fold:2,create_group:3,create_inst:10,create_packag:2,create_pag:12,create_subcontext:8,create_t:3,creation:[8,12],criteria:8,current:[8,10,11,12,13,14,22,24,25,26],custom:12,custom_editor:12,custom_excepthook:[1,18],data:[3,6,8,10,12,16,26],datafram:3,debug:[13,22],decid:10,decor:[13,24],decreas:7,deep:[16,26],def:[10,22,23,24],default_prefer:11,default_valu:24,defin:[7,9,10,11,13,24,25,26],definit:[8,11,24],delet:[2,3],delete_exist:3,demonstr:26,depend:[10,11,25],descend:11,describ:[8,9,10,23],descript:[3,12],desir:[3,8,23],destin:2,destroi:[8,17,25],destroy_subcontext:8,detail:[10,24],determin:[8,10],develop:[11,25,26],dialog:[12,13,25],dict:[3,10,13],dict_nod:[1,2],dictat:23,dictionari:[3,8,10,13,20,22],did:[11,22],differ:[3,8,10],dir_context:[1,18],dircontext:8,direct:25,directi:10,directli:[11,22,25],directori:[8,21,22],disabl:[16,26],disappear:25,discard:16,disconnect:[14,25],disconnect_selection_listen:[14,25],discuss:[22,23],disk:[3,10,22,26],displai:[4,25],distinct:25,divid:7,docstr:3,document:[3,22,24,26],doe:[2,3,4,8,10,11,13,17,22,23],doesn:[12,22],don:[22,23],done:[13,24,25,26],drawback:11,dtype:3,dump:[10,11,12,22],dump_stat:10,duplic:[10,14],dure:10,dynam:[7,8],dynamic_context:[1,18],dynamiccontext:8,each:[7,8,10,11,15,22,24,26],easi:[3,10,11],easili:[10,24],edit:[9,10,26],editor:[7,9,10,12,25,26],editor_factori:12,editorfactori:12,effect:[16,26],either:[3,9,10,11,22,24],element:[4,8,14,25,26],elimin:10,els:[3,10,15],email:6,embed:10,emit:4,empti:[8,11,14,16,26],encapsul:10,encod:10,encourag:[11,20],end:[4,8,10,13,16,24,26],end_macro:[16,26],endo:26,endpoint:8,enlib:5,enough:24,enqueu:4,ensur:[10,16,26],enthought:[2,8,10,11,13,16,26],enthoughtbas:4,entir:10,entri:26,environ:[3,8],envisag:[5,6,8,19,22,25],equal:7,error:[1,9,10,18],especi:25,etc:[4,8,10,11,17,22],etsconfig:22,even:14,event:[8,14,17,25,26],ever:[16,26],everi:4,everyth:10,exactli:22,examin:8,exampl:[3,9,10,11,12,22,25,26],excel:22,except:[1,4,9,10,11,13,14,18],exclud:10,execut:[4,13,16,24,26],exist:[2,3,8,10,11,12,13,22],exists_error:3,expect:14,explan:7,explicit:22,explicitli:[3,8,11,14,23,26],expos:[3,6,25],extend:[3,8],extens:[5,23,25],extern:25,extra:23,facil:24,factori:[8,12,26],fairli:24,fals:[3,5,6,7,8,11,12,13,14,22,24],featur:[1,26],few:24,fgcolor:22,file:[1,4,5,6,8,10,11,13,18,19,22,23],file_or_filenam:11,file_path:[1,18],filenam:[3,11,22],filenod:3,filepath:10,filesystem:22,fill:14,filter:8,find:[8,11,13,21,24],find_bind:8,find_class:[9,10],fire:[8,14,25,26],first:[3,10,22,24,25],fix:[7,10],fix_import:10,fixm:[5,11,13],flexibl:10,flush:[3,11,22],folder:2,follow:[13,22,24,26],forc:[7,11],form:[10,12],format:[6,8,10,22],formatt:4,formatted_record:7,forwardproperti:7,found:[8,14],fraction:7,framework:[8,13,19,24],fred:22,free:23,friend:[10,24],from:[4,6,8,10,11,12,13,14,16,22,24],from_address:5,from_available_item:14,fromaddr:[5,6],fruit:12,full:24,fulli:15,func:[13,14],further:19,gener:[0,4,8,10,12,22,26],get:[3,4,8,10,11,15,22,23,24,25],get_atom:3,get_attribut:8,get_cod:13,get_default_prefer:11,get_editor:9,get_initial_context:8,get_latest:10,get_mro:15,get_object_inst:8,get_object_path:13,get_prefer:23,get_record:13,get_scop:[11,22],get_script_id:13,get_select:[14,25],get_stat:10,get_state_to_bind:8,get_unique_nam:8,get_vers:10,get_width:7,give:[10,26],given:[3,7,8,10,11,13,14,15,16,24,25,26],global:[11,13,24],going:[10,24],great:17,group:[3,7],group_path:3,group_subpath:3,grow:24,guarante:[13,16,26],gui:[25,26],guid:9,gunzip_str:10,gzip:10,gzip_str:10,h5_group:3,h5_group_wrapp:3,h5attr:3,h5dictnod:3,h5file:3,h5filter:3,h5group:3,h5tablenod:3,halt:4,handi:24,handl:[10,12,25,26],handler:[4,7,9,10,12,13],handlerregistri:10,happen:8,happi:22,hard:5,has:[4,7,8,10,12,13,14,15,22,25,26],has_inst:10,has_new_record:4,has_selection_provid:14,has_trait:[2,5,6,8,11,12,13,14,16],hasprivatetrait:[2,8],hasstricttrait:24,hastrait:[5,6,8,9,11,12,13,14,16,24],have:[3,7,10,11,16,22,24,25,26],hdf5:[3,19],heirarchi:[8,21],help:[3,10,12],help_id:5,helper:[22,23],henc:[22,23],here:[5,10,11,21,22,24],hid_quality_agent_dlg:5,hierarch:22,hierarchi:[10,11,13,22,24],high:24,highli:[10,11],hold:22,hopefulli:22,horizont:7,how:[8,22,23,26],howev:[10,26],html:26,human:24,i_command:[1,18],i_command_stack:[1,18],i_prefer:[1,18],i_preferences_pag:[1,11],i_select:[1,18],i_selection_provid:[1,18],i_undo_manag:[1,18],icommand:16,icommandstack:[16,26],idconflicterror:14,idea:[10,22],ideal:[10,25],identifi:[3,14,26],ignor:[10,13,14,24,26],ignore_miss:[14,25],ilistselect:14,imag:[12,22],immedi:26,implement:[3,9,10,11,14,15,16,20,21,22,23,25,26],implent:11,import_nam:10,inadequ:10,inappropri:26,includ:[9,10,11,16,21,26],include_environ:6,include_project:5,include_userdata:[5,6],increas:[7,24],increment:[10,26],indent:[11,12],independ:26,index:[12,26],indic:[8,14,25,26],info:[8,9,12,13],info_text:9,inform:[3,8,9,10,14,22,24,25],infrastructur:24,inherit:[11,22],ini:[22,23],init:12,initarg:10,initi:[3,8,10,11,12,14,25],initial_context:[1,18],initial_context_factori:[1,18],initialcontext:8,initialcontextfactori:8,inject:13,input:3,insert:12,insert_aft:12,insert_befor:12,insid:24,instal:3,instanc:[3,7,8,9,10,11,12,13,14,15,16,17,24,25,26],instanti:[13,24],instead:[9,10,25],insuffici:10,integ:[7,26],intend:26,intent:11,interact:8,intercept:3,interest:[8,22],interfac:[3,7,9,11,12,13,14,16,21,22,24,25,26],intermedi:[2,8],intern:[14,24,25],interpret:[10,13],invalid:8,invalidnameerror:8,invert:13,investig:20,invok:[13,26],iprefer:[11,22],ipreferencespag:12,irrespect:26,is_context:8,is_dict_nod:3,is_empti:14,is_ok:[12,13],is_open:3,is_regist:13,is_table_nod:3,iselect:[14,25],iselectionprovid:[14,25],isn:22,issu:10,item:[3,7,8,12,14,25,26],items:3,iter:3,iter_group:3,iterator_length:3,iteritem:3,its:[7,8,10,11,12,13,14,15,22,24,25,26],itself:[8,10,11,13,22,23,24,26],iundomanag:[16,26],java:21,jndi:21,join:3,join_path:3,json:3,just:[10,11,22,23,24],keep:[10,16,25],kei:[3,10,11,24],keyboard:26,keyerror:15,keyword:[3,13,24,25],klass:10,know:10,knowledg:10,known:[10,13],kwarg:[3,5,6,7],larg:10,last:[10,15,16,17,26],later:[4,10,16],latest:10,layer:22,lazi:26,lazili:15,lazyregistri:15,learn:24,leav:[7,16,26],let:[22,24],level:[4,8,24],lib:5,librari:[20,24],like:[3,4,10,11,22,23,24],limit:22,line:[11,13,24],link:26,list:[3,4,6,7,8,10,11,13,14,15,24,25],list_bind:8,list_nam:8,list_select:[1,18],listen:[11,13,14,17,19,22,24],listenernotconnectederror:14,listselect:[14,25],littl:7,live:8,load:[8,10,11,22,23,26],load_build:10,load_project:10,load_stat:10,loads_stat:10,local:8,locat:[8,24],log:[4,6,7],log_point:[1,18],log_queue_handl:[1,18],log_record:7,log_records_editor:7,logfilehandl:4,logger:[1,18],logger_plugin:[1,4],logger_prefer:[1,4],logger_preferences_pag:[1,4,6],logger_servic:[1,4],logger_view:[1,4,6],loggerplugin:6,loggerprefer:6,loggerpreferencespag:7,loggerservic:6,loggerview:7,logic:13,logqueuehandl:4,logrecord:7,logrecordadapt:7,longer:[10,17,25],look:[3,8,11,15,22,24],lookup:[8,12,15],lookup_al:15,lookup_all_by_typ:15,lookup_bind:8,lookup_by_typ:15,lookup_context:8,lot:10,lowest:22,macro:[16,26],made:[8,12,16,22,23,26],mai:[8,10,13,16,24,26],mail_fil:6,main:25,maintain:[3,15,24,26],major:[10,26],make:[2,9,10,11,22,25],make_context:8,make_unique_nam:8,make_writ:2,manag:[3,8,10,11,12,16,22,25,26],mani:[10,22,26],manipul:[20,26],manner:24,manual:13,map:[3,10,20,24],mark:[13,24,26],match:[8,13,15],max_pass:10,maxbyt:4,maximum:7,mayavi:24,mean:[7,10,22],mechan:[8,19,23],mention:22,menu:26,merg:[11,16,26],messag:[4,5,6],metadata:[8,10,13,24],method:[3,8,9,10,11,13,15,16,17,20,22,24,25,26],might:[10,22,23,25],minu:7,miss:[2,8,11,14,22],mode:3,model:[8,16],modifi:[9,10,16,26],modul:[18,24],more:[3,4,9,11,16,22,24,25,26],motiv:10,move:[2,26],mro:10,msg:[4,5],much:[20,23],multidimension:3,multipl:[25,26],multipli:7,must:[2,3,8,9,14,15,16,24,25,26],mutablemap:3,mutat:11,my_dict:3,my_tabl:3,myapplic:23,mypackag:23,myplugin:23,name:[1,3,6,7,10,11,12,13,15,16,18,19,22,24,26],namealreadybounderror:8,namenotfounderror:8,namespac:[8,13],naming_ev:[1,18],naming_manag:[1,18],naming_trait:[1,8],namingerror:8,namingev:8,namingmanag:8,namingtraithandl:9,natur:22,navig:10,necessari:[3,10,16,26],need:[9,10,13,16,23,25,26],nest:[11,13,16,24,26],never:[8,14],new_nam:8,newest:4,newunpickl:10,next:[16,22,26],node:[3,11,12,22,23],node_attr:3,node_exist:11,node_nam:11,node_path:3,node_subpath:3,nodepath:3,non:[3,8,9,22],none:[3,4,8,10,11,12,13,15,22,26],normal:[3,7],notcontexterror:8,note:[3,7,8,9,10,11,24],noth:[2,11,13,16,17,26],notic:22,notif:25,notifi:[13,14,22,25],notion:11,now:[10,22,24],number:[10,22,23,26],numer:10,numpi:3,obj:[8,10,11,15,22],obj_class:15,object:[3,4,5,6,7,8,9,10,11,12,13,14,15,19,20,21,22,24,26],object_factori:[1,18],object_seri:[1,18],objectfactori:8,objectseri:8,obtain:10,obvious:22,occur:[9,24],often:10,ogbuji:4,old:[10,15,22],old_nam:8,oldest:4,on_trait_chang:22,on_ui_clos:13,onc:[4,16,26],one:[8,10,11,12,13,15,16,22,24,25,26],ones:10,onli:[3,9,10,11,13,15,16,17,23,25,26],onto:[15,17,26],opac:24,open:[3,10,25],open_h5fil:3,oper:[8,11,17,20,22,26],operationnotsupportederror:8,opportun:10,option:[10,13,25,26],or_non:9,orang:12,order:[8,10,11,14,15,22],organ:[24,25],organis:26,orient:7,origin:[3,8,9,10,16,26],other:[3,8,9,10,16,23,25,26],otherwis:[3,14,16,26],our:[3,7,22],out:[10,11,13,24],output:[10,13],outsid:[8,24],outstand:[16,26],over:[3,8,12],overrid:23,overridden:[9,10],overview:[19,24],overwrit:3,packag:[0,18,20,21,22,24,25],package_any_relevant_fil:5,package_glob:[1,18],package_single_project:5,package_workspac:5,page:[7,12,19],pair:3,panda:3,panel:12,panick:22,paramet:[3,9,10,13,14,15,24],parent:[3,12,13,15,24],pars:10,part:[2,3,4,8,10,11,13,16,24,25],particular:[8,9,10,11,13,14,24,26],particularli:[8,26],pass:[3,4,8,9,10,11,13,16,24,26],passiv:14,path:[2,3,4,8,10,11,13,20,24],pathlib:20,pathnam:3,pattern:26,pear:12,peopl:11,perfectli:14,perform:[7,8,11,17,22,24],perhap:10,persist:[1,6,11,18,22],phrase:9,pickl:10,pickle_filenam:10,pickler:10,pixel:7,pkgfile:23,place:[9,10,11,16,17,24,26],placehold:10,plain:[10,22,24],pleas:10,plug:8,plugin:[1,4,5,10,23,25,26],point:[5,8,22,23,24,26],pop:[13,15],popul:14,portion:21,posit:[8,26],posix:10,possibl:[10,13,15,25,26],post_setattr:9,potenti:26,power:24,pprint:10,preced:[11,22],predefin:[9,22],prefer:[1,6,7,8,18,19],preference_bind:[1,18],preference_path:11,preferencebind:11,preferences_help:[1,6,12,18],preferences_manag:[1,11],preferences_nod:[1,11],preferences_pag:[1,6,7,11],preferences_path:22,preferencesbind:11,preferenceshelp:[6,11,12,22,23],preferenceshelpwindow:12,preferencesmanag:12,preferencesmanagerhandl:12,preferencesnod:12,preferencespag:[7,12],prefix:8,prefixmap:24,present:[8,12,13],preserv:3,presum:10,pretti:[12,22],previou:[13,16,26],previous:22,primari:11,primarili:24,primit:11,print:[4,12,22,24],printabl:13,prioriti:[5,6],problem:10,process:10,produc:[8,24],program:3,project:[2,4,5,8,10,11,13,16],project_load:[1,18],project_vers:10,properli:16,properti:[3,20,24],propos:9,protocol:10,prove:[10,22],provid:[2,3,8,10,11,13,14,19,20,22,23,24,26],provider_id:[14,25],providernotregisterederror:[14,25],proxi:10,publish:[14,25],pure:10,purpos:9,push:[15,16,17,26],push_abc:15,put:4,py_context:[1,18],py_object_factori:[1,18],pycontext:8,pyf:8,pyfac:[5,7,17,26],pyfs_context:[1,18],pyfs_context_factori:[1,18],pyfs_initial_context_factori:[1,18],pyfs_object_factori:[1,18],pyfs_state_factori:[1,18],pyfscontext:8,pyfscontextfactori:8,pyfsinitialcontextfactori:8,pyfsobjectfactori:8,pyfsstatefactori:8,pyobjectfactori:8,pytabl:[3,20],pytables_group:3,pytables_nod:3,python:[3,4,8,10,11,13,20,21,24],qualifi:15,quality_agent_mail:[1,4],quality_agent_view:[1,4],qualityagentview:5,queue:4,quick:22,quickest:24,quit:[10,25],rais:[3,8,9,11,14,15,25],rang:24,rather:[3,8,9],ratio:[22,23],raw:22,reach:8,react:25,read:[3,10,19,24],readabl:[3,13,24],readi:4,readonly_editor:12,real:10,realli:[10,22],reason:[15,24],rebind:8,rec:13,receiv:[9,25],recogn:8,recognis:[8,16],recommend:11,reconstitut:10,record:[1,3,4,7,16,18,19],record_funct:13,recorder_with_ui:[1,18],recordererror:13,recorderwithui:[13,24],recreat:[10,24],red:22,redo:[16,17,26],redo_act:[1,16],redo_nam:26,redoabl:26,redoact:17,redon:[16,26],refactor:10,refer:[1,7,9,10,11,16,18,24,26],referenc:[1,18],referenceable_state_factori:[1,18],referenceablestatefactori:8,reflect:[8,26],refresh:8,regard:[8,25],regist:[10,13,14,15,23,24,25],registi:10,registri:[10,13,14,15],reimplement:17,rel:[3,8,10],rel_pth:10,releas:10,relev:[5,10],reli:24,remain:[5,10,14],remov:[3,11,12,14,26],remove_group:3,remove_nod:3,remove_preferences_listen:11,remove_selection_provid:[14,25],renam:8,repeat:26,repeatedli:[10,14],replac:16,report:6,repres:[8,10,12,13,14,22,25],represent:[2,8,10,24],request:[8,14,25],requir:[3,7,8,9,10,14,17,26],reset:4,reset_button:7,resiz:7,resolut:[8,15],resolv:8,resolve_class:9,respect:10,respons:[16,26],rest:14,restor:26,result:[7,8,9,16,17,26],reus:5,revers:[10,24],revert:26,revis:10,rewrit:5,ring_buff:[1,18],ringbuff:4,ringbufferful:4,root:[3,11,12,22],rotatingfilehandl:4,row:3,safer:8,saferepr:10,sai:[10,22],same:[7,8,10,14,16,22,25,26],satisfi:20,save:[6,8,10,11,13,16,22,24,26],save_prefer:6,scan:10,scheme:11,scope:[8,11,19,23],scope_nam:11,scoped_prefer:[1,18],scopedprefer:[11,22,23],screen:22,script:[1,16,18,19],script_id:[13,24],search:[8,15,19,22],second:10,section:[0,22,23,26],see:[3,10,22,24],select:[1,18,19],selection_servic:[1,18],selectionservic:[14,19],self:[10,23,24],send:[6,25],send_bug_report:6,sens:9,sentenc:9,seq:10,sequenc:[3,8,14,26],sequence_nr:[16,26],serial:8,servic:[5,6,7,14,19],set:[3,7,8,10,11,13,14,22,23,24,26],set_absolut:10,set_attribut:8,set_default_prefer:11,set_record:[13,24],set_rel:10,set_select:[14,25],set_stat:10,setup:[10,24],shape:3,shiva:24,shortcut:26,should:[3,5,8,9,10,11,14,22,24,25,26],show:[7,8,12,25],show_button:7,show_label:7,shown:13,signatur:14,silent:14,similar:[9,20,26],similarli:10,simpl:[7,10,12,13,22,24],simple_editor:12,simpli:[10,22,24],simplifi:10,sinc:[3,8,10,13,24,26],singl:[16,26],size:[4,5,7],size_max:4,small:24,smtp_server:[5,6],some:[3,8,22,26],someon:[8,10],sometim:24,somewher:8,soon:25,sort:[8,26],sound:22,sourc:[2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,24],space:7,special:10,specif:[8,9,10,11,13,14,21,24,25],specifi:[3,7,8,9,10,11,12,13,15,22,24,25],splash:22,splash_screen:22,splashscreenprefer:[22,23],split:3,split_path:3,sprocket:9,sprout:12,squar:9,stack:[4,15,16,17,26],stack_trac:[5,6],stack_upd:26,stage:10,standard:[8,10,11,20,26],start:[4,6,8,13,22,23,24],start_record:13,startup:4,state:[8,10,13,16,26],state_factori:[1,18],state_pickl:[1,18],statedict:10,statefactori:8,statelist:10,statement:13,statepickl:10,statepicklererror:10,statesett:10,statesettererror:10,statetupl:10,stateunpickl:10,stateunpicklererror:10,statu:26,stdout:[11,12],stop:[6,13,24],stop_record:13,storag:[3,10],store:[3,8,10,11,13,22,24],str:[3,5,7,9,11,13,14,22,24,26],strict:10,strightfoward:10,string:[3,8,9,10,11,12,13,15,24],strip:10,structur:12,stuff:[5,10],style:[7,15,20],sub:[8,20,24,26],subclass:[9,11,13],subgroup_nam:3,subject:[5,6],submodul:[1,18],subpackag:18,subsequ:[16,24,26],suffici:26,suggest:24,suit:[2,8,10,11,13,16,24,26],suitabl:8,superclass:15,support:[8,10,13,16,19,25,26],sure:[11,22,25],surfac:24,synchron:[11,25],synchronis:26,syntax:[8,22],system:[2,4,8,22],tabl:[3,7],table_nod:[1,2],tabular_adapt:7,tabular_editor:7,tabularadapt:7,tabulareditor:7,take:[11,17,22,25,26],taken:[10,24],technic:24,tediou:24,tell:26,terribl:22,test:24,text:[6,10,13,26],text_editor:12,than:[3,4,8,9],thei:[10,11,16,20,22,24,25,26],them:[4,8,10,11,22,26],themselv:[8,13],therefor:9,thi:[0,2,3,4,5,7,8,9,10,11,12,13,14,16,17,20,22,23,24,25,26],thin:3,thing:23,think:[8,10,11],those:[8,13,16,26],though:[8,10],thought:26,through:[8,24,25],thrown:8,thu:7,time:[4,7,8,10,25,26],titl:5,to_address:5,to_datafram:3,toaddr:[5,6],togeth:7,toi:24,too:[10,22,23,24],tool:[2,8,10,11,13,16,24,26],toolbar:25,toolkiteditorfactori:7,top:22,total:[7,12],tour:22,trace:4,traceback:4,tradit:22,trail:11,trait:[2,5,6,7,8,9,11,12,13,14,16,17,20,22,23,24,26],trait_def:[1,8],trait_handl:9,trait_modifi:7,trait_nam:[11,22],trait_name_on_par:13,trait_typ:[5,6,7],trait_view:7,traiterror:9,traithandl:9,traits_ui_view:7,traits_view:12,traitsui:[7,12,13],traitsuiview:7,transform:10,treat:[7,8,26],tree:[8,12,25],tree_item:[1,11],treeitem:12,tri:[23,24],trigger:14,tupl:[3,5,10,24],turn:[10,11,20,24],tutori:21,two:[10,11,16,22,25,26],typ:15,type:[3,4,7,8,9,10,11,15,19,24,26],type_registri:[1,18],typeregistri:15,typic:[10,16,25,26],uch:4,ui_sav:13,unbind:8,unchang:7,undo:[1,18,19],undo_act:[1,16],undo_manag:[1,18,26],undo_nam:26,undoabl:26,undoact:17,undomanag:16,undon:[16,17,26],unhook:17,unimpl:5,uniqu:[8,14,24,25,26],unique_nam:[1,18],unless:25,unlik:10,unnorm:7,unpickl:10,unregist:[10,13,24],unseri:10,until:[8,10,16,26],unzip:10,updat:[1,7,18,26],update1:10,update2:10,update3:10,update_st:10,updater_path:10,upgrad:10,upgrade_project:10,usabl:8,usag:26,use:[7,8,9,10,11,13,20,22,23,25],useag:22,used:[3,8,10,11,12,13,16,22,23,24,25,26],useful:[8,10,13,17,22],user:[7,8,9,10,11,12,13,20,22,24,25,26],uses:[11,23],using:[3,8,9,10,13,22,24,25],usual:[10,11,12,22],util:[1,2,5,18],valid:[3,9,10,14],validate_fail:9,valu:[3,4,7,8,9,10,11,16,22,26],valueerror:[3,11,14],variou:[10,26],veg:12,veri:[10,24],verifi:9,version:[8,10,22],version_registri:[1,18],versioned_unpickl:[1,18],versionedunpickl:10,via:[5,10,11,13,22,23,24],view:[1,3,4,6,10,12,25],visibl:[11,22,23],visitor:8,visual:24,wai:[8,11,22,24],walk:[10,24],want:[10,11,13,22,24,25],well:[10,24],were:[16,26],what:[7,10,22,24,25],whatev:[9,11,24],when:[3,4,8,10,13,14,15,16,17,22,23,24,25,26],whenev:[3,9,14,25,26],where:[3,8,10,11,13,22,25],whether:[3,9],which:[3,7,8,10,11,12,13,16,22,23,24,25,26],white:22,whole:10,whole_log_text:6,whose:[9,10],wide:11,widget:[11,12],widget_editor:[1,11],widgeteditor:12,width:[7,11,22,23],win:22,window:25,wire:24,wirefram:24,wish:25,within:8,without:[11,16,26],word:26,work:[3,10,12,16,22,24,26],workbench:[6,7,26],worth:[10,11,22],would:[3,10,11,16,17,22,23,25],wrap:[3,13,17,26],wrapper:[3,20,26],write:[3,10,22],write_script_id_in_namespac:13,writeabl:2,writer:8,written:8,xmarshal:10,xxx:3,year:24,yellow:23,yet:5,you:[3,10,11,13,21,22,23,24],your:[22,23,24],yourself:22,zip:5},titles:["API documentation","apptools package","apptools.io package","apptools.io.h5 package","apptools.logger package","apptools.logger.agent package","apptools.logger.plugin package","apptools.logger.plugin.view package","apptools.naming package","apptools.naming.trait_defs package","apptools.persistence package","apptools.preferences package","apptools.preferences.ui package","apptools.scripting package","apptools.selection package","apptools.type_registry package","apptools.undo package","apptools.undo.action package","apptools","AppTools Documentation","File I/O","Naming","Preferences","Preferences in Envisage","Automatic script recording","The selection service","Undo Framework"],titleterms:{"case":24,The:[22,24,25],abstract_command:16,abstract_command_stack_act:17,abstractcommand:26,access:22,action:17,activ:25,address:8,advanc:24,agent:5,api:[0,2,4,8,9,11,12,13,14,15,16,17,24,26],apptool:[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19],attach:5,automat:24,basic:22,bind:8,caveat:10,command_act:17,command_stack:16,commandact:26,commandstack:26,concept:26,content:[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17],context:8,custom_excepthook:4,dict_nod:3,dir_context:8,document:[0,19],dynamic_context:8,envisag:23,error:14,exampl:24,except:8,featur:10,file:[2,3,20],file_path:10,framework:26,further:22,gloriou:22,hdf5:20,i_command:16,i_command_stack:16,i_prefer:11,i_preferences_pag:12,i_select:14,i_selection_provid:14,i_undo_manag:16,icommand:26,initial_context:8,initial_context_factori:8,list_select:14,listen:25,log_point:4,log_queue_handl:4,logger:[4,5,6,7],logger_plugin:6,logger_prefer:6,logger_preferences_pag:7,logger_servic:6,logger_view:7,mechan:22,modul:[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17],name:[8,9,21],naming_ev:8,naming_manag:8,naming_trait:9,object:25,object_factori:8,object_seri:8,overview:26,packag:[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17],package_glob:[11,13],particular:22,passiv:25,persist:10,plugin:[6,7],prefer:[11,12,22,23],preference_bind:11,preferences_help:11,preferences_manag:12,preferences_nod:12,preferences_pag:12,project_load:10,provid:25,py_context:8,py_object_factori:8,pyfs_context:8,pyfs_context_factori:8,pyfs_initial_context_factori:8,pyfs_object_factori:8,pyfs_state_factori:8,quality_agent_mail:5,quality_agent_view:5,queri:25,read:22,record:[13,24],recorder_with_ui:13,redo_act:17,redoact:26,refer:8,referenc:8,referenceable_state_factori:8,registr:25,ring_buff:4,scope:22,scoped_prefer:11,script:[13,24],select:[14,25],selection_servic:14,selectionservic:25,servic:25,set:25,state_factori:8,state_pickl:10,string:22,submodul:[2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17],subpackag:[1,2,4,6,8,11,16],support:20,table_nod:3,tour:24,trait_def:9,tree_item:12,type:22,type_registri:15,undo:[16,17,26],undo_act:17,undo_manag:16,undoact:26,undomanag:26,unique_nam:8,updat:10,use:24,util:[3,13],version_registri:10,versioned_unpickl:10,view:7,widget_editor:12}}) \ No newline at end of file diff --git a/selection/selection.html b/selection/selection.html index 364171dac..9d1f7613a 100644 --- a/selection/selection.html +++ b/selection/selection.html @@ -13,9 +13,11 @@ @@ -29,7 +31,7 @@ - + @@ -62,7 +64,7 @@ >modules
  • - next
  • @@ -80,7 +82,7 @@
    -
    +

    The selection service

    @@ -95,8 +97,8 @@

    This package defines a selection service that manages the communication between providers and listener.

    -

    The SelectionService object

    -

    The SelectionService object is the central manager that handles +

    The SelectionService object

    +

    The SelectionService object is the central manager that handles the communication between selection providers and listener.

    Selection providers are components that wish to publish information about their current selection for public consumption. @@ -110,37 +112,37 @@

    The selection +selection event is fired.

    Selection providers

    Any object can become a selection provider by implementing the -ISelectionProvider +ISelectionProvider interface, and registering to the selection service.

    Selection providers must provide a unique ID -provider_id, +provider_id, which is used by listeners to request its current selection.

    Whenever its selection changes, providers fire a -selection +selection event. The content of the event is an instance implementing -ISelection that contains information about the selected items. -For example, a ListSelection object contains a list of selected +ISelection that contains information about the selected items. +For example, a ListSelection object contains a list of selected items, and their indices.

    Selection providers can also be queried directly about their current selection using the -get_selection +get_selection method, and can be requested to change their selection to a new one with the -set_selection +set_selection method.

    Registration

    Selection providers publish their selection by registering to the selection service using the -add_selection_provider +add_selection_provider method. When the selection is no longer available, selection providers should un-register through -remove_selection_provider.

    +remove_selection_provider.

    Typically, selection providers are UI objects showing a list or tree of items, they register as soon as the UI component is initialized, and un-register when the UI component disappears (e.g., because their window has been closed). @@ -151,29 +153,29 @@

    Registration

    Selection listeners

    Selection listeners request information regarding the current selection -of a selection provider given their provider ID. The SelectionService +of a selection provider given their provider ID. The SelectionService supports two distinct use cases:

      -
    1. Passively listening to selection changes: listener connect to a specific -provider and are notified when the provider’s selection changes.
    2. -
    3. Actively querying a provider for its current selection: the selection -service can be used to query a provider using its unique ID.
    4. +
    5. Passively listening to selection changes: listener connect to a specific +provider and are notified when the provider’s selection changes.

    6. +
    7. Actively querying a provider for its current selection: the selection +service can be used to query a provider using its unique ID.

    Passive listening

    Listeners connect to the selection events for a given provider using the -connect_selection_listener +connect_selection_listener method. They need to provide the unique ID of the provider, and a function (or callable) that is called to send the event. This callback function takes -one argument, an implementation of the ISelection that represents +one argument, an implementation of the ISelection that represents the selection.

    It is possible for a listener to connect to a provider ID before it is registered. As soon as the provider is registered, the listener will receive a notification containing the provider’s initial selection.

    To disconnect a listener use the methods -disconnect_selection_listener.

    +disconnect_selection_listener.

    Active querying

    @@ -182,361 +184,22 @@

    Active queryingget_selection +get_selection method calls the corresponding method on the provider with the given ID and -returns an ISelection instance.

    +returns an ISelection instance.

    Setting a selection

    Finally, it is possible to request a provider to set its selection to a given set of objects with -set_selection. +set_selection. The main use case for this method is multiple views of the same list of objects, which need to keep their selection synchronized.

    If the items specified in the arguments are not available in the provider, -a ProviderNotRegisteredError is raised, +a ProviderNotRegisteredError is raised, unless the optional keyword argument ignore_missing is set to True.

    -
    -

    API Reference

    -
    -

    apptools.selection Package

    -

    Users of the apptools.selection package can access the objects that are -part of the public API through the convenience apptools.selection.api.

    -
    -

    selection_service Module

    -
    -
    -class apptools.selection.selection_service.SelectionService[source]
    -

    Bases: traits.has_traits.HasTraits

    -

    The selection service connects selection providers and listeners.

    -

    The selection service is a register of selection providers, i.e., objects -that publish their current selection.

    -

    Selections can be requested actively, by explicitly requesting the current -selection in a provider (get_selection(id)()), or passively by -connecting selection listeners.

    -
    -
    -add_selection_provider(provider)[source]
    -

    Add a selection provider.

    -

    The provider is identified by its ID. If a provider with the same -ID has been already registered, an IDConflictError -is raised.

    -
  • diff --git a/index.html b/index.html index 18a4b7a37..53e7b1311 100644 --- a/index.html +++ b/index.html @@ -13,9 +13,11 @@ @@ -29,7 +31,7 @@ - +
    @@ -59,7 +61,7 @@ >modules
  • - next
  • @@ -73,56 +75,19 @@
    -
    +
    @@ -161,21 +130,19 @@

    AppTools Documentation

    Next topic

    -

    Application Scripting Framework

    +

    Preferences

    This Page

    @@ -199,10 +166,10 @@

    Quick search

    © Copyright 2008-2020, Enthought
  • - Last updated on Jun 12, 2020. + Last updated on Dec 17, 2020.
  • - Created using Sphinx 1.8.5. + Created using Sphinx 2.3.1.
  • diff --git a/io/introduction.html b/io/introduction.html new file mode 100644 index 000000000..1f4d10d3d --- /dev/null +++ b/io/introduction.html @@ -0,0 +1,169 @@ + + + + + + + File I/O — Apptools Documentation + + + + + + + + + + + + + + + + + + + + +
    +
    +
    +
    + +
    +
    + +
    +
    +
    + + + + + + +
    +
    +
    + + +
    +
    + +
    +
    + +
    +

    File I/O

    +

    The apptools.io package provides a traited File object provides +properties and methods for common file path manipulation operations. Much of +this functionality was implemented before Python 3 pathlib standard library +became available to provide similar support. For new code we encourage users +to investigate if pathlib can satisfy their use cases before they turn to +the apptools.io File object

    +
    +

    HDF5 File Support

    +

    The apptools.io.h5 sub-package provides a wrapper around PyTables +with a dictionary-style mapping.

    +
    +
    + + +
    +
    +
    +
    +
    + +

    Table of Contents

    + + +

    Previous topic

    +

    Naming

    +

    Next topic

    +

    API documentation

    +

    This Page

    + + + +
    +
    +
    +
    +
    + +
    +
    + +
    +
    +
    + +
    + + \ No newline at end of file diff --git a/naming/Introduction.html b/naming/Introduction.html new file mode 100644 index 000000000..6c5f08423 --- /dev/null +++ b/naming/Introduction.html @@ -0,0 +1,154 @@ + + + + + + + Naming — Apptools Documentation + + + + + + + + + + + + + + + + + + + + +
    +
    +
    +
    + +
    +
    + +
    +
    +
    + + + + + + +
    +
    +
    + + +
    +
    + +
    +
    + +
    +

    Naming

    +

    apptools.naming package is a Python implementation of the Naming portion of the Java +Naming and Directory Interface, +including specific implementations for a heirarchy of Python objects. You can +also find the Java JNDI tutorial here.

    +
    + + +
    +
    +
    +
    +
    + +

    Previous topic

    +

    The selection service

    +

    Next topic

    +

    File I/O

    +

    This Page

    + + + +
    +
    +
    +
    +
    + +
    +
    + +
    +
    +
    + +
    + + \ No newline at end of file diff --git a/objects.inv b/objects.inv index 8594ce6a4..784d3243d 100644 Binary files a/objects.inv and b/objects.inv differ diff --git a/preferences/Preferences.html b/preferences/Preferences.html index 2e1a1e387..062f6c0c0 100644 --- a/preferences/Preferences.html +++ b/preferences/Preferences.html @@ -13,9 +13,11 @@ @@ -30,7 +32,7 @@ - +
    @@ -66,7 +68,7 @@ accesskey="N">next
  • - previous
  • @@ -80,7 +82,7 @@
    -
    +

    Preferences

    @@ -89,17 +91,16 @@

    Preferences -

    The Basic Preferences Mechanism

    +

    The Basic Preferences Mechanism

    Lets start by taking a look at the lowest layer which consists of the -IPreferences interface and its default implementation in the Preferences +IPreferences interface and its default implementation in the Preferences class. This layer implements the basic preferences system which is a hierarchical arrangement of preferences ‘nodes’ (where each node is simply an -object that implements the IPreferences interface). Nodes in the hierarchy can +object that implements the IPreferences interface). Nodes in the hierarchy can contain preference settings and/or child nodes. This layer also provides a default way to read and write preferences from the filesystem using the -excellent ConfigObj package.

    +excellent ConfigObj package.

    This all sounds a bit complicated but, believe me, it isn’t! To prove it (hopefully) lets look at an example. Say I have the following preferences in a file ‘example.ini’:

    @@ -120,9 +121,9 @@

    The Basic Preferences Mechanism>>> preferences.dump() Node() {} - Node(acme) {} - Node(ui) {'bgcolor': 'blue', 'ratio': '1.0', 'width': '50', 'visible': 'True'} - Node(splash_screen) {'image': 'splash', 'fgcolor': 'red'} + Node(acme) {} + Node(ui) {'bgcolor': 'blue', 'width': '50', 'ratio': '1.0', 'visible': 'True'} + Node(splash_screen) {'image': 'splash', 'fgcolor': 'red'}

    The ‘dump’ method (useful for debugging etc) simply ‘pretty prints’ a @@ -189,7 +190,7 @@

    The Basic Preferences Mechanism -

    Strings, Glorious Strings

    +

    Strings, Glorious Strings

    At this point it is worth mentioning that preferences are always stored and returned as strings. This is because of the limitations of the traditional ‘.ini’ file format i.e. they don’t contain any type information! Now before you @@ -216,9 +217,9 @@

    Strings, Glorious Strings -

    Preferences and Types

    +

    Preferences and Types

    As mentioned previously, we would like to be able to get and set non-string -preferences in a more convenient way. This is where the PreferencesHelper +preferences in a more convenient way. This is where the PreferencesHelper class comes in.

    Let’s take another look at ‘example.ini’:

    -

    If you always use the same preference node as the root of your preferences you -can also set the class attribute ‘PreferencesHelper.preferences’ to be that -node and from then on in, you don’t have to pass a preferences collection in -each time you create a helper:

    -
    >>> PreferencesHelper.preferences = Preferences(filename='example.ini')
    ->>> helper = SplashScreenPreferences()
    ->>> helper.bgcolor
    -'blue'
    ->>> helper.width
    -100
    ->>> helper.ratio
    -1.0
    ->>> helper.visible
    -True
    -
    -
    -

    Scoped Preferences

    +

    Scoped Preferences

    In many applications the idea of preferences scopes is useful. In a scoped system, an actual preference value can be stored in any scope and when a call is made to the ‘get’ method the scopes are searched in order of precedence.

    -

    The default implementation (in the ScopedPreferences class) provides two +

    The default implementation (in the ScopedPreferences class) provides two scopes by default:

      -
    1. The application scope
    2. +
    3. The application scope

    This scope stores itself in the ‘ETSConfig.application_home’ directory. This scope is generally used when setting any user preferences.

      -
    1. The default scope
    2. +
    3. The default scope

    This scope is transient (i.e. it does not store itself anywhere). This scope is generally used to load any predefined default values into the preferences @@ -320,14 +305,14 @@

    Scoped Preferences
    >>> from apptools.preferences.api import ScopedPreferences
     >>> preferences = ScopedPreferences(filename='example.ini')
     >>> preferences.load('example.ini')
    ->>> p.dump()
    +>>> preferences.dump()
     
    -  Node() {}
    -    Node(application) {}
    -      Node(acme) {}
    -        Node(ui) {'bgcolor': 'blue', 'ratio': '1.0', 'width': '50', 'visible': 'True'}
    -          Node(splash_screen) {'image': 'splash', 'fgcolor': 'red'}
    -    Node(default) {}
    + Node() {}
    +   Node(application) {}
    +     Node(acme) {}
    +       Node(ui) {'bgcolor': 'blue', 'width': '50', 'ratio': '1.0', 'visible': 'True'}
    +         Node(splash_screen) {'image': 'splash', 'fgcolor': 'red'}
    +   Node(default) {}
     

    Here you can see that the root node now has a child node representing each @@ -346,22 +331,21 @@

    Scoped Preferences>>> preferences.set('acme.ui.bgcolor', 'red') >>> preferences.dump() - Node() {} - Node(application) {} - Node(acme) {} - Node(ui) {'bgcolor': 'red', 'ratio': '1.0', 'width': '50', 'visible': 'True'} - Node(splash_screen) {'image': 'splash', 'fgcolor': 'red'} - Node(default) {} + Node() {} + Node(application) {} + Node(acme) {} + Node(ui) {'bgcolor': 'red', 'width': '50', 'ratio': '1.0', 'visible': 'True'} + Node(splash_screen) {'image': 'splash', 'fgcolor': 'red'} + Node(default) {}

    And, conveniently, preference helpers work just the same with scoped preferences too:

    -
    >>> PreferencesHelper.preferences = ScopedPreferences(filename='example.ini')
    ->>> helper = SplashScreenPreferences()
    +
    >>> helper = SplashScreenPreferences(preferences=preferences)
     >>> helper.bgcolor
    -'blue'
    +'red'
     >>> helper.width
    -100
    +50
     >>> helper.ratio
     1.0
     >>> helper.visible
    @@ -369,7 +353,7 @@ 

    Scoped Preferences -

    Accessing a particular scope

    +

    Accessing a particular scope

    Should you care about getting or setting a preference in a particular scope then you use the following syntax:

    You can also get hold of a scope via:

    @@ -395,11 +379,12 @@

    Accessing a particular scope -

    Further Reading

    +

    Further Reading

    So that’s a quick tour around the basic useage of the preferences API. For more -imformation about what is provided take a look at the API documentation.

    +information about what is provided take a look at the API documentation.

    If you are using Envisage to build your applications then you might also be -interested in the Preferences in Envisage section.

    +interested in the Preferences in Envisage section.

    +
    @@ -413,7 +398,7 @@

    Further ReadingTable of Contents

    +

    Previous topic

    -

    Default User Manager Data API

    +

    AppTools Documentation

    Next topic

    Preferences in Envisage

    @@ -438,13 +425,11 @@

    This Page

    rel="nofollow">Show Source
    @@ -468,10 +453,10 @@

    Quick search

    © Copyright 2008-2020, Enthought
  • - Last updated on Jun 12, 2020. + Last updated on Dec 17, 2020.
  • - Created using Sphinx 1.8.5. + Created using Sphinx 2.3.1.
  • diff --git a/preferences/PreferencesInEnvisage.html b/preferences/PreferencesInEnvisage.html index 016305c71..cba25dc9f 100644 --- a/preferences/PreferencesInEnvisage.html +++ b/preferences/PreferencesInEnvisage.html @@ -13,9 +13,11 @@ @@ -80,14 +82,14 @@
    -
    +
    -

    Preferences in Envisage

    +

    Preferences in Envisage

    This section discusses how an Envisage application uses the preferences mechanism. Envisage tries not to dictate too much, and so this describes the default behaviour, but you are free to override it as desired.

    -

    Envisage uses the default implementation of the ScopedPreferences class which +

    Envisage uses the default implementation of the ScopedPreferences class which is made available via the application’s ‘preferences’ trait:

    >>> application = Application(id='myapplication')
     >>> application.preferences.set('acme.ui.bgcolor', 'yellow')
    @@ -98,7 +100,7 @@ 

    Preferences in EnvisageHence, you use the Envisage preferences just like you would any other scoped preferences.

    It also registers itself as the default preferences node used by the -PreferencesHelper class. Hence you don’t need to provide a preferences node +PreferencesHelper class. Hence you don’t need to provide a preferences node explicitly to your helper:

    >>> helper = SplashScreenPreferences()
     >>> helper.bgcolor
    @@ -146,13 +148,11 @@ 

    This Page

    rel="nofollow">Show Source
    @@ -176,10 +176,10 @@

    Quick search

    © Copyright 2008-2020, Enthought
  • - Last updated on Jun 12, 2020. + Last updated on Dec 17, 2020.
  • - Created using Sphinx 1.8.5. + Created using Sphinx 2.3.1.
  • diff --git a/py-modindex.html b/py-modindex.html index f93b3a7a6..7b3cbde79 100644 --- a/py-modindex.html +++ b/py-modindex.html @@ -13,9 +13,11 @@ @@ -73,7 +75,7 @@
    -
    +

    Python Module Index

    @@ -92,161 +94,6 @@

    Python Module Index

    apptools
        - apptools.appscripting -
        - apptools.appscripting.action -
        - apptools.appscripting.action.api -
        - apptools.appscripting.action.start_recording_action -
        - apptools.appscripting.action.stop_recording_action -
        - apptools.appscripting.api -
        - apptools.appscripting.bind_event -
        - apptools.appscripting.i_bind_event -
        - apptools.appscripting.i_script_manager -
        - apptools.appscripting.lazy_namespace -
        - apptools.appscripting.package_globals -
        - apptools.appscripting.script_manager -
        - apptools.appscripting.scriptable -
        - apptools.appscripting.scriptable_type -
        - apptools.help -
        - apptools.help.help_plugin -
        - apptools.help.help_plugin.action -
        - apptools.help.help_plugin.action.demo_action -
        - apptools.help.help_plugin.action.doc_action -
        - apptools.help.help_plugin.action.example_action -
        - apptools.help.help_plugin.action.load_url_action -
        - apptools.help.help_plugin.action.util -
        - apptools.help.help_plugin.api -
        - apptools.help.help_plugin.examples_preferences -
        - apptools.help.help_plugin.help_code -
        - apptools.help.help_plugin.help_doc -
        - apptools.help.help_plugin.help_plugin -
        - apptools.help.help_plugin.help_submenu_manager -
        - apptools.help.help_plugin.i_help_code -
        - apptools.help.help_plugin.i_help_doc -
        - apptools.help.help_plugin.preferences_pages -
        @@ -322,11 +169,6 @@

    Python Module Index

        apptools.logger.custom_excepthook
        - apptools.logger.filtering_handler -
        @@ -342,11 +184,6 @@

    Python Module Index

        apptools.logger.logger
        - apptools.logger.null_handler -
        @@ -387,96 +224,11 @@

    Python Module Index

        apptools.logger.ring_buffer
        - apptools.logger.util -
        - apptools.lru_cache -
        - apptools.lru_cache.lru_cache -
        apptools.naming
        - apptools.naming.adapter -
        - apptools.naming.adapter.api -
        - apptools.naming.adapter.dict_context_adapter -
        - apptools.naming.adapter.dict_context_adapter_factory -
        - apptools.naming.adapter.instance_context_adapter -
        - apptools.naming.adapter.instance_context_adapter_factory -
        - apptools.naming.adapter.list_context_adapter -
        - apptools.naming.adapter.list_context_adapter_factory -
        - apptools.naming.adapter.trait_dict_context_adapter -
        - apptools.naming.adapter.trait_dict_context_adapter_factory -
        - apptools.naming.adapter.trait_list_context_adapter -
        - apptools.naming.adapter.trait_list_context_adapter_factory -
        - apptools.naming.adapter.tuple_context_adapter -
        - apptools.naming.adapter.tuple_context_adapter_factory -
        @@ -497,16 +249,6 @@

    Python Module Index

        apptools.naming.context
        - apptools.naming.context_adapter -
        - apptools.naming.context_adapter_factory -
        @@ -625,367 +367,162 @@

    Python Module Index

        - apptools.naming.ui -
        - apptools.naming.ui.api -
        - apptools.naming.ui.context_monitor -
        - apptools.naming.ui.context_node_type -
        - apptools.naming.ui.explorer + apptools.naming.unique_name
        - apptools.naming.ui.naming_node_manager + apptools.persistence
        - apptools.naming.ui.naming_tree + apptools.persistence.file_path
        - apptools.naming.ui.naming_tree_model + apptools.persistence.project_loader
        - apptools.naming.ui.object_node_type + apptools.persistence.state_pickler
        - apptools.naming.unique_name + apptools.persistence.updater
        - apptools.permissions + apptools.persistence.version_registry
        - apptools.permissions.action + apptools.persistence.versioned_unpickler
        - apptools.permissions.action.api + apptools.preferences
        - apptools.permissions.action.login_action + apptools.preferences.api
        - apptools.permissions.action.logout_action + apptools.preferences.i_preferences
        - apptools.permissions.action.user_menu_manager + apptools.preferences.package_globals
        - apptools.permissions.adapter_base + apptools.preferences.preference_binding
        - apptools.permissions.adapters + apptools.preferences.preferences
        - apptools.permissions.adapters.pyface_action + apptools.preferences.preferences_helper
        - apptools.permissions.api + apptools.preferences.scoped_preferences
        - apptools.permissions.default + apptools.preferences.ui
        - apptools.permissions.default.api + apptools.preferences.ui.api
        - apptools.permissions.default.i_policy_storage + apptools.preferences.ui.i_preferences_page
        - apptools.permissions.default.i_user_database + apptools.preferences.ui.preferences_manager
        - apptools.permissions.default.i_user_storage + apptools.preferences.ui.preferences_node
        - apptools.permissions.default.persistent + apptools.preferences.ui.preferences_page
        - apptools.permissions.default.policy_data + apptools.preferences.ui.tree_item
        - apptools.permissions.default.policy_manager + apptools.preferences.ui.widget_editor
        - apptools.permissions.default.policy_storage + apptools.scripting
        - apptools.permissions.default.role_assignment + apptools.scripting.api
        - apptools.permissions.default.role_definition + apptools.scripting.package_globals
        - apptools.permissions.default.select_role + apptools.scripting.recordable
        - apptools.permissions.default.select_user + apptools.scripting.recorder
        - apptools.permissions.default.user_database + apptools.scripting.recorder_with_ui
        - apptools.permissions.default.user_manager + apptools.scripting.util
        - apptools.permissions.default.user_storage -
        - apptools.permissions.i_policy_manager -
        - apptools.permissions.i_user -
        - apptools.permissions.i_user_manager -
        - apptools.permissions.package_globals -
        - apptools.permissions.permission -
        - apptools.permissions.permissions_manager -
        - apptools.permissions.secure_proxy -
        - apptools.persistence -
        - apptools.persistence.file_path -
        - apptools.persistence.project_loader -
        - apptools.persistence.state_pickler -
        - apptools.persistence.updater -
        - apptools.persistence.version_registry -
        - apptools.persistence.versioned_unpickler -
        - apptools.preferences -
        - apptools.preferences.api -
        - apptools.preferences.i_preferences -
        - apptools.preferences.package_globals -
        - apptools.preferences.preference_binding -
        - apptools.preferences.preferences -
        - apptools.preferences.preferences_helper -
        - apptools.preferences.scoped_preferences -
        - apptools.preferences.ui -
        - apptools.preferences.ui.api -
        - apptools.preferences.ui.i_preferences_page -
        - apptools.preferences.ui.preferences_manager -
        - apptools.preferences.ui.preferences_node -
        - apptools.preferences.ui.preferences_page -
        - apptools.preferences.ui.tree_item -
        - apptools.scripting -
        - apptools.scripting.api -
        - apptools.scripting.package_globals -
        - apptools.scripting.recordable -
        - apptools.scripting.recorder -
        - apptools.scripting.recorder_with_ui -
        - apptools.scripting.util -
        - apptools.selection + apptools.selection
        - apptools.selection.errors -
        - apptools.selection.i_selection -
        - apptools.selection.i_selection_provider -
        - apptools.selection.list_selection -
        - apptools.selection.selection_service -
        - apptools.sweet_pickle -
        - apptools.sweet_pickle.global_registry -
        - apptools.sweet_pickle.placeholder -
        - apptools.sweet_pickle.updater -
        - apptools.sweet_pickle.versioned_unpickler -
        - apptools.template -
        - apptools.template.impl -
        - apptools.template.impl.any_context_data_name_item -
        - apptools.template.impl.any_data_name_item -
        - apptools.template.impl.api -
        - apptools.template.impl.context_data_name_item -
        - apptools.template.impl.helper -
        - apptools.template.impl.template_data_context -
        - apptools.template.impl.template_data_source -
        - apptools.template.impl.value_data_name_item -
        - apptools.template.impl.value_nd_data_name_item -
        - apptools.template.imutable_template -
        - apptools.template.itemplate -
        - apptools.template.itemplate_choice -
        - apptools.template.itemplate_data_context -
        - apptools.template.itemplate_data_name_item -
        - apptools.template.itemplate_data_source -
        - apptools.template.mutable_template -
        - apptools.template.template_choice -
        - apptools.template.template_data_name -
        - apptools.template.template_impl -
        - apptools.template.template_traits -
        - apptools.template.test -
        - apptools.type_manager -
        - apptools.type_manager.abstract_adapter_factory -
        - apptools.type_manager.abstract_factory -
        - apptools.type_manager.abstract_type_system -
        - apptools.type_manager.adaptable -
        - apptools.type_manager.adapter -
        - apptools.type_manager.adapter_factory -
        - apptools.type_manager.adapter_manager -
        - apptools.type_manager.api -
        - apptools.type_manager.factory + apptools.selection.errors
        - apptools.type_manager.hook + apptools.selection.i_selection
        - apptools.type_manager.python_type_system + apptools.selection.i_selection_provider
        - apptools.type_manager.type_manager + apptools.selection.list_selection
        - apptools.type_manager.util + apptools.selection.selection_service
    --- - - - -
    Parameters:-- ISelectionProvider (provider) – The selection provider added to the internal registry.
    - - -
    -
    -connect_selection_listener(provider_id, func)[source]
    -

    Connect a listener to selection events from a specific provider.

    -

    The signature if the listener callback is func(i_selection). -The listener is called:

    -
      -
    1. When a provider with the given ID is registered, with its initial -selection as argument, or
    2. -
    3. whenever the provider fires a selection event.
    4. -
    -

    It is perfectly valid to connect a listener before a provider with the -given ID is registered. The listener will remain connected even if -the provider is repeatedly connected and disconnected.

    - --- - - - -
    Parameters:
      -
    • -- str (provider_id) – The selection provider ID.
    • -
    • -- callable (func) – A callable object that is notified when the selection changes.
    • -
    -
    -
    - -
    -
    -disconnect_selection_listener(provider_id, func)[source]
    -

    Disconnect a listener from a specific provider.

    - --- - - - -
    Parameters:
      -
    • -- str (provider_id) – The selection provider ID.
    • -
    • -- callable (func) – A callable object that is notified when the selection changes.
    • -
    -
    -
    - -
    -
    -get_selection(provider_id)[source]
    -

    Return the current selection of the provider with the given ID.

    -

    If a provider with that ID has not been registered, a -ProviderNotRegisteredError is raised.

    - --- - - - - - -
    Parameters:-- str (provider_id) – The selection provider ID.
    Returns:
    -
    selection – ISelection
    -
    The current selection of the provider.
    -
    -
    -
    - -
    -
    -has_selection_provider(provider_id)[source]
    -

    Has a provider with the given ID been registered?

    -
    - -
    -
    -remove_selection_provider(provider)[source]
    -

    Remove a selection provider.

    -

    If the provider has not been registered, a -ProviderNotRegisteredError is raised.

    - --- - - - -
    Parameters:-- ISelectionProvider (provider) – The selection provider added to the internal registry.
    -
    - -
    -
    -set_selection(provider_id, items, ignore_missing=False)[source]
    -

    Set the current selection in a provider to the given items.

    -

    If a provider with the given ID has not been registered, a -ProviderNotRegisteredError is raised.

    -

    If ignore_missing is True, items that are not available in the -selection provider are silently ignored. If it is False (default), -a ValueError should be raised.

    - --- - - - -
    Parameters:
      -
    • -- str (provider_id) – The selection provider ID.
    • -
    • -- list (items) – List of items to be selected.
    • -
    • -- bool (ignore_missing) – If False (default), the provider raises an exception if any -of the items in items is not available to be selected. -Otherwise, missing elements are silently ignored, and the rest -is selected.
    • -
    -
    -
    - - - -
    -
    -

    i_selection_provider Module

    -
    -
    -class apptools.selection.i_selection_provider.ISelectionProvider[source]
    -

    Bases: traits.has_traits.Interface

    -

    Source of selections.

    -
    -
    -get_selection()[source]
    -

    Return the current selection.

    - --- - - - -
    Returns:
    -
    selection – ISelection
    -
    Object representing the current selection.
    -
    -
    -
    - -
    -
    -provider_id = Str()
    -

    Unique ID identifying the provider.

    -
    - -
    -
    -selection = Event
    -

    Event triggered when the selection changes. -The content of the event is an ISelection instance.

    -
    - -
    -
    -set_selection(items, ignore_missing=False)[source]
    -

    Set the current selection to the given items.

    -

    If ignore_missing is True, items that are not available in the -selection provider are silently ignored. If it is False (default), -an ValueError should be raised.

    - --- - - - -
    Parameters:
      -
    • -- list (items) – List of items to be selected.
    • -
    • -- bool (ignore_missing) – If False (default), the provider raises an exception if any -of the items in items is not available to be selected. -Otherwise, missing elements are silently ignored, and the rest -is selected.
    • -
    -
    -
    - -
    - -
    -
    -

    is_selection Module

    -
    -
    -class apptools.selection.i_selection.IListSelection[source]
    -

    Bases: apptools.selection.i_selection.ISelection

    -

    Selection for ordered sequences of items.

    -
    -
    -indices = List
    -

    Indices of the selected objects in the selection provider.

    -
    - -
    -
    -items = List
    -

    Selected objects.

    -
    - -
    - -
    -
    -class apptools.selection.i_selection.ISelection[source]
    -

    Bases: traits.has_traits.Interface

    -

    Collection of selected items.

    -
    -
    -is_empty()[source]
    -

    Is the selection empty?

    -
    - -
    -
    -provider_id = Str
    -

    ID of the selection provider that created this selection object.

    -
    - -
    - -
    -
    -

    list_selection Module

    -
    -
    -class apptools.selection.list_selection.ListSelection[source]
    -

    Bases: traits.has_traits.HasTraits

    -

    Selection for ordered sequences of items.

    -

    This is the default implementation of the IListSelection -interface.

    -
    -
    -classmethod from_available_items(provider_id, selected, all_items)[source]
    -

    Create a list selection given a list of all available items.

    -

    Fills in the required information (in particular, the indices) based -on a list of selected items and a list of all available items.

    -
    -

    Note

    -
      -
    • The list of available items must not contain any duplicate items.
    • -
    • It is expected that selected is populated by items in -all_items.
    • -
    -
    -
    - -
    -
    -indices = List
    -

    Indices of the selected objects in the selection provider.

    -
    - -
    -
    -is_empty()[source]
    -

    Is the selection empty?

    -
    - -
    -
    -items = List
    -

    Selected objects.

    -
    - -
    -
    -provider_id = Str
    -

    ID of the selection provider that created this selection object.

    -
    - -
    - -
    -
    -

    errors Module

    -
    -
    -exception apptools.selection.errors.IDConflictError(provider_id)[source]
    -

    Bases: Exception

    -

    Raised when a provider is added and its ID is already registered.

    -
    - -
    -
    -exception apptools.selection.errors.ListenerNotConnectedError(provider_id, listener)[source]
    -

    Bases: Exception

    -

    Raised when a listener that was never connected is disconnected.

    -
    - -
    -
    -exception apptools.selection.errors.ProviderNotRegisteredError(provider_id)[source]
    -

    Bases: Exception

    -

    Raised when a provider is requested by ID and not found.

    -
    - -
    -
    -
    @@ -551,7 +214,7 @@

    Table of Contents

    @@ -581,21 +233,19 @@

    Previous topic

    Undo Framework

    Next topic

    -

    API documentation

    +

    Naming

    This Page

    @@ -619,10 +269,10 @@

    Quick search

    © Copyright 2008-2020, Enthought
  • - Last updated on Jun 12, 2020. + Last updated on Dec 17, 2020.
  • - Created using Sphinx 1.8.5. + Created using Sphinx 2.3.1.
  • diff --git a/undo/Introduction.html b/undo/Introduction.html index de995060a..4351eaac1 100644 --- a/undo/Introduction.html +++ b/undo/Introduction.html @@ -13,9 +13,11 @@ @@ -80,7 +82,7 @@
    -
    +

    Undo Framework

    @@ -93,7 +95,7 @@

    Undo Framework

    The following are the concepts supported by the framework.

      -
    • Command

      +
    • Command

      A command is an application defined operation that can be done (i.e. executed), undone (i.e. reverted) and redone (i.e. repeated).

      A command operates on some data and maintains sufficient state to allow it to @@ -102,11 +104,11 @@

      Framework ConceptsMacro

      +
    • Macro

      A macro is a sequence of commands that is treated as a single command when being undone or redone.

    • -
    • Command Stack

      +
    • Command Stack

      A command is done by pushing it onto a command stack. The last command can be undone and redone by calling appropriate command stack methods. It is also possible to move the stack’s position to any point and the command stack @@ -117,7 +119,7 @@

      Framework ConceptsUndo Manager

      +
    • Undo Manager

      An undo manager is responsible for one or more command stacks and maintains a reference to the currently active stack. It provides convenience undo and redo methods that operate on the currently active stack.

      @@ -150,123 +152,123 @@

      API Overview

      The UndoManager class is the default implementation of the IUndoManager interface.

      -
      -
      active_stack
      -
      This trait is a reference to the currently active command stack and may be -None. Typically it is set when some sort of editor becomes active.
      -
      active_stack_clean
      -
      This boolean trait reflects the clean state of the currently active +
      +
      active_stack

      This trait is a reference to the currently active command stack and may be +None. Typically it is set when some sort of editor becomes active.

      +
      +
      active_stack_clean

      This boolean trait reflects the clean state of the currently active command stack. It is intended to support a “document modified” indicator -in the GUI. It is maintained by the undo manager.

      -
      stack_updated
      -
      This event is fired when the index of a command stack is changed. A +in the GUI. It is maintained by the undo manager.

      +
      +
      stack_updated

      This event is fired when the index of a command stack is changed. A reference to the stack is passed as an argument to the event and may not -be the currently active stack.

      -
      undo_name
      -
      This Unicode trait is the name of the command that can be undone, and will +be the currently active stack.

      +
      +
      undo_name

      This Str trait is the name of the command that can be undone, and will be empty if there is no such command. It is maintained by the undo -manager.

      -
      redo_name
      -
      This Unicode trait is the name of the command that can be redone, and will +manager.

      +
      +
      redo_name

      This Str trait is the name of the command that can be redone, and will be empty if there is no such command. It is maintained by the undo -manager.

      -
      sequence_nr
      -
      This integer trait is the sequence number of the next command to be +manager.

      +
      +
      sequence_nr

      This integer trait is the sequence number of the next command to be executed. It is incremented immediately before a command’s do() method is called. A particular sequence number identifies the state of all command stacks handled by the undo manager and allows those stacks to be set to the point they were at at a particular point in time. In other words, the sequence number allows otherwise independent command stacks to -be synchronised.

      -
      undo()
      -
      This method calls the undo() method of the last command on the active -command stack.
      -
      redo()
      -
      This method calls the redo() method of the last undone command on the -active command stack.
      +be synchronised.

      +
      +
      undo()

      This method calls the undo() method of the last command on the active +command stack.

      +
      +
      redo()

      This method calls the redo() method of the last undone command on the +active command stack.

      +

    CommandStack

    The CommandStack class is the default implementation of the ICommandStack interface.

    -
    -
    clean
    -
    This boolean traits reflects the clean state of the command stack. Its +
    +
    clean

    This boolean traits reflects the clean state of the command stack. Its value changes as commands are executed, undone and redone. It may also be explicitly set to mark the current stack position as being clean (when -data is saved to disk for example).

    -
    undo_name
    -
    This Unicode trait is the name of the command that can be undone, and will +data is saved to disk for example).

    +
    +
    undo_name

    This Str trait is the name of the command that can be undone, and will be empty if there is no such command. It is maintained by the command -stack.

    -
    redo_name
    -
    This Unicode trait is the name of the command that can be redone, and will +stack.

    +
    +
    redo_name

    This Str trait is the name of the command that can be redone, and will be empty if there is no such command. It is maintained by the command -stack.

    -
    undo_manager
    -
    This trait is a reference to the undo manager that manages the command -stack.
    -
    push(command)
    -
    This method executes the given command by calling its do() method. +stack.

    +
    +
    undo_manager

    This trait is a reference to the undo manager that manages the command +stack.

    +
    +
    push(command)

    This method executes the given command by calling its do() method. Any value returned by do() is returned by push(). If the command couldn’t be merged with the previous one then it is saved on the command -stack.

    -
    undo(sequence_nr=0)
    -
    This method undoes the last command. If a sequence number is given then -all commands are undone up to an including the sequence number.
    -
    redo(sequence_nr=0)
    -
    This method redoes the last command and returns any result. If a sequence +stack.

    +
    +
    undo(sequence_nr=0)

    This method undoes the last command. If a sequence number is given then +all commands are undone up to an including the sequence number.

    +
    +
    redo(sequence_nr=0)

    This method redoes the last command and returns any result. If a sequence number is given then all commands are redone up to an including the -sequence number and any result of the last of these is returned.

    -
    clear()
    -
    This method clears the command stack, without undoing or redoing any +sequence number and any result of the last of these is returned.

    +
    +
    clear()

    This method clears the command stack, without undoing or redoing any commands, and leaves the stack in a clean state. It is typically used -when all changes to the data have been abandoned.

    -
    begin_macro(name)
    -
    This method begins a macro by creating an empty command with the given +when all changes to the data have been abandoned.

    +
    +
    begin_macro(name)

    This method begins a macro by creating an empty command with the given name. The commands passed to all subsequent calls to push() will be contained in the macro until the next call to end_macro(). Macros may be nested. The command stack is disabled (ie. nothing can be undone or redone) while a macro is being created (ie. while there is an outstanding -end_macro() call).

    -
    end_macro()
    -
    This method ends the current macro.
    +end_macro() call).

    +
    +
    end_macro()

    This method ends the current macro.

    +

    ICommand

    The ICommand interface defines the interface that must be implemented by any undoable/redoable command.

    -
    -
    data
    -
    This optional trait is a reference to the data object that the command -operates on. It is not used by the framework itself.
    -
    name
    -
    This Unicode trait is the name of the command as it will appear in any GUI +
    +
    data

    This optional trait is a reference to the data object that the command +operates on. It is not used by the framework itself.

    +
    +
    name

    This Str trait is the name of the command as it will appear in any GUI element (e.g. in the text of an undo and redo menu entry). It may include & to indicate a keyboard shortcut which will be automatically removed -whenever it is inappropriate.

    -
    __init__(*args)
    -
    If the command takes arguments then the command must ensure that deep -copies should be made if appropriate.
    -
    do()
    -
    This method is called by a command stack to execute the command and to +whenever it is inappropriate.

    +
    +
    __init__(*args)

    If the command takes arguments then the command must ensure that deep +copies should be made if appropriate.

    +
    +
    do()

    This method is called by a command stack to execute the command and to return any result. The command must save any state necessary for the undo() and redo() methods to work. It is guaranteed that this will only ever be called once and that it will be called before any call -to undo() or redo().

    -
    undo()
    -
    This method is called by a command stack to undo the command.
    -
    redo()
    -
    This method is called by a command stack to redo the command and to return -any result.
    -
    merge(other)
    -
    This method is called by the command stack to try and merge the other +to undo() or redo().

    +
    +
    undo()

    This method is called by a command stack to undo the command.

    +
    +
    redo()

    This method is called by a command stack to redo the command and to return +any result.

    +
    +
    merge(other)

    This method is called by the command stack to try and merge the other command with this one. True should be returned if the commands were merged. If the commands are merged then other will not be placed on the command stack. A subsequent undo or redo of this modified command -must have the same effect as the two original commands.

    +must have the same effect as the two original commands.

    +
    @@ -278,17 +280,17 @@

    AbstractCommand

    The CommandAction class is a sub-class of the PyFace Action class that is used to wrap commands.

    -
    -
    command
    -
    This callable trait must be set to a factory that will return an object +
    +
    command

    This callable trait must be set to a factory that will return an object that implements ICommand. It will be called when the action is invoked -and the object created pushed onto the command stack.

    -
    command_stack
    -
    This instance trait must be set to the command stack that commands invoked -by the action are pushed to.
    -
    data
    -
    This optional trait is a reference to the data object that will be passed -to the command factory when it is called.
    +and the object created pushed onto the command stack.

    +
    +
    command_stack

    This instance trait must be set to the command stack that commands invoked +by the action are pushed to.

    +
    +
    data

    This optional trait is a reference to the data object that will be passed +to the command factory when it is called.

    +
    @@ -343,13 +345,11 @@

    This Page

    rel="nofollow">Show Source
    @@ -373,10 +373,10 @@

    Quick search

    © Copyright 2008-2020, Enthought
  • - Last updated on Jun 12, 2020. + Last updated on Dec 17, 2020.
  • - Created using Sphinx 1.8.5. + Created using Sphinx 2.3.1.