310 lines
9.9 KiB
Plaintext
310 lines
9.9 KiB
Plaintext
|
note
|
||
|
description: "[
|
||
|
TOOL used to hold a JJ_TREE_VIEW for displaying a hierarchical
|
||
|
structure of VIEWABLE_NODEs.
|
||
|
]"
|
||
|
author: "Jimmy J. Johnson"
|
||
|
date: "21 Apr 06"
|
||
|
|
||
|
class
|
||
|
JJ_TREE_TOOL
|
||
|
|
||
|
inherit
|
||
|
|
||
|
TOOL
|
||
|
redefine
|
||
|
initialize,
|
||
|
initialize_interface,
|
||
|
set_actions,
|
||
|
target,
|
||
|
set_target,
|
||
|
set_button_states,
|
||
|
draw
|
||
|
end
|
||
|
|
||
|
create
|
||
|
default_create
|
||
|
|
||
|
feature {NONE} -- Initialization
|
||
|
|
||
|
initialize
|
||
|
-- Set up the window
|
||
|
do
|
||
|
create tree_view
|
||
|
-- Create the new buttons before Precursor {TOOL} so `initialize'
|
||
|
-- can call `set_actions' without a Void reference.
|
||
|
create target_system_button
|
||
|
create new_node_button
|
||
|
create view_descendants_button
|
||
|
create view_ancestors_button
|
||
|
create cut_button
|
||
|
-- "Register" the widgets with the `interface_table' in use by the
|
||
|
-- current program (from SHARED in the "Standard Interface" cluster).
|
||
|
interface_table.register_widget (target_system_button, "{JJ_TREE_TOOL} - target_system")
|
||
|
interface_table.register_widget (new_node_button, "{JJ_TREE_TOOL} - new_node")
|
||
|
interface_table.register_widget (view_descendants_button, "{JJ_TREE_TOOL} - view_descendants")
|
||
|
interface_table.register_widget (view_ancestors_button, "{JJ_TREE_TOOL} - view_ancestors")
|
||
|
interface_table.register_widget (cut_button, "{JJ_TREE_TOOL} - cut")
|
||
|
interface_table.register_widget (Current, generating_type)
|
||
|
-- Create the tool and its views
|
||
|
Precursor {TOOL}
|
||
|
-- Add the buttons to the `tool_bar' (from TOOL)
|
||
|
tool_bar.extend (target_system_button)
|
||
|
tool_bar.extend (new_node_button)
|
||
|
tool_bar.extend (view_descendants_button)
|
||
|
tool_bar.extend (view_ancestors_button)
|
||
|
tool_bar.extend (cut_button)
|
||
|
-- Set up the views in this tool.
|
||
|
-- view_manager.enable_mode_changes
|
||
|
split_manager.extend (tree_view)
|
||
|
set_actions_for_views
|
||
|
end
|
||
|
|
||
|
initialize_interface
|
||
|
-- Create INTERFACE_ITEMs which could be used by Current.
|
||
|
-- Called by `initialize'.
|
||
|
do
|
||
|
-- Only add an interface item for Current if its `interface_name' has
|
||
|
-- not already been added; the other items are specific for this tool
|
||
|
-- and most likely will not be redefine, so no need to check inclusion
|
||
|
-- of these in the `interface_table'.
|
||
|
-- In redefinitions of this feature call this at the end of the redefinition
|
||
|
-- so an item for the `interface_name' can be added to the `interface_table'.
|
||
|
if not interface_table.has_key (generating_type) then
|
||
|
interface_table.add_item_with_tuple (<< generating_type, "JJ_TREE_TOOL", "Node tree tool", "Used to view relationships between nodes.", "icon_format_feature_descendants_color.ico">>)
|
||
|
end
|
||
|
interface_table.add_item_with_tuple (<<"{JJ_TREE_TOOL} - target_system", "Target System", "Make System be the target", "Set the target of this tool to the applications system.", "icon_object_symbol.ico">>)
|
||
|
interface_table.add_item_with_tuple (<<"{JJ_TREE_TOOL} - new_node", "New Node", "Create a new node", "Create a new node.", "icon_cluster_symbol_color.ico">>)
|
||
|
interface_table.add_item_with_tuple (<<"{JJ_TREE_TOOL} - view_descendants", "Descendents", "View descendants", "Show the descendent relationships of targeted object.", "icon_format_descendants_color.ico">>)
|
||
|
interface_table.add_item_with_tuple (<<"{JJ_TREE_TOOL} - view_ancestors", "Ancestors", "View Ancestors", "Show the ancestor relationships of targeted object.", "icon_format_ancestors_color.ico">>)
|
||
|
interface_table.add_item_with_tuple (<<"{JJ_TREE_TOOL} - cut", "Cut relationship", "Cut the link to the selected node", "Cut this link to the selected node.", "icon_cut_color.ico">>)
|
||
|
-- Call Precursor after current is set up. Specifically after the interface
|
||
|
-- item for Current's `interface_name' is added. (see above)
|
||
|
Precursor {TOOL}
|
||
|
end
|
||
|
|
||
|
set_actions
|
||
|
-- Add actions to the widgets
|
||
|
do
|
||
|
Precursor {TOOL}
|
||
|
target_system_button.select_actions.extend (agent on_target_system_button_pressed)
|
||
|
new_node_button.select_actions.extend (agent on_new_node_button_pressed (agent new_node))
|
||
|
view_descendants_button.select_actions.extend (agent on_view_descendants_button_pressed)
|
||
|
view_ancestors_button.select_actions.extend (agent on_view_ancestors_button_pressed)
|
||
|
cut_button.select_actions.extend (agent on_cut_button_pressed)
|
||
|
end
|
||
|
|
||
|
set_actions_for_views
|
||
|
-- Add actions to the views. This can only be done after the views are
|
||
|
-- created. Because `set_actions' is called in the precursor to `initialize'
|
||
|
-- this feature had to be added in order to access the "views" after they
|
||
|
-- are created in `initialize' with the calls to `register_view_function'
|
||
|
-- from `view_manager'.
|
||
|
do
|
||
|
tree_view.select_actions.extend (agent set_button_states)
|
||
|
end
|
||
|
|
||
|
feature -- Access
|
||
|
|
||
|
target: NODE
|
||
|
-- The object handled by this tool.
|
||
|
|
||
|
tree_view: JJ_TREE_VIEW
|
||
|
-- The VIEW which actually does the displaying of
|
||
|
-- the nodes in a tree.
|
||
|
|
||
|
feature -- Element change
|
||
|
|
||
|
set_target (a_target: like target)
|
||
|
-- Change the `target' of the tool.
|
||
|
-- Redefined to propegate `a_target' to the `tree_view'.
|
||
|
do
|
||
|
Precursor {TOOL} (a_target)
|
||
|
tree_view.set_target (a_target)
|
||
|
draw
|
||
|
set_button_states
|
||
|
end
|
||
|
|
||
|
feature -- Basic operations
|
||
|
|
||
|
draw
|
||
|
-- Builds the string shown at top of the tool in `viewable_label'
|
||
|
-- using the id of the object.
|
||
|
local
|
||
|
s: STRING
|
||
|
n: NODE
|
||
|
pw_test: ANY
|
||
|
do
|
||
|
Precursor {TOOL}
|
||
|
-- Reminder: `target_label' is built in Precursor {TOOL}; it fills in
|
||
|
-- the `display_name' if the TOOL's target is an EDITALBE, else it uses
|
||
|
-- the generating type of the target.
|
||
|
-- So, this redefined version simply addes the "not in system text"
|
||
|
-- to the display name if necessary.
|
||
|
s := target_label.tooltip
|
||
|
pw_test := parent_window.target
|
||
|
n ?= parent_window.target
|
||
|
check
|
||
|
n /= Void
|
||
|
end
|
||
|
if n /= Void and then not n.descendants.has (target) then
|
||
|
s := s + " " + interface_table.short_name ("not in system text")
|
||
|
end
|
||
|
target_label.set_tooltip (s)
|
||
|
set_button_states
|
||
|
end
|
||
|
|
||
|
set_button_states
|
||
|
-- Set the states of the buttons.
|
||
|
local
|
||
|
n: NODE
|
||
|
do
|
||
|
Precursor {TOOL}
|
||
|
check
|
||
|
tree_view_exists: tree_view /= Void
|
||
|
end
|
||
|
if tree_view.target = Void then
|
||
|
new_node_button.disable_sensitive
|
||
|
cut_button.disable_sensitive
|
||
|
view_descendants_button.disable_sensitive
|
||
|
view_ancestors_button.disable_sensitive
|
||
|
else
|
||
|
view_descendants_button.enable_sensitive
|
||
|
view_ancestors_button.enable_sensitive
|
||
|
n := tree_view.selected_target
|
||
|
if n.can_adopt then
|
||
|
new_node_button.enable_sensitive
|
||
|
else
|
||
|
new_node_button.disable_sensitive
|
||
|
end
|
||
|
if n /= target then
|
||
|
cut_button.enable_sensitive
|
||
|
else
|
||
|
cut_button.disable_sensitive
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
|
||
|
feature {NONE} -- Implementation (actions)
|
||
|
|
||
|
on_target_system_button_pressed
|
||
|
-- React to a press of the `target_system_button' by retargetting
|
||
|
-- the view to the application's `target' and view descendents mode.
|
||
|
local
|
||
|
app: JJ_APPLICATION
|
||
|
vn: NODE
|
||
|
do
|
||
|
app ?= (create {EV_ENVIRONMENT}).application
|
||
|
check
|
||
|
app_exists: app /= Void
|
||
|
-- Because this class is only used by JJJ_APPLICATIONs
|
||
|
end
|
||
|
vn ?= app.target
|
||
|
if vn /= Void then
|
||
|
set_target (vn)
|
||
|
end
|
||
|
if tree_view.selected_item /= Void then
|
||
|
tree_view.selected_item.disable_select
|
||
|
end
|
||
|
set_button_states
|
||
|
end
|
||
|
|
||
|
on_new_node_button_pressed (a_function: FUNCTION [NODE])
|
||
|
-- React to a press of the `new_node_button' by creating a
|
||
|
-- new node using `a_function' and make the new node a child
|
||
|
-- under the currently selected node.
|
||
|
local
|
||
|
c: ADD_NODE_COMMAND
|
||
|
ti: EV_TREE_NODE
|
||
|
new_n, n: NODE
|
||
|
do
|
||
|
new_n := a_function.item ([])
|
||
|
create c
|
||
|
n := tree_view.selected_target
|
||
|
c.set_parent_node (n)
|
||
|
c.set_child_node (new_n)
|
||
|
command_manager.add_command (c)
|
||
|
-- restore the selected object after a draw
|
||
|
ti := tree_view.retrieve_item_recursively_by_data (n, False)
|
||
|
if ti /= Void then
|
||
|
ti.enable_select
|
||
|
end
|
||
|
end
|
||
|
|
||
|
new_node: EDITABLE_NODE
|
||
|
-- Creation feature for a new node, used in `on_new_node_button_pressed'.
|
||
|
do
|
||
|
create Result
|
||
|
ensure
|
||
|
result_exists: Result /= Void
|
||
|
end
|
||
|
|
||
|
on_view_ancestors_button_pressed
|
||
|
-- React to a press of the `view_ancestors_button' by changing
|
||
|
-- the `view' to ancestors mode.
|
||
|
do
|
||
|
tree_view.set_view_ancestors
|
||
|
end
|
||
|
|
||
|
on_view_descendants_button_pressed
|
||
|
-- React to a press of the `view_descendants_button' by changing
|
||
|
-- the `view' to descendants mode.
|
||
|
do
|
||
|
tree_view.set_view_descendants
|
||
|
end
|
||
|
|
||
|
on_cut_button_pressed
|
||
|
-- React to a press of the `cut_button' by removing the current node
|
||
|
-- from its parent. (Does not necessarily delete from the system, but
|
||
|
-- the node could be deleted if this is its only location in the tree.)
|
||
|
require
|
||
|
not_viewing_ancestors: not tree_view.is_viewing_ancestors
|
||
|
cannot_cut_target_from_its_parent: tree_view.selected_target /= target
|
||
|
local
|
||
|
nti: JJ_NODE_ITEM
|
||
|
nti_parent: JJ_NODE_ITEM
|
||
|
parent_n: NODE
|
||
|
n: NODE
|
||
|
c: CUT_NODE_COMMAND
|
||
|
do
|
||
|
n := tree_view.selected_target
|
||
|
nti := tree_view.selected_item
|
||
|
nti_parent ?= nti.parent
|
||
|
if nti_parent = Void then
|
||
|
parent_n := target
|
||
|
check
|
||
|
parent_n.children.has (n)
|
||
|
-- because otherwise we have the wrong parent
|
||
|
end
|
||
|
else
|
||
|
parent_n := nti_parent.target
|
||
|
end
|
||
|
create c
|
||
|
c.set_parent_node (parent_n)
|
||
|
c.set_child_node (n)
|
||
|
command_manager.add_command (c)
|
||
|
-- Set the selected item to the `target' because we just deleted
|
||
|
-- the selected item.
|
||
|
draw_views (target)
|
||
|
end
|
||
|
|
||
|
feature {NONE} -- Implementation (Buttons)
|
||
|
|
||
|
target_system_button: EV_TOOL_BAR_BUTTON
|
||
|
-- To restore the application's `system' as the target of the view.
|
||
|
|
||
|
new_node_button: EV_TOOL_BAR_BUTTON
|
||
|
-- To create a new DATABASE_RECORD.
|
||
|
|
||
|
view_descendants_button: EV_TOOL_BAR_BUTTON
|
||
|
-- To make the tree show descendants (recursively) of the `target'.
|
||
|
|
||
|
view_ancestors_button: EV_TOOL_BAR_BUTTON
|
||
|
-- To make the tree show descendants (recursively) of the `target'.
|
||
|
|
||
|
cut_button: EV_TOOL_BAR_BUTTON
|
||
|
-- To cut the link between a parent node and the currently selected node
|
||
|
|
||
|
end
|
||
|
|