/usr/share/pyshared/editobj/custom.py is in python-editobj 0.5.7-9.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
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 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 | # EditObj
# Copyright (C) 2001-2002 Jean-Baptiste LAMY -- jiba@tuxfamily
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
from editobj import MultiEdit, EVAL_ENV
# Internationalization -- Set here your translator func
# (e.g. the "_" func from the GetText module)
TRANSLATOR = lambda key: key
# Editors customization
_attr_editors = {"children" : {None : None}}
def register_attr(attr, editor, clazz = None):
"""register_attr(attr, editor, clazz = None)
Registers EDITOR as the editor for atrribute ATTR of class CLAZZ, or for any class if
CLAZZ is None. EDITOR can be either a Tk widget subclass of editobj.editor.Editor, or
None to hide the attribute.
MRO is used in order to allow subclasses to use the editor registered for their mother."""
for_attr = _attr_editors.get(attr)
if for_attr: for_attr[clazz] = editor
else: _attr_editors[attr] = { clazz : editor }
def _find_editor(obj, attr):
if isinstance(obj, MultiEdit): clazz = obj._objs[0].__class__
else: clazz = obj.__class__
for_attr = _attr_editors.get(attr)
if for_attr:
if (len(for_attr) == 1) and for_attr.has_key(None): return for_attr[None]
for clazz in (getattr(clazz, "__mro__", None) or _mro(clazz)):
editor = for_attr.get(clazz, 0)
if not editor is 0: return editor
if for_attr.has_key(None): return for_attr[None]
if attr[0] == "_": return None # Hidden
import editobj.editor as editor
val = getattr(obj, attr)
if isinstance(val, int ): return editor.IntEditor
if isinstance(val, float): return editor.FloatEditor
if isinstance(val, basestring):
if "\n" in val: return editor.TextEditor
return editor.StringEditor
return editor.EntryEditor
# Children customization
_children_attrs = {None : [("children", "insert", "__delitem__")]}
def register_children_attr(attr, insert = "insert", del_ = "__delitem__", clazz = None):
"""register_children_attr(attr, insert = "insert", del_ = "__delitem__", clazz = None)
Registers ATTR as an attribute that can act as the "content" or the "children"
of an object of class CLAZZ (or any class if None). If ATTR is None, the object is used
as its own list of children (automatically done for list / dict subclasses).
INSERT and DEL_ are the names of the methods called for inserting and deleting items.
INSERT can accept 2 arguments (as list.insert) or only one (as list.append), if you
don't care the children's order. Default values for INSERT and DEL_ are OK for lists;
for dicts, use INSERT = "__setitem__". EditObj will display these items in the tree view.
Only one such attribute can be set for a given class (several are accepted for None).
MRO is used in order to allow subclasses to use the children attribute registered for
their mother.
By default, "children" is considered for any class, and instances of classes
that inherits from list or dict are their own children."""
if clazz: _children_attrs[clazz] = (attr, insert, del_)
else: _children_attrs[None].append((attr, insert, del_))
def _find_children(obj):
if isinstance(obj, MultiEdit): clazz = obj._objs[0].__class__
else: clazz = obj.__class__
if issubclass(clazz, list) or issubclass(clazz, dict): return obj
for clazz in (getattr(clazz, "__mro__", None) or _mro(clazz)):
children_attrs = _children_attrs.get(clazz, None)
if children_attrs:
if children_attrs[0]:
children = getattr(obj, children_attrs[0])
if callable(children): return children()
return children
else: return obj
for (children_attr, insert, del_) in _children_attrs[None]:
children = getattr(obj, children_attr, None)
if not children is None:
if callable(children): return children()
return children
def _find_children_insert_remove(obj):
if isinstance(obj, MultiEdit): clazz = obj._objs[0].__class__
else: clazz = obj.__class__
if issubclass(clazz, list): return obj, obj.insert, obj.__delitem__
elif issubclass(clazz, dict): return obj, obj.__setitem__, obj.__delitem__
for clazz in (getattr(clazz, "__mro__", None) or _mro(clazz)):
children_attrs = _children_attrs.get(clazz)
if children_attrs:
children_attr, insert, del_ = children_attrs
if children_attr:
children = getattr(obj, children_attr)
if callable(children): return children()
else: children = obj
break
else:
for (children_attr, insert, del_) in _children_attrs[None]:
children = getattr(obj, children_attr, None)
if not children is None:
if callable(children): return children()
break
else: return None, None, None
return children, getattr(obj, insert, None) or getattr(children, insert), getattr(obj, del_, None) or getattr(children, del_)
# Methods customization
_methods = {}
def register_method(method, clazz, *args_editor):
"""register_method(method, clazz, *args_editor)
Registers METHOD as a method that must be displayed in EditObj for instance of CLAZZ.
METHOD can be either a method name (a string), or a function (in this case, it is not
a method, strictly speaking).
*ARGS_EDITOR are the editors used for entering the argument, e.g. use
editobj.editor.FloatEditor for a float argument, or editobj.editor.EntryEditor for a
Python eval'ed line of code.
MRO is used in order to allow subclasses to use the methods registered for
their mother.
If *ARGS_EDITOR is (None,) the method is hidden. Use this on a subclass to hide a
method provided by a mother class."""
methods = _methods.get(clazz)
if methods: methods.append((method, args_editor))
else: _methods[clazz] = [(method, args_editor)]
def _find_methods(obj):
methods = []
if isinstance(obj, MultiEdit): clazz = obj._objs[0].__class__
else: clazz = obj.__class__
for clazz in (getattr(clazz, "__mro__", None) or _mro(clazz)): methods.extend(_methods.get(clazz, ()))
return methods
def _find_methods(obj):
methods = {}
if isinstance(obj, MultiEdit): clazz = obj._objs[0].__class__
else: clazz = obj.__class__
mro = list(getattr(clazz, "__mro__", None) or _mro(clazz))
mro.reverse()
for clazz in mro:
for method, args_editor in _methods.get(clazz, ()):
if args_editor == (None,):
if methods.has_key(method): del methods[method]
else:
methods[method] = method, args_editor
return methods.values()
# Available and default children class customization (for the "Add..." dialog box)
_available_children = {}
def register_available_children(children_codes, clazz):
"""register_available_children(children_codes, clazz)
Register the CHILDREN_CODES that are proposed for addition in an instance of CLAZZ.
If CHILDREN_CODES is a list of strings (Python code), EditObj will display a dialog box.
If CHILDREN_CODES is a single string, no dialog box will be displayed, and this code
will automatically be used.
If CHILDREN_CODES is "", nothing is done when clicking on the "Add..." button.
The codes are just eval'ed to create the children; they can use the "parent" variable,
which is set to the list/dict we are adding into."""
if isinstance(children_codes, list):
try: _available_children[clazz].extend(children_codes)
except: _available_children[clazz] = children_codes
else:
_available_children[clazz] = children_codes
def _find_available_children(obj):
available_children = []
if isinstance(obj, MultiEdit): clazz = obj._objs[0].__class__
else: clazz = obj.__class__
for clazz in (getattr(clazz, "__mro__", None) or _mro(clazz)):
a = _available_children.get(clazz)
if isinstance(a, list): available_children.extend(a)
elif isinstance(a, str): return a
return available_children
# Proposed values customization
_values = {}
def register_values(attr, code_expressions):
"""register_values(attr, code_expressions)
Registers CODE_EXPRESSIONS as a proposed value for ATTR."""
code_expressions = map(unicodify, code_expressions)
try: _values[attr].extend(code_expressions)
except KeyError: _values[attr] = list(code_expressions)
def _find_values(attr): return _values.get(attr) or []
# Editing events
_on_edit = {}
_on_children_visible = {}
def register_on_edit(func, clazz):
"""register_on_edit(func, clazz)
Register FUNC as an "on_edit" event for CLAZZ.
When an instance of CLAZZ is edited, FUNC is called with the instance and the editor
Tkinter window as arguments."""
_on_edit[clazz] = func
def _call_on_edit(obj, window):
if isinstance(obj, MultiEdit): clazz = obj._objs[0].__class__
else: clazz = obj.__class__
for clazz in (getattr(clazz, "__mro__", None) or _mro(clazz)):
on_edit = _on_edit.get(clazz, None)
if on_edit: on_edit(obj, window)
def register_on_children_visible(func, clazz):
"""register_on_children_visible(func, clazz)
Register FUNC as an "on_children_visible" event for CLAZZ.
When the children of an instance of CLAZZ are shown or hidden, FUNC is called
with the instance and the new visibility status (0 or 1) as arguments."""
_on_children_visible[clazz] = func
def _call_on_children_visible(obj, visible):
if isinstance(obj, MultiEdit): clazz = obj._objs[0].__class__
else: clazz = obj.__class__
for clazz in (getattr(clazz, "__mro__", None) or _mro(clazz)):
on_children_visible = _on_children_visible.get(clazz, None)
if on_children_visible: on_children_visible(obj, visible)
def encode(s):
if type(s) is unicode: return s.encode("latin")
return s
def unicodify(s):
if type(s) is str:
try: return unicode(s, "utf8")
except UnicodeError: return unicode(s, "latin")
return s
def _mro(clazz):
mro = [clazz]
for c in clazz.__bases__: mro.extend(_mro(c))
return mro
|