File: editor_factories.py

package info (click to toggle)
python-traits 6.4.3-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 8,648 kB
  • sloc: python: 34,801; ansic: 4,266; makefile: 102
file content (196 lines) | stat: -rw-r--r-- 5,808 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
# (C) Copyright 2005-2023 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!

"""
Editor factory functions.
"""

import datetime
from functools import partial
import logging


logger = logging.getLogger(__name__)


def password_editor(auto_set=True, enter_set=False):
    """ Factory function that returns an editor for passwords.
    """
    from traitsui.api import TextEditor
    return TextEditor(
        password=True, auto_set=auto_set, enter_set=enter_set
    )


def multi_line_text_editor(auto_set=True, enter_set=False):
    """ Factory function that returns a text editor for multi-line strings.
    """
    from traitsui.api import TextEditor
    return TextEditor(
        multi_line=True, auto_set=auto_set, enter_set=enter_set
    )


def bytes_editor(auto_set=True, enter_set=False, encoding=None):
    """ Factory function that returns a text editor for bytes.
    """
    from traitsui.api import TextEditor

    if encoding is None:
        format = bytes.hex
        evaluate = bytes.fromhex
    else:
        format = partial(bytes.decode, encoding=encoding)
        evaluate = partial(str.encode, encoding=encoding)

    return TextEditor(
        multi_line=True,
        format_func=format,
        evaluate=evaluate,
        auto_set=auto_set,
        enter_set=enter_set,
    )


def code_editor():
    """ Factory function that returns an editor that treats a multi-line string
    as source code.
    """
    from traitsui.api import CodeEditor
    return CodeEditor()


def html_editor():
    """ Factory function for an "editor" that displays a multi-line string as
    interpreted HTML.
    """
    from traitsui.api import HTMLEditor
    return HTMLEditor()


def shell_editor():
    """ Factory function that returns a Python shell for editing Python values.
    """
    from traitsui.api import ShellEditor
    return ShellEditor()


def time_editor():
    """ Factory function that returns a Time editor for editing Time values.
    """
    from traitsui.api import TimeEditor
    return TimeEditor()


def date_editor():
    """ Factory function that returns a Date editor for editing Date values.
    """
    from traitsui.api import DateEditor
    return DateEditor()


def _datetime_str_to_datetime(datetime_str, format="%Y-%m-%dT%H:%M:%S"):
    """ Returns the datetime object for a datetime string in the specified
    format (default ISO format).

    Raises a ValueError if datetime_str does not match the format.
    """
    # Allow the empty string to be translated to None.
    if not datetime_str:
        return None
    return datetime.datetime.strptime(datetime_str, format)


def _datetime_to_datetime_str(datetime_obj, format="%Y-%m-%dT%H:%M:%S"):
    """ Returns a string representation for a datetime object in the specified
    format (default ISO format).
    """
    # A Datetime trait can contain None. We translate that to an empty string.
    if datetime_obj is None:
        return ""
    return datetime.date.strftime(datetime_obj, format)


def datetime_editor():
    """ Factory function that returns an editor with date & time for
    editing Datetime values.
    """
    from traitsui.api import DatetimeEditor
    return DatetimeEditor()


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, DefaultValue, TraitInstance

    if isinstance(handler, TraitInstance):
        return handler.aClass
    elif isinstance(handler, BaseInstance):
        if handler.default_value_type == DefaultValue.callable_and_args:
            default_value_getter, args, kwargs = handler.default_value
            return lambda: default_value_getter(*args, **kwargs)
        else:
            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_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 "",
        )