note description: "Area in EB_CONTEXT_TOOL to display metrics calculation." legal: "See notice at end of class." status: "See notice at end of class." author: "Tanit Talbi" date: "$Date$" revision: "$Revision$" class ES_METRICS_TOOL_PANEL inherit EB_TOOL redefine show, internal_recycle, close end SHARED_WORKBENCH EB_METRIC_INTERFACE_PROVIDER EB_RECYCLER EB_METRIC_ACTIONS EB_METRIC_ACTION_SEQUENCES SHARED_EIFFEL_PROJECT EB_METRIC_TOOL_HELPER create make feature {NONE} -- Initialization build_interface -- <Precursor> do create widget create metric_notebook notify_project_unloaded_agent := agent notify_project_unloaded create metric_evaluation_panel.make (Current) create new_metric_panel.make (Current) create metric_archive_panel.make (Current) create detail_result_panel.make (Current) create metric_history_panel.make (Current) if not eiffel_project.manager.is_project_loaded then notify_project_loaded_agent := agent notify_project_loaded eiffel_project.manager.load_agents.extend (notify_project_loaded_agent) else notify_project_loaded end eiffel_project.manager.close_agents.extend (notify_project_unloaded_agent) metric_notebook.extend (metric_evaluation_panel) metric_notebook.extend (detail_result_panel) metric_notebook.extend (new_metric_panel) metric_notebook.extend (metric_history_panel) metric_notebook.extend (metric_archive_panel) -- Setup tab names metric_notebook.set_item_text (metric_notebook.i_th (1), metric_names.t_evaluation_tab) metric_notebook.set_item_text (metric_notebook.i_th (2), metric_names.t_detail_result_tab) metric_notebook.set_item_text (metric_notebook.i_th (3), metric_names.t_definition_tab) metric_notebook.set_item_text (metric_notebook.i_th (4), metric_names.t_history_tab) metric_notebook.set_item_text (metric_notebook.i_th (5), metric_names.t_archive_tab) metric_notebook.selection_actions.extend (agent on_tab_change) metric_notebook.select_item (metric_evaluation_panel) metric_notebook.drop_actions.extend (agent on_tab_dropped) metric_notebook.drop_actions.set_veto_pebble_function (agent on_tab_droppable) widget.extend (metric_notebook) install_agents (metric_manager) if not window_manager.compile_start_actions.has (metric_manager.on_compile_start_agent) then window_manager.compile_start_actions.extend (metric_manager.on_compile_start_agent) end register_action (content.show_actions, agent on_select) end feature -- Actions on_select -- Metric tool has been selected, synchronize. do if content.is_visible then if workbench.system_defined and then workbench.is_already_compiled then load_metrics_and_display_error (False, metric_names.t_loading_metrics) end on_tab_change set_title (Void) end end on_deselect -- Metric tool has been deselected. do on_tab_change end on_send_metric_value_in_history (a_archive: EB_METRIC_ARCHIVE_NODE; a_panel: ANY) -- Action to be performed to send last evaluated metric value (stored in `a_archive') in history -- `a_panel' is the metric tool panel from which the sending request occurs. require a_archive_attached: a_archive /= Void do set_last_metric_value_historied (True) send_metric_value_in_history_actions.call ([a_archive, a_panel]) end show -- <Precursor> do Precursor {EB_TOOL} on_select end close -- <Precursor> do Precursor {EB_TOOL} on_deselect end feature -- Basic operations go_to_definition (a_metric: EB_METRIC; a_new: BOOLEAN) -- Go to definition panel of metric named `a_name'. -- `a_new' is True indicates that `a_metric' is a new metric from quick metric definition. require a_metric_attached: a_metric /= Void nod_a_new_implies_a_metric_exists: not a_new implies metric_manager.has_metric (a_metric.name) do metric_notebook.select_item (new_metric_panel) if a_new then new_metric_panel.metric_selector.remove_selection new_metric_panel.load_metric_definition (a_metric, new_metric_panel.basic_metric_type, a_metric.unit, True) else new_metric_panel.metric_selector.select_metric (a_metric.name) end end go_to_result -- Go to result tab. local l_notebook: EV_NOTEBOOK do l_notebook := metric_notebook if l_notebook.selected_item /= detail_result_panel then l_notebook.select_item (detail_result_panel) end end load_metrics_and_display_error (a_force: BOOLEAN; a_msg: STRING_GENERAL) -- Load metrics if they are not already loaded. -- If `a_force' is True, load metrics even though they are already loaded. -- When loading metrics, `a_msg' will be displayed in a dialog. -- Error will be displayed if any. require a_msg_attached: a_msg /= Void not_a_msg_is_empty: not a_msg.is_empty do load_metrics (a_force, a_msg, develop_window) display_error_message end register_metric_result_for_display (a_metric: EB_METRIC; a_input: EB_METRIC_DOMAIN; a_value: DOUBLE; a_result: QL_DOMAIN; a_time: DATE_TIME; a_from_history: BOOLEAN; a_filtered: BOOLEAN) -- Register metric result for display. require a_metric_attached: a_metric /= Void a_input_attached: a_input /= Void a_time_attached: a_time /= Void do detail_result_panel.on_display_metric_value (a_metric, a_value, a_input, a_result, a_time, a_from_history, a_filtered) end register_archive_result_for_display (ref_archive, cur_archive: LIST [EB_METRIC_ARCHIVE_NODE]) -- Register metric archive for display. require archives_valid: not (ref_archive = Void and then cur_archive = Void) do detail_result_panel.on_display_archive_value (cur_archive, ref_archive) end store_metrics -- Store metrics. do metric_manager.store_userdefined_metrics display_error_message check_metric_validation (develop_window) metric_loaded_actions.call (Void) metric_manager.metric_loaded_actions.call (Void) end display_error_message -- Display error message from `metric_manager'. do if not metric_manager.is_exit_requested then if metric_manager.has_error then show_error_message (agent metric_manager.last_error, agent metric_manager.clear_last_error, develop_window.window) end end end set_focus -- Give the focus to the metrics. do end set_last_metric_value_historied (b: BOOLEAN) -- Set `last_metric_value_historied' with `b'. do last_metric_value_historied := b ensure last_metric_value_historied_set: last_metric_value_historied = b end feature -- Access widget: EV_VERTICAL_BOX -- Graphical object of `Current' metric_evaluation_panel: EB_METRIC_EVALUATION_PANEL -- Metric evaluation panel new_metric_panel: EB_NEW_METRIC_PANEL -- New metric panel detail_result_panel: EB_METRIC_RESULT_AREA -- Detailed result panel metric_archive_panel: EB_METRIC_ARCHIVE_PANEL -- Metric archive panel metric_history_panel: EB_METRIC_HISTORY_PANEL -- Metric history panel metric_notebook: EV_NOTEBOOK -- Notebook for metric tool panels send_metric_value_in_history_actions: ACTION_SEQUENCE [TUPLE [a_archive: EB_METRIC_ARCHIVE_NODE; a_panel: ANY]] -- Actions to be performed when last evalauted metric (stored in `a_archive') has been sent into history -- `a_panel' is the metric tool panel from which the sending request occurs. do if send_metric_value_in_history_actions_internal = Void then create send_metric_value_in_history_actions_internal end Result := send_metric_value_in_history_actions_internal -- Store metric archive history. if metric_manager.has_archive_been_loaded then metric_manager.store_archive_history end ensure result_attached: Result /= Void end feature {NONE} -- Memory management internal_recycle -- Remove all references to `Current', and leave `Current' in an -- unstable state, so that we know `Current' is not referenced any longer. do metric_evaluation_panel.recycle new_metric_panel.recycle metric_archive_panel.recycle detail_result_panel.recycle metric_history_panel.recycle metric_evaluation_panel := Void new_metric_panel := Void metric_archive_panel := Void detail_result_panel := Void metric_history_panel := Void uninstall_agents (metric_manager) if notify_project_loaded_agent /= Void then eiffel_project.manager.load_agents.prune_all (notify_project_loaded_agent) end eiffel_project.manager.close_agents.prune_all (notify_project_unloaded_agent) Precursor {EB_TOOL} end feature -- Status report is_metrics_loaded: BOOLEAN -- Have predefined and user-defined metrics been loaded from files? is_up_to_date: BOOLEAN -- Is interface of metric tool up-to-date? is_recompiled: BOOLEAN -- Has system been recompiled? is_eiffel_compiling: BOOLEAN -- Is eiffel compiling? do Result := metric_manager.is_eiffel_compiling end is_metric_evaluating: BOOLEAN -- Is metric being evaluated? do Result := metric_manager.is_metric_evaluating end is_archive_calculating: BOOLEAN -- Is metric archive being calculated? do Result := metric_manager.is_archive_calculating end is_project_loaded: BOOLEAN -- Is a project loaded? do Result := metric_manager.is_project_loaded end is_history_recalculation_running: BOOLEAN -- Is metric history recalculation running? do Result := metric_manager.is_history_recalculation_running end last_metric_value_historied: BOOLEAN -- Has last evaluated metric value been sent to history? is_ready: BOOLEAN -- Is Metrics tool ready? -- Ready means that a project is loaded and no compilation or metric calculation is undergoing, so a new metric calculation -- can start. do Result := is_project_loaded and then not (is_eiffel_compiling or is_metric_evaluating or is_archive_calculating or is_history_recalculation_running) end feature{NONE} -- Actions on_tab_change -- Action to be performed when selected tab changes local l_selected_index: INTEGER l_notebook: EV_NOTEBOOK i: INTEGER l_notebook_count: INTEGER do from l_notebook := metric_notebook l_selected_index := l_notebook.selected_item_index i := 1 l_notebook_count := l_notebook.count until i > l_notebook_count loop if attached {EB_METRIC_PANEL} (l_notebook [i]) as l_panel then if is_shown and then i = l_selected_index then l_panel.set_is_selected (True) l_panel.on_select else l_panel.set_is_selected (False) end else check is_panel: False end end i := i + 1 end end on_project_loaded -- Action to be performed when project loaded do on_tab_change project_load_actions.call (Void) end on_project_unloaded -- Action to be performed when project unloaded do project_unload_actions.call (Void) end on_compile_start -- Action to be performed when Eiffel compilation starts do compile_start_actions.call (Void) end on_compile_stop -- Action to be performed when Eiffel compilation stops do is_metric_validation_checked.put (False) compile_stop_actions.call (Void) end on_metric_evaluation_start (a_data: ANY) -- Action to be performed when metric evaluation starts -- `a_data' can be the metric tool panel from which metric evaluation starts. do metric_evaluation_start_actions.call ([a_data]) end on_metric_evaluation_stop (a_data: ANY) -- Action to be performed when metric evaluation stops -- `a_data' can be the metric tool panel from which metric evaluation stops. do set_last_metric_value_historied (False) metric_evaluation_stop_actions.call ([a_data]) end on_archive_calculation_start (a_data: ANY) -- Action to be performed when metric archive calculation starts -- `a_data' can be the metric tool panel from which metric archive calculation starts. do archive_calculation_start_actions.call ([a_data]) end on_archive_calculation_stop (a_data: ANY) -- Action to be performed when metric archive calculation stops -- `a_data' can be the metric tool panel from which metric archive calculation stops. do archive_calculation_stop_actions.call ([a_data]) end on_metric_loaded -- Action to be performed when metrics loaded in `metric_manager' do metric_loaded_actions.call (Void) end on_tab_droppable (a_pebble: ANY): BOOLEAN -- Function to decide if `a_pebble' can be dropped on a `metric_notebook' tab local l_tab_index: INTEGER do if attached {STONE} a_pebble then l_tab_index := metric_notebook.pointed_tab_index if l_tab_index > 0 then if metric_notebook.i_th (l_tab_index) = metric_evaluation_panel then Result := is_project_loaded and then not is_archive_calculating and then not is_metric_evaluating elseif metric_notebook.i_th (l_tab_index) = metric_archive_panel then Result := is_project_loaded and then not is_archive_calculating and then not is_metric_evaluating end end end end on_tab_dropped (a_pebble: ANY) -- Action called when `a_pebble' is dropped on `metric_notebook'. -- It will target current to `a_pebble'. local l_tab_index: INTEGER do if attached {STONE} a_pebble as l_stone then l_tab_index := metric_notebook.pointed_tab_index if l_tab_index > 0 then if attached {EB_METRIC_PANEL} metric_notebook.i_th (l_tab_index) as l_panel then l_panel.force_drop_stone (l_stone) else check is_panel: False end end end end end on_history_recalculation_start (a_data: ANY) -- Action to be performed when history recalculation starts -- `a_data' can be the metric tool panel from which history recalculation starts. do history_recalculation_start_actions.call ([a_data]) end on_history_recalculation_stop (a_data: ANY) -- Action to be performed when history recalculation stops -- `a_data' can be the metric tool panel from which history recalculation stops. do history_recalculation_stop_actions.call ([a_data]) end on_metric_renamed (a_old_name, a_new_name: STRING) -- Action to be performed when a metric with `a_old_name' has been renamed to `a_new_name'. do metric_renamed_actions.call ([a_old_name, a_new_name]) end feature{NONE} -- Implementation send_metric_value_in_history_actions_internal: like send_metric_value_in_history_actions; -- Implementation of `send_metric_value_in_history_actions' notify_project_loaded -- Notify `metric_manager' that project has been loaded. do if not metric_manager.is_project_loaded then metric_manager.on_project_loaded end end notify_project_unloaded -- Notify `metric_manager' that project has been unloaded. do if metric_manager.is_project_loaded then metric_manager.on_project_unloaded end end notify_project_loaded_agent: PROCEDURE -- Agent of `notify_project_loaded' notify_project_unloaded_agent: PROCEDURE -- Agent of `notify_project_unloaded' feature{EB_METRIC_EVALUATION_PANEL} -- Title change is_tool_opened: BOOLEAN -- Is Current tool opened? do Result := content.is_visible end is_tool_visible: BOOLEAN -- Is Current tool visible? do Result := widget.is_displayed end set_title (a_result: STRING_GENERAL) -- Set title of Current tool. -- If `a_result' is not Void, display it on title. local l_name: STRING_32 do l_name := interface_names.t_metric_tool.as_string_32 if is_tool_opened and then not is_tool_visible then if a_result /= Void then l_name.append (ti_l_parenthesis.as_string_32) l_name.append (a_result.as_string_32) l_name.append (ti_r_parenthesis.as_string_32) end end content.set_short_title (l_name) end invariant notify_project_unloaded_agent_attached: notify_project_unloaded_agent /= Void note copyright: "Copyright (c) 1984-2021, Eiffel Software" license: "GPL version 2 (see http://www.eiffel.com/licensing/gpl.txt)" licensing_options: "http://www.eiffel.com/licensing" copying: "[ This file is part of Eiffel Software's Eiffel Development Environment. Eiffel Software's Eiffel Development Environment 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, version 2 of the License (available at the URL listed under "license" above). Eiffel Software's Eiffel Development Environment 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 Eiffel Software's Eiffel Development Environment; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ]" source: "[ Eiffel Software 5949 Hollister Ave., Goleta, CA 93117 USA Telephone 805-685-1006, Fax 805-685-6869 Website http://www.eiffel.com Customer support http://support.eiffel.com ]" end -- class EB_METRIC_TOOL