1# ------------------------------------------------------------------------------
2#
3#  Copyright (c) 2008, Enthought, Inc.
4#  All rights reserved.
5#
6#  This software is provided without warranty under the terms of the BSD
7#  license included in LICENSE.txt and may be redistributed only
8#  under the conditions described in the aforementioned license.  The license
9#  is also available online at http://www.enthought.com/licenses/BSD.txt
10#
11#  Thanks for using Enthought open source!
12#
13#  Author: David C. Morrill
14#  Date:   10/21/2004
15#
16# ------------------------------------------------------------------------------
17""" Defines the list editor factory for the traits user interface toolkits..
18"""
19
20
21
22from traits.api import (
23    HasTraits,
24    BaseTraitHandler,
25    Range,
26    Str,
27    Any,
28    Int,
29    Instance,
30    Property,
31    Bool,
32    Callable,
33    Enum,
34    PrototypedFrom,
35)
36
37# CIRCULAR IMPORT FIXME: Importing from the source rather than traits.ui.api
38# to avoid circular imports, as this EditorFactory will be part of
39# traits.ui.api as well.
40from ..view import View
41
42from ..item import Item
43
44from ..ui_traits import style_trait, AView
45
46from ..editor_factory import EditorFactory
47
48from ..toolkit import toolkit_object
49
50# Currently, this traits is used only for the wx backend.
51from ..helper import DockStyle
52
53# -------------------------------------------------------------------------
54#  Trait definitions:
55# -------------------------------------------------------------------------
56
57# Trait whose value is a BaseTraitHandler object
58handler_trait = Instance(BaseTraitHandler)
59
60# The visible number of rows displayed
61rows_trait = Range(1, 50, 5, desc="the number of list rows to display")
62
63# The visible number of columns displayed
64columns_trait = Range(1, 10, 1, desc="the number of list columns to display")
65
66editor_trait = Instance(EditorFactory)
67
68# -------------------------------------------------------------------------
69#  'ToolkitEditorFactory' class:
70# -------------------------------------------------------------------------
71
72
73class ToolkitEditorFactory(EditorFactory):
74    """ Editor factory for list editors.
75    """
76
77    # -------------------------------------------------------------------------
78    #  Trait definitions:
79    # -------------------------------------------------------------------------
80
81    #: The editor to use for each list item:
82    editor = editor_trait
83
84    #: Can the list be reorganized, or have items added and deleted.
85    mutable = Bool(True)
86
87    #: Should the scrollbars be displayed if the list is too long.
88    scrollable = Bool(True, sync_value=True)
89
90    #: The style of editor to use for each item:
91    style = style_trait
92
93    #: The trait handler for each list item:
94    trait_handler = handler_trait
95
96    #: The number of list rows to display:
97    rows = rows_trait
98
99    #: The number of list columns to create:
100    columns = columns_trait
101
102    #: Use a notebook for a custom view?
103    use_notebook = Bool(False)
104
105    #: Show a right-click context menu for the notebook tabs?  (Qt only)
106    show_notebook_menu = Bool(False)
107
108    # -- Notebook Specific Traits ---------------------------------------------
109
110    #: Are notebook items deletable?
111    deletable = Bool(False)
112
113    #: The extended name of the trait on each page object which should be used
114    #: to determine whether or not an individual page should be deletable.
115    deletable_trait = Str()
116
117    #: FIXME: Currently, this trait is used only in the wx backend.
118    #: The DockWindow graphical theme
119    dock_theme = Any()
120
121    #: FIXME: Currently, this trait is used only in the wx backend.
122    #: Dock page style to use for each DockControl:
123    dock_style = DockStyle
124
125    #: Export class for each item in a notebook:
126    export = Str()
127
128    #: Name of the view to use in notebook mode:
129    view = AView
130
131    #: The type of UI to construct ('panel', 'subpanel', etc)
132    ui_kind = Enum("subpanel", "panel")
133
134    #: A factory function that can be used to define that actual object to be
135    #: edited (i.e. view_object = factory( object )):
136    factory = Callable()
137
138    #: Extended name to use for each notebook page. It can be either the actual
139    #: name or the name of an attribute on the object in the form:
140    #: '.name[.name...]'
141    page_name = Str()
142
143    #: Name of the [object.]trait[.trait...] to synchronize notebook page
144    #: selection with:
145    selected = Str()
146
147    # -------------------------------------------------------------------------
148    #  Traits view definition:
149    # -------------------------------------------------------------------------
150
151    traits_view = View(
152        [
153            ["use_notebook{Use a notebook in a custom view}", "|[Style]"],
154            [
155                Item("page_name", enabled_when="object.use_notebook"),
156                Item("view", enabled_when="object.use_notebook"),
157                "|[Notebook options]",
158            ],
159            [
160                Item("rows", enabled_when="not object.use_notebook"),
161                "|[Number of list rows to display]<>",
162            ],
163        ]
164    )
165
166    # -------------------------------------------------------------------------
167    #  'Editor' factory methods:
168    # -------------------------------------------------------------------------
169
170    def _get_custom_editor_class(self):
171        if self.use_notebook:
172            return toolkit_object("list_editor:NotebookEditor")
173        return toolkit_object("list_editor:CustomEditor")
174
175
176# -------------------------------------------------------------------------
177#  'ListItemProxy' class:
178#   This class is used to update the list editors when the object changes
179#   external to the editor.
180# -------------------------------------------------------------------------
181
182
183class ListItemProxy(HasTraits):
184
185    #: The list proxy:
186    list = Property()
187
188    #: The item proxies index into the original list:
189    index = Int()
190
191    #: Delegate all other traits to the original object:
192    _ = PrototypedFrom("_zzz_object")
193
194    #: Define all of the private internal use values (the funny names are an
195    #: attempt to avoid name collisions with delegated trait names):
196    _zzz_inited = Any()
197    _zzz_object = Any()
198    _zzz_name = Any()
199
200    def __init__(self, object, name, index, trait, value):
201        super(ListItemProxy, self).__init__()
202
203        self._zzz_inited = False
204        self._zzz_object = object
205        self._zzz_name = name
206        self.index = index
207
208        if trait is not None:
209            self.add_trait("value", trait)
210            self.value = value
211
212        self._zzz_inited = self.index < len(self.list)
213
214    def _get_list(self):
215        return getattr(self._zzz_object, self._zzz_name)
216
217    def _value_changed(self, old_value, new_value):
218        if self._zzz_inited:
219            self.list[self.index] = new_value
220
221
222# Define the ListEditor class
223ListEditor = ToolkitEditorFactory
224