1# (C) Copyright 2005-2020 Enthought, Inc., Austin, TX
2# All rights reserved.
3#
4# This software is provided without warranty under the terms of the BSD
5# license included in LICENSE.txt and may be redistributed only under
6# the conditions described in the aforementioned license. The license
7# is also available online at http://www.enthought.com/licenses/BSD.txt
8#
9# Thanks for using Enthought open source!
10
11""" An action manager item that represents an actual action. """
12
13
14from traits.api import Any, Instance, List, Property, Str, on_trait_change
15
16
17from pyface.action.action import Action
18from pyface.action.action_manager_item import ActionManagerItem
19
20# Import the toolkit specific versions of the internal classes.
21from pyface.toolkit import toolkit_object
22
23_MenuItem = toolkit_object("action.action_item:_MenuItem")
24_Tool = toolkit_object("action.action_item:_Tool")
25_PaletteTool = toolkit_object("action.action_item:_PaletteTool")
26
27
28class ActionItem(ActionManagerItem):
29    """ An action manager item that represents an actual action. """
30
31    # 'ActionManagerItem' interface ----------------------------------------
32
33    #: The item's unique identifier ('unique' in this case means unique within
34    #: its group).
35    id = Property(Str)
36
37    # 'ActionItem' interface -----------------------------------------------
38
39    #: The action!
40    action = Instance(Action)
41
42    #: The toolkit specific control created for this item.
43    control = Any()
44
45    #: The toolkit specific Id of the control created for this item.
46    #
47    #: We have to keep the Id as well as the control because wx tool bar tools
48    #: are created as 'wxObjectPtr's which do not have Ids, and the Id is
49    #: required to manipulate the state of a tool via the tool bar 8^(
50    # FIXME v3: Why is this part of the public interface?
51    control_id = Any()
52
53    # Private interface ----------------------------------------------------
54
55    #: All of the internal instances that wrap this item.
56    _wrappers = List(Any)
57
58    # ------------------------------------------------------------------------
59    # 'ActionManagerItem' interface.
60    # ------------------------------------------------------------------------
61
62    # Trait properties -----------------------------------------------------
63
64    def _get_id(self):
65        return self.action.id
66
67    # Trait change handlers ------------------------------------------------
68
69    def _enabled_changed(self, trait_name, old, new):
70        self.action.enabled = new
71
72    def _visible_changed(self, trait_name, old, new):
73        self.action.visible = new
74
75    @on_trait_change("_wrappers.control")
76    def _on_destroy(self, object, name, old, new):
77        """ Handle the destruction of the wrapper. """
78        if name == "control" and new is None:
79            self._wrappers.remove(object)
80
81    # ------------------------------------------------------------------------
82    # 'ActionItem' interface.
83    # ------------------------------------------------------------------------
84
85    def add_to_menu(self, parent, menu, controller):
86        """ Add the item to a menu.
87
88        Parameters
89        ----------
90        parent : toolkit control
91            The parent of the new menu item control.
92        menu : toolkit menu
93            The menu to add the action item to.
94        controller : ActionController instance or None
95            The controller to use.
96        """
97        if (controller is None) or controller.can_add_to_menu(self.action):
98            wrapper = _MenuItem(parent, menu, self, controller)
99
100            # fixme: Martin, who uses this information?
101            if controller is None:
102                self.control = wrapper.control
103                self.control_id = wrapper.control_id
104
105            self._wrappers.append(wrapper)
106
107    def add_to_toolbar(
108        self, parent, tool_bar, image_cache, controller, show_labels=True
109    ):
110        """ Adds the item to a tool bar.
111
112        Parameters
113        ----------
114        parent : toolkit control
115            The parent of the new menu item control.
116        tool_bar : toolkit toolbar
117            The toolbar to add the action item to.
118        image_cache : ImageCache instance
119            The image cache for resized images.
120        controller : ActionController instance or None
121            The controller to use.
122        show_labels : bool
123            Should the toolbar item show a label.
124        """
125        if (controller is None) or controller.can_add_to_toolbar(self.action):
126            wrapper = _Tool(
127                parent, tool_bar, image_cache, self, controller, show_labels
128            )
129
130            # fixme: Martin, who uses this information?
131            if controller is None:
132                self.control = wrapper.control
133                self.control_id = wrapper.control_id
134
135            self._wrappers.append(wrapper)
136
137    def add_to_palette(self, tool_palette, image_cache, show_labels=True):
138        """ Adds the item to a tool palette.
139
140        Parameters
141        ----------
142        parent : toolkit control
143            The parent of the new menu item control.
144        tool_palette : toolkit tool palette
145            The tool palette to add the action item to.
146        image_cache : ImageCache instance
147            The image cache for resized images.
148        show_labels : bool
149            Should the toolbar item show a label.
150        """
151        wrapper = _PaletteTool(tool_palette, image_cache, self, show_labels)
152        self._wrappers.append(wrapper)
153
154    def destroy(self):
155        """ Called when the action is no longer required.
156
157        By default this method calls 'destroy' on the action itself.
158        """
159        self.action.destroy()
160