From 7e2a19c5bf730a8fc9c868be95b25cbfed61851c Mon Sep 17 00:00:00 2001 From: Thales Lima Oliveira Date: Wed, 8 Nov 2017 19:43:57 -0200 Subject: Documentation and translation updated --- docs/doxygen/html/_about_form_8cpp_source.html | 4 +- docs/doxygen/html/_about_form_8h_source.html | 2 +- docs/doxygen/html/_chart_view_8cpp_source.html | 2 +- docs/doxygen/html/_constant_8cpp_source.html | 13 +- docs/doxygen/html/_constant_8h.html | 2 +- docs/doxygen/html/_constant_8h_source.html | 14 +- docs/doxygen/html/_constant_form_8cpp_source.html | 2 +- docs/doxygen/html/_constant_form_8h_source.html | 2 +- docs/doxygen/html/_control_editor_8cpp_source.html | 9 +- docs/doxygen/html/_control_editor_8h.html | 3 +- docs/doxygen/html/_control_editor_8h.js | 3 +- docs/doxygen/html/_control_editor_8h_source.html | 10 +- docs/doxygen/html/_control_element_8h_source.html | 3 +- .../_control_element_container_8cpp_source.html | 6 +- .../html/_control_element_container_8h.html | 1 + .../html/_control_element_container_8h_source.html | 7 +- .../html/_control_element_solver_8cpp_source.html | 9 +- .../html/_control_element_solver_8h_source.html | 7 +- .../html/_control_system_test_8cpp_source.html | 2 +- .../html/_control_system_test_8h_source.html | 2 +- docs/doxygen/html/_divider_8cpp_source.html | 111 ++++ docs/doxygen/html/_divider_8h.html | 115 ++++ docs/doxygen/html/_divider_8h_source.html | 109 ++++ .../html/_electric_calculation_8cpp_source.html | 2 +- .../html/_electromechanical_8cpp_source.html | 4 +- .../doxygen/html/_electromechanical_8h_source.html | 2 +- docs/doxygen/html/_element_8cpp_source.html | 2 +- .../html/_element_data_object_8cpp_source.html | 2 +- docs/doxygen/html/_element_form_8cpp_source.html | 2 +- docs/doxygen/html/_element_form_8h_source.html | 24 +- .../html/_element_plot_data_8cpp_source.html | 2 +- .../html/_exponential_form_8cpp_source.html | 2 +- docs/doxygen/html/_exponential_form_8h_source.html | 2 +- docs/doxygen/html/_file_handing_8cpp_source.html | 15 +- docs/doxygen/html/_file_handing_8h_source.html | 4 +- docs/doxygen/html/_formulas.tex | 8 - docs/doxygen/html/_gain_8cpp_source.html | 15 +- docs/doxygen/html/_gain_8h.html | 2 +- docs/doxygen/html/_gain_8h_source.html | 16 +- docs/doxygen/html/_gain_form_8cpp_source.html | 2 +- docs/doxygen/html/_gain_form_8h_source.html | 2 +- .../html/_general_properties_form_8cpp_source.html | 2 +- .../html/_general_properties_form_8h_source.html | 2 +- .../html/_generator_stab_form_8cpp_source.html | 6 +- .../html/_generator_stab_form_8h_source.html | 4 +- docs/doxygen/html/_i_o_control_8cpp_source.html | 9 +- docs/doxygen/html/_i_o_control_8h.html | 2 +- docs/doxygen/html/_i_o_control_8h_source.html | 14 +- .../html/_i_o_control_form_8cpp_source.html | 2 +- docs/doxygen/html/_i_o_control_form_8h_source.html | 2 +- docs/doxygen/html/_ind_motor_form_8cpp_source.html | 2 +- docs/doxygen/html/_ind_motor_form_8h_source.html | 2 +- docs/doxygen/html/_limiter_form_8cpp_source.html | 2 +- docs/doxygen/html/_limiter_form_8h_source.html | 2 +- docs/doxygen/html/_line_8cpp_source.html | 2 +- docs/doxygen/html/_load_8cpp_source.html | 6 +- docs/doxygen/html/_load_8h_source.html | 5 +- docs/doxygen/html/_load_form_8cpp_source.html | 5 +- docs/doxygen/html/_load_form_8h_source.html | 4 +- docs/doxygen/html/_machines_8h_source.html | 2 +- docs/doxygen/html/_main_frame_8cpp_source.html | 6 +- docs/doxygen/html/_main_frame_8h.html | 1 + docs/doxygen/html/_main_frame_8h_source.html | 6 +- docs/doxygen/html/_math_operation_8cpp_source.html | 109 ++++ docs/doxygen/html/_math_operation_8h.html | 115 ++++ docs/doxygen/html/_math_operation_8h_source.html | 113 ++++ docs/doxygen/html/_multiplier_8cpp_source.html | 9 +- docs/doxygen/html/_multiplier_8h.html | 2 +- docs/doxygen/html/_multiplier_8h_source.html | 13 +- docs/doxygen/html/_open_g_l_text_8cpp_source.html | 105 +++ docs/doxygen/html/_open_g_l_text_8h.html | 116 ++++ docs/doxygen/html/_open_g_l_text_8h_source.html | 104 +++ docs/doxygen/html/_power_flow_8cpp_source.html | 2 +- docs/doxygen/html/_properties_data_8h_source.html | 4 +- .../doxygen/html/_properties_form_8cpp_source.html | 2 +- docs/doxygen/html/_properties_form_8h_source.html | 4 +- .../html/_properties_form_bitmaps_8cpp_source.html | 2 +- .../html/_rate_limiter_form_8cpp_source.html | 2 +- .../doxygen/html/_rate_limiter_form_8h_source.html | 2 +- .../_reactive_shunt_element_form_8cpp_source.html | 2 +- .../_reactive_shunt_element_form_8h_source.html | 2 +- .../_simulations_settings_form_8cpp_source.html | 2 +- .../html/_simulations_settings_form_8h_source.html | 2 +- docs/doxygen/html/_sum_form_8cpp_source.html | 2 +- docs/doxygen/html/_sum_form_8h_source.html | 2 +- docs/doxygen/html/_switching_form_8cpp_source.html | 2 +- docs/doxygen/html/_switching_form_8h_source.html | 2 +- docs/doxygen/html/_sync_generator_8cpp_source.html | 2 +- docs/doxygen/html/_sync_generator_8h_source.html | 2 +- docs/doxygen/html/_sync_motor_8h_source.html | 2 +- docs/doxygen/html/_text_8cpp_source.html | 16 +- docs/doxygen/html/_text_8h.html | 6 +- docs/doxygen/html/_text_8h_source.html | 17 +- docs/doxygen/html/_text_form_8cpp_source.html | 6 +- docs/doxygen/html/_text_form_8h_source.html | 4 +- .../html/_transfer_function_8cpp_source.html | 17 +- docs/doxygen/html/_transfer_function_8h.html | 2 +- .../doxygen/html/_transfer_function_8h_source.html | 18 +- .../html/_transfer_function_form_8cpp_source.html | 2 +- .../html/_transfer_function_form_8h_source.html | 2 +- docs/doxygen/html/_workspace_8cpp_source.html | 14 +- docs/doxygen/html/_workspace_8h_source.html | 6 +- .../html/_workspace_bitmaps_8cpp_source.html | 2 +- docs/doxygen/html/annotated.html | 186 +++--- docs/doxygen/html/annotated_dup.js | 8 +- docs/doxygen/html/class_about_form_base.html | 2 +- .../html/class_connection_line-members.html | 2 +- docs/doxygen/html/class_connection_line.html | 6 +- docs/doxygen/html/class_constant-members.html | 133 ++-- docs/doxygen/html/class_constant.html | 55 +- docs/doxygen/html/class_constant.js | 5 +- docs/doxygen/html/class_constant_form_base.html | 2 +- .../doxygen/html/class_control_editor-members.html | 125 ++-- docs/doxygen/html/class_control_editor.html | 23 +- docs/doxygen/html/class_control_editor.js | 7 +- .../html/class_control_element-members.html | 2 +- docs/doxygen/html/class_control_element.html | 40 +- docs/doxygen/html/class_control_element.js | 2 +- docs/doxygen/html/class_control_element.png | Bin 2802 -> 2861 bytes .../doxygen/html/class_control_element_button.html | 2 +- .../class_control_element_container-members.html | 24 +- .../html/class_control_element_container.html | 8 +- .../html/class_control_element_container.js | 2 + .../html/class_control_element_solver-members.html | 48 +- .../doxygen/html/class_control_element_solver.html | 139 +++- docs/doxygen/html/class_control_element_solver.js | 38 +- docs/doxygen/html/class_divider-members.html | 222 +++++++ docs/doxygen/html/class_divider.html | 525 +++++++++++++++ docs/doxygen/html/class_divider.js | 8 + docs/doxygen/html/class_divider.png | Bin 0 -> 825 bytes .../html/class_electromechanical-members.html | 89 ++- docs/doxygen/html/class_electromechanical.html | 43 +- docs/doxygen/html/class_electromechanical.js | 13 +- docs/doxygen/html/class_element.html | 20 +- docs/doxygen/html/class_element.png | Bin 5530 -> 5601 bytes docs/doxygen/html/class_exponential-members.html | 2 +- docs/doxygen/html/class_exponential.html | 6 +- docs/doxygen/html/class_exponential_form_base.html | 2 +- docs/doxygen/html/class_gain-members.html | 135 ++-- docs/doxygen/html/class_gain.html | 59 +- docs/doxygen/html/class_gain.js | 5 +- docs/doxygen/html/class_gain_form_base.html | 2 +- docs/doxygen/html/class_i_o_control-members.html | 48 +- docs/doxygen/html/class_i_o_control.html | 63 +- docs/doxygen/html/class_i_o_control.js | 12 +- docs/doxygen/html/class_i_o_control_form_base.html | 2 +- docs/doxygen/html/class_ind_motor_form_base.html | 2 +- docs/doxygen/html/class_limiter-members.html | 2 +- docs/doxygen/html/class_limiter.html | 6 +- docs/doxygen/html/class_limiter_form_base.html | 2 +- docs/doxygen/html/class_load-members.html | 2 +- docs/doxygen/html/class_load.html | 47 +- docs/doxygen/html/class_load.js | 1 + docs/doxygen/html/class_load_form-members.html | 84 ++- docs/doxygen/html/class_load_form.html | 132 ++++ docs/doxygen/html/class_load_form.js | 2 + .../doxygen/html/class_load_form_base-members.html | 81 ++- docs/doxygen/html/class_load_form_base.html | 129 ++++ docs/doxygen/html/class_load_form_base.js | 45 +- docs/doxygen/html/class_main_frame-members.html | 85 +-- docs/doxygen/html/class_main_frame.html | 5 +- docs/doxygen/html/class_main_frame.js | 1 + .../doxygen/html/class_math_operation-members.html | 220 +++++++ docs/doxygen/html/class_math_operation.html | 703 +++++++++++++++++++++ docs/doxygen/html/class_math_operation.js | 12 + docs/doxygen/html/class_math_operation.png | Bin 0 -> 1145 bytes docs/doxygen/html/class_multiplier-members.html | 121 ++-- docs/doxygen/html/class_multiplier.html | 265 +------- docs/doxygen/html/class_multiplier.js | 9 +- docs/doxygen/html/class_multiplier.png | Bin 627 -> 846 bytes docs/doxygen/html/class_open_g_l_text-members.html | 125 ++++ docs/doxygen/html/class_open_g_l_text.html | 187 ++++++ docs/doxygen/html/class_open_g_l_text.js | 23 + docs/doxygen/html/class_power_element.html | 2 +- docs/doxygen/html/class_properties_data.html | 2 +- docs/doxygen/html/class_rate_limiter-members.html | 2 +- docs/doxygen/html/class_rate_limiter.html | 6 +- .../doxygen/html/class_rate_limiter_form_base.html | 2 +- .../class_reactive_shunt_element_form_base.html | 2 +- .../class_simulations_settings_form-members.html | 140 ++-- .../html/class_simulations_settings_form.html | 168 +++++ .../html/class_simulations_settings_form.js | 2 + ...ass_simulations_settings_form_base-members.html | 137 ++-- .../html/class_simulations_settings_form_base.html | 165 +++++ .../html/class_simulations_settings_form_base.js | 57 +- docs/doxygen/html/class_sum-members.html | 2 +- docs/doxygen/html/class_sum.html | 6 +- docs/doxygen/html/class_sum_form_base.html | 2 +- docs/doxygen/html/class_switching_form_base.html | 2 +- docs/doxygen/html/class_text-members.html | 99 ++- docs/doxygen/html/class_text.html | 35 +- docs/doxygen/html/class_text.js | 7 +- docs/doxygen/html/class_text_form_base.html | 2 +- .../html/class_text_g_l_drawable-members.html | 134 ---- docs/doxygen/html/class_text_g_l_drawable.html | 384 ----------- docs/doxygen/html/class_text_g_l_drawable.js | 32 - docs/doxygen/html/class_text_g_l_drawable.png | Bin 879 -> 0 bytes docs/doxygen/html/class_text_texture-members.html | 113 ---- docs/doxygen/html/class_text_texture.html | 138 ---- docs/doxygen/html/class_text_texture.js | 11 - .../html/class_transfer_function-members.html | 6 +- docs/doxygen/html/class_transfer_function.html | 62 +- docs/doxygen/html/class_transfer_function.js | 6 +- .../html/class_transfer_function_form_base.html | 2 +- docs/doxygen/html/class_workspace-members.html | 165 ++--- docs/doxygen/html/class_workspace.html | 15 +- docs/doxygen/html/class_workspace.js | 5 +- docs/doxygen/html/classes.html | 84 +-- .../html/classwx_g_l_number_renderer-members.html | 148 ----- docs/doxygen/html/classwx_g_l_number_renderer.html | 389 ------------ docs/doxygen/html/classwx_g_l_number_renderer.js | 9 - docs/doxygen/html/classwx_g_l_number_renderer.png | Bin 1250 -> 0 bytes docs/doxygen/html/classwx_g_l_string-members.html | 144 ----- docs/doxygen/html/classwx_g_l_string.html | 416 ------------ docs/doxygen/html/classwx_g_l_string.js | 16 - docs/doxygen/html/classwx_g_l_string.png | Bin 1259 -> 0 bytes .../html/classwx_g_l_string_array-members.html | 113 ---- docs/doxygen/html/classwx_g_l_string_array.html | 294 --------- docs/doxygen/html/classwx_g_l_string_array.js | 11 - .../html/dir_ffd1f789ec7bd0a45fc6ad92579c5070.html | 6 + .../html/dir_ffd1f789ec7bd0a45fc6ad92579c5070.js | 16 +- docs/doxygen/html/files.html | 230 +++---- docs/doxygen/html/footerFile | 21 - docs/doxygen/html/footerFile.bak | 21 - docs/doxygen/html/functions.html | 3 - docs/doxygen/html/functions_b.html | 106 ---- docs/doxygen/html/functions_c.html | 7 +- docs/doxygen/html/functions_d.html | 2 +- docs/doxygen/html/functions_dup.js | 1 - docs/doxygen/html/functions_func.html | 3 - docs/doxygen/html/functions_func.js | 1 - docs/doxygen/html/functions_func_b.html | 106 ---- docs/doxygen/html/functions_func_c.html | 7 +- docs/doxygen/html/functions_func_d.html | 2 +- docs/doxygen/html/functions_func_g.html | 11 +- docs/doxygen/html/functions_func_i.html | 2 +- docs/doxygen/html/functions_func_o.html | 3 - docs/doxygen/html/functions_func_r.html | 15 +- docs/doxygen/html/functions_func_s.html | 12 +- docs/doxygen/html/functions_func_u.html | 7 + docs/doxygen/html/functions_func_w.html | 6 - docs/doxygen/html/functions_g.html | 11 +- docs/doxygen/html/functions_i.html | 2 +- docs/doxygen/html/functions_m.html | 5 +- docs/doxygen/html/functions_o.html | 3 - docs/doxygen/html/functions_r.html | 15 +- docs/doxygen/html/functions_s.html | 12 +- docs/doxygen/html/functions_u.html | 7 + docs/doxygen/html/functions_vars.html | 3 + docs/doxygen/html/functions_w.html | 6 - docs/doxygen/html/hierarchy.html | 164 +++-- docs/doxygen/html/hierarchy.js | 16 +- docs/doxygen/html/main_8cpp_source.html | 4 +- docs/doxygen/html/menudata.js | 2 - docs/doxygen/html/navtreedata.js | 28 +- docs/doxygen/html/navtreeindex0.js | 358 +++++------ docs/doxygen/html/navtreeindex1.js | 246 +++---- docs/doxygen/html/navtreeindex10.js | 500 +++++++-------- docs/doxygen/html/navtreeindex11.js | 500 +++++++-------- docs/doxygen/html/navtreeindex12.js | 498 +++++++-------- docs/doxygen/html/navtreeindex13.js | 500 +++++++-------- docs/doxygen/html/navtreeindex14.js | 152 ++++- docs/doxygen/html/navtreeindex2.js | 28 +- docs/doxygen/html/navtreeindex3.js | 182 +++--- docs/doxygen/html/navtreeindex4.js | 370 +++++------ docs/doxygen/html/navtreeindex5.js | 500 +++++++-------- docs/doxygen/html/navtreeindex6.js | 500 +++++++-------- docs/doxygen/html/navtreeindex7.js | 500 +++++++-------- docs/doxygen/html/navtreeindex8.js | 500 +++++++-------- docs/doxygen/html/navtreeindex9.js | 500 +++++++-------- docs/doxygen/html/search/all_0.js | 3 +- docs/doxygen/html/search/all_1.js | 1 - docs/doxygen/html/search/all_10.js | 2 - docs/doxygen/html/search/all_11.js | 3 +- docs/doxygen/html/search/all_12.js | 3 - docs/doxygen/html/search/all_2.js | 3 +- docs/doxygen/html/search/all_3.js | 4 +- docs/doxygen/html/search/all_6.js | 9 +- docs/doxygen/html/search/all_8.js | 2 +- docs/doxygen/html/search/all_a.js | 3 + docs/doxygen/html/search/all_c.js | 3 +- docs/doxygen/html/search/all_e.js | 4 +- docs/doxygen/html/search/all_f.js | 5 +- docs/doxygen/html/search/classes_10.js | 3 - docs/doxygen/html/search/classes_3.js | 3 +- docs/doxygen/html/search/classes_9.js | 1 + docs/doxygen/html/search/classes_b.js | 3 +- docs/doxygen/html/search/classes_f.js | 2 - docs/doxygen/html/search/files_3.js | 3 +- docs/doxygen/html/search/files_9.js | 1 + docs/doxygen/html/search/files_a.js | 4 +- docs/doxygen/html/search/files_b.js | 6 +- docs/doxygen/html/search/files_c.js | 11 +- docs/doxygen/html/search/files_d.js | 14 +- docs/doxygen/html/search/files_e.js | 7 +- docs/doxygen/html/search/files_f.html | 26 + docs/doxygen/html/search/files_f.js | 4 + docs/doxygen/html/search/functions_0.js | 3 +- docs/doxygen/html/search/functions_1.js | 5 +- docs/doxygen/html/search/functions_10.js | 9 +- docs/doxygen/html/search/functions_2.js | 15 +- docs/doxygen/html/search/functions_3.js | 12 +- docs/doxygen/html/search/functions_4.js | 3 +- docs/doxygen/html/search/functions_5.js | 33 +- docs/doxygen/html/search/functions_6.js | 34 +- docs/doxygen/html/search/functions_7.js | 8 +- docs/doxygen/html/search/functions_8.js | 11 +- docs/doxygen/html/search/functions_9.js | 5 +- docs/doxygen/html/search/functions_a.js | 2 +- docs/doxygen/html/search/functions_b.js | 5 +- docs/doxygen/html/search/functions_c.js | 15 +- docs/doxygen/html/search/functions_d.js | 36 +- docs/doxygen/html/search/functions_e.js | 30 +- docs/doxygen/html/search/functions_f.js | 5 +- docs/doxygen/html/search/searchdata.js | 4 +- docs/doxygen/html/search/variables_2.js | 3 +- docs/doxygen/html/struct_general_data.html | 2 +- .../html/struct_load_electrical_data-members.html | 26 +- docs/doxygen/html/struct_load_electrical_data.html | 66 ++ docs/doxygen/html/struct_load_electrical_data.js | 24 +- .../html/struct_simulation_data-members.html | 9 + docs/doxygen/html/struct_simulation_data.html | 31 +- docs/doxygen/html/struct_simulation_data.js | 11 +- docs/doxygen/html/wx_g_l_string_8cpp_source.html | 124 ---- docs/doxygen/html/wx_g_l_string_8h_source.html | 116 ---- 325 files changed, 9152 insertions(+), 7743 deletions(-) create mode 100644 docs/doxygen/html/_divider_8cpp_source.html create mode 100644 docs/doxygen/html/_divider_8h.html create mode 100644 docs/doxygen/html/_divider_8h_source.html delete mode 100644 docs/doxygen/html/_formulas.tex create mode 100644 docs/doxygen/html/_math_operation_8cpp_source.html create mode 100644 docs/doxygen/html/_math_operation_8h.html create mode 100644 docs/doxygen/html/_math_operation_8h_source.html create mode 100644 docs/doxygen/html/_open_g_l_text_8cpp_source.html create mode 100644 docs/doxygen/html/_open_g_l_text_8h.html create mode 100644 docs/doxygen/html/_open_g_l_text_8h_source.html create mode 100644 docs/doxygen/html/class_divider-members.html create mode 100644 docs/doxygen/html/class_divider.html create mode 100644 docs/doxygen/html/class_divider.js create mode 100644 docs/doxygen/html/class_divider.png create mode 100644 docs/doxygen/html/class_math_operation-members.html create mode 100644 docs/doxygen/html/class_math_operation.html create mode 100644 docs/doxygen/html/class_math_operation.js create mode 100644 docs/doxygen/html/class_math_operation.png create mode 100644 docs/doxygen/html/class_open_g_l_text-members.html create mode 100644 docs/doxygen/html/class_open_g_l_text.html create mode 100644 docs/doxygen/html/class_open_g_l_text.js delete mode 100644 docs/doxygen/html/class_text_g_l_drawable-members.html delete mode 100644 docs/doxygen/html/class_text_g_l_drawable.html delete mode 100644 docs/doxygen/html/class_text_g_l_drawable.js delete mode 100644 docs/doxygen/html/class_text_g_l_drawable.png delete mode 100644 docs/doxygen/html/class_text_texture-members.html delete mode 100644 docs/doxygen/html/class_text_texture.html delete mode 100644 docs/doxygen/html/class_text_texture.js delete mode 100644 docs/doxygen/html/classwx_g_l_number_renderer-members.html delete mode 100644 docs/doxygen/html/classwx_g_l_number_renderer.html delete mode 100644 docs/doxygen/html/classwx_g_l_number_renderer.js delete mode 100644 docs/doxygen/html/classwx_g_l_number_renderer.png delete mode 100644 docs/doxygen/html/classwx_g_l_string-members.html delete mode 100644 docs/doxygen/html/classwx_g_l_string.html delete mode 100644 docs/doxygen/html/classwx_g_l_string.js delete mode 100644 docs/doxygen/html/classwx_g_l_string.png delete mode 100644 docs/doxygen/html/classwx_g_l_string_array-members.html delete mode 100644 docs/doxygen/html/classwx_g_l_string_array.html delete mode 100644 docs/doxygen/html/classwx_g_l_string_array.js delete mode 100644 docs/doxygen/html/footerFile delete mode 100644 docs/doxygen/html/footerFile.bak delete mode 100644 docs/doxygen/html/functions_b.html delete mode 100644 docs/doxygen/html/functions_func_b.html create mode 100644 docs/doxygen/html/search/files_f.html create mode 100644 docs/doxygen/html/search/files_f.js delete mode 100644 docs/doxygen/html/wx_g_l_string_8cpp_source.html delete mode 100644 docs/doxygen/html/wx_g_l_string_8h_source.html (limited to 'docs/doxygen/html') diff --git a/docs/doxygen/html/_about_form_8cpp_source.html b/docs/doxygen/html/_about_form_8cpp_source.html index 54c7a2f..252b47f 100644 --- a/docs/doxygen/html/_about_form_8cpp_source.html +++ b/docs/doxygen/html/_about_form_8cpp_source.html @@ -88,8 +88,8 @@ $(document).ready(function(){initNavTree('_about_form_8cpp_source.html','');});
AboutForm.cpp
-
1 /*
2  * Copyright (C) 2017 Thales Lima Oliveira <thales@ufu.br>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program. If not, see <https://www.gnu.org/licenses/>.
16  */
17 
18 #include "AboutForm.h"
19 
20 AboutForm::AboutForm(wxWindow* parent) : AboutFormBase(parent) { Init(); }
21 AboutForm::~AboutForm() {}
22 void AboutForm::Init()
23 {
24  // Create developers table
25  m_gridCredits->EnableGridLines(false);
26  wxFont headerFont = m_gridCredits->GetDefaultCellFont();
27  headerFont.SetWeight(wxFONTWEIGHT_BOLD);
28  headerFont.SetPointSize(headerFont.GetPointSize() + 1);
29  wxColour headerColour(200, 200, 200);
30  wxColour hyperlinkColour(6, 69, 173);
31 
32  m_gridCredits->AppendCols(3);
33  m_gridCredits->AppendRows(6);
34  m_gridCredits->HideColLabels();
35  m_gridCredits->HideRowLabels();
36  m_gridCredits->SetCellSize(0, 0, 1, 3);
37  m_gridCredits->SetCellSize(3, 0, 1, 3);
38 
39  m_gridCredits->SetCellValue(0, 0, _("Developers"));
40  m_gridCredits->SetCellAlignment(0, 0, wxALIGN_CENTRE, wxALIGN_CENTRE);
41  m_gridCredits->SetCellBackgroundColour(0, 0, headerColour);
42  m_gridCredits->SetCellFont(0, 0, headerFont);
43  m_gridCredits->SetCellValue(1, 0, wxT("Thales Lima Oliveira"));
44  m_gridCredits->SetCellValue(1, 1, _("Main developer and project admin"));
45  m_gridCredits->SetCellValue(1, 2, wxT("thales@ufu.br"));
46 
47  m_gridCredits->SetRowMinimalHeight(2, 30);
48 
49  m_gridCredits->SetCellValue(3, 0, _("Contributors / Special Thanks"));
50  m_gridCredits->SetCellAlignment(3, 0, wxALIGN_CENTRE, wxALIGN_CENTRE);
51  m_gridCredits->SetCellBackgroundColour(3, 0, headerColour);
52  m_gridCredits->SetCellFont(3, 0, headerFont);
53  // Caixeta
54  m_gridCredits->SetCellValue(4, 0, wxT("Geraldo Caixeta Guimar") + static_cast<wxString>(L'\u00E3') + wxT("es"));
55  m_gridCredits->SetCellValue(4, 1, _("Chief advisor"));
56  m_gridCredits->SetCellValue(4, 2, wxT("gcaixeta@ufu.br"));
57  // Marcio Tamashiro
58  m_gridCredits->SetCellValue(5, 0, wxT("M") + static_cast<wxString>(L'\u00E1') + wxT("rcio Augusto Tamashiro"));
59  m_gridCredits->SetCellValue(5, 1, "");
60  m_gridCredits->SetCellValue(5, 2, wxT("tamashiro@ifto.edu.br"));
61 
62  for(int i = 0; i < m_gridCredits->GetNumberRows(); ++i) {
63  m_gridCredits->SetCellTextColour(i, 2, hyperlinkColour);
64  }
65 
66  m_gridCredits->AutoSize();
67 
68  // Last col size
69  int lastColSize = m_notebook->GetPage(1)->GetSize().GetWidth();
70  int lastColNumber = m_gridCredits->GetNumberCols() - 1;
71  for(int i = 0; i < lastColNumber; ++i) {
72  lastColSize -= m_gridCredits->GetColSize(i);
73  }
74  m_gridCredits->SetColSize(lastColNumber, lastColSize);
75  m_gridCredits->SetSize(m_notebook->GetPage(1)->GetSize());
76 
77  // Load license file
78  wxString licenseStr = "";
79  wxTextFile file;
80  wxFileName fn(wxStandardPaths::Get().GetExecutablePath());
81  wxString licensePath = fn.GetPath() + "\\..\\data\\LICENSE";
82  if(!file.Open(licensePath)) {
83  // Error message
84  } else {
85  licenseStr += file.GetFirstLine() + "\n";
86  while(!file.Eof()) {
87  licenseStr += file.GetNextLine() + "\n";
88  }
89  }
90  wxFont font = m_richTextCtrlLicense->GetFont();
91  font.SetFamily(wxFONTFAMILY_TELETYPE);
92  m_richTextCtrlLicense->SetFont(font);
93  m_richTextCtrlLicense->SetEditable(false);
94  m_richTextCtrlLicense->AppendText(licenseStr);
95 }
- +
1 /*
2  * Copyright (C) 2017 Thales Lima Oliveira <thales@ufu.br>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program. If not, see <https://www.gnu.org/licenses/>.
16  */
17 
18 #include "AboutForm.h"
19 
20 AboutForm::AboutForm(wxWindow* parent) : AboutFormBase(parent) { Init(); }
21 AboutForm::~AboutForm() {}
22 void AboutForm::Init()
23 {
24  // Create developers table
25  m_gridCredits->EnableGridLines(false);
26  wxFont headerFont = m_gridCredits->GetDefaultCellFont();
27  headerFont.SetWeight(wxFONTWEIGHT_BOLD);
28  headerFont.SetPointSize(headerFont.GetPointSize() + 1);
29  wxColour headerColour(200, 200, 200);
30  wxColour hyperlinkColour(6, 69, 173);
31 
32  m_gridCredits->AppendCols(3);
33  m_gridCredits->AppendRows(6);
34  m_gridCredits->HideColLabels();
35  m_gridCredits->HideRowLabels();
36  m_gridCredits->SetCellSize(0, 0, 1, 3);
37  m_gridCredits->SetCellSize(3, 0, 1, 3);
38 
39  m_gridCredits->SetCellValue(0, 0, _("Developers"));
40  m_gridCredits->SetCellAlignment(0, 0, wxALIGN_CENTRE, wxALIGN_CENTRE);
41  m_gridCredits->SetCellBackgroundColour(0, 0, headerColour);
42  m_gridCredits->SetCellFont(0, 0, headerFont);
43  m_gridCredits->SetCellValue(1, 0, wxT("Thales Lima Oliveira"));
44  m_gridCredits->SetCellValue(1, 1, _("Main developer and project admin"));
45  m_gridCredits->SetCellValue(1, 2, wxT("thales@ufu.br"));
46 
47  m_gridCredits->SetRowMinimalHeight(2, 30);
48 
49  m_gridCredits->SetCellValue(3, 0, _("Contributors / Special Thanks"));
50  m_gridCredits->SetCellAlignment(3, 0, wxALIGN_CENTRE, wxALIGN_CENTRE);
51  m_gridCredits->SetCellBackgroundColour(3, 0, headerColour);
52  m_gridCredits->SetCellFont(3, 0, headerFont);
53  // Caixeta
54  m_gridCredits->SetCellValue(4, 0, wxT("Geraldo Caixeta Guimar") + static_cast<wxString>(L'\u00E3') + wxT("es"));
55  m_gridCredits->SetCellValue(4, 1, _("Chief advisor"));
56  m_gridCredits->SetCellValue(4, 2, wxT("gcaixeta@ufu.br"));
57  // Marcio Tamashiro
58  m_gridCredits->SetCellValue(5, 0, wxT("M") + static_cast<wxString>(L'\u00E1') + wxT("rcio Augusto Tamashiro"));
59  m_gridCredits->SetCellValue(5, 1, "");
60  m_gridCredits->SetCellValue(5, 2, wxT("tamashiro@ifto.edu.br"));
61 
62  for(int i = 0; i < m_gridCredits->GetNumberRows(); ++i) {
63  m_gridCredits->SetCellTextColour(i, 2, hyperlinkColour);
64  }
65 
66  m_gridCredits->AutoSize();
67 
68  // Last col size
69  int lastColSize = m_notebook->GetPage(1)->GetSize().GetWidth();
70  int lastColNumber = m_gridCredits->GetNumberCols() - 1;
71  for(int i = 0; i < lastColNumber; ++i) {
72  lastColSize -= m_gridCredits->GetColSize(i);
73  }
74  m_gridCredits->SetColSize(lastColNumber, lastColSize);
75  m_gridCredits->SetSize(m_notebook->GetPage(1)->GetSize());
76 
77  // Load license file
78  wxString licenseStr = "";
79  wxTextFile file;
80  wxFileName fn(wxStandardPaths::Get().GetExecutablePath());
81  wxString licensePath = fn.GetPath() + wxFileName::DirName("\\..\\data\\LICENSE", wxPATH_WIN).GetPath();
82  if(!file.Open(licensePath)) {
83  // Error message
84  } else {
85  licenseStr += file.GetFirstLine() + "\n";
86  while(!file.Eof()) {
87  licenseStr += file.GetNextLine() + "\n";
88  }
89  }
90  wxFont font = m_richTextCtrlLicense->GetFont();
91  font.SetFamily(wxFONTFAMILY_TELETYPE);
92  m_richTextCtrlLicense->SetFont(font);
93  m_richTextCtrlLicense->SetEditable(false);
94  m_richTextCtrlLicense->AppendText(licenseStr);
95 }
+
diff --git a/docs/doxygen/html/_about_form_8h_source.html b/docs/doxygen/html/_about_form_8h_source.html index b4b7f5b..9f7fec3 100644 --- a/docs/doxygen/html/_about_form_8h_source.html +++ b/docs/doxygen/html/_about_form_8h_source.html @@ -88,7 +88,7 @@ $(document).ready(function(){initNavTree('_about_form_8h_source.html','');});
AboutForm.h
-Go to the documentation of this file.
1 /*
2  * Copyright (C) 2017 Thales Lima Oliveira <thales@ufu.br>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program. If not, see <https://www.gnu.org/licenses/>.
16  */
17 
18 #ifndef ABOUTFORM_H
19 #define ABOUTFORM_H
20 #include "PropertiesForm.h"
21 
22 #include <wx/textfile.h>
23 #include <wx/stdpaths.h>
24 
32 class AboutForm : public AboutFormBase
33 {
34  public:
35  AboutForm(wxWindow* parent);
36  virtual ~AboutForm();
37  virtual void Init();
38 
39  protected:
40  virtual void OnOKButtonClick(wxCommandEvent& event) { EndModal(wxID_OK); };
41 };
42 #endif // ABOUTFORM_H
+Go to the documentation of this file.
1 /*
2  * Copyright (C) 2017 Thales Lima Oliveira <thales@ufu.br>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program. If not, see <https://www.gnu.org/licenses/>.
16  */
17 
18 #ifndef ABOUTFORM_H
19 #define ABOUTFORM_H
20 #include "PropertiesForm.h"
21 
22 #include <wx/textfile.h>
23 #include <wx/stdpaths.h>
24 
32 class AboutForm : public AboutFormBase
33 {
34  public:
35  AboutForm(wxWindow* parent);
36  virtual ~AboutForm();
37  virtual void Init();
38 
39  protected:
40  virtual void OnOKButtonClick(wxCommandEvent& event) { EndModal(wxID_OK); };
41 };
42 #endif // ABOUTFORM_H
Form to show some informations.
Definition: AboutForm.h:32
diff --git a/docs/doxygen/html/_chart_view_8cpp_source.html b/docs/doxygen/html/_chart_view_8cpp_source.html index 43c86f5..6521f7c 100644 --- a/docs/doxygen/html/_chart_view_8cpp_source.html +++ b/docs/doxygen/html/_chart_view_8cpp_source.html @@ -88,7 +88,7 @@ $(document).ready(function(){initNavTree('_chart_view_8cpp_source.html','');});
ChartView.cpp
-
1 /*
2  * Copyright (C) 2017 Thales Lima Oliveira <thales@ufu.br>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program. If not, see <https://www.gnu.org/licenses/>.
16  */
17 
18 #include "ChartView.h"
19 #include "ElementPlotData.h"
20 
21 ChartView::ChartView(wxWindow* parent, std::vector<ElementPlotData> epdList, std::vector<double> time)
22  : ChartViewBase(parent)
23 {
24  m_epdList = epdList;
25  m_time = time;
26  m_xAxisValues = time;
27 
28  m_menuItemShowGrid->Check(m_hideGrid ? false : true);
29  m_menuItemShowLabel->Check(m_showLeg);
30  m_menuItemShowCoordinates->Check(m_showCoords);
31  m_menuItemDarkTheme->Check(m_darkTheme);
32 
33  // Create color property.
34  m_pgPropColor = m_pgMgr->Insert(m_pgPropLineProp, 1, new wxColourProperty(_("Color")));
35  m_pgPropColor->SetEditor(wxT("ChoiceAndButton"));
36  m_pgPropColor->SetValue(static_cast<wxVariant>(*wxBLACK));
37 
38  // Set margins and axis limit to composed mode.
39  m_pgPropMargins->SetValue(wxT("<composed>"));
40  m_pgMgr->Collapse(m_pgPropMargins);
41  m_pgPropAxisLimit->SetValue(wxT("<composed>"));
42  m_pgMgr->Collapse(m_pgPropAxisLimit);
43 
44  // Add line type choices
45  m_pgProplineType->AddChoice(_("Solid"), wxPENSTYLE_SOLID);
46  m_pgProplineType->AddChoice(_("Dot"), wxPENSTYLE_DOT);
47  m_pgProplineType->AddChoice(_("Dash"), wxPENSTYLE_SHORT_DASH);
48  m_pgProplineType->AddChoice(_("Dot and dash"), wxPENSTYLE_DOT_DASH);
49  m_pgProplineType->AddChoice(_("Cross"), wxPENSTYLE_CROSS_HATCH);
50  m_pgProplineType->AddChoice(_("Driagonal cross"), wxPENSTYLE_CROSSDIAG_HATCH);
51 
52  SetMPWindow();
53  GetSizer()->Add(m_mpWindow, 1, wxEXPAND, WXC_FROM_DIP(5));
54  SetTreectrl();
55  Layout();
56  SetInitialSize();
57 
58  BuildColourList();
59 }
60 
61 ChartView::~ChartView() {}
62 void ChartView::SetMPWindow()
63 {
64  m_mpWindow = new mpWindow(this, wxID_ANY);
65 
66  m_mpWindow->SetDoubleBuffered(true);
67 
68  m_mpWindow->SetMargins(20, 10, 40, 60);
69  m_xaxis = new mpScaleX("", mpALIGN_BOTTOM, true);
70  m_yaxis = new mpScaleY("", mpALIGN_LEFT, true);
71  m_xaxis->SetDrawOutsideMargins(false);
72  m_yaxis->SetDrawOutsideMargins(false);
73  m_xaxis->SetTicks(m_hideGrid);
74  m_yaxis->SetTicks(m_hideGrid);
75 
76  m_leg = new mpInfoLegend(wxRect(200, 20, 40, 40), wxWHITE_BRUSH);
77  m_coords = new mpInfoCoords(wxRect(0, 0, 0, 0), wxWHITE_BRUSH);
78 
79  m_chartTitle = new mpText("", 50, 0);
80  wxFont chartTitleFont(12, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_BOLD);
81  m_chartTitle->SetFont(chartTitleFont);
82 
83  m_mpWindow->AddLayer(m_xaxis);
84  m_mpWindow->AddLayer(m_yaxis);
85  m_mpWindow->AddLayer(m_leg);
86  m_mpWindow->AddLayer(m_coords);
87  m_mpWindow->AddLayer(m_chartTitle);
88 
89  m_leg->SetVisible(m_showLeg);
90  m_coords->SetVisible(m_showCoords);
91 
92  m_mpWindow->EnableDoubleBuffer(true);
93  m_mpWindow->LockAspect(false);
94  Fit();
95 }
96 
97 void ChartView::SetTreectrl()
98 {
99  wxTreeItemId rootID = m_treeCtrl->AddRoot(wxT("root"));
100  m_treeTimeID = m_treeCtrl->AppendItem(rootID, _("Time"));
101  m_treeCtrl->SetItemTextColour(m_treeTimeID, *wxRED);
102 
103  bool firstElement[ElementPlotData::NUM_ELEMENTS];
104  for(int i = 0; i < ElementPlotData::NUM_ELEMENTS; ++i) firstElement[i] = true;
105 
106  wxString rootElementName[ElementPlotData::NUM_ELEMENTS];
107  rootElementName[ElementPlotData::CT_BUS] = _("Bus");
108  rootElementName[ElementPlotData::CT_IND_MOTOR] = _("Induction motor");
109  rootElementName[ElementPlotData::CT_LINE] = _("Line");
110  rootElementName[ElementPlotData::CT_LOAD] = _("Load");
111  rootElementName[ElementPlotData::CT_SHUNT_CAPACITOR] = _("Capacitor");
112  rootElementName[ElementPlotData::CT_SHUNT_INDUCTOR] = _("Inductor");
113  rootElementName[ElementPlotData::CT_SYNC_COMPENSATOR] = _("Synchronous compensator");
114  rootElementName[ElementPlotData::CT_SYNC_GENERATOR] = _("Synchronous generator");
115  rootElementName[ElementPlotData::CT_TRANSFORMER] = _("Transformer");
116  rootElementName[ElementPlotData::CT_TEST] = _("Test");
117 
118  wxTreeItemId rootItemID[ElementPlotData::NUM_ELEMENTS];
119 
120  for(auto it = m_epdList.begin(), itEnd = m_epdList.end(); it != itEnd; ++it) {
121  ElementPlotData data = *it;
122  ElementPlotData::CurveType curveType = data.GetCurveType();
123 
124  if(firstElement[curveType]) {
125  rootItemID[curveType] = m_treeCtrl->AppendItem(rootID, rootElementName[curveType]);
126  firstElement[curveType] = false;
127  }
128  wxTreeItemId itemID = m_treeCtrl->AppendItem(rootItemID[curveType], data.GetName());
129  for(int i = 0; i < data.GetElementDataNumber(); ++i) {
130  m_treeCtrl->AppendItem(itemID, data.GetDataName(i), -1, -1, data.GetPlotData(i));
131  }
132  }
133 }
134 
135 void ChartView::OnPropertyGridChange(wxPropertyGridEvent& event)
136 {
137  bool fit = false;
138 
139  if(m_treeCtrl->GetSelection()) {
140  if(PlotData* data = dynamic_cast<PlotData*>(m_treeCtrl->GetItemData(m_treeCtrl->GetSelection()))) {
141  if(event.GetPropertyName() == _("Draw")) {
142  bool isPlotting = m_pgPropDraw->GetValue();
143  data->SetPlot(isPlotting);
144  if(isPlotting) {
145  wxColour colour = GetNextColour();
146  data->SetColour(colour);
147  m_pgPropColor->SetValue(static_cast<wxVariant>(colour));
148  m_treeCtrl->SetItemBold(m_treeCtrl->GetSelection(), true);
149  } else {
150  m_treeCtrl->SetItemBold(m_treeCtrl->GetSelection(), false);
151  }
152  fit = true;
153  } else if(event.GetPropertyName() == _("Color")) {
154  wxColour colour;
155  colour << m_pgPropColor->GetValue();
156  data->SetColour(colour);
157  } else if(event.GetPropertyName() == _("Thickness")) {
158  data->SetThick(m_pgProplineThick->GetValue().GetInteger());
159  } else if(event.GetPropertyName() == _("Type")) {
160  data->SetPenType(static_cast<wxPenStyle>(m_pgProplineType->GetValue().GetInteger()));
161  } else if(event.GetPropertyName() == _("Axis")) {
162  int axis = m_pgProplineAxis->GetValue().GetInteger();
163  if(axis == 1) { // Y
164  // All lines to Y axis
165  AllToYAxis(m_treeCtrl->GetRootItem());
166  // curva selecionada para o eixo X
167  m_treeCtrl->SetItemTextColour(m_treeCtrl->GetSelection(), *wxRED);
168  m_xAxisValues = data->GetValues();
169  }
170  data->SetAxis(axis);
171  fit = true;
172  }
173  }
174  }
175 
176  if(event.GetPropertyName() == _("Margins")) {
177  m_mpWindow->SetMargins(m_pgPropMarginsUp->GetValue().GetLong(), m_pgPropMarginsRight->GetValue().GetLong(),
178  m_pgPropMarginsBot->GetValue().GetLong(), m_pgPropMarginsLeft->GetValue().GetLong());
179  m_mpWindow->UpdateAll();
180  }
181  if(event.GetPropertyName() == _("Axis limit")) {
182  m_mpWindow->Fit(m_pgPropXMin->GetValue().GetDouble(), m_pgPropXMax->GetValue().GetDouble(),
183  m_pgPropYMin->GetValue().GetDouble(), m_pgPropYMax->GetValue().GetDouble());
184  m_mpWindow->UpdateAll();
185  }
186  UpdatePlot(fit);
187 }
188 
189 void ChartView::OnMenuDarkThemeClick(wxCommandEvent& event)
190 {
191  m_darkTheme = event.IsChecked();
192  wxColour grey(96, 96, 96);
193 
194  if(m_darkTheme) {
195  m_mpWindow->SetColourTheme(*wxBLACK, *wxWHITE, grey);
196  m_leg->SetBrush(*wxBLACK_BRUSH);
197  m_coords->SetBrush(*wxBLACK_BRUSH);
198  } else {
199  m_mpWindow->SetColourTheme(*wxWHITE, *wxBLACK, grey);
200  m_leg->SetBrush(*wxWHITE_BRUSH);
201  m_coords->SetBrush(*wxWHITE_BRUSH);
202  }
203 
204  m_mpWindow->UpdateAll();
205 }
206 
207 void ChartView::OnMenuSaveImageClick(wxCommandEvent& event)
208 {
209  int x = m_mpWindow->GetScreenPosition().x;
210  int y = m_mpWindow->GetScreenPosition().y;
211  int width = m_mpWindow->GetSize().GetWidth();
212  int height = m_mpWindow->GetSize().GetHeight();
213 
214  wxScreenDC dcScreen;
215  wxBitmap screenshot(width, height);
216 
217  wxMemoryDC memDC;
218  memDC.SelectObject(screenshot);
219 
220  memDC.Blit(0, 0, width, height, &dcScreen, x, y);
221  memDC.SelectObject(wxNullBitmap);
222 
223  wxFileDialog saveFileDialog(
224  this, _("Save image"), "", "",
225  "PNG image file (*.png)|*.png|Bitmap image file (*.bmp)|*.bmp|JPEG image file (*.jpg)|*.jpg",
226  wxFD_SAVE | wxFD_OVERWRITE_PROMPT);
227  if(saveFileDialog.ShowModal() == wxID_CANCEL) return;
228 
229  wxFileName imagePath(saveFileDialog.GetPath());
230  wxBitmapType imageType = wxBITMAP_TYPE_BMP;
231 
232  if(imagePath.GetExt() == "png")
233  imageType = wxBITMAP_TYPE_PNG;
234  else if(imagePath.GetExt() == "jpg")
235  imageType = wxBITMAP_TYPE_JPEG;
236 
237  screenshot.SaveFile(imagePath.GetFullPath(), imageType);
238 }
239 
240 void ChartView::OnMenuSendClipClick(wxCommandEvent& event)
241 {
242  int x = m_mpWindow->GetScreenPosition().x;
243  int y = m_mpWindow->GetScreenPosition().y;
244  int width = m_mpWindow->GetSize().GetWidth();
245  int height = m_mpWindow->GetSize().GetHeight();
246 
247  wxScreenDC dcScreen;
248  wxBitmap screenshot(width, height);
249 
250  wxMemoryDC memDC;
251  memDC.SelectObject(screenshot);
252 
253  memDC.Blit(0, 0, width, height, &dcScreen, x, y);
254  memDC.SelectObject(wxNullBitmap);
255 
256  if(wxTheClipboard->Open()) {
257  wxTheClipboard->SetData(new wxBitmapDataObject(screenshot));
258  wxTheClipboard->Close();
259 
260  wxMessageDialog msgDialog(this, _("Chart send to clipboard"), _("Info"), wxOK | wxICON_INFORMATION,
261  wxDefaultPosition);
262  msgDialog.ShowModal();
263  } else {
264  wxMessageDialog msgDialog(this, _("It was not possible to send to clipboard"), _("Error"), wxOK | wxICON_ERROR,
265  wxDefaultPosition);
266  msgDialog.ShowModal();
267  }
268 }
269 
270 void ChartView::OnMenuShowCoordinatesClick(wxCommandEvent& event)
271 {
272  m_showCoords = event.IsChecked();
273  m_coords->SetVisible(m_showCoords);
274  m_mpWindow->UpdateAll();
275 }
276 
277 void ChartView::OnMenuShowGridClick(wxCommandEvent& event)
278 {
279  m_hideGrid = event.IsChecked() ? false : true;
280  m_xaxis->SetTicks(m_hideGrid);
281  m_yaxis->SetTicks(m_hideGrid);
282  m_mpWindow->UpdateAll();
283 }
284 
285 void ChartView::OnMenuShowLabelClick(wxCommandEvent& event)
286 {
287  m_showLeg = event.IsChecked();
288  m_leg->SetVisible(m_showLeg);
289  m_mpWindow->UpdateAll();
290 }
291 
292 void ChartView::Fit()
293 {
294  m_mpWindow->Fit();
295  double bBox[4];
296  m_mpWindow->GetBoundingBox(bBox);
297 
298  m_pgPropXMin->SetValue(bBox[0]);
299  m_pgPropXMax->SetValue(bBox[1]);
300  m_pgPropYMin->SetValue(bBox[2]);
301  m_pgPropYMax->SetValue(bBox[3]);
302 }
303 
304 void ChartView::UpdatePlot(bool fit)
305 {
306  wxRect legRect = m_leg->GetRectangle();
307  wxRect coordsRect = m_coords->GetRectangle();
308  m_mpWindow->DelAllLayers(true, false);
309 
310  // GoAllTrees(treeCtrl_ChartSelection->GetRootItem());
311  UpdateAllPlots(m_treeCtrl->GetRootItem());
312 
313  m_xaxis = new mpScaleX(m_pgPropXLabel->GetValueAsString(), mpALIGN_BOTTOM, true);
314  m_yaxis = new mpScaleY(m_pgPropYLabel->GetValueAsString(), mpALIGN_LEFT, true);
315  m_leg = new mpInfoLegend(legRect, wxWHITE_BRUSH);
316  m_coords = new mpInfoCoords(coordsRect, wxWHITE_BRUSH);
317 
318  m_xaxis->SetDrawOutsideMargins(false);
319  m_yaxis->SetDrawOutsideMargins(false);
320  m_xaxis->SetTicks(m_hideGrid);
321  m_yaxis->SetTicks(m_hideGrid);
322 
323  mpText* chartTitle = new mpText(m_pgPropChartTitle->GetValueAsString(), 50, 0);
324  wxFont chartTitleFont(12, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_BOLD);
325  chartTitle->SetFont(chartTitleFont);
326 
327  m_mpWindow->AddLayer(m_xaxis);
328  m_mpWindow->AddLayer(m_yaxis);
329  m_mpWindow->AddLayer(m_leg);
330  m_mpWindow->AddLayer(m_coords);
331  m_mpWindow->AddLayer(chartTitle);
332 
333  m_leg->SetVisible(m_showLeg);
334  m_coords->SetVisible(m_showCoords);
335 
336  if(fit) Fit();
337 
338  wxColour grey(96, 96, 96);
339  if(m_darkTheme) {
340  m_mpWindow->SetColourTheme(*wxBLACK, *wxWHITE, grey);
341  m_leg->SetBrush(*wxBLACK_BRUSH);
342  m_coords->SetBrush(*wxBLACK_BRUSH);
343  } else {
344  m_mpWindow->SetColourTheme(*wxWHITE, *wxBLACK, grey);
345  m_leg->SetBrush(*wxWHITE_BRUSH);
346  m_coords->SetBrush(*wxWHITE_BRUSH);
347  }
348 }
349 
350 void ChartView::OnTreeItemActivated(wxTreeEvent& event)
351 {
352  if(PlotData* data = dynamic_cast<PlotData*>(m_treeCtrl->GetItemData(event.GetItem()))) {
353  bool isPlotting = data->IsPlot() ? false : true;
354  data->SetPlot(isPlotting);
355  m_pgPropDraw->SetValue(data->IsPlot());
356  if(isPlotting) {
357  wxColour colour = GetNextColour();
358  data->SetColour(colour);
359  m_pgPropColor->SetValue(static_cast<wxVariant>(colour));
360  m_treeCtrl->SetItemBold(m_treeCtrl->GetSelection(), true);
361  } else {
362  m_treeCtrl->SetItemBold(m_treeCtrl->GetSelection(), false);
363  }
364  UpdatePlot(true);
365  }
366 
367  if(event.GetItem() == m_treeTimeID) {
368  AllToYAxis(m_treeCtrl->GetRootItem());
369  m_treeCtrl->SetItemTextColour(m_treeTimeID, *wxRED);
370  m_xAxisValues = m_time;
371  UpdatePlot(true);
372  }
373 
374  event.Skip();
375 }
376 
377 void ChartView::OnTreeItemSelectionChanged(wxTreeEvent& event)
378 {
379  if(PlotData* data = dynamic_cast<PlotData*>(m_treeCtrl->GetItemData(event.GetItem()))) {
380  m_pgPropDraw->SetValue(data->IsPlot());
381  wxVariant colour;
382  colour << data->GetColour();
383  m_pgPropColor->SetValue(colour);
384  m_pgProplineThick->SetValue(data->GetThick());
385  m_pgProplineType->SetValue(data->GetPenType());
386  m_pgProplineAxis->SetValue(data->GetAxis());
387  }
388  event.Skip();
389 }
390 
391 void ChartView::BuildColourList()
392 {
393  m_colourList.push_back(wxColour(255, 0, 0));
394  m_colourList.push_back(wxColour(0, 0, 255));
395  m_colourList.push_back(wxColour(0, 255, 0));
396  m_colourList.push_back(wxColour(255, 128, 0));
397  m_colourList.push_back(wxColour(128, 0, 255));
398  m_colourList.push_back(wxColour(0, 255, 128));
399  m_colourList.push_back(wxColour(255, 255, 0));
400  m_colourList.push_back(wxColour(255, 0, 255));
401  m_colourList.push_back(wxColour(0, 255, 255));
402  m_colourList.push_back(wxColour(128, 255, 0));
403  m_colourList.push_back(wxColour(255, 0, 128));
404  m_colourList.push_back(wxColour(0, 128, 255));
405  m_colourList.push_back(wxColour(128, 128, 128));
406  m_colourList.push_back(*wxBLACK);
407  m_itColourList = --m_colourList.end();
408 }
409 
410 wxColour ChartView::GetNextColour()
411 {
412  if(*m_itColourList == *wxBLACK)
413  m_itColourList = m_colourList.begin();
414  else
415  ++m_itColourList;
416 
417  return *m_itColourList;
418 }
419 
420 wxTreeItemId ChartView::AllToYAxis(wxTreeItemId root)
421 {
422  wxTreeItemIdValue cookie;
423  wxTreeItemId item = m_treeCtrl->GetFirstChild(root, cookie);
424  wxTreeItemId child;
425 
426  while(item.IsOk()) {
427  m_treeCtrl->SetItemTextColour(item, *wxBLACK);
428  if(PlotData* data = dynamic_cast<PlotData*>(m_treeCtrl->GetItemData(item))) data->SetAxis(0); // X axis.
429 
430  if(m_treeCtrl->ItemHasChildren(item)) {
431  wxTreeItemId nextChild = AllToYAxis(item);
432  if(nextChild.IsOk()) return nextChild;
433  }
434  item = m_treeCtrl->GetNextChild(root, cookie);
435  }
436 
437  wxTreeItemId dummyID;
438  return dummyID;
439 }
440 
441 wxTreeItemId ChartView::UpdateAllPlots(wxTreeItemId root)
442 {
443  wxTreeItemIdValue cookie;
444  wxTreeItemId item = m_treeCtrl->GetFirstChild(root, cookie);
445  wxTreeItemId child;
446 
447  while(item.IsOk()) {
448  if(PlotData* data = dynamic_cast<PlotData*>(m_treeCtrl->GetItemData(item))) {
449  if(data->IsPlot()) {
450  wxString parentName = m_treeCtrl->GetItemText(m_treeCtrl->GetItemParent(item));
451  mpFXYVector* newLayer = new mpFXYVector(data->GetName() + " (" + parentName + ")");
452  newLayer->SetData(m_xAxisValues, data->GetValues());
453  newLayer->SetContinuity(true);
454  wxPen layerPen(data->GetColour(), data->GetThick(), data->GetPenType());
455  newLayer->SetPen(layerPen);
456  newLayer->SetDrawOutsideMargins(false);
457  newLayer->ShowName(false);
458 
459  m_mpWindow->AddLayer(newLayer);
460  }
461  }
462 
463  if(m_treeCtrl->ItemHasChildren(item)) {
464  wxTreeItemId nextChild = UpdateAllPlots(item);
465  if(nextChild.IsOk()) return nextChild;
466  }
467  item = m_treeCtrl->GetNextChild(root, cookie);
468  }
469 
470  wxTreeItemId dummyID;
471  return dummyID;
472 }
473 
474 void ChartView::OnMenuExpCSVClick(wxCommandEvent& event)
475 {
476  wxFileDialog saveFileDialog(this, _("Save CSV file"), "", "", "CSV file (*.csv)|*.csv",
477  wxFD_SAVE | wxFD_OVERWRITE_PROMPT);
478  if(saveFileDialog.ShowModal() == wxID_CANCEL) return;
479 
480  wxTextFile csvFile(saveFileDialog.GetPath());
481  if(!csvFile.Create()) {
482  if(!csvFile.Open()) {
483  wxMessageDialog msgDialog(this, _("It was not possible to open or create the selected file."), _("Error"),
484  wxOK | wxCENTRE | wxICON_ERROR);
485  msgDialog.ShowModal();
486  }
487  } else
488  csvFile.Open();
489  if(csvFile.IsOpened()) {
490  csvFile.Clear();
491  csvFile.AddLine(GetActiveCurvesCSV());
492  csvFile.Write();
493  csvFile.Close();
494  }
495 }
496 
497 wxString ChartView::GetActiveCurvesCSV()
498 {
499  std::vector<PlotData*> activePlotDataList;
500  GetActivePlotData(m_treeCtrl->GetRootItem(), activePlotDataList);
501 
502  std::vector<double> xValues;
503  wxString xName = "";
504 
505  // Find X axis curve, if none is found, X is the m_time.
506  bool foundXAxis = false;
507  for(auto it = activePlotDataList.begin(), itEnd = activePlotDataList.end(); it != itEnd; ++it) {
508  PlotData* data = *it;
509  if(data->GetAxis() == 1) {
510  xValues = data->GetValues();
511  xName = data->GetName();
512  foundXAxis = true;
513  activePlotDataList.erase(it);
514  delete data;
515  break;
516  }
517  }
518  if(!foundXAxis) {
519  xValues = m_time;
520  xName = _("Time");
521  }
522 
523  // Build CSV text.
524  wxString csvText = xName + ";";
525  // Header
526  for(auto it = activePlotDataList.begin(), itEnd = activePlotDataList.end(); it != itEnd; ++it) {
527  PlotData* data = *it;
528  csvText += data->GetName() + ";";
529  }
530  csvText[csvText.length() - 1] = '\n';
531  // Values
532  for(unsigned int i = 0; i < xValues.size(); ++i) {
533  csvText += wxString::FromCDouble(xValues[i], 13) + ";";
534  for(unsigned int j = 0; j < activePlotDataList.size(); ++j) {
535  double value = 0.0;
536  if(i < activePlotDataList[j]->GetValues().size()) {
537  value = activePlotDataList[j]->GetValues()[i];
538  }
539  csvText += wxString::FromCDouble(value, 13) + ";";
540  }
541  csvText[csvText.length() - 1] = '\n';
542  }
543 
544  // Clear active plot data vector.
545  for(auto it = activePlotDataList.begin(); it != activePlotDataList.end(); ++it) {
546  delete(*it);
547  }
548  activePlotDataList.clear();
549 
550  return csvText;
551 }
552 
553 wxTreeItemId ChartView::GetActivePlotData(wxTreeItemId root, std::vector<PlotData*>& plotDataList)
554 {
555  wxTreeItemIdValue cookie;
556  wxTreeItemId item = m_treeCtrl->GetFirstChild(root, cookie);
557  wxTreeItemId child;
558 
559  while(item.IsOk()) {
560  if(PlotData* data = dynamic_cast<PlotData*>(m_treeCtrl->GetItemData(item))) {
561  if(data->IsPlot() || data->GetAxis() == 1) {
562  wxString parentName = m_treeCtrl->GetItemText(m_treeCtrl->GetItemParent(item));
563 
564  PlotData* dataCopy = new PlotData();
565  *dataCopy = *data;
566  dataCopy->SetName(data->GetName() + " (" + parentName + ")");
567  plotDataList.push_back(dataCopy);
568  }
569  }
570 
571  if(m_treeCtrl->ItemHasChildren(item)) {
572  wxTreeItemId nextChild = GetActivePlotData(item, plotDataList);
573  if(nextChild.IsOk()) return nextChild;
574  }
575  item = m_treeCtrl->GetNextChild(root, cookie);
576  }
577 
578  wxTreeItemId dummyID;
579  return dummyID;
580 }
+
1 /*
2  * Copyright (C) 2017 Thales Lima Oliveira <thales@ufu.br>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program. If not, see <https://www.gnu.org/licenses/>.
16  */
17 
18 #include "ChartView.h"
19 #include "ElementPlotData.h"
20 
21 ChartView::ChartView(wxWindow* parent, std::vector<ElementPlotData> epdList, std::vector<double> time)
22  : ChartViewBase(parent)
23 {
24  m_epdList = epdList;
25  m_time = time;
26  m_xAxisValues = time;
27 
28  m_menuItemShowGrid->Check(m_hideGrid ? false : true);
29  m_menuItemShowLabel->Check(m_showLeg);
30  m_menuItemShowCoordinates->Check(m_showCoords);
31  m_menuItemDarkTheme->Check(m_darkTheme);
32 
33  // Create color property.
34  m_pgPropColor = m_pgMgr->Insert(m_pgPropLineProp, 1, new wxColourProperty(_("Color")));
35  m_pgPropColor->SetEditor(wxT("ChoiceAndButton"));
36  m_pgPropColor->SetValue(static_cast<wxVariant>(static_cast<wxAny>(*wxBLACK)));
37 
38  // Set margins and axis limit to composed mode.
39  m_pgPropMargins->SetValue(wxT("<composed>"));
40  m_pgMgr->Collapse(m_pgPropMargins);
41  m_pgPropAxisLimit->SetValue(wxT("<composed>"));
42  m_pgMgr->Collapse(m_pgPropAxisLimit);
43 
44  // Add line type choices
45  m_pgProplineType->AddChoice(_("Solid"), wxPENSTYLE_SOLID);
46  m_pgProplineType->AddChoice(_("Dot"), wxPENSTYLE_DOT);
47  m_pgProplineType->AddChoice(_("Dash"), wxPENSTYLE_SHORT_DASH);
48  m_pgProplineType->AddChoice(_("Dot and dash"), wxPENSTYLE_DOT_DASH);
49  m_pgProplineType->AddChoice(_("Cross"), wxPENSTYLE_CROSS_HATCH);
50  m_pgProplineType->AddChoice(_("Driagonal cross"), wxPENSTYLE_CROSSDIAG_HATCH);
51 
52  SetMPWindow();
53  GetSizer()->Add(m_mpWindow, 1, wxEXPAND, WXC_FROM_DIP(5));
54  SetTreectrl();
55  Layout();
56  SetInitialSize();
57 
58  BuildColourList();
59 }
60 
61 ChartView::~ChartView() {}
62 void ChartView::SetMPWindow()
63 {
64  m_mpWindow = new mpWindow(this, wxID_ANY);
65 
66  m_mpWindow->SetDoubleBuffered(true);
67 
68  m_mpWindow->SetMargins(20, 10, 40, 60);
69  m_xaxis = new mpScaleX("", mpALIGN_BOTTOM, true);
70  m_yaxis = new mpScaleY("", mpALIGN_LEFT, true);
71  m_xaxis->SetDrawOutsideMargins(false);
72  m_yaxis->SetDrawOutsideMargins(false);
73  m_xaxis->SetTicks(m_hideGrid);
74  m_yaxis->SetTicks(m_hideGrid);
75 
76  m_leg = new mpInfoLegend(wxRect(200, 20, 40, 40), wxWHITE_BRUSH);
77  m_coords = new mpInfoCoords(wxRect(0, 0, 0, 0), wxWHITE_BRUSH);
78 
79  m_chartTitle = new mpText("", 50, 0);
80  wxFont chartTitleFont(12, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_BOLD);
81  m_chartTitle->SetFont(chartTitleFont);
82 
83  m_mpWindow->AddLayer(m_xaxis);
84  m_mpWindow->AddLayer(m_yaxis);
85  m_mpWindow->AddLayer(m_leg);
86  m_mpWindow->AddLayer(m_coords);
87  m_mpWindow->AddLayer(m_chartTitle);
88 
89  m_leg->SetVisible(m_showLeg);
90  m_coords->SetVisible(m_showCoords);
91 
92  m_mpWindow->EnableDoubleBuffer(true);
93  m_mpWindow->LockAspect(false);
94  Fit();
95 }
96 
97 void ChartView::SetTreectrl()
98 {
99  wxTreeItemId rootID = m_treeCtrl->AddRoot(wxT("root"));
100  m_treeTimeID = m_treeCtrl->AppendItem(rootID, _("Time"));
101  m_treeCtrl->SetItemTextColour(m_treeTimeID, *wxRED);
102 
103  bool firstElement[ElementPlotData::NUM_ELEMENTS];
104  for(int i = 0; i < ElementPlotData::NUM_ELEMENTS; ++i) firstElement[i] = true;
105 
106  wxString rootElementName[ElementPlotData::NUM_ELEMENTS];
107  rootElementName[ElementPlotData::CT_BUS] = _("Bus");
108  rootElementName[ElementPlotData::CT_IND_MOTOR] = _("Induction motor");
109  rootElementName[ElementPlotData::CT_LINE] = _("Line");
110  rootElementName[ElementPlotData::CT_LOAD] = _("Load");
111  rootElementName[ElementPlotData::CT_SHUNT_CAPACITOR] = _("Capacitor");
112  rootElementName[ElementPlotData::CT_SHUNT_INDUCTOR] = _("Inductor");
113  rootElementName[ElementPlotData::CT_SYNC_COMPENSATOR] = _("Synchronous compensator");
114  rootElementName[ElementPlotData::CT_SYNC_GENERATOR] = _("Synchronous generator");
115  rootElementName[ElementPlotData::CT_TRANSFORMER] = _("Transformer");
116  rootElementName[ElementPlotData::CT_TEST] = _("Test");
117 
118  wxTreeItemId rootItemID[ElementPlotData::NUM_ELEMENTS];
119 
120  for(auto it = m_epdList.begin(), itEnd = m_epdList.end(); it != itEnd; ++it) {
121  ElementPlotData data = *it;
122  ElementPlotData::CurveType curveType = data.GetCurveType();
123 
124  if(firstElement[curveType]) {
125  rootItemID[curveType] = m_treeCtrl->AppendItem(rootID, rootElementName[curveType]);
126  firstElement[curveType] = false;
127  }
128  wxTreeItemId itemID = m_treeCtrl->AppendItem(rootItemID[curveType], data.GetName());
129  for(int i = 0; i < data.GetElementDataNumber(); ++i) {
130  m_treeCtrl->AppendItem(itemID, data.GetDataName(i), -1, -1, data.GetPlotData(i));
131  }
132  }
133 }
134 
135 void ChartView::OnPropertyGridChange(wxPropertyGridEvent& event)
136 {
137  bool fit = false;
138 
139  if(m_treeCtrl->GetSelection()) {
140  if(PlotData* data = dynamic_cast<PlotData*>(m_treeCtrl->GetItemData(m_treeCtrl->GetSelection()))) {
141  if(event.GetPropertyName() == _("Draw")) {
142  bool isPlotting = m_pgPropDraw->GetValue();
143  data->SetPlot(isPlotting);
144  if(isPlotting) {
145  wxColour colour = GetNextColour();
146  data->SetColour(colour);
147  m_pgPropColor->SetValue(static_cast<wxVariant>(static_cast<wxAny>(colour)));
148  m_treeCtrl->SetItemBold(m_treeCtrl->GetSelection(), true);
149  } else {
150  m_treeCtrl->SetItemBold(m_treeCtrl->GetSelection(), false);
151  }
152  fit = true;
153  } else if(event.GetPropertyName() == _("Color")) {
154  wxColour colour;
155  colour << m_pgPropColor->GetValue();
156  data->SetColour(colour);
157  } else if(event.GetPropertyName() == _("Thickness")) {
158  data->SetThick(m_pgProplineThick->GetValue().GetInteger());
159  } else if(event.GetPropertyName() == _("Type")) {
160  data->SetPenType(static_cast<wxPenStyle>(m_pgProplineType->GetValue().GetInteger()));
161  } else if(event.GetPropertyName() == _("Axis")) {
162  int axis = m_pgProplineAxis->GetValue().GetInteger();
163  if(axis == 1) { // Y
164  // All lines to Y axis
165  AllToYAxis(m_treeCtrl->GetRootItem());
166  // curva selecionada para o eixo X
167  m_treeCtrl->SetItemTextColour(m_treeCtrl->GetSelection(), *wxRED);
168  m_xAxisValues = data->GetValues();
169  }
170  data->SetAxis(axis);
171  fit = true;
172  }
173  }
174  }
175 
176  if(event.GetPropertyName() == _("Margins")) {
177  m_mpWindow->SetMargins(m_pgPropMarginsUp->GetValue().GetLong(), m_pgPropMarginsRight->GetValue().GetLong(),
178  m_pgPropMarginsBot->GetValue().GetLong(), m_pgPropMarginsLeft->GetValue().GetLong());
179  m_mpWindow->UpdateAll();
180  }
181  if(event.GetPropertyName() == _("Axis limit")) {
182  m_mpWindow->Fit(m_pgPropXMin->GetValue().GetDouble(), m_pgPropXMax->GetValue().GetDouble(),
183  m_pgPropYMin->GetValue().GetDouble(), m_pgPropYMax->GetValue().GetDouble());
184  m_mpWindow->UpdateAll();
185  }
186  UpdatePlot(fit);
187 }
188 
189 void ChartView::OnMenuDarkThemeClick(wxCommandEvent& event)
190 {
191  m_darkTheme = event.IsChecked();
192  wxColour grey(96, 96, 96);
193 
194  if(m_darkTheme) {
195  m_mpWindow->SetColourTheme(*wxBLACK, *wxWHITE, grey);
196  m_leg->SetBrush(*wxBLACK_BRUSH);
197  m_coords->SetBrush(*wxBLACK_BRUSH);
198  } else {
199  m_mpWindow->SetColourTheme(*wxWHITE, *wxBLACK, grey);
200  m_leg->SetBrush(*wxWHITE_BRUSH);
201  m_coords->SetBrush(*wxWHITE_BRUSH);
202  }
203 
204  m_mpWindow->UpdateAll();
205 }
206 
207 void ChartView::OnMenuSaveImageClick(wxCommandEvent& event)
208 {
209  int x = m_mpWindow->GetScreenPosition().x;
210  int y = m_mpWindow->GetScreenPosition().y;
211  int width = m_mpWindow->GetSize().GetWidth();
212  int height = m_mpWindow->GetSize().GetHeight();
213 
214  wxScreenDC dcScreen;
215  wxBitmap screenshot(width, height);
216 
217  wxMemoryDC memDC;
218  memDC.SelectObject(screenshot);
219 
220  memDC.Blit(0, 0, width, height, &dcScreen, x, y);
221  memDC.SelectObject(wxNullBitmap);
222 
223  wxFileDialog saveFileDialog(
224  this, _("Save image"), "", "",
225  "PNG image file (*.png)|*.png|Bitmap image file (*.bmp)|*.bmp|JPEG image file (*.jpg)|*.jpg",
226  wxFD_SAVE | wxFD_OVERWRITE_PROMPT);
227  if(saveFileDialog.ShowModal() == wxID_CANCEL) return;
228 
229  wxFileName imagePath(saveFileDialog.GetPath());
230  wxBitmapType imageType = wxBITMAP_TYPE_BMP;
231 
232  if(imagePath.GetExt() == "png")
233  imageType = wxBITMAP_TYPE_PNG;
234  else if(imagePath.GetExt() == "jpg")
235  imageType = wxBITMAP_TYPE_JPEG;
236 
237  screenshot.SaveFile(imagePath.GetFullPath(), imageType);
238 }
239 
240 void ChartView::OnMenuSendClipClick(wxCommandEvent& event)
241 {
242  int x = m_mpWindow->GetScreenPosition().x;
243  int y = m_mpWindow->GetScreenPosition().y;
244  int width = m_mpWindow->GetSize().GetWidth();
245  int height = m_mpWindow->GetSize().GetHeight();
246 
247  wxScreenDC dcScreen;
248  wxBitmap screenshot(width, height);
249 
250  wxMemoryDC memDC;
251  memDC.SelectObject(screenshot);
252 
253  memDC.Blit(0, 0, width, height, &dcScreen, x, y);
254  memDC.SelectObject(wxNullBitmap);
255 
256  if(wxTheClipboard->Open()) {
257  wxTheClipboard->SetData(new wxBitmapDataObject(screenshot));
258  wxTheClipboard->Close();
259 
260  wxMessageDialog msgDialog(this, _("Chart send to clipboard"), _("Info"), wxOK | wxICON_INFORMATION,
261  wxDefaultPosition);
262  msgDialog.ShowModal();
263  } else {
264  wxMessageDialog msgDialog(this, _("It was not possible to send to clipboard"), _("Error"), wxOK | wxICON_ERROR,
265  wxDefaultPosition);
266  msgDialog.ShowModal();
267  }
268 }
269 
270 void ChartView::OnMenuShowCoordinatesClick(wxCommandEvent& event)
271 {
272  m_showCoords = event.IsChecked();
273  m_coords->SetVisible(m_showCoords);
274  m_mpWindow->UpdateAll();
275 }
276 
277 void ChartView::OnMenuShowGridClick(wxCommandEvent& event)
278 {
279  m_hideGrid = event.IsChecked() ? false : true;
280  m_xaxis->SetTicks(m_hideGrid);
281  m_yaxis->SetTicks(m_hideGrid);
282  m_mpWindow->UpdateAll();
283 }
284 
285 void ChartView::OnMenuShowLabelClick(wxCommandEvent& event)
286 {
287  m_showLeg = event.IsChecked();
288  m_leg->SetVisible(m_showLeg);
289  m_mpWindow->UpdateAll();
290 }
291 
292 void ChartView::Fit()
293 {
294  m_mpWindow->Fit();
295  double bBox[4];
296  m_mpWindow->GetBoundingBox(bBox);
297 
298  m_pgPropXMin->SetValue(bBox[0]);
299  m_pgPropXMax->SetValue(bBox[1]);
300  m_pgPropYMin->SetValue(bBox[2]);
301  m_pgPropYMax->SetValue(bBox[3]);
302 }
303 
304 void ChartView::UpdatePlot(bool fit)
305 {
306  wxRect legRect = m_leg->GetRectangle();
307  wxRect coordsRect = m_coords->GetRectangle();
308  m_mpWindow->DelAllLayers(true, false);
309 
310  // GoAllTrees(treeCtrl_ChartSelection->GetRootItem());
311  UpdateAllPlots(m_treeCtrl->GetRootItem());
312 
313  m_xaxis = new mpScaleX(m_pgPropXLabel->GetValueAsString(), mpALIGN_BOTTOM, true);
314  m_yaxis = new mpScaleY(m_pgPropYLabel->GetValueAsString(), mpALIGN_LEFT, true);
315  m_leg = new mpInfoLegend(legRect, wxWHITE_BRUSH);
316  m_coords = new mpInfoCoords(coordsRect, wxWHITE_BRUSH);
317 
318  m_xaxis->SetDrawOutsideMargins(false);
319  m_yaxis->SetDrawOutsideMargins(false);
320  m_xaxis->SetTicks(m_hideGrid);
321  m_yaxis->SetTicks(m_hideGrid);
322 
323  mpText* chartTitle = new mpText(m_pgPropChartTitle->GetValueAsString(), 50, 0);
324  wxFont chartTitleFont(12, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_BOLD);
325  chartTitle->SetFont(chartTitleFont);
326 
327  m_mpWindow->AddLayer(m_xaxis);
328  m_mpWindow->AddLayer(m_yaxis);
329  m_mpWindow->AddLayer(m_leg);
330  m_mpWindow->AddLayer(m_coords);
331  m_mpWindow->AddLayer(chartTitle);
332 
333  m_leg->SetVisible(m_showLeg);
334  m_coords->SetVisible(m_showCoords);
335 
336  if(fit) Fit();
337 
338  wxColour grey(96, 96, 96);
339  if(m_darkTheme) {
340  m_mpWindow->SetColourTheme(*wxBLACK, *wxWHITE, grey);
341  m_leg->SetBrush(*wxBLACK_BRUSH);
342  m_coords->SetBrush(*wxBLACK_BRUSH);
343  } else {
344  m_mpWindow->SetColourTheme(*wxWHITE, *wxBLACK, grey);
345  m_leg->SetBrush(*wxWHITE_BRUSH);
346  m_coords->SetBrush(*wxWHITE_BRUSH);
347  }
348 }
349 
350 void ChartView::OnTreeItemActivated(wxTreeEvent& event)
351 {
352  if(PlotData* data = dynamic_cast<PlotData*>(m_treeCtrl->GetItemData(event.GetItem()))) {
353  bool isPlotting = data->IsPlot() ? false : true;
354  data->SetPlot(isPlotting);
355  m_pgPropDraw->SetValue(data->IsPlot());
356  if(isPlotting) {
357  wxColour colour = GetNextColour();
358  data->SetColour(colour);
359  m_pgPropColor->SetValue(static_cast<wxVariant>(static_cast<wxAny>(colour)));
360  m_treeCtrl->SetItemBold(m_treeCtrl->GetSelection(), true);
361  } else {
362  m_treeCtrl->SetItemBold(m_treeCtrl->GetSelection(), false);
363  }
364  UpdatePlot(true);
365  }
366 
367  if(event.GetItem() == m_treeTimeID) {
368  AllToYAxis(m_treeCtrl->GetRootItem());
369  m_treeCtrl->SetItemTextColour(m_treeTimeID, *wxRED);
370  m_xAxisValues = m_time;
371  UpdatePlot(true);
372  }
373 
374  event.Skip();
375 }
376 
377 void ChartView::OnTreeItemSelectionChanged(wxTreeEvent& event)
378 {
379  if(PlotData* data = dynamic_cast<PlotData*>(m_treeCtrl->GetItemData(event.GetItem()))) {
380  m_pgPropDraw->SetValue(data->IsPlot());
381  wxVariant colour;
382  colour << data->GetColour();
383  m_pgPropColor->SetValue(colour);
384  m_pgProplineThick->SetValue(data->GetThick());
385  m_pgProplineType->SetValue(data->GetPenType());
386  m_pgProplineAxis->SetValue(data->GetAxis());
387  }
388  event.Skip();
389 }
390 
391 void ChartView::BuildColourList()
392 {
393  m_colourList.push_back(wxColour(255, 0, 0));
394  m_colourList.push_back(wxColour(0, 0, 255));
395  m_colourList.push_back(wxColour(0, 255, 0));
396  m_colourList.push_back(wxColour(255, 128, 0));
397  m_colourList.push_back(wxColour(128, 0, 255));
398  m_colourList.push_back(wxColour(0, 255, 128));
399  m_colourList.push_back(wxColour(255, 255, 0));
400  m_colourList.push_back(wxColour(255, 0, 255));
401  m_colourList.push_back(wxColour(0, 255, 255));
402  m_colourList.push_back(wxColour(128, 255, 0));
403  m_colourList.push_back(wxColour(255, 0, 128));
404  m_colourList.push_back(wxColour(0, 128, 255));
405  m_colourList.push_back(wxColour(128, 128, 128));
406  m_colourList.push_back(*wxBLACK);
407  m_itColourList = --m_colourList.end();
408 }
409 
410 wxColour ChartView::GetNextColour()
411 {
412  if(*m_itColourList == *wxBLACK)
413  m_itColourList = m_colourList.begin();
414  else
415  ++m_itColourList;
416 
417  return *m_itColourList;
418 }
419 
420 wxTreeItemId ChartView::AllToYAxis(wxTreeItemId root)
421 {
422  wxTreeItemIdValue cookie;
423  wxTreeItemId item = m_treeCtrl->GetFirstChild(root, cookie);
424  wxTreeItemId child;
425 
426  while(item.IsOk()) {
427  m_treeCtrl->SetItemTextColour(item, *wxBLACK);
428  if(PlotData* data = dynamic_cast<PlotData*>(m_treeCtrl->GetItemData(item))) data->SetAxis(0); // X axis.
429 
430  if(m_treeCtrl->ItemHasChildren(item)) {
431  wxTreeItemId nextChild = AllToYAxis(item);
432  if(nextChild.IsOk()) return nextChild;
433  }
434  item = m_treeCtrl->GetNextChild(root, cookie);
435  }
436 
437  wxTreeItemId dummyID;
438  return dummyID;
439 }
440 
441 wxTreeItemId ChartView::UpdateAllPlots(wxTreeItemId root)
442 {
443  wxTreeItemIdValue cookie;
444  wxTreeItemId item = m_treeCtrl->GetFirstChild(root, cookie);
445  wxTreeItemId child;
446 
447  while(item.IsOk()) {
448  if(PlotData* data = dynamic_cast<PlotData*>(m_treeCtrl->GetItemData(item))) {
449  if(data->IsPlot()) {
450  wxString parentName = m_treeCtrl->GetItemText(m_treeCtrl->GetItemParent(item));
451  mpFXYVector* newLayer = new mpFXYVector(data->GetName() + " (" + parentName + ")");
452  newLayer->SetData(m_xAxisValues, data->GetValues());
453  newLayer->SetContinuity(true);
454  wxPen layerPen(data->GetColour(), data->GetThick(), data->GetPenType());
455  newLayer->SetPen(layerPen);
456  newLayer->SetDrawOutsideMargins(false);
457  newLayer->ShowName(false);
458 
459  m_mpWindow->AddLayer(newLayer);
460  }
461  }
462 
463  if(m_treeCtrl->ItemHasChildren(item)) {
464  wxTreeItemId nextChild = UpdateAllPlots(item);
465  if(nextChild.IsOk()) return nextChild;
466  }
467  item = m_treeCtrl->GetNextChild(root, cookie);
468  }
469 
470  wxTreeItemId dummyID;
471  return dummyID;
472 }
473 
474 void ChartView::OnMenuExpCSVClick(wxCommandEvent& event)
475 {
476  wxFileDialog saveFileDialog(this, _("Save CSV file"), "", "", "CSV file (*.csv)|*.csv",
477  wxFD_SAVE | wxFD_OVERWRITE_PROMPT);
478  if(saveFileDialog.ShowModal() == wxID_CANCEL) return;
479 
480  wxTextFile csvFile(saveFileDialog.GetPath());
481  if(!csvFile.Create()) {
482  if(!csvFile.Open()) {
483  wxMessageDialog msgDialog(this, _("It was not possible to open or create the selected file."), _("Error"),
484  wxOK | wxCENTRE | wxICON_ERROR);
485  msgDialog.ShowModal();
486  }
487  } else
488  csvFile.Open();
489  if(csvFile.IsOpened()) {
490  csvFile.Clear();
491  csvFile.AddLine(GetActiveCurvesCSV());
492  csvFile.Write();
493  csvFile.Close();
494  }
495 }
496 
497 wxString ChartView::GetActiveCurvesCSV()
498 {
499  std::vector<PlotData*> activePlotDataList;
500  GetActivePlotData(m_treeCtrl->GetRootItem(), activePlotDataList);
501 
502  std::vector<double> xValues;
503  wxString xName = "";
504 
505  // Find X axis curve, if none is found, X is the m_time.
506  bool foundXAxis = false;
507  for(auto it = activePlotDataList.begin(), itEnd = activePlotDataList.end(); it != itEnd; ++it) {
508  PlotData* data = *it;
509  if(data->GetAxis() == 1) {
510  xValues = data->GetValues();
511  xName = data->GetName();
512  foundXAxis = true;
513  activePlotDataList.erase(it);
514  delete data;
515  break;
516  }
517  }
518  if(!foundXAxis) {
519  xValues = m_time;
520  xName = _("Time");
521  }
522 
523  // Build CSV text.
524  wxString csvText = xName + ";";
525  // Header
526  for(auto it = activePlotDataList.begin(), itEnd = activePlotDataList.end(); it != itEnd; ++it) {
527  PlotData* data = *it;
528  csvText += data->GetName() + ";";
529  }
530  csvText[csvText.length() - 1] = '\n';
531  // Values
532  for(unsigned int i = 0; i < xValues.size(); ++i) {
533  csvText += wxString::FromCDouble(xValues[i], 13) + ";";
534  for(unsigned int j = 0; j < activePlotDataList.size(); ++j) {
535  double value = 0.0;
536  if(i < activePlotDataList[j]->GetValues().size()) {
537  value = activePlotDataList[j]->GetValues()[i];
538  }
539  csvText += wxString::FromCDouble(value, 13) + ";";
540  }
541  csvText[csvText.length() - 1] = '\n';
542  }
543 
544  // Clear active plot data vector.
545  for(auto it = activePlotDataList.begin(); it != activePlotDataList.end(); ++it) {
546  delete(*it);
547  }
548  activePlotDataList.clear();
549 
550  return csvText;
551 }
552 
553 wxTreeItemId ChartView::GetActivePlotData(wxTreeItemId root, std::vector<PlotData*>& plotDataList)
554 {
555  wxTreeItemIdValue cookie;
556  wxTreeItemId item = m_treeCtrl->GetFirstChild(root, cookie);
557  wxTreeItemId child;
558 
559  while(item.IsOk()) {
560  if(PlotData* data = dynamic_cast<PlotData*>(m_treeCtrl->GetItemData(item))) {
561  if(data->IsPlot() || data->GetAxis() == 1) {
562  wxString parentName = m_treeCtrl->GetItemText(m_treeCtrl->GetItemParent(item));
563 
564  PlotData* dataCopy = new PlotData();
565  *dataCopy = *data;
566  dataCopy->SetName(data->GetName() + " (" + parentName + ")");
567  plotDataList.push_back(dataCopy);
568  }
569  }
570 
571  if(m_treeCtrl->ItemHasChildren(item)) {
572  wxTreeItemId nextChild = GetActivePlotData(item, plotDataList);
573  if(nextChild.IsOk()) return nextChild;
574  }
575  item = m_treeCtrl->GetNextChild(root, cookie);
576  }
577 
578  wxTreeItemId dummyID;
579  return dummyID;
580 }
diff --git a/docs/doxygen/html/_constant_8cpp_source.html b/docs/doxygen/html/_constant_8cpp_source.html index 2329458..c3dda31 100644 --- a/docs/doxygen/html/_constant_8cpp_source.html +++ b/docs/doxygen/html/_constant_8cpp_source.html @@ -88,21 +88,22 @@ $(document).ready(function(){initNavTree('_constant_8cpp_source.html','');});
Constant.cpp
-
1 /*
2  * Copyright (C) 2017 Thales Lima Oliveira <thales@ufu.br>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program. If not, see <https://www.gnu.org/licenses/>.
16  */
17 
18 #include "Constant.h"
19 #include "ConstantForm.h"
20 
21 Constant::Constant(int id) : ControlElement(id)
22 {
23  SetValue(m_value);
24  m_angle = 180.0;
25  Node* nodeOut = new Node(m_position + wxPoint2DDouble(m_width / 2, 0), Node::NODE_OUT, m_borderSize);
26  nodeOut->SetAngle(180.0);
27  nodeOut->StartMove(m_position);
28  m_nodeList.push_back(nodeOut);
29 }
30 
31 Constant::~Constant() {}
32 void Constant::Draw(wxPoint2DDouble translation, double scale) const
33 {
34  glLineWidth(1.0);
35  if(m_selected) {
36  glColor4dv(m_selectionColour.GetRGBA());
37  double borderSize = (m_borderSize * 2.0 + 1.0) / scale;
38  DrawRectangle(m_position, m_width + borderSize, m_height + borderSize);
39  }
40  glColor4d(1.0, 1.0, 1.0, 1.0);
41  DrawRectangle(m_position, m_width, m_height);
42  glColor4d(0.0, 0.0, 0.0, 1.0);
43  DrawRectangle(m_position, m_width, m_height, GL_LINE_LOOP);
44 
45  // Plot number.
46  glEnable(GL_TEXTURE_2D);
47  glColor4d(0.0, 0.0, 0.0, 1.0);
48  m_glStringValue->bind();
49  m_glStringValue->render(m_position.m_x, m_position.m_y);
50  glDisable(GL_TEXTURE_2D);
51 
52  glColor4d(0.0, 0.0, 0.0, 1.0);
53  DrawNodes();
54 }
55 
56 bool Constant::ShowForm(wxWindow* parent, Element* element)
57 {
58  ConstantForm* form = new ConstantForm(parent, this);
59  if(form->ShowModal() == wxID_OK) {
60  form->Destroy();
61  return true;
62  }
63  form->Destroy();
64  return false;
65 }
66 
67 void Constant::Rotate(bool clockwise)
68 {
69  if(clockwise)
70  m_angle += 90.0;
71  else
72  m_angle -= 90.0;
73  if(m_angle >= 360.0)
74  m_angle = 0.0;
75  else if(m_angle < 0)
76  m_angle = 270.0;
77 
78  UpdatePoints();
79 
80  for(auto it = m_nodeList.begin(), itEnd = m_nodeList.end(); it != itEnd; ++it) {
81  Node* node = *it;
82  node->Rotate(clockwise);
83  }
84 }
85 
86 void Constant::UpdatePoints()
87 {
88  if(m_nodeList.size() != 0) {
89  if(m_angle == 0.0) {
90  m_nodeList[0]->SetPosition(m_position + wxPoint2DDouble(-m_width / 2, 0));
91  } else if(m_angle == 90.0) {
92  m_nodeList[0]->SetPosition(m_position + wxPoint2DDouble(0, -m_height / 2));
93  } else if(m_angle == 180.0) {
94  m_nodeList[0]->SetPosition(m_position + wxPoint2DDouble(m_width / 2, 0));
95  } else if(m_angle == 270.0) {
96  m_nodeList[0]->SetPosition(m_position + wxPoint2DDouble(0, m_height / 2));
97  }
98  }
99 }
100 
101 void Constant::SetValue(double value)
102 {
103  m_value = value;
104  wxString text = StringFromDouble(m_value);
105 
106  wxFont font(m_fontSize, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL);
107  wxScreenDC dc;
108 
109  if(m_glStringValue) {
110  delete m_glStringValue;
111  m_glStringValue = NULL;
112  }
113  m_glStringValue = new wxGLString(text);
114  m_glStringValue->setFont(font);
115  m_glStringValue->consolidate(&dc);
116 
117  m_width = m_glStringValue->getWidth() + 6 + 2 * m_borderSize;
118  m_height = m_glStringValue->getheight() + 6 + 2 * m_borderSize;
119 
120  UpdatePoints();
121 }
122 
124 {
125  Constant* copy = new Constant(m_elementID);
126  *copy = *this;
127  m_glStringValue = NULL;
128  SetValue(m_value);
129  return copy;
130 }
Base class of all elements of the program. This class is responsible for manage graphical and his dat...
Definition: Element.h:113
+
1 /*
2  * Copyright (C) 2017 Thales Lima Oliveira <thales@ufu.br>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program. If not, see <https://www.gnu.org/licenses/>.
16  */
17 
18 #include "Constant.h"
19 #include "ConstantForm.h"
20 
21 Constant::Constant(int id) : ControlElement(id)
22 {
23  SetValue(m_value);
24  m_angle = 180.0;
25  Node* nodeOut = new Node(m_position + wxPoint2DDouble(m_width / 2, 0), Node::NODE_OUT, m_borderSize);
26  nodeOut->SetAngle(180.0);
27  nodeOut->StartMove(m_position);
28  m_nodeList.push_back(nodeOut);
29 }
30 
31 Constant::~Constant()
32 {
33  if(m_glText) delete m_glText;
34 }
35 void Constant::Draw(wxPoint2DDouble translation, double scale) const
36 {
37  glLineWidth(1.0);
38  if(m_selected) {
39  glColor4dv(m_selectionColour.GetRGBA());
40  double borderSize = (m_borderSize * 2.0 + 1.0) / scale;
41  DrawRectangle(m_position, m_width + borderSize, m_height + borderSize);
42  }
43  glColor4d(1.0, 1.0, 1.0, 1.0);
44  DrawRectangle(m_position, m_width, m_height);
45  glColor4d(0.0, 0.0, 0.0, 1.0);
46  DrawRectangle(m_position, m_width, m_height, GL_LINE_LOOP);
47 
48  // Plot number.
49  m_glText->Draw(m_position);
50 
51  glColor4d(0.0, 0.0, 0.0, 1.0);
52  DrawNodes();
53 }
54 
55 bool Constant::ShowForm(wxWindow* parent, Element* element)
56 {
57  ConstantForm* form = new ConstantForm(parent, this);
58  if(form->ShowModal() == wxID_OK) {
59  form->Destroy();
60  return true;
61  }
62  form->Destroy();
63  return false;
64 }
65 
66 void Constant::Rotate(bool clockwise)
67 {
68  if(clockwise)
69  m_angle += 90.0;
70  else
71  m_angle -= 90.0;
72  if(m_angle >= 360.0)
73  m_angle = 0.0;
74  else if(m_angle < 0)
75  m_angle = 270.0;
76 
77  UpdatePoints();
78 
79  for(auto it = m_nodeList.begin(), itEnd = m_nodeList.end(); it != itEnd; ++it) {
80  Node* node = *it;
81  node->Rotate(clockwise);
82  }
83 }
84 
85 void Constant::UpdatePoints()
86 {
87  if(m_nodeList.size() != 0) {
88  if(m_angle == 0.0) {
89  m_nodeList[0]->SetPosition(m_position + wxPoint2DDouble(-m_width / 2, 0));
90  } else if(m_angle == 90.0) {
91  m_nodeList[0]->SetPosition(m_position + wxPoint2DDouble(0, -m_height / 2));
92  } else if(m_angle == 180.0) {
93  m_nodeList[0]->SetPosition(m_position + wxPoint2DDouble(m_width / 2, 0));
94  } else if(m_angle == 270.0) {
95  m_nodeList[0]->SetPosition(m_position + wxPoint2DDouble(0, m_height / 2));
96  }
97  }
98 }
99 
100 void Constant::SetValue(double value)
101 {
102  m_value = value;
103  wxString text = StringFromDouble(m_value);
104 
105  if(m_glText)
106  m_glText->SetText(text);
107  else
108  m_glText = new OpenGLText(text);
109 
110  m_width = m_glText->GetWidth() + 6 + 2 * m_borderSize;
111  m_height = m_glText->GetHeight() + 6 + 2 * m_borderSize;
112 
113  UpdatePoints();
114 }
115 
117 {
118  Constant* copy = new Constant(m_elementID);
119  *copy = *this;
120  copy->m_glText = m_glText->GetCopy();
121  return copy;
122 }
123 
125 {
126  SetValue(m_value);
127  if(!m_glText->IsTextureOK()) return false;
128  return true;
129 }
Base class of all elements of the program. This class is responsible for manage graphical and his dat...
Definition: Element.h:113
Node of a control element. This class manages the user interaction with the connection and control el...
-
virtual Element * GetCopy()
Get a the element copy.
Definition: Constant.cpp:123
+
virtual bool UpdateText()
Update the OpenGL text in the element (if present).
Definition: Constant.cpp:124
+
virtual Element * GetCopy()
Get a the element copy.
Definition: Constant.cpp:116
virtual void DrawRectangle(wxPoint2DDouble position, double width, double height, GLenum mode=GL_QUADS) const
Draw rectangle.
Definition: Element.cpp:69
+
Class to draw text on OpenGL using wxWidgets.
Definition: OpenGLText.h:31
Form to edit the constant control data.
Definition: ConstantForm.h:31
-
virtual bool ShowForm(wxWindow *parent, Element *element)
Show element data form.
Definition: Constant.cpp:56
-
virtual void Rotate(bool clockwise=true)
Rotate the element.
Definition: Constant.cpp:67
+
virtual bool ShowForm(wxWindow *parent, Element *element)
Show element data form.
Definition: Constant.cpp:55
+
virtual void Rotate(bool clockwise=true)
Rotate the element.
Definition: Constant.cpp:66
static wxString StringFromDouble(double value, int minDecimal=1)
Convert a double value to string.
Definition: Element.cpp:320
A control element that provides a constant value.
Definition: Constant.h:35
-
const GLdouble * GetRGBA() const
Get colour in RGBA.
Definition: Element.h:101
-
virtual void Draw(wxPoint2DDouble translation, double scale) const
Draw the element.
Definition: Constant.cpp:32
+
virtual void Draw(wxPoint2DDouble translation, double scale) const
Draw the element.
Definition: Constant.cpp:35
diff --git a/docs/doxygen/html/_constant_8h.html b/docs/doxygen/html/_constant_8h.html index 30c1dbf..0cf5a19 100644 --- a/docs/doxygen/html/_constant_8h.html +++ b/docs/doxygen/html/_constant_8h.html @@ -92,7 +92,7 @@ $(document).ready(function(){initNavTree('_constant_8h.html','');});
#include "ControlElement.h"
#include <wx/dcscreen.h>
-#include "wxGLString.h"
+#include "OpenGLText.h"

Go to the source code of this file.

diff --git a/docs/doxygen/html/_constant_8h_source.html b/docs/doxygen/html/_constant_8h_source.html index 53dc0fa..9e8bace 100644 --- a/docs/doxygen/html/_constant_8h_source.html +++ b/docs/doxygen/html/_constant_8h_source.html @@ -88,18 +88,20 @@ $(document).ready(function(){initNavTree('_constant_8h_source.html','');});
Constant.h
-Go to the documentation of this file.
1 /*
2  * Copyright (C) 2017 Thales Lima Oliveira <thales@ufu.br>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program. If not, see <https://www.gnu.org/licenses/>.
16  */
17 
18 #ifndef CONSTANT_H
19 #define CONSTANT_H
20 
21 #include "ControlElement.h"
22 
23 #include <wx/dcscreen.h>
24 #include "wxGLString.h"
25 
26 class ConstantForm;
27 
35 class Constant : public ControlElement
36 {
37  public:
38  Constant(int id);
39  ~Constant();
40 
41  virtual void Draw(wxPoint2DDouble translation, double scale) const;
42  virtual bool Contains(wxPoint2DDouble position) const { return m_rect.Contains(position); }
43  virtual bool Intersects(wxRect2DDouble rect) const { return m_rect.Intersects(rect); }
44  virtual bool ShowForm(wxWindow* parent, Element* element);
45  virtual void Rotate(bool clockwise = true);
46  virtual void UpdateText() { SetValue(m_value); }
47  virtual void SetValue(double value);
48  virtual double GetValue() const { return m_value; }
49  virtual void UpdatePoints();
50 
51  virtual Element* GetCopy();
52 
53  protected:
54  double m_value = 1.0;
55 
56  wxGLString* m_glStringValue = NULL;
57  int m_fontSize = 10;
58 };
59 
60 #endif // CONSTANT_H
Base class of all elements of the program. This class is responsible for manage graphical and his dat...
Definition: Element.h:113
+Go to the documentation of this file.
1 /*
2  * Copyright (C) 2017 Thales Lima Oliveira <thales@ufu.br>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program. If not, see <https://www.gnu.org/licenses/>.
16  */
17 
18 #ifndef CONSTANT_H
19 #define CONSTANT_H
20 
21 #include "ControlElement.h"
22 
23 #include <wx/dcscreen.h>
24 #include "OpenGLText.h"
25 
26 class ConstantForm;
27 
35 class Constant : public ControlElement
36 {
37  public:
38  Constant(int id);
39  ~Constant();
40 
41  virtual void Draw(wxPoint2DDouble translation, double scale) const;
42  virtual bool Contains(wxPoint2DDouble position) const { return m_rect.Contains(position); }
43  virtual bool Intersects(wxRect2DDouble rect) const { return m_rect.Intersects(rect); }
44  virtual bool ShowForm(wxWindow* parent, Element* element);
45  virtual void Rotate(bool clockwise = true);
46  virtual bool UpdateText();
47  virtual void SetValue(double value);
48  virtual double GetValue() const { return m_value; }
49  virtual void UpdatePoints();
50 
51  virtual Element* GetCopy();
52 
53  protected:
54  double m_value = 1.0;
55 
56  OpenGLText* m_glText = NULL;
57 };
58 
59 #endif // CONSTANT_H
Base class of all elements of the program. This class is responsible for manage graphical and his dat...
Definition: Element.h:113
virtual bool Contains(wxPoint2DDouble position) const
Checks if the element contains a position.
Definition: Constant.h:42
virtual bool Intersects(wxRect2DDouble rect) const
Check if the element&#39;s rect intersects other rect.
Definition: Constant.h:43
-
virtual Element * GetCopy()
Get a the element copy.
Definition: Constant.cpp:123
+
virtual bool UpdateText()
Update the OpenGL text in the element (if present).
Definition: Constant.cpp:124
+
virtual Element * GetCopy()
Get a the element copy.
Definition: Constant.cpp:116
+ +
Class to draw text on OpenGL using wxWidgets.
Definition: OpenGLText.h:31
Form to edit the constant control data.
Definition: ConstantForm.h:31
-
virtual bool ShowForm(wxWindow *parent, Element *element)
Show element data form.
Definition: Constant.cpp:56
+
virtual bool ShowForm(wxWindow *parent, Element *element)
Show element data form.
Definition: Constant.cpp:55
Base class of a control element. Provide general methods to other control classes.
-
virtual void Rotate(bool clockwise=true)
Rotate the element.
Definition: Constant.cpp:67
+
virtual void Rotate(bool clockwise=true)
Rotate the element.
Definition: Constant.cpp:66
A control element that provides a constant value.
Definition: Constant.h:35
- -
virtual void Draw(wxPoint2DDouble translation, double scale) const
Draw the element.
Definition: Constant.cpp:32
+
virtual void Draw(wxPoint2DDouble translation, double scale) const
Draw the element.
Definition: Constant.cpp:35
diff --git a/docs/doxygen/html/_constant_form_8cpp_source.html b/docs/doxygen/html/_constant_form_8cpp_source.html index f90c121..226ad45 100644 --- a/docs/doxygen/html/_constant_form_8cpp_source.html +++ b/docs/doxygen/html/_constant_form_8cpp_source.html @@ -89,7 +89,7 @@ $(document).ready(function(){initNavTree('_constant_form_8cpp_source.html','');}
1 /*
2  * Copyright (C) 2017 Thales Lima Oliveira <thales@ufu.br>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program. If not, see <https://www.gnu.org/licenses/>.
16  */
17 
18 #include "ConstantForm.h"
19 #include "Constant.h"
20 
21 ConstantForm::ConstantForm(wxWindow* parent, Constant* constant) : ConstantFormBase(parent)
22 {
23  SetSize(GetBestSize());
24 
25  m_parent = parent;
26  m_constant = constant;
27 
28  m_textCtrlValue->SetValue(m_constant->StringFromDouble(m_constant->GetValue()));
29 }
30 
31 ConstantForm::~ConstantForm() {}
32 void ConstantForm::OnOKButtonClick(wxCommandEvent& event)
33 {
34  if(ValidateData()) EndModal(wxID_OK);
35 }
36 
37 bool ConstantForm::ValidateData()
38 {
39  double value;
40  if(!m_constant->DoubleFromString(this, m_textCtrlValue->GetValue(), value,
41  _("Value entered incorrectly in the field \"Constant value\".")))
42  return false;
43 
44  m_constant->SetValue(value);
45  return true;
46 }
- +
A control element that provides a constant value.
Definition: Constant.h:35
diff --git a/docs/doxygen/html/_constant_form_8h_source.html b/docs/doxygen/html/_constant_form_8h_source.html index 60eae01..3211f0a 100644 --- a/docs/doxygen/html/_constant_form_8h_source.html +++ b/docs/doxygen/html/_constant_form_8h_source.html @@ -88,7 +88,7 @@ $(document).ready(function(){initNavTree('_constant_form_8h_source.html','');});
ConstantForm.h
-Go to the documentation of this file.
1 /*
2  * Copyright (C) 2017 Thales Lima Oliveira <thales@ufu.br>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program. If not, see <https://www.gnu.org/licenses/>.
16  */
17 
18 #ifndef CONSTANTFORM_H
19 #define CONSTANTFORM_H
20 #include "ElementForm.h"
21 
22 class Constant;
23 
32 {
33  public:
34  ConstantForm(wxWindow* parent, Constant* constant);
35  virtual ~ConstantForm();
36  virtual bool ValidateData();
37 
38  protected:
39  virtual void OnCancelButtonClick(wxCommandEvent& event) { EndModal(wxID_CANCEL); }
40  virtual void OnOKButtonClick(wxCommandEvent& event);
41 
42  wxWindow* m_parent = NULL;
43  Constant* m_constant = NULL;
44 };
45 #endif // CONSTANTFORM_H
+Go to the documentation of this file.
1 /*
2  * Copyright (C) 2017 Thales Lima Oliveira <thales@ufu.br>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program. If not, see <https://www.gnu.org/licenses/>.
16  */
17 
18 #ifndef CONSTANTFORM_H
19 #define CONSTANTFORM_H
20 #include "ElementForm.h"
21 
22 class Constant;
23 
32 {
33  public:
34  ConstantForm(wxWindow* parent, Constant* constant);
35  virtual ~ConstantForm();
36  virtual bool ValidateData();
37 
38  protected:
39  virtual void OnCancelButtonClick(wxCommandEvent& event) { EndModal(wxID_CANCEL); }
40  virtual void OnOKButtonClick(wxCommandEvent& event);
41 
42  wxWindow* m_parent = NULL;
43  Constant* m_constant = NULL;
44 };
45 #endif // CONSTANTFORM_H
Form to edit the constant control data.
Definition: ConstantForm.h:31
A control element that provides a constant value.
Definition: Constant.h:35
diff --git a/docs/doxygen/html/_control_editor_8cpp_source.html b/docs/doxygen/html/_control_editor_8cpp_source.html index a71cf1d..f35458e 100644 --- a/docs/doxygen/html/_control_editor_8cpp_source.html +++ b/docs/doxygen/html/_control_editor_8cpp_source.html @@ -88,9 +88,10 @@ $(document).ready(function(){initNavTree('_control_editor_8cpp_source.html','');
ControlEditor.cpp
-
1 /*
2  * Copyright (C) 2017 Thales Lima Oliveira <thales@ufu.br>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program. If not, see <https://www.gnu.org/licenses/>.
16  */
17 
18 #include "ControlEditor.h"
19 
20 #ifdef USING_WX_3_0_X
21 #include "DegreesAndRadians.h"
22 #endif
23 #include "FileHanding.h"
24 #include "Camera.h"
25 #include "ControlElement.h"
26 #include "TransferFunction.h"
27 #include "ConnectionLine.h"
28 #include "Sum.h"
29 #include "Multiplier.h"
30 #include "Limiter.h"
31 #include "RateLimiter.h"
32 #include "Exponential.h"
33 #include "Constant.h"
34 #include "Gain.h"
35 
36 #include "ControlElementSolver.h"
38 
39 #include "ChartView.h"
40 #include "ElementPlotData.h"
41 
42 ControlElementButton::ControlElementButton(wxWindow* parent, wxString label, wxImage image, wxWindowID id)
43  : wxWindow(parent, id)
44 {
45  SetBackgroundColour(*wxWHITE);
46  // m_font = wxFont(8, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL);
47  m_font = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT);
48  m_label = label;
49  m_image = image;
50  m_imageSize = wxSize(image.GetWidth(), image.GetHeight());
51 
52  // Calculate label size.
53  wxScreenDC dc;
54  dc.SetFont(m_font);
55  wxSize textSize = dc.GetTextExtent(label);
56 
57  int buttonWidth = 0;
58  if(textSize.GetWidth() > m_imageSize.GetWidth()) {
59  buttonWidth = textSize.GetWidth();
60  m_imagePosition = wxPoint((buttonWidth - m_imageSize.GetWidth()) / 2 + m_borderSize, m_borderSize);
61  m_labelPosition = wxPoint(m_borderSize, m_imageSize.GetHeight() + m_borderSize);
62  } else {
63  buttonWidth = m_imageSize.GetWidth();
64  m_imagePosition = wxPoint(m_borderSize, m_borderSize);
65  m_labelPosition =
66  wxPoint((buttonWidth - textSize.GetWidth()) / 2 + m_borderSize, m_imageSize.GetHeight() + m_borderSize);
67  }
68  m_buttonSize =
69  wxSize(buttonWidth + 2 * m_borderSize, textSize.GetHeight() + m_imageSize.GetHeight() + 2 * m_borderSize);
70  SetMinSize(m_buttonSize + wxSize(m_borderSize, m_borderSize));
71 
72  // Events.
73  Bind(wxEVT_PAINT, &ControlElementButton::OnPaint, this);
74  Bind(wxEVT_ENTER_WINDOW, &ControlElementButton::OnMouseEnter, this);
75  Bind(wxEVT_LEAVE_WINDOW, &ControlElementButton::OnMouseLeave, this);
76  Bind(wxEVT_LEFT_DOWN, &ControlElementButton::OnLeftClickDown, this);
77  Bind(wxEVT_LEFT_UP, &ControlElementButton::OnLeftClickUp, this);
78 }
79 
80 ControlElementButton::~ControlElementButton() {}
81 void ControlElementButton::OnPaint(wxPaintEvent& event)
82 {
83  wxPaintDC dc(this);
84  wxGraphicsContext* gc = wxGraphicsContext::Create(dc);
85  if(gc) {
86  if(m_mouseAbove) {
87  if(m_selected) {
88  gc->SetPen(wxPen(wxColour(0, 125, 255, 255), m_borderSize - 1));
89  gc->SetBrush(wxBrush(wxColour(0, 125, 255, 100)));
90  } else {
91  gc->SetPen(*wxTRANSPARENT_PEN);
92  gc->SetBrush(wxBrush(wxColour(0, 125, 255, 70)));
93  }
94  gc->DrawRectangle(m_borderSize / 2, m_borderSize / 2, m_buttonSize.GetWidth(), m_buttonSize.GetHeight());
95  }
96  gc->DrawBitmap(gc->CreateBitmapFromImage(m_image), m_imagePosition.x, m_imagePosition.y, m_imageSize.GetWidth(),
97  m_imageSize.GetHeight());
98  gc->SetFont(m_font, *wxBLACK);
99  gc->DrawText(m_label, m_labelPosition.x, m_labelPosition.y);
100  delete gc;
101  }
102 }
103 
104 void ControlElementButton::OnMouseEnter(wxMouseEvent& event)
105 {
106  m_mouseAbove = true;
107  Refresh();
108  event.Skip();
109 }
110 
111 void ControlElementButton::OnMouseLeave(wxMouseEvent& event)
112 {
113  m_mouseAbove = false;
114  Refresh();
115  event.Skip();
116 }
117 
118 void ControlElementButton::OnLeftClickDown(wxMouseEvent& event)
119 {
120  m_selected = true;
121  Refresh();
122  event.Skip();
123 }
124 
125 void ControlElementButton::OnLeftClickUp(wxMouseEvent& event)
126 {
127  m_selected = false;
128  Refresh();
129  event.Skip();
130 }
131 
132 ControlEditor::ControlEditor(wxWindow* parent, int ioflags) : ControlEditorBase(parent)
133 {
134  BuildControlElementPanel();
135  m_glContext = new wxGLContext(m_glCanvas);
136  m_camera = new Camera();
137  m_selectionRect = wxRect2DDouble(0, 0, 0, 0);
138  // m_camera->SetScale(1.2);
139  m_ioFlags = ioflags;
140 }
141 ControlEditor::~ControlEditor()
142 {
143  // m_tfButton->Disconnect(wxEVT_LEFT_DOWN, wxMouseEventHandler(ControlEditor::LeftClickDown), m_tfButton, this);
144 }
145 
146 void ControlEditor::BuildControlElementPanel()
147 {
148  m_panelControlElements->SetDoubleBuffered(true);
149  wxWrapSizer* wrapSizer = new wxWrapSizer();
150  m_panelControlElements->SetSizer(wrapSizer);
151 
152  wxFileName exeFileName(wxStandardPaths::Get().GetExecutablePath());
153  wxString exePath = exeFileName.GetPath();
154 
156  m_panelControlElements, _("In/Out"), wxImage(exePath + "\\..\\data\\images\\control\\io.png"), ID_IO);
157  wrapSizer->Add(ioButton, 0, wxALL, 5);
158  ioButton->Bind(wxEVT_LEFT_DOWN, &ControlEditor::LeftClickDown, this);
159 
160  ControlElementButton* tfButton =
161  new ControlElementButton(m_panelControlElements, _("Transfer fcn"),
162  wxImage(exePath + "\\..\\data\\images\\control\\transferFunc.png"), ID_TF);
163  wrapSizer->Add(tfButton, 0, wxALL, 5);
164  tfButton->Bind(wxEVT_LEFT_DOWN, &ControlEditor::LeftClickDown, this);
165 
167  m_panelControlElements, _("Sum"), wxImage(exePath + "\\..\\data\\images\\control\\sum.png"), ID_SUM);
168  wrapSizer->Add(sumButton, 0, wxALL, 5);
169  sumButton->Bind(wxEVT_LEFT_DOWN, &ControlEditor::LeftClickDown, this);
170 
171  ControlElementButton* constButton = new ControlElementButton(
172  m_panelControlElements, _("Constant"), wxImage(exePath + "\\..\\data\\images\\control\\value.png"), ID_CONST);
173  wrapSizer->Add(constButton, 0, wxALL, 5);
174  constButton->Bind(wxEVT_LEFT_DOWN, &ControlEditor::LeftClickDown, this);
175 
176  ControlElementButton* limButton =
177  new ControlElementButton(m_panelControlElements, _("Limiter"),
178  wxImage(exePath + "\\..\\data\\images\\control\\limiter.png"), ID_LIMITER);
179  wrapSizer->Add(limButton, 0, wxALL, 5);
180  limButton->Bind(wxEVT_LEFT_DOWN, &ControlEditor::LeftClickDown, this);
181 
182  ControlElementButton* gainButton = new ControlElementButton(
183  m_panelControlElements, _("Gain"), wxImage(exePath + "\\..\\data\\images\\control\\gain.png"), ID_GAIN);
184  wrapSizer->Add(gainButton, 0, wxALL, 5);
185  gainButton->Bind(wxEVT_LEFT_DOWN, &ControlEditor::LeftClickDown, this);
186 
187  ControlElementButton* multButton = new ControlElementButton(
188  m_panelControlElements, _("Multiplier"), wxImage(exePath + "\\..\\data\\images\\control\\mult.png"), ID_MULT);
189  wrapSizer->Add(multButton, 0, wxALL, 5);
190  multButton->Bind(wxEVT_LEFT_DOWN, &ControlEditor::LeftClickDown, this);
191 
193  m_panelControlElements, _("Exponential"), wxImage(exePath + "\\..\\data\\images\\control\\sat.png"), ID_EXP);
194  wrapSizer->Add(satButton, 0, wxALL, 5);
195  satButton->Bind(wxEVT_LEFT_DOWN, &ControlEditor::LeftClickDown, this);
196 
197  ControlElementButton* rateLimButton =
198  new ControlElementButton(m_panelControlElements, _("Rate limiter"),
199  wxImage(exePath + "\\..\\data\\images\\control\\rateLimiter.png"), ID_RATELIM);
200  wrapSizer->Add(rateLimButton, 0, wxALL, 5);
201  rateLimButton->Bind(wxEVT_LEFT_DOWN, &ControlEditor::LeftClickDown, this);
202 }
203 
204 void ControlEditor::LeftClickDown(wxMouseEvent& event)
205 {
206  AddElement(static_cast<ControlElementButtonID>(event.GetId()));
207  event.Skip();
208 }
209 
210 void ControlEditor::SetViewport()
211 {
212  glClearColor(1.0, 1.0, 1.0, 1.0); // White background.
213  glClear(GL_COLOR_BUFFER_BIT);
214  glDisable(GL_DEPTH_TEST);
215  glDisable(GL_TEXTURE_2D);
216  glEnable(GL_COLOR_MATERIAL);
217  glEnable(GL_BLEND);
218  glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
219  glEnable(GL_LINE_SMOOTH);
220 
221  double width = m_glCanvas->GetSize().x - 1;
222  double height = m_glCanvas->GetSize().y - 1;
223 
224  // Viewport fit the screen.
225  glViewport(0, 0, width, height);
226 
227  glMatrixMode(GL_PROJECTION);
228  glLoadIdentity();
229  gluOrtho2D(0.0, width, height, 0.0);
230 
231  glMatrixMode(GL_MODELVIEW);
232  glLoadIdentity();
233 }
234 
235 void ControlEditor::AddElement(ControlElementButtonID id)
236 {
237  switch(id) {
238  case ID_IO: {
239  m_mode = MODE_INSERT;
240  IOControl* io = new IOControl(m_ioFlags, m_lastElementID);
241  m_elementList.push_back(io);
242  } break;
243  case ID_TF: {
244  m_mode = MODE_INSERT;
245  TransferFunction* tf = new TransferFunction(m_lastElementID);
246  m_elementList.push_back(tf);
247  } break;
248  case ID_SUM: {
249  m_mode = MODE_INSERT;
250  Sum* sum = new Sum(m_lastElementID);
251  m_elementList.push_back(sum);
252  } break;
253  case ID_CONST: {
254  m_mode = MODE_INSERT;
255  Constant* constant = new Constant(m_lastElementID);
256  m_elementList.push_back(constant);
257  } break;
258  case ID_LIMITER: {
259  m_mode = MODE_INSERT;
260  Limiter* limiter = new Limiter(m_lastElementID);
261  m_elementList.push_back(limiter);
262  } break;
263  case ID_GAIN: {
264  m_mode = MODE_INSERT;
265  Gain* gain = new Gain(m_lastElementID);
266  m_elementList.push_back(gain);
267  } break;
268  case ID_MULT: {
269  m_mode = MODE_INSERT;
270  Multiplier* mult = new Multiplier(m_lastElementID);
271  m_elementList.push_back(mult);
272  } break;
273  case ID_EXP: {
274  m_mode = MODE_INSERT;
275  Exponential* exp = new Exponential(m_lastElementID);
276  m_elementList.push_back(exp);
277  } break;
278  case ID_RATELIM: {
279  m_mode = MODE_INSERT;
280  RateLimiter* rateLim = new RateLimiter(m_lastElementID);
281  m_elementList.push_back(rateLim);
282  } break;
283  }
284  m_lastElementID++;
285 }
286 
287 void ControlEditor::OnPaint(wxPaintEvent& event)
288 {
289  wxPaintDC dc(m_glCanvas);
290  m_glContext->SetCurrent(*m_glCanvas);
291  SetViewport();
292 
293  // Set GLCanvas scale and translation.
294  glScaled(m_camera->GetScale(), m_camera->GetScale(), 0.0); // Scale
295  glTranslated(m_camera->GetTranslation().m_x, m_camera->GetTranslation().m_y, 0.0); // Translation
296 
297  for(auto it = m_connectionList.begin(), itEnd = m_connectionList.end(); it != itEnd; ++it) {
298  ConnectionLine* line = *it;
299  line->Draw(m_camera->GetTranslation(), m_camera->GetScale());
300  }
301 
302  for(auto it = m_elementList.begin(), itEnd = m_elementList.end(); it != itEnd; ++it) {
303  Element* element = *it;
304  element->Draw(m_camera->GetTranslation(), m_camera->GetScale());
305  }
306 
307  // Selection rectangle
308  glLineWidth(1.0);
309  glColor4d(0.0, 0.5, 1.0, 1.0);
310  glBegin(GL_LINE_LOOP);
311  glVertex2d(m_selectionRect.m_x, m_selectionRect.m_y);
312  glVertex2d(m_selectionRect.m_x, m_selectionRect.m_y + m_selectionRect.m_height);
313  glVertex2d(m_selectionRect.m_x + m_selectionRect.m_width, m_selectionRect.m_y + m_selectionRect.m_height);
314  glVertex2d(m_selectionRect.m_x + m_selectionRect.m_width, m_selectionRect.m_y);
315  glEnd();
316  glColor4d(0.0, 0.5, 1.0, 0.3);
317  glBegin(GL_QUADS);
318  glVertex2d(m_selectionRect.m_x, m_selectionRect.m_y);
319  glVertex2d(m_selectionRect.m_x, m_selectionRect.m_y + m_selectionRect.m_height);
320  glVertex2d(m_selectionRect.m_x + m_selectionRect.m_width, m_selectionRect.m_y + m_selectionRect.m_height);
321  glVertex2d(m_selectionRect.m_x + m_selectionRect.m_width, m_selectionRect.m_y);
322  glEnd();
323 
324  glFlush(); // Sends all pending information directly to the GPU.
325  m_glCanvas->SwapBuffers();
326  event.Skip();
327 }
328 
329 void ControlEditor::OnDoubleClick(wxMouseEvent& event)
330 {
331  wxPoint2DDouble clickPoint = event.GetPosition();
332  bool redraw = false;
333 
334  if(m_mode == MODE_EDIT) {
335  for(auto it = m_elementList.begin(), itEnd = m_elementList.end(); it != itEnd; ++it) {
336  Element* element = *it;
337  if(element->Contains(m_camera->ScreenToWorld(clickPoint))) {
338  element->ShowForm(this, element);
339  CheckConnections();
340  auto childList = element->GetChildList();
341  for(auto itC = childList.begin(), itEndC = childList.end(); itC != itEndC; ++itC) {
342  ConnectionLine* line = static_cast<ConnectionLine*>(*itC);
343  line->UpdatePoints();
344  }
345  redraw = true;
346  }
347  }
348  }
349 
350  if(redraw) Redraw();
351 }
352 
353 void ControlEditor::OnLeftClickDown(wxMouseEvent& event)
354 {
355  wxPoint2DDouble clickPoint = event.GetPosition();
356  bool foundElement = false;
357 
358  if(m_mode == MODE_INSERT) {
359  m_mode = MODE_EDIT;
360  } else {
361  for(auto it = m_elementList.begin(), itEnd = m_elementList.end(); it != itEnd; ++it) {
362  ControlElement* element = *it;
363  bool foundNode = false;
364  auto nodeList = element->GetNodeList();
365  for(auto itN = nodeList.begin(), itNEnd = nodeList.end(); itN != itNEnd; ++itN) {
366  Node* node = *itN;
367  if(node->Contains(m_camera->ScreenToWorld(clickPoint))) {
368  m_mode = MODE_INSERT_LINE;
369  ConnectionLine* line = new ConnectionLine(node, m_lastElementID);
370  m_lastElementID++;
371  m_connectionList.push_back(line);
372  element->AddChild(line);
373  line->AddParent(element);
374  foundElement = true;
375  foundNode = true;
376  }
377  }
378 
379  if(!foundNode) {
380  // Set movement initial position (not necessarily will be moved).
381  element->StartMove(m_camera->ScreenToWorld(clickPoint));
382 
383  // Click in an element.
384  if(element->Contains(m_camera->ScreenToWorld(clickPoint))) {
385  if(!foundElement) {
386  element->SetSelected();
387  foundElement = true;
388  }
389  m_mode = MODE_MOVE_ELEMENT;
390  }
391  }
392  }
393  if(m_mode != MODE_INSERT_LINE) {
394  for(auto it = m_connectionList.begin(), itEnd = m_connectionList.end(); it != itEnd; ++it) {
395  ConnectionLine* line = *it;
396  line->StartMove(m_camera->ScreenToWorld(clickPoint));
397  if(line->Contains(m_camera->ScreenToWorld(clickPoint))) {
398  line->SetSelected();
399  foundElement = true;
400  m_mode = MODE_MOVE_LINE;
401  }
402  }
403  }
404  }
405 
406  if(!foundElement) {
407  m_mode = MODE_SELECTION_RECT;
408  m_startSelRect = m_camera->ScreenToWorld(clickPoint);
409  }
410 
411  Redraw();
412  event.Skip();
413 }
414 
415 void ControlEditor::OnLeftClickUp(wxMouseEvent& event)
416 {
417  bool foundNode = false;
418  for(auto it = m_elementList.begin(), itEnd = m_elementList.end(); it != itEnd; it++) {
419  ControlElement* element = *it;
420  if(m_mode == MODE_INSERT_LINE) {
421  auto nodeList = element->GetNodeList();
422  for(auto itN = nodeList.begin(), itNEnd = nodeList.end(); itN != itNEnd; ++itN) {
423  Node* node = *itN;
424  if(node->Contains(m_camera->ScreenToWorld(event.GetPosition()))) {
425  ConnectionLine* line = *(m_connectionList.end() - 1);
426  if(line->AppendNode(node, element)) {
427  line->AddParent(element);
428  element->AddChild(line);
429  line->UpdatePoints();
430  m_mode = MODE_EDIT;
431  foundNode = true;
432  }
433  }
434  }
435  } else if(m_mode == MODE_SELECTION_RECT) {
436  if(element->Intersects(m_selectionRect)) {
437  element->SetSelected();
438  } else if(!event.ControlDown()) {
439  element->SetSelected(false);
440  }
441  } else if(!event.ControlDown()) {
442  if(!element->Contains(m_camera->ScreenToWorld(event.GetPosition()))) {
443  element->SetSelected(false);
444  }
445  }
446  }
447  for(auto it = m_connectionList.begin(), itEnd = m_connectionList.end(); it != itEnd; ++it) {
448  ConnectionLine* cLine = *it;
449  if(m_mode == MODE_INSERT_LINE && !foundNode && it != (itEnd - 1)) {
450  if(cLine->Contains(m_camera->ScreenToWorld(event.GetPosition()))) {
451  ConnectionLine* iLine = *(m_connectionList.end() - 1);
452  if(iLine->SetParentLine(cLine)) {
453  cLine->AddChild(iLine);
454  iLine->UpdatePoints();
455  m_mode = MODE_EDIT;
456  foundNode = true;
457  }
458  }
459  } else if(m_mode == MODE_SELECTION_RECT) {
460  if(cLine->Intersects(m_selectionRect)) {
461  cLine->SetSelected();
462  } else if(!event.ControlDown()) {
463  cLine->SetSelected(false);
464  }
465  } else if(!event.ControlDown()) {
466  if(!cLine->Contains(m_camera->ScreenToWorld(event.GetPosition()))) {
467  cLine->SetSelected(false);
468  }
469  }
470  }
471 
472  m_selectionRect = wxRect2DDouble(0, 0, 0, 0);
473 
474  if(m_mode == MODE_INSERT_LINE && !foundNode) {
475  ConnectionLine* cLine = *(m_connectionList.end() - 1);
476  // Free nodes
477  auto nodeList = cLine->GetNodeList();
478  for(auto itN = nodeList.begin(), itEndN = nodeList.end(); itN != itEndN; ++itN) {
479  Node* node = *itN;
480  node->SetConnected(false);
481  }
482  // Remove the associated child from parents.
483  auto parentList = cLine->GetParentList();
484  for(auto it = parentList.begin(), itEnd = parentList.end(); it != itEnd; ++it) {
485  Element* element = *it;
486  element->RemoveChild(cLine);
487  }
488  m_connectionList.pop_back();
489  if(cLine) delete cLine;
490  m_mode = MODE_EDIT;
491  } else if(m_mode != MODE_INSERT) {
492  m_mode = MODE_EDIT;
493  }
494 
495  Redraw();
496  event.Skip();
497 }
498 
499 void ControlEditor::OnMiddleDown(wxMouseEvent& event)
500 {
501  // Set to drag mode.
502  switch(m_mode) {
503  case MODE_INSERT: {
504  m_mode = MODE_DRAG_INSERT;
505  } break;
506  case MODE_PASTE: {
507  m_mode = MODE_DRAG_PASTE;
508  } break;
509  default: {
510  m_mode = MODE_DRAG;
511  } break;
512  }
513  m_camera->StartTranslation(m_camera->ScreenToWorld(event.GetPosition()));
514 }
515 
516 void ControlEditor::OnMiddleUp(wxMouseEvent& event)
517 {
518  switch(m_mode) {
519  case MODE_DRAG_INSERT: {
520  m_mode = MODE_INSERT;
521  } break;
522  case MODE_DRAG_PASTE: {
523  m_mode = MODE_PASTE;
524  } break;
525  case MODE_INSERT:
526  case MODE_PASTE: {
527  // Does nothing.
528  } break;
529  default: {
530  m_mode = MODE_EDIT;
531  } break;
532  }
533 }
534 
535 void ControlEditor::OnMouseMotion(wxMouseEvent& event)
536 {
537  wxPoint2DDouble clickPoint = event.GetPosition();
538  bool redraw = false;
539 
540  switch(m_mode) {
541  case MODE_INSERT: {
542  Element* newElement = *(m_elementList.end() - 1); // Get the last element in the list.
543  newElement->Move(m_camera->ScreenToWorld(clickPoint));
544  redraw = true;
545  } break;
546  case MODE_INSERT_LINE: {
547  ConnectionLine* line = *(m_connectionList.end() - 1);
548  line->SetTemporarySecondPoint(m_camera->ScreenToWorld(clickPoint));
549  line->UpdatePoints();
550  redraw = true;
551  } break;
552  case MODE_DRAG:
553  case MODE_DRAG_INSERT:
554  case MODE_DRAG_PASTE: {
555  m_camera->SetTranslation(clickPoint);
556  redraw = true;
557  } break;
558  case MODE_MOVE_ELEMENT: {
559  for(auto it = m_elementList.begin(), itEnd = m_elementList.end(); it != itEnd; it++) {
560  Element* element = *it;
561  if(element->IsSelected()) {
562  element->Move(m_camera->ScreenToWorld(clickPoint));
563  auto childList = element->GetChildList();
564  for(auto itC = childList.begin(), itEndC = childList.end(); itC != itEndC; itC++) {
565  ConnectionLine* line = static_cast<ConnectionLine*>(*itC);
566  line->UpdatePoints();
567  }
568  redraw = true;
569  }
570  }
571  } break;
572  case MODE_MOVE_LINE: {
573  for(auto it = m_connectionList.begin(), itEnd = m_connectionList.end(); it != itEnd; it++) {
574  ConnectionLine* line = *it;
575  if(line->IsSelected()) {
576  line->Move(m_camera->ScreenToWorld(clickPoint));
577  redraw = true;
578  }
579  }
580  } break;
581  case MODE_SELECTION_RECT: {
582  wxPoint2DDouble currentPos = m_camera->ScreenToWorld(clickPoint);
583  double x, y, w, h;
584  if(currentPos.m_x < m_startSelRect.m_x) {
585  x = currentPos.m_x;
586  w = m_startSelRect.m_x - currentPos.m_x;
587  } else {
588  x = m_startSelRect.m_x;
589  w = currentPos.m_x - m_startSelRect.m_x;
590  }
591  if(currentPos.m_y < m_startSelRect.m_y) {
592  y = currentPos.m_y;
593  h = m_startSelRect.m_y - currentPos.m_y;
594  } else {
595  y = m_startSelRect.m_y;
596  h = currentPos.m_y - m_startSelRect.m_y;
597  }
598 
599  m_selectionRect = wxRect2DDouble(x, y, w, h);
600  redraw = true;
601  } break;
602  default:
603  break;
604  }
605 
606  if(redraw) Redraw();
607  event.Skip();
608 }
609 
610 void ControlEditor::OnScroll(wxMouseEvent& event)
611 {
612  if(event.GetWheelRotation() > 0)
613  m_camera->SetScale(event.GetPosition(), +0.05);
614  else
615  m_camera->SetScale(event.GetPosition(), -0.05);
616 
617  Redraw();
618 }
619 
620 void ControlEditor::OnIdle(wxIdleEvent& event) { ConsolidateTexts(); }
621 void ControlEditor::OnKeyDown(wxKeyEvent& event)
622 {
623  char key = event.GetUnicodeKey();
624  if(key != WXK_NONE) {
625  switch(key) {
626  case WXK_DELETE: // Delete selected elements.
627  {
628  DeleteSelectedElements();
629  } break;
630  case 'R': // Rotate the selected elements.
631  {
632  RotateSelectedElements(event.GetModifiers() != wxMOD_SHIFT);
633  } break;
634  case 'L': {
635  // tests
636  } break;
637  }
638  }
639 }
640 
641 void ControlEditor::RotateSelectedElements(bool clockwise)
642 {
643  for(auto it = m_elementList.begin(), itEnd = m_elementList.end(); it != itEnd; ++it) {
644  Element* element = *it;
645  if(element->IsSelected()) {
646  element->Rotate(clockwise);
647  auto childList = element->GetChildList();
648  for(auto itC = childList.begin(), itEndC = childList.end(); itC != itEndC; itC++) {
649  ConnectionLine* line = static_cast<ConnectionLine*>(*itC);
650  line->UpdatePoints();
651  }
652  }
653  }
654  Redraw();
655 }
656 
657 void ControlEditor::DeleteSelectedElements()
658 {
659  for(auto it = m_elementList.begin(); it != m_elementList.end(); ++it) {
660  Element* element = *it;
661  if(element->IsSelected()) {
662  // Remove child/parent.
663  auto childList = element->GetChildList();
664  for(auto itC = childList.begin(), itEnd = childList.end(); itC != itEnd; ++itC) {
665  // The child is always a connection line.
666  ConnectionLine* child = static_cast<ConnectionLine*>(*itC);
667  // Delete the connection line.
668  for(auto itCo = m_connectionList.begin(); itCo != m_connectionList.end(); ++itCo) {
669  ConnectionLine* line = *itCo;
670  if(line == child) {
671  itCo = DeleteLineFromList(itCo);
672  break;
673  }
674  }
675  }
676  m_elementList.erase(it--);
677  if(element) delete element;
678  }
679  }
680 
681  for(auto it = m_connectionList.begin(); it != m_connectionList.end(); ++it) {
682  ConnectionLine* line = *it;
683  if(line->IsSelected()) {
684  it = DeleteLineFromList(it);
685  }
686  }
687  Redraw();
688 }
689 
690 std::vector<ConnectionLine*>::iterator ControlEditor::DeleteLineFromList(std::vector<ConnectionLine*>::iterator& it)
691 {
692  ConnectionLine* cLine = *it;
693  auto childList = cLine->GetLineChildList();
694  for(auto itC = childList.begin(), itEndC = childList.end(); itC != itEndC; ++itC) {
695  ConnectionLine* child = *itC;
696  for(auto itL = m_connectionList.begin(); itL != m_connectionList.end(); ++itL) {
697  ConnectionLine* childOnList = *itL;
698  if(childOnList == child) {
699  itL = DeleteLineFromList(itL);
700  }
701  }
702  }
703  // Remove
704  auto parentList = cLine->GetParentList();
705  for(auto itP = parentList.begin(), itEnd = parentList.end(); itP != itEnd; ++itP) {
706  Element* parent = *itP;
707  if(parent) parent->RemoveChild(cLine);
708  }
709  if(cLine->GetParentLine()) cLine->GetParentLine()->RemoveChild(cLine);
710  // Free nodes
711  auto nodeList = cLine->GetNodeList();
712  for(auto itN = nodeList.begin(), itEndN = nodeList.end(); itN != itEndN; ++itN) {
713  Node* node = *itN;
714  node->SetConnected(false);
715  }
716  m_connectionList.erase(it--);
717  if(cLine) delete cLine;
718  return it;
719 }
720 
721 void ControlEditor::CheckConnections()
722 {
723  for(auto it = m_connectionList.begin(); it != m_connectionList.end(); ++it) {
724  ConnectionLine* cLine = *it;
725  if(cLine->GetType() == ConnectionLine::ELEMENT_ELEMENT) {
726  if(cLine->GetParentList().size() < 2) {
727  it = DeleteLineFromList(it);
728  }
729  }
730  }
731 }
732 
733 void ControlEditor::OnExportClick(wxCommandEvent& event)
734 {
735  FileHanding fileHandling(this);
736 
737  wxFileDialog saveFileDialog(this, _("Save CTL file"), "", "", "CTL files (*.ctl)|*.ctl",
738  wxFD_SAVE | wxFD_OVERWRITE_PROMPT);
739  if(saveFileDialog.ShowModal() == wxID_CANCEL) return;
740 
741  fileHandling.SaveControl(saveFileDialog.GetPath());
742  wxFileName fileName(saveFileDialog.GetPath());
743  event.Skip();
744 }
745 
746 void ControlEditor::OnImportClick(wxCommandEvent& event)
747 {
748  wxFileDialog openFileDialog(this, _("Open CTL file"), "", "", "CTL files (*.ctl)|*.ctl",
749  wxFD_OPEN | wxFD_FILE_MUST_EXIST);
750  if(openFileDialog.ShowModal() == wxID_CANCEL) return;
751 
752  wxFileName fileName(openFileDialog.GetPath());
753 
754  FileHanding fileHandling(this);
755  if(!fileHandling.OpenControl(fileName, m_elementList, m_connectionList)) {
756  wxMessageDialog msgDialog(this, _("It was not possible to open the selected file."), _("Error"),
757  wxOK | wxCENTRE | wxICON_ERROR);
758  msgDialog.ShowModal();
759  }
760 
761  SetLastElementID();
762  Redraw();
763  event.Skip();
764 }
765 
766 void ControlEditor::OnTestClick(wxCommandEvent& event)
767 {
768  ControlSystemTest csTest(this, &m_inputType, &m_startTime, &m_slope, &m_timeStep, &m_simTime);
769  if(csTest.ShowModal() == wxID_OK) {
770  double printStep = 1e-3;
771  double pdbStep = 1e-1;
772 
773  wxProgressDialog pbd(_("Test"), _("Initializing..."), 100, this,
774  wxPD_APP_MODAL | wxPD_AUTO_HIDE | wxPD_CAN_ABORT | wxPD_SMOOTH);
775  ControlElementSolver solver(this, m_timeStep, 1e-5);
776  if(solver.IsOK()) {
777  bool simStopped = false;
778  double currentTime = 0.0;
779  double printTime = 0.0;
780  double pdbTime = 0.0;
781  std::vector<double> time;
782  std::vector<double> solution;
783  std::vector<double> inputV;
784  while(currentTime <= m_simTime) {
785  double input = 0.0;
786  if(currentTime >= m_startTime) {
787  switch(m_inputType) {
788  case 0: {
789  input = m_slope;
790  } break;
791  case 1: {
792  input = m_slope * (currentTime - m_startTime);
793  } break;
794  case 2: {
795  input = m_slope * std::pow(currentTime - m_startTime, 2);
796  } break;
797  default: {
798  input = 0.0;
799  break;
800  }
801  }
802  }
803 
804  solver.SolveNextStep(input);
805 
806  if(printTime >= printStep) {
807  time.push_back(currentTime);
808  solution.push_back(solver.GetLastSolution());
809  inputV.push_back(input);
810  printTime = 0.0;
811  }
812 
813  if(pdbTime > pdbStep) {
814  if(!pbd.Update((currentTime / m_simTime) * 100, wxString::Format("Time = %.2fs", currentTime))) {
815  pbd.Update(100);
816  simStopped = true;
817  currentTime = m_simTime;
818  }
819  pdbTime = 0.0;
820  }
821 
822  printTime += m_timeStep;
823  currentTime += m_timeStep;
824  pdbTime += m_timeStep;
825  }
826  if(!simStopped) {
827  std::vector<ElementPlotData> epdList;
828  ElementPlotData curveData(_("I/O"), ElementPlotData::CT_TEST);
829  curveData.AddData(inputV, _("Input"));
830  curveData.AddData(solution, _("Output"));
831 
832  curveData.SetPlot(0);
833  curveData.SetColour(0, *wxRED);
834  curveData.SetPlot(1);
835  curveData.SetColour(1, *wxBLUE);
836 
837  epdList.push_back(curveData);
838 
839  ChartView* cView = new ChartView(this, epdList, time);
840  cView->Show();
841  cView->UpdatePlot();
842  }
843  } else {
844  wxMessageDialog msgDialog(this, _("It was not possible to solve the control system"), _("Error"),
845  wxOK | wxCENTRE | wxICON_ERROR);
846  msgDialog.ShowModal();
847  }
848  }
849 }
850 
851 void ControlEditor::OnClose(wxCloseEvent& event)
852 {
853  if(m_ctrlContainer) {
854  m_ctrlContainer->FillContainer(this);
855  }
856  event.Skip();
857 }
858 
859 void ControlEditor::ConsolidateTexts()
860 {
861  // Solve wxGLString bug.
862  if(m_firstDraw) {
863  TransferFunction* tf = new TransferFunction(0);
864  m_elementList.push_back(tf);
865  for(auto it = m_elementList.begin(), itEnd = m_elementList.end(); it != itEnd; ++it) {
866  ControlElement* element = *it;
867  element->UpdateText();
868  }
869  Redraw();
870  m_elementList.pop_back();
871  delete tf;
872  m_firstDraw = false;
873  }
874 }
875 
876 void ControlEditor::SetLastElementID()
877 {
878  int id = 0;
879  for(auto it = m_elementList.begin(), itEnd = m_elementList.end(); it != itEnd; ++it) {
880  int elementID = (*it)->GetID();
881  if(id < elementID) id = elementID;
882  }
883  for(auto it = m_connectionList.begin(), itEnd = m_connectionList.end(); it != itEnd; ++it) {
884  int elementID = (*it)->GetID();
885  if(id < elementID) id = elementID;
886  }
887  m_lastElementID = ++id;
888 }
virtual void Move(wxPoint2DDouble position)
Move the element other position.
Definition: Element.cpp:123
+
1 /*
2  * Copyright (C) 2017 Thales Lima Oliveira <thales@ufu.br>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program. If not, see <https://www.gnu.org/licenses/>.
16  */
17 
18 #include "ControlEditor.h"
19 
20 #ifdef USING_WX_3_0_X
21 #include "DegreesAndRadians.h"
22 #endif
23 #include "FileHanding.h"
24 #include "Camera.h"
25 #include "ControlElement.h"
26 #include "TransferFunction.h"
27 #include "ConnectionLine.h"
28 #include "Sum.h"
29 #include "Multiplier.h"
30 #include "Limiter.h"
31 #include "RateLimiter.h"
32 #include "Exponential.h"
33 #include "Constant.h"
34 #include "Gain.h"
35 #include "MathOperation.h"
36 #include "Divider.h"
37 
38 #include "ControlElementSolver.h"
40 
41 #include "ChartView.h"
42 #include "ElementPlotData.h"
43 
44 ControlElementButton::ControlElementButton(wxWindow* parent, wxString label, wxImage image, wxWindowID id)
45  : wxWindow(parent, id)
46 {
47  SetBackgroundColour(*wxWHITE);
48  m_font = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT);
49  m_label = label;
50  m_image = image;
51  m_imageSize = wxSize(image.GetWidth(), image.GetHeight());
52 
53  // Calculate label size.
54  wxScreenDC dc;
55  dc.SetFont(m_font);
56  wxSize textSize = dc.GetTextExtent(label);
57 
58  int buttonWidth = 0;
59  if(textSize.GetWidth() > m_imageSize.GetWidth()) {
60  buttonWidth = textSize.GetWidth();
61  m_imagePosition = wxPoint((buttonWidth - m_imageSize.GetWidth()) / 2 + m_borderSize, m_borderSize);
62  m_labelPosition = wxPoint(m_borderSize, m_imageSize.GetHeight() + m_borderSize);
63  } else {
64  buttonWidth = m_imageSize.GetWidth();
65  m_imagePosition = wxPoint(m_borderSize, m_borderSize);
66  m_labelPosition =
67  wxPoint((buttonWidth - textSize.GetWidth()) / 2 + m_borderSize, m_imageSize.GetHeight() + m_borderSize);
68  }
69  m_buttonSize =
70  wxSize(buttonWidth + 2 * m_borderSize, textSize.GetHeight() + m_imageSize.GetHeight() + 2 * m_borderSize);
71  SetMinSize(m_buttonSize + wxSize(m_borderSize, m_borderSize));
72 
73  // Events.
74  Bind(wxEVT_PAINT, &ControlElementButton::OnPaint, this);
75  Bind(wxEVT_ENTER_WINDOW, &ControlElementButton::OnMouseEnter, this);
76  Bind(wxEVT_LEAVE_WINDOW, &ControlElementButton::OnMouseLeave, this);
77  Bind(wxEVT_LEFT_DOWN, &ControlElementButton::OnLeftClickDown, this);
78  Bind(wxEVT_LEFT_UP, &ControlElementButton::OnLeftClickUp, this);
79 }
80 
81 ControlElementButton::~ControlElementButton() {}
82 void ControlElementButton::OnPaint(wxPaintEvent& event)
83 {
84  wxPaintDC dc(this);
85  wxGraphicsContext* gc = wxGraphicsContext::Create(dc);
86  if(gc) {
87  if(m_mouseAbove) {
88  if(m_selected) {
89  gc->SetPen(wxPen(wxColour(0, 125, 255, 255), m_borderSize - 1));
90  gc->SetBrush(wxBrush(wxColour(0, 125, 255, 100)));
91  } else {
92  gc->SetPen(*wxTRANSPARENT_PEN);
93  gc->SetBrush(wxBrush(wxColour(0, 125, 255, 70)));
94  }
95  gc->DrawRectangle(m_borderSize / 2, m_borderSize / 2, m_buttonSize.GetWidth(), m_buttonSize.GetHeight());
96  }
97  gc->DrawBitmap(gc->CreateBitmapFromImage(m_image), m_imagePosition.x, m_imagePosition.y, m_imageSize.GetWidth(),
98  m_imageSize.GetHeight());
99  gc->SetFont(m_font, *wxBLACK);
100  gc->DrawText(m_label, m_labelPosition.x, m_labelPosition.y);
101  delete gc;
102  }
103 }
104 
105 void ControlElementButton::OnMouseEnter(wxMouseEvent& event)
106 {
107  m_mouseAbove = true;
108  Refresh();
109  event.Skip();
110 }
111 
112 void ControlElementButton::OnMouseLeave(wxMouseEvent& event)
113 {
114  m_mouseAbove = false;
115  Refresh();
116  event.Skip();
117 }
118 
119 void ControlElementButton::OnLeftClickDown(wxMouseEvent& event)
120 {
121  m_selected = true;
122  Refresh();
123  event.Skip();
124 }
125 
126 void ControlElementButton::OnLeftClickUp(wxMouseEvent& event)
127 {
128  m_selected = false;
129  Refresh();
130  event.Skip();
131 }
132 
133 ControlEditor::ControlEditor(wxWindow* parent, int ioflags) : ControlEditorBase(parent)
134 {
135  BuildControlElementPanel();
136  m_glContext = new wxGLContext(m_glCanvas);
137  m_glContext->SetCurrent(*m_glCanvas);
138  m_camera = new Camera();
139  m_selectionRect = wxRect2DDouble(0, 0, 0, 0);
140  // m_camera->SetScale(1.2);
141  m_ioFlags = ioflags;
142 }
143 ControlEditor::~ControlEditor()
144 {
145  // m_tfButton->Disconnect(wxEVT_LEFT_DOWN, wxMouseEventHandler(ControlEditor::LeftClickDown), m_tfButton, this);
146 }
147 
148 void ControlEditor::BuildControlElementPanel()
149 {
150  m_panelControlElements->SetDoubleBuffered(true);
151  wxWrapSizer* wrapSizer = new wxWrapSizer();
152  m_panelControlElements->SetSizer(wrapSizer);
153 
154  wxFileName exeFileName(wxStandardPaths::Get().GetExecutablePath());
155  wxString exePath = exeFileName.GetPath();
156 
158  m_panelControlElements, _("In/Out"),
159  wxImage(exePath + wxFileName::DirName("\\..\\data\\images\\control\\io.png", wxPATH_WIN).GetPath()), ID_IO);
160  wrapSizer->Add(ioButton, 0, wxALL, 5);
161  ioButton->Bind(wxEVT_LEFT_DOWN, &ControlEditor::LeftClickDown, this);
162 
164  m_panelControlElements, _("Transfer fcn"),
165  wxImage(exePath + wxFileName::DirName("\\..\\data\\images\\control\\transferFunc.png", wxPATH_WIN).GetPath()),
166  ID_TF);
167  wrapSizer->Add(tfButton, 0, wxALL, 5);
168  tfButton->Bind(wxEVT_LEFT_DOWN, &ControlEditor::LeftClickDown, this);
169 
171  m_panelControlElements, _("Sum"),
172  wxImage(exePath + wxFileName::DirName("\\..\\data\\images\\control\\sum.png", wxPATH_WIN).GetPath()), ID_SUM);
173  wrapSizer->Add(sumButton, 0, wxALL, 5);
174  sumButton->Bind(wxEVT_LEFT_DOWN, &ControlEditor::LeftClickDown, this);
175 
176  ControlElementButton* constButton = new ControlElementButton(
177  m_panelControlElements, _("Constant"),
178  wxImage(exePath + wxFileName::DirName("\\..\\data\\images\\control\\value.png", wxPATH_WIN).GetPath()),
179  ID_CONST);
180  wrapSizer->Add(constButton, 0, wxALL, 5);
181  constButton->Bind(wxEVT_LEFT_DOWN, &ControlEditor::LeftClickDown, this);
182 
183  ControlElementButton* gainButton = new ControlElementButton(
184  m_panelControlElements, _("Gain"),
185  wxImage(exePath + wxFileName::DirName("\\..\\data\\images\\control\\gain.png", wxPATH_WIN).GetPath()), ID_GAIN);
186  wrapSizer->Add(gainButton, 0, wxALL, 5);
187  gainButton->Bind(wxEVT_LEFT_DOWN, &ControlEditor::LeftClickDown, this);
188 
190  m_panelControlElements, _("Limiter"),
191  wxImage(exePath + wxFileName::DirName("\\..\\data\\images\\control\\limiter.png", wxPATH_WIN).GetPath()),
192  ID_LIMITER);
193  wrapSizer->Add(limButton, 0, wxALL, 5);
194  limButton->Bind(wxEVT_LEFT_DOWN, &ControlEditor::LeftClickDown, this);
195 
196  ControlElementButton* rateLimButton = new ControlElementButton(
197  m_panelControlElements, _("Rate limiter"),
198  wxImage(exePath + wxFileName::DirName("\\..\\data\\images\\control\\rateLimiter.png", wxPATH_WIN).GetPath()),
199  ID_RATELIM);
200  wrapSizer->Add(rateLimButton, 0, wxALL, 5);
201  rateLimButton->Bind(wxEVT_LEFT_DOWN, &ControlEditor::LeftClickDown, this);
202 
203  ControlElementButton* multButton = new ControlElementButton(
204  m_panelControlElements, _("Multiplier"),
205  wxImage(exePath + wxFileName::DirName("\\..\\data\\images\\control\\mult.png", wxPATH_WIN).GetPath()), ID_MULT);
206  wrapSizer->Add(multButton, 0, wxALL, 5);
207  multButton->Bind(wxEVT_LEFT_DOWN, &ControlEditor::LeftClickDown, this);
208 
210  m_panelControlElements, _("Divider"),
211  wxImage(exePath + wxFileName::DirName("\\..\\data\\images\\control\\div.png", wxPATH_WIN).GetPath()),
212  ID_MATH_DIV);
213  wrapSizer->Add(divButton, 0, wxALL, 5);
214  divButton->Bind(wxEVT_LEFT_DOWN, &ControlEditor::LeftClickDown, this);
215 
217  m_panelControlElements, _("Exponential"),
218  wxImage(exePath + wxFileName::DirName("\\..\\data\\images\\control\\sat.png", wxPATH_WIN).GetPath()), ID_EXP);
219  wrapSizer->Add(satButton, 0, wxALL, 5);
220  satButton->Bind(wxEVT_LEFT_DOWN, &ControlEditor::LeftClickDown, this);
221 }
222 
223 void ControlEditor::LeftClickDown(wxMouseEvent& event)
224 {
225  AddElement(static_cast<ControlElementButtonID>(event.GetId()));
226  event.Skip();
227 }
228 
229 void ControlEditor::SetViewport()
230 {
231  glClearColor(1.0, 1.0, 1.0, 1.0); // White background.
232  glClear(GL_COLOR_BUFFER_BIT);
233  glDisable(GL_DEPTH_TEST);
234  glDisable(GL_TEXTURE_2D);
235  glEnable(GL_COLOR_MATERIAL);
236  glEnable(GL_BLEND);
237  glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
238  glEnable(GL_LINE_SMOOTH);
239 
240  double width = m_glCanvas->GetSize().x - 1;
241  double height = m_glCanvas->GetSize().y - 1;
242 
243  // Viewport fit the screen.
244  glViewport(0, 0, width, height);
245 
246  glMatrixMode(GL_PROJECTION);
247  glLoadIdentity();
248  gluOrtho2D(0.0, width, height, 0.0);
249 
250  glMatrixMode(GL_MODELVIEW);
251  glLoadIdentity();
252 }
253 
254 void ControlEditor::AddElement(ControlElementButtonID id)
255 {
256  switch(id) {
257  case ID_IO: {
258  m_mode = MODE_INSERT;
259  IOControl* io = new IOControl(m_ioFlags, GetNextID());
260  m_elementList.push_back(io);
261  } break;
262  case ID_TF: {
263  m_mode = MODE_INSERT;
264  TransferFunction* tf = new TransferFunction(GetNextID());
265  m_elementList.push_back(tf);
266  } break;
267  case ID_SUM: {
268  m_mode = MODE_INSERT;
269  Sum* sum = new Sum(GetNextID());
270  m_elementList.push_back(sum);
271  } break;
272  case ID_CONST: {
273  m_mode = MODE_INSERT;
274  Constant* constant = new Constant(GetNextID());
275  m_elementList.push_back(constant);
276  } break;
277  case ID_LIMITER: {
278  m_mode = MODE_INSERT;
279  Limiter* limiter = new Limiter(GetNextID());
280  m_elementList.push_back(limiter);
281  } break;
282  case ID_GAIN: {
283  m_mode = MODE_INSERT;
284  Gain* gain = new Gain(GetNextID());
285  m_elementList.push_back(gain);
286  } break;
287  case ID_MULT: {
288  m_mode = MODE_INSERT;
289  Multiplier* mult = new Multiplier(GetNextID());
290  m_elementList.push_back(mult);
291  } break;
292  case ID_EXP: {
293  m_mode = MODE_INSERT;
294  Exponential* exp = new Exponential(GetNextID());
295  m_elementList.push_back(exp);
296  } break;
297  case ID_RATELIM: {
298  m_mode = MODE_INSERT;
299  RateLimiter* rateLim = new RateLimiter(GetNextID());
300  m_elementList.push_back(rateLim);
301  } break;
302  case ID_MATH_DIV: {
303  m_mode = MODE_INSERT;
304  Divider* divider = new Divider(GetNextID());
305  m_elementList.push_back(divider);
306  }
307  }
308 }
309 
310 void ControlEditor::OnPaint(wxPaintEvent& event)
311 {
312  wxPaintDC dc(m_glCanvas);
313  m_glContext->SetCurrent(*m_glCanvas);
314  SetViewport();
315 
316  // Set GLCanvas scale and translation.
317  glScaled(m_camera->GetScale(), m_camera->GetScale(), 0.0); // Scale
318  glTranslated(m_camera->GetTranslation().m_x, m_camera->GetTranslation().m_y, 0.0); // Translation
319 
320  for(auto it = m_connectionList.begin(), itEnd = m_connectionList.end(); it != itEnd; ++it) {
321  ConnectionLine* line = *it;
322  line->Draw(m_camera->GetTranslation(), m_camera->GetScale());
323  }
324 
325  for(auto it = m_elementList.begin(), itEnd = m_elementList.end(); it != itEnd; ++it) {
326  Element* element = *it;
327  element->Draw(m_camera->GetTranslation(), m_camera->GetScale());
328  }
329 
330  // Selection rectangle
331  glLineWidth(1.0);
332  glColor4d(0.0, 0.5, 1.0, 1.0);
333  glBegin(GL_LINE_LOOP);
334  glVertex2d(m_selectionRect.m_x, m_selectionRect.m_y);
335  glVertex2d(m_selectionRect.m_x, m_selectionRect.m_y + m_selectionRect.m_height);
336  glVertex2d(m_selectionRect.m_x + m_selectionRect.m_width, m_selectionRect.m_y + m_selectionRect.m_height);
337  glVertex2d(m_selectionRect.m_x + m_selectionRect.m_width, m_selectionRect.m_y);
338  glEnd();
339  glColor4d(0.0, 0.5, 1.0, 0.3);
340  glBegin(GL_QUADS);
341  glVertex2d(m_selectionRect.m_x, m_selectionRect.m_y);
342  glVertex2d(m_selectionRect.m_x, m_selectionRect.m_y + m_selectionRect.m_height);
343  glVertex2d(m_selectionRect.m_x + m_selectionRect.m_width, m_selectionRect.m_y + m_selectionRect.m_height);
344  glVertex2d(m_selectionRect.m_x + m_selectionRect.m_width, m_selectionRect.m_y);
345  glEnd();
346 
347  glFlush(); // Sends all pending information directly to the GPU.
348  m_glCanvas->SwapBuffers();
349  event.Skip();
350 }
351 
352 void ControlEditor::OnDoubleClick(wxMouseEvent& event)
353 {
354  wxPoint2DDouble clickPoint = event.GetPosition();
355  bool redraw = false;
356 
357  if(m_mode == MODE_EDIT) {
358  for(auto it = m_elementList.begin(), itEnd = m_elementList.end(); it != itEnd; ++it) {
359  Element* element = *it;
360  if(element->Contains(m_camera->ScreenToWorld(clickPoint))) {
361  element->ShowForm(this, element);
362  CheckConnections();
363  auto childList = element->GetChildList();
364  for(auto itC = childList.begin(), itEndC = childList.end(); itC != itEndC; ++itC) {
365  ConnectionLine* line = static_cast<ConnectionLine*>(*itC);
366  line->UpdatePoints();
367  }
368  redraw = true;
369  }
370  }
371  }
372 
373  if(redraw) Redraw();
374 }
375 
376 void ControlEditor::OnLeftClickDown(wxMouseEvent& event)
377 {
378  wxPoint2DDouble clickPoint = event.GetPosition();
379  bool foundElement = false;
380 
381  if(m_mode == MODE_INSERT) {
382  m_mode = MODE_EDIT;
383  } else {
384  for(auto it = m_elementList.begin(), itEnd = m_elementList.end(); it != itEnd; ++it) {
385  ControlElement* element = *it;
386  bool foundNode = false;
387  auto nodeList = element->GetNodeList();
388  for(auto itN = nodeList.begin(), itNEnd = nodeList.end(); itN != itNEnd; ++itN) {
389  Node* node = *itN;
390  if(node->Contains(m_camera->ScreenToWorld(clickPoint))) {
391  m_mode = MODE_INSERT_LINE;
392  ConnectionLine* line = new ConnectionLine(node, GetNextID());
393  m_connectionList.push_back(line);
394  element->AddChild(line);
395  line->AddParent(element);
396  foundElement = true;
397  foundNode = true;
398  }
399  }
400 
401  if(!foundNode) {
402  // Set movement initial position (not necessarily will be moved).
403  element->StartMove(m_camera->ScreenToWorld(clickPoint));
404 
405  // Click in an element.
406  if(element->Contains(m_camera->ScreenToWorld(clickPoint))) {
407  if(!foundElement) {
408  element->SetSelected();
409  foundElement = true;
410  }
411  m_mode = MODE_MOVE_ELEMENT;
412  }
413  }
414  }
415  if(m_mode != MODE_INSERT_LINE) {
416  for(auto it = m_connectionList.begin(), itEnd = m_connectionList.end(); it != itEnd; ++it) {
417  ConnectionLine* line = *it;
418  line->StartMove(m_camera->ScreenToWorld(clickPoint));
419  if(line->Contains(m_camera->ScreenToWorld(clickPoint))) {
420  line->SetSelected();
421  foundElement = true;
422  m_mode = MODE_MOVE_LINE;
423  }
424  }
425  }
426  }
427 
428  if(!foundElement) {
429  m_mode = MODE_SELECTION_RECT;
430  m_startSelRect = m_camera->ScreenToWorld(clickPoint);
431  }
432 
433  Redraw();
434  event.Skip();
435 }
436 
437 void ControlEditor::OnLeftClickUp(wxMouseEvent& event)
438 {
439  bool foundNode = false;
440  for(auto it = m_elementList.begin(), itEnd = m_elementList.end(); it != itEnd; it++) {
441  ControlElement* element = *it;
442  if(m_mode == MODE_INSERT_LINE) {
443  auto nodeList = element->GetNodeList();
444  for(auto itN = nodeList.begin(), itNEnd = nodeList.end(); itN != itNEnd; ++itN) {
445  Node* node = *itN;
446  if(node->Contains(m_camera->ScreenToWorld(event.GetPosition()))) {
447  ConnectionLine* line = *(m_connectionList.end() - 1);
448  if(line->AppendNode(node, element)) {
449  line->AddParent(element);
450  element->AddChild(line);
451  line->UpdatePoints();
452  m_mode = MODE_EDIT;
453  foundNode = true;
454  }
455  }
456  }
457  } else if(m_mode == MODE_SELECTION_RECT) {
458  if(element->Intersects(m_selectionRect)) {
459  element->SetSelected();
460  } else if(!event.ControlDown()) {
461  element->SetSelected(false);
462  }
463  } else if(!event.ControlDown()) {
464  if(!element->Contains(m_camera->ScreenToWorld(event.GetPosition()))) {
465  element->SetSelected(false);
466  }
467  }
468  }
469  for(auto it = m_connectionList.begin(), itEnd = m_connectionList.end(); it != itEnd; ++it) {
470  ConnectionLine* cLine = *it;
471  if(m_mode == MODE_INSERT_LINE && !foundNode && it != (itEnd - 1)) {
472  if(cLine->Contains(m_camera->ScreenToWorld(event.GetPosition()))) {
473  ConnectionLine* iLine = *(m_connectionList.end() - 1);
474  if(iLine->SetParentLine(cLine)) {
475  cLine->AddChild(iLine);
476  iLine->UpdatePoints();
477  m_mode = MODE_EDIT;
478  foundNode = true;
479  }
480  }
481  } else if(m_mode == MODE_SELECTION_RECT) {
482  if(cLine->Intersects(m_selectionRect)) {
483  cLine->SetSelected();
484  } else if(!event.ControlDown()) {
485  cLine->SetSelected(false);
486  }
487  } else if(!event.ControlDown()) {
488  if(!cLine->Contains(m_camera->ScreenToWorld(event.GetPosition()))) {
489  cLine->SetSelected(false);
490  }
491  }
492  }
493 
494  m_selectionRect = wxRect2DDouble(0, 0, 0, 0);
495 
496  if(m_mode == MODE_INSERT_LINE && !foundNode) {
497  ConnectionLine* cLine = *(m_connectionList.end() - 1);
498  // Free nodes
499  auto nodeList = cLine->GetNodeList();
500  for(auto itN = nodeList.begin(), itEndN = nodeList.end(); itN != itEndN; ++itN) {
501  Node* node = *itN;
502  node->SetConnected(false);
503  }
504  // Remove the associated child from parents.
505  auto parentList = cLine->GetParentList();
506  for(auto it = parentList.begin(), itEnd = parentList.end(); it != itEnd; ++it) {
507  Element* element = *it;
508  element->RemoveChild(cLine);
509  }
510  m_connectionList.pop_back();
511  if(cLine) delete cLine;
512  m_mode = MODE_EDIT;
513  } else if(m_mode != MODE_INSERT) {
514  m_mode = MODE_EDIT;
515  }
516 
517  Redraw();
518  event.Skip();
519 }
520 
521 void ControlEditor::OnMiddleDown(wxMouseEvent& event)
522 {
523  // Set to drag mode.
524  switch(m_mode) {
525  case MODE_INSERT: {
526  m_mode = MODE_DRAG_INSERT;
527  } break;
528  case MODE_PASTE: {
529  m_mode = MODE_DRAG_PASTE;
530  } break;
531  default: {
532  m_mode = MODE_DRAG;
533  } break;
534  }
535  m_camera->StartTranslation(m_camera->ScreenToWorld(event.GetPosition()));
536 }
537 
538 void ControlEditor::OnMiddleUp(wxMouseEvent& event)
539 {
540  switch(m_mode) {
541  case MODE_DRAG_INSERT: {
542  m_mode = MODE_INSERT;
543  } break;
544  case MODE_DRAG_PASTE: {
545  m_mode = MODE_PASTE;
546  } break;
547  case MODE_INSERT:
548  case MODE_PASTE: {
549  // Does nothing.
550  } break;
551  default: {
552  m_mode = MODE_EDIT;
553  } break;
554  }
555 }
556 
557 void ControlEditor::OnMouseMotion(wxMouseEvent& event)
558 {
559  wxPoint2DDouble clickPoint = event.GetPosition();
560  bool redraw = false;
561 
562  switch(m_mode) {
563  case MODE_INSERT: {
564  Element* newElement = *(m_elementList.end() - 1); // Get the last element in the list.
565  newElement->Move(m_camera->ScreenToWorld(clickPoint));
566  redraw = true;
567  } break;
568  case MODE_INSERT_LINE: {
569  ConnectionLine* line = *(m_connectionList.end() - 1);
570  line->SetTemporarySecondPoint(m_camera->ScreenToWorld(clickPoint));
571  line->UpdatePoints();
572  redraw = true;
573  } break;
574  case MODE_DRAG:
575  case MODE_DRAG_INSERT:
576  case MODE_DRAG_PASTE: {
577  m_camera->SetTranslation(clickPoint);
578  redraw = true;
579  } break;
580  case MODE_MOVE_ELEMENT: {
581  for(auto it = m_elementList.begin(), itEnd = m_elementList.end(); it != itEnd; it++) {
582  Element* element = *it;
583  if(element->IsSelected()) {
584  element->Move(m_camera->ScreenToWorld(clickPoint));
585  auto childList = element->GetChildList();
586  for(auto itC = childList.begin(), itEndC = childList.end(); itC != itEndC; itC++) {
587  ConnectionLine* line = static_cast<ConnectionLine*>(*itC);
588  line->UpdatePoints();
589  }
590  redraw = true;
591  }
592  }
593  } break;
594  case MODE_MOVE_LINE: {
595  for(auto it = m_connectionList.begin(), itEnd = m_connectionList.end(); it != itEnd; it++) {
596  ConnectionLine* line = *it;
597  if(line->IsSelected()) {
598  line->Move(m_camera->ScreenToWorld(clickPoint));
599  redraw = true;
600  }
601  }
602  } break;
603  case MODE_SELECTION_RECT: {
604  wxPoint2DDouble currentPos = m_camera->ScreenToWorld(clickPoint);
605  double x, y, w, h;
606  if(currentPos.m_x < m_startSelRect.m_x) {
607  x = currentPos.m_x;
608  w = m_startSelRect.m_x - currentPos.m_x;
609  } else {
610  x = m_startSelRect.m_x;
611  w = currentPos.m_x - m_startSelRect.m_x;
612  }
613  if(currentPos.m_y < m_startSelRect.m_y) {
614  y = currentPos.m_y;
615  h = m_startSelRect.m_y - currentPos.m_y;
616  } else {
617  y = m_startSelRect.m_y;
618  h = currentPos.m_y - m_startSelRect.m_y;
619  }
620 
621  m_selectionRect = wxRect2DDouble(x, y, w, h);
622  redraw = true;
623  } break;
624  default:
625  break;
626  }
627 
628  if(redraw) Redraw();
629  event.Skip();
630 }
631 
632 void ControlEditor::OnScroll(wxMouseEvent& event)
633 {
634  if(event.GetWheelRotation() > 0)
635  m_camera->SetScale(event.GetPosition(), +0.05);
636  else
637  m_camera->SetScale(event.GetPosition(), -0.05);
638 
639  Redraw();
640 }
641 
642 void ControlEditor::OnIdle(wxIdleEvent& event)
643 {
644  if(m_justOpened) {
645  this->Raise();
646 
647  // Update all text elements
648  m_justOpened = false;
649  for(auto it = m_elementList.begin(), itEnd = m_elementList.end(); it != itEnd; ++it) {
650  ControlElement* element = *it;
651  if(!element->UpdateText()) m_justOpened = true;
652  }
653  Redraw();
654  }
655 }
656 void ControlEditor::OnKeyDown(wxKeyEvent& event)
657 {
658  char key = event.GetUnicodeKey();
659  if(key != WXK_NONE) {
660  switch(key) {
661  case WXK_DELETE: // Delete selected elements.
662  {
663  DeleteSelectedElements();
664  } break;
665  case 'R': // Rotate the selected elements.
666  {
667  RotateSelectedElements(event.GetModifiers() != wxMOD_SHIFT);
668  } break;
669  case 'L': {
670  // tests
671  } break;
672  }
673  }
674 }
675 
676 void ControlEditor::RotateSelectedElements(bool clockwise)
677 {
678  for(auto it = m_elementList.begin(), itEnd = m_elementList.end(); it != itEnd; ++it) {
679  Element* element = *it;
680  if(element->IsSelected()) {
681  element->Rotate(clockwise);
682  auto childList = element->GetChildList();
683  for(auto itC = childList.begin(), itEndC = childList.end(); itC != itEndC; itC++) {
684  ConnectionLine* line = static_cast<ConnectionLine*>(*itC);
685  line->UpdatePoints();
686  }
687  }
688  }
689  Redraw();
690 }
691 
692 void ControlEditor::DeleteSelectedElements()
693 {
694  for(auto it = m_elementList.begin(); it != m_elementList.end(); ++it) {
695  Element* element = *it;
696  if(element->IsSelected()) {
697  // Remove child/parent.
698  auto childList = element->GetChildList();
699  for(auto itC = childList.begin(), itEnd = childList.end(); itC != itEnd; ++itC) {
700  // The child is always a connection line.
701  ConnectionLine* child = static_cast<ConnectionLine*>(*itC);
702  // Delete the connection line.
703  for(auto itCo = m_connectionList.begin(); itCo != m_connectionList.end(); ++itCo) {
704  ConnectionLine* line = *itCo;
705  if(line == child) {
706  itCo = DeleteLineFromList(itCo);
707  break;
708  }
709  }
710  }
711  m_elementList.erase(it--);
712  if(element) delete element;
713  }
714  }
715 
716  for(auto it = m_connectionList.begin(); it != m_connectionList.end(); ++it) {
717  ConnectionLine* line = *it;
718  if(line->IsSelected()) {
719  it = DeleteLineFromList(it);
720  }
721  }
722  Redraw();
723 }
724 
725 std::vector<ConnectionLine*>::iterator ControlEditor::DeleteLineFromList(std::vector<ConnectionLine*>::iterator& it)
726 {
727  ConnectionLine* cLine = *it;
728  auto childList = cLine->GetLineChildList();
729  for(auto itC = childList.begin(), itEndC = childList.end(); itC != itEndC; ++itC) {
730  ConnectionLine* child = *itC;
731  for(auto itL = m_connectionList.begin(); itL != m_connectionList.end(); ++itL) {
732  ConnectionLine* childOnList = *itL;
733  if(childOnList == child) {
734  itL = DeleteLineFromList(itL);
735  }
736  }
737  }
738  // Remove
739  auto parentList = cLine->GetParentList();
740  for(auto itP = parentList.begin(), itEnd = parentList.end(); itP != itEnd; ++itP) {
741  Element* parent = *itP;
742  if(parent) parent->RemoveChild(cLine);
743  }
744  if(cLine->GetParentLine()) cLine->GetParentLine()->RemoveChild(cLine);
745  // Free nodes
746  auto nodeList = cLine->GetNodeList();
747  for(auto itN = nodeList.begin(), itEndN = nodeList.end(); itN != itEndN; ++itN) {
748  Node* node = *itN;
749  node->SetConnected(false);
750  }
751  m_connectionList.erase(it--);
752  if(cLine) delete cLine;
753  return it;
754 }
755 
756 void ControlEditor::CheckConnections()
757 {
758  for(auto it = m_connectionList.begin(); it != m_connectionList.end(); ++it) {
759  ConnectionLine* cLine = *it;
760  if(cLine->GetType() == ConnectionLine::ELEMENT_ELEMENT) {
761  if(cLine->GetParentList().size() < 2) {
762  it = DeleteLineFromList(it);
763  }
764  }
765  }
766 }
767 
768 void ControlEditor::OnExportClick(wxCommandEvent& event)
769 {
770  FileHanding fileHandling(this);
771 
772  wxFileDialog saveFileDialog(this, _("Save CTL file"), "", "", "CTL files (*.ctl)|*.ctl",
773  wxFD_SAVE | wxFD_OVERWRITE_PROMPT);
774  if(saveFileDialog.ShowModal() == wxID_CANCEL) return;
775 
776  fileHandling.SaveControl(saveFileDialog.GetPath());
777  wxFileName fileName(saveFileDialog.GetPath());
778  event.Skip();
779 }
780 
781 void ControlEditor::OnImportClick(wxCommandEvent& event)
782 {
783  wxFileDialog openFileDialog(this, _("Open CTL file"), "", "", "CTL files (*.ctl)|*.ctl",
784  wxFD_OPEN | wxFD_FILE_MUST_EXIST);
785  if(openFileDialog.ShowModal() == wxID_CANCEL) return;
786 
787  wxFileName fileName(openFileDialog.GetPath());
788 
789  FileHanding fileHandling(this);
790  if(!fileHandling.OpenControl(fileName, m_elementList, m_connectionList)) {
791  wxMessageDialog msgDialog(this, _("It was not possible to open the selected file."), _("Error"),
792  wxOK | wxCENTRE | wxICON_ERROR);
793  msgDialog.ShowModal();
794  }
795  Redraw();
796  event.Skip();
797 }
798 
799 void ControlEditor::OnTestClick(wxCommandEvent& event)
800 {
801  ControlSystemTest csTest(this, &m_inputType, &m_startTime, &m_slope, &m_timeStep, &m_simTime);
802  if(csTest.ShowModal() == wxID_OK) {
803  double printStep = 1e-3;
804  double pdbStep = 1e-1;
805 
806  wxProgressDialog pbd(_("Test"), _("Initializing..."), 100, this,
807  wxPD_APP_MODAL | wxPD_AUTO_HIDE | wxPD_CAN_ABORT | wxPD_SMOOTH);
808  ControlElementSolver solver(this, m_timeStep, 1e-5);
809  if(solver.IsOK()) {
810  bool simStopped = false;
811  double currentTime = 0.0;
812  double printTime = 0.0;
813  double pdbTime = 0.0;
814  std::vector<double> time;
815  std::vector<double> solution;
816  std::vector<double> inputV;
817  while(currentTime <= m_simTime) {
818  double input = 0.0;
819  if(currentTime >= m_startTime) {
820  switch(m_inputType) {
821  case 0: {
822  input = m_slope;
823  } break;
824  case 1: {
825  input = m_slope * (currentTime - m_startTime);
826  } break;
827  case 2: {
828  input = m_slope * std::pow(currentTime - m_startTime, 2);
829  } break;
830  default: {
831  input = 0.0;
832  break;
833  }
834  }
835  }
836 
837  // solver.SolveNextStep(input);
838  solver.SetInitialTerminalVoltage(input);
839  solver.SetActivePower(input);
840  solver.SetInitialMecPower(input);
841  solver.SetInitialVelocity(input);
842  solver.SetReactivePower(input);
843  solver.SetTerminalVoltage(input);
844  solver.SetVelocity(input);
845  solver.SolveNextStep();
846 
847  if(printTime >= printStep) {
848  time.push_back(currentTime);
849  solution.push_back(solver.GetLastSolution());
850  inputV.push_back(input);
851  printTime = 0.0;
852  }
853 
854  if(pdbTime > pdbStep) {
855  if(!pbd.Update((currentTime / m_simTime) * 100, wxString::Format("Time = %.2fs", currentTime))) {
856  pbd.Update(100);
857  simStopped = true;
858  currentTime = m_simTime;
859  }
860  pdbTime = 0.0;
861  }
862 
863  printTime += m_timeStep;
864  currentTime += m_timeStep;
865  pdbTime += m_timeStep;
866  }
867  if(!simStopped) {
868  std::vector<ElementPlotData> epdList;
869  ElementPlotData curveData(_("I/O"), ElementPlotData::CT_TEST);
870  curveData.AddData(inputV, _("Input"));
871  curveData.AddData(solution, _("Output"));
872 
873  curveData.SetPlot(0);
874  curveData.SetColour(0, *wxRED);
875  curveData.SetPlot(1);
876  curveData.SetColour(1, *wxBLUE);
877 
878  epdList.push_back(curveData);
879 
880  ChartView* cView = new ChartView(this, epdList, time);
881  cView->Show();
882  cView->UpdatePlot();
883  }
884  } else {
885  wxMessageDialog msgDialog(this, _("It was not possible to solve the control system"), _("Error"),
886  wxOK | wxCENTRE | wxICON_ERROR);
887  msgDialog.ShowModal();
888  }
889  }
890 }
891 
892 void ControlEditor::OnClose(wxCloseEvent& event)
893 {
894  if(m_ctrlContainer) {
895  m_ctrlContainer->FillContainer(this);
896  }
897  event.Skip();
898 }
899 
900 int ControlEditor::GetNextID()
901 {
902  int id = 0;
903  for(auto it = m_elementList.begin(), itEnd = m_elementList.end(); it != itEnd; ++it) {
904  ControlElement* element = *it;
905  if(element->GetID() > id) id = element->GetID();
906  }
907  for(auto it = m_connectionList.begin(), itEnd = m_connectionList.end(); it != itEnd; ++it) {
908  ConnectionLine* line = *it;
909  if(line->GetID() > id) id = line->GetID();
910  }
911  id++;
912  return id;
913 }
virtual void Move(wxPoint2DDouble position)
Move the element other position.
Definition: Element.cpp:123
Multiplies two inputs.
Definition: Multiplier.h:32
Base class of all elements of the program. This class is responsible for manage graphical and his dat...
Definition: Element.h:113
+
void SetSelected(bool selected=true)
Set element selection.
Definition: Element.h:146
Solves in the time the control system. Can solve the control system directly from a ControlEditor or ...
Sum the all inputs (can choose the input signal).
Definition: Sum.h:33
@@ -102,19 +103,22 @@ $(document).ready(function(){initNavTree('_control_editor_8cpp_source.html','');
Save and opens the projects created on disk.
Definition: FileHanding.h:43
virtual void Draw(wxPoint2DDouble translation, double scale) const
Draw the element.
+
virtual bool UpdateText()
Update the OpenGL text in the element (if present).
Limits the input value by superior and inferior values.
Definition: Limiter.h:32
virtual void RemoveChild(Element *child)
Remove a child from the list.
Definition: Element.cpp:354
virtual void StartMove(wxPoint2DDouble position)
Update the element attributes related to the movement.
virtual bool Intersects(wxRect2DDouble rect) const =0
Check if the element&#39;s rect intersects other rect.
Class responsible for the correct visualization of the elements on screen.
Definition: Camera.h:30
-
This class is responsible to handle the user interaction with control elements.
Definition: ControlEditor.h:63
+ +
This class is responsible to handle the user interaction with control elements.
Definition: ControlEditor.h:76
Provides the communication with the power element.
Definition: IOControl.h:35
virtual bool AddParent(Element *parent, wxPoint2DDouble position)
Add a parent to the element. This method must be used on power elements that connect to a bus...
Definition: Element.h:240
virtual void Draw(wxPoint2DDouble translation, double scale) const
Draw the element.
Definition: Element.h:302
+
Control element that divides two inputs.
Definition: Divider.h:32
Generates an output following an exponential function.
Definition: Exponential.h:32
@@ -136,6 +140,7 @@ $(document).ready(function(){initNavTree('_control_editor_8cpp_source.html','');
Base class of a control element. Provide general methods to other control classes.
+
virtual int GetID() const
Get the element ID.
Definition: Element.h:272
virtual bool Contains(wxPoint2DDouble position) const =0
Checks if the element contains a position.
diff --git a/docs/doxygen/html/_control_editor_8h.html b/docs/doxygen/html/_control_editor_8h.html index de363bb..4332121 100644 --- a/docs/doxygen/html/_control_editor_8h.html +++ b/docs/doxygen/html/_control_editor_8h.html @@ -125,7 +125,8 @@ Enumerations ID_MULT, ID_EXP,
-  ID_RATELIM +  ID_RATELIM, +ID_MATH_DIV
}
diff --git a/docs/doxygen/html/_control_editor_8h.js b/docs/doxygen/html/_control_editor_8h.js index 41a8e39..19d15b1 100644 --- a/docs/doxygen/html/_control_editor_8h.js +++ b/docs/doxygen/html/_control_editor_8h.js @@ -11,6 +11,7 @@ var _control_editor_8h = [ "ID_GAIN", "_control_editor_8h.html#a8b2fbb4494abb95ea860e1b6b3cb7076abc8cc51c937d00684cb6967548dbbe12", null ], [ "ID_MULT", "_control_editor_8h.html#a8b2fbb4494abb95ea860e1b6b3cb7076a4db14943629d93315bc091b2d7e8ac1b", null ], [ "ID_EXP", "_control_editor_8h.html#a8b2fbb4494abb95ea860e1b6b3cb7076a9f541dfe8890f2636816ed2d7f8d07d7", null ], - [ "ID_RATELIM", "_control_editor_8h.html#a8b2fbb4494abb95ea860e1b6b3cb7076aec5fbed678b51ff6e1b215cb36ac9bfa", null ] + [ "ID_RATELIM", "_control_editor_8h.html#a8b2fbb4494abb95ea860e1b6b3cb7076aec5fbed678b51ff6e1b215cb36ac9bfa", null ], + [ "ID_MATH_DIV", "_control_editor_8h.html#a8b2fbb4494abb95ea860e1b6b3cb7076a9dc7ab1b6b773b8c0ef749ccf6cff831", null ] ] ] ]; \ No newline at end of file diff --git a/docs/doxygen/html/_control_editor_8h_source.html b/docs/doxygen/html/_control_editor_8h_source.html index f8bfc03..d984ce9 100644 --- a/docs/doxygen/html/_control_editor_8h_source.html +++ b/docs/doxygen/html/_control_editor_8h_source.html @@ -88,7 +88,7 @@ $(document).ready(function(){initNavTree('_control_editor_8h_source.html','');})
ControlEditor.h
-Go to the documentation of this file.
1 /*
2  * Copyright (C) 2017 Thales Lima Oliveira <thales@ufu.br>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program. If not, see <https://www.gnu.org/licenses/>.
16  */
17 
18 #ifndef CONTROLEDITOR_H
19 #define CONTROLEDITOR_H
20 
21 #include "ControlEditorBase.h"
22 #include <wx/wrapsizer.h>
23 #include <wx/dcclient.h>
24 #include <wx/dcscreen.h>
25 #include <wx/graphics.h>
26 #include <GL/gl.h>
27 #include <GL/glu.h>
28 
29 #include <wx/progdlg.h>
30 
31 #include "IOControl.h"
32 #include "ControlSystemTest.h"
33 
34 class FileHanding;
35 class Camera;
36 class Element;
37 class ControlElement;
38 class TransferFunction;
39 class ConnectionLine;
40 class Sum;
41 class Multiplier;
42 class Limiter;
43 class RateLimiter;
44 class Exponential;
45 class Constant;
46 class Gain;
47 
50 
51 class ChartView;
52 class ElementDataObject;
53 
54 enum ControlElementButtonID { ID_IO = 0, ID_TF, ID_SUM, ID_CONST, ID_LIMITER, ID_GAIN, ID_MULT, ID_EXP, ID_RATELIM };
55 
63 class ControlElementButton : public wxWindow
64 {
65  public:
66  ControlElementButton(wxWindow* parent, wxString label, wxImage image, wxWindowID id = wxID_ANY);
68 
69  protected:
70  virtual void OnPaint(wxPaintEvent& event);
71  virtual void OnMouseEnter(wxMouseEvent& event);
72  virtual void OnMouseLeave(wxMouseEvent& event);
73  virtual void OnLeftClickDown(wxMouseEvent& event);
74  virtual void OnLeftClickUp(wxMouseEvent& event);
75 
76  wxString m_label;
77  wxFont m_font;
78  wxPoint m_labelPosition;
79 
80  wxImage m_image;
81  wxSize m_imageSize;
82  wxPoint m_imagePosition;
83 
84  int m_borderSize = 2;
85  bool m_mouseAbove = false;
86  bool m_selected = false;
87 
88  wxSize m_buttonSize;
89 };
90 
92 {
93  public:
94  enum ControlEditorMode {
95  MODE_EDIT = 0,
96  MODE_MOVE_ELEMENT,
97  MODE_MOVE_LINE,
98  MODE_DRAG,
99  MODE_DRAG_INSERT,
100  MODE_INSERT,
101  MODE_INSERT_LINE,
102  MODE_SELECTION_RECT,
103  MODE_PASTE,
104  MODE_DRAG_PASTE
105  };
106 
107  ControlEditor(wxWindow* parent,
108  int ioflags = IOControl::IN_TERMINAL_VOLTAGE | IOControl::IN_VELOCITY | IOControl::OUT_FIELD_VOLTAGE |
109  IOControl::OUT_MEC_POWER);
110  virtual ~ControlEditor();
111 
112  virtual void AddElement(ControlElementButtonID id);
113  virtual void Redraw() { m_glCanvas->Refresh(); }
114  virtual void RotateSelectedElements(bool clockwise);
115  virtual void DeleteSelectedElements();
116  virtual void CheckConnections();
117  virtual std::vector<ConnectionLine*> GetConnectionLineList() const { return m_connectionList; }
118  virtual std::vector<ControlElement*> GetControlElementList() const { return m_elementList; }
119  virtual void SetElementsList(std::vector<ControlElement*> elementList) { m_elementList = elementList; }
120  virtual void SetConnectionsList(std::vector<ConnectionLine*> connectionList) { m_connectionList = connectionList; }
121  virtual void SetControlContainer(ControlElementContainer* ctrlContainer) { m_ctrlContainer = ctrlContainer; }
122  protected:
123  virtual void OnClose(wxCloseEvent& event);
124  virtual void OnTestClick(wxCommandEvent& event);
125  virtual void OnButtonOKClick(wxCommandEvent& event) { Close(); }
126  virtual void OnImportClick(wxCommandEvent& event);
127  virtual void OnExportClick(wxCommandEvent& event);
128  virtual void OnKeyDown(wxKeyEvent& event);
129  virtual void OnIdle(wxIdleEvent& event);
130  virtual void OnScroll(wxMouseEvent& event);
131  virtual void OnDoubleClick(wxMouseEvent& event);
132  virtual void OnLeftClickDown(wxMouseEvent& event);
133  virtual void OnLeftClickUp(wxMouseEvent& event);
134  virtual void OnMiddleDown(wxMouseEvent& event);
135  virtual void OnMiddleUp(wxMouseEvent& event);
136  virtual void OnMouseMotion(wxMouseEvent& event);
137  virtual void OnPaint(wxPaintEvent& event);
138  virtual void LeftClickDown(wxMouseEvent& event);
139 
140  void BuildControlElementPanel();
141  void SetViewport();
142  void ConsolidateTexts();
143  void SetLastElementID();
144 
145  std::vector<ConnectionLine*>::iterator DeleteLineFromList(std::vector<ConnectionLine*>::iterator& it);
146 
147  wxGLContext* m_glContext = NULL;
148  Camera* m_camera = NULL;
149 
150  ControlEditorMode m_mode = MODE_EDIT;
151 
152  wxRect2DDouble m_selectionRect;
153  wxPoint2DDouble m_startSelRect;
154 
155  std::vector<ControlElement*> m_elementList;
156  std::vector<ConnectionLine*> m_connectionList;
157 
158  ControlElementContainer* m_ctrlContainer = NULL;
159 
160  bool m_firstDraw = true;
161  int m_ioFlags;
162 
163  int m_lastElementID = 0;
164 
165  int m_inputType = 0;
166  double m_startTime = 1.0;
167  double m_slope = 1.0;
168  double m_timeStep = 1e-4;
169  double m_simTime = 10.0;
170 };
171 #endif // CONTROLEDITOR_H
Multiplies two inputs.
Definition: Multiplier.h:32
+Go to the documentation of this file.
1 /*
2  * Copyright (C) 2017 Thales Lima Oliveira <thales@ufu.br>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program. If not, see <https://www.gnu.org/licenses/>.
16  */
17 
18 #ifndef CONTROLEDITOR_H
19 #define CONTROLEDITOR_H
20 
21 #include "ControlEditorBase.h"
22 #include <wx/wrapsizer.h>
23 #include <wx/dcclient.h>
24 #include <wx/dcscreen.h>
25 #include <wx/graphics.h>
26 #include <GL/gl.h>
27 #include <GL/glu.h>
28 
29 #include <wx/progdlg.h>
30 
31 #include "IOControl.h"
32 #include "ControlSystemTest.h"
33 
34 class FileHanding;
35 class Camera;
36 class Element;
37 class ControlElement;
38 class TransferFunction;
39 class ConnectionLine;
40 class Sum;
41 class Multiplier;
42 class Limiter;
43 class RateLimiter;
44 class Exponential;
45 class Constant;
46 class Gain;
47 class MathOperation;
48 class Divider;
49 
52 
53 class ChartView;
54 class ElementDataObject;
55 
56 enum ControlElementButtonID {
57  ID_IO = 0,
58  ID_TF,
59  ID_SUM,
60  ID_CONST,
61  ID_LIMITER,
62  ID_GAIN,
63  ID_MULT,
64  ID_EXP,
65  ID_RATELIM,
66  ID_MATH_DIV
67 };
68 
76 class ControlElementButton : public wxWindow
77 {
78  public:
79  ControlElementButton(wxWindow* parent, wxString label, wxImage image, wxWindowID id = wxID_ANY);
81 
82  protected:
83  virtual void OnPaint(wxPaintEvent& event);
84  virtual void OnMouseEnter(wxMouseEvent& event);
85  virtual void OnMouseLeave(wxMouseEvent& event);
86  virtual void OnLeftClickDown(wxMouseEvent& event);
87  virtual void OnLeftClickUp(wxMouseEvent& event);
88 
89  wxString m_label;
90  wxFont m_font;
91  wxPoint m_labelPosition;
92 
93  wxImage m_image;
94  wxSize m_imageSize;
95  wxPoint m_imagePosition;
96 
97  int m_borderSize = 2;
98  bool m_mouseAbove = false;
99  bool m_selected = false;
100 
101  wxSize m_buttonSize;
102 };
103 
105 {
106  public:
107  enum ControlEditorMode {
108  MODE_EDIT = 0,
109  MODE_MOVE_ELEMENT,
110  MODE_MOVE_LINE,
111  MODE_DRAG,
112  MODE_DRAG_INSERT,
113  MODE_INSERT,
114  MODE_INSERT_LINE,
115  MODE_SELECTION_RECT,
116  MODE_PASTE,
117  MODE_DRAG_PASTE
118  };
119 
120  ControlEditor(wxWindow* parent,
121  int ioflags = IOControl::IN_TERMINAL_VOLTAGE | IOControl::IN_VELOCITY | IOControl::OUT_FIELD_VOLTAGE |
122  IOControl::OUT_MEC_POWER);
123  virtual ~ControlEditor();
124 
125  virtual void AddElement(ControlElementButtonID id);
126  virtual void Redraw() { m_glCanvas->Refresh(); }
127  virtual void SetJustOpened(bool justOpened) { m_justOpened = justOpened; }
128  virtual void RotateSelectedElements(bool clockwise);
129  virtual void DeleteSelectedElements();
130  virtual void CheckConnections();
131  virtual std::vector<ConnectionLine*> GetConnectionLineList() const { return m_connectionList; }
132  virtual std::vector<ControlElement*> GetControlElementList() const { return m_elementList; }
133  virtual void SetElementsList(std::vector<ControlElement*> elementList) { m_elementList = elementList; }
134  virtual void SetConnectionsList(std::vector<ConnectionLine*> connectionList) { m_connectionList = connectionList; }
135  virtual void SetControlContainer(ControlElementContainer* ctrlContainer) { m_ctrlContainer = ctrlContainer; }
136  protected:
137  virtual void OnClose(wxCloseEvent& event);
138  virtual void OnTestClick(wxCommandEvent& event);
139  virtual void OnButtonOKClick(wxCommandEvent& event) { Close(); }
140  virtual void OnImportClick(wxCommandEvent& event);
141  virtual void OnExportClick(wxCommandEvent& event);
142  virtual void OnKeyDown(wxKeyEvent& event);
143  virtual void OnIdle(wxIdleEvent& event);
144  virtual void OnScroll(wxMouseEvent& event);
145  virtual void OnDoubleClick(wxMouseEvent& event);
146  virtual void OnLeftClickDown(wxMouseEvent& event);
147  virtual void OnLeftClickUp(wxMouseEvent& event);
148  virtual void OnMiddleDown(wxMouseEvent& event);
149  virtual void OnMiddleUp(wxMouseEvent& event);
150  virtual void OnMouseMotion(wxMouseEvent& event);
151  virtual void OnPaint(wxPaintEvent& event);
152  virtual void LeftClickDown(wxMouseEvent& event);
153 
154  void BuildControlElementPanel();
155  void SetViewport();
156  int GetNextID();
157 
158  std::vector<ConnectionLine*>::iterator DeleteLineFromList(std::vector<ConnectionLine*>::iterator& it);
159 
160  wxGLContext* m_glContext = NULL;
161  Camera* m_camera = NULL;
162 
163  ControlEditorMode m_mode = MODE_EDIT;
164 
165  wxRect2DDouble m_selectionRect;
166  wxPoint2DDouble m_startSelRect;
167 
168  std::vector<ControlElement*> m_elementList;
169  std::vector<ConnectionLine*> m_connectionList;
170 
171  ControlElementContainer* m_ctrlContainer = NULL;
172 
173  bool m_justOpened = false;
174  int m_ioFlags;
175 
176  int m_inputType = 0;
177  double m_startTime = 1.0;
178  double m_slope = 1.0;
179  double m_timeStep = 1e-4;
180  double m_simTime = 10.0;
181 };
182 #endif // CONTROLEDITOR_H
Multiplies two inputs.
Definition: Multiplier.h:32
Base class of all elements of the program. This class is responsible for manage graphical and his dat...
Definition: Element.h:113
Solves in the time the control system. Can solve the control system directly from a ControlEditor or ...
Sum the all inputs (can choose the input signal).
Definition: Sum.h:33
@@ -97,17 +97,19 @@ $(document).ready(function(){initNavTree('_control_editor_8h_source.html','');})
Save and opens the projects created on disk.
Definition: FileHanding.h:43
Limits the input value by superior and inferior values.
Definition: Limiter.h:32
Class responsible for the correct visualization of the elements on screen.
Definition: Camera.h:30
-
This class is responsible to handle the user interaction with control elements.
Definition: ControlEditor.h:63
+
This class is responsible to handle the user interaction with control elements.
Definition: ControlEditor.h:76
+
Control element that divides two inputs.
Definition: Divider.h:32
Generates an output following an exponential function.
Definition: Exponential.h:32
+
Abstract class that define the general behavior of math operation control block.
Definition: MathOperation.h:32
Class to store the elements in the clipboard.
This class is responsible to manage the charts generated in the transient electromechanical studies...
Definition: ChartView.h:40
Limits the rising and/or falling rate.
Definition: RateLimiter.h:32
-
Class that can contain all control elements. Can identify (using RTTI) the elements from a generic li...
+
Class that can contain all control elements. Can identify (using RTTI) the elements from a generic li...
Connection between two control elements or other connection line and an element.
Calculates the time response by a frequency domain transfer function.
- +
A control element that provides a constant value.
Definition: Constant.h:35
diff --git a/docs/doxygen/html/_control_element_8h_source.html b/docs/doxygen/html/_control_element_8h_source.html index 4e1c5d9..038d345 100644 --- a/docs/doxygen/html/_control_element_8h_source.html +++ b/docs/doxygen/html/_control_element_8h_source.html @@ -88,8 +88,9 @@ $(document).ready(function(){initNavTree('_control_element_8h_source.html','');}
ControlElement.h
-Go to the documentation of this file.
1 /*
2  * Copyright (C) 2017 Thales Lima Oliveira <thales@ufu.br>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program. If not, see <https://www.gnu.org/licenses/>.
16  */
17 
18 #ifndef CONTROLELEMENT_H
19 #define CONTROLELEMENT_H
20 
21 #include "Element.h"
22 
30 class Node
31 {
32  public:
33  enum NodeType { NODE_IN = 0, NODE_OUT };
34 
35  Node(wxPoint2DDouble position = wxPoint2DDouble(0, 0), NodeType nodeType = NODE_IN, double borderSize = 0.0);
36  ~Node();
37 
38  wxRect2DDouble GetRect() const { return m_rect; }
39  void SetRect(wxRect2DDouble rect) { m_rect = rect; }
40  wxPoint2DDouble GetPosition() const;
41  void SetPosition(wxPoint2DDouble position);
42 
43  NodeType GetNodeType() const { return m_nodeType; }
44  void SetNodeType(NodeType nodeType) { m_nodeType = nodeType; }
45  double GetRadius() const { return m_radius; }
46  std::vector<wxPoint2DDouble> GetInTrianglePts() const { return m_triPts; }
47  double GetAngle() const { return m_angle; }
48  void SetAngle(double angle) { m_angle = angle; }
49  void Rotate(bool clockwise = true);
50 
51  void RotateTriPt(double angle);
52 
53  void StartMove(wxPoint2DDouble position);
54  void Move(wxPoint2DDouble position);
55  bool Contains(wxPoint2DDouble position) const;
56 
57  bool IsConnected() const { return m_connected; }
58  void SetConnected(bool connected = true) { m_connected = connected; }
59  int GetID() const { return m_id; }
60  void SetID(int id) { m_id = id; }
61  protected:
62  int m_id = -1;
63 
64  wxRect2DDouble m_rect;
65  NodeType m_nodeType;
66 
67  bool m_connected = false;
68 
69  wxPoint2DDouble m_moveStartPt;
70  wxPoint2DDouble m_movePos;
71 
72  double m_radius = 3.0;
73  std::vector<wxPoint2DDouble> m_triPts;
74  double m_angle = 0.0;
75 };
76 
84 class ControlElement : public Element
85 {
86  public:
87  ControlElement(int id);
88  ~ControlElement();
89 
90  virtual void StartMove(wxPoint2DDouble position);
91  virtual void Move(wxPoint2DDouble position);
92 
93  void SetNodeList(std::vector<Node*> nodeList) { m_nodeList = nodeList; }
94  std::vector<Node*> GetNodeList() const { return m_nodeList; }
95  virtual void DrawNodes() const;
96  virtual void ReplaceNode(Node* oldNode, Node* newNode);
97  virtual void UpdateText() {}
98  virtual bool IsSolved() const { return m_solved; }
99  virtual void SetSolved(bool solved = true) { m_solved = solved; }
100  virtual bool Solve(double input, double timeStep);
101  virtual double GetOutput() const { return m_output; }
102  virtual void SetOutput(double output) { m_output = output; }
103  protected:
104  std::vector<Node*> m_nodeList;
105  bool m_solved = false;
106  double m_output = 0.0;
107 };
108 
109 #endif // CONTROLELEMENT_H
Base class of all elements of the program. This class is responsible for manage graphical and his dat...
Definition: Element.h:113
+Go to the documentation of this file.
1 /*
2  * Copyright (C) 2017 Thales Lima Oliveira <thales@ufu.br>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program. If not, see <https://www.gnu.org/licenses/>.
16  */
17 
18 #ifndef CONTROLELEMENT_H
19 #define CONTROLELEMENT_H
20 
21 #include "Element.h"
22 
30 class Node
31 {
32  public:
33  enum NodeType { NODE_IN = 0, NODE_OUT };
34 
35  Node(wxPoint2DDouble position = wxPoint2DDouble(0, 0), NodeType nodeType = NODE_IN, double borderSize = 0.0);
36  ~Node();
37 
38  wxRect2DDouble GetRect() const { return m_rect; }
39  void SetRect(wxRect2DDouble rect) { m_rect = rect; }
40  wxPoint2DDouble GetPosition() const;
41  void SetPosition(wxPoint2DDouble position);
42 
43  NodeType GetNodeType() const { return m_nodeType; }
44  void SetNodeType(NodeType nodeType) { m_nodeType = nodeType; }
45  double GetRadius() const { return m_radius; }
46  std::vector<wxPoint2DDouble> GetInTrianglePts() const { return m_triPts; }
47  double GetAngle() const { return m_angle; }
48  void SetAngle(double angle) { m_angle = angle; }
49  void Rotate(bool clockwise = true);
50 
51  void RotateTriPt(double angle);
52 
53  void StartMove(wxPoint2DDouble position);
54  void Move(wxPoint2DDouble position);
55  bool Contains(wxPoint2DDouble position) const;
56 
57  bool IsConnected() const { return m_connected; }
58  void SetConnected(bool connected = true) { m_connected = connected; }
59  int GetID() const { return m_id; }
60  void SetID(int id) { m_id = id; }
61  protected:
62  int m_id = -1;
63 
64  wxRect2DDouble m_rect;
65  NodeType m_nodeType;
66 
67  bool m_connected = false;
68 
69  wxPoint2DDouble m_moveStartPt;
70  wxPoint2DDouble m_movePos;
71 
72  double m_radius = 3.0;
73  std::vector<wxPoint2DDouble> m_triPts;
74  double m_angle = 0.0;
75 };
76 
84 class ControlElement : public Element
85 {
86  public:
87  ControlElement(int id);
88  ~ControlElement();
89 
90  virtual void StartMove(wxPoint2DDouble position);
91  virtual void Move(wxPoint2DDouble position);
92 
93  void SetNodeList(std::vector<Node*> nodeList) { m_nodeList = nodeList; }
94  std::vector<Node*> GetNodeList() const { return m_nodeList; }
95  virtual void DrawNodes() const;
96  virtual void ReplaceNode(Node* oldNode, Node* newNode);
97 
102  virtual bool UpdateText() { return true; }
103  virtual bool IsSolved() const { return m_solved; }
104  virtual void SetSolved(bool solved = true) { m_solved = solved; }
105  virtual bool Solve(double input, double timeStep);
106  virtual double GetOutput() const { return m_output; }
107  virtual void SetOutput(double output) { m_output = output; }
108  protected:
109  std::vector<Node*> m_nodeList;
110  bool m_solved = false;
111  double m_output = 0.0;
112 };
113 
114 #endif // CONTROLELEMENT_H
Base class of all elements of the program. This class is responsible for manage graphical and his dat...
Definition: Element.h:113
Node of a control element. This class manages the user interaction with the connection and control el...
+
virtual bool UpdateText()
Update the OpenGL text in the element (if present).
diff --git a/docs/doxygen/html/_control_element_container_8cpp_source.html b/docs/doxygen/html/_control_element_container_8cpp_source.html index 1e4bdf8..c2be813 100644 --- a/docs/doxygen/html/_control_element_container_8cpp_source.html +++ b/docs/doxygen/html/_control_element_container_8cpp_source.html @@ -88,8 +88,7 @@ $(document).ready(function(){initNavTree('_control_element_container_8cpp_source
ControlElementContainer.cpp
-
1 /*
2  * Copyright (C) 2017 Thales Lima Oliveira <thales@ufu.br>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program. If not, see <https://www.gnu.org/licenses/>.
16  */
17 
19 #include "ControlEditor.h"
20 #include "ControlElement.h"
21 
22 ControlElementContainer::ControlElementContainer() { ClearContainer(); }
23 ControlElementContainer::~ControlElementContainer() {}
24 void ControlElementContainer::FillContainer(ControlEditor* editor)
25 {
26  ClearContainer();
27  m_ctrlElementsList = editor->GetControlElementList();
28  m_cLineList = editor->GetConnectionLineList();
29  auto cElementList = editor->GetControlElementList();
30  for(auto it = cElementList.begin(), itEnd = cElementList.end(); it != itEnd; ++it) {
31  if(Constant* constant = dynamic_cast<Constant*>(*it)) {
32  m_constantList.push_back(constant);
33  } else if(Exponential* exponential = dynamic_cast<Exponential*>(*it)) {
34  m_exponentialList.push_back(exponential);
35  } else if(Gain* gain = dynamic_cast<Gain*>(*it)) {
36  m_gainList.push_back(gain);
37  } else if(IOControl* ioControl = dynamic_cast<IOControl*>(*it)) {
38  m_ioControlList.push_back(ioControl);
39  } else if(Limiter* limiter = dynamic_cast<Limiter*>(*it)) {
40  m_limiterList.push_back(limiter);
41  } else if(Multiplier* multiplier = dynamic_cast<Multiplier*>(*it)) {
42  m_multiplierList.push_back(multiplier);
43  } else if(RateLimiter* rateLimiter = dynamic_cast<RateLimiter*>(*it)) {
44  m_rateLimiterList.push_back(rateLimiter);
45  } else if(Sum* sum = dynamic_cast<Sum*>(*it)) {
46  m_sumList.push_back(sum);
47  } else if(TransferFunction* tf = dynamic_cast<TransferFunction*>(*it)) {
48  m_tfList.push_back(tf);
49  }
50  }
51 }
52 
53 void ControlElementContainer::ClearContainer()
54 {
55  m_cLineList.clear();
56  m_constantList.clear();
57  m_exponentialList.clear();
58  m_gainList.clear();
59  m_ioControlList.clear();
60  m_limiterList.clear();
61  m_multiplierList.clear();
62  m_rateLimiterList.clear();
63  m_sumList.clear();
64  m_tfList.clear();
65 }
66 
67 void ControlElementContainer::FillContainer(std::vector<ControlElement*> controlElementList,
68  std::vector<ConnectionLine*> connectionLineList)
69 {
70  ClearContainer();
71  m_ctrlElementsList = controlElementList;
72  m_cLineList = connectionLineList;
73 
74  for(auto it = controlElementList.begin(), itEnd = controlElementList.end(); it != itEnd; ++it) {
75  if(Constant* constant = dynamic_cast<Constant*>(*it)) {
76  m_constantList.push_back(constant);
77  } else if(Exponential* exponential = dynamic_cast<Exponential*>(*it)) {
78  m_exponentialList.push_back(exponential);
79  } else if(Gain* gain = dynamic_cast<Gain*>(*it)) {
80  m_gainList.push_back(gain);
81  } else if(IOControl* ioControl = dynamic_cast<IOControl*>(*it)) {
82  m_ioControlList.push_back(ioControl);
83  } else if(Limiter* limiter = dynamic_cast<Limiter*>(*it)) {
84  m_limiterList.push_back(limiter);
85  } else if(Multiplier* multiplier = dynamic_cast<Multiplier*>(*it)) {
86  m_multiplierList.push_back(multiplier);
87  } else if(RateLimiter* rateLimiter = dynamic_cast<RateLimiter*>(*it)) {
88  m_rateLimiterList.push_back(rateLimiter);
89  } else if(Sum* sum = dynamic_cast<Sum*>(*it)) {
90  m_sumList.push_back(sum);
91  } else if(TransferFunction* tf = dynamic_cast<TransferFunction*>(*it)) {
92  m_tfList.push_back(tf);
93  }
94  }
95 }
96 
97 void ControlElementContainer::GetContainerCopy(std::vector<ControlElement*>& controlElementList,
98  std::vector<ConnectionLine*>& connectionLineList)
99 {
100  controlElementList.clear();
101  connectionLineList.clear();
102 
103  // Copy connection lines
104  for(auto it = m_cLineList.begin(), itEnd = m_cLineList.end(); it != itEnd; ++it) {
105  ConnectionLine* copy = static_cast<ConnectionLine*>((*it)->GetCopy());
106  connectionLineList.push_back(copy);
107  }
108 
109  // Copy elements (exept connection line).
110  int nodeID = 0;
111  for(auto it = m_ctrlElementsList.begin(), itEnd = m_ctrlElementsList.end(); it != itEnd; ++it) {
112  Element* oldElement = *it;
113  ControlElement* copy = static_cast<ControlElement*>(oldElement->GetCopy());
114  controlElementList.push_back(copy);
115  // Copy nodes.
116  std::vector<Node*> nodeList = copy->GetNodeList();
117  std::vector<Node*> nodeListCopy;
118  for(auto itN = nodeList.begin(), itEndN = nodeList.end(); itN != itEndN; ++itN) {
119  Node* node = *itN;
120  node->SetID(nodeID);
121  Node* copyNode = new Node();
122  *copyNode = *node;
123  nodeListCopy.push_back(copyNode);
124  nodeID++;
125  }
126  copy->SetNodeList(nodeListCopy);
127 
128  // Replace children to copies.
129  auto childList = copy->GetChildList();
130  for(auto itC = childList.begin(), itEndC = childList.end(); itC != itEndC; ++itC) {
131  ConnectionLine* child = static_cast<ConnectionLine*>(*itC);
132  // Replace child's parent to copy.
133  for(auto itCL = connectionLineList.begin(), itEndCL = connectionLineList.end(); itCL != itEndCL; ++itCL) {
134  ConnectionLine* copyLine = *itCL;
135  if(copyLine->GetID() == child->GetID()) {
136  // Replace node.
137  nodeList = child->GetNodeList();
138  for(auto itN = nodeList.begin(), itEndN = nodeList.end(); itN != itEndN; ++itN) {
139  Node* node = *itN;
140  for(auto itCN = nodeListCopy.begin(), itEndCN = nodeListCopy.end(); itCN != itEndCN; ++itCN) {
141  Node* nodeCopy = *itCN;
142  if(node->GetID() == nodeCopy->GetID()) {
143  copyLine->ReplaceNode(node, nodeCopy);
144  break;
145  }
146  }
147  }
148  copyLine->ReplaceParent(oldElement, copy);
149  copy->ReplaceChild(child, copyLine);
150  }
151  }
152  }
153  }
154 }
Multiplies two inputs.
Definition: Multiplier.h:32
-
Base class of all elements of the program. This class is responsible for manage graphical and his dat...
Definition: Element.h:113
+
1 /*
2  * Copyright (C) 2017 Thales Lima Oliveira <thales@ufu.br>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program. If not, see <https://www.gnu.org/licenses/>.
16  */
17 
19 #include "ControlEditor.h"
20 #include "ControlElement.h"
21 
22 ControlElementContainer::ControlElementContainer() { ClearContainer(); }
23 ControlElementContainer::~ControlElementContainer() {}
24 void ControlElementContainer::FillContainer(ControlEditor* editor)
25 {
26  ClearContainer();
27  m_ctrlElementsList = editor->GetControlElementList();
28  m_cLineList = editor->GetConnectionLineList();
29  auto cElementList = editor->GetControlElementList();
30  for(auto it = cElementList.begin(), itEnd = cElementList.end(); it != itEnd; ++it) {
31  if(Constant* constant = dynamic_cast<Constant*>(*it)) {
32  m_constantList.push_back(constant);
33  } else if(Exponential* exponential = dynamic_cast<Exponential*>(*it)) {
34  m_exponentialList.push_back(exponential);
35  } else if(Gain* gain = dynamic_cast<Gain*>(*it)) {
36  m_gainList.push_back(gain);
37  } else if(IOControl* ioControl = dynamic_cast<IOControl*>(*it)) {
38  m_ioControlList.push_back(ioControl);
39  } else if(Limiter* limiter = dynamic_cast<Limiter*>(*it)) {
40  m_limiterList.push_back(limiter);
41  } else if(Multiplier* multiplier = dynamic_cast<Multiplier*>(*it)) {
42  m_multiplierList.push_back(multiplier);
43  } else if(RateLimiter* rateLimiter = dynamic_cast<RateLimiter*>(*it)) {
44  m_rateLimiterList.push_back(rateLimiter);
45  } else if(Sum* sum = dynamic_cast<Sum*>(*it)) {
46  m_sumList.push_back(sum);
47  } else if(TransferFunction* tf = dynamic_cast<TransferFunction*>(*it)) {
48  m_tfList.push_back(tf);
49  } else if(Divider* divider = dynamic_cast<Divider*>(*it)) {
50  m_dividerList.push_back(divider);
51  }
52  }
53 }
54 
55 void ControlElementContainer::ClearContainer()
56 {
57  m_cLineList.clear();
58  m_constantList.clear();
59  m_exponentialList.clear();
60  m_gainList.clear();
61  m_ioControlList.clear();
62  m_limiterList.clear();
63  m_multiplierList.clear();
64  m_rateLimiterList.clear();
65  m_sumList.clear();
66  m_tfList.clear();
67  m_dividerList.clear();
68 }
69 
70 void ControlElementContainer::FillContainer(std::vector<ControlElement*> controlElementList,
71  std::vector<ConnectionLine*> connectionLineList)
72 {
73  ClearContainer();
74  m_ctrlElementsList = controlElementList;
75  m_cLineList = connectionLineList;
76 
77  for(auto it = controlElementList.begin(), itEnd = controlElementList.end(); it != itEnd; ++it) {
78  if(Constant* constant = dynamic_cast<Constant*>(*it)) {
79  m_constantList.push_back(constant);
80  } else if(Exponential* exponential = dynamic_cast<Exponential*>(*it)) {
81  m_exponentialList.push_back(exponential);
82  } else if(Gain* gain = dynamic_cast<Gain*>(*it)) {
83  m_gainList.push_back(gain);
84  } else if(IOControl* ioControl = dynamic_cast<IOControl*>(*it)) {
85  m_ioControlList.push_back(ioControl);
86  } else if(Limiter* limiter = dynamic_cast<Limiter*>(*it)) {
87  m_limiterList.push_back(limiter);
88  } else if(Multiplier* multiplier = dynamic_cast<Multiplier*>(*it)) {
89  m_multiplierList.push_back(multiplier);
90  } else if(RateLimiter* rateLimiter = dynamic_cast<RateLimiter*>(*it)) {
91  m_rateLimiterList.push_back(rateLimiter);
92  } else if(Sum* sum = dynamic_cast<Sum*>(*it)) {
93  m_sumList.push_back(sum);
94  } else if(TransferFunction* tf = dynamic_cast<TransferFunction*>(*it)) {
95  m_tfList.push_back(tf);
96  } else if(Divider* divider = dynamic_cast<Divider*>(*it)) {
97  m_dividerList.push_back(divider);
98  }
99  }
100 }
101 
102 void ControlElementContainer::GetContainerCopy(std::vector<ControlElement*>& controlElementList,
103  std::vector<ConnectionLine*>& connectionLineList)
104 {
105  controlElementList.clear();
106  connectionLineList.clear();
107 
108  // Copy connection lines
109  for(auto it = m_cLineList.begin(), itEnd = m_cLineList.end(); it != itEnd; ++it) {
110  ConnectionLine* copy = static_cast<ConnectionLine*>((*it)->GetCopy());
111  connectionLineList.push_back(copy);
112  }
113 
114  // Copy elements (exept connection line).
115  int nodeID = 0;
116  for(auto it = m_ctrlElementsList.begin(), itEnd = m_ctrlElementsList.end(); it != itEnd; ++it) {
117  ControlElement* oldElement = *it;
118  ControlElement* copy = static_cast<ControlElement*>(oldElement->GetCopy());
119  controlElementList.push_back(copy);
120  // Copy nodes.
121  std::vector<Node*> nodeList = copy->GetNodeList();
122  std::vector<Node*> nodeListCopy;
123  for(auto itN = nodeList.begin(), itEndN = nodeList.end(); itN != itEndN; ++itN) {
124  Node* node = *itN;
125  node->SetID(nodeID);
126  Node* copyNode = new Node();
127  *copyNode = *node;
128  nodeListCopy.push_back(copyNode);
129  nodeID++;
130  }
131  copy->SetNodeList(nodeListCopy);
132 
133  // Replace children to copies.
134  auto childList = copy->GetChildList();
135  for(auto itC = childList.begin(), itEndC = childList.end(); itC != itEndC; ++itC) {
136  ConnectionLine* child = static_cast<ConnectionLine*>(*itC);
137  // Replace child's parent to copy.
138  for(auto itCL = connectionLineList.begin(), itEndCL = connectionLineList.end(); itCL != itEndCL; ++itCL) {
139  ConnectionLine* copyLine = *itCL;
140  if(copyLine->GetID() == child->GetID()) {
141  // Replace node.
142  nodeList = child->GetNodeList();
143  for(auto itN = nodeList.begin(), itEndN = nodeList.end(); itN != itEndN; ++itN) {
144  Node* node = *itN;
145  for(auto itCN = nodeListCopy.begin(), itEndCN = nodeListCopy.end(); itCN != itEndCN; ++itCN) {
146  Node* nodeCopy = *itCN;
147  if(node->GetID() == nodeCopy->GetID()) {
148  copyLine->ReplaceNode(node, nodeCopy);
149  break;
150  }
151  }
152  }
153  copyLine->ReplaceParent(oldElement, copy);
154  copy->ReplaceChild(child, copyLine);
155  }
156  }
157  }
158  }
159 }
Multiplies two inputs.
Definition: Multiplier.h:32
Sum the all inputs (can choose the input signal).
Definition: Sum.h:33
Provide an output multiplying the input by a constant.
Definition: Gain.h:35
virtual std::vector< Element * > GetChildList() const
Get the Child list.
Definition: Element.h:511
@@ -98,12 +97,13 @@ $(document).ready(function(){initNavTree('_control_element_container_8cpp_source
Provides the communication with the power element.
Definition: IOControl.h:35
virtual void ReplaceChild(Element *oldChild, Element *newChild)
Replace a child from the list.
Definition: Element.cpp:362
+
Control element that divides two inputs.
Definition: Divider.h:32
Generates an output following an exponential function.
Definition: Exponential.h:32
Limits the rising and/or falling rate.
Definition: RateLimiter.h:32
Connection between two control elements or other connection line and an element.
Calculates the time response by a frequency domain transfer function.
- +
Base class of a control element. Provide general methods to other control classes.
virtual int GetID() const
Get the element ID.
Definition: Element.h:272
virtual void ReplaceParent(Element *oldParent, Element *newParent)
Replace a parent.
Definition: Element.cpp:346
diff --git a/docs/doxygen/html/_control_element_container_8h.html b/docs/doxygen/html/_control_element_container_8h.html index 1b8b197..585eee8 100644 --- a/docs/doxygen/html/_control_element_container_8h.html +++ b/docs/doxygen/html/_control_element_container_8h.html @@ -101,6 +101,7 @@ $(document).ready(function(){initNavTree('_control_element_container_8h.html','' #include "RateLimiter.h"
#include "Sum.h"
#include "TransferFunction.h"
+#include "Divider.h"

Go to the source code of this file.

 
diff --git a/docs/doxygen/html/_control_element_container_8h_source.html b/docs/doxygen/html/_control_element_container_8h_source.html index c91c02d..80e77c4 100644 --- a/docs/doxygen/html/_control_element_container_8h_source.html +++ b/docs/doxygen/html/_control_element_container_8h_source.html @@ -88,14 +88,15 @@ $(document).ready(function(){initNavTree('_control_element_container_8h_source.h
ControlElementContainer.h
-Go to the documentation of this file.
1 /*
2  * Copyright (C) 2017 Thales Lima Oliveira <thales@ufu.br>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program. If not, see <https://www.gnu.org/licenses/>.
16  */
17 
18 #ifndef CONTROLELEMENTCONTAINER_H
19 #define CONTROLELEMENTCONTAINER_H
20 
21 #include <vector>
22 
23 class ControlEditor;
24 class ControlElement;
25 
26 #include "ConnectionLine.h"
27 #include "Constant.h"
28 #include "Exponential.h"
29 #include "Gain.h"
30 #include "IOControl.h"
31 #include "Limiter.h"
32 #include "Multiplier.h"
33 #include "RateLimiter.h"
34 #include "Sum.h"
35 #include "TransferFunction.h"
36 
46 {
47  public:
50 
51  virtual void FillContainer(ControlEditor* editor);
52  virtual void FillContainer(std::vector<ControlElement*> controlElementList,
53  std::vector<ConnectionLine*> connectionLineList);
54  virtual void GetContainerCopy(std::vector<ControlElement*>& controlElementList,
55  std::vector<ConnectionLine*>& connectionLineList);
56  virtual void ClearContainer();
57 
58  std::vector<ControlElement*> GetControlElementsList() const { return m_ctrlElementsList; }
59  std::vector<ConnectionLine*> GetConnectionLineList() const { return m_cLineList; }
60  std::vector<Constant*> GetConstantList() const { return m_constantList; }
61  std::vector<Exponential*> GetExponentialList() const { return m_exponentialList; }
62  std::vector<Gain*> GetGainList() const { return m_gainList; }
63  std::vector<IOControl*> GetIOControlList() const { return m_ioControlList; }
64  std::vector<Limiter*> GetLimiterList() const { return m_limiterList; }
65  std::vector<Multiplier*> GetMultiplierList() const { return m_multiplierList; }
66  std::vector<RateLimiter*> GetRateLimiterList() const { return m_rateLimiterList; }
67  std::vector<Sum*> GetSumList() const { return m_sumList; }
68  std::vector<TransferFunction*> GetTFList() const { return m_tfList; }
69  protected:
70  std::vector<ControlElement*> m_ctrlElementsList;
71  std::vector<Constant*> m_constantList;
72 
73  std::vector<ConnectionLine*> m_cLineList;
74  std::vector<Exponential*> m_exponentialList;
75  std::vector<Gain*> m_gainList;
76  std::vector<IOControl*> m_ioControlList;
77  std::vector<Limiter*> m_limiterList;
78  std::vector<Multiplier*> m_multiplierList;
79  std::vector<RateLimiter*> m_rateLimiterList;
80  std::vector<Sum*> m_sumList;
81  std::vector<TransferFunction*> m_tfList;
82 };
83 
84 #endif // CONTROLELEMENTCONTAINER_H
+Go to the documentation of this file.
1 /*
2  * Copyright (C) 2017 Thales Lima Oliveira <thales@ufu.br>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program. If not, see <https://www.gnu.org/licenses/>.
16  */
17 
18 #ifndef CONTROLELEMENTCONTAINER_H
19 #define CONTROLELEMENTCONTAINER_H
20 
21 #include <vector>
22 
23 class ControlEditor;
24 class ControlElement;
25 
26 #include "ConnectionLine.h"
27 #include "Constant.h"
28 #include "Exponential.h"
29 #include "Gain.h"
30 #include "IOControl.h"
31 #include "Limiter.h"
32 #include "Multiplier.h"
33 #include "RateLimiter.h"
34 #include "Sum.h"
35 #include "TransferFunction.h"
36 #include "Divider.h"
37 
47 {
48  public:
51 
52  virtual void FillContainer(ControlEditor* editor);
53  virtual void FillContainer(std::vector<ControlElement*> controlElementList,
54  std::vector<ConnectionLine*> connectionLineList);
55  virtual void GetContainerCopy(std::vector<ControlElement*>& controlElementList,
56  std::vector<ConnectionLine*>& connectionLineList);
57  virtual void ClearContainer();
58 
59  std::vector<ControlElement*> GetControlElementsList() const { return m_ctrlElementsList; }
60  std::vector<ConnectionLine*> GetConnectionLineList() const { return m_cLineList; }
61  std::vector<Constant*> GetConstantList() const { return m_constantList; }
62  std::vector<Exponential*> GetExponentialList() const { return m_exponentialList; }
63  std::vector<Gain*> GetGainList() const { return m_gainList; }
64  std::vector<IOControl*> GetIOControlList() const { return m_ioControlList; }
65  std::vector<Limiter*> GetLimiterList() const { return m_limiterList; }
66  std::vector<Multiplier*> GetMultiplierList() const { return m_multiplierList; }
67  std::vector<RateLimiter*> GetRateLimiterList() const { return m_rateLimiterList; }
68  std::vector<Sum*> GetSumList() const { return m_sumList; }
69  std::vector<TransferFunction*> GetTFList() const { return m_tfList; }
70  std::vector<Divider*> GetDividerList() const { return m_dividerList; }
71  protected:
72  std::vector<ControlElement*> m_ctrlElementsList;
73  std::vector<Constant*> m_constantList;
74  std::vector<ConnectionLine*> m_cLineList;
75  std::vector<Exponential*> m_exponentialList;
76  std::vector<Gain*> m_gainList;
77  std::vector<IOControl*> m_ioControlList;
78  std::vector<Limiter*> m_limiterList;
79  std::vector<Multiplier*> m_multiplierList;
80  std::vector<RateLimiter*> m_rateLimiterList;
81  std::vector<Sum*> m_sumList;
82  std::vector<TransferFunction*> m_tfList;
83  std::vector<Divider*> m_dividerList;
84 };
85 
86 #endif // CONTROLELEMENTCONTAINER_H
+ -
Class that can contain all control elements. Can identify (using RTTI) the elements from a generic li...
+
Class that can contain all control elements. Can identify (using RTTI) the elements from a generic li...
- + diff --git a/docs/doxygen/html/_control_element_solver_8cpp_source.html b/docs/doxygen/html/_control_element_solver_8cpp_source.html index a103734..5611b4e 100644 --- a/docs/doxygen/html/_control_element_solver_8cpp_source.html +++ b/docs/doxygen/html/_control_element_solver_8cpp_source.html @@ -88,23 +88,24 @@ $(document).ready(function(){initNavTree('_control_element_solver_8cpp_source.ht
ControlElementSolver.cpp
-
1 /*
2  * Copyright (C) 2017 Thales Lima Oliveira <thales@ufu.br>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program. If not, see <https://www.gnu.org/licenses/>.
16  */
17 
18 #include "ControlElementSolver.h"
19 
21 #include "ControlEditor.h"
22 #include "ConnectionLine.h"
23 #include "Constant.h"
24 #include "Exponential.h"
25 #include "Gain.h"
26 #include "IOControl.h"
27 #include "Limiter.h"
28 #include "Multiplier.h"
29 #include "RateLimiter.h"
30 #include "Sum.h"
31 #include "TransferFunction.h"
32 
33 ControlElementSolver::ControlElementSolver(ControlEditor* controlEditor,
34  double timeStep,
35  double integrationError,
36  bool startAllZero,
37  double input)
38 {
39  m_ctrlContainer = new ControlElementContainer();
40  m_ctrlContainer->FillContainer(controlEditor);
41  Initialize(controlEditor, timeStep, integrationError, startAllZero, input);
42 }
43 
44 ControlElementSolver::ControlElementSolver(ControlElementContainer* ctrlContainer,
45  double timeStep,
46  double integrationError,
47  bool startAllZero,
48  double input,
49  wxWindow* parent)
50 {
51  m_ctrlContainer = ctrlContainer;
52  Initialize(parent, timeStep, integrationError, startAllZero, input);
53 }
54 
55 void ControlElementSolver::Initialize(wxWindow* parent,
56  double timeStep,
57  double integrationError,
58  bool startAllZero,
59  double input)
60 {
61  // Check if the sistem have one input and one output
62  bool fail = false;
63  wxString failMessage = "";
64  auto ioList = m_ctrlContainer->GetIOControlList();
65  if(ioList.size() != 2) {
66  fail = true;
67  failMessage = _("The control system must have one input and one output.");
68  }
69  bool haveInput, haveOutput;
70  haveInput = haveOutput = false;
71  for(auto it = ioList.begin(), itEnd = ioList.end(); it != itEnd; ++it) {
72  IOControl* io = *it;
73  if(io->GetType() == Node::NODE_OUT) {
74  m_inputControl = io;
75  haveInput = true;
76  } else if(io->GetType() == Node::NODE_IN) {
77  m_outputControl = io;
78  haveOutput = true;
79  }
80  }
81  if(!fail && !haveInput) {
82  fail = true;
83  failMessage = _("There is no input in the control system.");
84  }
85  if(!fail && !haveOutput) {
86  fail = true;
87  failMessage = _("There is no output in the control system.");
88  }
89  if(!fail) {
90  if(m_inputControl->GetChildList().size() == 0) {
91  fail = true;
92  failMessage = _("Input not connected.");
93  }
94  }
95 
96  m_timeStep = timeStep;
97  m_integrationError = integrationError;
98  if(!fail) {
99  if(!InitializeValues(input, startAllZero)) {
100  fail = true;
101  failMessage = _("It was not possible to initialize the control system.");
102  }
103  }
104 
105  if(fail) {
106  wxMessageDialog msgDialog(parent, failMessage, _("Error"), wxOK | wxCENTRE | wxICON_ERROR);
107  msgDialog.ShowModal();
108  } else {
109  m_isOK = true;
110  }
111 }
112 
113 bool ControlElementSolver::InitializeValues(double input, bool startAllZero)
114 {
115  // Reset Elements values
116  auto elementList = m_ctrlContainer->GetControlElementsList();
117  for(auto it = elementList.begin(), itEnd = elementList.end(); it != itEnd; ++it) {
118  ControlElement* element = *it;
119  element->SetSolved(false);
120  element->SetOutput(0.0);
121  }
122  auto tfList = m_ctrlContainer->GetTFList();
123  for(auto it = tfList.begin(), itEnd = tfList.end(); it != itEnd; ++it) {
124  TransferFunction* tf = *it;
125  tf->CalculateSpaceState(100, m_integrationError);
126  }
127  auto connectionLineList = m_ctrlContainer->GetConnectionLineList();
128  for(auto it = connectionLineList.begin(), itEnd = connectionLineList.end(); it != itEnd; ++it) {
129  ConnectionLine* cLine = *it;
130  cLine->SetSolved(false);
131  cLine->SetValue(0.0);
132  }
133 
134  if(!startAllZero) {
135  double origTimeStep = m_timeStep;
136  double minStep = m_timeStep / 10;
137  double maxStep = m_timeStep * 10;
138  // Calculate the steady-state results according to the input.
139  double minError = 1e-7 * m_timeStep;
140  int maxIteration = 100 / m_timeStep;
141 
142  double prevSol = 0.0;
143  double currentSol = 1.0;
144  double error = 1.0;
145  double prevError = 1.0;
146  int numIt = 0;
147  while(error > minError) {
148  prevSol = currentSol;
149  prevError = error;
150  SolveNextStep(input);
151  currentSol = GetLastSolution();
152  numIt++;
153  error = std::abs(prevSol - currentSol);
154  if(std::abs(error - prevError) < 1e-1) {
155  if(m_timeStep < maxStep) {
156  m_timeStep *= 1.5;
157  }
158  } else if(std::abs(error - prevError) > 10) {
159  if(m_timeStep > minStep) {
160  m_timeStep /= 1.5;
161  }
162  }
163  if(numIt >= maxIteration) return false;
164  }
165  m_timeStep = origTimeStep;
166  m_solutions.clear();
167  }
168 
169  return true;
170 }
171 
172 void ControlElementSolver::SolveNextStep(double input)
173 {
174  // Set all elements as not solved
175  auto elementList = m_ctrlContainer->GetControlElementsList();
176  for(auto it = elementList.begin(), itEnd = elementList.end(); it != itEnd; ++it) {
177  ControlElement* element = *it;
178  element->SetSolved(false);
179  }
180  auto connectionLineList = m_ctrlContainer->GetConnectionLineList();
181  for(auto it = connectionLineList.begin(), itEnd = connectionLineList.end(); it != itEnd; ++it) {
182  ConnectionLine* cLine = *it;
183  cLine->SetSolved(false);
184  }
185 
186  // Get first node and set input value on connected lines
187  ConnectionLine* firstConn = static_cast<ConnectionLine*>(m_inputControl->GetChildList()[0]);
188  m_inputControl->SetSolved();
189  firstConn->SetValue(input);
190  firstConn->SetSolved();
191  FillAllConnectedChildren(firstConn);
192 
193  // Set value to the connected lines in constants
194  auto constantList = m_ctrlContainer->GetConstantList();
195  for(auto it = constantList.begin(), itEnd = constantList.end(); it != itEnd; ++it) {
196  Constant* constant = *it;
197  if(constant->GetChildList().size() == 1) {
198  constant->SetSolved();
199  ConnectionLine* child = static_cast<ConnectionLine*>(constant->GetChildList()[0]);
200  child->SetValue(constant->GetValue());
201  child->SetSolved();
202  FillAllConnectedChildren(child);
203  }
204  }
205 
206  ConnectionLine* currentLine = firstConn;
207  while(currentLine) {
208  currentLine = SolveNextElement(currentLine);
209  }
210 
211  bool haveUnsolvedElement = true;
212  while(haveUnsolvedElement) {
213  haveUnsolvedElement = false;
214  // Get the solved line connected with unsolved element (elements not connected in the main branch).
215  for(auto it = connectionLineList.begin(), itEnd = connectionLineList.end(); it != itEnd; ++it) {
216  ConnectionLine* cLine = *it;
217  if(cLine->IsSolved()) {
218  auto parentList = cLine->GetParentList();
219  for(auto itP = parentList.begin(), itPEnd = parentList.end(); itP != itPEnd; ++itP) {
220  ControlElement* parent = static_cast<ControlElement*>(*itP);
221  if(!parent->IsSolved()) {
222  haveUnsolvedElement = true;
223  // Solve secondary branch.
224  currentLine = cLine;
225  while(currentLine) {
226  currentLine = SolveNextElement(currentLine);
227  }
228  break;
229  }
230  }
231  }
232  if(haveUnsolvedElement) break;
233  }
234  }
235 
236  // Set the control system step output.
237  if(m_outputControl->GetChildList().size() == 1) {
238  ConnectionLine* cLine = static_cast<ConnectionLine*>(m_outputControl->GetChildList()[0]);
239  m_solutions.push_back(cLine->GetValue());
240  } else
241  m_solutions.push_back(0.0);
242 }
243 
244 void ControlElementSolver::FillAllConnectedChildren(ConnectionLine* parent)
245 {
246  auto childList = parent->GetLineChildList();
247  for(auto it = childList.begin(), itEnd = childList.end(); it != itEnd; ++it) {
248  ConnectionLine* child = *it;
249  child->SetValue(parent->GetValue());
250  child->SetSolved();
251  FillAllConnectedChildren(child);
252  }
253 }
254 
255 ConnectionLine* ControlElementSolver::SolveNextElement(ConnectionLine* currentLine)
256 {
257  auto parentList = currentLine->GetParentList();
258  for(auto it = parentList.begin(), itEnd = parentList.end(); it != itEnd; ++it) {
259  ControlElement* element = static_cast<ControlElement*>(*it);
260  // Solve the unsolved parent.
261  if(!element->IsSolved()) {
262  if(!element->Solve(currentLine->GetValue(), m_timeStep)) return NULL;
263  element->SetSolved();
264 
265  // Get the output node (must have one or will result NULL).
266  Node* outNode = NULL;
267  auto nodeList = element->GetNodeList();
268  for(auto itN = nodeList.begin(), itNEnd = nodeList.end(); itN != itNEnd; ++itN) {
269  Node* node = *itN;
270  if(node->GetNodeType() == Node::NODE_OUT) outNode = node;
271  }
272  if(!outNode) return NULL;
273 
274  // Set connection line value associated with the output node.
275  auto childList = element->GetChildList();
276  for(auto itC = childList.begin(), itCEnd = childList.end(); itC != itCEnd; ++itC) {
277  ConnectionLine* cLine = static_cast<ConnectionLine*>(*itC);
278  if(!cLine->IsSolved()) { // Only check unsolved lines
279  // Check if the connection line have the output node on the list
280  auto lineNodeList = cLine->GetNodeList();
281  for(auto itCN = nodeList.begin(), itCNEnd = nodeList.end(); itCN != itCNEnd; ++itCN) {
282  Node* childNode = *itCN;
283  if(childNode == outNode) {
284  // Check if the line connect two elements, otherwise return NULL
285  if(cLine->GetType() != ConnectionLine::ELEMENT_ELEMENT) return NULL;
286 
287  // Set the connection line value and return it.
288  cLine->SetValue(element->GetOutput());
289  cLine->SetSolved();
290  FillAllConnectedChildren(cLine);
291  return cLine;
292  }
293  }
294  }
295  }
296  }
297  }
298  return NULL;
299 }
virtual std::vector< Element * > GetParentList() const
Get the parent list.
Definition: Element.h:506
+
1 /*
2  * Copyright (C) 2017 Thales Lima Oliveira <thales@ufu.br>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program. If not, see <https://www.gnu.org/licenses/>.
16  */
17 
18 #include "ControlElementSolver.h"
19 
21 #include "ControlEditor.h"
22 #include "ConnectionLine.h"
23 #include "Constant.h"
24 #include "Exponential.h"
25 #include "Gain.h"
26 #include "IOControl.h"
27 #include "Limiter.h"
28 #include "Multiplier.h"
29 #include "RateLimiter.h"
30 #include "Sum.h"
31 #include "TransferFunction.h"
32 
33 ControlElementSolver::ControlElementSolver(ControlEditor* controlEditor, double timeStep, double integrationError)
34 {
35  m_ctrlContainer = new ControlElementContainer();
36  m_ctrlContainer->FillContainer(controlEditor);
37  Initialize(controlEditor, timeStep, integrationError);
38 }
39 
40 ControlElementSolver::ControlElementSolver(ControlElementContainer* ctrlContainer,
41  double timeStep,
42  double integrationError,
43  wxWindow* parent)
44 {
45  m_ctrlContainer = ctrlContainer;
46  Initialize(parent, timeStep, integrationError);
47 }
48 
49 void ControlElementSolver::Initialize(wxWindow* parent, double timeStep, double integrationError)
50 {
51  // Check if the sistem have one input and one output
52  bool fail = false;
53  auto ioList = m_ctrlContainer->GetIOControlList();
54  if(ioList.size() < 2) {
55  fail = true;
56  m_failMessage = _("The control system must have at least one input and one output.");
57  }
58  bool haveInput, haveOutput;
59  haveInput = haveOutput = false;
60  for(auto it = ioList.begin(), itEnd = ioList.end(); it != itEnd; ++it) {
61  IOControl* io = *it;
62  if(io->GetType() == Node::NODE_OUT && !haveInput) {
63  m_inputControl = io;
64  haveInput = true;
65  } else if(io->GetType() == Node::NODE_IN) {
66  m_outputControl = io;
67  haveOutput = true;
68  }
69  }
70  if(!fail && !haveInput) {
71  fail = true;
72  m_failMessage = _("There is no input in the control system.");
73  }
74  if(!fail && !haveOutput) {
75  fail = true;
76  m_failMessage = _("There is no output in the control system.");
77  }
78  if(!fail) {
79  if(m_inputControl->GetChildList().size() == 0) {
80  fail = true;
81  m_failMessage = _("Input not connected.");
82  }
83  }
84 
85  m_timeStep = timeStep;
86  m_integrationError = integrationError;
87  if(!fail) {
88  if(!InitializeValues(true)) {
89  fail = true;
90  m_failMessage = _("It was not possible to initialize the control system.");
91  }
92  }
93 
94  if(fail) {
95  wxMessageDialog msgDialog(parent, m_failMessage, _("Error"), wxOK | wxCENTRE | wxICON_ERROR);
96  msgDialog.ShowModal();
97  } else {
98  m_isOK = true;
99  }
100 }
101 
102 bool ControlElementSolver::InitializeValues(bool startAllZero)
103 {
104  // Reset Elements values
105  auto elementList = m_ctrlContainer->GetControlElementsList();
106  for(auto it = elementList.begin(), itEnd = elementList.end(); it != itEnd; ++it) {
107  ControlElement* element = *it;
108  element->SetSolved(false);
109  element->SetOutput(0.0);
110  }
111  auto tfList = m_ctrlContainer->GetTFList();
112  for(auto it = tfList.begin(), itEnd = tfList.end(); it != itEnd; ++it) {
113  TransferFunction* tf = *it;
114  tf->CalculateSpaceState(100, m_integrationError);
115  }
116  auto connectionLineList = m_ctrlContainer->GetConnectionLineList();
117  for(auto it = connectionLineList.begin(), itEnd = connectionLineList.end(); it != itEnd; ++it) {
118  ConnectionLine* cLine = *it;
119  cLine->SetSolved(false);
120  cLine->SetValue(0.0);
121  }
122 
123  if(!startAllZero) {
124  double origTimeStep = m_timeStep;
125  double minStep = m_timeStep / 10;
126  double maxStep = m_timeStep * 10;
127  // Calculate the steady-state results according to the input.
128  double minError = 1e-7 * m_timeStep;
129  int maxIteration = 100 / m_timeStep;
130 
131  double prevSol = 0.0;
132  double currentSol = 1.0;
133  double error = 1.0;
134  double prevError = 1.0;
135  int numIt = 0;
136  while(error > minError) {
137  prevSol = currentSol;
138  prevError = error;
139  SolveNextStep();
140  currentSol = GetLastSolution();
141  numIt++;
142  error = std::abs(prevSol - currentSol);
143  if(std::abs(error - prevError) < 1e-1) {
144  if(m_timeStep < maxStep) {
145  m_timeStep *= 1.5;
146  }
147  } else if(std::abs(error - prevError) > 10) {
148  if(m_timeStep > minStep) {
149  m_timeStep /= 1.5;
150  }
151  }
152  if(numIt >= maxIteration) {
153  m_failMessage = _("It was not possible to initialize the control system.");
154  return false;
155  }
156  }
157  m_timeStep = origTimeStep;
158  m_solutions.clear();
159  }
160 
161  return true;
162 }
163 
164 void ControlElementSolver::SolveNextStep()
165 {
166  // Set all elements as not solved
167  auto elementList = m_ctrlContainer->GetControlElementsList();
168  for(auto it = elementList.begin(), itEnd = elementList.end(); it != itEnd; ++it) {
169  ControlElement* element = *it;
170  element->SetSolved(false);
171  }
172  auto connectionLineList = m_ctrlContainer->GetConnectionLineList();
173  for(auto it = connectionLineList.begin(), itEnd = connectionLineList.end(); it != itEnd; ++it) {
174  ConnectionLine* cLine = *it;
175  cLine->SetSolved(false);
176  }
177 
178  // Get first node connection
179  ConnectionLine* firstConn = static_cast<ConnectionLine*>(m_inputControl->GetChildList()[0]);
180  /*m_inputControl->SetSolved();
181  firstConn->SetValue(1);
182  firstConn->SetSolved();
183  FillAllConnectedChildren(firstConn);*/
184 
185  // Set value to the connected lines in constants
186  auto constantList = m_ctrlContainer->GetConstantList();
187  for(auto it = constantList.begin(), itEnd = constantList.end(); it != itEnd; ++it) {
188  Constant* constant = *it;
189  if(constant->GetChildList().size() == 1) {
190  constant->SetSolved();
191  ConnectionLine* child = static_cast<ConnectionLine*>(constant->GetChildList()[0]);
192  child->SetValue(constant->GetValue());
193  child->SetSolved();
194  FillAllConnectedChildren(child);
195  }
196  }
197 
198  // Set value to the connected lines in inputs
199  auto ioList = m_ctrlContainer->GetIOControlList();
200  for(auto it = ioList.begin(), itEnd = ioList.end(); it != itEnd; ++it) {
201  IOControl* io = *it;
202  if(io->GetChildList().size() == 1) {
203  io->SetSolved();
204  ConnectionLine* child = static_cast<ConnectionLine*>(io->GetChildList()[0]);
205  if(m_inputControl == io) firstConn = child;
206  bool inputType = true;
207  switch(io->GetValue()) {
208  io->SetSolved();
209  case IOControl::IN_TERMINAL_VOLTAGE: {
210  child->SetValue(m_terminalVoltage);
211  } break;
212  case IOControl::IN_VELOCITY: {
213  child->SetValue(m_velocity);
214  } break;
215  case IOControl::IN_ACTIVE_POWER: {
216  child->SetValue(m_activePower);
217  } break;
218  case IOControl::IN_REACTIVE_POWER: {
219  child->SetValue(m_reactivePower);
220  } break;
221  case IOControl::IN_INITIAL_TERMINAL_VOLTAGE: {
222  child->SetValue(m_initTerminalVoltage);
223  } break;
224  case IOControl::IN_INITIAL_MEC_POWER: {
225  child->SetValue(m_initMecPower);
226  } break;
227  case IOControl::IN_INITIAL_VELOCITY: {
228  child->SetValue(m_initVelocity);
229  } break;
230  case IOControl::IN_DELTA_VELOCITY: {
231  child->SetValue(m_deltaVelocity);
232  } break;
233  case IOControl::IN_DELTA_ACTIVE_POWER: {
234  child->SetValue(m_deltaPe);
235  } break;
236  default: {
237  inputType = false;
238  } break;
239  }
240  if(inputType) {
241  child->SetSolved();
242  FillAllConnectedChildren(child);
243  }
244  }
245  }
246 
247  ConnectionLine* currentLine = firstConn;
248  while(currentLine) {
249  currentLine = SolveNextElement(currentLine);
250  }
251 
252  bool haveUnsolvedElement = true;
253  while(haveUnsolvedElement) {
254  haveUnsolvedElement = false;
255  // Get the solved line connected with unsolved element (elements not connected in the main branch).
256  for(auto it = connectionLineList.begin(), itEnd = connectionLineList.end(); it != itEnd; ++it) {
257  ConnectionLine* cLine = *it;
258  if(cLine->IsSolved()) {
259  auto parentList = cLine->GetParentList();
260  for(auto itP = parentList.begin(), itPEnd = parentList.end(); itP != itPEnd; ++itP) {
261  ControlElement* parent = static_cast<ControlElement*>(*itP);
262  if(!parent->IsSolved()) {
263  haveUnsolvedElement = true;
264  // Solve secondary branch.
265  currentLine = cLine;
266  while(currentLine) {
267  currentLine = SolveNextElement(currentLine);
268  }
269  break;
270  }
271  }
272  }
273  if(haveUnsolvedElement) break;
274  }
275  }
276 
277  // Set the control system output.
278  /*if(m_outputControl->GetChildList().size() == 1) {
279  ConnectionLine* cLine = static_cast<ConnectionLine*>(m_outputControl->GetChildList()[0]);
280  m_solutions.push_back(cLine->GetValue());
281  } else
282  m_solutions.push_back(0.0);*/
283  for(auto it = ioList.begin(), itEnd = ioList.end(); it != itEnd; ++it) {
284  IOControl* io = *it;
285  if(io->GetChildList().size() == 1) {
286  io->SetSolved();
287  ConnectionLine* child = static_cast<ConnectionLine*>(io->GetChildList()[0]);
288  switch(io->GetValue()) {
289  io->SetSolved();
290  case IOControl::OUT_MEC_POWER: {
291  m_mecPower = child->GetValue();
292  m_solutions.push_back(m_mecPower);
293  } break;
294  case IOControl::OUT_FIELD_VOLTAGE: {
295  m_fieldVoltage = child->GetValue();
296  m_solutions.push_back(m_fieldVoltage);
297  } break;
298  default:
299  break;
300  }
301  }
302  }
303 }
304 
305 void ControlElementSolver::FillAllConnectedChildren(ConnectionLine* parent)
306 {
307  auto childList = parent->GetLineChildList();
308  for(auto it = childList.begin(), itEnd = childList.end(); it != itEnd; ++it) {
309  ConnectionLine* child = *it;
310  child->SetValue(parent->GetValue());
311  child->SetSolved();
312  FillAllConnectedChildren(child);
313  }
314 }
315 
316 ConnectionLine* ControlElementSolver::SolveNextElement(ConnectionLine* currentLine)
317 {
318  auto parentList = currentLine->GetParentList();
319  for(auto it = parentList.begin(), itEnd = parentList.end(); it != itEnd; ++it) {
320  ControlElement* element = static_cast<ControlElement*>(*it);
321  // Solve the unsolved parent.
322  if(!element->IsSolved()) {
323  if(!element->Solve(currentLine->GetValue(), m_timeStep)) return NULL;
324  element->SetSolved();
325 
326  // Get the output node (must have one or will result NULL).
327  Node* outNode = NULL;
328  auto nodeList = element->GetNodeList();
329  for(auto itN = nodeList.begin(), itNEnd = nodeList.end(); itN != itNEnd; ++itN) {
330  Node* node = *itN;
331  if(node->GetNodeType() == Node::NODE_OUT) outNode = node;
332  }
333  if(!outNode) return NULL;
334 
335  // Set connection line value associated with the output node.
336  auto childList = element->GetChildList();
337  for(auto itC = childList.begin(), itCEnd = childList.end(); itC != itCEnd; ++itC) {
338  ConnectionLine* cLine = static_cast<ConnectionLine*>(*itC);
339  if(!cLine->IsSolved()) { // Only check unsolved lines
340  // Check if the connection line have the output node on the list
341  auto lineNodeList = cLine->GetNodeList();
342  for(auto itCN = nodeList.begin(), itCNEnd = nodeList.end(); itCN != itCNEnd; ++itCN) {
343  Node* childNode = *itCN;
344  if(childNode == outNode) {
345  // Check if the line connect two elements, otherwise return NULL
346  if(cLine->GetType() != ConnectionLine::ELEMENT_ELEMENT) return NULL;
347 
348  // Set the connection line value and return it.
349  cLine->SetValue(element->GetOutput());
350  cLine->SetSolved();
351  FillAllConnectedChildren(cLine);
352  return cLine;
353  }
354  }
355  }
356  }
357  }
358  }
359  return NULL;
360 }
virtual std::vector< Element * > GetParentList() const
Get the parent list.
Definition: Element.h:506
virtual std::vector< Element * > GetChildList() const
Get the Child list.
Definition: Element.h:511
Node of a control element. This class manages the user interaction with the connection and control el...
-
virtual void CalculateSpaceState(int maxIteration=100, double error=1e-3)
Convert the transfer function to space state on controllable canonical form (CCF).
+
virtual void CalculateSpaceState(int maxIteration=100, double error=1e-3)
Convert the transfer function to space state on controllable canonical form (CCF).
Provides the communication with the power element.
Definition: IOControl.h:35
+ -
Class that can contain all control elements. Can identify (using RTTI) the elements from a generic li...
+
Class that can contain all control elements. Can identify (using RTTI) the elements from a generic li...
Connection between two control elements or other connection line and an element.
Calculates the time response by a frequency domain transfer function.
- + diff --git a/docs/doxygen/html/_control_element_solver_8h_source.html b/docs/doxygen/html/_control_element_solver_8h_source.html index 1f88c74..6f6ebbb 100644 --- a/docs/doxygen/html/_control_element_solver_8h_source.html +++ b/docs/doxygen/html/_control_element_solver_8h_source.html @@ -88,18 +88,19 @@ $(document).ready(function(){initNavTree('_control_element_solver_8h_source.html
ControlElementSolver.h
-Go to the documentation of this file.
1 /*
2  * Copyright (C) 2017 Thales Lima Oliveira <thales@ufu.br>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program. If not, see <https://www.gnu.org/licenses/>.
16  */
17 
18 #ifndef CONTROLELEMENTSOLVER_H
19 #define CONTROLELEMENTSOLVER_H
20 
21 #include <wx/window.h>
22 #include <vector>
23 
25 class ControlEditor;
26 class ConnectionLine;
27 class Constant;
28 class Exponential;
29 class Gain;
30 class IOControl;
31 class Limiter;
32 class Multiplier;
33 class RateLimiter;
34 class Sum;
35 class TransferFunction;
36 
46 {
47  public:
49  ControlElementSolver(ControlEditor* controlEditor,
50  double timeStep = 1e-3,
51  double integrationError = 1e-3,
52  bool startAllZero = true,
53  double input = 0.0);
55  double timeStep = 1e-3,
56  double integrationError = 1e-3,
57  bool startAllZero = true,
58  double input = 0.0,
59  wxWindow* parent = NULL);
60  virtual ~ControlElementSolver() {}
61  virtual bool InitializeValues(double input, bool startAllZero);
62  virtual void SolveNextStep(double input);
63  virtual std::vector<double> GetSolutions() { return m_solutions; }
64  virtual double GetLastSolution() { return m_solutions[m_solutions.size() - 1]; }
65  virtual bool IsOK() const { return m_isOK; }
66  protected:
67  void Initialize(wxWindow* parent, double timeStep, double integrationError, bool startAllZero, double input);
68  void FillAllConnectedChildren(ConnectionLine* parent);
69  ConnectionLine* SolveNextElement(ConnectionLine* currentLine);
70 
71  ControlElementContainer* m_ctrlContainer = NULL;
72  double m_timeStep;
73  double m_integrationError;
74  std::vector<double> m_solutions;
75  bool m_isOK = false;
76 
77  IOControl* m_inputControl = NULL;
78  IOControl* m_outputControl = NULL;
79 };
80 
81 #endif // CONTROLELEMENTSOLVER_H
Multiplies two inputs.
Definition: Multiplier.h:32
+Go to the documentation of this file.
1 /*
2  * Copyright (C) 2017 Thales Lima Oliveira <thales@ufu.br>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program. If not, see <https://www.gnu.org/licenses/>.
16  */
17 
18 #ifndef CONTROLELEMENTSOLVER_H
19 #define CONTROLELEMENTSOLVER_H
20 
21 #include <wx/window.h>
22 #include <vector>
23 
25 class ControlEditor;
26 class ConnectionLine;
27 class Constant;
28 class Exponential;
29 class Gain;
30 class IOControl;
31 class Limiter;
32 class Multiplier;
33 class RateLimiter;
34 class Sum;
35 class TransferFunction;
36 
46 {
47  public:
49  ControlElementSolver(ControlEditor* controlEditor, double timeStep = 1e-3, double integrationError = 1e-3);
51  double timeStep = 1e-3,
52  double integrationError = 1e-3,
53  wxWindow* parent = NULL);
54  virtual ~ControlElementSolver() {}
55  virtual bool InitializeValues(bool startAllZero);
56  virtual void SolveNextStep();
57  virtual std::vector<double> GetSolutions() { return m_solutions; }
58  virtual double GetLastSolution() { return m_solutions[m_solutions.size() - 1]; }
59  virtual bool IsOK() const { return m_isOK; }
60  virtual wxString GetErrorMessage() { return m_failMessage; }
61  void SetTerminalVoltage(double value) { m_terminalVoltage = value; }
62  void SetVelocity(double value) { m_velocity = value; }
63  void SetActivePower(double value) { m_activePower = value; }
64  void SetReactivePower(double value) { m_reactivePower = value; }
65  void SetInitialTerminalVoltage(double value) { m_initTerminalVoltage = value; }
66  void SetInitialMecPower(double value) { m_initMecPower = value; }
67  void SetInitialVelocity(double value) { m_initVelocity = value; }
68  void SetDeltaVelocity(double value) { m_deltaVelocity = value; }
69  void SetDeltaActivePower(double value) { m_deltaPe = value; }
70  double GetFieldVoltage() { return m_fieldVoltage; }
71  double GetMechanicalPower() { return m_mecPower; }
72  double GetVelocity() { return m_velocity; }
73  double GetActivePower() { return m_activePower; }
74  protected:
75  void Initialize(wxWindow* parent, double timeStep, double integrationError);
76  void FillAllConnectedChildren(ConnectionLine* parent);
77  ConnectionLine* SolveNextElement(ConnectionLine* currentLine);
78 
79  ControlElementContainer* m_ctrlContainer = NULL;
80  double m_timeStep;
81  double m_integrationError;
82  std::vector<double> m_solutions;
83  bool m_isOK = false;
84  wxString m_failMessage = _("Unknown error.");
85 
87  IOControl* m_outputControl = NULL;
88  // Inputs
89  double m_terminalVoltage = 0.0;
90  double m_velocity = 0.0;
91  double m_activePower = 0.0;
92  double m_reactivePower = 0.0;
93  double m_initTerminalVoltage = 0.0;
94  double m_initMecPower = 0.0;
95  double m_initVelocity = 0.0;
96  double m_deltaVelocity = 0.0;
97  double m_deltaPe = 0.0;
98  // Outputs
99  double m_fieldVoltage = 0.0;
100  double m_mecPower = 0.0;
101 };
102 
103 #endif // CONTROLELEMENTSOLVER_H
Multiplies two inputs.
Definition: Multiplier.h:32
Solves in the time the control system. Can solve the control system directly from a ControlEditor or ...
Sum the all inputs (can choose the input signal).
Definition: Sum.h:33
Provide an output multiplying the input by a constant.
Definition: Gain.h:35
Limits the input value by superior and inferior values.
Definition: Limiter.h:32
Provides the communication with the power element.
Definition: IOControl.h:35
+
Generates an output following an exponential function.
Definition: Exponential.h:32
Limits the rising and/or falling rate.
Definition: RateLimiter.h:32
-
Class that can contain all control elements. Can identify (using RTTI) the elements from a generic li...
+
Class that can contain all control elements. Can identify (using RTTI) the elements from a generic li...
Connection between two control elements or other connection line and an element.
Calculates the time response by a frequency domain transfer function.
- +
A control element that provides a constant value.
Definition: Constant.h:35
diff --git a/docs/doxygen/html/_control_system_test_8cpp_source.html b/docs/doxygen/html/_control_system_test_8cpp_source.html index c0230ae..cbf3dd7 100644 --- a/docs/doxygen/html/_control_system_test_8cpp_source.html +++ b/docs/doxygen/html/_control_system_test_8cpp_source.html @@ -91,7 +91,7 @@ $(document).ready(function(){initNavTree('_control_system_test_8cpp_source.html'
1 /*
2  * Copyright (C) 2017 Thales Lima Oliveira <thales@ufu.br>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program. If not, see <https://www.gnu.org/licenses/>.
16  */
17 
18 #include "ControlSystemTest.h"
19 #include "ControlEditor.h"
20 
21 ControlSystemTest::ControlSystemTest(ControlEditor* parent,
22  int* inputType,
23  double* startTime,
24  double* slope,
25  double* timeStep,
26  double* simTime)
27  : ControlSystemTestBase(parent)
28 {
29  SetSize(GetBestSize());
30 
31  m_inputType = inputType;
32  m_startTime = startTime;
33  m_slope = slope;
34  m_timeStep = timeStep;
35  m_simTime = simTime;
36 
37  m_choiceInput->SetSelection(*m_inputType);
38  m_textCtrlStartTime->SetValue(wxString::FromDouble(*m_startTime));
39  m_textCtrlSlope->SetValue(wxString::FromDouble(*m_slope));
40  m_textCtrlTimeStep->SetValue(wxString::FromDouble(*m_timeStep));
41  m_textCtrlSimTime->SetValue(wxString::FromDouble(*m_simTime));
42 }
43 
44 ControlSystemTest::~ControlSystemTest() {}
45 void ControlSystemTest::OnRunButtonClick(wxCommandEvent& event)
46 {
47  int inputType;
48  double startTime, slope, timeStep, simTime;
49 
50  inputType = m_choiceInput->GetSelection();
51 
52  if(!m_textCtrlStartTime->GetValue().ToDouble(&startTime)) {
53  wxMessageDialog msgDialog(this, _("Value entered incorrectly in the field \"Start time\"."), _("Error"),
54  wxOK | wxCENTRE | wxICON_ERROR);
55  msgDialog.ShowModal();
56  return;
57  }
58 
59  if(!m_textCtrlSlope->GetValue().ToDouble(&slope)) {
60  wxMessageDialog msgDialog(this, _("Value entered incorrectly in the field \"Slope\"."), _("Error"),
61  wxOK | wxCENTRE | wxICON_ERROR);
62  msgDialog.ShowModal();
63  return;
64  }
65 
66  if(!m_textCtrlTimeStep->GetValue().ToDouble(&timeStep)) {
67  wxMessageDialog msgDialog(this, _("Value entered incorrectly in the field \"Time step\"."), _("Error"),
68  wxOK | wxCENTRE | wxICON_ERROR);
69  msgDialog.ShowModal();
70  return;
71  }
72 
73  if(!m_textCtrlSimTime->GetValue().ToDouble(&simTime)) {
74  wxMessageDialog msgDialog(this, _("Value entered incorrectly in the field \"Simulation time\"."), _("Error"),
75  wxOK | wxCENTRE | wxICON_ERROR);
76  msgDialog.ShowModal();
77  return;
78  }
79 
80  *m_inputType = inputType;
81  *m_startTime = startTime;
82  *m_slope = slope;
83  *m_timeStep = timeStep;
84  *m_simTime = simTime;
85 
86  EndModal(wxID_OK);
87 }
- +
diff --git a/docs/doxygen/html/_control_system_test_8h_source.html b/docs/doxygen/html/_control_system_test_8h_source.html index cf82a39..574aed2 100644 --- a/docs/doxygen/html/_control_system_test_8h_source.html +++ b/docs/doxygen/html/_control_system_test_8h_source.html @@ -89,7 +89,7 @@ $(document).ready(function(){initNavTree('_control_system_test_8h_source.html','
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2017 Thales Lima Oliveira <thales@ufu.br>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program. If not, see <https://www.gnu.org/licenses/>.
16  */
17 
18 #ifndef CONTROLSYSTEMTEST_H
19 #define CONTROLSYSTEMTEST_H
20 
21 #include "ControlEditorBase.h"
22 
23 class ControlEditor;
24 
33 {
34  public:
36  int* inputType,
37  double* startTime,
38  double* slope,
39  double* timeStep,
40  double* simTime);
41  virtual ~ControlSystemTest();
42 
43  protected:
44  virtual void OnCancelButtonClick(wxCommandEvent& event) { EndModal(wxID_CANCEL); }
45  virtual void OnRunButtonClick(wxCommandEvent& event);
46  int* m_inputType = NULL;
47  double* m_startTime = NULL;
48  double* m_slope = NULL;
49  double* m_timeStep = NULL;
50  double* m_simTime = NULL;
51 };
52 #endif // CONTROLSYSTEMTEST_H
- +
Form to edit properties to test the control system created.
diff --git a/docs/doxygen/html/_divider_8cpp_source.html b/docs/doxygen/html/_divider_8cpp_source.html new file mode 100644 index 0000000..167d5e1 --- /dev/null +++ b/docs/doxygen/html/_divider_8cpp_source.html @@ -0,0 +1,111 @@ + + + + + + + + + +Project/Divider.cpp Source File + + + + + + + + + + + + + + + +
+
+
+ + + + + +
+
+ + + + + + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+ +
+ +
+
+
Divider.cpp
+
+
+
1 /*
2  * Copyright (C) 2017 Thales Lima Oliveira <thales@ufu.br>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program. If not, see <https://www.gnu.org/licenses/>.
16  */
17 
18 #include "Divider.h"
19 #include "ConnectionLine.h"
20 
21 Divider::Divider(int id) : MathOperation(id) {}
22 Divider::~Divider() {}
23 void Divider::DrawSymbol() const
24 {
25  // Plot divider.
26  glLineWidth(2.0);
27  std::vector<wxPoint2DDouble> mSymbol;
28  mSymbol.push_back(m_position + wxPoint2DDouble(-5, 0));
29  mSymbol.push_back(m_position + wxPoint2DDouble(5, 0));
30  glColor4d(0.0, 0.3, 1.0, 1.0);
31  DrawLine(mSymbol, GL_LINES);
32  DrawCircle(m_position + wxPoint2DDouble(0, -3), 2, 10, GL_POLYGON);
33  DrawCircle(m_position + wxPoint2DDouble(0, 3), 2, 10, GL_POLYGON);
34 }
35 
36 bool Divider::Solve(double input, double timeStep)
37 {
38  std::vector<double> inputVector;
39  for(auto itN = m_nodeList.begin(), itNEnd = m_nodeList.end(); itN != itNEnd; ++itN) {
40  Node* node = *itN;
41  if(node->GetNodeType() != Node::NODE_OUT) {
42  if(!node->IsConnected()) {
43  inputVector.push_back(0.0);
44  } else {
45  for(auto itC = m_childList.begin(), itCEnd = m_childList.end(); itC != itCEnd; ++itC) {
46  ConnectionLine* cLine = static_cast<ConnectionLine*>(*itC);
47  auto nodeList = cLine->GetNodeList();
48  for(auto itCN = nodeList.begin(), itCNEnd = nodeList.end(); itCN != itCNEnd; ++itCN) {
49  Node* childNode = *itCN;
50  if(childNode == node) {
51  inputVector.push_back(cLine->GetValue());
52  break;
53  }
54  }
55  }
56  }
57  }
58  }
59  if(inputVector.size() != 2) return false;
60 
61  // If the denominator is zero, set the output a big number (1e15).
62  if(std::abs(inputVector[1]) < 1e-15) {
63  m_output = 1e15;
64  } else {
65  m_output = inputVector[0] / inputVector[1];
66  }
67 
68  return true;
69 }
70 
72 {
73  Divider* copy = new Divider(m_elementID);
74  *copy = *this;
75  return copy;
76 }
Base class of all elements of the program. This class is responsible for manage graphical and his dat...
Definition: Element.h:113
+ +
Node of a control element. This class manages the user interaction with the connection and control el...
+ +
Control element that divides two inputs.
Definition: Divider.h:32
+
Abstract class that define the general behavior of math operation control block.
Definition: MathOperation.h:32
+
virtual Element * GetCopy()
Get a the element copy.
Definition: Divider.cpp:71
+
Connection between two control elements or other connection line and an element.
+
+
+ + + + diff --git a/docs/doxygen/html/_divider_8h.html b/docs/doxygen/html/_divider_8h.html new file mode 100644 index 0000000..e6d9190 --- /dev/null +++ b/docs/doxygen/html/_divider_8h.html @@ -0,0 +1,115 @@ + + + + + + + + + +Project/Divider.h File Reference + + + + + + + + + + + + + + + +
+
+ + + + + + +
+
+ + + + + + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+ +
+ +
+ +
+
Divider.h File Reference
+
+
+
#include "MathOperation.h"
+
+

Go to the source code of this file.

+ + + + + +

+Classes

class  Divider
 Control element that divides two inputs. More...
 
+
+
+ + + + diff --git a/docs/doxygen/html/_divider_8h_source.html b/docs/doxygen/html/_divider_8h_source.html new file mode 100644 index 0000000..9f3d3da --- /dev/null +++ b/docs/doxygen/html/_divider_8h_source.html @@ -0,0 +1,109 @@ + + + + + + + + + +Project/Divider.h Source File + + + + + + + + + + + + + + + +
+
+ + + + + + +
+
+ + + + + + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+ +
+ +
+
+
Divider.h
+
+
+Go to the documentation of this file.
1 /*
2  * Copyright (C) 2017 Thales Lima Oliveira <thales@ufu.br>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program. If not, see <https://www.gnu.org/licenses/>.
16  */
17 
18 #ifndef DIVIDER_H
19 #define DIVIDER_H
20 
21 #include "MathOperation.h"
22 
23 class ConnectionLine;
24 
32 class Divider : public MathOperation
33 {
34  public:
35  Divider(int id);
36  ~Divider();
37 
38  virtual void DrawSymbol() const;
39  virtual bool Solve(double input, double timeStep);
40  virtual Element* GetCopy();
41 };
42 
43 #endif // DIVIDER_H
Base class of all elements of the program. This class is responsible for manage graphical and his dat...
Definition: Element.h:113
+ +
Control element that divides two inputs.
Definition: Divider.h:32
+
Abstract class that define the general behavior of math operation control block.
Definition: MathOperation.h:32
+
virtual Element * GetCopy()
Get a the element copy.
Definition: Divider.cpp:71
+
Connection between two control elements or other connection line and an element.
+
+
+ + + + diff --git a/docs/doxygen/html/_electric_calculation_8cpp_source.html b/docs/doxygen/html/_electric_calculation_8cpp_source.html index 3833a23..4092e29 100644 --- a/docs/doxygen/html/_electric_calculation_8cpp_source.html +++ b/docs/doxygen/html/_electric_calculation_8cpp_source.html @@ -109,7 +109,7 @@ $(document).ready(function(){initNavTree('_electric_calculation_8cpp_source.html
Definition: PowerElement.h:42
virtual bool InvertMatrix(std::vector< std::vector< std::complex< double > > > matrix, std::vector< std::vector< std::complex< double > > > &inverse)
Invert a matrix.
Power line element.
Definition: Line.h:59
-
Loas shunt power element.
Definition: Load.h:42
+
Loas shunt power element.
Definition: Load.h:73
Definition: PowerElement.h:83
Definition: PowerElement.h:41
Definition: Line.h:24
diff --git a/docs/doxygen/html/_electromechanical_8cpp_source.html b/docs/doxygen/html/_electromechanical_8cpp_source.html index 951a8d7..65abff8 100644 --- a/docs/doxygen/html/_electromechanical_8cpp_source.html +++ b/docs/doxygen/html/_electromechanical_8cpp_source.html @@ -88,7 +88,7 @@ $(document).ready(function(){initNavTree('_electromechanical_8cpp_source.html','
Electromechanical.cpp
-
1 /*
2  * Copyright (C) 2017 Thales Lima Oliveira <thales@ufu.br>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program. If not, see <https://www.gnu.org/licenses/>.
16  */
17 
18 #include "Electromechanical.h"
19 #include "ControlElementSolver.h"
20 
21 Electromechanical::Electromechanical(wxWindow* parent, std::vector<Element*> elementList, SimulationData data)
22 {
23  m_parent = parent;
24  GetElementsFromList(elementList);
25  SetEventTimeList();
26 
27  Bus dummyBus;
28  m_powerSystemBase = dummyBus.GetValueFromUnit(data.basePower, data.basePowerUnit);
29  m_systemFreq = data.stabilityFrequency;
30  m_simTime = data.stabilitySimulationTime;
31  m_timeStep = data.timeStep;
32  m_tolerance = data.stabilityTolerance;
33  m_maxIterations = data.stabilityMaxIterations;
34 
35  m_ctrlTimeStepMultiplier = 1.0 / static_cast<double>(data.controlTimeStepRatio);
36 
37  m_plotTime = data.plotTime;
38  m_useCOI = data.useCOI;
39 }
40 
41 Electromechanical::~Electromechanical() {}
42 bool Electromechanical::RunStabilityCalculation()
43 {
44  wxProgressDialog pbd(_("Running simulation"), _("Initializing..."), 100, m_parent,
45  wxPD_APP_MODAL | wxPD_AUTO_HIDE | wxPD_CAN_ABORT | wxPD_SMOOTH);
46 
47  SetSyncMachinesModel();
48 
49  // Calculate the admittance matrix with the synchronous machines.
50  if(!GetYBus(m_yBus, m_powerSystemBase, POSITIVE_SEQ, false, true)) {
51  m_errorMsg = _("It was not possible to build the admittance matrix.");
52  return false;
53  }
54  InsertSyncMachinesOnYBus();
55  GetLUDecomposition(m_yBus, m_yBusL, m_yBusU);
56 
57  // Get buses voltages.
58  m_vBus.clear();
59  m_vBus.resize(m_busList.size());
60  for(auto it = m_busList.begin(), itEnd = m_busList.end(); it != itEnd; ++it) {
61  Bus* bus = *it;
62  auto data = bus->GetElectricalData();
63  m_vBus[data.number] = data.voltage;
64  }
65 
66  // Calculate injected currents
67  m_iBus = ComplexMatrixTimesVector(m_yBus, m_vBus);
68  for(unsigned int i = 0; i < m_iBus.size(); ++i) {
69  if(std::abs(m_iBus[i]) < 1e-5) m_iBus[i] = std::complex<double>(0.0, 0.0);
70  }
71 
72  if(!InitializeDynamicElements()) return false;
73 
74  double pbdTime = m_plotTime;
75  double currentTime = 0.0;
76  double currentPlotTime = 0.0;
77  double currentPbdTime = 0.0;
78  while(currentTime < m_simTime) {
79  if(HasEvent(currentTime)) {
80  SetEvent(currentTime);
81  GetLUDecomposition(m_yBus, m_yBusL, m_yBusU);
82  }
83 
84  if(currentPlotTime >= m_plotTime || currentTime == 0.0) {
85  m_timeVector.push_back(currentTime);
86  SaveData();
87  currentPlotTime = 0.0;
88  }
89 
90  if(currentPbdTime > pbdTime) {
91  if(!pbd.Update((currentTime / m_simTime) * 100, wxString::Format("Time = %.2fs", currentTime))) {
92  m_errorMsg = wxString::Format(_("Simulation cancelled at %.2fs."), currentTime);
93  pbd.Update(100);
94  return false;
95  }
96  currentPbdTime = 0.0;
97  }
98 
99  if(!SolveSynchronousMachines()) return false;
100 
101  currentTime += m_timeStep;
102  currentPlotTime += m_timeStep;
103  currentPbdTime += m_timeStep;
104  }
105  return true;
106 }
107 
108 void Electromechanical::SetEventTimeList()
109 {
110  // Fault
111  for(auto it = m_busList.begin(), itEnd = m_busList.end(); it != itEnd; ++it) {
112  Bus* bus = *it;
113  auto data = bus->GetElectricalData();
114  if(data.stabHasFault) {
115  m_eventTimeList.push_back(data.stabFaultTime);
116  m_eventOccurrenceList.push_back(false);
117  m_eventTimeList.push_back(data.stabFaultTime + data.stabFaultLength);
118  m_eventOccurrenceList.push_back(false);
119  }
120  }
121  // Switching
122  for(auto it = m_powerElementList.begin(), itEnd = m_powerElementList.end(); it != itEnd; ++it) {
123  PowerElement* element = *it;
124  SwitchingData swData = element->GetSwitchingData();
125  for(unsigned int i = 0; i < swData.swTime.size(); ++i) {
126  m_eventTimeList.push_back(swData.swTime[i]);
127  m_eventOccurrenceList.push_back(false);
128  }
129  }
130 }
131 
132 bool Electromechanical::HasEvent(double currentTime)
133 {
134  for(unsigned int i = 0; i < m_eventTimeList.size(); ++i) {
135  if(!m_eventOccurrenceList[i]) {
136  if(EventTrigger(m_eventTimeList[i], currentTime)) {
137  m_eventOccurrenceList[i] = true;
138  return true;
139  }
140  }
141  }
142  return false;
143 }
144 
145 void Electromechanical::SetEvent(double currentTime)
146 {
147  // Fault
148  for(auto it = m_busList.begin(), itEnd = m_busList.end(); it != itEnd; ++it) {
149  Bus* bus = *it;
150  auto data = bus->GetElectricalData();
151  if(data.stabHasFault) {
152  int n = data.number;
153 
154  // Insert fault
155  if(EventTrigger(data.stabFaultTime, currentTime)) {
156  double r, x;
157  r = data.stabFaultResistance;
158  x = data.stabFaultReactance;
159  if(x < 1e-5) x = 1e-5;
160  m_yBus[n][n] += std::complex<double>(1.0, 0.0) / std::complex<double>(r, x);
161  }
162 
163  // Remove fault
164  else if(EventTrigger(data.stabFaultTime + data.stabFaultLength, currentTime)) {
165  double r, x;
166  r = data.stabFaultResistance;
167  x = data.stabFaultReactance;
168  if(x < 1e-5) x = 1e-5;
169  m_yBus[n][n] -= std::complex<double>(1.0, 0.0) / std::complex<double>(r, x);
170  }
171  }
172  }
173 
174  // SyncGenerator switching
175  for(auto it = m_syncGeneratorList.begin(), itEnd = m_syncGeneratorList.end(); it != itEnd; ++it) {
176  SyncGenerator* generator = *it;
177  auto swData = generator->GetSwitchingData();
178  for(unsigned int i = 0; i < swData.swType.size(); ++i) {
179  if(EventTrigger(swData.swTime[i], currentTime)) {
180  // Remove machine (only connected machines)
181  if(swData.swType[i] == SW_REMOVE && generator->IsOnline()) {
182  generator->SetOnline(false);
183  int n = static_cast<Bus*>(generator->GetParentList()[0])->GetElectricalData().number;
184  m_yBus[n][n] -= GetSyncMachineAdmittance(generator);
185  }
186 
187  // Insert machine (only disconnected machines)
188  if(swData.swType[i] == SW_INSERT && !generator->IsOnline() && generator->GetParentList().size() == 1) {
189  if(generator->SetOnline(true)) {
190  int n = static_cast<Bus*>(generator->GetParentList()[0])->GetElectricalData().number;
191  m_yBus[n][n] += GetSyncMachineAdmittance(generator);
192  }
193  }
194  }
195  }
196  }
197 
198  // Load switching
199  for(auto it = m_loadList.begin(), itEnd = m_loadList.end(); it != itEnd; ++it) {
200  Load* load = *it;
201  auto swData = load->GetSwitchingData();
202  for(unsigned int i = 0; i < swData.swType.size(); ++i) {
203  if(EventTrigger(swData.swTime[i], currentTime)) {
204  // Remove load (only connected loads)
205  if(swData.swType[i] == SW_REMOVE && load->IsOnline()) {
206  load->SetOnline(false);
207  auto data = load->GetPUElectricalData(m_powerSystemBase);
208  Bus* parentBus = static_cast<Bus*>(load->GetParentList()[0]);
209  int n = parentBus->GetElectricalData().number;
210  std::complex<double> v = parentBus->GetElectricalData().voltage;
211  m_yBus[n][n] -= std::complex<double>(data.activePower, -data.reactivePower) / (v * v);
212  }
213 
214  // Insert load (only disconnected load)
215  if(swData.swType[i] == SW_INSERT && !load->IsOnline() && load->GetParentList().size() == 1) {
216  if(load->SetOnline(true)) {
217  auto data = load->GetPUElectricalData(m_powerSystemBase);
218  Bus* parentBus = static_cast<Bus*>(load->GetParentList()[0]);
219  int n = parentBus->GetElectricalData().number;
220  std::complex<double> v = parentBus->GetElectricalData().voltage;
221  m_yBus[n][n] += std::complex<double>(data.activePower, -data.reactivePower) / (v * v);
222  }
223  }
224  }
225  }
226  }
227 
228  // Line switching
229  for(auto it = m_lineList.begin(), itEnd = m_lineList.end(); it != itEnd; ++it) {
230  Line* line = *it;
231  auto swData = line->GetSwitchingData();
232  for(unsigned int i = 0; i < swData.swType.size(); ++i) {
233  if(EventTrigger(swData.swTime[i], currentTime)) {
234  // Remove line (only connected lines)
235  if(swData.swType[i] == SW_REMOVE && line->IsOnline()) {
236  line->SetOnline(false);
237  auto data = line->GetElectricalData();
238 
239  int n1 = static_cast<Bus*>(line->GetParentList()[0])->GetElectricalData().number;
240  int n2 = static_cast<Bus*>(line->GetParentList()[1])->GetElectricalData().number;
241 
242  m_yBus[n1][n2] += 1.0 / std::complex<double>(data.resistance, data.indReactance);
243  m_yBus[n2][n1] += 1.0 / std::complex<double>(data.resistance, data.indReactance);
244 
245  m_yBus[n1][n1] -= 1.0 / std::complex<double>(data.resistance, data.indReactance);
246  m_yBus[n2][n2] -= 1.0 / std::complex<double>(data.resistance, data.indReactance);
247 
248  m_yBus[n1][n1] -= std::complex<double>(0.0, data.capSusceptance / 2.0);
249  m_yBus[n2][n2] -= std::complex<double>(0.0, data.capSusceptance / 2.0);
250  }
251 
252  // Insert line (only disconnected lines)
253  if(swData.swType[i] == SW_INSERT && !line->IsOnline() && line->GetParentList().size() == 2) {
254  if(line->SetOnline(true)) {
255  auto data = line->GetElectricalData();
256 
257  int n1 = static_cast<Bus*>(line->GetParentList()[0])->GetElectricalData().number;
258  int n2 = static_cast<Bus*>(line->GetParentList()[1])->GetElectricalData().number;
259 
260  m_yBus[n1][n2] -= 1.0 / std::complex<double>(data.resistance, data.indReactance);
261  m_yBus[n2][n1] -= 1.0 / std::complex<double>(data.resistance, data.indReactance);
262 
263  m_yBus[n1][n1] += 1.0 / std::complex<double>(data.resistance, data.indReactance);
264  m_yBus[n2][n2] += 1.0 / std::complex<double>(data.resistance, data.indReactance);
265 
266  m_yBus[n1][n1] += std::complex<double>(0.0, data.capSusceptance / 2.0);
267  m_yBus[n2][n2] += std::complex<double>(0.0, data.capSusceptance / 2.0);
268  }
269  }
270  }
271  }
272  }
273 
274  // Transformer switching
275  for(auto it = m_transformerList.begin(), itEnd = m_transformerList.end(); it != itEnd; ++it) {
276  Transformer* transformer = *it;
277  auto swData = transformer->GetSwitchingData();
278  for(unsigned int i = 0; i < swData.swType.size(); ++i) {
279  if(EventTrigger(swData.swTime[i], currentTime)) {
280  // Remove transformer (only connected transformers)
281  if(swData.swType[i] == SW_REMOVE && transformer->IsOnline()) {
282  transformer->SetOnline(false);
283  auto data = transformer->GetElectricalData();
284 
285  int n1 = static_cast<Bus*>(transformer->GetParentList()[0])->GetElectricalData().number;
286  int n2 = static_cast<Bus*>(transformer->GetParentList()[1])->GetElectricalData().number;
287 
288  if(data.turnsRatio == 1.0 && data.phaseShift == 0.0) {
289  m_yBus[n1][n2] -= -1.0 / std::complex<double>(data.resistance, data.indReactance);
290  m_yBus[n2][n1] -= -1.0 / std::complex<double>(data.resistance, data.indReactance);
291 
292  m_yBus[n1][n1] -= 1.0 / std::complex<double>(data.resistance, data.indReactance);
293  m_yBus[n2][n2] -= 1.0 / std::complex<double>(data.resistance, data.indReactance);
294  } else {
295  // Complex turns ratio
296  double radPhaseShift = wxDegToRad(data.phaseShift);
297  std::complex<double> a = std::complex<double>(data.turnsRatio * std::cos(radPhaseShift),
298  -data.turnsRatio * std::sin(radPhaseShift));
299 
300  // Transformer admitance
301  std::complex<double> y = 1.0 / std::complex<double>(data.resistance, data.indReactance);
302  m_yBus[n1][n1] -= y / std::pow(std::abs(a), 2.0);
303  m_yBus[n1][n2] -= -(y / std::conj(a));
304  m_yBus[n2][n1] -= -(y / a);
305  m_yBus[n2][n2] -= y;
306  }
307  }
308 
309  // Insert transformer (only disconnected transformers)
310  if(swData.swType[i] == SW_INSERT && !transformer->IsOnline() &&
311  transformer->GetParentList().size() == 2) {
312  if(transformer->SetOnline(true)) {
313  auto data = transformer->GetElectricalData();
314 
315  int n1 = static_cast<Bus*>(transformer->GetParentList()[0])->GetElectricalData().number;
316  int n2 = static_cast<Bus*>(transformer->GetParentList()[1])->GetElectricalData().number;
317 
318  if(data.turnsRatio == 1.0 && data.phaseShift == 0.0) {
319  m_yBus[n1][n2] += -1.0 / std::complex<double>(data.resistance, data.indReactance);
320  m_yBus[n2][n1] += -1.0 / std::complex<double>(data.resistance, data.indReactance);
321 
322  m_yBus[n1][n1] += 1.0 / std::complex<double>(data.resistance, data.indReactance);
323  m_yBus[n2][n2] += 1.0 / std::complex<double>(data.resistance, data.indReactance);
324  } else {
325  // Complex turns ratio
326  double radPhaseShift = wxDegToRad(data.phaseShift);
327  std::complex<double> a = std::complex<double>(data.turnsRatio * std::cos(radPhaseShift),
328  -data.turnsRatio * std::sin(radPhaseShift));
329 
330  // Transformer admitance
331  std::complex<double> y = 1.0 / std::complex<double>(data.resistance, data.indReactance);
332  m_yBus[n1][n1] += y / std::pow(std::abs(a), 2.0);
333  m_yBus[n1][n2] += -(y / std::conj(a));
334  m_yBus[n2][n1] += -(y / a);
335  m_yBus[n2][n2] += y;
336  }
337  }
338  }
339  }
340  }
341  }
342 
343  // Capacitor switching
344  for(auto it = m_capacitorList.begin(), itEnd = m_capacitorList.end(); it != itEnd; ++it) {
345  Capacitor* capacitor = *it;
346  auto swData = capacitor->GetSwitchingData();
347  for(unsigned int i = 0; i < swData.swType.size(); ++i) {
348  if(EventTrigger(swData.swTime[i], currentTime)) {
349  // Remove capacitor (only connected capacitors)
350  if(swData.swType[i] == SW_REMOVE && capacitor->IsOnline()) {
351  capacitor->SetOnline(false);
352  auto data = capacitor->GetPUElectricalData(m_powerSystemBase);
353  int n = static_cast<Bus*>(capacitor->GetParentList()[0])->GetElectricalData().number;
354  m_yBus[n][n] -= std::complex<double>(0.0, data.reactivePower);
355  }
356 
357  // Insert capacitor (only disconnected capacitors)
358  if(swData.swType[i] == SW_INSERT && !capacitor->IsOnline() && capacitor->GetParentList().size() == 1) {
359  if(capacitor->SetOnline(true)) {
360  auto data = capacitor->GetPUElectricalData(m_powerSystemBase);
361  int n = static_cast<Bus*>(capacitor->GetParentList()[0])->GetElectricalData().number;
362  m_yBus[n][n] += std::complex<double>(0.0, data.reactivePower);
363  }
364  }
365  }
366  }
367  }
368 
369  // Inductor switching
370  for(auto it = m_inductorList.begin(), itEnd = m_inductorList.end(); it != itEnd; ++it) {
371  Inductor* inductor = *it;
372  auto swData = inductor->GetSwitchingData();
373  for(unsigned int i = 0; i < swData.swType.size(); ++i) {
374  if(EventTrigger(swData.swTime[i], currentTime)) {
375  // Remove inductor (only connected inductors)
376  if(swData.swType[i] == SW_REMOVE && inductor->IsOnline()) {
377  inductor->SetOnline(false);
378  auto data = inductor->GetPUElectricalData(m_powerSystemBase);
379  int n = static_cast<Bus*>(inductor->GetParentList()[0])->GetElectricalData().number;
380  m_yBus[n][n] -= std::complex<double>(0.0, -data.reactivePower);
381  }
382 
383  // Insert inductor (only disconnected inductors)
384  if(swData.swType[i] == SW_INSERT && !inductor->IsOnline() && inductor->GetParentList().size() == 1) {
385  if(inductor->SetOnline(true)) {
386  auto data = inductor->GetPUElectricalData(m_powerSystemBase);
387  int n = static_cast<Bus*>(inductor->GetParentList()[0])->GetElectricalData().number;
388  m_yBus[n][n] += std::complex<double>(0.0, -data.reactivePower);
389  }
390  }
391  }
392  }
393  }
394 }
395 
396 void Electromechanical::InsertSyncMachinesOnYBus()
397 {
398  for(auto it = m_syncGeneratorList.begin(), itEnd = m_syncGeneratorList.end(); it != itEnd; ++it) {
399  SyncGenerator* generator = *it;
400  if(generator->IsOnline()) {
401  auto data = generator->GetElectricalData();
402  int n = static_cast<Bus*>(generator->GetParentList()[0])->GetElectricalData().number;
403  m_yBus[n][n] += GetSyncMachineAdmittance(generator);
404  }
405  }
406 }
407 
408 bool Electromechanical::EventTrigger(double eventTime, double currentTime)
409 {
410  return (((eventTime - m_timeStep) < currentTime) && (eventTime >= currentTime));
411 }
412 
413 std::complex<double> Electromechanical::GetSyncMachineAdmittance(SyncGenerator* generator)
414 {
415  auto data = generator->GetElectricalData();
416  double k = 1.0; // Power base change factor.
417  if(data.useMachineBase) {
418  double oldBase = generator->GetValueFromUnit(data.nominalPower, data.nominalPowerUnit);
419  k = m_powerSystemBase / oldBase;
420  }
421 
422  double ra = data.armResistance * k;
423  auto smModelData = GetSyncMachineModelData(generator);
424  double xd = smModelData.xd;
425  double xq = smModelData.xq;
426  double xdq = 0.5 * (xd + xq);
427  return (std::complex<double>(ra, -xdq) / std::complex<double>(ra * ra + xd * xq, 0.0));
428 }
429 
430 bool Electromechanical::InitializeDynamicElements()
431 {
432  // Buses
433  for(auto it = m_busList.begin(), itEnd = m_busList.end(); it != itEnd; ++it) {
434  Bus* bus = *it;
435  auto data = bus->GetElectricalData();
436  data.stabVoltageVector.clear();
437  bus->SetElectricalData(data);
438  }
439  // Synchronous generators
440  for(auto it = m_syncGeneratorList.begin(), itEnd = m_syncGeneratorList.end(); it != itEnd; ++it) {
441  SyncGenerator* syncGenerator = *it;
442  auto dataPU = syncGenerator->GetPUElectricalData(m_powerSystemBase);
443  auto data = syncGenerator->GetElectricalData();
444  if(syncGenerator->IsOnline()) {
445  double k = 1.0; // Power base change factor.
446  if(data.useMachineBase) {
447  double oldBase = syncGenerator->GetValueFromUnit(data.nominalPower, data.nominalPowerUnit);
448  k = m_powerSystemBase / oldBase;
449  }
450  data.terminalVoltage = static_cast<Bus*>(syncGenerator->GetParentList()[0])->GetElectricalData().voltage;
451 
452  std::complex<double> conjS(dataPU.activePower, -dataPU.reactivePower);
453  std::complex<double> vt = data.terminalVoltage;
454  std::complex<double> ia = conjS / std::conj(vt);
455 
456  double xd = data.syncXd * k;
457  double xq = data.syncXq * k;
458  double ra = data.armResistance * k;
459 
460  if(data.model == Machines::SM_MODEL_1) {
461  xq = data.transXd * k;
462  xd = xq;
463  } else if(data.syncXq == 0.0)
464  xq = data.syncXd * k;
465 
466  double sd = 1.0;
467  double sq = 1.0;
468  double satF = 1.0;
469  double xp = data.potierReactance * k;
470  bool hasSaturation = false;
471  if(data.satFactor != 0.0) { // Have saturation.
472  satF = (data.satFactor - 1.2) / std::pow(1.2, 7);
473  if(xp == 0.0) xp = 0.8 * (data.transXd * k);
474  hasSaturation = true;
475  }
476 
477  // Initialize state variables
478  std::complex<double> eq0 = vt + std::complex<double>(ra, xq) * ia;
479  double delta = std::arg(eq0);
480 
481  double id0, iq0, vd0, vq0;
482  ABCtoDQ0(ia, delta, id0, iq0);
483  ABCtoDQ0(vt, delta, vd0, vq0);
484 
485  // Initialize saturation
486  double xqs = xq;
487  double xds = xd;
488  if(hasSaturation) {
489  double oldDelta = 0;
490  bool exit = false;
491  int numIt = 0;
492  while(!exit) {
493  oldDelta = delta;
494  ABCtoDQ0(ia, delta, id0, iq0);
495  ABCtoDQ0(vt, delta, vd0, vq0);
496 
497  // Direct-axis Potier voltage.
498  double epd = vd0 + ra * id0 + xp * iq0;
499 
500  sq = 1.0 + satF * (xq / xd) * std::pow(epd, 6);
501  xqs = (xq - xp) / sq + xp;
502  eq0 = data.terminalVoltage + std::complex<double>(ra, xqs) * ia;
503  delta = std::arg(eq0);
504  if(std::abs(delta - oldDelta) < m_saturationTolerance) {
505  exit = true;
506  } else if(numIt >= m_maxIterations) {
507  m_errorMsg = _("Error on initializate the saturation values of \"") + data.name + _("\".");
508  return false;
509  }
510  numIt++;
511  }
512  // Quadrature-axis Potier voltage.
513  double epq = vq0 + ra * iq0 - xp * id0;
514  sd = 1.0 + satF * std::pow(epq, 6);
515  xds = (xd - xp) / sd + xp;
516  /*CalculateSyncMachineSaturation(syncGenerator, id0, iq0, sq, sd, true, k);
517  xqs = (xq - xp) / sq + xp;
518  xds = (xd - xp) / sd + xp;
519  eq0 = data.terminalVoltage + std::complex<double>(ra, xqs) * ia;
520  delta = std::arg(eq0);*/
521  }
522 
523  double ef0 = vq0 + ra * iq0 - xds * id0;
524 
525  data.initialFieldVoltage = ef0 * sd;
526  data.fieldVoltage = data.initialFieldVoltage;
527  data.pm = std::real((data.terminalVoltage * std::conj(ia)) + (std::abs(ia) * std::abs(ia) * ra));
528  data.speed = 2.0 * M_PI * m_systemFreq;
529  data.delta = delta;
530  data.pe = data.pm;
531  data.electricalPower = std::complex<double>(dataPU.activePower, dataPU.reactivePower);
532  data.sd = sd;
533  data.sq = sq;
534  data.id = id0;
535  data.iq = iq0;
536 
537  // Variables to extrapolate.
538  data.oldIq = iq0;
539  data.oldId = id0;
540  data.oldPe = data.pe;
541  data.oldSd = sd;
542  data.oldSq = sq;
543 
544  m_sdC = sd;
545  m_sqC = sq;
546 
547  switch(data.model) {
548  case Machines::SM_MODEL_1: {
549  // double tranXd = data.transXd * k;
550 
551  // data.tranEq = data.initialFieldVoltage + (xd - tranXd) * id0;
552  data.tranEq = std::abs(eq0);
553 
554  data.tranEd = 0.0;
555  data.subEq = 0.0;
556  data.subEd = 0.0;
557  } break;
558  case Machines::SM_MODEL_2: {
559  double tranXd = data.transXd * k;
560 
561  data.tranEq = ef0 + (xd - tranXd) * (id0 / sd);
562  data.tranEd = 0.0;
563  data.subEd = 0.0;
564  data.subEq = 0.0;
565  } break;
566  case Machines::SM_MODEL_3: {
567  double tranXd = data.transXd * k;
568  double tranXq = data.transXq * k;
569  if(tranXq == 0.0) tranXq = tranXd;
570 
571  data.tranEq = ef0 + (xd - tranXd) * (id0 / sd);
572  data.tranEd = -(xq - tranXq) * (iq0 / sq);
573 
574  data.subEd = 0.0;
575  data.subEq = 0.0;
576  } break;
577  case Machines::SM_MODEL_4: {
578  double tranXd = data.transXd * k;
579  double subXd = data.subXd * k;
580  double subXq = data.subXq * k;
581  if(subXd == 0.0) subXd = subXq;
582  if(subXq == 0.0) subXq = subXd;
583 
584  data.tranEq = ef0 + (xd - tranXd) * (id0 / sd);
585  data.tranEd = 0.0;
586  data.subEq = data.tranEq + (tranXd - subXd) * (id0 / sd);
587  data.subEd = -(xq - subXq) * (iq0 / sq);
588  } break;
589  case Machines::SM_MODEL_5: {
590  double tranXd = data.transXd * k;
591  double tranXq = data.transXq * k;
592  double subXd = data.subXd * k;
593  double subXq = data.subXq * k;
594  if(subXd == 0.0) subXd = subXq;
595  if(subXq == 0.0) subXq = subXd;
596 
597  data.tranEq = ef0 + (xd - tranXd) * (id0 / sd);
598  data.tranEd = -(xq - tranXq) * (iq0 / sq);
599  data.subEq = data.tranEq + (tranXd - subXd) * (id0 / sd);
600  data.subEd = data.tranEd - (tranXq - subXq) * (iq0 / sq);
601  } break;
602  default:
603  break;
604  }
605 
606  // Initialize controllers
607  if(data.useAVR) {
608  if(data.avrSolver) delete data.avrSolver;
609  data.avrSolver = new ControlElementSolver(data.avr, m_timeStep * m_ctrlTimeStepMultiplier, m_tolerance,
610  false, std::abs(data.terminalVoltage), m_parent);
611  if(!data.avrSolver->IsOK()) {
612  m_errorMsg = _("Error on initializate the AVR of \"") + data.name + _("\".");
613  syncGenerator->SetElectricalData(data);
614  return false;
615  }
616  }
617  if(data.useSpeedGovernor) {
618  if(data.speedGovSolver) delete data.speedGovSolver;
619  data.speedGovSolver = new ControlElementSolver(data.speedGov, m_timeStep * m_ctrlTimeStepMultiplier,
620  m_tolerance, false, data.speed, m_parent);
621  if(!data.speedGovSolver->IsOK()) {
622  m_errorMsg = _("Error on initializate the speed governor of \"") + data.name + _("\".");
623  syncGenerator->SetElectricalData(data);
624  return false;
625  }
626  }
627  } else {
628  // Initialize open circuit machine.
629  }
630  // Reset plot data
631  data.terminalVoltageVector.clear();
632  data.electricalPowerVector.clear();
633  data.mechanicalPowerVector.clear();
634  data.freqVector.clear();
635  data.fieldVoltageVector.clear();
636  data.deltaVector.clear();
637 
638  syncGenerator->SetElectricalData(data);
639  }
640  CalculateReferenceSpeed();
641  return true;
642 }
643 
644 bool Electromechanical::CalculateMachinesCurrents()
645 {
646  // Reset injected currents vector
647  for(unsigned int i = 0; i < m_iBus.size(); ++i) m_iBus[i] = std::complex<double>(0.0, 0.0);
648 
649  for(auto it = m_syncGeneratorList.begin(), itEnd = m_syncGeneratorList.end(); it != itEnd; ++it) {
650  SyncGenerator* syncGenerator = *it;
651  auto data = syncGenerator->GetElectricalData();
652  if(syncGenerator->IsOnline()) {
653  double k = 1.0; // Power base change factor.
654  if(data.useMachineBase) {
655  double oldBase = syncGenerator->GetValueFromUnit(data.nominalPower, data.nominalPowerUnit);
656  k = m_powerSystemBase / oldBase;
657  }
658 
659  double ra = data.armResistance * k;
660  double xp = data.potierReactance * k;
661  if(xp == 0.0) xp = 0.8 * data.transXd * k;
662 
663  int n = static_cast<Bus*>(syncGenerator->GetParentList()[0])->GetElectricalData().number;
664  std::complex<double> e = std::complex<double>(0.0, 0.0);
665  std::complex<double> v = m_vBus[n];
666  std::complex<double> iInj = m_iBus[n];
667 
668  auto smModelData = GetSyncMachineModelData(syncGenerator);
669  DQ0toABC(smModelData.ed, smModelData.eq, data.delta, e);
670  double xd = smModelData.xd;
671  double xq = smModelData.xq;
672 
673  double sd = data.sd;
674  double sq = data.sq;
675  double id, iq;
676 
677  // Calculate the saturation effect
678  if(data.satFactor != 0.0) {
679  if(!CalculateSyncMachineSaturation(syncGenerator, id, iq, sd, sq, false, k)) return false;
680  }
681 
682  double xdq, xds, xqs, xdqs;
683  xdq = 0.5 * (xd + xq);
684  xds = (xd - xp) / sd + xp;
685  xqs = (xq - xp) / sq + xp;
686  xdqs = 0.5 * (xds + xqs);
687 
688  std::complex<double> y0 = std::complex<double>(ra, -xdq) / std::complex<double>(ra * ra + xd * xq, 0.0);
689  // std::complex<double> iUnadjusted = y0 * e;
690  std::complex<double> iUnadjusted = y0 * v;
691 
692  // [Ref] Arrillaga, J.; Arnold, C. P.. "Computer Modelling of Electrical Power Systems". Pg. 225-226
693  // [Ref] Dommell, H. W.; Sato, N.. "Fast transient stability solutions". IEEE Transactions on Power
694  // Apparatus and Systems, PAS-91 (4), 1643-1650
695  std::complex<double> iSaliency = std::complex<double>(0.0, -((0.5 * (xqs - xds)) / (ra * ra + xds * xqs))) *
696  (std::conj(e) - std::conj(v));
697  iSaliency = iSaliency * std::cos(2.0 * data.delta) +
698  iSaliency * std::complex<double>(0.0, std::sin(2.0 * data.delta));
699 
700  // [Ref] Arrillaga, J.; Arnold, C. P.; Computer Modelling of Electrical Power Systems. Pg. 258-259
701  std::complex<double> y0s = std::complex<double>(ra, -xdqs) / std::complex<double>(ra * ra + xds * xqs, 0.0);
702  std::complex<double> iSaturation = y0s * (e - v);
703 
704  iInj = iUnadjusted + iSaliency + iSaturation;
705 
706  m_iBus[n] += iInj;
707 
708  // Remove the current flowing through y0 (i.e. iUnadjusted in this case, y0 is inserted in admittance
709  // matrix) to calculate the electrical power.
710  std::complex<double> iMachine = iInj - iUnadjusted;
711  data.electricalPower = v * std::conj(iMachine);
712 
713  ABCtoDQ0(iMachine, data.delta, id, iq);
714 
715  data.id = id;
716  data.iq = iq;
717  data.sd = sd;
718  data.sq = sq;
719  } else {
720  data.electricalPower = std::complex<double>(0.0, 0.0);
721  }
722 
723  syncGenerator->SetElectricalData(data);
724  }
725  return true;
726 }
727 
728 void Electromechanical::CalculateIntegrationConstants(SyncGenerator* syncGenerator, double id, double iq, double k)
729 {
730  CalculateReferenceSpeed();
731  auto data = syncGenerator->GetElectricalData();
732 
733  double syncXd, syncXq, transXd, transXq, subXd, subXq;
734  syncXd = data.syncXd * k;
735  syncXq = data.syncXq * k;
736  transXd = data.transXd * k;
737  transXq = data.transXq * k;
738  subXd = data.subXd * k;
739  subXq = data.subXq * k;
740 
741  if(syncXq == 0.0) syncXq = syncXd;
742  if(transXq == 0.0) transXq = transXd;
743  if(subXd == 0.0) subXd = subXq;
744  if(subXq == 0.0) subXq = subXd;
745 
746  double transTd0, transTq0, subTd0, subTq0;
747  transTd0 = data.transTd0;
748  transTq0 = data.transTq0;
749  subTd0 = data.subTd0;
750  subTq0 = data.subTq0;
751 
752  if(subTd0 == 0.0) subTd0 = subTq0;
753  if(subTq0 == 0.0) subTq0 = subTd0;
754 
755  // Speed
756  data.icSpeed.m = m_timeStep / ((4.0f * data.inertia / m_refSpeed) / k + m_timeStep * data.damping * k);
757  data.icSpeed.c = (1.0f - 2.0f * data.icSpeed.m * data.damping * k) * data.speed +
758  data.icSpeed.m * (data.pm - data.pe + 2.0f * m_refSpeed * data.damping * k);
759 
760  // Delta
761  data.icDelta.m = 0.5f * m_timeStep;
762  data.icDelta.c = data.delta + data.icDelta.m * (data.speed - 2.0f * m_refSpeed);
763 
764  // Eq'
765  if(data.model == Machines::SM_MODEL_2 || data.model == Machines::SM_MODEL_3 || data.model == Machines::SM_MODEL_4 ||
766  data.model == Machines::SM_MODEL_5) {
767  data.icTranEq.m = m_timeStep / (2.0f * transTd0 + m_timeStep);
768  // data.icTranEq.c = (1.0f - 2.0 * data.icTranEq.m) * data.tranEq +
769  // data.icTranEq.m * (data.fieldVoltage + (syncXd - transXd) * id);
770  data.icTranEq.c = (1.0 - data.icTranEq.m * (1.0 + data.sd)) * data.tranEq +
771  data.icTranEq.m * (data.fieldVoltage + (syncXd - transXd) * id);
772  }
773 
774  // Ed'
775  if(data.model == Machines::SM_MODEL_3 || data.model == Machines::SM_MODEL_4 || data.model == Machines::SM_MODEL_5) {
776  data.icTranEd.m = m_timeStep / (2.0f * transTq0 + m_timeStep);
777  // data.icTranEd.c = (1.0f - 2.0f * data.icTranEd.m) * data.tranEd - data.icTranEd.m * (syncXq - transXq) * iq;
778  data.icTranEd.c =
779  (1.0 - data.icTranEd.m * (1.0 + data.sq)) * data.tranEd - data.icTranEd.m * (syncXq - transXq) * iq;
780  }
781 
782  // Eq''
783  if(data.model == Machines::SM_MODEL_4 || data.model == Machines::SM_MODEL_5) {
784  data.icSubEq.m = m_timeStep / (2.0f * subTd0 + m_timeStep);
785  // data.icSubEq.c =
786  // (1.0f - 2.0f * data.icSubEq.m) * data.subEq + data.icSubEq.m * (data.tranEq + (transXd - subXd) * id);
787  data.icSubEq.c = (1.0 - data.icSubEq.m * (1.0 + data.sd)) * data.subEq +
788  data.icSubEq.m * (data.sd * data.tranEq + (transXd - subXd) * id);
789  }
790  // Ed''
791  if(data.model == Machines::SM_MODEL_4) {
792  data.icSubEd.m = m_timeStep / (2.0f * subTq0 + m_timeStep);
793  // data.icSubEd.c = (1.0f - 2.0f * data.icSubEd.m) * data.subEd - data.icSubEd.m * (syncXq - subXq) * iq;
794  data.icSubEd.c =
795  (1.0f - data.icSubEd.m * (1.0 + data.sq)) * data.subEd - data.icSubEd.m * (syncXq - subXq) * iq;
796  }
797  if(data.model == Machines::SM_MODEL_5) {
798  data.icSubEd.m = m_timeStep / (2.0f * subTq0 + m_timeStep);
799  // data.icSubEd.c =
800  // (1.0f - 2.0f * data.icSubEd.m) * data.subEd + data.icSubEd.m * (data.tranEd - (transXq - subXq) * iq);
801  data.icSubEd.c = (1.0f - data.icSubEd.m * (1.0 + data.sq)) * data.subEd +
802  data.icSubEd.m * (data.sq * data.tranEd - (transXq - subXq) * iq);
803  }
804 
805  syncGenerator->SetElectricalData(data);
806 }
807 
808 bool Electromechanical::SolveSynchronousMachines()
809 {
810  for(auto it = m_syncGeneratorList.begin(), itEnd = m_syncGeneratorList.end(); it != itEnd; ++it) {
811  SyncGenerator* syncGenerator = *it;
812  auto data = syncGenerator->GetElectricalData();
813 
814  if(syncGenerator->IsOnline()) {
815  double id, iq, pe, sd, sq;
816  pe = data.pe;
817  id = data.id;
818  iq = data.iq;
819  sd = data.sd;
820  sq = data.sq;
821 
822  double k = 1.0; // Power base change factor.
823  if(data.useMachineBase) {
824  double oldBase = syncGenerator->GetValueFromUnit(data.nominalPower, data.nominalPowerUnit);
825  k = m_powerSystemBase / oldBase;
826  }
827 
828  // Calculate integration constants.
829  CalculateIntegrationConstants(syncGenerator, id, iq, k);
830 
831  if(!CalculateSyncMachineNonIntVariables(syncGenerator, id, iq, sd, sq, pe, k)) return false;
832  // Extrapolate nonintegrable variables.
833  id = 2.0 * id - data.oldId;
834  iq = 2.0 * iq - data.oldIq;
835  pe = 2.0 * pe - data.oldPe;
836  sd = 2.0 * sd - data.oldSd;
837  sq = 2.0 * sq - data.oldSq;
838 
839  m_sdC = sd;
840  m_sqC = sq;
841 
842  CalculateSyncMachineIntVariables(syncGenerator, id, iq, sd, sq, pe, k);
843  } else {
844  CalculateIntegrationConstants(syncGenerator, 0.0f, 0.0f);
845  }
846  }
847 
848  m_wError = 0;
849 
850  double error = 1.0;
851  int iterations = 0;
852  while(error > m_tolerance) {
853  error = 0.0;
854 
855  // Calculate the injected currents.
856  if(!CalculateMachinesCurrents()) return false;
857 
858  // Calculate the buses voltages.
859  m_vBus = LUEvaluate(m_yBusU, m_yBusL, m_iBus);
860 
861  // Solve machine equations.
862  for(auto it = m_syncGeneratorList.begin(), itEnd = m_syncGeneratorList.end(); it != itEnd; ++it) {
863  SyncGenerator* syncGenerator = *it;
864 
865  auto data = syncGenerator->GetElectricalData();
866 
867  double id = data.id;
868  double iq = data.iq;
869  double pe = data.pe;
870  double sd = data.sd;
871  double sq = data.sq;
872 
873  // Power base change factor.
874  double k = 1.0;
875  if(data.useMachineBase) {
876  double oldBase = syncGenerator->GetValueFromUnit(data.nominalPower, data.nominalPowerUnit);
877  k = m_powerSystemBase / oldBase;
878  }
879 
880  // Calculate id, iq, dq, sd
881  if(!CalculateSyncMachineNonIntVariables(syncGenerator, id, iq, sd, sq, pe, k)) return false;
882 
883  double genError = CalculateSyncMachineIntVariables(syncGenerator, id, iq, sd, sq, pe, k);
884 
885  if(genError > error) error = genError;
886  }
887 
888  ++iterations;
889 
890  if(iterations > m_maxIterations) {
891  m_errorMsg = _("Impossible to solve the synchronous generators.\nCheck the system parameters and/or "
892  "decrease the time step.");
893  return false;
894  }
895  }
896  m_numIt = iterations;
897 
898  // Solve controllers.
899  int ctrlRatio = static_cast<int>(1 / m_ctrlTimeStepMultiplier);
900  for(auto it = m_syncGeneratorList.begin(), itEnd = m_syncGeneratorList.end(); it != itEnd; ++it) {
901  SyncGenerator* syncGenerator = *it;
902  auto data = syncGenerator->GetElectricalData();
903  if(data.useAVR && data.avrSolver) {
904  for(int i = 0; i < ctrlRatio; ++i) data.avrSolver->SolveNextStep(std::abs(data.terminalVoltage));
905  data.fieldVoltage = data.initialFieldVoltage + data.avrSolver->GetLastSolution();
906  }
907 
908  if(data.useSpeedGovernor && data.speedGovSolver) {
909  for(int i = 0; i < ctrlRatio; ++i) data.speedGovSolver->SolveNextStep(data.speed);
910  data.pm = data.speedGovSolver->GetLastSolution();
911  }
912  syncGenerator->SetElectricalData(data);
913  }
914 
915  return true;
916 }
917 
918 void Electromechanical::SaveData()
919 {
920  for(auto it = m_syncGeneratorList.begin(), itEnd = m_syncGeneratorList.end(); it != itEnd; ++it) {
921  SyncGenerator* syncGenerator = *it;
922  auto data = syncGenerator->GetElectricalData();
923  if(data.plotSyncMachine) {
924  data.terminalVoltageVector.push_back(data.terminalVoltage);
925  data.electricalPowerVector.push_back(data.electricalPower);
926  data.mechanicalPowerVector.push_back(data.pm);
927  data.freqVector.push_back(data.speed / (2.0f * M_PI));
928  data.fieldVoltageVector.push_back(data.fieldVoltage);
929  data.deltaVector.push_back(wxRadToDeg(data.delta));
930  syncGenerator->SetElectricalData(data);
931  }
932  }
933  for(auto it = m_busList.begin(), itEnd = m_busList.end(); it != itEnd; ++it) {
934  Bus* bus = *it;
935  auto data = bus->GetElectricalData();
936  if(data.plotBus) {
937  data.stabVoltageVector.push_back(m_vBus[data.number]);
938  bus->SetElectricalData(data);
939  }
940  }
941 
942  m_wErrorVector.push_back(m_wError);
943  m_numItVector.push_back(m_numIt);
944  m_sdCVector.push_back(m_sdC);
945  m_sqCVector.push_back(m_sqC);
946 }
947 
948 void Electromechanical::SetSyncMachinesModel()
949 {
950  for(auto it = m_syncGeneratorList.begin(), itEnd = m_syncGeneratorList.end(); it != itEnd; ++it) {
951  SyncGenerator* syncGenerator = *it;
952  auto data = syncGenerator->GetElectricalData();
953  data.model = GetMachineModel(syncGenerator);
954  syncGenerator->SetElectricalData(data);
955  }
956 }
957 
958 bool Electromechanical::CalculateSyncMachineNonIntVariables(SyncGenerator* syncGenerator,
959  double& id,
960  double& iq,
961  double& sd,
962  double& sq,
963  double& pe,
964  double k)
965 {
966  auto data = syncGenerator->GetElectricalData();
967  int n = static_cast<Bus*>(syncGenerator->GetParentList()[0])->GetElectricalData().number;
968 
969  if(syncGenerator->IsOnline()) {
970  data.terminalVoltage = m_vBus[n];
971  }
972 
973  double vd, vq;
974  ABCtoDQ0(data.terminalVoltage, data.delta, vd, vq);
975 
976  if(data.satFactor != 0.0) {
977  if(!CalculateSyncMachineSaturation(syncGenerator, id, iq, sd, sq, true, k)) return false;
978  data.sd = sd;
979  data.sq = sq;
980  data.oldSd = sd;
981  data.oldSq = sq;
982  }
983 
984  if(syncGenerator->IsOnline()) {
985  pe = id * vd + iq * vq + (id * id + iq * iq) * data.armResistance * k;
986  } else {
987  pe = id = iq = 0.0f;
988  }
989  data.pe = pe;
990  data.id = id;
991  data.iq = iq;
992  data.oldPe = pe;
993  data.oldId = id;
994  data.oldIq = iq;
995  syncGenerator->SetElectricalData(data);
996 
997  return true;
998 }
999 
1000 double Electromechanical::CalculateSyncMachineIntVariables(SyncGenerator* syncGenerator,
1001  double id,
1002  double iq,
1003  double sd,
1004  double sq,
1005  double pe,
1006  double k)
1007 {
1008  double error = 0.0;
1009  auto data = syncGenerator->GetElectricalData();
1010 
1011  // Mechanical differential equations.
1012  double w = data.icSpeed.c + data.icSpeed.m * (data.pm - pe);
1013  error = std::max(error, std::abs(data.speed - w) / m_refSpeed);
1014 
1015  m_wError += std::abs(data.speed - w) / m_refSpeed;
1016 
1017  double delta = data.icDelta.c + data.icDelta.m * w;
1018  error = std::max(error, std::abs(data.delta - delta));
1019 
1020  data.speed = w;
1021  data.delta = delta;
1022 
1023  // Electrical differential equations
1024  switch(data.model) {
1025  case Machines::SM_MODEL_1: {
1026  // There is no differential equations.
1027  } break;
1028  case Machines::SM_MODEL_2: {
1029  double syncXd, transXd;
1030  syncXd = data.syncXd * k;
1031  transXd = data.transXd * k;
1032 
1033  double tranEq = (data.icTranEq.c + data.icTranEq.m * (data.fieldVoltage + (syncXd - transXd) * id)) /
1034  (1.0 + data.icTranEq.m * (sd - 1.0));
1035  error = std::max(error, std::abs(data.tranEq - tranEq));
1036 
1037  data.tranEq = tranEq;
1038  } break;
1039  case Machines::SM_MODEL_3: {
1040  double syncXd, syncXq, transXd, transXq;
1041  syncXd = data.syncXd * k;
1042  syncXq = data.syncXq * k;
1043  transXd = data.transXd * k;
1044  transXq = data.transXq * k;
1045  if(syncXq == 0.0) syncXq = syncXd;
1046  if(transXq == 0.0) transXq = transXd;
1047 
1048  double tranEq = (data.icTranEq.c + data.icTranEq.m * (data.fieldVoltage + (syncXd - transXd) * id)) /
1049  (1.0 + data.icTranEq.m * (sd - 1.0));
1050  error = std::max(error, std::abs(data.tranEq - tranEq));
1051 
1052  double tranEd =
1053  (data.icTranEd.c - data.icTranEd.m * (syncXq - transXq) * iq) / (1.0 + data.icTranEd.m * (sq - 1.0));
1054  error = std::max(error, std::abs(data.tranEd - tranEd));
1055 
1056  data.tranEq = tranEq;
1057  data.tranEd = tranEd;
1058 
1059  if(!syncGenerator->IsOnline()) {
1060  std::complex<double> e;
1061  DQ0toABC(data.tranEd, data.tranEq, data.delta, e);
1062  data.terminalVoltage = e;
1063  }
1064  } break;
1065  case Machines::SM_MODEL_4: {
1066  double syncXd, syncXq, transXd, subXd, subXq;
1067  syncXd = data.syncXd * k;
1068  syncXq = data.syncXq * k;
1069  transXd = data.transXd * k;
1070  subXd = data.subXd * k;
1071  subXq = data.subXq * k;
1072  if(syncXq == 0.0) syncXq = syncXd;
1073  if(subXd == 0.0) subXd = subXq;
1074  if(subXq == 0.0) subXq = subXd;
1075 
1076  double tranEq = (data.icTranEq.c + data.icTranEq.m * (data.fieldVoltage + (syncXd - transXd) * id)) /
1077  (1.0 + data.icTranEq.m * (sd - 1.0));
1078  error = std::max(error, std::abs(data.tranEq - tranEq));
1079 
1080  double subEq = (data.icSubEq.c + data.icSubEq.m * (sd * tranEq + (transXd - subXd) * id)) /
1081  (1.0 + data.icSubEq.m * (sd - 1.0));
1082  error = std::max(error, std::abs(data.subEq - subEq));
1083 
1084  double subEd =
1085  (data.icSubEd.c - data.icSubEd.m * ((syncXq - subXq) * iq)) / (1.0 + data.icSubEd.m * (sq - 1.0));
1086  error = std::max(error, std::abs(data.subEd - subEd));
1087 
1088  data.tranEq = tranEq;
1089  data.subEq = subEq;
1090  data.subEd = subEd;
1091  } break;
1092  case Machines::SM_MODEL_5: {
1093  double syncXd, syncXq, transXd, transXq, subXd, subXq;
1094  syncXd = data.syncXd * k;
1095  syncXq = data.syncXq * k;
1096  transXd = data.transXd * k;
1097  transXq = data.transXq * k;
1098  subXd = data.subXd * k;
1099  subXq = data.subXq * k;
1100  if(syncXq == 0.0) syncXq = syncXd;
1101  if(transXq == 0.0) transXq = transXd;
1102  if(subXd == 0.0) subXd = subXq;
1103  if(subXq == 0.0) subXq = subXd;
1104 
1105  double tranEq = (data.icTranEq.c + data.icTranEq.m * (data.fieldVoltage + (syncXd - transXd) * id)) /
1106  (1.0 + data.icTranEq.m * (sd - 1.0));
1107  error = std::max(error, std::abs(data.tranEq - tranEq));
1108 
1109  double tranEd =
1110  (data.icTranEd.c - data.icTranEd.m * (syncXq - transXq) * iq) / (1.0 + data.icTranEd.m * (sq - 1.0));
1111  error = std::max(error, std::abs(data.tranEd - tranEd));
1112 
1113  double subEq = (data.icSubEq.c + data.icSubEq.m * (sd * tranEq + (transXd - subXd) * id)) /
1114  (1.0 + data.icSubEq.m * (sd - 1.0));
1115  error = std::max(error, std::abs(data.subEq - subEq));
1116 
1117  double subEd = (data.icSubEd.c + data.icSubEd.m * (sq * tranEd - (transXq - subXq) * iq)) /
1118  (1.0 + data.icSubEd.m * (sq - 1.0));
1119  error = std::max(error, std::abs(data.subEd - subEd));
1120 
1121  data.tranEq = tranEq;
1122  data.tranEd = tranEd;
1123  data.subEq = subEq;
1124  data.subEd = subEd;
1125  } break;
1126  }
1127 
1128  syncGenerator->SetElectricalData(data);
1129  return error;
1130 }
1131 
1132 void Electromechanical::CalculateReferenceSpeed()
1133 {
1134  if(m_useCOI) {
1135  double sumHW = 0.0;
1136  double sumH = 0.0;
1137  for(auto it = m_syncGeneratorList.begin(), itEnd = m_syncGeneratorList.end(); it != itEnd; ++it) {
1138  SyncGenerator* syncGenerator = *it;
1139  if(syncGenerator->IsOnline()) {
1140  auto data = syncGenerator->GetElectricalData();
1141  double k = 1.0; // Power base change factor.
1142  if(data.useMachineBase) {
1143  double oldBase = syncGenerator->GetValueFromUnit(data.nominalPower, data.nominalPowerUnit);
1144  k = m_powerSystemBase / oldBase;
1145  }
1146  sumH += data.inertia / k;
1147  sumHW += data.inertia * data.speed / k;
1148  }
1149  }
1150  m_refSpeed = sumHW / sumH;
1151  } else {
1152  m_refSpeed = 2.0 * M_PI * m_systemFreq;
1153  }
1154 }
1155 
1156 bool Electromechanical::CalculateSyncMachineSaturation(SyncGenerator* syncMachine,
1157  double& id,
1158  double& iq,
1159  double& sd,
1160  double& sq,
1161  bool updateCurrents,
1162  double k)
1163 {
1164  // [Ref] Arrillaga, J.; Arnold, C. P.. "Computer Modelling of Electrical Power Systems". Pg. 254-260
1165  auto data = syncMachine->GetElectricalData();
1166  auto smDataModel = GetSyncMachineModelData(syncMachine);
1167 
1168  int n = static_cast<Bus*>(syncMachine->GetParentList()[0])->GetElectricalData().number;
1169  if(syncMachine->IsOnline()) {
1170  data.terminalVoltage = m_vBus[n];
1171  }
1172  double idCalc = id;
1173  double iqCalc = iq;
1174  double sdCalc = sd;
1175  double sqCalc = sq;
1176 
1177  double vd, vq;
1178  ABCtoDQ0(data.terminalVoltage, data.delta, vd, vq);
1179  double deltaVd = smDataModel.ed - vd;
1180  double deltaVq = smDataModel.eq - vq;
1181 
1182  double ra = data.armResistance * k;
1183  double xd = smDataModel.xd;
1184  double xq = smDataModel.xq;
1185 
1186  double syncXd = data.syncXd * k;
1187  double syncXq = data.syncXq * k;
1188  if(data.model == Machines::SM_MODEL_1) {
1189  syncXq = data.transXd * k;
1190  syncXd = syncXq;
1191  } else if(data.syncXq == 0.0)
1192  syncXq = data.syncXd * k;
1193 
1194  double xp = data.potierReactance * k;
1195  if(xp == 0.0) xp = 0.8 * data.transXd * k;
1196  double satFacd = (data.satFactor - 1.2) / std::pow(1.2, 7);
1197  double satFacq = satFacd * (syncXq / syncXd);
1198 
1199  bool exit = false;
1200  int iterations = 0;
1201  while(!exit) {
1202  double oldSd = sdCalc;
1203  double oldSq = sqCalc;
1204 
1205  // Saturated reactances.
1206  double xds = (xd - xp) / sdCalc + xp;
1207  double xqs = (xq - xp) / sqCalc + xp;
1208  // dq currents.
1209  double den = 1.0 / (ra * ra + xds * xqs);
1210  iqCalc = den * (ra * deltaVq + xds * deltaVd);
1211  idCalc = den * (-xqs * deltaVq + ra * deltaVd);
1212  // Potier voltages
1213  double epq = vq + ra * iqCalc - xp * idCalc;
1214  double epd = vd + ra * idCalc + xp * iqCalc;
1215  // Saturation factors.
1216  // Gauss
1217  /*sdCalc = 1.0 + satFacd * std::pow(epq, 6);
1218  sqCalc = 1.0 + satFacq * std::pow(epd, 6);*/
1219 
1220  // Newton-raphson
1221  double f1 = 1.0 - sdCalc + satFacd * std::pow(epq, 6);
1222  double f2 = 1.0 - sqCalc + satFacq * std::pow(epd, 6);
1223  double dF1dSd =
1224  (6.0 * satFacd * std::pow(epq, 5) * xp * (xd - xp) * deltaVq) / ((sdCalc - 1.0) * xp + xd) - 1.0;
1225  double dF2dSq =
1226  (6.0 * satFacq * std::pow(epd, 5) * xp * (xq - xp) * deltaVd) / ((sqCalc - 1.0) * xp + xq) - 1.0;
1227 
1228  sdCalc = sdCalc - f1 / dF1dSd;
1229  sqCalc = sqCalc - f2 / dF2dSq;
1230 
1231  double error = std::abs(sdCalc - oldSd) + std::abs(sqCalc - oldSq);
1232  if(error < m_saturationTolerance) exit = true;
1233 
1234  iterations++;
1235  if((iterations >= m_maxIterations) & !exit) {
1236  m_errorMsg =
1237  _("It was not possible to solve the saturation of the synchronous machine \"") + data.name + wxT("\".");
1238  return false;
1239  }
1240  }
1241 
1242  sd = sdCalc;
1243  sq = sqCalc;
1244  if(updateCurrents) {
1245  id = idCalc;
1246  iq = iqCalc;
1247  }
1248  return true;
1249 }
1250 
1251 SyncMachineModelData Electromechanical::GetSyncMachineModelData(SyncGenerator* syncMachine)
1252 {
1253  SyncMachineModelData smModelData;
1254 
1255  auto data = syncMachine->GetElectricalData();
1256  double k = 1.0; // Power base change factor.
1257  if(data.useMachineBase) {
1258  double oldBase = syncMachine->GetValueFromUnit(data.nominalPower, data.nominalPowerUnit);
1259  k = m_powerSystemBase / oldBase;
1260  }
1261 
1262  switch(data.model) {
1263  case Machines::SM_MODEL_1: {
1264  smModelData.ed = data.tranEd;
1265  smModelData.eq = data.tranEq;
1266  smModelData.xq = data.transXd * k;
1267  smModelData.xd = smModelData.xq;
1268  } break;
1269  case Machines::SM_MODEL_2: {
1270  smModelData.ed = data.tranEd;
1271  smModelData.eq = data.tranEq;
1272  smModelData.xd = data.transXd * k;
1273  smModelData.xq = data.transXq * k;
1274  if(smModelData.xq == 0.0) {
1275  smModelData.xq = data.syncXq * k;
1276  if(smModelData.xq == 0.0) {
1277  smModelData.xq = data.syncXd * k;
1278  }
1279  }
1280  } break;
1281  case Machines::SM_MODEL_3: {
1282  smModelData.ed = data.tranEd;
1283  smModelData.eq = data.tranEq;
1284  smModelData.xd = data.transXd * k;
1285  smModelData.xq = data.transXq * k;
1286  if(smModelData.xq == 0.0) smModelData.xq = smModelData.xd;
1287  } break;
1288  case Machines::SM_MODEL_4:
1289  case Machines::SM_MODEL_5: {
1290  smModelData.ed = data.subEd;
1291  smModelData.eq = data.subEq;
1292  smModelData.xd = data.subXd * k;
1293  smModelData.xq = data.subXq * k;
1294  if(smModelData.xd == 0.0) smModelData.xd = smModelData.xq;
1295  if(smModelData.xq == 0.0) smModelData.xq = smModelData.xd;
1296  } break;
1297  }
1298  return smModelData;
1299 }
std::vector< double > swTime
Definition: PowerElement.h:95
+
1 /*
2  * Copyright (C) 2017 Thales Lima Oliveira <thales@ufu.br>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program. If not, see <https://www.gnu.org/licenses/>.
16  */
17 
18 #include "Electromechanical.h"
19 #include "ControlElementSolver.h"
20 
21 Electromechanical::Electromechanical(wxWindow* parent, std::vector<Element*> elementList, SimulationData data)
22 {
23  m_parent = parent;
24  GetElementsFromList(elementList);
25  SetEventTimeList();
26 
27  Bus dummyBus;
28  m_powerSystemBase = dummyBus.GetValueFromUnit(data.basePower, data.basePowerUnit);
29  m_systemFreq = data.stabilityFrequency;
30  m_simTime = data.stabilitySimulationTime;
31  m_timeStep = data.timeStep;
32  m_tolerance = data.stabilityTolerance;
33  m_maxIterations = data.stabilityMaxIterations;
34 
35  m_ctrlTimeStepMultiplier = 1.0 / static_cast<double>(data.controlTimeStepRatio);
36 
37  m_plotTime = data.plotTime;
38  m_useCOI = data.useCOI;
39  // If the user use all load as ZIP, updates the portions of each model, otherwise use constant impedance only.
40  for(auto it = m_loadList.begin(), itEnd = m_loadList.end(); it != itEnd; ++it) {
41  Load* load = *it;
42  auto loadData = load->GetElectricalData();
43  if(!loadData.useCompLoad) { // If no individual load composition defined.
44  if(data.useCompLoads) { // Use general composition, if defined.
45  loadData.constImpedanceActive = data.constImpedanceActive;
46  loadData.constCurrentActive = data.constCurrentActive;
47  loadData.constPowerActive = data.constPowerActive;
48  loadData.constImpedanceReactive = data.constImpedanceReactive;
49  loadData.constCurrentReactive = data.constCurrentReactive;
50  loadData.constPowerReactive = data.constPowerReactive;
51  } else { // Otherwise, use constant impedance.
52  loadData.constImpedanceActive = 100.0;
53  loadData.constCurrentActive = 0.0;
54  loadData.constPowerActive = 0.0;
55  loadData.constImpedanceReactive = 100.0;
56  loadData.constCurrentReactive = 0.0;
57  loadData.constPowerReactive = 0.0;
58  }
59  }
60 
61  loadData.constCurrentUV = data.underVoltageConstCurrent / 100.0;
62  loadData.constPowerUV = data.underVoltageConstPower / 100.0;
63  load->SetElectricalData(loadData);
64  }
65 }
66 
67 Electromechanical::~Electromechanical() {}
68 bool Electromechanical::RunStabilityCalculation()
69 {
70  wxProgressDialog pbd(_("Running simulation"), _("Initializing..."), 100, m_parent,
71  wxPD_APP_MODAL | wxPD_AUTO_HIDE | wxPD_CAN_ABORT | wxPD_SMOOTH);
72 
73  SetSyncMachinesModel();
74 
75  // Calculate the admittance matrix with the synchronous machines.
76  if(!GetYBus(m_yBus, m_powerSystemBase, POSITIVE_SEQ, false, true)) {
77  m_errorMsg = _("It was not possible to build the admittance matrix.");
78  return false;
79  }
80  InsertSyncMachinesOnYBus();
81  GetLUDecomposition(m_yBus, m_yBusL, m_yBusU);
82 
83  // Get buses voltages.
84  m_vBus.clear();
85  m_vBus.resize(m_busList.size());
86  for(auto it = m_busList.begin(), itEnd = m_busList.end(); it != itEnd; ++it) {
87  Bus* bus = *it;
88  auto data = bus->GetElectricalData();
89  m_vBus[data.number] = data.voltage;
90  }
91 
92  // Calculate injected currents
93  m_iBus = ComplexMatrixTimesVector(m_yBus, m_vBus);
94  for(unsigned int i = 0; i < m_iBus.size(); ++i) {
95  if(std::abs(m_iBus[i]) < 1e-5) m_iBus[i] = std::complex<double>(0.0, 0.0);
96  }
97 
98  if(!InitializeDynamicElements()) return false;
99 
100  double pbdTime = m_plotTime;
101  double currentTime = 0.0;
102  double currentPlotTime = 0.0;
103  double currentPbdTime = 0.0;
104  while(currentTime < m_simTime) {
105  if(HasEvent(currentTime)) {
106  SetEvent(currentTime);
107  GetLUDecomposition(m_yBus, m_yBusL, m_yBusU);
108  }
109 
110  if(currentPlotTime >= m_plotTime || currentTime == 0.0) {
111  m_timeVector.push_back(currentTime);
112  SaveData();
113  currentPlotTime = 0.0;
114  }
115 
116  if(currentPbdTime > pbdTime) {
117  if(!pbd.Update((currentTime / m_simTime) * 100, wxString::Format("Time = %.2fs", currentTime))) {
118  m_errorMsg = wxString::Format(_("Simulation cancelled at %.2fs."), currentTime);
119  pbd.Update(100);
120  return false;
121  }
122  currentPbdTime = 0.0;
123  }
124 
125  if(!SolveSynchronousMachines()) return false;
126 
127  currentTime += m_timeStep;
128  currentPlotTime += m_timeStep;
129  currentPbdTime += m_timeStep;
130  }
131  return true;
132 }
133 
134 void Electromechanical::SetEventTimeList()
135 {
136  // Fault
137  for(auto it = m_busList.begin(), itEnd = m_busList.end(); it != itEnd; ++it) {
138  Bus* bus = *it;
139  auto data = bus->GetElectricalData();
140  if(data.stabHasFault) {
141  m_eventTimeList.push_back(data.stabFaultTime);
142  m_eventOccurrenceList.push_back(false);
143  m_eventTimeList.push_back(data.stabFaultTime + data.stabFaultLength);
144  m_eventOccurrenceList.push_back(false);
145  }
146  }
147  // Switching
148  for(auto it = m_powerElementList.begin(), itEnd = m_powerElementList.end(); it != itEnd; ++it) {
149  PowerElement* element = *it;
150  SwitchingData swData = element->GetSwitchingData();
151  for(unsigned int i = 0; i < swData.swTime.size(); ++i) {
152  m_eventTimeList.push_back(swData.swTime[i]);
153  m_eventOccurrenceList.push_back(false);
154  }
155  }
156 }
157 
158 bool Electromechanical::HasEvent(double currentTime)
159 {
160  for(unsigned int i = 0; i < m_eventTimeList.size(); ++i) {
161  if(!m_eventOccurrenceList[i]) {
162  if(EventTrigger(m_eventTimeList[i], currentTime)) {
163  m_eventOccurrenceList[i] = true;
164  return true;
165  }
166  }
167  }
168  return false;
169 }
170 
171 void Electromechanical::SetEvent(double currentTime)
172 {
173  // Fault
174  for(auto it = m_busList.begin(), itEnd = m_busList.end(); it != itEnd; ++it) {
175  Bus* bus = *it;
176  auto data = bus->GetElectricalData();
177  if(data.stabHasFault) {
178  int n = data.number;
179 
180  // Insert fault
181  if(EventTrigger(data.stabFaultTime, currentTime)) {
182  double r, x;
183  r = data.stabFaultResistance;
184  x = data.stabFaultReactance;
185  if(x < 1e-5) x = 1e-5;
186  m_yBus[n][n] += std::complex<double>(1.0, 0.0) / std::complex<double>(r, x);
187  }
188 
189  // Remove fault
190  else if(EventTrigger(data.stabFaultTime + data.stabFaultLength, currentTime)) {
191  double r, x;
192  r = data.stabFaultResistance;
193  x = data.stabFaultReactance;
194  if(x < 1e-5) x = 1e-5;
195  m_yBus[n][n] -= std::complex<double>(1.0, 0.0) / std::complex<double>(r, x);
196  }
197  }
198  }
199 
200  // SyncGenerator switching
201  for(auto it = m_syncGeneratorList.begin(), itEnd = m_syncGeneratorList.end(); it != itEnd; ++it) {
202  SyncGenerator* generator = *it;
203  auto swData = generator->GetSwitchingData();
204  for(unsigned int i = 0; i < swData.swType.size(); ++i) {
205  if(EventTrigger(swData.swTime[i], currentTime)) {
206  // Remove machine (only connected machines)
207  if(swData.swType[i] == SW_REMOVE && generator->IsOnline()) {
208  generator->SetOnline(false);
209  int n = static_cast<Bus*>(generator->GetParentList()[0])->GetElectricalData().number;
210  m_yBus[n][n] -= GetSyncMachineAdmittance(generator);
211  }
212 
213  // Insert machine (only disconnected machines)
214  if(swData.swType[i] == SW_INSERT && !generator->IsOnline() && generator->GetParentList().size() == 1) {
215  if(generator->SetOnline(true)) {
216  int n = static_cast<Bus*>(generator->GetParentList()[0])->GetElectricalData().number;
217  m_yBus[n][n] += GetSyncMachineAdmittance(generator);
218  }
219  }
220  }
221  }
222  }
223 
224  // Load switching
225  for(auto it = m_loadList.begin(), itEnd = m_loadList.end(); it != itEnd; ++it) {
226  Load* load = *it;
227  auto swData = load->GetSwitchingData();
228  for(unsigned int i = 0; i < swData.swType.size(); ++i) {
229  if(EventTrigger(swData.swTime[i], currentTime)) {
230  // Remove load (only connected loads)
231  if(swData.swType[i] == SW_REMOVE && load->IsOnline()) {
232  load->SetOnline(false);
233  auto data = load->GetPUElectricalData(m_powerSystemBase);
234  Bus* parentBus = static_cast<Bus*>(load->GetParentList()[0]);
235  int n = parentBus->GetElectricalData().number;
236  std::complex<double> v = parentBus->GetElectricalData().voltage;
237  m_yBus[n][n] -= std::complex<double>(data.activePower, -data.reactivePower) / (v * v);
238  }
239 
240  // Insert load (only disconnected load)
241  if(swData.swType[i] == SW_INSERT && !load->IsOnline() && load->GetParentList().size() == 1) {
242  if(load->SetOnline(true)) {
243  auto data = load->GetPUElectricalData(m_powerSystemBase);
244  Bus* parentBus = static_cast<Bus*>(load->GetParentList()[0]);
245  int n = parentBus->GetElectricalData().number;
246  std::complex<double> v = parentBus->GetElectricalData().voltage;
247  m_yBus[n][n] += std::complex<double>(data.activePower, -data.reactivePower) / (v * v);
248  }
249  }
250  }
251  }
252  }
253 
254  // Line switching
255  for(auto it = m_lineList.begin(), itEnd = m_lineList.end(); it != itEnd; ++it) {
256  Line* line = *it;
257  auto swData = line->GetSwitchingData();
258  for(unsigned int i = 0; i < swData.swType.size(); ++i) {
259  if(EventTrigger(swData.swTime[i], currentTime)) {
260  // Remove line (only connected lines)
261  if(swData.swType[i] == SW_REMOVE && line->IsOnline()) {
262  line->SetOnline(false);
263  auto data = line->GetElectricalData();
264 
265  int n1 = static_cast<Bus*>(line->GetParentList()[0])->GetElectricalData().number;
266  int n2 = static_cast<Bus*>(line->GetParentList()[1])->GetElectricalData().number;
267 
268  m_yBus[n1][n2] += 1.0 / std::complex<double>(data.resistance, data.indReactance);
269  m_yBus[n2][n1] += 1.0 / std::complex<double>(data.resistance, data.indReactance);
270 
271  m_yBus[n1][n1] -= 1.0 / std::complex<double>(data.resistance, data.indReactance);
272  m_yBus[n2][n2] -= 1.0 / std::complex<double>(data.resistance, data.indReactance);
273 
274  m_yBus[n1][n1] -= std::complex<double>(0.0, data.capSusceptance / 2.0);
275  m_yBus[n2][n2] -= std::complex<double>(0.0, data.capSusceptance / 2.0);
276  }
277 
278  // Insert line (only disconnected lines)
279  if(swData.swType[i] == SW_INSERT && !line->IsOnline() && line->GetParentList().size() == 2) {
280  if(line->SetOnline(true)) {
281  auto data = line->GetElectricalData();
282 
283  int n1 = static_cast<Bus*>(line->GetParentList()[0])->GetElectricalData().number;
284  int n2 = static_cast<Bus*>(line->GetParentList()[1])->GetElectricalData().number;
285 
286  m_yBus[n1][n2] -= 1.0 / std::complex<double>(data.resistance, data.indReactance);
287  m_yBus[n2][n1] -= 1.0 / std::complex<double>(data.resistance, data.indReactance);
288 
289  m_yBus[n1][n1] += 1.0 / std::complex<double>(data.resistance, data.indReactance);
290  m_yBus[n2][n2] += 1.0 / std::complex<double>(data.resistance, data.indReactance);
291 
292  m_yBus[n1][n1] += std::complex<double>(0.0, data.capSusceptance / 2.0);
293  m_yBus[n2][n2] += std::complex<double>(0.0, data.capSusceptance / 2.0);
294  }
295  }
296  }
297  }
298  }
299 
300  // Transformer switching
301  for(auto it = m_transformerList.begin(), itEnd = m_transformerList.end(); it != itEnd; ++it) {
302  Transformer* transformer = *it;
303  auto swData = transformer->GetSwitchingData();
304  for(unsigned int i = 0; i < swData.swType.size(); ++i) {
305  if(EventTrigger(swData.swTime[i], currentTime)) {
306  // Remove transformer (only connected transformers)
307  if(swData.swType[i] == SW_REMOVE && transformer->IsOnline()) {
308  transformer->SetOnline(false);
309  auto data = transformer->GetElectricalData();
310 
311  int n1 = static_cast<Bus*>(transformer->GetParentList()[0])->GetElectricalData().number;
312  int n2 = static_cast<Bus*>(transformer->GetParentList()[1])->GetElectricalData().number;
313 
314  if(data.turnsRatio == 1.0 && data.phaseShift == 0.0) {
315  m_yBus[n1][n2] -= -1.0 / std::complex<double>(data.resistance, data.indReactance);
316  m_yBus[n2][n1] -= -1.0 / std::complex<double>(data.resistance, data.indReactance);
317 
318  m_yBus[n1][n1] -= 1.0 / std::complex<double>(data.resistance, data.indReactance);
319  m_yBus[n2][n2] -= 1.0 / std::complex<double>(data.resistance, data.indReactance);
320  } else {
321  // Complex turns ratio
322  double radPhaseShift = wxDegToRad(data.phaseShift);
323  std::complex<double> a = std::complex<double>(data.turnsRatio * std::cos(radPhaseShift),
324  -data.turnsRatio * std::sin(radPhaseShift));
325 
326  // Transformer admitance
327  std::complex<double> y = 1.0 / std::complex<double>(data.resistance, data.indReactance);
328  m_yBus[n1][n1] -= y / std::pow(std::abs(a), 2.0);
329  m_yBus[n1][n2] -= -(y / std::conj(a));
330  m_yBus[n2][n1] -= -(y / a);
331  m_yBus[n2][n2] -= y;
332  }
333  }
334 
335  // Insert transformer (only disconnected transformers)
336  if(swData.swType[i] == SW_INSERT && !transformer->IsOnline() &&
337  transformer->GetParentList().size() == 2) {
338  if(transformer->SetOnline(true)) {
339  auto data = transformer->GetElectricalData();
340 
341  int n1 = static_cast<Bus*>(transformer->GetParentList()[0])->GetElectricalData().number;
342  int n2 = static_cast<Bus*>(transformer->GetParentList()[1])->GetElectricalData().number;
343 
344  if(data.turnsRatio == 1.0 && data.phaseShift == 0.0) {
345  m_yBus[n1][n2] += -1.0 / std::complex<double>(data.resistance, data.indReactance);
346  m_yBus[n2][n1] += -1.0 / std::complex<double>(data.resistance, data.indReactance);
347 
348  m_yBus[n1][n1] += 1.0 / std::complex<double>(data.resistance, data.indReactance);
349  m_yBus[n2][n2] += 1.0 / std::complex<double>(data.resistance, data.indReactance);
350  } else {
351  // Complex turns ratio
352  double radPhaseShift = wxDegToRad(data.phaseShift);
353  std::complex<double> a = std::complex<double>(data.turnsRatio * std::cos(radPhaseShift),
354  -data.turnsRatio * std::sin(radPhaseShift));
355 
356  // Transformer admitance
357  std::complex<double> y = 1.0 / std::complex<double>(data.resistance, data.indReactance);
358  m_yBus[n1][n1] += y / std::pow(std::abs(a), 2.0);
359  m_yBus[n1][n2] += -(y / std::conj(a));
360  m_yBus[n2][n1] += -(y / a);
361  m_yBus[n2][n2] += y;
362  }
363  }
364  }
365  }
366  }
367  }
368 
369  // Capacitor switching
370  for(auto it = m_capacitorList.begin(), itEnd = m_capacitorList.end(); it != itEnd; ++it) {
371  Capacitor* capacitor = *it;
372  auto swData = capacitor->GetSwitchingData();
373  for(unsigned int i = 0; i < swData.swType.size(); ++i) {
374  if(EventTrigger(swData.swTime[i], currentTime)) {
375  // Remove capacitor (only connected capacitors)
376  if(swData.swType[i] == SW_REMOVE && capacitor->IsOnline()) {
377  capacitor->SetOnline(false);
378  auto data = capacitor->GetPUElectricalData(m_powerSystemBase);
379  int n = static_cast<Bus*>(capacitor->GetParentList()[0])->GetElectricalData().number;
380  m_yBus[n][n] -= std::complex<double>(0.0, data.reactivePower);
381  }
382 
383  // Insert capacitor (only disconnected capacitors)
384  if(swData.swType[i] == SW_INSERT && !capacitor->IsOnline() && capacitor->GetParentList().size() == 1) {
385  if(capacitor->SetOnline(true)) {
386  auto data = capacitor->GetPUElectricalData(m_powerSystemBase);
387  int n = static_cast<Bus*>(capacitor->GetParentList()[0])->GetElectricalData().number;
388  m_yBus[n][n] += std::complex<double>(0.0, data.reactivePower);
389  }
390  }
391  }
392  }
393  }
394 
395  // Inductor switching
396  for(auto it = m_inductorList.begin(), itEnd = m_inductorList.end(); it != itEnd; ++it) {
397  Inductor* inductor = *it;
398  auto swData = inductor->GetSwitchingData();
399  for(unsigned int i = 0; i < swData.swType.size(); ++i) {
400  if(EventTrigger(swData.swTime[i], currentTime)) {
401  // Remove inductor (only connected inductors)
402  if(swData.swType[i] == SW_REMOVE && inductor->IsOnline()) {
403  inductor->SetOnline(false);
404  auto data = inductor->GetPUElectricalData(m_powerSystemBase);
405  int n = static_cast<Bus*>(inductor->GetParentList()[0])->GetElectricalData().number;
406  m_yBus[n][n] -= std::complex<double>(0.0, -data.reactivePower);
407  }
408 
409  // Insert inductor (only disconnected inductors)
410  if(swData.swType[i] == SW_INSERT && !inductor->IsOnline() && inductor->GetParentList().size() == 1) {
411  if(inductor->SetOnline(true)) {
412  auto data = inductor->GetPUElectricalData(m_powerSystemBase);
413  int n = static_cast<Bus*>(inductor->GetParentList()[0])->GetElectricalData().number;
414  m_yBus[n][n] += std::complex<double>(0.0, -data.reactivePower);
415  }
416  }
417  }
418  }
419  }
420 }
421 
422 void Electromechanical::InsertSyncMachinesOnYBus()
423 {
424  for(auto it = m_syncGeneratorList.begin(), itEnd = m_syncGeneratorList.end(); it != itEnd; ++it) {
425  SyncGenerator* generator = *it;
426  if(generator->IsOnline()) {
427  auto data = generator->GetElectricalData();
428  int n = static_cast<Bus*>(generator->GetParentList()[0])->GetElectricalData().number;
429  m_yBus[n][n] += GetSyncMachineAdmittance(generator);
430  }
431  }
432 }
433 
434 bool Electromechanical::EventTrigger(double eventTime, double currentTime)
435 {
436  return (((eventTime - m_timeStep) < currentTime) && (eventTime >= currentTime));
437 }
438 
439 std::complex<double> Electromechanical::GetSyncMachineAdmittance(SyncGenerator* generator)
440 {
441  auto data = generator->GetElectricalData();
442  double k = 1.0; // Power base change factor.
443  if(data.useMachineBase) {
444  double oldBase = generator->GetValueFromUnit(data.nominalPower, data.nominalPowerUnit);
445  k = m_powerSystemBase / oldBase;
446  }
447 
448  double ra = data.armResistance * k;
449  auto smModelData = GetSyncMachineModelData(generator);
450  double xd = smModelData.xd;
451  double xq = smModelData.xq;
452  double xdq = 0.5 * (xd + xq);
453  return (std::complex<double>(ra, -xdq) / std::complex<double>(ra * ra + xd * xq, 0.0));
454 }
455 
456 bool Electromechanical::InitializeDynamicElements()
457 {
458  // Buses
459  for(auto it = m_busList.begin(), itEnd = m_busList.end(); it != itEnd; ++it) {
460  Bus* bus = *it;
461  auto data = bus->GetElectricalData();
462  data.stabVoltageVector.clear();
463  bus->SetElectricalData(data);
464  }
465  // Loads
466  for(auto it = m_loadList.begin(), itEnd = m_loadList.end(); it != itEnd; ++it) {
467  Load* load = *it;
468  auto dataPU = load->GetPUElectricalData(m_powerSystemBase);
469  auto data = load->GetElectricalData();
470 
471  double activePower = dataPU.activePower;
472  double reactivePower = dataPU.reactivePower;
473 
474  if(load) data.voltage = static_cast<Bus*>(load->GetParentList()[0])->GetElectricalData().voltage;
475  data.v0 = std::abs(data.voltage);
476  data.y0 = std::complex<double>(activePower, -reactivePower) / (data.v0 * data.v0);
477 
478  if(data.loadType == CONST_IMPEDANCE) {
479  std::complex<double> s0 = std::complex<double>(activePower, -reactivePower) * (data.v0 * data.v0);
480  activePower = s0.real();
481  reactivePower = -s0.imag();
482  }
483 
484  data.pz0 = (data.constImpedanceActive / 100.0) * activePower;
485  data.pi0 = (data.constCurrentActive / 100.0) * activePower;
486  data.pp0 = (data.constPowerActive / 100.0) * activePower;
487 
488  data.qz0 = (data.constImpedanceReactive / 100.0) * reactivePower;
489  data.qi0 = (data.constCurrentReactive / 100.0) * reactivePower;
490  data.qp0 = (data.constPowerReactive / 100.0) * reactivePower;
491 
492  data.voltageVector.clear();
493  data.electricalPowerVector.clear();
494 
495  if(load->IsOnline())
496  data.electricalPower = std::complex<double>(activePower, reactivePower);
497  else {
498  data.electricalPower = std::complex<double>(0.0, 0.0);
499  data.voltage = std::complex<double>(0.0, 0.0);
500  }
501 
502  load->SetElectricalData(data);
503  }
504  // Synchronous generators
505  for(auto it = m_syncGeneratorList.begin(), itEnd = m_syncGeneratorList.end(); it != itEnd; ++it) {
506  SyncGenerator* syncGenerator = *it;
507  auto dataPU = syncGenerator->GetPUElectricalData(m_powerSystemBase);
508  auto data = syncGenerator->GetElectricalData();
509  if(syncGenerator->IsOnline()) {
510  double k = 1.0; // Power base change factor.
511  if(data.useMachineBase) {
512  double oldBase = syncGenerator->GetValueFromUnit(data.nominalPower, data.nominalPowerUnit);
513  k = m_powerSystemBase / oldBase;
514  }
515  data.terminalVoltage = static_cast<Bus*>(syncGenerator->GetParentList()[0])->GetElectricalData().voltage;
516 
517  std::complex<double> conjS(dataPU.activePower, -dataPU.reactivePower);
518  std::complex<double> vt = data.terminalVoltage;
519  std::complex<double> ia = conjS / std::conj(vt);
520 
521  double xd = data.syncXd * k;
522  double xq = data.syncXq * k;
523  double ra = data.armResistance * k;
524 
525  if(data.model == Machines::SM_MODEL_1) {
526  xq = data.transXd * k;
527  xd = xq;
528  } else if(data.syncXq == 0.0)
529  xq = data.syncXd * k;
530 
531  double sd = 1.0;
532  double sq = 1.0;
533  double satF = 1.0;
534  double xp = data.potierReactance * k;
535  bool hasSaturation = false;
536  if(data.satFactor != 0.0) { // Have saturation.
537  satF = (data.satFactor - 1.2) / std::pow(1.2, 7);
538  if(xp == 0.0) xp = 0.8 * (data.transXd * k);
539  hasSaturation = true;
540  }
541 
542  // Initialize state variables
543  std::complex<double> eq0 = vt + std::complex<double>(ra, xq) * ia;
544  double delta = std::arg(eq0);
545 
546  double id0, iq0, vd0, vq0;
547  ABCtoDQ0(ia, delta, id0, iq0);
548  ABCtoDQ0(vt, delta, vd0, vq0);
549 
550  // Initialize saturation
551  double xqs = xq;
552  double xds = xd;
553  if(hasSaturation) {
554  double oldDelta = 0;
555  bool exit = false;
556  int numIt = 0;
557  while(!exit) {
558  oldDelta = delta;
559  ABCtoDQ0(ia, delta, id0, iq0);
560  ABCtoDQ0(vt, delta, vd0, vq0);
561 
562  // Direct-axis Potier voltage.
563  double epd = vd0 + ra * id0 + xp * iq0;
564 
565  sq = 1.0 + satF * (xq / xd) * std::pow(epd, 6);
566  xqs = (xq - xp) / sq + xp;
567  eq0 = data.terminalVoltage + std::complex<double>(ra, xqs) * ia;
568  delta = std::arg(eq0);
569  if(std::abs(delta - oldDelta) < m_saturationTolerance) {
570  exit = true;
571  } else if(numIt >= m_maxIterations) {
572  m_errorMsg = _("Error on initializate the saturation values of \"") + data.name + _("\".");
573  return false;
574  }
575  numIt++;
576  }
577  // Quadrature-axis Potier voltage.
578  double epq = vq0 + ra * iq0 - xp * id0;
579  sd = 1.0 + satF * std::pow(epq, 6);
580  xds = (xd - xp) / sd + xp;
581  }
582 
583  double ef0 = vq0 + ra * iq0 - xds * id0;
584 
585  data.initialFieldVoltage = ef0 * sd;
586  data.fieldVoltage = data.initialFieldVoltage;
587  data.pm = std::real((data.terminalVoltage * std::conj(ia)) + (std::abs(ia) * std::abs(ia) * ra));
588  data.speed = 2.0 * M_PI * m_systemFreq;
589  data.delta = delta;
590  data.pe = data.pm;
591  data.electricalPower = std::complex<double>(dataPU.activePower, dataPU.reactivePower);
592  data.sd = sd;
593  data.sq = sq;
594  data.id = id0;
595  data.iq = iq0;
596 
597  // Variables to extrapolate.
598  data.oldIq = iq0;
599  data.oldId = id0;
600  data.oldPe = data.pe;
601  data.oldSd = sd;
602  data.oldSq = sq;
603 
604  switch(data.model) {
605  case Machines::SM_MODEL_1: {
606  data.tranEq = std::abs(eq0);
607 
608  data.tranEd = 0.0;
609  data.subEq = 0.0;
610  data.subEd = 0.0;
611  } break;
612  case Machines::SM_MODEL_2: {
613  double tranXd = data.transXd * k;
614 
615  data.tranEq = ef0 + (xd - tranXd) * (id0 / sd);
616  data.tranEd = 0.0;
617  data.subEd = 0.0;
618  data.subEq = 0.0;
619  } break;
620  case Machines::SM_MODEL_3: {
621  double tranXd = data.transXd * k;
622  double tranXq = data.transXq * k;
623  if(tranXq == 0.0) tranXq = tranXd;
624 
625  data.tranEq = ef0 + (xd - tranXd) * (id0 / sd);
626  data.tranEd = -(xq - tranXq) * (iq0 / sq);
627 
628  data.subEd = 0.0;
629  data.subEq = 0.0;
630  } break;
631  case Machines::SM_MODEL_4: {
632  double tranXd = data.transXd * k;
633  double subXd = data.subXd * k;
634  double subXq = data.subXq * k;
635  if(subXd == 0.0) subXd = subXq;
636  if(subXq == 0.0) subXq = subXd;
637 
638  data.tranEq = ef0 + (xd - tranXd) * (id0 / sd);
639  data.tranEd = 0.0;
640  data.subEq = data.tranEq + (tranXd - subXd) * (id0 / sd);
641  data.subEd = -(xq - subXq) * (iq0 / sq);
642  } break;
643  case Machines::SM_MODEL_5: {
644  double tranXd = data.transXd * k;
645  double tranXq = data.transXq * k;
646  double subXd = data.subXd * k;
647  double subXq = data.subXq * k;
648  if(subXd == 0.0) subXd = subXq;
649  if(subXq == 0.0) subXq = subXd;
650 
651  data.tranEq = ef0 + (xd - tranXd) * (id0 / sd);
652  data.tranEd = -(xq - tranXq) * (iq0 / sq);
653  data.subEq = data.tranEq + (tranXd - subXd) * (id0 / sd);
654  data.subEd = data.tranEd - (tranXq - subXq) * (iq0 / sq);
655  } break;
656  default:
657  break;
658  }
659 
660  // Initialize controllers
661  if(data.useAVR) {
662  if(data.avrSolver) delete data.avrSolver;
663  data.avrSolver =
664  new ControlElementSolver(data.avr, m_timeStep * m_ctrlTimeStepMultiplier, m_tolerance, m_parent);
665  data.avrSolver->SetTerminalVoltage(std::abs(data.terminalVoltage));
666  data.avrSolver->SetInitialTerminalVoltage(std::abs(data.terminalVoltage));
667  data.avrSolver->SetActivePower(dataPU.activePower);
668  data.avrSolver->SetReactivePower(dataPU.reactivePower);
669  data.avrSolver->SetVelocity(data.speed);
670  data.avrSolver->SetInitialVelocity(data.speed);
671  data.avrSolver->InitializeValues(false);
672  if(!data.avrSolver->IsOK()) {
673  m_errorMsg = _("Error on initializate the AVR of \"") + data.name + wxT("\".\n") +
674  data.avrSolver->GetErrorMessage();
675  syncGenerator->SetElectricalData(data);
676  return false;
677  }
678  }
679  if(data.useSpeedGovernor) {
680  if(data.speedGovSolver) delete data.speedGovSolver;
681  data.speedGovSolver = new ControlElementSolver(data.speedGov, m_timeStep * m_ctrlTimeStepMultiplier,
682  m_tolerance, m_parent);
683  data.speedGovSolver->SetActivePower(dataPU.activePower);
684  data.speedGovSolver->SetReactivePower(dataPU.reactivePower);
685  data.speedGovSolver->SetVelocity(data.speed);
686  data.speedGovSolver->SetInitialVelocity(data.speed);
687  data.speedGovSolver->SetInitialMecPower(data.pm);
688  data.speedGovSolver->InitializeValues(false);
689  if(!data.speedGovSolver->IsOK()) {
690  m_errorMsg = _("Error on initializate the speed governor of \"") + data.name + wxT("\".\n") +
691  data.speedGovSolver->GetErrorMessage();
692  syncGenerator->SetElectricalData(data);
693  return false;
694  }
695  }
696  } else {
697  // Initialize open circuit machine.
698  }
699  // Reset plot data
700  data.terminalVoltageVector.clear();
701  data.electricalPowerVector.clear();
702  data.mechanicalPowerVector.clear();
703  data.freqVector.clear();
704  data.fieldVoltageVector.clear();
705  data.deltaVector.clear();
706 
707  syncGenerator->SetElectricalData(data);
708  }
709  CalculateReferenceSpeed();
710  return true;
711 }
712 
713 bool Electromechanical::CalculateInjectedCurrents()
714 {
715  // Reset injected currents vector
716  for(unsigned int i = 0; i < m_iBus.size(); ++i) m_iBus[i] = std::complex<double>(0.0, 0.0);
717 
718  // Synchronous machines
719  for(auto it = m_syncGeneratorList.begin(), itEnd = m_syncGeneratorList.end(); it != itEnd; ++it) {
720  SyncGenerator* syncGenerator = *it;
721  auto data = syncGenerator->GetElectricalData();
722  if(syncGenerator->IsOnline()) {
723  double k = 1.0; // Power base change factor.
724  if(data.useMachineBase) {
725  double oldBase = syncGenerator->GetValueFromUnit(data.nominalPower, data.nominalPowerUnit);
726  k = m_powerSystemBase / oldBase;
727  }
728 
729  double ra = data.armResistance * k;
730  double xp = data.potierReactance * k;
731  if(xp == 0.0) xp = 0.8 * data.transXd * k;
732 
733  int n = static_cast<Bus*>(syncGenerator->GetParentList()[0])->GetElectricalData().number;
734  std::complex<double> e = std::complex<double>(0.0, 0.0);
735  std::complex<double> v = m_vBus[n];
736  std::complex<double> iInj = m_iBus[n];
737 
738  auto smModelData = GetSyncMachineModelData(syncGenerator);
739  DQ0toABC(smModelData.ed, smModelData.eq, data.delta, e);
740  double xd = smModelData.xd;
741  double xq = smModelData.xq;
742 
743  double sd = data.sd;
744  double sq = data.sq;
745  double id, iq;
746 
747  // Calculate the saturation effect
748  if(data.satFactor != 0.0) {
749  if(!CalculateSyncMachineSaturation(syncGenerator, id, iq, sd, sq, false, k)) return false;
750  }
751 
752  double xdq, xds, xqs, xdqs;
753  xdq = 0.5 * (xd + xq);
754  xds = (xd - xp) / sd + xp;
755  xqs = (xq - xp) / sq + xp;
756  xdqs = 0.5 * (xds + xqs);
757 
758  std::complex<double> y0 = std::complex<double>(ra, -xdq) / std::complex<double>(ra * ra + xd * xq, 0.0);
759  std::complex<double> iUnadjusted = y0 * v;
760 
761  // [Ref] Arrillaga, J.; Arnold, C. P.. "Computer Modelling of Electrical Power Systems". Pg. 225-226
762  // [Ref] Dommell, H. W.; Sato, N.. "Fast transient stability solutions". IEEE Transactions on Power
763  // Apparatus and Systems, PAS-91 (4), 1643-1650
764  std::complex<double> iSaliency = std::complex<double>(0.0, -((0.5 * (xqs - xds)) / (ra * ra + xds * xqs))) *
765  (std::conj(e) - std::conj(v));
766  iSaliency = iSaliency * std::cos(2.0 * data.delta) +
767  iSaliency * std::complex<double>(0.0, std::sin(2.0 * data.delta));
768 
769  // [Ref] Arrillaga, J.; Arnold, C. P.; Computer Modelling of Electrical Power Systems. Pg. 258-259
770  std::complex<double> y0s = std::complex<double>(ra, -xdqs) / std::complex<double>(ra * ra + xds * xqs, 0.0);
771  std::complex<double> iSaturation = y0s * (e - v);
772 
773  iInj = iUnadjusted + iSaliency + iSaturation;
774 
775  m_iBus[n] += iInj;
776 
777  // Remove the current flowing through y0 (i.e. iUnadjusted in this case, y0 is inserted in admittance
778  // matrix) to calculate the electrical power.
779  std::complex<double> iMachine = iInj - iUnadjusted;
780  data.electricalPower = v * std::conj(iMachine);
781 
782  ABCtoDQ0(iMachine, data.delta, id, iq);
783 
784  data.id = id;
785  data.iq = iq;
786  data.sd = sd;
787  data.sq = sq;
788  } else {
789  data.electricalPower = std::complex<double>(0.0, 0.0);
790  }
791 
792  syncGenerator->SetElectricalData(data);
793  }
794 
795  // Loads
796  for(auto it = m_loadList.begin(), itEnd = m_loadList.end(); it != itEnd; ++it) {
797  Load* load = *it;
798  auto data = load->GetElectricalData();
799 
800  if(load->IsOnline()) {
801  int n = static_cast<Bus*>(load->GetParentList()[0])->GetElectricalData().number;
802  data.voltage = m_vBus[n];
803  double vAbs = std::abs(data.voltage);
804 
805  double pz, pi, pp, qz, qi, qp;
806  pz = data.pz0 * std::pow(vAbs / data.v0, 2);
807  pi = data.pi0 * (vAbs / data.v0);
808  pp = data.pp0;
809  qz = data.qz0 * std::pow(vAbs / data.v0, 2);
810  qi = data.qi0 * (vAbs / data.v0);
811  qp = data.qp0;
812 
813  // If voltage value is low, set the ZIP load to constant impedance.
814  if(vAbs < data.constCurrentUV) {
815  pi = data.pi0 * (data.constCurrentUV / data.v0) * std::pow(vAbs / data.constCurrentUV, 2);
816  qi = data.qi0 * (data.constCurrentUV / data.v0) * std::pow(vAbs / data.constCurrentUV, 2);
817  }
818  if(vAbs < data.constPowerUV) {
819  pp *= std::pow(vAbs / data.constPowerUV, 2);
820  qp *= std::pow(vAbs / data.constPowerUV, 2);
821  }
822 
823  double activePower = pz + pi + pp;
824  double reactivePower = qz + qi + qp;
825 
826  std::complex<double> newY = std::complex<double>(activePower, -reactivePower) / (vAbs * vAbs);
827  m_iBus[n] += (data.y0 - newY) * data.voltage;
828 
829  data.electricalPower = std::complex<double>(activePower, reactivePower);
830  } else {
831  data.voltage = std::complex<double>(0.0, 0.0);
832  data.electricalPower = std::complex<double>(0.0, 0.0);
833  }
834 
835  load->SetElectricalData(data);
836  }
837  return true;
838 }
839 
840 void Electromechanical::CalculateIntegrationConstants(SyncGenerator* syncGenerator, double id, double iq, double k)
841 {
842  CalculateReferenceSpeed();
843  auto data = syncGenerator->GetElectricalData();
844 
845  double syncXd, syncXq, transXd, transXq, subXd, subXq;
846  syncXd = data.syncXd * k;
847  syncXq = data.syncXq * k;
848  transXd = data.transXd * k;
849  transXq = data.transXq * k;
850  subXd = data.subXd * k;
851  subXq = data.subXq * k;
852 
853  if(syncXq == 0.0) syncXq = syncXd;
854  if(transXq == 0.0) transXq = transXd;
855  if(subXd == 0.0) subXd = subXq;
856  if(subXq == 0.0) subXq = subXd;
857 
858  double transTd0, transTq0, subTd0, subTq0;
859  transTd0 = data.transTd0;
860  transTq0 = data.transTq0;
861  subTd0 = data.subTd0;
862  subTq0 = data.subTq0;
863 
864  if(subTd0 == 0.0) subTd0 = subTq0;
865  if(subTq0 == 0.0) subTq0 = subTd0;
866 
867  // Speed
868  data.icSpeed.m = m_timeStep / ((4.0f * data.inertia / m_refSpeed) / k + m_timeStep * data.damping * k);
869  data.icSpeed.c = (1.0f - 2.0f * data.icSpeed.m * data.damping * k) * data.speed +
870  data.icSpeed.m * (data.pm - data.pe + 2.0f * m_refSpeed * data.damping * k);
871 
872  // Delta
873  data.icDelta.m = 0.5f * m_timeStep;
874  data.icDelta.c = data.delta + data.icDelta.m * (data.speed - 2.0f * m_refSpeed);
875 
876  // Eq'
877  if(data.model == Machines::SM_MODEL_2 || data.model == Machines::SM_MODEL_3 || data.model == Machines::SM_MODEL_4 ||
878  data.model == Machines::SM_MODEL_5) {
879  data.icTranEq.m = m_timeStep / (2.0f * transTd0 + m_timeStep);
880  data.icTranEq.c = (1.0 - data.icTranEq.m * (1.0 + data.sd)) * data.tranEq +
881  data.icTranEq.m * (data.fieldVoltage + (syncXd - transXd) * id);
882  }
883 
884  // Ed'
885  if(data.model == Machines::SM_MODEL_3 || data.model == Machines::SM_MODEL_4 || data.model == Machines::SM_MODEL_5) {
886  data.icTranEd.m = m_timeStep / (2.0f * transTq0 + m_timeStep);
887  data.icTranEd.c =
888  (1.0 - data.icTranEd.m * (1.0 + data.sq)) * data.tranEd - data.icTranEd.m * (syncXq - transXq) * iq;
889  }
890 
891  // Eq''
892  if(data.model == Machines::SM_MODEL_4 || data.model == Machines::SM_MODEL_5) {
893  data.icSubEq.m = m_timeStep / (2.0f * subTd0 + m_timeStep);
894  data.icSubEq.c = (1.0 - data.icSubEq.m * (1.0 + data.sd)) * data.subEq +
895  data.icSubEq.m * (data.sd * data.tranEq + (transXd - subXd) * id);
896  }
897  // Ed''
898  if(data.model == Machines::SM_MODEL_4) {
899  data.icSubEd.m = m_timeStep / (2.0f * subTq0 + m_timeStep);
900  data.icSubEd.c =
901  (1.0f - data.icSubEd.m * (1.0 + data.sq)) * data.subEd - data.icSubEd.m * (syncXq - subXq) * iq;
902  }
903  if(data.model == Machines::SM_MODEL_5) {
904  data.icSubEd.m = m_timeStep / (2.0f * subTq0 + m_timeStep);
905  data.icSubEd.c = (1.0f - data.icSubEd.m * (1.0 + data.sq)) * data.subEd +
906  data.icSubEd.m * (data.sq * data.tranEd - (transXq - subXq) * iq);
907  }
908 
909  syncGenerator->SetElectricalData(data);
910 }
911 
912 bool Electromechanical::SolveSynchronousMachines()
913 {
914  for(auto it = m_syncGeneratorList.begin(), itEnd = m_syncGeneratorList.end(); it != itEnd; ++it) {
915  SyncGenerator* syncGenerator = *it;
916  auto data = syncGenerator->GetElectricalData();
917 
918  if(syncGenerator->IsOnline()) {
919  double id, iq, pe, sd, sq;
920  pe = data.pe;
921  id = data.id;
922  iq = data.iq;
923  sd = data.sd;
924  sq = data.sq;
925 
926  double k = 1.0; // Power base change factor.
927  if(data.useMachineBase) {
928  double oldBase = syncGenerator->GetValueFromUnit(data.nominalPower, data.nominalPowerUnit);
929  k = m_powerSystemBase / oldBase;
930  }
931 
932  // Calculate integration constants.
933  CalculateIntegrationConstants(syncGenerator, id, iq, k);
934 
935  if(!CalculateSyncMachineNonIntVariables(syncGenerator, id, iq, sd, sq, pe, k)) return false;
936  // Extrapolate nonintegrable variables.
937  id = 2.0 * id - data.oldId;
938  iq = 2.0 * iq - data.oldIq;
939  pe = 2.0 * pe - data.oldPe;
940  sd = 2.0 * sd - data.oldSd;
941  sq = 2.0 * sq - data.oldSq;
942 
943  CalculateSyncMachineIntVariables(syncGenerator, id, iq, sd, sq, pe, k);
944  } else {
945  CalculateIntegrationConstants(syncGenerator, 0.0f, 0.0f);
946  }
947  }
948 
949  double error = 1.0;
950  int iterations = 0;
951  while(error > m_tolerance) {
952  error = 0.0;
953 
954  // Calculate the injected currents.
955  if(!CalculateInjectedCurrents()) return false;
956 
957  // Calculate the buses voltages.
958  m_vBus = LUEvaluate(m_yBusU, m_yBusL, m_iBus);
959 
960  // Solve machine equations.
961  for(auto it = m_syncGeneratorList.begin(), itEnd = m_syncGeneratorList.end(); it != itEnd; ++it) {
962  SyncGenerator* syncGenerator = *it;
963 
964  auto data = syncGenerator->GetElectricalData();
965 
966  double id = data.id;
967  double iq = data.iq;
968  double pe = data.pe;
969  double sd = data.sd;
970  double sq = data.sq;
971 
972  // Power base change factor.
973  double k = 1.0;
974  if(data.useMachineBase) {
975  double oldBase = syncGenerator->GetValueFromUnit(data.nominalPower, data.nominalPowerUnit);
976  k = m_powerSystemBase / oldBase;
977  }
978 
979  // Calculate id, iq, dq, sd
980  if(!CalculateSyncMachineNonIntVariables(syncGenerator, id, iq, sd, sq, pe, k)) return false;
981 
982  double genError = CalculateSyncMachineIntVariables(syncGenerator, id, iq, sd, sq, pe, k);
983 
984  if(genError > error) error = genError;
985  }
986 
987  ++iterations;
988 
989  if(iterations > m_maxIterations) {
990  m_errorMsg = _("Impossible to solve the synchronous generators.\nCheck the system parameters and/or "
991  "decrease the time step.");
992  return false;
993  }
994  }
995 
996  // Solve controllers.
997  int ctrlRatio = static_cast<int>(1 / m_ctrlTimeStepMultiplier);
998  for(auto it = m_syncGeneratorList.begin(), itEnd = m_syncGeneratorList.end(); it != itEnd; ++it) {
999  SyncGenerator* syncGenerator = *it;
1000  auto data = syncGenerator->GetElectricalData();
1001  if(data.useAVR && data.avrSolver) {
1002  data.avrSolver->SetTerminalVoltage(std::abs(data.terminalVoltage));
1003  data.avrSolver->SetDeltaActivePower(data.electricalPower.real() - data.avrSolver->GetActivePower());
1004  data.avrSolver->SetActivePower(data.electricalPower.real());
1005  data.avrSolver->SetReactivePower(data.electricalPower.imag());
1006  data.avrSolver->SetDeltaVelocity(data.speed - data.avrSolver->GetVelocity());
1007  data.avrSolver->SetVelocity(data.speed);
1008 
1009  for(int i = 0; i < ctrlRatio; ++i) data.avrSolver->SolveNextStep();
1010 
1011  data.fieldVoltage = data.initialFieldVoltage + data.avrSolver->GetFieldVoltage();
1012  }
1013 
1014  if(data.useSpeedGovernor && data.speedGovSolver) {
1015  data.speedGovSolver->SetVelocity(data.speed);
1016  data.speedGovSolver->SetActivePower(data.electricalPower.real());
1017  data.speedGovSolver->SetReactivePower(data.electricalPower.imag());
1018 
1019  for(int i = 0; i < ctrlRatio; ++i) data.speedGovSolver->SolveNextStep();
1020 
1021  data.pm = data.speedGovSolver->GetMechanicalPower();
1022  }
1023  syncGenerator->SetElectricalData(data);
1024  }
1025 
1026  return true;
1027 }
1028 
1029 void Electromechanical::SaveData()
1030 {
1031  for(auto it = m_syncGeneratorList.begin(), itEnd = m_syncGeneratorList.end(); it != itEnd; ++it) {
1032  SyncGenerator* syncGenerator = *it;
1033  auto data = syncGenerator->GetElectricalData();
1034  if(data.plotSyncMachine) {
1035  data.terminalVoltageVector.push_back(data.terminalVoltage);
1036  data.electricalPowerVector.push_back(data.electricalPower);
1037  data.mechanicalPowerVector.push_back(data.pm);
1038  data.freqVector.push_back(data.speed / (2.0f * M_PI));
1039  data.fieldVoltageVector.push_back(data.fieldVoltage);
1040  data.deltaVector.push_back(wxRadToDeg(data.delta));
1041  syncGenerator->SetElectricalData(data);
1042  }
1043  }
1044  for(auto it = m_busList.begin(), itEnd = m_busList.end(); it != itEnd; ++it) {
1045  Bus* bus = *it;
1046  auto data = bus->GetElectricalData();
1047  if(data.plotBus) {
1048  data.stabVoltageVector.push_back(m_vBus[data.number]);
1049  bus->SetElectricalData(data);
1050  }
1051  }
1052  for(auto it = m_loadList.begin(), itEnd = m_loadList.end(); it != itEnd; ++it) {
1053  Load* load = *it;
1054  auto data = load->GetElectricalData();
1055  if(data.plotLoad) {
1056  data.voltageVector.push_back(data.voltage);
1057  data.electricalPowerVector.push_back(data.electricalPower);
1058  load->SetElectricalData(data);
1059  }
1060  }
1061 }
1062 
1063 void Electromechanical::SetSyncMachinesModel()
1064 {
1065  for(auto it = m_syncGeneratorList.begin(), itEnd = m_syncGeneratorList.end(); it != itEnd; ++it) {
1066  SyncGenerator* syncGenerator = *it;
1067  auto data = syncGenerator->GetElectricalData();
1068  data.model = GetMachineModel(syncGenerator);
1069  syncGenerator->SetElectricalData(data);
1070  }
1071 }
1072 
1073 bool Electromechanical::CalculateSyncMachineNonIntVariables(SyncGenerator* syncGenerator,
1074  double& id,
1075  double& iq,
1076  double& sd,
1077  double& sq,
1078  double& pe,
1079  double k)
1080 {
1081  auto data = syncGenerator->GetElectricalData();
1082  int n = static_cast<Bus*>(syncGenerator->GetParentList()[0])->GetElectricalData().number;
1083 
1084  if(syncGenerator->IsOnline()) {
1085  data.terminalVoltage = m_vBus[n];
1086  }
1087 
1088  double vd, vq;
1089  ABCtoDQ0(data.terminalVoltage, data.delta, vd, vq);
1090 
1091  if(data.satFactor != 0.0) {
1092  if(!CalculateSyncMachineSaturation(syncGenerator, id, iq, sd, sq, true, k)) return false;
1093  data.sd = sd;
1094  data.sq = sq;
1095  data.oldSd = sd;
1096  data.oldSq = sq;
1097  }
1098 
1099  if(syncGenerator->IsOnline()) {
1100  pe = id * vd + iq * vq + (id * id + iq * iq) * data.armResistance * k;
1101  } else {
1102  pe = id = iq = 0.0f;
1103  }
1104  data.pe = pe;
1105  data.id = id;
1106  data.iq = iq;
1107  data.oldPe = pe;
1108  data.oldId = id;
1109  data.oldIq = iq;
1110  syncGenerator->SetElectricalData(data);
1111 
1112  return true;
1113 }
1114 
1115 double Electromechanical::CalculateSyncMachineIntVariables(SyncGenerator* syncGenerator,
1116  double id,
1117  double iq,
1118  double sd,
1119  double sq,
1120  double pe,
1121  double k)
1122 {
1123  double error = 0.0;
1124  auto data = syncGenerator->GetElectricalData();
1125 
1126  // Mechanical differential equations.
1127  double w = data.icSpeed.c + data.icSpeed.m * (data.pm - pe);
1128  error = std::max(error, std::abs(data.speed - w) / m_refSpeed);
1129 
1130  double delta = data.icDelta.c + data.icDelta.m * w;
1131  error = std::max(error, std::abs(data.delta - delta));
1132 
1133  data.speed = w;
1134  data.delta = delta;
1135 
1136  // Electrical differential equations
1137  switch(data.model) {
1138  case Machines::SM_MODEL_1: {
1139  // There is no differential equations.
1140  } break;
1141  case Machines::SM_MODEL_2: {
1142  double syncXd, transXd;
1143  syncXd = data.syncXd * k;
1144  transXd = data.transXd * k;
1145 
1146  double tranEq = (data.icTranEq.c + data.icTranEq.m * (data.fieldVoltage + (syncXd - transXd) * id)) /
1147  (1.0 + data.icTranEq.m * (sd - 1.0));
1148  error = std::max(error, std::abs(data.tranEq - tranEq));
1149 
1150  data.tranEq = tranEq;
1151  } break;
1152  case Machines::SM_MODEL_3: {
1153  double syncXd, syncXq, transXd, transXq;
1154  syncXd = data.syncXd * k;
1155  syncXq = data.syncXq * k;
1156  transXd = data.transXd * k;
1157  transXq = data.transXq * k;
1158  if(syncXq == 0.0) syncXq = syncXd;
1159  if(transXq == 0.0) transXq = transXd;
1160 
1161  double tranEq = (data.icTranEq.c + data.icTranEq.m * (data.fieldVoltage + (syncXd - transXd) * id)) /
1162  (1.0 + data.icTranEq.m * (sd - 1.0));
1163  error = std::max(error, std::abs(data.tranEq - tranEq));
1164 
1165  double tranEd =
1166  (data.icTranEd.c - data.icTranEd.m * (syncXq - transXq) * iq) / (1.0 + data.icTranEd.m * (sq - 1.0));
1167  error = std::max(error, std::abs(data.tranEd - tranEd));
1168 
1169  data.tranEq = tranEq;
1170  data.tranEd = tranEd;
1171 
1172  if(!syncGenerator->IsOnline()) {
1173  std::complex<double> e;
1174  DQ0toABC(data.tranEd, data.tranEq, data.delta, e);
1175  data.terminalVoltage = e;
1176  }
1177  } break;
1178  case Machines::SM_MODEL_4: {
1179  double syncXd, syncXq, transXd, subXd, subXq;
1180  syncXd = data.syncXd * k;
1181  syncXq = data.syncXq * k;
1182  transXd = data.transXd * k;
1183  subXd = data.subXd * k;
1184  subXq = data.subXq * k;
1185  if(syncXq == 0.0) syncXq = syncXd;
1186  if(subXd == 0.0) subXd = subXq;
1187  if(subXq == 0.0) subXq = subXd;
1188 
1189  double tranEq = (data.icTranEq.c + data.icTranEq.m * (data.fieldVoltage + (syncXd - transXd) * id)) /
1190  (1.0 + data.icTranEq.m * (sd - 1.0));
1191  error = std::max(error, std::abs(data.tranEq - tranEq));
1192 
1193  double subEq = (data.icSubEq.c + data.icSubEq.m * (sd * tranEq + (transXd - subXd) * id)) /
1194  (1.0 + data.icSubEq.m * (sd - 1.0));
1195  error = std::max(error, std::abs(data.subEq - subEq));
1196 
1197  double subEd =
1198  (data.icSubEd.c - data.icSubEd.m * ((syncXq - subXq) * iq)) / (1.0 + data.icSubEd.m * (sq - 1.0));
1199  error = std::max(error, std::abs(data.subEd - subEd));
1200 
1201  data.tranEq = tranEq;
1202  data.subEq = subEq;
1203  data.subEd = subEd;
1204  } break;
1205  case Machines::SM_MODEL_5: {
1206  double syncXd, syncXq, transXd, transXq, subXd, subXq;
1207  syncXd = data.syncXd * k;
1208  syncXq = data.syncXq * k;
1209  transXd = data.transXd * k;
1210  transXq = data.transXq * k;
1211  subXd = data.subXd * k;
1212  subXq = data.subXq * k;
1213  if(syncXq == 0.0) syncXq = syncXd;
1214  if(transXq == 0.0) transXq = transXd;
1215  if(subXd == 0.0) subXd = subXq;
1216  if(subXq == 0.0) subXq = subXd;
1217 
1218  double tranEq = (data.icTranEq.c + data.icTranEq.m * (data.fieldVoltage + (syncXd - transXd) * id)) /
1219  (1.0 + data.icTranEq.m * (sd - 1.0));
1220  error = std::max(error, std::abs(data.tranEq - tranEq));
1221 
1222  double tranEd =
1223  (data.icTranEd.c - data.icTranEd.m * (syncXq - transXq) * iq) / (1.0 + data.icTranEd.m * (sq - 1.0));
1224  error = std::max(error, std::abs(data.tranEd - tranEd));
1225 
1226  double subEq = (data.icSubEq.c + data.icSubEq.m * (sd * tranEq + (transXd - subXd) * id)) /
1227  (1.0 + data.icSubEq.m * (sd - 1.0));
1228  error = std::max(error, std::abs(data.subEq - subEq));
1229 
1230  double subEd = (data.icSubEd.c + data.icSubEd.m * (sq * tranEd - (transXq - subXq) * iq)) /
1231  (1.0 + data.icSubEd.m * (sq - 1.0));
1232  error = std::max(error, std::abs(data.subEd - subEd));
1233 
1234  data.tranEq = tranEq;
1235  data.tranEd = tranEd;
1236  data.subEq = subEq;
1237  data.subEd = subEd;
1238  } break;
1239  }
1240 
1241  syncGenerator->SetElectricalData(data);
1242  return error;
1243 }
1244 
1245 void Electromechanical::CalculateReferenceSpeed()
1246 {
1247  if(m_useCOI) {
1248  double sumHW = 0.0;
1249  double sumH = 0.0;
1250  for(auto it = m_syncGeneratorList.begin(), itEnd = m_syncGeneratorList.end(); it != itEnd; ++it) {
1251  SyncGenerator* syncGenerator = *it;
1252  if(syncGenerator->IsOnline()) {
1253  auto data = syncGenerator->GetElectricalData();
1254  double k = 1.0; // Power base change factor.
1255  if(data.useMachineBase) {
1256  double oldBase = syncGenerator->GetValueFromUnit(data.nominalPower, data.nominalPowerUnit);
1257  k = m_powerSystemBase / oldBase;
1258  }
1259  sumH += data.inertia / k;
1260  sumHW += data.inertia * data.speed / k;
1261  }
1262  }
1263  m_refSpeed = sumHW / sumH;
1264  } else {
1265  m_refSpeed = 2.0 * M_PI * m_systemFreq;
1266  }
1267 }
1268 
1269 bool Electromechanical::CalculateSyncMachineSaturation(SyncGenerator* syncMachine,
1270  double& id,
1271  double& iq,
1272  double& sd,
1273  double& sq,
1274  bool updateCurrents,
1275  double k)
1276 {
1277  // [Ref] Arrillaga, J.; Arnold, C. P.. "Computer Modelling of Electrical Power Systems". Pg. 254-260
1278  auto data = syncMachine->GetElectricalData();
1279  auto smDataModel = GetSyncMachineModelData(syncMachine);
1280 
1281  int n = static_cast<Bus*>(syncMachine->GetParentList()[0])->GetElectricalData().number;
1282  if(syncMachine->IsOnline()) {
1283  data.terminalVoltage = m_vBus[n];
1284  }
1285  double idCalc = id;
1286  double iqCalc = iq;
1287  double sdCalc = sd;
1288  double sqCalc = sq;
1289 
1290  double vd, vq;
1291  ABCtoDQ0(data.terminalVoltage, data.delta, vd, vq);
1292  double deltaVd = smDataModel.ed - vd;
1293  double deltaVq = smDataModel.eq - vq;
1294 
1295  double ra = data.armResistance * k;
1296  double xd = smDataModel.xd;
1297  double xq = smDataModel.xq;
1298 
1299  double syncXd = data.syncXd * k;
1300  double syncXq = data.syncXq * k;
1301  if(data.model == Machines::SM_MODEL_1) {
1302  syncXq = data.transXd * k;
1303  syncXd = syncXq;
1304  } else if(data.syncXq == 0.0)
1305  syncXq = data.syncXd * k;
1306 
1307  double xp = data.potierReactance * k;
1308  if(xp == 0.0) xp = 0.8 * data.transXd * k;
1309  double satFacd = (data.satFactor - 1.2) / std::pow(1.2, 7);
1310  double satFacq = satFacd * (syncXq / syncXd);
1311 
1312  bool exit = false;
1313  int iterations = 0;
1314  while(!exit) {
1315  double oldSd = sdCalc;
1316  double oldSq = sqCalc;
1317 
1318  // Saturated reactances.
1319  double xds = (xd - xp) / sdCalc + xp;
1320  double xqs = (xq - xp) / sqCalc + xp;
1321  // dq currents.
1322  double den = 1.0 / (ra * ra + xds * xqs);
1323  iqCalc = den * (ra * deltaVq + xds * deltaVd);
1324  idCalc = den * (-xqs * deltaVq + ra * deltaVd);
1325  // Potier voltages
1326  double epq = vq + ra * iqCalc - xp * idCalc;
1327  double epd = vd + ra * idCalc + xp * iqCalc;
1328  // Saturation factors.
1329  // Gauss
1330  /*sdCalc = 1.0 + satFacd * std::pow(epq, 6);
1331  sqCalc = 1.0 + satFacq * std::pow(epd, 6);*/
1332 
1333  // Newton-raphson
1334  double f1 = 1.0 - sdCalc + satFacd * std::pow(epq, 6);
1335  double f2 = 1.0 - sqCalc + satFacq * std::pow(epd, 6);
1336  double dF1dSd =
1337  (6.0 * satFacd * std::pow(epq, 5) * xp * (xd - xp) * deltaVq) / ((sdCalc - 1.0) * xp + xd) - 1.0;
1338  double dF2dSq =
1339  (6.0 * satFacq * std::pow(epd, 5) * xp * (xq - xp) * deltaVd) / ((sqCalc - 1.0) * xp + xq) - 1.0;
1340 
1341  sdCalc = sdCalc - f1 / dF1dSd;
1342  sqCalc = sqCalc - f2 / dF2dSq;
1343 
1344  double error = std::abs(sdCalc - oldSd) + std::abs(sqCalc - oldSq);
1345  if(error < m_saturationTolerance) exit = true;
1346 
1347  iterations++;
1348  if((iterations >= m_maxIterations) & !exit) {
1349  m_errorMsg =
1350  _("It was not possible to solve the saturation of the synchronous machine \"") + data.name + wxT("\".");
1351  return false;
1352  }
1353  }
1354 
1355  sd = sdCalc;
1356  sq = sqCalc;
1357  if(updateCurrents) {
1358  id = idCalc;
1359  iq = iqCalc;
1360  }
1361  return true;
1362 }
1363 
1364 SyncMachineModelData Electromechanical::GetSyncMachineModelData(SyncGenerator* syncMachine)
1365 {
1366  SyncMachineModelData smModelData;
1367 
1368  auto data = syncMachine->GetElectricalData();
1369  double k = 1.0; // Power base change factor.
1370  if(data.useMachineBase) {
1371  double oldBase = syncMachine->GetValueFromUnit(data.nominalPower, data.nominalPowerUnit);
1372  k = m_powerSystemBase / oldBase;
1373  }
1374 
1375  switch(data.model) {
1376  case Machines::SM_MODEL_1: {
1377  smModelData.ed = data.tranEd;
1378  smModelData.eq = data.tranEq;
1379  smModelData.xq = data.transXd * k;
1380  smModelData.xd = smModelData.xq;
1381  } break;
1382  case Machines::SM_MODEL_2: {
1383  smModelData.ed = data.tranEd;
1384  smModelData.eq = data.tranEq;
1385  smModelData.xd = data.transXd * k;
1386  smModelData.xq = data.transXq * k;
1387  if(smModelData.xq == 0.0) {
1388  smModelData.xq = data.syncXq * k;
1389  if(smModelData.xq == 0.0) {
1390  smModelData.xq = data.syncXd * k;
1391  }
1392  }
1393  } break;
1394  case Machines::SM_MODEL_3: {
1395  smModelData.ed = data.tranEd;
1396  smModelData.eq = data.tranEq;
1397  smModelData.xd = data.transXd * k;
1398  smModelData.xq = data.transXq * k;
1399  if(smModelData.xq == 0.0) smModelData.xq = smModelData.xd;
1400  } break;
1401  case Machines::SM_MODEL_4:
1402  case Machines::SM_MODEL_5: {
1403  smModelData.ed = data.subEd;
1404  smModelData.eq = data.subEq;
1405  smModelData.xd = data.subXd * k;
1406  smModelData.xq = data.subXq * k;
1407  if(smModelData.xd == 0.0) smModelData.xd = smModelData.xq;
1408  if(smModelData.xq == 0.0) smModelData.xq = smModelData.xd;
1409  } break;
1410  }
1411  return smModelData;
1412 }
std::vector< double > swTime
Definition: PowerElement.h:95
Solves in the time the control system. Can solve the control system directly from a ControlEditor or ...
virtual std::vector< Element * > GetParentList() const
Get the parent list.
Definition: Element.h:506
@@ -105,7 +105,7 @@ $(document).ready(function(){initNavTree('_electromechanical_8cpp_source.html','
Synchronous machine data for different models.
Power line element.
Definition: Line.h:59
-
Loas shunt power element.
Definition: Load.h:42
+
Loas shunt power element.
Definition: Load.h:73
virtual bool GetYBus(std::vector< std::vector< std::complex< double > > > &yBus, double systemPowerBase, YBusSequence sequence=POSITIVE_SEQ, bool includeSyncMachines=false, bool allLoadsAsImpedances=false)
Get the admittance matrix from the list of elements (use GetElementsFromList first).
virtual SwitchingData GetSwitchingData()
Returns the switching data of the element.
Definition: PowerElement.h:182
diff --git a/docs/doxygen/html/_electromechanical_8h_source.html b/docs/doxygen/html/_electromechanical_8h_source.html index 02710ac..2d741d0 100644 --- a/docs/doxygen/html/_electromechanical_8h_source.html +++ b/docs/doxygen/html/_electromechanical_8h_source.html @@ -88,7 +88,7 @@ $(document).ready(function(){initNavTree('_electromechanical_8h_source.html','')
Electromechanical.h
-Go to the documentation of this file.
1 /*
2  * Copyright (C) 2017 Thales Lima Oliveira <thales@ufu.br>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program. If not, see <https://www.gnu.org/licenses/>.
16  */
17 
18 #ifndef ELECTROMECHANICAL_H
19 #define ELECTROMECHANICAL_H
20 
21 #include "ElectricCalculation.h"
22 
23 #include <wx/progdlg.h>
24 #include <wx/log.h>
25 
27 
35  double xd;
37  double xq;
39  double ed;
41  double eq;
42 };
43 
52 {
53  public:
54  Electromechanical(wxWindow* parent, std::vector<Element*> elementList, SimulationData data);
56 
57  bool RunStabilityCalculation();
58  wxString GetErrorMessage() const { return m_errorMsg; }
59  std::vector<double> GetTimeVector() const { return m_timeVector; }
60  std::vector<double> m_wErrorVector;
61  std::vector<double> m_deltaErrorVector;
62  std::vector<double> m_transEdErrorVector;
63  std::vector<double> m_transEqErrorVector;
64  std::vector<double> m_numItVector;
65  std::vector<double> m_sdCVector;
66  std::vector<double> m_sqCVector;
67 
68  protected:
69  void SetEventTimeList();
70  bool HasEvent(double currentTime);
71  void SetEvent(double currentTime);
72  inline bool EventTrigger(double eventTime, double currentTime);
73 
74  // double GetPowerValue(double value, ElectricalUnit unit);
75 
76  void InsertSyncMachinesOnYBus();
77  std::complex<double> GetSyncMachineAdmittance(SyncGenerator* generator);
78  bool InitializeDynamicElements();
79  bool CalculateMachinesCurrents();
80  void CalculateIntegrationConstants(SyncGenerator* syncGenerator, double id, double iq, double k = 1.0);
81  bool SolveSynchronousMachines();
82  void SetSyncMachinesModel();
83  SyncMachineModelData GetSyncMachineModelData(SyncGenerator* syncMachine);
84  double CalculateSyncMachineIntVariables(SyncGenerator* syncGenerator,
85  double id,
86  double iq,
87  double sd,
88  double sq,
89  double pe,
90  double k = 1.0);
91  bool CalculateSyncMachineNonIntVariables(SyncGenerator* syncGenerator,
92  double& id,
93  double& iq,
94  double& sd,
95  double& sq,
96  double& pe,
97  double k = 1.0);
98  void CalculateReferenceSpeed();
99  bool CalculateSyncMachineSaturation(SyncGenerator* syncMachine,
100  double& id,
101  double& iq,
102  double& sd,
103  double& sq,
104  bool updateCurrents = true,
105  double k = 1.0);
106 
107  void SaveData();
108 
109  wxWindow* m_parent = NULL;
110  wxString m_errorMsg = _("Unknown error");
111 
112  double m_systemFreq = 60.0;
113  double m_refSpeed = 2.0 * M_PI * 60.0;
114  bool m_useCOI = false;
115 
116  std::vector<std::vector<std::complex<double> > > m_yBus;
117  std::vector<std::vector<std::complex<double> > > m_yBusU;
118  std::vector<std::vector<std::complex<double> > > m_yBusL;
119 
120  std::vector<std::complex<double> > m_vBus;
121  std::vector<std::complex<double> > m_iBus;
122 
123  double m_powerSystemBase = 100e6;
124  double m_simTime = 10.0;
125  double m_plotTime = 1e-2;
126  double m_timeStep = 1e-2;
127  double m_ctrlTimeStepMultiplier = 0.1;
128  double m_tolerance = 1e-8;
129  int m_maxIterations = 100;
130  double m_saturationTolerance = 1e-8;
131 
132  std::vector<double> m_eventTimeList;
133  std::vector<bool> m_eventOccurrenceList;
134 
135  std::vector<double> m_timeVector;
136 
137  // tests
138  double m_wError = 0.0;
139  double m_sdC = 1.0;
140  double m_sqC = 1.0;
141  double m_numIt = 0;
142 };
143 
144 #endif // ELECTROMECHANICAL_H
Solves in the time the control system. Can solve the control system directly from a ControlEditor or ...
+Go to the documentation of this file.
1 /*
2  * Copyright (C) 2017 Thales Lima Oliveira <thales@ufu.br>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program. If not, see <https://www.gnu.org/licenses/>.
16  */
17 
18 #ifndef ELECTROMECHANICAL_H
19 #define ELECTROMECHANICAL_H
20 
21 #include "ElectricCalculation.h"
22 
23 #include <wx/progdlg.h>
24 #include <wx/log.h>
25 
27 
35  double xd;
37  double xq;
39  double ed;
41  double eq;
42 };
43 
52 {
53  public:
54  Electromechanical(wxWindow* parent, std::vector<Element*> elementList, SimulationData data);
56 
57  bool RunStabilityCalculation();
58  wxString GetErrorMessage() const { return m_errorMsg; }
59  std::vector<double> GetTimeVector() const { return m_timeVector; }
60 
61  protected:
62  void SetEventTimeList();
63  bool HasEvent(double currentTime);
64  void SetEvent(double currentTime);
65  inline bool EventTrigger(double eventTime, double currentTime);
66 
67  // double GetPowerValue(double value, ElectricalUnit unit);
68 
69  void InsertSyncMachinesOnYBus();
70  std::complex<double> GetSyncMachineAdmittance(SyncGenerator* generator);
71  bool InitializeDynamicElements();
72  bool CalculateInjectedCurrents();
73  void CalculateIntegrationConstants(SyncGenerator* syncGenerator, double id, double iq, double k = 1.0);
74  bool SolveSynchronousMachines();
75  void SetSyncMachinesModel();
76  SyncMachineModelData GetSyncMachineModelData(SyncGenerator* syncMachine);
77  double CalculateSyncMachineIntVariables(SyncGenerator* syncGenerator,
78  double id,
79  double iq,
80  double sd,
81  double sq,
82  double pe,
83  double k = 1.0);
84  bool CalculateSyncMachineNonIntVariables(SyncGenerator* syncGenerator,
85  double& id,
86  double& iq,
87  double& sd,
88  double& sq,
89  double& pe,
90  double k = 1.0);
91  void CalculateReferenceSpeed();
92  bool CalculateSyncMachineSaturation(SyncGenerator* syncMachine,
93  double& id,
94  double& iq,
95  double& sd,
96  double& sq,
97  bool updateCurrents = true,
98  double k = 1.0);
99 
100  void SaveData();
101 
102  wxWindow* m_parent = NULL;
103  wxString m_errorMsg = _("Unknown error");
104 
105  double m_systemFreq = 60.0;
106  double m_refSpeed = 2.0 * M_PI * 60.0;
107  bool m_useCOI = false;
108 
109  std::vector<std::vector<std::complex<double> > > m_yBus;
110  std::vector<std::vector<std::complex<double> > > m_yBusU;
111  std::vector<std::vector<std::complex<double> > > m_yBusL;
112 
113  std::vector<std::complex<double> > m_vBus;
114  std::vector<std::complex<double> > m_iBus;
115 
116  double m_powerSystemBase = 100e6;
117  double m_simTime = 10.0;
118  double m_plotTime = 1e-2;
119  double m_timeStep = 1e-2;
120  double m_ctrlTimeStepMultiplier = 0.1;
121  double m_tolerance = 1e-8;
122  int m_maxIterations = 100;
123  double m_saturationTolerance = 1e-8;
124 
125  std::vector<double> m_eventTimeList;
126  std::vector<bool> m_eventOccurrenceList;
127 
128  std::vector<double> m_timeVector;
129 };
130 
131 #endif // ELECTROMECHANICAL_H
Solves in the time the control system. Can solve the control system directly from a ControlEditor or ...
diff --git a/docs/doxygen/html/_element_8cpp_source.html b/docs/doxygen/html/_element_8cpp_source.html index 3ea17ab..f39b69d 100644 --- a/docs/doxygen/html/_element_8cpp_source.html +++ b/docs/doxygen/html/_element_8cpp_source.html @@ -88,7 +88,7 @@ $(document).ready(function(){initNavTree('_element_8cpp_source.html','');});
Element.cpp
-
1 /*
2  * Copyright (C) 2017 Thales Lima Oliveira <thales@ufu.br>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program. If not, see <https://www.gnu.org/licenses/>.
16  */
17 
18 #include "Element.h"
19 #ifdef USING_WX_3_0_X
20 #include "DegreesAndRadians.h"
21 #endif
22 
23 Element::Element() { m_selectionColour.SetRGBA(0.0, 0.5, 1.0, 0.5); }
25 void Element::SetPosition(const wxPoint2DDouble position)
26 {
27  m_position = position;
28  m_rect =
29  wxRect2DDouble(m_position.m_x - m_width / 2.0 - m_borderSize, m_position.m_y - m_height / 2.0 - m_borderSize,
30  m_width + 2.0 * m_borderSize, m_height + 2.0 * m_borderSize);
31 }
32 
33 void Element::DrawCircle(wxPoint2DDouble position, double radius, int numSegments, GLenum mode) const
34 {
35  glBegin(mode);
36  for(int i = 0; i < numSegments; i++) {
37  double theta = 2.0 * 3.1415926 * double(i) / double(numSegments);
38  glVertex2f(radius * std::cos(theta) + position.m_x, radius * std::sin(theta) + position.m_y);
39  }
40  glEnd();
41 }
42 
43 void Element::DrawArc(wxPoint2DDouble position,
44  double radius,
45  double initAngle,
46  double finalAngle,
47  int numSegments,
48  GLenum mode) const
49 {
50  double initAngRad = wxDegToRad(initAngle);
51  double finalAngRad = wxDegToRad(finalAngle);
52  glBegin(mode);
53  for(int i = 0; i <= numSegments; i++) {
54  double theta = initAngRad + (finalAngRad - initAngRad) * double(i) / double(numSegments);
55  glVertex2f(radius * std::cos(theta) + position.m_x, radius * std::sin(theta) + position.m_y);
56  }
57  glEnd();
58 }
59 
60 void Element::DrawTriangle(std::vector<wxPoint2DDouble> points, GLenum mode) const
61 {
62  glBegin(mode);
63  for(int i = 0; i < 3; i++) {
64  glVertex2d(points[i].m_x, points[i].m_y);
65  }
66  glEnd();
67 }
68 
69 void Element::DrawRectangle(wxPoint2DDouble position, double width, double height, GLenum mode) const
70 {
71  glBegin(mode); // TODO: GL_QUADS é obsoleto (OpenGL 3.0+), encontrar outra solução.
72  glVertex2d(position.m_x - width / 2.0, position.m_y - height / 2.0);
73  glVertex2d(position.m_x - width / 2.0, position.m_y + height / 2.0);
74  glVertex2d(position.m_x + width / 2.0, position.m_y + height / 2.0);
75  glVertex2d(position.m_x + width / 2.0, position.m_y - height / 2.0);
76  glEnd();
77 }
78 
79 void Element::DrawRectangle(wxPoint2DDouble* points, GLenum mode) const
80 {
81  glBegin(mode); // TODO: GL_QUADS é obsoleto (OpenGL 3.0+), encontrar outra solução.
82  glVertex2d(points[0].m_x, points[0].m_y);
83  glVertex2d(points[1].m_x, points[1].m_y);
84  glVertex2d(points[2].m_x, points[2].m_y);
85  glVertex2d(points[3].m_x, points[3].m_y);
86  glEnd();
87 }
88 
89 void Element::DrawLine(std::vector<wxPoint2DDouble> points, GLenum mode) const
90 {
91  glBegin(mode);
92  for(auto it = points.begin(); it != points.end(); ++it) {
93  glVertex2d((*it).m_x, (*it).m_y);
94  }
95  glEnd();
96 }
97 
98 void Element::DrawPickbox(wxPoint2DDouble position) const
99 {
100  glLineWidth(1.0);
101  glColor4d(1.0, 1.0, 1.0, 0.8);
102  DrawRectangle(position, 8.0, 8.0);
103  glColor4d(0.0, 0.0, 0.0, 1.0);
104  DrawRectangle(position, 8.0, 8.0, GL_LINE_LOOP);
105 }
106 
107 wxPoint2DDouble Element::RotateAtPosition(wxPoint2DDouble pointToRotate, double angle, bool degrees) const
108 {
109  double radAngle = angle;
110  if(degrees) radAngle = wxDegToRad(angle);
111  return wxPoint2DDouble(std::cos(radAngle) * (pointToRotate.m_x - m_position.m_x) -
112  std::sin(radAngle) * (pointToRotate.m_y - m_position.m_y) + m_position.m_x,
113  std::sin(radAngle) * (pointToRotate.m_x - m_position.m_x) +
114  std::cos(radAngle) * (pointToRotate.m_y - m_position.m_y) + m_position.m_y);
115 }
116 
117 void Element::StartMove(wxPoint2DDouble position)
118 {
119  this->m_moveStartPt = position;
120  this->m_movePos = m_position;
121 }
122 
123 void Element::Move(wxPoint2DDouble position) { SetPosition(m_movePos + position - m_moveStartPt); }
124 wxPoint2DDouble Element::WorldToScreen(wxPoint2DDouble translation, double scale, double offsetX, double offsetY) const
125 {
126  return wxPoint2DDouble(m_position.m_x + offsetX + translation.m_x, m_position.m_y + offsetY + translation.m_y) *
127  scale;
128 }
129 
130 wxPoint2DDouble Element::WorldToScreen(wxPoint2DDouble position,
131  wxPoint2DDouble translation,
132  double scale,
133  double offsetX,
134  double offsetY) const
135 {
136  return wxPoint2DDouble(position.m_x + offsetX + translation.m_x, position.m_y + offsetY + translation.m_y) * scale;
137 }
138 
139 void Element::DrawPoint(wxPoint2DDouble position, double size) const
140 {
141  glPointSize(size);
142  glBegin(GL_POINTS);
143  glVertex2d(position.m_x, position.m_y);
144  glEnd();
145 }
146 
147 bool Element::RotatedRectanglesIntersects(wxRect2DDouble rect1,
148  wxRect2DDouble rect2,
149  double angle1,
150  double angle2) const
151 {
152  wxPoint2DDouble rect1Corners[4] = {rect1.GetLeftTop(), rect1.GetLeftBottom(), rect1.GetRightBottom(),
153  rect1.GetRightTop()};
154  wxPoint2DDouble rect2Corners[4] = {rect2.GetLeftTop(), rect2.GetLeftBottom(), rect2.GetRightBottom(),
155  rect2.GetRightTop()};
156  wxPoint2DDouble rect1Center(rect1.m_x + rect1.m_width / 2.0, rect1.m_y + rect1.m_height / 2.0);
157  wxPoint2DDouble rect2Center(rect2.m_x + rect2.m_width / 2.0, rect2.m_y + rect2.m_height / 2.0);
158 
159  // Rotate the corners.
160  double radAngle1 = wxDegToRad(angle1);
161  double radAngle2 = wxDegToRad(angle2);
162 
163  for(int i = 0; i < 4; i++) {
164  rect1Corners[i] =
165  wxPoint2DDouble(std::cos(radAngle1) * (rect1Corners[i].m_x - rect1Center.m_x) -
166  std::sin(radAngle1) * (rect1Corners[i].m_y - rect1Center.m_y) + rect1Center.m_x,
167  std::sin(radAngle1) * (rect1Corners[i].m_x - rect1Center.m_x) +
168  std::cos(radAngle1) * (rect1Corners[i].m_y - rect1Center.m_y) + rect1Center.m_y);
169 
170  rect2Corners[i] =
171  wxPoint2DDouble(std::cos(radAngle2) * (rect2Corners[i].m_x - rect2Center.m_x) -
172  std::sin(radAngle2) * (rect2Corners[i].m_y - rect2Center.m_y) + rect2Center.m_x,
173  std::sin(radAngle2) * (rect2Corners[i].m_x - rect2Center.m_x) +
174  std::cos(radAngle2) * (rect2Corners[i].m_y - rect2Center.m_y) + rect2Center.m_y);
175  }
176 
177  //[Ref] http://www.gamedev.net/page/resources/_/technical/game-programming/2d-rotated-rectangle-collision-r2604
178 
179  // Find the rectangles axis to project
180  wxPoint2DDouble axis[4] = {rect1Corners[3] - rect1Corners[0], rect1Corners[3] - rect1Corners[2],
181  rect2Corners[3] - rect2Corners[0], rect2Corners[3] - rect2Corners[2]};
182 
183  // Calculate the projected points to each axis
184  wxPoint2DDouble rect1ProjPts[4][4]; // [axis][corner]
185  wxPoint2DDouble rect2ProjPts[4][4]; // [axis][corner]
186  for(int i = 0; i < 4; i++) {
187  double den = axis[i].m_x * axis[i].m_x + axis[i].m_y * axis[i].m_y;
188  for(int j = 0; j < 4; j++) {
189  double m_rectProj = (rect1Corners[j].m_x * axis[i].m_x + rect1Corners[j].m_y * axis[i].m_y) / den;
190  double rectProj = (rect2Corners[j].m_x * axis[i].m_x + rect2Corners[j].m_y * axis[i].m_y) / den;
191 
192  rect1ProjPts[i][j] = wxPoint2DDouble(m_rectProj * axis[i].m_x, m_rectProj * axis[i].m_y);
193  rect2ProjPts[i][j] = wxPoint2DDouble(rectProj * axis[i].m_x, rectProj * axis[i].m_y);
194  }
195  }
196 
197  // Calculate the scalar value to identify the max and min values on projections
198  double rect1Scalar[4][4]; //[axis][corner]
199  double rect2Scalar[4][4]; //[axis][corner]
200  for(int i = 0; i < 4; i++) {
201  for(int j = 0; j < 4; j++) {
202  rect1Scalar[i][j] = rect1ProjPts[i][j].m_x * axis[i].m_x + rect1ProjPts[i][j].m_y * axis[i].m_y;
203  rect2Scalar[i][j] = rect2ProjPts[i][j].m_x * axis[i].m_x + rect2ProjPts[i][j].m_y * axis[i].m_y;
204  }
205  }
206  // Identify the max and min scalar values
207  double rect1Min[4];
208  double rect1Max[4];
209  double rect2Min[4];
210  double rect2Max[4];
211 
212  for(int i = 0; i < 4; i++) {
213  rect1Max[i] = rect1Scalar[i][0];
214  rect2Max[i] = rect2Scalar[i][0];
215  rect1Min[i] = rect1Scalar[i][0];
216  rect2Min[i] = rect2Scalar[i][0];
217 
218  for(int j = 1; j < 4; j++) {
219  if(rect1Max[i] < rect1Scalar[i][j]) rect1Max[i] = rect1Scalar[i][j];
220  if(rect2Max[i] < rect2Scalar[i][j]) rect2Max[i] = rect2Scalar[i][j];
221 
222  if(rect1Min[i] > rect1Scalar[i][j]) rect1Min[i] = rect1Scalar[i][j];
223  if(rect2Min[i] > rect2Scalar[i][j]) rect2Min[i] = rect2Scalar[i][j];
224  }
225  }
226 
227  // Check if any segment don't overlap
228  for(int i = 0; i < 4; i++) {
229  if(!(rect2Min[i] <= rect1Max[i] && rect2Max[i] >= rect1Min[i])) return false;
230  }
231 
232  return true;
233 }
234 
235 bool Element::SetOnline(bool online)
236 {
237  // Check if any parent is null.
238  for(auto it = m_parentList.begin(); it != m_parentList.end(); it++) {
239  if(!(*it)) return false;
240  }
241  m_online = online;
242  return true;
243 }
244 
245 void Element::GeneralMenuItens(wxMenu& menu)
246 {
247  wxFileName exeFileName(wxStandardPaths::Get().GetExecutablePath());
248  wxString exePath = exeFileName.GetPath();
249 
250  wxMenuItem* clockItem = new wxMenuItem(&menu, ID_ROTATE_CLOCK, _("Rotate clockwise"));
251  clockItem->SetBitmap(wxImage(exePath + "\\..\\data\\images\\menu\\rotateClock16.png"));
252  menu.Append(clockItem);
253 
254  wxMenuItem* counterClockItem = new wxMenuItem(&menu, ID_ROTATE_COUNTERCLOCK, _("Rotate counter-clockwise"));
255  counterClockItem->SetBitmap(wxImage(exePath + "\\..\\data\\images\\menu\\rotateCounterClock16.png"));
256  menu.Append(counterClockItem);
257 
258  wxMenuItem* deleteItem = new wxMenuItem(&menu, ID_DELETE, _("Delete"));
259  deleteItem->SetBitmap(wxImage(exePath + "\\..\\data\\images\\menu\\delete16.png"));
260  menu.Append(deleteItem);
261 }
262 
263 void Element::CalculateBoundaries(wxPoint2DDouble& leftUp, wxPoint2DDouble& rightBottom) const
264 {
265  // Check rect corners boundaries.
266 
267  // Get rectangle corners
268  wxPoint2DDouble rectCorner[4] = {m_rect.GetLeftTop(), m_rect.GetLeftBottom(), m_rect.GetRightBottom(),
269  m_rect.GetRightTop()};
270  // Rotate corners.
271  for(int i = 0; i < 4; ++i) {
272  rectCorner[i] = RotateAtPosition(rectCorner[i], m_angle);
273  }
274  leftUp = rectCorner[0];
275  rightBottom = rectCorner[0];
276  for(int i = 1; i < 4; ++i) {
277  if(rectCorner[i].m_x < leftUp.m_x) leftUp.m_x = rectCorner[i].m_x;
278  if(rectCorner[i].m_y < leftUp.m_y) leftUp.m_y = rectCorner[i].m_y;
279  if(rectCorner[i].m_x > rightBottom.m_x) rightBottom.m_x = rectCorner[i].m_x;
280  if(rectCorner[i].m_y > rightBottom.m_y) rightBottom.m_y = rectCorner[i].m_y;
281  }
282 
283  // Check points list boundaries.
284  for(int i = 0; i < (int)m_pointList.size(); i++) {
285  if(m_pointList[i].m_x < leftUp.m_x) leftUp.m_x = m_pointList[i].m_x;
286  if(m_pointList[i].m_y < leftUp.m_y) leftUp.m_y = m_pointList[i].m_y;
287  if(m_pointList[i].m_x > rightBottom.m_x) rightBottom.m_x = m_pointList[i].m_x;
288  if(m_pointList[i].m_y > rightBottom.m_y) rightBottom.m_y = m_pointList[i].m_y;
289  }
290 }
291 
292 bool Element::DoubleFromString(wxWindow* parent, wxString strValue, double& value, wxString errorMsg)
293 {
294  double dValue = 0.0;
295 
296  if(!strValue.ToDouble(&dValue)) {
297  wxMessageDialog msgDialog(parent, errorMsg, _("Error"), wxOK | wxCENTRE | wxICON_ERROR);
298  msgDialog.ShowModal();
299  return false;
300  }
301 
302  value = dValue;
303  return true;
304 }
305 
306 bool Element::IntFromString(wxWindow* parent, wxString strValue, int& value, wxString errorMsg)
307 {
308  long int iValue = 0;
309 
310  if(!strValue.ToLong(&iValue)) {
311  wxMessageDialog msgDialog(parent, errorMsg, _("Error"), wxOK | wxCENTRE | wxICON_ERROR);
312  msgDialog.ShowModal();
313  return false;
314  }
315 
316  value = iValue;
317  return true;
318 }
319 
320 wxString Element::StringFromDouble(double value, int minDecimal)
321 {
322  wxString str = wxString::FromCDouble(value, 13);
323  int cutNumber = 0;
324  int numDecimal = 0;
325  bool foundCut = false;
326  for(int i = (int)str.length() - 1; i >= 0; i--) {
327  if(str[i] != '0' && !foundCut) {
328  cutNumber = i;
329  foundCut = true;
330  }
331  if(str[i] == '.') {
332  numDecimal = i;
333  break;
334  }
335  }
336 
337  wxString formatedStr = "";
338  if(cutNumber - numDecimal > minDecimal)
339  formatedStr = wxString::FromDouble(value, cutNumber - numDecimal);
340  else
341  formatedStr = wxString::FromDouble(value, minDecimal);
342 
343  return formatedStr;
344 }
345 
346 void Element::ReplaceParent(Element* oldParent, Element* newParent)
347 {
348  for(int i = 0; i < (int)m_parentList.size(); i++) {
349  if(m_parentList[i] == oldParent) m_parentList[i] = newParent;
350  }
351 }
352 
353 void Element::AddChild(Element* child) { m_childList.push_back(child); }
355 {
356  for(auto it = m_childList.begin(); it != m_childList.end(); ++it) {
357  Element* element = *it;
358  if(element == child) m_childList.erase(it--);
359  }
360 }
361 
362 void Element::ReplaceChild(Element* oldChild, Element* newChild)
363 {
364  for(int i = 0; i < (int)m_childList.size(); i++) {
365  if(m_childList[i] == oldChild) m_childList[i] = newChild;
366  }
367 }
368 
369 void OpenGLColour::SetRGBA(GLdouble red, GLdouble green, GLdouble blue, GLdouble alpha)
370 {
371  rgba[0] = red;
372  rgba[1] = green;
373  rgba[2] = blue;
374  rgba[3] = alpha;
375 }
376 
377 OpenGLColour::OpenGLColour() { SetRGBA(1.0, 1.0, 1.0, 1.0); }
378 OpenGLColour::OpenGLColour(GLdouble red, GLdouble green, GLdouble blue, GLdouble alpha)
379 {
380  SetRGBA(red, green, blue, alpha);
381 }
382 
383 double Element::PointToLineDistance(wxPoint2DDouble point, int* segmentNumber) const
384 {
385  //[Ref] http://geomalgorithms.com/a02-_lines.html
386  double distance = 100.0; // Big initial distance.
387  wxPoint2DDouble p0 = point;
388 
389  for(int i = 1; i < (int)m_pointList.size() - 2; i++) {
390  double d = 0.0;
391 
392  wxPoint2DDouble p1 = m_pointList[i];
393  wxPoint2DDouble p2 = m_pointList[i + 1];
394 
395  wxPoint2DDouble v = p2 - p1;
396  wxPoint2DDouble w = p0 - p1;
397 
398  double c1 = w.m_x * v.m_x + w.m_y * v.m_y;
399  double c2 = v.m_x * v.m_x + v.m_y * v.m_y;
400 
401  if(c1 <= 0.0) {
402  d = std::sqrt(std::pow(p0.m_y - p1.m_y, 2) + std::pow(p0.m_x - p1.m_x, 2));
403  } else if(c2 <= c1) {
404  d = std::sqrt(std::pow(p0.m_y - p2.m_y, 2) + std::pow(p0.m_x - p2.m_x, 2));
405  } else {
406  d = std::abs((p2.m_y - p1.m_y) * p0.m_x - (p2.m_x - p1.m_x) * p0.m_y + p2.m_x * p1.m_y - p2.m_y * p1.m_x) /
407  std::sqrt(std::pow(p2.m_y - p1.m_y, 2) + std::pow(p2.m_x - p1.m_x, 2));
408  }
409  if(d < distance) {
410  distance = d;
411  if(segmentNumber) *segmentNumber = i;
412  }
413  }
414 
415  return distance;
416 }
virtual void Move(wxPoint2DDouble position)
Move the element other position.
Definition: Element.cpp:123
+
1 /*
2  * Copyright (C) 2017 Thales Lima Oliveira <thales@ufu.br>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program. If not, see <https://www.gnu.org/licenses/>.
16  */
17 
18 #include "Element.h"
19 #ifdef USING_WX_3_0_X
20 #include "DegreesAndRadians.h"
21 #endif
22 
23 Element::Element() { m_selectionColour.SetRGBA(0.0, 0.5, 1.0, 0.5); }
25 void Element::SetPosition(const wxPoint2DDouble position)
26 {
27  m_position = position;
28  m_rect =
29  wxRect2DDouble(m_position.m_x - m_width / 2.0 - m_borderSize, m_position.m_y - m_height / 2.0 - m_borderSize,
30  m_width + 2.0 * m_borderSize, m_height + 2.0 * m_borderSize);
31 }
32 
33 void Element::DrawCircle(wxPoint2DDouble position, double radius, int numSegments, GLenum mode) const
34 {
35  glBegin(mode);
36  for(int i = 0; i < numSegments; i++) {
37  double theta = 2.0 * 3.1415926 * double(i) / double(numSegments);
38  glVertex2f(radius * std::cos(theta) + position.m_x, radius * std::sin(theta) + position.m_y);
39  }
40  glEnd();
41 }
42 
43 void Element::DrawArc(wxPoint2DDouble position,
44  double radius,
45  double initAngle,
46  double finalAngle,
47  int numSegments,
48  GLenum mode) const
49 {
50  double initAngRad = wxDegToRad(initAngle);
51  double finalAngRad = wxDegToRad(finalAngle);
52  glBegin(mode);
53  for(int i = 0; i <= numSegments; i++) {
54  double theta = initAngRad + (finalAngRad - initAngRad) * double(i) / double(numSegments);
55  glVertex2f(radius * std::cos(theta) + position.m_x, radius * std::sin(theta) + position.m_y);
56  }
57  glEnd();
58 }
59 
60 void Element::DrawTriangle(std::vector<wxPoint2DDouble> points, GLenum mode) const
61 {
62  glBegin(mode);
63  for(int i = 0; i < 3; i++) {
64  glVertex2d(points[i].m_x, points[i].m_y);
65  }
66  glEnd();
67 }
68 
69 void Element::DrawRectangle(wxPoint2DDouble position, double width, double height, GLenum mode) const
70 {
71  glBegin(mode); // TODO: GL_QUADS é obsoleto (OpenGL 3.0+), encontrar outra solução.
72  glVertex2d(position.m_x - width / 2.0, position.m_y - height / 2.0);
73  glVertex2d(position.m_x - width / 2.0, position.m_y + height / 2.0);
74  glVertex2d(position.m_x + width / 2.0, position.m_y + height / 2.0);
75  glVertex2d(position.m_x + width / 2.0, position.m_y - height / 2.0);
76  glEnd();
77 }
78 
79 void Element::DrawRectangle(wxPoint2DDouble* points, GLenum mode) const
80 {
81  glBegin(mode); // TODO: GL_QUADS é obsoleto (OpenGL 3.0+), encontrar outra solução.
82  glVertex2d(points[0].m_x, points[0].m_y);
83  glVertex2d(points[1].m_x, points[1].m_y);
84  glVertex2d(points[2].m_x, points[2].m_y);
85  glVertex2d(points[3].m_x, points[3].m_y);
86  glEnd();
87 }
88 
89 void Element::DrawLine(std::vector<wxPoint2DDouble> points, GLenum mode) const
90 {
91  glBegin(mode);
92  for(auto it = points.begin(); it != points.end(); ++it) {
93  glVertex2d((*it).m_x, (*it).m_y);
94  }
95  glEnd();
96 }
97 
98 void Element::DrawPickbox(wxPoint2DDouble position) const
99 {
100  glLineWidth(1.0);
101  glColor4d(1.0, 1.0, 1.0, 0.8);
102  DrawRectangle(position, 8.0, 8.0);
103  glColor4d(0.0, 0.0, 0.0, 1.0);
104  DrawRectangle(position, 8.0, 8.0, GL_LINE_LOOP);
105 }
106 
107 wxPoint2DDouble Element::RotateAtPosition(wxPoint2DDouble pointToRotate, double angle, bool degrees) const
108 {
109  double radAngle = angle;
110  if(degrees) radAngle = wxDegToRad(angle);
111  return wxPoint2DDouble(std::cos(radAngle) * (pointToRotate.m_x - m_position.m_x) -
112  std::sin(radAngle) * (pointToRotate.m_y - m_position.m_y) + m_position.m_x,
113  std::sin(radAngle) * (pointToRotate.m_x - m_position.m_x) +
114  std::cos(radAngle) * (pointToRotate.m_y - m_position.m_y) + m_position.m_y);
115 }
116 
117 void Element::StartMove(wxPoint2DDouble position)
118 {
119  this->m_moveStartPt = position;
120  this->m_movePos = m_position;
121 }
122 
123 void Element::Move(wxPoint2DDouble position) { SetPosition(m_movePos + position - m_moveStartPt); }
124 wxPoint2DDouble Element::WorldToScreen(wxPoint2DDouble translation, double scale, double offsetX, double offsetY) const
125 {
126  return wxPoint2DDouble(m_position.m_x + offsetX + translation.m_x, m_position.m_y + offsetY + translation.m_y) *
127  scale;
128 }
129 
130 wxPoint2DDouble Element::WorldToScreen(wxPoint2DDouble position,
131  wxPoint2DDouble translation,
132  double scale,
133  double offsetX,
134  double offsetY) const
135 {
136  return wxPoint2DDouble(position.m_x + offsetX + translation.m_x, position.m_y + offsetY + translation.m_y) * scale;
137 }
138 
139 void Element::DrawPoint(wxPoint2DDouble position, double size) const
140 {
141  glPointSize(size);
142  glBegin(GL_POINTS);
143  glVertex2d(position.m_x, position.m_y);
144  glEnd();
145 }
146 
147 bool Element::RotatedRectanglesIntersects(wxRect2DDouble rect1,
148  wxRect2DDouble rect2,
149  double angle1,
150  double angle2) const
151 {
152  wxPoint2DDouble rect1Corners[4] = {rect1.GetLeftTop(), rect1.GetLeftBottom(), rect1.GetRightBottom(),
153  rect1.GetRightTop()};
154  wxPoint2DDouble rect2Corners[4] = {rect2.GetLeftTop(), rect2.GetLeftBottom(), rect2.GetRightBottom(),
155  rect2.GetRightTop()};
156  wxPoint2DDouble rect1Center(rect1.m_x + rect1.m_width / 2.0, rect1.m_y + rect1.m_height / 2.0);
157  wxPoint2DDouble rect2Center(rect2.m_x + rect2.m_width / 2.0, rect2.m_y + rect2.m_height / 2.0);
158 
159  // Rotate the corners.
160  double radAngle1 = wxDegToRad(angle1);
161  double radAngle2 = wxDegToRad(angle2);
162 
163  for(int i = 0; i < 4; i++) {
164  rect1Corners[i] =
165  wxPoint2DDouble(std::cos(radAngle1) * (rect1Corners[i].m_x - rect1Center.m_x) -
166  std::sin(radAngle1) * (rect1Corners[i].m_y - rect1Center.m_y) + rect1Center.m_x,
167  std::sin(radAngle1) * (rect1Corners[i].m_x - rect1Center.m_x) +
168  std::cos(radAngle1) * (rect1Corners[i].m_y - rect1Center.m_y) + rect1Center.m_y);
169 
170  rect2Corners[i] =
171  wxPoint2DDouble(std::cos(radAngle2) * (rect2Corners[i].m_x - rect2Center.m_x) -
172  std::sin(radAngle2) * (rect2Corners[i].m_y - rect2Center.m_y) + rect2Center.m_x,
173  std::sin(radAngle2) * (rect2Corners[i].m_x - rect2Center.m_x) +
174  std::cos(radAngle2) * (rect2Corners[i].m_y - rect2Center.m_y) + rect2Center.m_y);
175  }
176 
177  //[Ref] http://www.gamedev.net/page/resources/_/technical/game-programming/2d-rotated-rectangle-collision-r2604
178 
179  // Find the rectangles axis to project
180  wxPoint2DDouble axis[4] = {rect1Corners[3] - rect1Corners[0], rect1Corners[3] - rect1Corners[2],
181  rect2Corners[3] - rect2Corners[0], rect2Corners[3] - rect2Corners[2]};
182 
183  // Calculate the projected points to each axis
184  wxPoint2DDouble rect1ProjPts[4][4]; // [axis][corner]
185  wxPoint2DDouble rect2ProjPts[4][4]; // [axis][corner]
186  for(int i = 0; i < 4; i++) {
187  double den = axis[i].m_x * axis[i].m_x + axis[i].m_y * axis[i].m_y;
188  for(int j = 0; j < 4; j++) {
189  double m_rectProj = (rect1Corners[j].m_x * axis[i].m_x + rect1Corners[j].m_y * axis[i].m_y) / den;
190  double rectProj = (rect2Corners[j].m_x * axis[i].m_x + rect2Corners[j].m_y * axis[i].m_y) / den;
191 
192  rect1ProjPts[i][j] = wxPoint2DDouble(m_rectProj * axis[i].m_x, m_rectProj * axis[i].m_y);
193  rect2ProjPts[i][j] = wxPoint2DDouble(rectProj * axis[i].m_x, rectProj * axis[i].m_y);
194  }
195  }
196 
197  // Calculate the scalar value to identify the max and min values on projections
198  double rect1Scalar[4][4]; //[axis][corner]
199  double rect2Scalar[4][4]; //[axis][corner]
200  for(int i = 0; i < 4; i++) {
201  for(int j = 0; j < 4; j++) {
202  rect1Scalar[i][j] = rect1ProjPts[i][j].m_x * axis[i].m_x + rect1ProjPts[i][j].m_y * axis[i].m_y;
203  rect2Scalar[i][j] = rect2ProjPts[i][j].m_x * axis[i].m_x + rect2ProjPts[i][j].m_y * axis[i].m_y;
204  }
205  }
206  // Identify the max and min scalar values
207  double rect1Min[4];
208  double rect1Max[4];
209  double rect2Min[4];
210  double rect2Max[4];
211 
212  for(int i = 0; i < 4; i++) {
213  rect1Max[i] = rect1Scalar[i][0];
214  rect2Max[i] = rect2Scalar[i][0];
215  rect1Min[i] = rect1Scalar[i][0];
216  rect2Min[i] = rect2Scalar[i][0];
217 
218  for(int j = 1; j < 4; j++) {
219  if(rect1Max[i] < rect1Scalar[i][j]) rect1Max[i] = rect1Scalar[i][j];
220  if(rect2Max[i] < rect2Scalar[i][j]) rect2Max[i] = rect2Scalar[i][j];
221 
222  if(rect1Min[i] > rect1Scalar[i][j]) rect1Min[i] = rect1Scalar[i][j];
223  if(rect2Min[i] > rect2Scalar[i][j]) rect2Min[i] = rect2Scalar[i][j];
224  }
225  }
226 
227  // Check if any segment don't overlap
228  for(int i = 0; i < 4; i++) {
229  if(!(rect2Min[i] <= rect1Max[i] && rect2Max[i] >= rect1Min[i])) return false;
230  }
231 
232  return true;
233 }
234 
235 bool Element::SetOnline(bool online)
236 {
237  // Check if any parent is null.
238  for(auto it = m_parentList.begin(); it != m_parentList.end(); it++) {
239  if(!(*it)) return false;
240  }
241  m_online = online;
242  return true;
243 }
244 
245 void Element::GeneralMenuItens(wxMenu& menu)
246 {
247  wxFileName exeFileName(wxStandardPaths::Get().GetExecutablePath());
248  wxString exePath = exeFileName.GetPath();
249 
250  wxMenuItem* clockItem = new wxMenuItem(&menu, ID_ROTATE_CLOCK, _("Rotate clockwise"));
251  clockItem->SetBitmap(wxImage(exePath + wxFileName::DirName("\\..\\data\\images\\menu\\rotateClock16.png", wxPATH_WIN).GetPath()));
252  menu.Append(clockItem);
253 
254  wxMenuItem* counterClockItem = new wxMenuItem(&menu, ID_ROTATE_COUNTERCLOCK, _("Rotate counter-clockwise"));
255  counterClockItem->SetBitmap(wxImage(exePath + wxFileName::DirName("\\..\\data\\images\\menu\\rotateCounterClock16.png", wxPATH_WIN).GetPath()));
256  menu.Append(counterClockItem);
257 
258  wxMenuItem* deleteItem = new wxMenuItem(&menu, ID_DELETE, _("Delete"));
259  deleteItem->SetBitmap(wxImage(exePath + wxFileName::DirName("\\..\\data\\images\\menu\\delete16.png", wxPATH_WIN).GetPath()));
260  menu.Append(deleteItem);
261 }
262 
263 void Element::CalculateBoundaries(wxPoint2DDouble& leftUp, wxPoint2DDouble& rightBottom) const
264 {
265  // Check rect corners boundaries.
266 
267  // Get rectangle corners
268  wxPoint2DDouble rectCorner[4] = {m_rect.GetLeftTop(), m_rect.GetLeftBottom(), m_rect.GetRightBottom(),
269  m_rect.GetRightTop()};
270  // Rotate corners.
271  for(int i = 0; i < 4; ++i) {
272  rectCorner[i] = RotateAtPosition(rectCorner[i], m_angle);
273  }
274  leftUp = rectCorner[0];
275  rightBottom = rectCorner[0];
276  for(int i = 1; i < 4; ++i) {
277  if(rectCorner[i].m_x < leftUp.m_x) leftUp.m_x = rectCorner[i].m_x;
278  if(rectCorner[i].m_y < leftUp.m_y) leftUp.m_y = rectCorner[i].m_y;
279  if(rectCorner[i].m_x > rightBottom.m_x) rightBottom.m_x = rectCorner[i].m_x;
280  if(rectCorner[i].m_y > rightBottom.m_y) rightBottom.m_y = rectCorner[i].m_y;
281  }
282 
283  // Check points list boundaries.
284  for(int i = 0; i < (int)m_pointList.size(); i++) {
285  if(m_pointList[i].m_x < leftUp.m_x) leftUp.m_x = m_pointList[i].m_x;
286  if(m_pointList[i].m_y < leftUp.m_y) leftUp.m_y = m_pointList[i].m_y;
287  if(m_pointList[i].m_x > rightBottom.m_x) rightBottom.m_x = m_pointList[i].m_x;
288  if(m_pointList[i].m_y > rightBottom.m_y) rightBottom.m_y = m_pointList[i].m_y;
289  }
290 }
291 
292 bool Element::DoubleFromString(wxWindow* parent, wxString strValue, double& value, wxString errorMsg)
293 {
294  double dValue = 0.0;
295 
296  if(!strValue.ToDouble(&dValue)) {
297  wxMessageDialog msgDialog(parent, errorMsg, _("Error"), wxOK | wxCENTRE | wxICON_ERROR);
298  msgDialog.ShowModal();
299  return false;
300  }
301 
302  value = dValue;
303  return true;
304 }
305 
306 bool Element::IntFromString(wxWindow* parent, wxString strValue, int& value, wxString errorMsg)
307 {
308  long int iValue = 0;
309 
310  if(!strValue.ToLong(&iValue)) {
311  wxMessageDialog msgDialog(parent, errorMsg, _("Error"), wxOK | wxCENTRE | wxICON_ERROR);
312  msgDialog.ShowModal();
313  return false;
314  }
315 
316  value = iValue;
317  return true;
318 }
319 
320 wxString Element::StringFromDouble(double value, int minDecimal)
321 {
322  wxString str = wxString::FromCDouble(value, 13);
323  int cutNumber = 0;
324  int numDecimal = 0;
325  bool foundCut = false;
326  for(int i = (int)str.length() - 1; i >= 0; i--) {
327  if(str[i] != '0' && !foundCut) {
328  cutNumber = i;
329  foundCut = true;
330  }
331  if(str[i] == '.') {
332  numDecimal = i;
333  break;
334  }
335  }
336 
337  wxString formatedStr = "";
338  if(cutNumber - numDecimal > minDecimal)
339  formatedStr = wxString::FromDouble(value, cutNumber - numDecimal);
340  else
341  formatedStr = wxString::FromDouble(value, minDecimal);
342 
343  return formatedStr;
344 }
345 
346 void Element::ReplaceParent(Element* oldParent, Element* newParent)
347 {
348  for(int i = 0; i < (int)m_parentList.size(); i++) {
349  if(m_parentList[i] == oldParent) m_parentList[i] = newParent;
350  }
351 }
352 
353 void Element::AddChild(Element* child) { m_childList.push_back(child); }
355 {
356  for(auto it = m_childList.begin(); it != m_childList.end(); ++it) {
357  Element* element = *it;
358  if(element == child) m_childList.erase(it--);
359  }
360 }
361 
362 void Element::ReplaceChild(Element* oldChild, Element* newChild)
363 {
364  for(int i = 0; i < (int)m_childList.size(); i++) {
365  if(m_childList[i] == oldChild) m_childList[i] = newChild;
366  }
367 }
368 
369 void OpenGLColour::SetRGBA(GLdouble red, GLdouble green, GLdouble blue, GLdouble alpha)
370 {
371  rgba[0] = red;
372  rgba[1] = green;
373  rgba[2] = blue;
374  rgba[3] = alpha;
375 }
376 
377 OpenGLColour::OpenGLColour() { SetRGBA(1.0, 1.0, 1.0, 1.0); }
378 OpenGLColour::OpenGLColour(GLdouble red, GLdouble green, GLdouble blue, GLdouble alpha)
379 {
380  SetRGBA(red, green, blue, alpha);
381 }
382 
383 double Element::PointToLineDistance(wxPoint2DDouble point, int* segmentNumber) const
384 {
385  //[Ref] http://geomalgorithms.com/a02-_lines.html
386  double distance = 100.0; // Big initial distance.
387  wxPoint2DDouble p0 = point;
388 
389  for(int i = 1; i < (int)m_pointList.size() - 2; i++) {
390  double d = 0.0;
391 
392  wxPoint2DDouble p1 = m_pointList[i];
393  wxPoint2DDouble p2 = m_pointList[i + 1];
394 
395  wxPoint2DDouble v = p2 - p1;
396  wxPoint2DDouble w = p0 - p1;
397 
398  double c1 = w.m_x * v.m_x + w.m_y * v.m_y;
399  double c2 = v.m_x * v.m_x + v.m_y * v.m_y;
400 
401  if(c1 <= 0.0) {
402  d = std::sqrt(std::pow(p0.m_y - p1.m_y, 2) + std::pow(p0.m_x - p1.m_x, 2));
403  } else if(c2 <= c1) {
404  d = std::sqrt(std::pow(p0.m_y - p2.m_y, 2) + std::pow(p0.m_x - p2.m_x, 2));
405  } else {
406  d = std::abs((p2.m_y - p1.m_y) * p0.m_x - (p2.m_x - p1.m_x) * p0.m_y + p2.m_x * p1.m_y - p2.m_y * p1.m_x) /
407  std::sqrt(std::pow(p2.m_y - p1.m_y, 2) + std::pow(p2.m_x - p1.m_x, 2));
408  }
409  if(d < distance) {
410  distance = d;
411  if(segmentNumber) *segmentNumber = i;
412  }
413  }
414 
415  return distance;
416 }
virtual void Move(wxPoint2DDouble position)
Move the element other position.
Definition: Element.cpp:123
Base class of all elements of the program. This class is responsible for manage graphical and his dat...
Definition: Element.h:113
virtual void DrawTriangle(std::vector< wxPoint2DDouble > points, GLenum mode=GL_TRIANGLES) const
Draw a triangle.
Definition: Element.cpp:60
virtual void DrawLine(std::vector< wxPoint2DDouble > points, GLenum mode=GL_LINE_STRIP) const
Draw line.
Definition: Element.cpp:89
diff --git a/docs/doxygen/html/_element_data_object_8cpp_source.html b/docs/doxygen/html/_element_data_object_8cpp_source.html index 273056d..6551ee1 100644 --- a/docs/doxygen/html/_element_data_object_8cpp_source.html +++ b/docs/doxygen/html/_element_data_object_8cpp_source.html @@ -88,7 +88,7 @@ $(document).ready(function(){initNavTree('_element_data_object_8cpp_source.html'
ElementDataObject.cpp
-
1 /*
2  * Copyright (C) 2017 Thales Lima Oliveira <thales@ufu.br>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program. If not, see <https://www.gnu.org/licenses/>.
16  */
17 
18 #include "ElementDataObject.h"
19 
20 ElementDataObject::ElementDataObject() : wxDataObjectSimple(wxDataFormat("PSPCopy"))
21 {
22  m_elementsLists = new ElementsLists();
23 }
24 
25 ElementDataObject::ElementDataObject(std::vector<Element*> elementList) : wxDataObjectSimple(wxDataFormat("PSPCopy"))
26 {
27  m_elementsLists = new ElementsLists();
28  if(elementList.size() > 0) {
29  // Separate buses (parents) from the rest of the elements (childs).
30  for(auto it = elementList.begin(), itEnd = elementList.end(); it != itEnd; ++it) {
31  Element* copy = (*it)->GetCopy();
32  if(copy) {
33  if(Bus* bus = dynamic_cast<Bus*>(copy))
34  m_elementsLists->parentList.push_back(bus);
35  else
36  m_elementsLists->elementList.push_back(copy);
37  }
38  }
39  }
40 }
41 
42 ElementDataObject::~ElementDataObject() {}
43 size_t ElementDataObject::GetDataSize() const { return sizeof(void*); }
44 bool ElementDataObject::GetDataHere(void* buf) const
45 {
46  *(ElementsLists**)buf = m_elementsLists;
47  return true;
48 }
49 
50 bool ElementDataObject::SetData(size_t len, const void* buf)
51 {
52  m_elementsLists = *(ElementsLists**)buf;
53  return true;
54 }
Base class of all elements of the program. This class is responsible for manage graphical and his dat...
Definition: Element.h:113
+
1 /*
2  * Copyright (C) 2017 Thales Lima Oliveira <thales@ufu.br>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program. If not, see <https://www.gnu.org/licenses/>.
16  */
17 
18 #include "ElementDataObject.h"
19 
20 ElementDataObject::ElementDataObject() : wxDataObjectSimple(wxDataFormat(wxT("PSPCopy")))
21 {
22  m_elementsLists = new ElementsLists();
23 }
24 
25 ElementDataObject::ElementDataObject(std::vector<Element*> elementList) : wxDataObjectSimple(wxDataFormat(wxT("PSPCopy")))
26 {
27  m_elementsLists = new ElementsLists();
28  if(elementList.size() > 0) {
29  // Separate buses (parents) from the rest of the elements (childs).
30  for(auto it = elementList.begin(), itEnd = elementList.end(); it != itEnd; ++it) {
31  Element* copy = (*it)->GetCopy();
32  if(copy) {
33  if(Bus* bus = dynamic_cast<Bus*>(copy))
34  m_elementsLists->parentList.push_back(bus);
35  else
36  m_elementsLists->elementList.push_back(copy);
37  }
38  }
39  }
40 }
41 
42 ElementDataObject::~ElementDataObject() {}
43 size_t ElementDataObject::GetDataSize() const
44 {
45  return sizeof(void*);
46  //return sizeof(*this);
47 }
48 
49 bool ElementDataObject::GetDataHere(void* buf) const
50 {
51  *(ElementsLists**)buf = m_elementsLists;
52  //buf = m_elementsLists;
53  return true;
54 }
55 
56 bool ElementDataObject::SetData(size_t len, const void* buf)
57 {
58  m_elementsLists = *(ElementsLists**)buf;
59  //m_elementsLists = const_cast<ElementsLists*>(static_cast<const ElementsLists*>(buf));
60  return true;
61 }
Base class of all elements of the program. This class is responsible for manage graphical and his dat...
Definition: Element.h:113
Node for power elements. All others power elements are connected through this.
Definition: Bus.h:69
diff --git a/docs/doxygen/html/_element_form_8cpp_source.html b/docs/doxygen/html/_element_form_8cpp_source.html index ca0b601..f12ca04 100644 --- a/docs/doxygen/html/_element_form_8cpp_source.html +++ b/docs/doxygen/html/_element_form_8cpp_source.html @@ -88,7 +88,7 @@ $(document).ready(function(){initNavTree('_element_form_8cpp_source.html','');})
ElementForm.cpp
-
1 // This file was auto-generated by codelite's wxCrafter Plugin
3 // wxCrafter project file: ElementForm.wxcp
4 // Do not modify this file by hand!
6 
7 #include "ElementForm.h"
8 
9 
10 // Declare the bitmap loading function
11 extern void wxC9EE9InitBitmapResources();
12 
13 static bool bBitmapLoaded = false;
14 
15 
16 BusFormBase::BusFormBase(wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style)
17  : wxDialog(parent, id, title, pos, size, style)
18 {
19  if ( !bBitmapLoaded ) {
20  // We need to initialise the default bitmap handler
21  wxXmlResource::Get()->AddHandler(new wxBitmapXmlHandler);
22  wxC9EE9InitBitmapResources();
23  bBitmapLoaded = true;
24  }
25 
26  wxBoxSizer* boxSizerLvl1_1 = new wxBoxSizer(wxVERTICAL);
27  this->SetSizer(boxSizerLvl1_1);
28 
29  m_notebook = new wxNotebook(this, wxID_ANY, wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), wxBK_DEFAULT);
30  m_notebook->SetName(wxT("m_notebook"));
31 
32  boxSizerLvl1_1->Add(m_notebook, 1, wxEXPAND, WXC_FROM_DIP(5));
33 
34  m_panelGeneral = new wxPanel(m_notebook, wxID_ANY, wxDefaultPosition, wxDLG_UNIT(m_notebook, wxSize(-1,-1)), wxTAB_TRAVERSAL);
35  m_notebook->AddPage(m_panelGeneral, _("General"), false);
36 
37  wxBoxSizer* boxSizerLvl2_1 = new wxBoxSizer(wxVERTICAL);
38  m_panelGeneral->SetSizer(boxSizerLvl2_1);
39 
40  m_staticTextName = new wxStaticText(m_panelGeneral, wxID_ANY, _("Name"), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
41 
42  boxSizerLvl2_1->Add(m_staticTextName, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
43 
44  m_textCtrlName = new wxTextCtrl(m_panelGeneral, wxID_ANY, wxT(""), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
45  #if wxVERSION_NUMBER >= 3000
46  m_textCtrlName->SetHint(wxT(""));
47  #endif
48 
49  boxSizerLvl2_1->Add(m_textCtrlName, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxEXPAND|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
50  m_textCtrlName->SetMinSize(wxSize(300,-1));
51 
52  wxGridSizer* gridSizerLvl3_1 = new wxGridSizer(0, 2, 0, 0);
53 
54  boxSizerLvl2_1->Add(gridSizerLvl3_1, 0, wxEXPAND, WXC_FROM_DIP(5));
55 
56  wxBoxSizer* boxSizerLvl4_1 = new wxBoxSizer(wxVERTICAL);
57 
58  gridSizerLvl3_1->Add(boxSizerLvl4_1, 0, wxEXPAND, WXC_FROM_DIP(5));
59 
60  m_staticTextNomVoltage = new wxStaticText(m_panelGeneral, wxID_ANY, _("Rated voltage"), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
61 
62  boxSizerLvl4_1->Add(m_staticTextNomVoltage, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
63 
64  wxBoxSizer* boxSizerLvl5_1 = new wxBoxSizer(wxHORIZONTAL);
65 
66  boxSizerLvl4_1->Add(boxSizerLvl5_1, 0, wxEXPAND, WXC_FROM_DIP(5));
67 
68  m_textCtrlNomVoltage = new wxTextCtrl(m_panelGeneral, wxID_ANY, wxT(""), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
69  #if wxVERSION_NUMBER >= 3000
70  m_textCtrlNomVoltage->SetHint(wxT(""));
71  #endif
72 
73  boxSizerLvl5_1->Add(m_textCtrlNomVoltage, 1, wxLEFT|wxRIGHT|wxBOTTOM|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
74 
75  wxArrayString m_choiceNomVoltageArr;
76  m_choiceNomVoltageArr.Add(wxT("V"));
77  m_choiceNomVoltageArr.Add(wxT("kV"));
78  m_choiceNomVoltage = new wxChoice(m_panelGeneral, wxID_ANY, wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), m_choiceNomVoltageArr, 0);
79  m_choiceNomVoltage->SetSelection(1);
80 
81  boxSizerLvl5_1->Add(m_choiceNomVoltage, 0, wxLEFT|wxRIGHT|wxBOTTOM, WXC_FROM_DIP(5));
82 
83  wxBoxSizer* boxSizerLvl4_2 = new wxBoxSizer(wxVERTICAL);
84 
85  gridSizerLvl3_1->Add(boxSizerLvl4_2, 0, wxEXPAND, WXC_FROM_DIP(5));
86 
87  m_checkBoxCtrlVoltage = new wxCheckBox(m_panelGeneral, wxID_ANY, _("Controlled voltage"), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
88  m_checkBoxCtrlVoltage->SetValue(false);
89 
90  boxSizerLvl4_2->Add(m_checkBoxCtrlVoltage, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
91 
92  wxBoxSizer* boxSizerLvl5_2 = new wxBoxSizer(wxHORIZONTAL);
93 
94  boxSizerLvl4_2->Add(boxSizerLvl5_2, 0, wxEXPAND, WXC_FROM_DIP(5));
95 
96  m_textCtrlCtrlVoltage = new wxTextCtrl(m_panelGeneral, wxID_ANY, wxT(""), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
97  #if wxVERSION_NUMBER >= 3000
98  m_textCtrlCtrlVoltage->SetHint(wxT(""));
99  #endif
100 
101  boxSizerLvl5_2->Add(m_textCtrlCtrlVoltage, 1, wxLEFT|wxRIGHT|wxBOTTOM|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
102 
103  wxArrayString m_choiceCtrlVoltageArr;
104  m_choiceCtrlVoltageArr.Add(wxT("p.u."));
105  m_choiceCtrlVoltageArr.Add(wxT("kV"));
106  m_choiceCtrlVoltage = new wxChoice(m_panelGeneral, wxID_ANY, wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), m_choiceCtrlVoltageArr, 0);
107  m_choiceCtrlVoltage->SetSelection(0);
108 
109  boxSizerLvl5_2->Add(m_choiceCtrlVoltage, 0, wxLEFT|wxRIGHT|wxBOTTOM, WXC_FROM_DIP(5));
110 
111  m_checkBoxSlackBus = new wxCheckBox(m_panelGeneral, wxID_ANY, _("Slack Bus"), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
112  m_checkBoxSlackBus->SetValue(false);
113 
114  boxSizerLvl2_1->Add(m_checkBoxSlackBus, 0, wxALL|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
115 
116  m_panelFault = new wxPanel(m_notebook, wxID_ANY, wxDefaultPosition, wxDLG_UNIT(m_notebook, wxSize(-1,-1)), wxTAB_TRAVERSAL);
117  m_notebook->AddPage(m_panelFault, _("Fault"), false);
118 
119  wxBoxSizer* boxSizerLvl2_2 = new wxBoxSizer(wxVERTICAL);
120  m_panelFault->SetSizer(boxSizerLvl2_2);
121 
122  m_checkBoxFault = new wxCheckBox(m_panelFault, wxID_ANY, _("Insert fault in the bus"), wxDefaultPosition, wxDLG_UNIT(m_panelFault, wxSize(-1,-1)), 0);
123  m_checkBoxFault->SetValue(false);
124 
125  boxSizerLvl2_2->Add(m_checkBoxFault, 0, wxALL|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
126 
127  wxGridSizer* gridSizerLvl3_2 = new wxGridSizer(0, 2, 0, 0);
128 
129  boxSizerLvl2_2->Add(gridSizerLvl3_2, 0, wxEXPAND, WXC_FROM_DIP(5));
130 
131  wxBoxSizer* boxSizerLvl4_3 = new wxBoxSizer(wxVERTICAL);
132 
133  gridSizerLvl3_2->Add(boxSizerLvl4_3, 0, wxEXPAND, WXC_FROM_DIP(5));
134 
135  m_staticTextFaultType = new wxStaticText(m_panelFault, wxID_ANY, _("Fault type"), wxDefaultPosition, wxDLG_UNIT(m_panelFault, wxSize(-1,-1)), 0);
136 
137  boxSizerLvl4_3->Add(m_staticTextFaultType, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
138 
139  wxArrayString m_choiceFaultTypeArr;
140  m_choiceFaultTypeArr.Add(wxT("Three-phase"));
141  m_choiceFaultTypeArr.Add(wxT("Line-to-line"));
142  m_choiceFaultTypeArr.Add(wxT("Double line-to-ground"));
143  m_choiceFaultTypeArr.Add(wxT("Line-to-ground"));
144  m_choiceFaultType = new wxChoice(m_panelFault, wxID_ANY, wxDefaultPosition, wxDLG_UNIT(m_panelFault, wxSize(-1,-1)), m_choiceFaultTypeArr, 0);
145  m_choiceFaultType->SetSelection(0);
146 
147  boxSizerLvl4_3->Add(m_choiceFaultType, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxEXPAND|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
148 
149  wxBoxSizer* boxSizerLvl4_4 = new wxBoxSizer(wxVERTICAL);
150 
151  gridSizerLvl3_2->Add(boxSizerLvl4_4, 0, wxEXPAND, WXC_FROM_DIP(5));
152 
153  m_staticTextFaultPlace = new wxStaticText(m_panelFault, wxID_ANY, _("Fault place"), wxDefaultPosition, wxDLG_UNIT(m_panelFault, wxSize(-1,-1)), 0);
154 
155  boxSizerLvl4_4->Add(m_staticTextFaultPlace, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
156 
157  wxArrayString m_choiceFaultPlaceArr;
158  m_choiceFaultPlaceArr.Add(wxT("Line A"));
159  m_choiceFaultPlaceArr.Add(wxT("Line B"));
160  m_choiceFaultPlaceArr.Add(wxT("Line C"));
161  m_choiceFaultPlace = new wxChoice(m_panelFault, wxID_ANY, wxDefaultPosition, wxDLG_UNIT(m_panelFault, wxSize(-1,-1)), m_choiceFaultPlaceArr, 0);
162  m_choiceFaultPlace->SetSelection(0);
163 
164  boxSizerLvl4_4->Add(m_choiceFaultPlace, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxEXPAND|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
165 
166  wxBoxSizer* boxSizerLvl4_5 = new wxBoxSizer(wxVERTICAL);
167 
168  gridSizerLvl3_2->Add(boxSizerLvl4_5, 0, wxEXPAND, WXC_FROM_DIP(5));
169 
170  m_staticTextFaultResistance = new wxStaticText(m_panelFault, wxID_ANY, _("Fault resistance (R)"), wxDefaultPosition, wxDLG_UNIT(m_panelFault, wxSize(-1,-1)), 0);
171 
172  boxSizerLvl4_5->Add(m_staticTextFaultResistance, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
173 
174  wxBoxSizer* boxSizerLvl5_3 = new wxBoxSizer(wxHORIZONTAL);
175 
176  boxSizerLvl4_5->Add(boxSizerLvl5_3, 0, wxEXPAND, WXC_FROM_DIP(5));
177 
178  m_textCtrlFaultResistance = new wxTextCtrl(m_panelFault, wxID_ANY, wxT(""), wxDefaultPosition, wxDLG_UNIT(m_panelFault, wxSize(-1,-1)), 0);
179  #if wxVERSION_NUMBER >= 3000
180  m_textCtrlFaultResistance->SetHint(wxT(""));
181  #endif
182 
183  boxSizerLvl5_3->Add(m_textCtrlFaultResistance, 1, wxLEFT|wxRIGHT|wxBOTTOM|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
184 
185  m_staticTextPU_1 = new wxStaticText(m_panelFault, wxID_ANY, _("p.u."), wxDefaultPosition, wxDLG_UNIT(m_panelFault, wxSize(-1,-1)), 0);
186 
187  boxSizerLvl5_3->Add(m_staticTextPU_1, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
188 
189  wxBoxSizer* boxSizerLvl4_6 = new wxBoxSizer(wxVERTICAL);
190 
191  gridSizerLvl3_2->Add(boxSizerLvl4_6, 0, wxEXPAND, WXC_FROM_DIP(5));
192 
193  m_staticTextReactance = new wxStaticText(m_panelFault, wxID_ANY, _("Fault reactance (Xl)"), wxDefaultPosition, wxDLG_UNIT(m_panelFault, wxSize(-1,-1)), 0);
194 
195  boxSizerLvl4_6->Add(m_staticTextReactance, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
196 
197  wxBoxSizer* boxSizerLvl5_4 = new wxBoxSizer(wxHORIZONTAL);
198 
199  boxSizerLvl4_6->Add(boxSizerLvl5_4, 0, wxEXPAND, WXC_FROM_DIP(5));
200 
201  m_textCtrlFaultReactance = new wxTextCtrl(m_panelFault, wxID_ANY, wxT(""), wxDefaultPosition, wxDLG_UNIT(m_panelFault, wxSize(-1,-1)), 0);
202  #if wxVERSION_NUMBER >= 3000
203  m_textCtrlFaultReactance->SetHint(wxT(""));
204  #endif
205 
206  boxSizerLvl5_4->Add(m_textCtrlFaultReactance, 1, wxLEFT|wxRIGHT|wxBOTTOM|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
207 
208  m_staticTextPU_2 = new wxStaticText(m_panelFault, wxID_ANY, _("p.u."), wxDefaultPosition, wxDLG_UNIT(m_panelFault, wxSize(-1,-1)), 0);
209 
210  boxSizerLvl5_4->Add(m_staticTextPU_2, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
211 
212  m_panelStability = new wxPanel(m_notebook, wxID_ANY, wxDefaultPosition, wxDLG_UNIT(m_notebook, wxSize(-1,-1)), wxTAB_TRAVERSAL);
213  m_notebook->AddPage(m_panelStability, _("Stability"), false);
214 
215  wxBoxSizer* boxSizerLvl2_3 = new wxBoxSizer(wxVERTICAL);
216  m_panelStability->SetSizer(boxSizerLvl2_3);
217 
218  m_checkBoxPlotData = new wxCheckBox(m_panelStability, wxID_ANY, _("Plot bus data"), wxDefaultPosition, wxDLG_UNIT(m_panelStability, wxSize(-1,-1)), 0);
219  m_checkBoxPlotData->SetValue(false);
220 
221  boxSizerLvl2_3->Add(m_checkBoxPlotData, 0, wxALL|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
222 
223  m_checkBoxStabFault = new wxCheckBox(m_panelStability, wxID_ANY, _("Insert fault in the bus"), wxDefaultPosition, wxDLG_UNIT(m_panelStability, wxSize(-1,-1)), 0);
224  m_checkBoxStabFault->SetValue(false);
225 
226  boxSizerLvl2_3->Add(m_checkBoxStabFault, 0, wxALL|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
227 
228  wxGridSizer* gridSizerLvl3_3 = new wxGridSizer(0, 2, 0, 0);
229 
230  boxSizerLvl2_3->Add(gridSizerLvl3_3, 0, wxEXPAND, WXC_FROM_DIP(5));
231 
232  wxBoxSizer* boxSizerLvl4_7 = new wxBoxSizer(wxVERTICAL);
233 
234  gridSizerLvl3_3->Add(boxSizerLvl4_7, 0, wxEXPAND, WXC_FROM_DIP(5));
235 
236  m_staticTextStabFaultTime = new wxStaticText(m_panelStability, wxID_ANY, _("Time"), wxDefaultPosition, wxDLG_UNIT(m_panelStability, wxSize(-1,-1)), 0);
237 
238  boxSizerLvl4_7->Add(m_staticTextStabFaultTime, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
239 
240  wxBoxSizer* boxSizerLvl5_5 = new wxBoxSizer(wxHORIZONTAL);
241 
242  boxSizerLvl4_7->Add(boxSizerLvl5_5, 0, wxEXPAND, WXC_FROM_DIP(5));
243 
244  m_textCtrlStabFaultTime = new wxTextCtrl(m_panelStability, wxID_ANY, wxT(""), wxDefaultPosition, wxDLG_UNIT(m_panelStability, wxSize(-1,-1)), 0);
245  #if wxVERSION_NUMBER >= 3000
246  m_textCtrlStabFaultTime->SetHint(wxT(""));
247  #endif
248 
249  boxSizerLvl5_5->Add(m_textCtrlStabFaultTime, 1, wxLEFT|wxRIGHT|wxBOTTOM|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
250 
251  m_staticTextS_1 = new wxStaticText(m_panelStability, wxID_ANY, _("s"), wxDefaultPosition, wxDLG_UNIT(m_panelStability, wxSize(-1,-1)), 0);
252 
253  boxSizerLvl5_5->Add(m_staticTextS_1, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
254 
255  wxBoxSizer* boxSizerLvl4_8 = new wxBoxSizer(wxVERTICAL);
256 
257  gridSizerLvl3_3->Add(boxSizerLvl4_8, 0, wxEXPAND, WXC_FROM_DIP(5));
258 
259  m_staticTextStabFaultLength = new wxStaticText(m_panelStability, wxID_ANY, _("Fault length"), wxDefaultPosition, wxDLG_UNIT(m_panelStability, wxSize(-1,-1)), 0);
260 
261  boxSizerLvl4_8->Add(m_staticTextStabFaultLength, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
262 
263  wxBoxSizer* boxSizerLvl5_6 = new wxBoxSizer(wxHORIZONTAL);
264 
265  boxSizerLvl4_8->Add(boxSizerLvl5_6, 0, wxEXPAND, WXC_FROM_DIP(5));
266 
267  m_textCtrlStabFaultLength = new wxTextCtrl(m_panelStability, wxID_ANY, wxT(""), wxDefaultPosition, wxDLG_UNIT(m_panelStability, wxSize(-1,-1)), 0);
268  #if wxVERSION_NUMBER >= 3000
269  m_textCtrlStabFaultLength->SetHint(wxT(""));
270  #endif
271 
272  boxSizerLvl5_6->Add(m_textCtrlStabFaultLength, 1, wxLEFT|wxRIGHT|wxBOTTOM|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
273 
274  m_staticTextS_2 = new wxStaticText(m_panelStability, wxID_ANY, _("s"), wxDefaultPosition, wxDLG_UNIT(m_panelStability, wxSize(-1,-1)), 0);
275 
276  boxSizerLvl5_6->Add(m_staticTextS_2, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
277 
278  wxBoxSizer* boxSizerLvl4_9 = new wxBoxSizer(wxVERTICAL);
279 
280  gridSizerLvl3_3->Add(boxSizerLvl4_9, 0, wxEXPAND, WXC_FROM_DIP(5));
281 
282  m_staticTextStabFaultResistance = new wxStaticText(m_panelStability, wxID_ANY, _("Fault resistance (R)"), wxDefaultPosition, wxDLG_UNIT(m_panelStability, wxSize(-1,-1)), 0);
283 
284  boxSizerLvl4_9->Add(m_staticTextStabFaultResistance, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
285 
286  wxBoxSizer* boxSizerLvl5_7 = new wxBoxSizer(wxHORIZONTAL);
287 
288  boxSizerLvl4_9->Add(boxSizerLvl5_7, 0, wxEXPAND, WXC_FROM_DIP(5));
289 
290  m_textCtrlStabFaultResistance = new wxTextCtrl(m_panelStability, wxID_ANY, wxT(""), wxDefaultPosition, wxDLG_UNIT(m_panelStability, wxSize(-1,-1)), 0);
291  #if wxVERSION_NUMBER >= 3000
292  m_textCtrlStabFaultResistance->SetHint(wxT(""));
293  #endif
294 
295  boxSizerLvl5_7->Add(m_textCtrlStabFaultResistance, 1, wxLEFT|wxRIGHT|wxBOTTOM|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
296 
297  m_staticTextPU_3 = new wxStaticText(m_panelStability, wxID_ANY, _("p.u."), wxDefaultPosition, wxDLG_UNIT(m_panelStability, wxSize(-1,-1)), 0);
298 
299  boxSizerLvl5_7->Add(m_staticTextPU_3, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
300 
301  wxBoxSizer* boxSizerLvl4_10 = new wxBoxSizer(wxVERTICAL);
302 
303  gridSizerLvl3_3->Add(boxSizerLvl4_10, 0, wxEXPAND, WXC_FROM_DIP(5));
304 
305  m_staticTextStabFaultReactance = new wxStaticText(m_panelStability, wxID_ANY, _("Fault reactance (Xl)"), wxDefaultPosition, wxDLG_UNIT(m_panelStability, wxSize(-1,-1)), 0);
306 
307  boxSizerLvl4_10->Add(m_staticTextStabFaultReactance, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
308 
309  wxBoxSizer* boxSizerLvl5_8 = new wxBoxSizer(wxHORIZONTAL);
310 
311  boxSizerLvl4_10->Add(boxSizerLvl5_8, 0, wxEXPAND, WXC_FROM_DIP(5));
312 
313  m_textCtrlStabFaultReactance = new wxTextCtrl(m_panelStability, wxID_ANY, wxT(""), wxDefaultPosition, wxDLG_UNIT(m_panelStability, wxSize(-1,-1)), 0);
314  #if wxVERSION_NUMBER >= 3000
315  m_textCtrlStabFaultReactance->SetHint(wxT(""));
316  #endif
317 
318  boxSizerLvl5_8->Add(m_textCtrlStabFaultReactance, 1, wxLEFT|wxRIGHT|wxBOTTOM|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
319 
320  m_staticTextPU_4 = new wxStaticText(m_panelStability, wxID_ANY, _("p.u."), wxDefaultPosition, wxDLG_UNIT(m_panelStability, wxSize(-1,-1)), 0);
321 
322  boxSizerLvl5_8->Add(m_staticTextPU_4, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
323 
324  wxBoxSizer* boxSizerOkCancel = new wxBoxSizer(wxHORIZONTAL);
325 
326  boxSizerLvl1_1->Add(boxSizerOkCancel, 0, wxALL|wxALIGN_RIGHT, WXC_FROM_DIP(5));
327 
328  m_buttonOK = new wxButton(this, wxID_ANY, _("OK"), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
329 
330  boxSizerOkCancel->Add(m_buttonOK, 0, wxALL|wxALIGN_RIGHT, WXC_FROM_DIP(5));
331 
332  m_ButtonCancel = new wxButton(this, wxID_ANY, _("Cancel"), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
333 
334  boxSizerOkCancel->Add(m_ButtonCancel, 0, wxALL|wxALIGN_RIGHT, WXC_FROM_DIP(5));
335 
336 
337  #if wxVERSION_NUMBER >= 2900
338  if(!wxPersistenceManager::Get().Find(m_notebook)){
339  wxPersistenceManager::Get().RegisterAndRestore(m_notebook);
340  } else {
341  wxPersistenceManager::Get().Restore(m_notebook);
342  }
343  #endif
344 
345  SetName(wxT("BusFormBase"));
346  SetSize(-1,-1);
347  if (GetSizer()) {
348  GetSizer()->Fit(this);
349  }
350  if(GetParent()) {
351  CentreOnParent(wxVERTICAL);
352  } else {
353  CentreOnScreen(wxVERTICAL);
354  }
355 #if wxVERSION_NUMBER >= 2900
356  if(!wxPersistenceManager::Get().Find(this)) {
357  wxPersistenceManager::Get().RegisterAndRestore(this);
358  } else {
359  wxPersistenceManager::Get().Restore(this);
360  }
361 #endif
362  // Connect events
363  m_choiceNomVoltage->Connect(wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler(BusFormBase::OnNominalVoltageChoice), NULL, this);
364  m_checkBoxCtrlVoltage->Connect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler(BusFormBase::OnControlledVoltageClick), NULL, this);
365  m_checkBoxFault->Connect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler(BusFormBase::OnInsertFaultClick), NULL, this);
366  m_choiceFaultType->Connect(wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler(BusFormBase::OnFaultTypeChoice), NULL, this);
367  m_checkBoxStabFault->Connect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler(BusFormBase::OnInsertStabFaultClick), NULL, this);
368  m_buttonOK->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(BusFormBase::OnButtonOKClick), NULL, this);
369  m_ButtonCancel->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(BusFormBase::OnButtonCancelClick), NULL, this);
370 
371 }
372 
373 BusFormBase::~BusFormBase()
374 {
375  m_choiceNomVoltage->Disconnect(wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler(BusFormBase::OnNominalVoltageChoice), NULL, this);
376  m_checkBoxCtrlVoltage->Disconnect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler(BusFormBase::OnControlledVoltageClick), NULL, this);
377  m_checkBoxFault->Disconnect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler(BusFormBase::OnInsertFaultClick), NULL, this);
378  m_choiceFaultType->Disconnect(wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler(BusFormBase::OnFaultTypeChoice), NULL, this);
379  m_checkBoxStabFault->Disconnect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler(BusFormBase::OnInsertStabFaultClick), NULL, this);
380  m_buttonOK->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(BusFormBase::OnButtonOKClick), NULL, this);
381  m_ButtonCancel->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(BusFormBase::OnButtonCancelClick), NULL, this);
382 
383 }
384 
385 SyncMachineFormBase::SyncMachineFormBase(wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style)
386  : wxDialog(parent, id, title, pos, size, style)
387 {
388  if ( !bBitmapLoaded ) {
389  // We need to initialise the default bitmap handler
390  wxXmlResource::Get()->AddHandler(new wxBitmapXmlHandler);
391  wxC9EE9InitBitmapResources();
392  bBitmapLoaded = true;
393  }
394 
395  wxBoxSizer* boxSizerLvl1_1 = new wxBoxSizer(wxVERTICAL);
396  this->SetSizer(boxSizerLvl1_1);
397 
398  m_notebook = new wxNotebook(this, wxID_ANY, wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), wxBK_DEFAULT);
399  m_notebook->SetName(wxT("m_notebook"));
400 
401  boxSizerLvl1_1->Add(m_notebook, 1, wxEXPAND, WXC_FROM_DIP(5));
402 
403  m_panelGeneral = new wxPanel(m_notebook, wxID_ANY, wxDefaultPosition, wxDLG_UNIT(m_notebook, wxSize(-1,-1)), wxTAB_TRAVERSAL);
404  m_notebook->AddPage(m_panelGeneral, _("General"), false);
405 
406  wxBoxSizer* boxSizerLvl2_1 = new wxBoxSizer(wxVERTICAL);
407  m_panelGeneral->SetSizer(boxSizerLvl2_1);
408 
409  m_staticTextName = new wxStaticText(m_panelGeneral, wxID_ANY, _("Name"), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
410 
411  boxSizerLvl2_1->Add(m_staticTextName, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
412 
413  m_textCtrlName = new wxTextCtrl(m_panelGeneral, wxID_ANY, wxT(""), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
414  #if wxVERSION_NUMBER >= 3000
415  m_textCtrlName->SetHint(wxT(""));
416  #endif
417 
418  boxSizerLvl2_1->Add(m_textCtrlName, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxEXPAND|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
419  m_textCtrlName->SetMinSize(wxSize(300,-1));
420 
421  wxGridSizer* gridSizerLvl3_1 = new wxGridSizer(0, 2, 0, 0);
422 
423  boxSizerLvl2_1->Add(gridSizerLvl3_1, 0, wxEXPAND, WXC_FROM_DIP(5));
424 
425  wxBoxSizer* boxSizerLvl4_5 = new wxBoxSizer(wxVERTICAL);
426 
427  gridSizerLvl3_1->Add(boxSizerLvl4_5, 0, wxEXPAND, WXC_FROM_DIP(5));
428 
429  m_staticTextNominalPower = new wxStaticText(m_panelGeneral, wxID_ANY, _("Rated power"), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
430 
431  boxSizerLvl4_5->Add(m_staticTextNominalPower, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
432 
433  wxBoxSizer* boxSizerLvl5_5 = new wxBoxSizer(wxHORIZONTAL);
434 
435  boxSizerLvl4_5->Add(boxSizerLvl5_5, 0, wxEXPAND, WXC_FROM_DIP(5));
436 
437  m_textCtrlnominalPower = new wxTextCtrl(m_panelGeneral, wxID_ANY, wxT(""), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
438  #if wxVERSION_NUMBER >= 3000
439  m_textCtrlnominalPower->SetHint(wxT(""));
440  #endif
441 
442  boxSizerLvl5_5->Add(m_textCtrlnominalPower, 1, wxLEFT|wxRIGHT|wxBOTTOM|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
443 
444  wxArrayString m_choiceNominalPowerArr;
445  m_choiceNominalPowerArr.Add(wxT("VA"));
446  m_choiceNominalPowerArr.Add(wxT("kVA"));
447  m_choiceNominalPowerArr.Add(wxT("MVA"));
448  m_choiceNominalPower = new wxChoice(m_panelGeneral, wxID_ANY, wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), m_choiceNominalPowerArr, 0);
449  m_choiceNominalPower->SetSelection(2);
450 
451  boxSizerLvl5_5->Add(m_choiceNominalPower, 0, wxLEFT|wxRIGHT|wxBOTTOM, WXC_FROM_DIP(5));
452 
453  gridSizerLvl3_1->Add(0, 0, 1, wxALL|wxEXPAND, WXC_FROM_DIP(5));
454 
455  wxBoxSizer* boxSizerLvl4_1 = new wxBoxSizer(wxVERTICAL);
456 
457  gridSizerLvl3_1->Add(boxSizerLvl4_1, 0, wxEXPAND, WXC_FROM_DIP(5));
458 
459  m_staticTextActivePower = new wxStaticText(m_panelGeneral, wxID_ANY, _("Active power"), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
460 
461  boxSizerLvl4_1->Add(m_staticTextActivePower, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
462 
463  wxBoxSizer* boxSizerLvl5_1 = new wxBoxSizer(wxHORIZONTAL);
464 
465  boxSizerLvl4_1->Add(boxSizerLvl5_1, 0, wxEXPAND, WXC_FROM_DIP(5));
466 
467  m_textCtrlActivePower = new wxTextCtrl(m_panelGeneral, wxID_ANY, wxT(""), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
468  #if wxVERSION_NUMBER >= 3000
469  m_textCtrlActivePower->SetHint(wxT(""));
470  #endif
471 
472  boxSizerLvl5_1->Add(m_textCtrlActivePower, 1, wxLEFT|wxRIGHT|wxBOTTOM|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
473 
474  wxArrayString m_choiceActivePowerArr;
475  m_choiceActivePowerArr.Add(wxT("p.u."));
476  m_choiceActivePowerArr.Add(wxT("W"));
477  m_choiceActivePowerArr.Add(wxT("kW"));
478  m_choiceActivePowerArr.Add(wxT("MW"));
479  m_choiceActivePower = new wxChoice(m_panelGeneral, wxID_ANY, wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), m_choiceActivePowerArr, 0);
480  m_choiceActivePower->SetSelection(3);
481 
482  boxSizerLvl5_1->Add(m_choiceActivePower, 0, wxLEFT|wxRIGHT|wxBOTTOM, WXC_FROM_DIP(5));
483 
484  wxBoxSizer* boxSizerLvl4_2 = new wxBoxSizer(wxVERTICAL);
485 
486  gridSizerLvl3_1->Add(boxSizerLvl4_2, 0, wxEXPAND, WXC_FROM_DIP(5));
487 
488  m_staticTextReactivePower = new wxStaticText(m_panelGeneral, wxID_ANY, _("Reactive power"), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
489 
490  boxSizerLvl4_2->Add(m_staticTextReactivePower, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
491 
492  wxBoxSizer* boxSizerLvl5_2 = new wxBoxSizer(wxHORIZONTAL);
493 
494  boxSizerLvl4_2->Add(boxSizerLvl5_2, 0, wxEXPAND, WXC_FROM_DIP(5));
495 
496  m_textCtrlReactivePower = new wxTextCtrl(m_panelGeneral, wxID_ANY, wxT(""), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
497  #if wxVERSION_NUMBER >= 3000
498  m_textCtrlReactivePower->SetHint(wxT(""));
499  #endif
500 
501  boxSizerLvl5_2->Add(m_textCtrlReactivePower, 1, wxLEFT|wxRIGHT|wxBOTTOM|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
502 
503  wxArrayString m_choiceReactivePowerArr;
504  m_choiceReactivePowerArr.Add(wxT("p.u."));
505  m_choiceReactivePowerArr.Add(wxT("VAr"));
506  m_choiceReactivePowerArr.Add(wxT("kVAr"));
507  m_choiceReactivePowerArr.Add(wxT("MVAr"));
508  m_choiceReactivePower = new wxChoice(m_panelGeneral, wxID_ANY, wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), m_choiceReactivePowerArr, 0);
509  m_choiceReactivePower->SetSelection(3);
510 
511  boxSizerLvl5_2->Add(m_choiceReactivePower, 0, wxLEFT|wxRIGHT|wxBOTTOM, WXC_FROM_DIP(5));
512 
513  wxBoxSizer* boxSizerLvl4_3 = new wxBoxSizer(wxVERTICAL);
514 
515  gridSizerLvl3_1->Add(boxSizerLvl4_3, 0, wxEXPAND, WXC_FROM_DIP(5));
516 
517  m_checkBoxMaxReactive = new wxCheckBox(m_panelGeneral, wxID_ANY, _("Max reactive power"), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
518  m_checkBoxMaxReactive->SetValue(false);
519 
520  boxSizerLvl4_3->Add(m_checkBoxMaxReactive, 0, wxALL, WXC_FROM_DIP(5));
521 
522  wxBoxSizer* boxSizerLvl5_3 = new wxBoxSizer(wxHORIZONTAL);
523 
524  boxSizerLvl4_3->Add(boxSizerLvl5_3, 0, wxEXPAND, WXC_FROM_DIP(5));
525 
526  m_textCtrlMaxRectivePower = new wxTextCtrl(m_panelGeneral, wxID_ANY, wxT(""), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
527  #if wxVERSION_NUMBER >= 3000
528  m_textCtrlMaxRectivePower->SetHint(wxT(""));
529  #endif
530 
531  boxSizerLvl5_3->Add(m_textCtrlMaxRectivePower, 1, wxLEFT|wxRIGHT|wxBOTTOM|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
532 
533  wxArrayString m_choiceMaxRectivePowerArr;
534  m_choiceMaxRectivePowerArr.Add(wxT("p.u."));
535  m_choiceMaxRectivePowerArr.Add(wxT("VAr"));
536  m_choiceMaxRectivePowerArr.Add(wxT("kVAr"));
537  m_choiceMaxRectivePowerArr.Add(wxT("MVAr"));
538  m_choiceMaxRectivePower = new wxChoice(m_panelGeneral, wxID_ANY, wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), m_choiceMaxRectivePowerArr, 0);
539  m_choiceMaxRectivePower->SetSelection(3);
540 
541  boxSizerLvl5_3->Add(m_choiceMaxRectivePower, 0, wxLEFT|wxRIGHT|wxBOTTOM, WXC_FROM_DIP(5));
542 
543  wxBoxSizer* boxSizerLvl4_4 = new wxBoxSizer(wxVERTICAL);
544 
545  gridSizerLvl3_1->Add(boxSizerLvl4_4, 0, wxEXPAND, WXC_FROM_DIP(5));
546 
547  m_checkBoxMinReactive = new wxCheckBox(m_panelGeneral, wxID_ANY, _("Min reactive power"), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
548  m_checkBoxMinReactive->SetValue(false);
549 
550  boxSizerLvl4_4->Add(m_checkBoxMinReactive, 0, wxALL, WXC_FROM_DIP(5));
551 
552  wxBoxSizer* boxSizerLvl5_4 = new wxBoxSizer(wxHORIZONTAL);
553 
554  boxSizerLvl4_4->Add(boxSizerLvl5_4, 0, wxEXPAND, WXC_FROM_DIP(5));
555 
556  m_textCtrlMinRectivePower = new wxTextCtrl(m_panelGeneral, wxID_ANY, wxT(""), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
557  #if wxVERSION_NUMBER >= 3000
558  m_textCtrlMinRectivePower->SetHint(wxT(""));
559  #endif
560 
561  boxSizerLvl5_4->Add(m_textCtrlMinRectivePower, 1, wxLEFT|wxRIGHT|wxBOTTOM|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
562 
563  wxArrayString m_choiceMinRectivePowerArr;
564  m_choiceMinRectivePowerArr.Add(wxT("p.u."));
565  m_choiceMinRectivePowerArr.Add(wxT("VAr"));
566  m_choiceMinRectivePowerArr.Add(wxT("kVAr"));
567  m_choiceMinRectivePowerArr.Add(wxT("MVAr"));
568  m_choiceMinRectivePower = new wxChoice(m_panelGeneral, wxID_ANY, wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), m_choiceMinRectivePowerArr, 0);
569  m_choiceMinRectivePower->SetSelection(3);
570 
571  boxSizerLvl5_4->Add(m_choiceMinRectivePower, 0, wxLEFT|wxRIGHT|wxBOTTOM, WXC_FROM_DIP(5));
572 
573  m_checkBoxUseMachinePower = new wxCheckBox(m_panelGeneral, wxID_ANY, _("Use machine rated power as base"), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
574  m_checkBoxUseMachinePower->SetValue(false);
575 
576  boxSizerLvl2_1->Add(m_checkBoxUseMachinePower, 0, wxALL|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
577 
578  m_panelFault = new wxPanel(m_notebook, wxID_ANY, wxDefaultPosition, wxDLG_UNIT(m_notebook, wxSize(-1,-1)), wxTAB_TRAVERSAL);
579  m_notebook->AddPage(m_panelFault, _("Fault"), false);
580 
581  wxBoxSizer* boxSizerLvl2_2 = new wxBoxSizer(wxVERTICAL);
582  m_panelFault->SetSizer(boxSizerLvl2_2);
583 
584  wxStaticBoxSizer* staticBoxSizerLvl3_1 = new wxStaticBoxSizer( new wxStaticBox(m_panelFault, wxID_ANY, _("Sequence impedances (p.u.)")), wxVERTICAL);
585 
586  boxSizerLvl2_2->Add(staticBoxSizerLvl3_1, 0, wxALL|wxEXPAND, WXC_FROM_DIP(5));
587 
588  wxGridSizer* gridSizerLvl4_2 = new wxGridSizer(0, 2, 0, 0);
589 
590  staticBoxSizerLvl3_1->Add(gridSizerLvl4_2, 0, wxEXPAND, WXC_FROM_DIP(5));
591 
592  wxBoxSizer* boxSizerLvl5_6 = new wxBoxSizer(wxVERTICAL);
593 
594  gridSizerLvl4_2->Add(boxSizerLvl5_6, 0, wxEXPAND, WXC_FROM_DIP(5));
595 
596  m_staticTextPosResistance = new wxStaticText(m_panelFault, wxID_ANY, _("Positive resistance (R1)"), wxDefaultPosition, wxDLG_UNIT(m_panelFault, wxSize(-1,-1)), 0);
597 
598  boxSizerLvl5_6->Add(m_staticTextPosResistance, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
599 
600  m_textCtrlPosResistance = new wxTextCtrl(m_panelFault, wxID_ANY, wxT(""), wxDefaultPosition, wxDLG_UNIT(m_panelFault, wxSize(-1,-1)), 0);
601  #if wxVERSION_NUMBER >= 3000
602  m_textCtrlPosResistance->SetHint(wxT(""));
603  #endif
604 
605  boxSizerLvl5_6->Add(m_textCtrlPosResistance, 1, wxLEFT|wxRIGHT|wxBOTTOM|wxEXPAND|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
606 
607  wxBoxSizer* boxSizerLvl5_7 = new wxBoxSizer(wxVERTICAL);
608 
609  gridSizerLvl4_2->Add(boxSizerLvl5_7, 0, wxEXPAND, WXC_FROM_DIP(5));
610 
611  m_staticTextPosReactance = new wxStaticText(m_panelFault, wxID_ANY, _("Positive reactance (X1)"), wxDefaultPosition, wxDLG_UNIT(m_panelFault, wxSize(-1,-1)), 0);
612 
613  boxSizerLvl5_7->Add(m_staticTextPosReactance, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
614 
615  m_textCtrlPosReactance = new wxTextCtrl(m_panelFault, wxID_ANY, wxT(""), wxDefaultPosition, wxDLG_UNIT(m_panelFault, wxSize(-1,-1)), 0);
616  #if wxVERSION_NUMBER >= 3000
617  m_textCtrlPosReactance->SetHint(wxT(""));
618  #endif
619 
620  boxSizerLvl5_7->Add(m_textCtrlPosReactance, 1, wxLEFT|wxRIGHT|wxBOTTOM|wxEXPAND|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
621 
622  wxBoxSizer* boxSizerLvl5_8 = new wxBoxSizer(wxVERTICAL);
623 
624  gridSizerLvl4_2->Add(boxSizerLvl5_8, 0, wxEXPAND, WXC_FROM_DIP(5));
625 
626  m_staticTextNegResistance = new wxStaticText(m_panelFault, wxID_ANY, _("Negative resistance (R2)"), wxDefaultPosition, wxDLG_UNIT(m_panelFault, wxSize(-1,-1)), 0);
627 
628  boxSizerLvl5_8->Add(m_staticTextNegResistance, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
629 
630  m_textCtrlNegResistance = new wxTextCtrl(m_panelFault, wxID_ANY, wxT(""), wxDefaultPosition, wxDLG_UNIT(m_panelFault, wxSize(-1,-1)), 0);
631  #if wxVERSION_NUMBER >= 3000
632  m_textCtrlNegResistance->SetHint(wxT(""));
633  #endif
634 
635  boxSizerLvl5_8->Add(m_textCtrlNegResistance, 1, wxLEFT|wxRIGHT|wxBOTTOM|wxEXPAND|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
636 
637  wxBoxSizer* boxSizerLvl5_9 = new wxBoxSizer(wxVERTICAL);
638 
639  gridSizerLvl4_2->Add(boxSizerLvl5_9, 0, wxEXPAND, WXC_FROM_DIP(5));
640 
641  m_staticTextNegReactance = new wxStaticText(m_panelFault, wxID_ANY, _("Negative reactance (X2)"), wxDefaultPosition, wxDLG_UNIT(m_panelFault, wxSize(-1,-1)), 0);
642 
643  boxSizerLvl5_9->Add(m_staticTextNegReactance, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
644 
645  m_textCtrlNegReactance = new wxTextCtrl(m_panelFault, wxID_ANY, wxT(""), wxDefaultPosition, wxDLG_UNIT(m_panelFault, wxSize(-1,-1)), 0);
646  #if wxVERSION_NUMBER >= 3000
647  m_textCtrlNegReactance->SetHint(wxT(""));
648  #endif
649 
650  boxSizerLvl5_9->Add(m_textCtrlNegReactance, 1, wxLEFT|wxRIGHT|wxBOTTOM|wxEXPAND|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
651 
652  wxBoxSizer* boxSizerLvl5_10 = new wxBoxSizer(wxVERTICAL);
653 
654  gridSizerLvl4_2->Add(boxSizerLvl5_10, 0, wxEXPAND, WXC_FROM_DIP(5));
655 
656  m_staticTextZeroResistance = new wxStaticText(m_panelFault, wxID_ANY, _("Zero resistance (R0)"), wxDefaultPosition, wxDLG_UNIT(m_panelFault, wxSize(-1,-1)), 0);
657 
658  boxSizerLvl5_10->Add(m_staticTextZeroResistance, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
659 
660  m_textCtrlZeroResistance = new wxTextCtrl(m_panelFault, wxID_ANY, wxT(""), wxDefaultPosition, wxDLG_UNIT(m_panelFault, wxSize(-1,-1)), 0);
661  #if wxVERSION_NUMBER >= 3000
662  m_textCtrlZeroResistance->SetHint(wxT(""));
663  #endif
664 
665  boxSizerLvl5_10->Add(m_textCtrlZeroResistance, 1, wxLEFT|wxRIGHT|wxBOTTOM|wxEXPAND|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
666 
667  wxBoxSizer* boxSizerLvl5_11 = new wxBoxSizer(wxVERTICAL);
668 
669  gridSizerLvl4_2->Add(boxSizerLvl5_11, 0, wxEXPAND, WXC_FROM_DIP(5));
670 
671  m_staticTextZeroReactance = new wxStaticText(m_panelFault, wxID_ANY, _("Zero reactance (X0)"), wxDefaultPosition, wxDLG_UNIT(m_panelFault, wxSize(-1,-1)), 0);
672 
673  boxSizerLvl5_11->Add(m_staticTextZeroReactance, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
674 
675  m_textCtrlZeroReactance = new wxTextCtrl(m_panelFault, wxID_ANY, wxT(""), wxDefaultPosition, wxDLG_UNIT(m_panelFault, wxSize(-1,-1)), 0);
676  #if wxVERSION_NUMBER >= 3000
677  m_textCtrlZeroReactance->SetHint(wxT(""));
678  #endif
679 
680  boxSizerLvl5_11->Add(m_textCtrlZeroReactance, 1, wxLEFT|wxRIGHT|wxBOTTOM|wxEXPAND|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
681 
682  wxGridSizer* gridSizerLvl3_3 = new wxGridSizer(0, 2, 0, 0);
683 
684  boxSizerLvl2_2->Add(gridSizerLvl3_3, 0, wxEXPAND, WXC_FROM_DIP(5));
685 
686  wxBoxSizer* boxSizerLvl4_12 = new wxBoxSizer(wxVERTICAL);
687 
688  gridSizerLvl3_3->Add(boxSizerLvl4_12, 0, wxEXPAND, WXC_FROM_DIP(5));
689 
690  m_staticTextGrdResistance = new wxStaticText(m_panelFault, wxID_ANY, _("Ground resistance (p.u.)"), wxDefaultPosition, wxDLG_UNIT(m_panelFault, wxSize(-1,-1)), 0);
691 
692  boxSizerLvl4_12->Add(m_staticTextGrdResistance, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
693 
694  m_textCtrlGrdResistance = new wxTextCtrl(m_panelFault, wxID_ANY, wxT(""), wxDefaultPosition, wxDLG_UNIT(m_panelFault, wxSize(-1,-1)), 0);
695  #if wxVERSION_NUMBER >= 3000
696  m_textCtrlGrdResistance->SetHint(wxT(""));
697  #endif
698 
699  boxSizerLvl4_12->Add(m_textCtrlGrdResistance, 1, wxLEFT|wxRIGHT|wxBOTTOM|wxEXPAND|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
700 
701  wxBoxSizer* boxSizerLvl4_13 = new wxBoxSizer(wxVERTICAL);
702 
703  gridSizerLvl3_3->Add(boxSizerLvl4_13, 0, wxEXPAND, WXC_FROM_DIP(5));
704 
705  m_staticTextGrdReactance = new wxStaticText(m_panelFault, wxID_ANY, _("Ground reactance (p.u.)"), wxDefaultPosition, wxDLG_UNIT(m_panelFault, wxSize(-1,-1)), 0);
706 
707  boxSizerLvl4_13->Add(m_staticTextGrdReactance, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
708 
709  m_textCtrlGrdReactance = new wxTextCtrl(m_panelFault, wxID_ANY, wxT(""), wxDefaultPosition, wxDLG_UNIT(m_panelFault, wxSize(-1,-1)), 0);
710  #if wxVERSION_NUMBER >= 3000
711  m_textCtrlGrdReactance->SetHint(wxT(""));
712  #endif
713 
714  boxSizerLvl4_13->Add(m_textCtrlGrdReactance, 1, wxLEFT|wxRIGHT|wxBOTTOM|wxEXPAND|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
715 
716  m_checkBoxGroundNeutral = new wxCheckBox(m_panelFault, wxID_ANY, _("Grounded neutral"), wxDefaultPosition, wxDLG_UNIT(m_panelFault, wxSize(-1,-1)), 0);
717  m_checkBoxGroundNeutral->SetValue(true);
718 
719  boxSizerLvl2_2->Add(m_checkBoxGroundNeutral, 0, wxALL, WXC_FROM_DIP(5));
720 
721  wxBoxSizer* boxSizerBottomButtons = new wxBoxSizer(wxHORIZONTAL);
722 
723  boxSizerLvl1_1->Add(boxSizerBottomButtons, 0, wxALL|wxEXPAND, WXC_FROM_DIP(5));
724 
725  m_buttonStab = new wxButton(this, wxID_ANY, _("Stability"), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
726 
727  boxSizerBottomButtons->Add(m_buttonStab, 0, wxALL|wxALIGN_LEFT, WXC_FROM_DIP(5));
728 
729  boxSizerBottomButtons->Add(0, 0, 1, wxALL|wxEXPAND, WXC_FROM_DIP(5));
730 
731  m_buttonOK = new wxButton(this, wxID_ANY, _("OK"), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
732 
733  boxSizerBottomButtons->Add(m_buttonOK, 0, wxALL|wxALIGN_RIGHT, WXC_FROM_DIP(5));
734 
735  m_ButtonCancel = new wxButton(this, wxID_ANY, _("Cancel"), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
736 
737  boxSizerBottomButtons->Add(m_ButtonCancel, 0, wxALL|wxALIGN_RIGHT, WXC_FROM_DIP(5));
738 
739 
740  #if wxVERSION_NUMBER >= 2900
741  if(!wxPersistenceManager::Get().Find(m_notebook)){
742  wxPersistenceManager::Get().RegisterAndRestore(m_notebook);
743  } else {
744  wxPersistenceManager::Get().Restore(m_notebook);
745  }
746  #endif
747 
748  SetName(wxT("SyncMachineFormBase"));
749  SetSize(-1,-1);
750  if (GetSizer()) {
751  GetSizer()->Fit(this);
752  }
753  if(GetParent()) {
754  CentreOnParent(wxBOTH);
755  } else {
756  CentreOnScreen(wxBOTH);
757  }
758 #if wxVERSION_NUMBER >= 2900
759  if(!wxPersistenceManager::Get().Find(this)) {
760  wxPersistenceManager::Get().RegisterAndRestore(this);
761  } else {
762  wxPersistenceManager::Get().Restore(this);
763  }
764 #endif
765  // Connect events
766  m_checkBoxMaxReactive->Connect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler(SyncMachineFormBase::OnCheckMaxReactive), NULL, this);
767  m_checkBoxMinReactive->Connect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler(SyncMachineFormBase::OnCheckMinReactive), NULL, this);
768  m_buttonStab->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(SyncMachineFormBase::OnStabilityButtonClick), NULL, this);
769  m_buttonOK->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(SyncMachineFormBase::OnOKButtonClick), NULL, this);
770  m_ButtonCancel->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(SyncMachineFormBase::OnCancelButtonClick), NULL, this);
771 
772 }
773 
774 SyncMachineFormBase::~SyncMachineFormBase()
775 {
776  m_checkBoxMaxReactive->Disconnect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler(SyncMachineFormBase::OnCheckMaxReactive), NULL, this);
777  m_checkBoxMinReactive->Disconnect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler(SyncMachineFormBase::OnCheckMinReactive), NULL, this);
778  m_buttonStab->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(SyncMachineFormBase::OnStabilityButtonClick), NULL, this);
779  m_buttonOK->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(SyncMachineFormBase::OnOKButtonClick), NULL, this);
780  m_ButtonCancel->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(SyncMachineFormBase::OnCancelButtonClick), NULL, this);
781 
782 }
783 
784 GeneratorStabFormBase::GeneratorStabFormBase(wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style)
785  : wxDialog(parent, id, title, pos, size, style)
786 {
787  if ( !bBitmapLoaded ) {
788  // We need to initialise the default bitmap handler
789  wxXmlResource::Get()->AddHandler(new wxBitmapXmlHandler);
790  wxC9EE9InitBitmapResources();
791  bBitmapLoaded = true;
792  }
793 
794  wxBoxSizer* boxSizerLvl1_1 = new wxBoxSizer(wxVERTICAL);
795  this->SetSizer(boxSizerLvl1_1);
796 
797  wxBoxSizer* boxSizerLvl2_1 = new wxBoxSizer(wxVERTICAL);
798 
799  boxSizerLvl1_1->Add(boxSizerLvl2_1, 1, wxALL|wxEXPAND, WXC_FROM_DIP(5));
800 
801  m_checkBoxPlotSyncMachine = new wxCheckBox(this, wxID_ANY, _("Plot synchronous machine data"), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
802  m_checkBoxPlotSyncMachine->SetValue(false);
803 
804  boxSizerLvl2_1->Add(m_checkBoxPlotSyncMachine, 0, wxALL|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
805 
806  wxGridSizer* gridSizerLvl3_1 = new wxGridSizer(0, 2, 0, 0);
807 
808  boxSizerLvl2_1->Add(gridSizerLvl3_1, 0, wxEXPAND, WXC_FROM_DIP(5));
809 
810  wxBoxSizer* boxSizerLvl4_1 = new wxBoxSizer(wxVERTICAL);
811 
812  gridSizerLvl3_1->Add(boxSizerLvl4_1, 0, wxEXPAND, WXC_FROM_DIP(5));
813 
814  m_staticTextInertia = new wxStaticText(this, wxID_ANY, _("Inertia (H)"), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
815 
816  boxSizerLvl4_1->Add(m_staticTextInertia, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
817 
818  wxBoxSizer* boxSizerLvl5_1 = new wxBoxSizer(wxHORIZONTAL);
819 
820  boxSizerLvl4_1->Add(boxSizerLvl5_1, 0, wxEXPAND, WXC_FROM_DIP(5));
821 
822  m_textCtrlInertia = new wxTextCtrl(this, wxID_ANY, wxT(""), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
823  #if wxVERSION_NUMBER >= 3000
824  m_textCtrlInertia->SetHint(wxT(""));
825  #endif
826 
827  boxSizerLvl5_1->Add(m_textCtrlInertia, 1, wxLEFT|wxRIGHT|wxBOTTOM|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
828 
829  m_staticTextS_1 = new wxStaticText(this, wxID_ANY, _("s"), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
830 
831  boxSizerLvl5_1->Add(m_staticTextS_1, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
832 
833  wxBoxSizer* boxSizerLvl4_2 = new wxBoxSizer(wxVERTICAL);
834 
835  gridSizerLvl3_1->Add(boxSizerLvl4_2, 0, wxEXPAND, WXC_FROM_DIP(5));
836 
837  m_staticTextDamping = new wxStaticText(this, wxID_ANY, _("Damping factor"), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
838 
839  boxSizerLvl4_2->Add(m_staticTextDamping, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
840 
841  wxBoxSizer* boxSizerLvl5_2 = new wxBoxSizer(wxHORIZONTAL);
842 
843  boxSizerLvl4_2->Add(boxSizerLvl5_2, 0, wxEXPAND, WXC_FROM_DIP(5));
844 
845  m_textCtrlDamping = new wxTextCtrl(this, wxID_ANY, wxT(""), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
846  #if wxVERSION_NUMBER >= 3000
847  m_textCtrlDamping->SetHint(wxT(""));
848  #endif
849 
850  boxSizerLvl5_2->Add(m_textCtrlDamping, 1, wxLEFT|wxRIGHT|wxBOTTOM|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
851 
852  m_staticTextPU_1 = new wxStaticText(this, wxID_ANY, _("p.u."), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
853 
854  boxSizerLvl5_2->Add(m_staticTextPU_1, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
855 
856  wxBoxSizer* boxSizerLvl4_3 = new wxBoxSizer(wxVERTICAL);
857 
858  gridSizerLvl3_1->Add(boxSizerLvl4_3, 0, wxEXPAND, WXC_FROM_DIP(5));
859 
860  m_checkBoxUseAVR = new wxCheckBox(this, wxID_ANY, _("Use AVR"), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
861  m_checkBoxUseAVR->SetValue(false);
862 
863  boxSizerLvl4_3->Add(m_checkBoxUseAVR, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
864 
865  m_buttonEditAVR = new wxButton(this, wxID_ANY, _("Edit AVR"), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
866 
867  boxSizerLvl4_3->Add(m_buttonEditAVR, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxEXPAND|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
868 
869  wxBoxSizer* boxSizerLvl4_4 = new wxBoxSizer(wxVERTICAL);
870 
871  gridSizerLvl3_1->Add(boxSizerLvl4_4, 0, wxEXPAND, WXC_FROM_DIP(5));
872 
873  m_checkBoxUseSG = new wxCheckBox(this, wxID_ANY, _("Use speed governor"), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
874  m_checkBoxUseSG->SetValue(false);
875 
876  boxSizerLvl4_4->Add(m_checkBoxUseSG, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
877 
878  m_buttonEditSG = new wxButton(this, wxID_ANY, _("Edit speed governor"), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
879 
880  boxSizerLvl4_4->Add(m_buttonEditSG, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxEXPAND|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
881 
882  m_staticLine_1 = new wxStaticLine(this, wxID_ANY, wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), wxLI_HORIZONTAL);
883 
884  boxSizerLvl2_1->Add(m_staticLine_1, 0, wxALL|wxEXPAND, WXC_FROM_DIP(5));
885 
886  wxGridSizer* gridSizerLvl3_2 = new wxGridSizer(0, 2, 0, 0);
887 
888  boxSizerLvl2_1->Add(gridSizerLvl3_2, 1, wxEXPAND, WXC_FROM_DIP(5));
889 
890  wxBoxSizer* boxSizerLvl4_5 = new wxBoxSizer(wxVERTICAL);
891 
892  gridSizerLvl3_2->Add(boxSizerLvl4_5, 0, wxEXPAND, WXC_FROM_DIP(5));
893 
894  m_staticTextRa = new wxStaticText(this, wxID_ANY, _("Armature resistance (Ra)"), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
895 
896  boxSizerLvl4_5->Add(m_staticTextRa, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
897 
898  wxBoxSizer* boxSizerLvl5_3 = new wxBoxSizer(wxHORIZONTAL);
899 
900  boxSizerLvl4_5->Add(boxSizerLvl5_3, 0, wxEXPAND, WXC_FROM_DIP(5));
901 
902  m_textCtrlRa = new wxTextCtrl(this, wxID_ANY, wxT(""), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
903  #if wxVERSION_NUMBER >= 3000
904  m_textCtrlRa->SetHint(wxT(""));
905  #endif
906 
907  boxSizerLvl5_3->Add(m_textCtrlRa, 1, wxLEFT|wxRIGHT|wxBOTTOM|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
908 
909  m_staticTextPU_2 = new wxStaticText(this, wxID_ANY, _("p.u."), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
910 
911  boxSizerLvl5_3->Add(m_staticTextPU_2, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
912 
913  wxBoxSizer* boxSizerLvl4_6 = new wxBoxSizer(wxVERTICAL);
914 
915  gridSizerLvl3_2->Add(boxSizerLvl4_6, 0, wxEXPAND, WXC_FROM_DIP(5));
916 
917  m_staticTextXp = new wxStaticText(this, wxID_ANY, _("Potier reactance (Xp)"), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
918 
919  boxSizerLvl4_6->Add(m_staticTextXp, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
920 
921  wxBoxSizer* boxSizerLvl5_14 = new wxBoxSizer(wxHORIZONTAL);
922 
923  boxSizerLvl4_6->Add(boxSizerLvl5_14, 0, wxEXPAND, WXC_FROM_DIP(5));
924 
925  m_textCtrlXp = new wxTextCtrl(this, wxID_ANY, wxT(""), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
926  #if wxVERSION_NUMBER >= 3000
927  m_textCtrlXp->SetHint(wxT(""));
928  #endif
929 
930  boxSizerLvl5_14->Add(m_textCtrlXp, 1, wxLEFT|wxRIGHT|wxBOTTOM|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
931 
932  m_staticTextPU_9 = new wxStaticText(this, wxID_ANY, _("p.u."), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
933 
934  boxSizerLvl5_14->Add(m_staticTextPU_9, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
935 
936  wxBoxSizer* boxSizerLvl4_7 = new wxBoxSizer(wxVERTICAL);
937 
938  gridSizerLvl3_2->Add(boxSizerLvl4_7, 0, wxEXPAND, WXC_FROM_DIP(5));
939 
940  m_staticTextSat = new wxStaticText(this, wxID_ANY, _("Saturation factor"), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
941 
942  boxSizerLvl4_7->Add(m_staticTextSat, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
943 
944  wxBoxSizer* boxSizerLvl5_15 = new wxBoxSizer(wxHORIZONTAL);
945 
946  boxSizerLvl4_7->Add(boxSizerLvl5_15, 0, wxEXPAND, WXC_FROM_DIP(5));
947 
948  m_textCtrlSat = new wxTextCtrl(this, wxID_ANY, wxT(""), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
949  #if wxVERSION_NUMBER >= 3000
950  m_textCtrlSat->SetHint(wxT(""));
951  #endif
952 
953  boxSizerLvl5_15->Add(m_textCtrlSat, 1, wxLEFT|wxRIGHT|wxBOTTOM|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
954 
955  m_staticTextPU_10 = new wxStaticText(this, wxID_ANY, _("p.u."), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
956 
957  boxSizerLvl5_15->Add(m_staticTextPU_10, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
958 
959  wxStaticBoxSizer* staticBoxSizerSyncronous = new wxStaticBoxSizer( new wxStaticBox(this, wxID_ANY, _("Syncronous")), wxVERTICAL);
960 
961  boxSizerLvl2_1->Add(staticBoxSizerSyncronous, 0, wxALL|wxEXPAND, WXC_FROM_DIP(5));
962 
963  wxGridSizer* gridSizerLvl4_3 = new wxGridSizer(0, 2, 0, 0);
964 
965  staticBoxSizerSyncronous->Add(gridSizerLvl4_3, 1, wxEXPAND, WXC_FROM_DIP(5));
966 
967  wxBoxSizer* boxSizerLvl5_4 = new wxBoxSizer(wxVERTICAL);
968 
969  gridSizerLvl4_3->Add(boxSizerLvl5_4, 0, wxEXPAND, WXC_FROM_DIP(5));
970 
971  m_staticTextSyncXd = new wxStaticText(this, wxID_ANY, _("Direct-axis reactance (Xd)"), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
972 
973  boxSizerLvl5_4->Add(m_staticTextSyncXd, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
974 
975  wxBoxSizer* boxSizerLvl6_1 = new wxBoxSizer(wxHORIZONTAL);
976 
977  boxSizerLvl5_4->Add(boxSizerLvl6_1, 0, wxEXPAND, WXC_FROM_DIP(5));
978 
979  m_textCtrlSyncXd = new wxTextCtrl(this, wxID_ANY, wxT(""), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
980  #if wxVERSION_NUMBER >= 3000
981  m_textCtrlSyncXd->SetHint(wxT(""));
982  #endif
983 
984  boxSizerLvl6_1->Add(m_textCtrlSyncXd, 1, wxLEFT|wxRIGHT|wxBOTTOM|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
985 
986  m_staticTextPU_3 = new wxStaticText(this, wxID_ANY, _("p.u."), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
987 
988  boxSizerLvl6_1->Add(m_staticTextPU_3, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
989 
990  wxBoxSizer* boxSizerLvl5_5 = new wxBoxSizer(wxVERTICAL);
991 
992  gridSizerLvl4_3->Add(boxSizerLvl5_5, 0, wxEXPAND, WXC_FROM_DIP(5));
993 
994  m_staticTextSyncXq = new wxStaticText(this, wxID_ANY, _("Quadrature-axis reactance (Xq)"), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
995 
996  boxSizerLvl5_5->Add(m_staticTextSyncXq, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
997 
998  wxBoxSizer* boxSizerLvl6_2 = new wxBoxSizer(wxHORIZONTAL);
999 
1000  boxSizerLvl5_5->Add(boxSizerLvl6_2, 0, wxEXPAND, WXC_FROM_DIP(5));
1001 
1002  m_textCtrlSyncXq = new wxTextCtrl(this, wxID_ANY, wxT(""), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
1003  #if wxVERSION_NUMBER >= 3000
1004  m_textCtrlSyncXq->SetHint(wxT(""));
1005  #endif
1006 
1007  boxSizerLvl6_2->Add(m_textCtrlSyncXq, 1, wxLEFT|wxRIGHT|wxBOTTOM|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
1008 
1009  m_staticTextPU_4 = new wxStaticText(this, wxID_ANY, _("p.u."), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
1010 
1011  boxSizerLvl6_2->Add(m_staticTextPU_4, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
1012 
1013  wxStaticBoxSizer* staticBoxSizerTransient = new wxStaticBoxSizer( new wxStaticBox(this, wxID_ANY, _("Transient")), wxVERTICAL);
1014 
1015  boxSizerLvl2_1->Add(staticBoxSizerTransient, 0, wxALL|wxEXPAND, WXC_FROM_DIP(5));
1016 
1017  wxGridSizer* gridSizerLvl4_4 = new wxGridSizer(0, 2, 0, 0);
1018 
1019  staticBoxSizerTransient->Add(gridSizerLvl4_4, 1, wxEXPAND, WXC_FROM_DIP(5));
1020 
1021  wxBoxSizer* boxSizerLvl5_6 = new wxBoxSizer(wxVERTICAL);
1022 
1023  gridSizerLvl4_4->Add(boxSizerLvl5_6, 0, wxEXPAND, WXC_FROM_DIP(5));
1024 
1025  m_staticTextTranXd = new wxStaticText(this, wxID_ANY, _("Direct-axis reactance (X'd)"), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
1026 
1027  boxSizerLvl5_6->Add(m_staticTextTranXd, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
1028 
1029  wxBoxSizer* boxSizerLvl6_3 = new wxBoxSizer(wxHORIZONTAL);
1030 
1031  boxSizerLvl5_6->Add(boxSizerLvl6_3, 0, wxEXPAND, WXC_FROM_DIP(5));
1032 
1033  m_textCtrlTranXd = new wxTextCtrl(this, wxID_ANY, wxT(""), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
1034  #if wxVERSION_NUMBER >= 3000
1035  m_textCtrlTranXd->SetHint(wxT(""));
1036  #endif
1037 
1038  boxSizerLvl6_3->Add(m_textCtrlTranXd, 1, wxLEFT|wxRIGHT|wxBOTTOM|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
1039 
1040  m_staticTextPU_5 = new wxStaticText(this, wxID_ANY, _("p.u."), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
1041 
1042  boxSizerLvl6_3->Add(m_staticTextPU_5, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
1043 
1044  wxBoxSizer* boxSizerLvl5_7 = new wxBoxSizer(wxVERTICAL);
1045 
1046  gridSizerLvl4_4->Add(boxSizerLvl5_7, 0, wxEXPAND, WXC_FROM_DIP(5));
1047 
1048  m_staticTextTranXq = new wxStaticText(this, wxID_ANY, _("Quadrature-axis reactance (X'q)"), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
1049 
1050  boxSizerLvl5_7->Add(m_staticTextTranXq, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
1051 
1052  wxBoxSizer* boxSizerLvl6_4 = new wxBoxSizer(wxHORIZONTAL);
1053 
1054  boxSizerLvl5_7->Add(boxSizerLvl6_4, 0, wxEXPAND, WXC_FROM_DIP(5));
1055 
1056  m_textCtrlTranXq = new wxTextCtrl(this, wxID_ANY, wxT(""), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
1057  #if wxVERSION_NUMBER >= 3000
1058  m_textCtrlTranXq->SetHint(wxT(""));
1059  #endif
1060 
1061  boxSizerLvl6_4->Add(m_textCtrlTranXq, 1, wxLEFT|wxRIGHT|wxBOTTOM|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
1062 
1063  m_staticTextPU_6 = new wxStaticText(this, wxID_ANY, _("p.u."), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
1064 
1065  boxSizerLvl6_4->Add(m_staticTextPU_6, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
1066 
1067  wxBoxSizer* boxSizerLvl5_8 = new wxBoxSizer(wxVERTICAL);
1068 
1069  gridSizerLvl4_4->Add(boxSizerLvl5_8, 0, wxEXPAND, WXC_FROM_DIP(5));
1070 
1071  m_staticTextTranTd0 = new wxStaticText(this, wxID_ANY, _("Direct-axis time constant (T'd0)"), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
1072 
1073  boxSizerLvl5_8->Add(m_staticTextTranTd0, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
1074 
1075  wxBoxSizer* boxSizerLvl6_5 = new wxBoxSizer(wxHORIZONTAL);
1076 
1077  boxSizerLvl5_8->Add(boxSizerLvl6_5, 0, wxEXPAND, WXC_FROM_DIP(5));
1078 
1079  m_textCtrlTranTd0 = new wxTextCtrl(this, wxID_ANY, wxT(""), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
1080  #if wxVERSION_NUMBER >= 3000
1081  m_textCtrlTranTd0->SetHint(wxT(""));
1082  #endif
1083 
1084  boxSizerLvl6_5->Add(m_textCtrlTranTd0, 1, wxLEFT|wxRIGHT|wxBOTTOM|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
1085 
1086  m_staticTextS_2 = new wxStaticText(this, wxID_ANY, _("s"), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
1087 
1088  boxSizerLvl6_5->Add(m_staticTextS_2, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
1089 
1090  wxBoxSizer* boxSizerLvl5_9 = new wxBoxSizer(wxVERTICAL);
1091 
1092  gridSizerLvl4_4->Add(boxSizerLvl5_9, 0, wxEXPAND, WXC_FROM_DIP(5));
1093 
1094  m_staticTextTranTq0 = new wxStaticText(this, wxID_ANY, _("Quadrature-axis time constant (T'q0)"), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
1095 
1096  boxSizerLvl5_9->Add(m_staticTextTranTq0, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
1097 
1098  wxBoxSizer* boxSizerLvl6_6 = new wxBoxSizer(wxHORIZONTAL);
1099 
1100  boxSizerLvl5_9->Add(boxSizerLvl6_6, 0, wxEXPAND, WXC_FROM_DIP(5));
1101 
1102  m_textCtrlTranTq0 = new wxTextCtrl(this, wxID_ANY, wxT(""), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
1103  #if wxVERSION_NUMBER >= 3000
1104  m_textCtrlTranTq0->SetHint(wxT(""));
1105  #endif
1106 
1107  boxSizerLvl6_6->Add(m_textCtrlTranTq0, 1, wxLEFT|wxRIGHT|wxBOTTOM|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
1108 
1109  m_staticTextS_3 = new wxStaticText(this, wxID_ANY, _("s"), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
1110 
1111  boxSizerLvl6_6->Add(m_staticTextS_3, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
1112 
1113  wxStaticBoxSizer* staticBoxSizerSubtransient = new wxStaticBoxSizer( new wxStaticBox(this, wxID_ANY, _("Sub-transient")), wxVERTICAL);
1114 
1115  boxSizerLvl2_1->Add(staticBoxSizerSubtransient, 0, wxALL|wxEXPAND, WXC_FROM_DIP(5));
1116 
1117  wxGridSizer* gridSizerLvl4_5 = new wxGridSizer(0, 2, 0, 0);
1118 
1119  staticBoxSizerSubtransient->Add(gridSizerLvl4_5, 1, wxEXPAND, WXC_FROM_DIP(5));
1120 
1121  wxBoxSizer* boxSizerLvl5_10 = new wxBoxSizer(wxVERTICAL);
1122 
1123  gridSizerLvl4_5->Add(boxSizerLvl5_10, 0, wxEXPAND, WXC_FROM_DIP(5));
1124 
1125  m_staticTextSubXd = new wxStaticText(this, wxID_ANY, _("Direct-axis reactance (X''d)"), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
1126 
1127  boxSizerLvl5_10->Add(m_staticTextSubXd, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
1128 
1129  wxBoxSizer* boxSizerLvl6_7 = new wxBoxSizer(wxHORIZONTAL);
1130 
1131  boxSizerLvl5_10->Add(boxSizerLvl6_7, 0, wxEXPAND, WXC_FROM_DIP(5));
1132 
1133  m_textCtrlSubXd = new wxTextCtrl(this, wxID_ANY, wxT(""), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
1134  #if wxVERSION_NUMBER >= 3000
1135  m_textCtrlSubXd->SetHint(wxT(""));
1136  #endif
1137 
1138  boxSizerLvl6_7->Add(m_textCtrlSubXd, 1, wxLEFT|wxRIGHT|wxBOTTOM|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
1139 
1140  m_staticTextPU_7 = new wxStaticText(this, wxID_ANY, _("p.u."), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
1141 
1142  boxSizerLvl6_7->Add(m_staticTextPU_7, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
1143 
1144  wxBoxSizer* boxSizerLvl5_11 = new wxBoxSizer(wxVERTICAL);
1145 
1146  gridSizerLvl4_5->Add(boxSizerLvl5_11, 0, wxEXPAND, WXC_FROM_DIP(5));
1147 
1148  m_staticTextSubXq = new wxStaticText(this, wxID_ANY, _("Quadrature-axis reactance (X''q)"), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
1149 
1150  boxSizerLvl5_11->Add(m_staticTextSubXq, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
1151 
1152  wxBoxSizer* boxSizerLvl6_8 = new wxBoxSizer(wxHORIZONTAL);
1153 
1154  boxSizerLvl5_11->Add(boxSizerLvl6_8, 0, wxEXPAND, WXC_FROM_DIP(5));
1155 
1156  m_textCtrlSubXq = new wxTextCtrl(this, wxID_ANY, wxT(""), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
1157  #if wxVERSION_NUMBER >= 3000
1158  m_textCtrlSubXq->SetHint(wxT(""));
1159  #endif
1160 
1161  boxSizerLvl6_8->Add(m_textCtrlSubXq, 1, wxLEFT|wxRIGHT|wxBOTTOM|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
1162 
1163  m_staticTextPU_8 = new wxStaticText(this, wxID_ANY, _("p.u."), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
1164 
1165  boxSizerLvl6_8->Add(m_staticTextPU_8, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
1166 
1167  wxBoxSizer* boxSizerLvl5_12 = new wxBoxSizer(wxVERTICAL);
1168 
1169  gridSizerLvl4_5->Add(boxSizerLvl5_12, 0, wxEXPAND, WXC_FROM_DIP(5));
1170 
1171  m_staticTextSubTd0 = new wxStaticText(this, wxID_ANY, _("Direct-axis time constant (T''d0)"), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
1172 
1173  boxSizerLvl5_12->Add(m_staticTextSubTd0, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
1174 
1175  wxBoxSizer* boxSizerLvl6_9 = new wxBoxSizer(wxHORIZONTAL);
1176 
1177  boxSizerLvl5_12->Add(boxSizerLvl6_9, 0, wxEXPAND, WXC_FROM_DIP(5));
1178 
1179  m_textCtrlSubTd0 = new wxTextCtrl(this, wxID_ANY, wxT(""), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
1180  #if wxVERSION_NUMBER >= 3000
1181  m_textCtrlSubTd0->SetHint(wxT(""));
1182  #endif
1183 
1184  boxSizerLvl6_9->Add(m_textCtrlSubTd0, 1, wxLEFT|wxRIGHT|wxBOTTOM|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
1185 
1186  m_staticTextS_4 = new wxStaticText(this, wxID_ANY, _("s"), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
1187 
1188  boxSizerLvl6_9->Add(m_staticTextS_4, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
1189 
1190  wxBoxSizer* boxSizerLvl5_13 = new wxBoxSizer(wxVERTICAL);
1191 
1192  gridSizerLvl4_5->Add(boxSizerLvl5_13, 0, wxEXPAND, WXC_FROM_DIP(5));
1193 
1194  m_staticTextSubTq0 = new wxStaticText(this, wxID_ANY, _("Quadrature-axis time constant (T''q0)"), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
1195 
1196  boxSizerLvl5_13->Add(m_staticTextSubTq0, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
1197 
1198  wxBoxSizer* boxSizerLvl6_10 = new wxBoxSizer(wxHORIZONTAL);
1199 
1200  boxSizerLvl5_13->Add(boxSizerLvl6_10, 0, wxEXPAND, WXC_FROM_DIP(5));
1201 
1202  m_textCtrlSubTq0 = new wxTextCtrl(this, wxID_ANY, wxT(""), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
1203  #if wxVERSION_NUMBER >= 3000
1204  m_textCtrlSubTq0->SetHint(wxT(""));
1205  #endif
1206 
1207  boxSizerLvl6_10->Add(m_textCtrlSubTq0, 1, wxLEFT|wxRIGHT|wxBOTTOM|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
1208 
1209  m_staticTextS_5 = new wxStaticText(this, wxID_ANY, _("s"), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
1210 
1211  boxSizerLvl6_10->Add(m_staticTextS_5, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
1212 
1213  wxBoxSizer* boxSizerVDivider = new wxBoxSizer(wxVERTICAL);
1214 
1215  boxSizerLvl2_1->Add(boxSizerVDivider, 1, wxALL|wxEXPAND, WXC_FROM_DIP(5));
1216 
1217  wxBoxSizer* boxSizerSection_2 = new wxBoxSizer(wxVERTICAL);
1218 
1219  boxSizerVDivider->Add(boxSizerSection_2, 1, wxALL|wxEXPAND, WXC_FROM_DIP(5));
1220 
1221  wxBoxSizer* boxSizerSection_1 = new wxBoxSizer(wxVERTICAL);
1222 
1223  boxSizerVDivider->Add(boxSizerSection_1, 1, wxALL|wxEXPAND, WXC_FROM_DIP(5));
1224 
1225  wxBoxSizer* boxSizerBottomButtons = new wxBoxSizer(wxHORIZONTAL);
1226 
1227  boxSizerLvl1_1->Add(boxSizerBottomButtons, 0, wxALL|wxEXPAND, WXC_FROM_DIP(5));
1228 
1229  m_buttonSwitching = new wxButton(this, wxID_ANY, _("Switching"), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
1230 
1231  boxSizerBottomButtons->Add(m_buttonSwitching, 0, wxALL|wxALIGN_LEFT, WXC_FROM_DIP(5));
1232 
1233  boxSizerBottomButtons->Add(0, 0, 1, wxALL|wxEXPAND, WXC_FROM_DIP(5));
1234 
1235  m_buttonOK = new wxButton(this, wxID_ANY, _("OK"), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
1236 
1237  boxSizerBottomButtons->Add(m_buttonOK, 0, wxALL|wxALIGN_RIGHT, WXC_FROM_DIP(5));
1238 
1239  m_ButtonCancel = new wxButton(this, wxID_ANY, _("Cancel"), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
1240 
1241  boxSizerBottomButtons->Add(m_ButtonCancel, 0, wxALL|wxALIGN_RIGHT, WXC_FROM_DIP(5));
1242 
1243  SetName(wxT("GeneratorStabFormBase"));
1244  SetSize(-1,-1);
1245  if (GetSizer()) {
1246  GetSizer()->Fit(this);
1247  }
1248  if(GetParent()) {
1249  CentreOnParent(wxBOTH);
1250  } else {
1251  CentreOnScreen(wxBOTH);
1252  }
1253 #if wxVERSION_NUMBER >= 2900
1254  if(!wxPersistenceManager::Get().Find(this)) {
1255  wxPersistenceManager::Get().RegisterAndRestore(this);
1256  } else {
1257  wxPersistenceManager::Get().Restore(this);
1258  }
1259 #endif
1260  // Connect events
1261  m_checkBoxUseAVR->Connect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler(GeneratorStabFormBase::UseAVRClick), NULL, this);
1262  m_buttonEditAVR->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(GeneratorStabFormBase::OnEditAVRButtonClick), NULL, this);
1263  m_checkBoxUseSG->Connect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler(GeneratorStabFormBase::UseSGClick), NULL, this);
1264  m_buttonEditSG->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(GeneratorStabFormBase::OnSpeedGovernorButtonClick), NULL, this);
1265  m_buttonSwitching->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(GeneratorStabFormBase::OnSwitchingButtonClick), NULL, this);
1266  m_buttonOK->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(GeneratorStabFormBase::OnOKButtonClick), NULL, this);
1267  m_ButtonCancel->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(GeneratorStabFormBase::OnCancelButtonClick), NULL, this);
1268 
1269 }
1270 
1271 GeneratorStabFormBase::~GeneratorStabFormBase()
1272 {
1273  m_checkBoxUseAVR->Disconnect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler(GeneratorStabFormBase::UseAVRClick), NULL, this);
1274  m_buttonEditAVR->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(GeneratorStabFormBase::OnEditAVRButtonClick), NULL, this);
1275  m_checkBoxUseSG->Disconnect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler(GeneratorStabFormBase::UseSGClick), NULL, this);
1276  m_buttonEditSG->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(GeneratorStabFormBase::OnSpeedGovernorButtonClick), NULL, this);
1277  m_buttonSwitching->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(GeneratorStabFormBase::OnSwitchingButtonClick), NULL, this);
1278  m_buttonOK->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(GeneratorStabFormBase::OnOKButtonClick), NULL, this);
1279  m_ButtonCancel->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(GeneratorStabFormBase::OnCancelButtonClick), NULL, this);
1280 
1281 }
1282 
1283 LineFormBase::LineFormBase(wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style)
1284  : wxDialog(parent, id, title, pos, size, style)
1285 {
1286  if ( !bBitmapLoaded ) {
1287  // We need to initialise the default bitmap handler
1288  wxXmlResource::Get()->AddHandler(new wxBitmapXmlHandler);
1289  wxC9EE9InitBitmapResources();
1290  bBitmapLoaded = true;
1291  }
1292 
1293  wxBoxSizer* boxSizerLvl1_1 = new wxBoxSizer(wxVERTICAL);
1294  this->SetSizer(boxSizerLvl1_1);
1295 
1296  m_notebook = new wxNotebook(this, wxID_ANY, wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), wxBK_DEFAULT);
1297  m_notebook->SetName(wxT("m_notebook"));
1298 
1299  boxSizerLvl1_1->Add(m_notebook, 1, wxEXPAND, WXC_FROM_DIP(5));
1300 
1301  m_panelGeneral = new wxPanel(m_notebook, wxID_ANY, wxDefaultPosition, wxDLG_UNIT(m_notebook, wxSize(-1,-1)), wxTAB_TRAVERSAL);
1302  m_notebook->AddPage(m_panelGeneral, _("General"), false);
1303 
1304  wxBoxSizer* boxSizerLvl2_1 = new wxBoxSizer(wxVERTICAL);
1305  m_panelGeneral->SetSizer(boxSizerLvl2_1);
1306 
1307  m_staticTextName = new wxStaticText(m_panelGeneral, wxID_ANY, _("Name"), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
1308 
1309  boxSizerLvl2_1->Add(m_staticTextName, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
1310 
1311  m_textCtrlName = new wxTextCtrl(m_panelGeneral, wxID_ANY, wxT(""), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
1312  #if wxVERSION_NUMBER >= 3000
1313  m_textCtrlName->SetHint(wxT(""));
1314  #endif
1315 
1316  boxSizerLvl2_1->Add(m_textCtrlName, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxEXPAND|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
1317  m_textCtrlName->SetMinSize(wxSize(300,-1));
1318 
1319  wxGridSizer* gridSizerLvl3_1 = new wxGridSizer(0, 2, 0, 0);
1320 
1321  boxSizerLvl2_1->Add(gridSizerLvl3_1, 0, wxEXPAND, WXC_FROM_DIP(5));
1322 
1323  wxBoxSizer* boxSizerLvl4_9 = new wxBoxSizer(wxVERTICAL);
1324 
1325  gridSizerLvl3_1->Add(boxSizerLvl4_9, 0, wxEXPAND, WXC_FROM_DIP(5));
1326 
1327  m_staticTextNominalVoltage = new wxStaticText(m_panelGeneral, wxID_ANY, _("Rated voltage"), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
1328 
1329  boxSizerLvl4_9->Add(m_staticTextNominalVoltage, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
1330 
1331  m_staticTextNominalVoltageValue = new wxStaticText(m_panelGeneral, wxID_ANY, _("138 kV"), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
1332  wxFont m_staticTextNominalVoltageValueFont = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT);
1333  m_staticTextNominalVoltageValueFont.SetWeight(wxFONTWEIGHT_BOLD);
1334  m_staticTextNominalVoltageValue->SetFont(m_staticTextNominalVoltageValueFont);
1335 
1336  boxSizerLvl4_9->Add(m_staticTextNominalVoltageValue, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
1337 
1338  wxBoxSizer* boxSizerLvl4_8 = new wxBoxSizer(wxVERTICAL);
1339 
1340  gridSizerLvl3_1->Add(boxSizerLvl4_8, 0, wxEXPAND, WXC_FROM_DIP(5));
1341 
1342  m_staticTextNominalPower = new wxStaticText(m_panelGeneral, wxID_ANY, _("Rated power"), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
1343 
1344  boxSizerLvl4_8->Add(m_staticTextNominalPower, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
1345 
1346  wxBoxSizer* boxSizerLvl5_5 = new wxBoxSizer(wxHORIZONTAL);
1347 
1348  boxSizerLvl4_8->Add(boxSizerLvl5_5, 0, wxEXPAND, WXC_FROM_DIP(5));
1349 
1350  m_textCtrlNominalPower = new wxTextCtrl(m_panelGeneral, wxID_ANY, wxT(""), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
1351  #if wxVERSION_NUMBER >= 3000
1352  m_textCtrlNominalPower->SetHint(wxT(""));
1353  #endif
1354 
1355  boxSizerLvl5_5->Add(m_textCtrlNominalPower, 1, wxLEFT|wxRIGHT|wxBOTTOM|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
1356 
1357  wxArrayString m_choiceNominalPowerArr;
1358  m_choiceNominalPowerArr.Add(wxT("VA"));
1359  m_choiceNominalPowerArr.Add(wxT("kVA"));
1360  m_choiceNominalPowerArr.Add(wxT("MVA"));
1361  m_choiceNominalPower = new wxChoice(m_panelGeneral, wxID_ANY, wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), m_choiceNominalPowerArr, 0);
1362  m_choiceNominalPower->SetSelection(2);
1363 
1364  boxSizerLvl5_5->Add(m_choiceNominalPower, 0, wxLEFT|wxRIGHT|wxBOTTOM, WXC_FROM_DIP(5));
1365 
1366  wxBoxSizer* boxSizerLvl4_1 = new wxBoxSizer(wxVERTICAL);
1367 
1368  gridSizerLvl3_1->Add(boxSizerLvl4_1, 0, wxEXPAND, WXC_FROM_DIP(5));
1369 
1370  m_staticTextResistance = new wxStaticText(m_panelGeneral, wxID_ANY, _("Resistance (R)"), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
1371 
1372  boxSizerLvl4_1->Add(m_staticTextResistance, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
1373 
1374  wxBoxSizer* boxSizerLvl5_1 = new wxBoxSizer(wxHORIZONTAL);
1375 
1376  boxSizerLvl4_1->Add(boxSizerLvl5_1, 0, wxEXPAND, WXC_FROM_DIP(5));
1377 
1378  m_textCtrlResistance = new wxTextCtrl(m_panelGeneral, wxID_ANY, wxT(""), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
1379  #if wxVERSION_NUMBER >= 3000
1380  m_textCtrlResistance->SetHint(wxT(""));
1381  #endif
1382 
1383  boxSizerLvl5_1->Add(m_textCtrlResistance, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxEXPAND|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
1384 
1385  wxArrayString m_choiceResistanceArr;
1386  m_choiceResistanceArr.Add(wxT("p.u."));
1387  m_choiceResistanceArr.Add(wxT("Ohm"));
1388  m_choiceResistanceArr.Add(wxT("Ohm/km"));
1389  m_choiceResistance = new wxChoice(m_panelGeneral, wxID_ANY, wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), m_choiceResistanceArr, 0);
1390  m_choiceResistance->SetSelection(0);
1391 
1392  boxSizerLvl5_1->Add(m_choiceResistance, 0, wxLEFT|wxRIGHT|wxBOTTOM, WXC_FROM_DIP(5));
1393 
1394  wxBoxSizer* boxSizerLvl4_2 = new wxBoxSizer(wxVERTICAL);
1395 
1396  gridSizerLvl3_1->Add(boxSizerLvl4_2, 0, wxEXPAND, WXC_FROM_DIP(5));
1397 
1398  m_staticTextReactance = new wxStaticText(m_panelGeneral, wxID_ANY, _("Indutive reactance (XL)"), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
1399 
1400  boxSizerLvl4_2->Add(m_staticTextReactance, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
1401 
1402  wxBoxSizer* boxSizerLvl5_2 = new wxBoxSizer(wxHORIZONTAL);
1403 
1404  boxSizerLvl4_2->Add(boxSizerLvl5_2, 0, wxEXPAND, WXC_FROM_DIP(5));
1405 
1406  m_textCtrlReactance = new wxTextCtrl(m_panelGeneral, wxID_ANY, wxT(""), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
1407  #if wxVERSION_NUMBER >= 3000
1408  m_textCtrlReactance->SetHint(wxT(""));
1409  #endif
1410 
1411  boxSizerLvl5_2->Add(m_textCtrlReactance, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxEXPAND|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
1412 
1413  wxArrayString m_choiceReactanceArr;
1414  m_choiceReactanceArr.Add(wxT("p.u."));
1415  m_choiceReactanceArr.Add(wxT("Ohm"));
1416  m_choiceReactanceArr.Add(wxT("Ohm/km"));
1417  m_choiceReactance = new wxChoice(m_panelGeneral, wxID_ANY, wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), m_choiceReactanceArr, 0);
1418  m_choiceReactance->SetSelection(0);
1419 
1420  boxSizerLvl5_2->Add(m_choiceReactance, 0, wxLEFT|wxRIGHT|wxBOTTOM, WXC_FROM_DIP(5));
1421 
1422  wxBoxSizer* boxSizerLvl4_3 = new wxBoxSizer(wxVERTICAL);
1423 
1424  gridSizerLvl3_1->Add(boxSizerLvl4_3, 0, wxEXPAND, WXC_FROM_DIP(5));
1425 
1426  m_staticTextSusceptance = new wxStaticText(m_panelGeneral, wxID_ANY, _("Capacitive susceptance (B)"), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
1427 
1428  boxSizerLvl4_3->Add(m_staticTextSusceptance, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
1429 
1430  wxBoxSizer* boxSizerLvl5_3 = new wxBoxSizer(wxHORIZONTAL);
1431 
1432  boxSizerLvl4_3->Add(boxSizerLvl5_3, 0, wxEXPAND, WXC_FROM_DIP(5));
1433 
1434  m_textCtrlSusceptance = new wxTextCtrl(m_panelGeneral, wxID_ANY, wxT(""), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
1435  #if wxVERSION_NUMBER >= 3000
1436  m_textCtrlSusceptance->SetHint(wxT(""));
1437  #endif
1438 
1439  boxSizerLvl5_3->Add(m_textCtrlSusceptance, 1, wxLEFT|wxRIGHT|wxBOTTOM|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
1440 
1441  wxArrayString m_choiceSusceptanceArr;
1442  m_choiceSusceptanceArr.Add(wxT("p.u."));
1443  m_choiceSusceptanceArr.Add(wxT("S"));
1444  m_choiceSusceptanceArr.Add(wxT("S/km"));
1445  m_choiceSusceptance = new wxChoice(m_panelGeneral, wxID_ANY, wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), m_choiceSusceptanceArr, 0);
1446  m_choiceSusceptance->SetSelection(0);
1447 
1448  boxSizerLvl5_3->Add(m_choiceSusceptance, 0, wxLEFT|wxRIGHT|wxBOTTOM, WXC_FROM_DIP(5));
1449 
1450  wxBoxSizer* boxSizerLvl4_4 = new wxBoxSizer(wxVERTICAL);
1451 
1452  gridSizerLvl3_1->Add(boxSizerLvl4_4, 0, wxEXPAND, WXC_FROM_DIP(5));
1453 
1454  m_staticTextLineSize = new wxStaticText(m_panelGeneral, wxID_ANY, _("Line size"), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
1455 
1456  boxSizerLvl4_4->Add(m_staticTextLineSize, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
1457 
1458  wxBoxSizer* boxSizerLvl5_4 = new wxBoxSizer(wxHORIZONTAL);
1459 
1460  boxSizerLvl4_4->Add(boxSizerLvl5_4, 0, wxEXPAND, WXC_FROM_DIP(5));
1461 
1462  m_textCtrlLineSize = new wxTextCtrl(m_panelGeneral, wxID_ANY, wxT(""), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
1463  #if wxVERSION_NUMBER >= 3000
1464  m_textCtrlLineSize->SetHint(wxT(""));
1465  #endif
1466 
1467  boxSizerLvl5_4->Add(m_textCtrlLineSize, 1, wxLEFT|wxRIGHT|wxBOTTOM|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
1468 
1469  m_staticTextKM = new wxStaticText(m_panelGeneral, wxID_ANY, _("km"), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
1470 
1471  boxSizerLvl5_4->Add(m_staticTextKM, 0, wxALL, WXC_FROM_DIP(5));
1472 
1473  m_checkUseLinePower = new wxCheckBox(m_panelGeneral, wxID_ANY, _("Use line rated power as base"), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
1474  m_checkUseLinePower->SetValue(false);
1475 
1476  boxSizerLvl2_1->Add(m_checkUseLinePower, 0, wxALL, WXC_FROM_DIP(5));
1477 
1478  m_panelFault = new wxPanel(m_notebook, wxID_ANY, wxDefaultPosition, wxDLG_UNIT(m_notebook, wxSize(-1,-1)), wxTAB_TRAVERSAL);
1479  m_notebook->AddPage(m_panelFault, _("Fault"), false);
1480 
1481  wxBoxSizer* boxSizerLvl2_2 = new wxBoxSizer(wxVERTICAL);
1482  m_panelFault->SetSizer(boxSizerLvl2_2);
1483 
1484  wxStaticBoxSizer* staticBoxSizerZeroImpSeq = new wxStaticBoxSizer( new wxStaticBox(m_panelFault, wxID_ANY, _("Zero-sequence impedances (p.u.)")), wxVERTICAL);
1485 
1486  boxSizerLvl2_2->Add(staticBoxSizerZeroImpSeq, 0, wxALL|wxEXPAND, WXC_FROM_DIP(5));
1487 
1488  wxGridSizer* gridSizerLvl3_2 = new wxGridSizer(0, 2, 0, 0);
1489 
1490  staticBoxSizerZeroImpSeq->Add(gridSizerLvl3_2, 0, wxEXPAND, WXC_FROM_DIP(5));
1491 
1492  wxBoxSizer* boxSizerLvl4_5 = new wxBoxSizer(wxVERTICAL);
1493 
1494  gridSizerLvl3_2->Add(boxSizerLvl4_5, 0, wxEXPAND, WXC_FROM_DIP(5));
1495 
1496  m_staticTextZeroResistance = new wxStaticText(m_panelFault, wxID_ANY, _("Resistance (R0)"), wxDefaultPosition, wxDLG_UNIT(m_panelFault, wxSize(-1,-1)), 0);
1497 
1498  boxSizerLvl4_5->Add(m_staticTextZeroResistance, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
1499 
1500  m_textCtrlZeroResistance = new wxTextCtrl(m_panelFault, wxID_ANY, wxT(""), wxDefaultPosition, wxDLG_UNIT(m_panelFault, wxSize(-1,-1)), 0);
1501  #if wxVERSION_NUMBER >= 3000
1502  m_textCtrlZeroResistance->SetHint(wxT(""));
1503  #endif
1504 
1505  boxSizerLvl4_5->Add(m_textCtrlZeroResistance, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxEXPAND|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
1506 
1507  wxBoxSizer* boxSizerLvl4_6 = new wxBoxSizer(wxVERTICAL);
1508 
1509  gridSizerLvl3_2->Add(boxSizerLvl4_6, 0, wxEXPAND, WXC_FROM_DIP(5));
1510 
1511  m_staticTextZeroReactance = new wxStaticText(m_panelFault, wxID_ANY, _("Indutive reactance (X0)"), wxDefaultPosition, wxDLG_UNIT(m_panelFault, wxSize(-1,-1)), 0);
1512 
1513  boxSizerLvl4_6->Add(m_staticTextZeroReactance, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
1514 
1515  m_textCtrlZeroReactance = new wxTextCtrl(m_panelFault, wxID_ANY, wxT(""), wxDefaultPosition, wxDLG_UNIT(m_panelFault, wxSize(-1,-1)), 0);
1516  #if wxVERSION_NUMBER >= 3000
1517  m_textCtrlZeroReactance->SetHint(wxT(""));
1518  #endif
1519 
1520  boxSizerLvl4_6->Add(m_textCtrlZeroReactance, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxEXPAND|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
1521 
1522  wxBoxSizer* boxSizerLvl4_7 = new wxBoxSizer(wxVERTICAL);
1523 
1524  gridSizerLvl3_2->Add(boxSizerLvl4_7, 0, wxEXPAND, WXC_FROM_DIP(5));
1525 
1526  m_staticTextZeroSusceptance = new wxStaticText(m_panelFault, wxID_ANY, _("Capacitive susceptance (B0)"), wxDefaultPosition, wxDLG_UNIT(m_panelFault, wxSize(-1,-1)), 0);
1527 
1528  boxSizerLvl4_7->Add(m_staticTextZeroSusceptance, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
1529 
1530  m_textCtrlZeroSusceptance = new wxTextCtrl(m_panelFault, wxID_ANY, wxT(""), wxDefaultPosition, wxDLG_UNIT(m_panelFault, wxSize(-1,-1)), 0);
1531  #if wxVERSION_NUMBER >= 3000
1532  m_textCtrlZeroSusceptance->SetHint(wxT(""));
1533  #endif
1534 
1535  boxSizerLvl4_7->Add(m_textCtrlZeroSusceptance, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxEXPAND|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
1536 
1537  wxBoxSizer* boxSizerBottomButtons = new wxBoxSizer(wxHORIZONTAL);
1538 
1539  boxSizerLvl1_1->Add(boxSizerBottomButtons, 0, wxALL|wxEXPAND, WXC_FROM_DIP(5));
1540 
1541  m_buttonStability = new wxButton(this, wxID_ANY, _("Stability"), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
1542 
1543  boxSizerBottomButtons->Add(m_buttonStability, 0, wxALL|wxALIGN_LEFT, WXC_FROM_DIP(5));
1544 
1545  boxSizerBottomButtons->Add(0, 0, 1, wxALL|wxEXPAND, WXC_FROM_DIP(5));
1546 
1547  m_buttonOK = new wxButton(this, wxID_ANY, _("OK"), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
1548 
1549  boxSizerBottomButtons->Add(m_buttonOK, 0, wxALL|wxALIGN_RIGHT, WXC_FROM_DIP(5));
1550 
1551  m_buttonCancel = new wxButton(this, wxID_ANY, _("Cancel"), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
1552 
1553  boxSizerBottomButtons->Add(m_buttonCancel, 0, wxALL|wxALIGN_RIGHT, WXC_FROM_DIP(5));
1554 
1555 
1556  #if wxVERSION_NUMBER >= 2900
1557  if(!wxPersistenceManager::Get().Find(m_notebook)){
1558  wxPersistenceManager::Get().RegisterAndRestore(m_notebook);
1559  } else {
1560  wxPersistenceManager::Get().Restore(m_notebook);
1561  }
1562  #endif
1563 
1564  SetName(wxT("LineFormBase"));
1565  SetSize(-1,-1);
1566  if (GetSizer()) {
1567  GetSizer()->Fit(this);
1568  }
1569  if(GetParent()) {
1570  CentreOnParent(wxBOTH);
1571  } else {
1572  CentreOnScreen(wxBOTH);
1573  }
1574 #if wxVERSION_NUMBER >= 2900
1575  if(!wxPersistenceManager::Get().Find(this)) {
1576  wxPersistenceManager::Get().RegisterAndRestore(this);
1577  } else {
1578  wxPersistenceManager::Get().Restore(this);
1579  }
1580 #endif
1581  // Connect events
1582  m_buttonStability->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(LineFormBase::OnStabilityButtonClick), NULL, this);
1583  m_buttonOK->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(LineFormBase::OnOKButtonClick), NULL, this);
1584  m_buttonCancel->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(LineFormBase::OnCancelButtonClick), NULL, this);
1585 
1586 }
1587 
1588 LineFormBase::~LineFormBase()
1589 {
1590  m_buttonStability->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(LineFormBase::OnStabilityButtonClick), NULL, this);
1591  m_buttonOK->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(LineFormBase::OnOKButtonClick), NULL, this);
1592  m_buttonCancel->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(LineFormBase::OnCancelButtonClick), NULL, this);
1593 
1594 }
1595 
1596 TransformerFormBase::TransformerFormBase(wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style)
1597  : wxDialog(parent, id, title, pos, size, style)
1598 {
1599  if ( !bBitmapLoaded ) {
1600  // We need to initialise the default bitmap handler
1601  wxXmlResource::Get()->AddHandler(new wxBitmapXmlHandler);
1602  wxC9EE9InitBitmapResources();
1603  bBitmapLoaded = true;
1604  }
1605 
1606  wxBoxSizer* boxSizerLvl1_1 = new wxBoxSizer(wxVERTICAL);
1607  this->SetSizer(boxSizerLvl1_1);
1608 
1609  m_notebook = new wxNotebook(this, wxID_ANY, wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), wxBK_DEFAULT);
1610  m_notebook->SetName(wxT("m_notebook"));
1611 
1612  boxSizerLvl1_1->Add(m_notebook, 1, wxEXPAND, WXC_FROM_DIP(5));
1613 
1614  m_panelGeneral = new wxPanel(m_notebook, wxID_ANY, wxDefaultPosition, wxDLG_UNIT(m_notebook, wxSize(-1,-1)), wxTAB_TRAVERSAL);
1615  m_notebook->AddPage(m_panelGeneral, _("General"), false);
1616 
1617  wxBoxSizer* boxSizerLvl2_1 = new wxBoxSizer(wxVERTICAL);
1618  m_panelGeneral->SetSizer(boxSizerLvl2_1);
1619 
1620  m_staticTextName = new wxStaticText(m_panelGeneral, wxID_ANY, _("Name"), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
1621 
1622  boxSizerLvl2_1->Add(m_staticTextName, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
1623 
1624  m_textCtrlName = new wxTextCtrl(m_panelGeneral, wxID_ANY, wxT(""), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
1625  #if wxVERSION_NUMBER >= 3000
1626  m_textCtrlName->SetHint(wxT(""));
1627  #endif
1628 
1629  boxSizerLvl2_1->Add(m_textCtrlName, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxEXPAND|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
1630  m_textCtrlName->SetMinSize(wxSize(300,-1));
1631 
1632  wxGridSizer* gridSizerLvl3_1 = new wxGridSizer(0, 2, 0, 0);
1633 
1634  boxSizerLvl2_1->Add(gridSizerLvl3_1, 0, wxEXPAND, WXC_FROM_DIP(5));
1635 
1636  wxBoxSizer* boxSizerLvl4_1 = new wxBoxSizer(wxVERTICAL);
1637 
1638  gridSizerLvl3_1->Add(boxSizerLvl4_1, 0, wxEXPAND, WXC_FROM_DIP(5));
1639 
1640  m_staticTextNominalVoltage = new wxStaticText(m_panelGeneral, wxID_ANY, _("Rated voltage"), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
1641 
1642  boxSizerLvl4_1->Add(m_staticTextNominalVoltage, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
1643 
1644  m_staticTextNominalVoltageValue = new wxStaticText(m_panelGeneral, wxID_ANY, _("138 kV / 138 kV"), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
1645  wxFont m_staticTextNominalVoltageValueFont = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT);
1646  m_staticTextNominalVoltageValueFont.SetWeight(wxFONTWEIGHT_BOLD);
1647  m_staticTextNominalVoltageValue->SetFont(m_staticTextNominalVoltageValueFont);
1648 
1649  boxSizerLvl4_1->Add(m_staticTextNominalVoltageValue, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
1650 
1651  wxBoxSizer* boxSizerLvl4_5 = new wxBoxSizer(wxVERTICAL);
1652 
1653  gridSizerLvl3_1->Add(boxSizerLvl4_5, 0, wxEXPAND, WXC_FROM_DIP(5));
1654 
1655  m_staticTextBaseVoltage = new wxStaticText(m_panelGeneral, wxID_ANY, _("Base voltage"), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
1656 
1657  boxSizerLvl4_5->Add(m_staticTextBaseVoltage, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
1658 
1659  wxArrayString m_choiceBaseVoltageArr;
1660  m_choiceBaseVoltageArr.Add(wxT("138 kV"));
1661  m_choiceBaseVoltageArr.Add(wxT("138 kV"));
1662  m_choiceBaseVoltage = new wxChoice(m_panelGeneral, wxID_ANY, wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), m_choiceBaseVoltageArr, 0);
1663  m_choiceBaseVoltage->SetSelection(0);
1664 
1665  boxSizerLvl4_5->Add(m_choiceBaseVoltage, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxEXPAND, WXC_FROM_DIP(5));
1666 
1667  wxBoxSizer* boxSizerLvl4_2 = new wxBoxSizer(wxVERTICAL);
1668 
1669  gridSizerLvl3_1->Add(boxSizerLvl4_2, 0, wxEXPAND, WXC_FROM_DIP(5));
1670 
1671  m_staticTextNominalPower = new wxStaticText(m_panelGeneral, wxID_ANY, _("Rated power"), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
1672 
1673  boxSizerLvl4_2->Add(m_staticTextNominalPower, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
1674 
1675  wxBoxSizer* boxSizerLvl5_1 = new wxBoxSizer(wxHORIZONTAL);
1676 
1677  boxSizerLvl4_2->Add(boxSizerLvl5_1, 0, wxEXPAND, WXC_FROM_DIP(5));
1678 
1679  m_textCtrlNominalPower = new wxTextCtrl(m_panelGeneral, wxID_ANY, wxT(""), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
1680  #if wxVERSION_NUMBER >= 3000
1681  m_textCtrlNominalPower->SetHint(wxT(""));
1682  #endif
1683 
1684  boxSizerLvl5_1->Add(m_textCtrlNominalPower, 1, wxLEFT|wxRIGHT|wxBOTTOM|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
1685 
1686  wxArrayString m_choiceNominalPowerArr;
1687  m_choiceNominalPowerArr.Add(wxT("VA"));
1688  m_choiceNominalPowerArr.Add(wxT("kVA"));
1689  m_choiceNominalPowerArr.Add(wxT("MVA"));
1690  m_choiceNominalPower = new wxChoice(m_panelGeneral, wxID_ANY, wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), m_choiceNominalPowerArr, 0);
1691  m_choiceNominalPower->SetSelection(2);
1692 
1693  boxSizerLvl5_1->Add(m_choiceNominalPower, 0, wxLEFT|wxRIGHT|wxBOTTOM, WXC_FROM_DIP(5));
1694 
1695  gridSizerLvl3_1->Add(0, 0, 1, wxALL, WXC_FROM_DIP(5));
1696 
1697  wxBoxSizer* boxSizerLvl4_3 = new wxBoxSizer(wxVERTICAL);
1698 
1699  gridSizerLvl3_1->Add(boxSizerLvl4_3, 0, wxEXPAND, WXC_FROM_DIP(5));
1700 
1701  m_staticTextResistance = new wxStaticText(m_panelGeneral, wxID_ANY, _("Resistance (R)"), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
1702 
1703  boxSizerLvl4_3->Add(m_staticTextResistance, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
1704 
1705  wxBoxSizer* boxSizerLvl5_2 = new wxBoxSizer(wxHORIZONTAL);
1706 
1707  boxSizerLvl4_3->Add(boxSizerLvl5_2, 0, wxEXPAND, WXC_FROM_DIP(5));
1708 
1709  m_textCtrlResistance = new wxTextCtrl(m_panelGeneral, wxID_ANY, wxT(""), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
1710  #if wxVERSION_NUMBER >= 3000
1711  m_textCtrlResistance->SetHint(wxT(""));
1712  #endif
1713 
1714  boxSizerLvl5_2->Add(m_textCtrlResistance, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxEXPAND|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
1715 
1716  wxArrayString m_choiceResistanceArr;
1717  m_choiceResistanceArr.Add(wxT("p.u."));
1718  m_choiceResistanceArr.Add(wxT("Ohm"));
1719  m_choiceResistance = new wxChoice(m_panelGeneral, wxID_ANY, wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), m_choiceResistanceArr, 0);
1720  m_choiceResistance->SetSelection(0);
1721 
1722  boxSizerLvl5_2->Add(m_choiceResistance, 0, wxLEFT|wxRIGHT|wxBOTTOM, WXC_FROM_DIP(5));
1723 
1724  wxBoxSizer* boxSizerLvl4_4 = new wxBoxSizer(wxVERTICAL);
1725 
1726  gridSizerLvl3_1->Add(boxSizerLvl4_4, 0, wxEXPAND, WXC_FROM_DIP(5));
1727 
1728  m_staticTextReactance = new wxStaticText(m_panelGeneral, wxID_ANY, _("Indutive reactance (XL)"), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
1729 
1730  boxSizerLvl4_4->Add(m_staticTextReactance, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
1731 
1732  wxBoxSizer* boxSizerLvl5_3 = new wxBoxSizer(wxHORIZONTAL);
1733 
1734  boxSizerLvl4_4->Add(boxSizerLvl5_3, 0, wxEXPAND, WXC_FROM_DIP(5));
1735 
1736  m_textCtrlReactance = new wxTextCtrl(m_panelGeneral, wxID_ANY, wxT(""), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
1737  #if wxVERSION_NUMBER >= 3000
1738  m_textCtrlReactance->SetHint(wxT(""));
1739  #endif
1740 
1741  boxSizerLvl5_3->Add(m_textCtrlReactance, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxEXPAND|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
1742 
1743  wxArrayString m_choiceReactanceArr;
1744  m_choiceReactanceArr.Add(wxT("p.u."));
1745  m_choiceReactanceArr.Add(wxT("Ohm"));
1746  m_choiceReactance = new wxChoice(m_panelGeneral, wxID_ANY, wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), m_choiceReactanceArr, 0);
1747  m_choiceReactance->SetSelection(0);
1748 
1749  boxSizerLvl5_3->Add(m_choiceReactance, 0, wxLEFT|wxRIGHT|wxBOTTOM, WXC_FROM_DIP(5));
1750 
1751  m_staticLine_1 = new wxStaticLine(m_panelGeneral, wxID_ANY, wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), wxLI_HORIZONTAL);
1752 
1753  boxSizerLvl2_1->Add(m_staticLine_1, 0, wxALL|wxEXPAND, WXC_FROM_DIP(5));
1754 
1755  wxBoxSizer* boxSizerLvl3_1 = new wxBoxSizer(wxVERTICAL);
1756 
1757  boxSizerLvl2_1->Add(boxSizerLvl3_1, 0, wxEXPAND, WXC_FROM_DIP(5));
1758 
1759  m_staticTextConnection = new wxStaticText(m_panelGeneral, wxID_ANY, _("Connection"), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
1760 
1761  boxSizerLvl3_1->Add(m_staticTextConnection, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
1762 
1763  wxArrayString m_choiceConnectionArr;
1764  m_choiceConnectionArr.Add(wxT("Grounded Wye - Grounded Wye"));
1765  m_choiceConnectionArr.Add(wxT("Wye - Grounded Wye"));
1766  m_choiceConnectionArr.Add(wxT("Grounded Wye - Wye"));
1767  m_choiceConnectionArr.Add(wxT("Wye - Wye"));
1768  m_choiceConnectionArr.Add(wxT("Delta - Grounded Wye"));
1769  m_choiceConnectionArr.Add(wxT("Delta - Wye"));
1770  m_choiceConnectionArr.Add(wxT("Grounded Wye - Delta"));
1771  m_choiceConnectionArr.Add(wxT("Wye - Delta"));
1772  m_choiceConnectionArr.Add(wxT("Delta - Delta"));
1773  m_choiceConnection = new wxChoice(m_panelGeneral, wxID_ANY, wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), m_choiceConnectionArr, 0);
1774  m_choiceConnection->SetSelection(0);
1775 
1776  boxSizerLvl3_1->Add(m_choiceConnection, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxEXPAND, WXC_FROM_DIP(5));
1777 
1778  wxGridSizer* gridSizerLvl3_2 = new wxGridSizer(0, 2, 0, 0);
1779 
1780  boxSizerLvl2_1->Add(gridSizerLvl3_2, 0, wxEXPAND, WXC_FROM_DIP(5));
1781 
1782  wxBoxSizer* boxSizerLvl4_6 = new wxBoxSizer(wxVERTICAL);
1783 
1784  gridSizerLvl3_2->Add(boxSizerLvl4_6, 0, wxEXPAND, WXC_FROM_DIP(5));
1785 
1786  m_staticTextTurnsRatio = new wxStaticText(m_panelGeneral, wxID_ANY, _("Turns ratio"), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
1787 
1788  boxSizerLvl4_6->Add(m_staticTextTurnsRatio, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
1789 
1790  m_textCtrlTurnRatio = new wxTextCtrl(m_panelGeneral, wxID_ANY, wxT(""), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
1791  #if wxVERSION_NUMBER >= 3000
1792  m_textCtrlTurnRatio->SetHint(wxT(""));
1793  #endif
1794 
1795  boxSizerLvl4_6->Add(m_textCtrlTurnRatio, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxEXPAND|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
1796 
1797  wxBoxSizer* boxSizerLvl4_7 = new wxBoxSizer(wxVERTICAL);
1798 
1799  gridSizerLvl3_2->Add(boxSizerLvl4_7, 0, wxEXPAND, WXC_FROM_DIP(5));
1800 
1801  m_staticTextPhaseShift = new wxStaticText(m_panelGeneral, wxID_ANY, _("Phase shift"), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
1802 
1803  boxSizerLvl4_7->Add(m_staticTextPhaseShift, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
1804 
1805  wxBoxSizer* boxSizerLvl5_4 = new wxBoxSizer(wxHORIZONTAL);
1806 
1807  boxSizerLvl4_7->Add(boxSizerLvl5_4, 0, wxEXPAND, WXC_FROM_DIP(5));
1808 
1809  m_textCtrlPhaseShift = new wxTextCtrl(m_panelGeneral, wxID_ANY, wxT(""), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
1810  #if wxVERSION_NUMBER >= 3000
1811  m_textCtrlPhaseShift->SetHint(wxT(""));
1812  #endif
1813 
1814  boxSizerLvl5_4->Add(m_textCtrlPhaseShift, 1, wxLEFT|wxRIGHT|wxBOTTOM|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
1815 
1816  m_staticTextDeg = new wxStaticText(m_panelGeneral, wxID_ANY, _("degrees"), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
1817 
1818  boxSizerLvl5_4->Add(m_staticTextDeg, 0, wxALL, WXC_FROM_DIP(5));
1819 
1820  m_checkUseTransformerPower = new wxCheckBox(m_panelGeneral, wxID_ANY, _("Use transformer rated power as base"), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
1821  m_checkUseTransformerPower->SetValue(false);
1822 
1823  boxSizerLvl2_1->Add(m_checkUseTransformerPower, 0, wxALL, WXC_FROM_DIP(5));
1824 
1825  m_panelFault = new wxPanel(m_notebook, wxID_ANY, wxDefaultPosition, wxDLG_UNIT(m_notebook, wxSize(-1,-1)), wxTAB_TRAVERSAL);
1826  m_notebook->AddPage(m_panelFault, _("Fault"), false);
1827 
1828  wxBoxSizer* boxSizerLvl2_2 = new wxBoxSizer(wxVERTICAL);
1829  m_panelFault->SetSizer(boxSizerLvl2_2);
1830 
1831  wxStaticBoxSizer* staticBoxSizerZeroImpSeq = new wxStaticBoxSizer( new wxStaticBox(m_panelFault, wxID_ANY, _("Zero-sequence impedances (p.u.)")), wxVERTICAL);
1832 
1833  boxSizerLvl2_2->Add(staticBoxSizerZeroImpSeq, 0, wxALL|wxEXPAND, WXC_FROM_DIP(5));
1834 
1835  wxGridSizer* gridSizerLvl3_3 = new wxGridSizer(0, 2, 0, 0);
1836 
1837  staticBoxSizerZeroImpSeq->Add(gridSizerLvl3_3, 0, wxEXPAND, WXC_FROM_DIP(5));
1838 
1839  wxBoxSizer* boxSizerLvl4_8 = new wxBoxSizer(wxVERTICAL);
1840 
1841  gridSizerLvl3_3->Add(boxSizerLvl4_8, 0, wxEXPAND, WXC_FROM_DIP(5));
1842 
1843  m_staticTextZeroResistance = new wxStaticText(m_panelFault, wxID_ANY, _("Resistance (R0)"), wxDefaultPosition, wxDLG_UNIT(m_panelFault, wxSize(-1,-1)), 0);
1844 
1845  boxSizerLvl4_8->Add(m_staticTextZeroResistance, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
1846 
1847  m_textCtrlZeroResistance = new wxTextCtrl(m_panelFault, wxID_ANY, wxT(""), wxDefaultPosition, wxDLG_UNIT(m_panelFault, wxSize(-1,-1)), 0);
1848  #if wxVERSION_NUMBER >= 3000
1849  m_textCtrlZeroResistance->SetHint(wxT(""));
1850  #endif
1851 
1852  boxSizerLvl4_8->Add(m_textCtrlZeroResistance, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxEXPAND|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
1853 
1854  wxBoxSizer* boxSizerLvl4_9 = new wxBoxSizer(wxVERTICAL);
1855 
1856  gridSizerLvl3_3->Add(boxSizerLvl4_9, 0, wxEXPAND, WXC_FROM_DIP(5));
1857 
1858  m_staticTextZeroReactance = new wxStaticText(m_panelFault, wxID_ANY, _("Indutive reactance (X0)"), wxDefaultPosition, wxDLG_UNIT(m_panelFault, wxSize(-1,-1)), 0);
1859 
1860  boxSizerLvl4_9->Add(m_staticTextZeroReactance, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
1861 
1862  m_textCtrlZeroReactance = new wxTextCtrl(m_panelFault, wxID_ANY, wxT(""), wxDefaultPosition, wxDLG_UNIT(m_panelFault, wxSize(-1,-1)), 0);
1863  #if wxVERSION_NUMBER >= 3000
1864  m_textCtrlZeroReactance->SetHint(wxT(""));
1865  #endif
1866 
1867  boxSizerLvl4_9->Add(m_textCtrlZeroReactance, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxEXPAND|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
1868 
1869  wxStaticBoxSizer* staticBoxSizerGroundImpedances = new wxStaticBoxSizer( new wxStaticBox(m_panelFault, wxID_ANY, _("Ground impedances (p.u.)")), wxVERTICAL);
1870 
1871  boxSizerLvl2_2->Add(staticBoxSizerGroundImpedances, 0, wxALL|wxEXPAND, WXC_FROM_DIP(5));
1872 
1873  wxGridSizer* gridSizerLvl3_4 = new wxGridSizer(0, 2, 0, 0);
1874 
1875  staticBoxSizerGroundImpedances->Add(gridSizerLvl3_4, 0, wxEXPAND, WXC_FROM_DIP(5));
1876 
1877  wxBoxSizer* boxSizerLvl4_10 = new wxBoxSizer(wxVERTICAL);
1878 
1879  gridSizerLvl3_4->Add(boxSizerLvl4_10, 0, wxEXPAND, WXC_FROM_DIP(5));
1880 
1881  m_staticTextPrimResistance = new wxStaticText(m_panelFault, wxID_ANY, _("Primary resistance"), wxDefaultPosition, wxDLG_UNIT(m_panelFault, wxSize(-1,-1)), 0);
1882 
1883  boxSizerLvl4_10->Add(m_staticTextPrimResistance, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
1884 
1885  m_textCtrlPrimResistance = new wxTextCtrl(m_panelFault, wxID_ANY, wxT(""), wxDefaultPosition, wxDLG_UNIT(m_panelFault, wxSize(-1,-1)), 0);
1886  #if wxVERSION_NUMBER >= 3000
1887  m_textCtrlPrimResistance->SetHint(wxT(""));
1888  #endif
1889 
1890  boxSizerLvl4_10->Add(m_textCtrlPrimResistance, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxEXPAND|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
1891 
1892  wxBoxSizer* boxSizerLvl4_11 = new wxBoxSizer(wxVERTICAL);
1893 
1894  gridSizerLvl3_4->Add(boxSizerLvl4_11, 0, wxEXPAND, WXC_FROM_DIP(5));
1895 
1896  m_staticTextPrimReactance = new wxStaticText(m_panelFault, wxID_ANY, _("Primary reactance"), wxDefaultPosition, wxDLG_UNIT(m_panelFault, wxSize(-1,-1)), 0);
1897 
1898  boxSizerLvl4_11->Add(m_staticTextPrimReactance, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
1899 
1900  m_textCtrlPrimReactance = new wxTextCtrl(m_panelFault, wxID_ANY, wxT(""), wxDefaultPosition, wxDLG_UNIT(m_panelFault, wxSize(-1,-1)), 0);
1901  #if wxVERSION_NUMBER >= 3000
1902  m_textCtrlPrimReactance->SetHint(wxT(""));
1903  #endif
1904 
1905  boxSizerLvl4_11->Add(m_textCtrlPrimReactance, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxEXPAND|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
1906 
1907  wxBoxSizer* boxSizerLvl4_12 = new wxBoxSizer(wxVERTICAL);
1908 
1909  gridSizerLvl3_4->Add(boxSizerLvl4_12, 0, wxEXPAND, WXC_FROM_DIP(5));
1910 
1911  m_staticTextSecResistance = new wxStaticText(m_panelFault, wxID_ANY, _("Secondary resistance"), wxDefaultPosition, wxDLG_UNIT(m_panelFault, wxSize(-1,-1)), 0);
1912 
1913  boxSizerLvl4_12->Add(m_staticTextSecResistance, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
1914 
1915  m_textCtrlSecResistance = new wxTextCtrl(m_panelFault, wxID_ANY, wxT(""), wxDefaultPosition, wxDLG_UNIT(m_panelFault, wxSize(-1,-1)), 0);
1916  #if wxVERSION_NUMBER >= 3000
1917  m_textCtrlSecResistance->SetHint(wxT(""));
1918  #endif
1919 
1920  boxSizerLvl4_12->Add(m_textCtrlSecResistance, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxEXPAND|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
1921 
1922  wxBoxSizer* boxSizerLvl4_13 = new wxBoxSizer(wxVERTICAL);
1923 
1924  gridSizerLvl3_4->Add(boxSizerLvl4_13, 0, wxEXPAND, WXC_FROM_DIP(5));
1925 
1926  m_staticTextSecReactance = new wxStaticText(m_panelFault, wxID_ANY, _("Secondary reactance"), wxDefaultPosition, wxDLG_UNIT(m_panelFault, wxSize(-1,-1)), 0);
1927 
1928  boxSizerLvl4_13->Add(m_staticTextSecReactance, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
1929 
1930  m_textCtrlSecReactance = new wxTextCtrl(m_panelFault, wxID_ANY, wxT(""), wxDefaultPosition, wxDLG_UNIT(m_panelFault, wxSize(-1,-1)), 0);
1931  #if wxVERSION_NUMBER >= 3000
1932  m_textCtrlSecReactance->SetHint(wxT(""));
1933  #endif
1934 
1935  boxSizerLvl4_13->Add(m_textCtrlSecReactance, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxEXPAND|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
1936 
1937  wxBoxSizer* boxSizerBottomButtons = new wxBoxSizer(wxHORIZONTAL);
1938 
1939  boxSizerLvl1_1->Add(boxSizerBottomButtons, 0, wxALL|wxEXPAND, WXC_FROM_DIP(5));
1940 
1941  m_buttonStability = new wxButton(this, wxID_ANY, _("Stability"), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
1942 
1943  boxSizerBottomButtons->Add(m_buttonStability, 0, wxALL|wxALIGN_LEFT, WXC_FROM_DIP(5));
1944 
1945  boxSizerBottomButtons->Add(0, 0, 1, wxALL|wxEXPAND, WXC_FROM_DIP(5));
1946 
1947  m_buttonOK = new wxButton(this, wxID_ANY, _("OK"), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
1948 
1949  boxSizerBottomButtons->Add(m_buttonOK, 0, wxALL|wxALIGN_RIGHT, WXC_FROM_DIP(5));
1950 
1951  m_buttonCancel = new wxButton(this, wxID_ANY, _("Cancel"), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
1952 
1953  boxSizerBottomButtons->Add(m_buttonCancel, 0, wxALL|wxALIGN_RIGHT, WXC_FROM_DIP(5));
1954 
1955 
1956  #if wxVERSION_NUMBER >= 2900
1957  if(!wxPersistenceManager::Get().Find(m_notebook)){
1958  wxPersistenceManager::Get().RegisterAndRestore(m_notebook);
1959  } else {
1960  wxPersistenceManager::Get().Restore(m_notebook);
1961  }
1962  #endif
1963 
1964  SetName(wxT("TransformerFormBase"));
1965  SetSize(-1,-1);
1966  if (GetSizer()) {
1967  GetSizer()->Fit(this);
1968  }
1969  if(GetParent()) {
1970  CentreOnParent(wxBOTH);
1971  } else {
1972  CentreOnScreen(wxBOTH);
1973  }
1974 #if wxVERSION_NUMBER >= 2900
1975  if(!wxPersistenceManager::Get().Find(this)) {
1976  wxPersistenceManager::Get().RegisterAndRestore(this);
1977  } else {
1978  wxPersistenceManager::Get().Restore(this);
1979  }
1980 #endif
1981  // Connect events
1982  m_buttonStability->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(TransformerFormBase::OnStabilityButtonClick), NULL, this);
1983  m_buttonOK->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(TransformerFormBase::OnOKButtonClick), NULL, this);
1984  m_buttonCancel->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(TransformerFormBase::OnCancelButtonClick), NULL, this);
1985 
1986 }
1987 
1988 TransformerFormBase::~TransformerFormBase()
1989 {
1990  m_buttonStability->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(TransformerFormBase::OnStabilityButtonClick), NULL, this);
1991  m_buttonOK->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(TransformerFormBase::OnOKButtonClick), NULL, this);
1992  m_buttonCancel->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(TransformerFormBase::OnCancelButtonClick), NULL, this);
1993 
1994 }
1995 
1996 LoadFormBase::LoadFormBase(wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style)
1997  : wxDialog(parent, id, title, pos, size, style)
1998 {
1999  if ( !bBitmapLoaded ) {
2000  // We need to initialise the default bitmap handler
2001  wxXmlResource::Get()->AddHandler(new wxBitmapXmlHandler);
2002  wxC9EE9InitBitmapResources();
2003  bBitmapLoaded = true;
2004  }
2005 
2006  wxBoxSizer* boxSizerLvl1_1 = new wxBoxSizer(wxVERTICAL);
2007  this->SetSizer(boxSizerLvl1_1);
2008 
2009  m_notebook = new wxNotebook(this, wxID_ANY, wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), wxBK_DEFAULT);
2010  m_notebook->SetName(wxT("m_notebook"));
2011 
2012  boxSizerLvl1_1->Add(m_notebook, 1, wxEXPAND, WXC_FROM_DIP(5));
2013 
2014  m_panelGeneral = new wxPanel(m_notebook, wxID_ANY, wxDefaultPosition, wxDLG_UNIT(m_notebook, wxSize(-1,-1)), wxTAB_TRAVERSAL);
2015  m_notebook->AddPage(m_panelGeneral, _("General"), false);
2016 
2017  wxBoxSizer* boxSizerLvl2_1 = new wxBoxSizer(wxVERTICAL);
2018  m_panelGeneral->SetSizer(boxSizerLvl2_1);
2019 
2020  m_staticTextName = new wxStaticText(m_panelGeneral, wxID_ANY, _("Name"), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
2021 
2022  boxSizerLvl2_1->Add(m_staticTextName, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
2023 
2024  m_textCtrlName = new wxTextCtrl(m_panelGeneral, wxID_ANY, wxT(""), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
2025  #if wxVERSION_NUMBER >= 3000
2026  m_textCtrlName->SetHint(wxT(""));
2027  #endif
2028 
2029  boxSizerLvl2_1->Add(m_textCtrlName, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxEXPAND|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
2030  m_textCtrlName->SetMinSize(wxSize(300,-1));
2031 
2032  wxGridSizer* gridSizerLvl3_1 = new wxGridSizer(0, 2, 0, 0);
2033 
2034  boxSizerLvl2_1->Add(gridSizerLvl3_1, 0, wxEXPAND, WXC_FROM_DIP(5));
2035 
2036  wxBoxSizer* boxSizerLvl4_1 = new wxBoxSizer(wxVERTICAL);
2037 
2038  gridSizerLvl3_1->Add(boxSizerLvl4_1, 0, wxEXPAND, WXC_FROM_DIP(5));
2039 
2040  m_staticTextActivePower = new wxStaticText(m_panelGeneral, wxID_ANY, _("Active power"), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
2041 
2042  boxSizerLvl4_1->Add(m_staticTextActivePower, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
2043 
2044  wxBoxSizer* boxSizerLvl5_1 = new wxBoxSizer(wxHORIZONTAL);
2045 
2046  boxSizerLvl4_1->Add(boxSizerLvl5_1, 0, wxEXPAND, WXC_FROM_DIP(5));
2047 
2048  m_textCtrlActivePower = new wxTextCtrl(m_panelGeneral, wxID_ANY, wxT(""), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
2049  #if wxVERSION_NUMBER >= 3000
2050  m_textCtrlActivePower->SetHint(wxT(""));
2051  #endif
2052 
2053  boxSizerLvl5_1->Add(m_textCtrlActivePower, 1, wxLEFT|wxRIGHT|wxBOTTOM|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
2054 
2055  wxArrayString m_choiceActivePowerArr;
2056  m_choiceActivePowerArr.Add(wxT("p.u."));
2057  m_choiceActivePowerArr.Add(wxT("W"));
2058  m_choiceActivePowerArr.Add(wxT("kW"));
2059  m_choiceActivePowerArr.Add(wxT("MW"));
2060  m_choiceActivePower = new wxChoice(m_panelGeneral, wxID_ANY, wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), m_choiceActivePowerArr, 0);
2061  m_choiceActivePower->SetSelection(3);
2062 
2063  boxSizerLvl5_1->Add(m_choiceActivePower, 0, wxLEFT|wxRIGHT|wxBOTTOM, WXC_FROM_DIP(5));
2064 
2065  wxBoxSizer* boxSizerLvl4_2 = new wxBoxSizer(wxVERTICAL);
2066 
2067  gridSizerLvl3_1->Add(boxSizerLvl4_2, 0, wxEXPAND, WXC_FROM_DIP(5));
2068 
2069  m_staticTextReactivePower = new wxStaticText(m_panelGeneral, wxID_ANY, _("Reactive power"), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
2070 
2071  boxSizerLvl4_2->Add(m_staticTextReactivePower, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
2072 
2073  wxBoxSizer* boxSizerLvl5_2 = new wxBoxSizer(wxHORIZONTAL);
2074 
2075  boxSizerLvl4_2->Add(boxSizerLvl5_2, 0, wxEXPAND, WXC_FROM_DIP(5));
2076 
2077  m_textCtrlReactivePower = new wxTextCtrl(m_panelGeneral, wxID_ANY, wxT(""), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
2078  #if wxVERSION_NUMBER >= 3000
2079  m_textCtrlReactivePower->SetHint(wxT(""));
2080  #endif
2081 
2082  boxSizerLvl5_2->Add(m_textCtrlReactivePower, 1, wxLEFT|wxRIGHT|wxBOTTOM|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
2083 
2084  wxArrayString m_choiceReactivePowerArr;
2085  m_choiceReactivePowerArr.Add(wxT("p.u."));
2086  m_choiceReactivePowerArr.Add(wxT("VAr"));
2087  m_choiceReactivePowerArr.Add(wxT("kVAr"));
2088  m_choiceReactivePowerArr.Add(wxT("MVAr"));
2089  m_choiceReactivePower = new wxChoice(m_panelGeneral, wxID_ANY, wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), m_choiceReactivePowerArr, 0);
2090  m_choiceReactivePower->SetSelection(3);
2091 
2092  boxSizerLvl5_2->Add(m_choiceReactivePower, 0, wxLEFT|wxRIGHT|wxBOTTOM, WXC_FROM_DIP(5));
2093 
2094  m_staticTextType = new wxStaticText(m_panelGeneral, wxID_ANY, _("Load type"), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
2095 
2096  boxSizerLvl2_1->Add(m_staticTextType, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
2097 
2098  wxArrayString m_choiceTypeArr;
2099  m_choiceTypeArr.Add(wxT("Constant power"));
2100  m_choiceTypeArr.Add(wxT("Constant impedance"));
2101  m_choiceType = new wxChoice(m_panelGeneral, wxID_ANY, wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), m_choiceTypeArr, 0);
2102  m_choiceType->SetSelection(0);
2103 
2104  boxSizerLvl2_1->Add(m_choiceType, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxEXPAND, WXC_FROM_DIP(5));
2105 
2106  wxBoxSizer* boxSizerBottomButtons = new wxBoxSizer(wxHORIZONTAL);
2107 
2108  boxSizerLvl1_1->Add(boxSizerBottomButtons, 0, wxALL|wxEXPAND, WXC_FROM_DIP(5));
2109 
2110  m_buttonStabButton = new wxButton(this, wxID_ANY, _("Stability"), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
2111 
2112  boxSizerBottomButtons->Add(m_buttonStabButton, 0, wxALL|wxALIGN_LEFT, WXC_FROM_DIP(5));
2113 
2114  boxSizerBottomButtons->Add(0, 0, 1, wxALL, WXC_FROM_DIP(5));
2115 
2116  m_buttonOK = new wxButton(this, wxID_ANY, _("OK"), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
2117 
2118  boxSizerBottomButtons->Add(m_buttonOK, 0, wxALL|wxALIGN_RIGHT, WXC_FROM_DIP(5));
2119 
2120  m_ButtonCancel = new wxButton(this, wxID_ANY, _("Cancel"), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
2121 
2122  boxSizerBottomButtons->Add(m_ButtonCancel, 0, wxALL|wxALIGN_RIGHT, WXC_FROM_DIP(5));
2123 
2124 
2125  #if wxVERSION_NUMBER >= 2900
2126  if(!wxPersistenceManager::Get().Find(m_notebook)){
2127  wxPersistenceManager::Get().RegisterAndRestore(m_notebook);
2128  } else {
2129  wxPersistenceManager::Get().Restore(m_notebook);
2130  }
2131  #endif
2132 
2133  SetName(wxT("LoadFormBase"));
2134  SetSize(-1,-1);
2135  if (GetSizer()) {
2136  GetSizer()->Fit(this);
2137  }
2138  if(GetParent()) {
2139  CentreOnParent(wxBOTH);
2140  } else {
2141  CentreOnScreen(wxBOTH);
2142  }
2143 #if wxVERSION_NUMBER >= 2900
2144  if(!wxPersistenceManager::Get().Find(this)) {
2145  wxPersistenceManager::Get().RegisterAndRestore(this);
2146  } else {
2147  wxPersistenceManager::Get().Restore(this);
2148  }
2149 #endif
2150  // Connect events
2151  m_buttonStabButton->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(LoadFormBase::OnStabilityButtonClick), NULL, this);
2152  m_buttonOK->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(LoadFormBase::OnOnButtonClick), NULL, this);
2153  m_ButtonCancel->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(LoadFormBase::OnCancelButtonClick), NULL, this);
2154 
2155 }
2156 
2157 LoadFormBase::~LoadFormBase()
2158 {
2159  m_buttonStabButton->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(LoadFormBase::OnStabilityButtonClick), NULL, this);
2160  m_buttonOK->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(LoadFormBase::OnOnButtonClick), NULL, this);
2161  m_ButtonCancel->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(LoadFormBase::OnCancelButtonClick), NULL, this);
2162 
2163 }
2164 
2165 ReactiveShuntElementFormBase::ReactiveShuntElementFormBase(wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style)
2166  : wxDialog(parent, id, title, pos, size, style)
2167 {
2168  if ( !bBitmapLoaded ) {
2169  // We need to initialise the default bitmap handler
2170  wxXmlResource::Get()->AddHandler(new wxBitmapXmlHandler);
2171  wxC9EE9InitBitmapResources();
2172  bBitmapLoaded = true;
2173  }
2174 
2175  wxBoxSizer* boxSizerLvl1_1 = new wxBoxSizer(wxVERTICAL);
2176  this->SetSizer(boxSizerLvl1_1);
2177 
2178  m_notebook = new wxNotebook(this, wxID_ANY, wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), wxBK_DEFAULT);
2179  m_notebook->SetName(wxT("m_notebook"));
2180 
2181  boxSizerLvl1_1->Add(m_notebook, 1, wxEXPAND, WXC_FROM_DIP(5));
2182 
2183  m_panelGeneral = new wxPanel(m_notebook, wxID_ANY, wxDefaultPosition, wxDLG_UNIT(m_notebook, wxSize(-1,-1)), wxTAB_TRAVERSAL);
2184  m_notebook->AddPage(m_panelGeneral, _("General"), false);
2185 
2186  wxBoxSizer* boxSizerLvl2_1 = new wxBoxSizer(wxVERTICAL);
2187  m_panelGeneral->SetSizer(boxSizerLvl2_1);
2188 
2189  m_staticTextName = new wxStaticText(m_panelGeneral, wxID_ANY, _("Name"), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
2190 
2191  boxSizerLvl2_1->Add(m_staticTextName, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
2192 
2193  m_textCtrlName = new wxTextCtrl(m_panelGeneral, wxID_ANY, wxT(""), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
2194  #if wxVERSION_NUMBER >= 3000
2195  m_textCtrlName->SetHint(wxT(""));
2196  #endif
2197 
2198  boxSizerLvl2_1->Add(m_textCtrlName, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxEXPAND|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
2199  m_textCtrlName->SetMinSize(wxSize(300,-1));
2200 
2201  wxGridSizer* gridSizerLvl3_1 = new wxGridSizer(0, 2, 0, 0);
2202 
2203  boxSizerLvl2_1->Add(gridSizerLvl3_1, 0, wxEXPAND, WXC_FROM_DIP(5));
2204 
2205  wxBoxSizer* boxSizerLvl4_2 = new wxBoxSizer(wxVERTICAL);
2206 
2207  gridSizerLvl3_1->Add(boxSizerLvl4_2, 0, wxEXPAND, WXC_FROM_DIP(5));
2208 
2209  m_staticTextReactivePower = new wxStaticText(m_panelGeneral, wxID_ANY, _("Reactive power"), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
2210 
2211  boxSizerLvl4_2->Add(m_staticTextReactivePower, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
2212 
2213  wxBoxSizer* boxSizerLvl5_2 = new wxBoxSizer(wxHORIZONTAL);
2214 
2215  boxSizerLvl4_2->Add(boxSizerLvl5_2, 0, wxEXPAND, WXC_FROM_DIP(5));
2216 
2217  m_textCtrlReactivePower = new wxTextCtrl(m_panelGeneral, wxID_ANY, wxT(""), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
2218  #if wxVERSION_NUMBER >= 3000
2219  m_textCtrlReactivePower->SetHint(wxT(""));
2220  #endif
2221 
2222  boxSizerLvl5_2->Add(m_textCtrlReactivePower, 1, wxLEFT|wxRIGHT|wxBOTTOM|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
2223 
2224  wxArrayString m_choiceReactivePowerArr;
2225  m_choiceReactivePowerArr.Add(wxT("p.u."));
2226  m_choiceReactivePowerArr.Add(wxT("VAr"));
2227  m_choiceReactivePowerArr.Add(wxT("kVAr"));
2228  m_choiceReactivePowerArr.Add(wxT("MVAr"));
2229  m_choiceReactivePower = new wxChoice(m_panelGeneral, wxID_ANY, wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), m_choiceReactivePowerArr, 0);
2230  m_choiceReactivePower->SetSelection(3);
2231 
2232  boxSizerLvl5_2->Add(m_choiceReactivePower, 0, wxLEFT|wxRIGHT|wxBOTTOM, WXC_FROM_DIP(5));
2233 
2234  wxBoxSizer* boxSizerBottomButtons = new wxBoxSizer(wxHORIZONTAL);
2235 
2236  boxSizerLvl1_1->Add(boxSizerBottomButtons, 0, wxALL|wxEXPAND, WXC_FROM_DIP(5));
2237 
2238  m_buttonStabButton = new wxButton(this, wxID_ANY, _("Stability"), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
2239 
2240  boxSizerBottomButtons->Add(m_buttonStabButton, 0, wxALL|wxALIGN_LEFT, WXC_FROM_DIP(5));
2241 
2242  boxSizerBottomButtons->Add(0, 0, 1, wxALL, WXC_FROM_DIP(5));
2243 
2244  m_buttonOK = new wxButton(this, wxID_ANY, _("OK"), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
2245 
2246  boxSizerBottomButtons->Add(m_buttonOK, 0, wxALL|wxALIGN_RIGHT, WXC_FROM_DIP(5));
2247 
2248  m_buttonCancel = new wxButton(this, wxID_ANY, _("Cancel"), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
2249 
2250  boxSizerBottomButtons->Add(m_buttonCancel, 0, wxALL|wxALIGN_RIGHT, WXC_FROM_DIP(5));
2251 
2252 
2253  #if wxVERSION_NUMBER >= 2900
2254  if(!wxPersistenceManager::Get().Find(m_notebook)){
2255  wxPersistenceManager::Get().RegisterAndRestore(m_notebook);
2256  } else {
2257  wxPersistenceManager::Get().Restore(m_notebook);
2258  }
2259  #endif
2260 
2261  SetName(wxT("ReactiveShuntElementFormBase"));
2262  SetSize(-1,-1);
2263  if (GetSizer()) {
2264  GetSizer()->Fit(this);
2265  }
2266  if(GetParent()) {
2267  CentreOnParent(wxBOTH);
2268  } else {
2269  CentreOnScreen(wxBOTH);
2270  }
2271 #if wxVERSION_NUMBER >= 2900
2272  if(!wxPersistenceManager::Get().Find(this)) {
2273  wxPersistenceManager::Get().RegisterAndRestore(this);
2274  } else {
2275  wxPersistenceManager::Get().Restore(this);
2276  }
2277 #endif
2278  // Connect events
2279  m_buttonStabButton->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(ReactiveShuntElementFormBase::OnStabilityButtonClick), NULL, this);
2280  m_buttonOK->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(ReactiveShuntElementFormBase::OnOKButtonClick), NULL, this);
2281  m_buttonCancel->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(ReactiveShuntElementFormBase::OnCancelButtonClick), NULL, this);
2282 
2283 }
2284 
2285 ReactiveShuntElementFormBase::~ReactiveShuntElementFormBase()
2286 {
2287  m_buttonStabButton->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(ReactiveShuntElementFormBase::OnStabilityButtonClick), NULL, this);
2288  m_buttonOK->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(ReactiveShuntElementFormBase::OnOKButtonClick), NULL, this);
2289  m_buttonCancel->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(ReactiveShuntElementFormBase::OnCancelButtonClick), NULL, this);
2290 
2291 }
2292 
2293 SwitchingFormBase::SwitchingFormBase(wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style)
2294  : wxDialog(parent, id, title, pos, size, style)
2295 {
2296  if ( !bBitmapLoaded ) {
2297  // We need to initialise the default bitmap handler
2298  wxXmlResource::Get()->AddHandler(new wxBitmapXmlHandler);
2299  wxC9EE9InitBitmapResources();
2300  bBitmapLoaded = true;
2301  }
2302 
2303  wxBoxSizer* boxSizerLvl1_1 = new wxBoxSizer(wxVERTICAL);
2304  this->SetSizer(boxSizerLvl1_1);
2305 
2306  wxBoxSizer* boxSizerLvl2_1 = new wxBoxSizer(wxHORIZONTAL);
2307 
2308  boxSizerLvl1_1->Add(boxSizerLvl2_1, 0, wxALL, WXC_FROM_DIP(5));
2309 
2310  wxBoxSizer* boxSizerLvl3_1 = new wxBoxSizer(wxVERTICAL);
2311 
2312  boxSizerLvl2_1->Add(boxSizerLvl3_1, 0, wxALL|wxEXPAND, WXC_FROM_DIP(5));
2313 
2314  wxArrayString m_pgMgrSwitchingsPropArr;
2315  wxUnusedVar(m_pgMgrSwitchingsPropArr);
2316  wxArrayInt m_pgMgrSwitchingsPropIntArr;
2317  wxUnusedVar(m_pgMgrSwitchingsPropIntArr);
2318  m_pgMgrSwitchingsProp = new wxPropertyGridManager(this, wxID_ANY, wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), wxPG_STATIC_LAYOUT|wxPG_SPLITTER_AUTO_CENTER|wxPG_BOLD_MODIFIED);
2319 
2320  boxSizerLvl3_1->Add(m_pgMgrSwitchingsProp, 1, wxALL, WXC_FROM_DIP(5));
2321 
2322  m_pgPropTitle = m_pgMgrSwitchingsProp->Append( new wxPropertyCategory( _("Switching properties") ) );
2323  m_pgPropTitle->SetHelpString(wxT(""));
2324 
2325  m_pgMgrSwitchingsPropArr.Clear();
2326  m_pgMgrSwitchingsPropIntArr.Clear();
2327  m_pgMgrSwitchingsPropArr.Add(_("Insert"));
2328  m_pgMgrSwitchingsPropArr.Add(_("Remove"));
2329  m_pgPropType = m_pgMgrSwitchingsProp->Append( new wxEnumProperty( _("Type"), wxPG_LABEL, m_pgMgrSwitchingsPropArr, m_pgMgrSwitchingsPropIntArr, 0) );
2330  m_pgPropType->SetHelpString(wxT(""));
2331 
2332  m_pgPropTime = m_pgMgrSwitchingsProp->Append( new wxFloatProperty( _("Time (s)"), wxPG_LABEL, 0) );
2333  m_pgPropTime->SetHelpString(wxT(""));
2334  m_pgMgrSwitchingsProp->SetMinSize(wxSize(150,-1));
2335 
2336  wxBoxSizer* boxSizerLvl3_3 = new wxBoxSizer(wxVERTICAL);
2337 
2338  boxSizerLvl2_1->Add(boxSizerLvl3_3, 0, wxALL|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
2339 
2340  m_buttonInsert = new wxButton(this, wxID_ANY, _("Add"), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
2341 
2342  boxSizerLvl3_3->Add(m_buttonInsert, 0, wxALL|wxALIGN_RIGHT, WXC_FROM_DIP(5));
2343 
2344  m_buttonRemove = new wxButton(this, wxID_ANY, _("Remove"), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
2345 
2346  boxSizerLvl3_3->Add(m_buttonRemove, 0, wxALL|wxALIGN_RIGHT, WXC_FROM_DIP(5));
2347 
2348  m_buttonUp = new wxButton(this, wxID_ANY, _("Up"), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
2349 
2350  boxSizerLvl3_3->Add(m_buttonUp, 0, wxALL|wxALIGN_RIGHT, WXC_FROM_DIP(5));
2351 
2352  m_buttonDown = new wxButton(this, wxID_ANY, _("Down"), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
2353 
2354  boxSizerLvl3_3->Add(m_buttonDown, 0, wxALL|wxALIGN_RIGHT, WXC_FROM_DIP(5));
2355 
2356  wxBoxSizer* boxSizerLvl3_2 = new wxBoxSizer(wxVERTICAL);
2357 
2358  boxSizerLvl2_1->Add(boxSizerLvl3_2, 0, wxALL, WXC_FROM_DIP(5));
2359 
2360  m_staticTextSwList = new wxStaticText(this, wxID_ANY, _("Switching list"), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
2361 
2362  boxSizerLvl3_2->Add(m_staticTextSwList, 0, wxLEFT|wxRIGHT|wxTOP, WXC_FROM_DIP(5));
2363 
2364  m_listCtrlSwitchings = new wxListCtrl(this, wxID_ANY, wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), wxLC_REPORT);
2365 
2366  boxSizerLvl3_2->Add(m_listCtrlSwitchings, 0, wxLEFT|wxRIGHT|wxBOTTOM, WXC_FROM_DIP(5));
2367 
2368  wxBoxSizer* boxSizerBottomButtons = new wxBoxSizer(wxHORIZONTAL);
2369 
2370  boxSizerLvl1_1->Add(boxSizerBottomButtons, 0, wxALL|wxALIGN_RIGHT, WXC_FROM_DIP(5));
2371 
2372  m_buttonOK = new wxButton(this, wxID_ANY, _("OK"), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
2373 
2374  boxSizerBottomButtons->Add(m_buttonOK, 0, wxALL|wxALIGN_RIGHT, WXC_FROM_DIP(5));
2375 
2376  m_buttonCancel = new wxButton(this, wxID_ANY, _("Cancel"), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
2377 
2378  boxSizerBottomButtons->Add(m_buttonCancel, 0, wxALL|wxALIGN_RIGHT, WXC_FROM_DIP(5));
2379 
2380  SetName(wxT("SwitchingFormBase"));
2381  SetSize(-1,-1);
2382  if (GetSizer()) {
2383  GetSizer()->Fit(this);
2384  }
2385  if(GetParent()) {
2386  CentreOnParent(wxBOTH);
2387  } else {
2388  CentreOnScreen(wxBOTH);
2389  }
2390 #if wxVERSION_NUMBER >= 2900
2391  if(!wxPersistenceManager::Get().Find(this)) {
2392  wxPersistenceManager::Get().RegisterAndRestore(this);
2393  } else {
2394  wxPersistenceManager::Get().Restore(this);
2395  }
2396 #endif
2397  // Connect events
2398  m_pgMgrSwitchingsProp->Connect(wxEVT_PG_CHANGED, wxPropertyGridEventHandler(SwitchingFormBase::OnChangeProperties), NULL, this);
2399  m_buttonInsert->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(SwitchingFormBase::OnInsertButtonClick), NULL, this);
2400  m_buttonRemove->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(SwitchingFormBase::OnRemoveButtonClick), NULL, this);
2401  m_buttonUp->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(SwitchingFormBase::OnUpButtonClick), NULL, this);
2402  m_buttonDown->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(SwitchingFormBase::OnDownButtonClick), NULL, this);
2403  m_listCtrlSwitchings->Connect(wxEVT_COMMAND_LIST_ITEM_SELECTED, wxListEventHandler(SwitchingFormBase::OnSelectItem), NULL, this);
2404  m_buttonOK->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(SwitchingFormBase::OnOKButtonClick), NULL, this);
2405  m_buttonCancel->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(SwitchingFormBase::OnCancelButtonClick), NULL, this);
2406 
2407 }
2408 
2409 SwitchingFormBase::~SwitchingFormBase()
2410 {
2411  m_pgMgrSwitchingsProp->Disconnect(wxEVT_PG_CHANGED, wxPropertyGridEventHandler(SwitchingFormBase::OnChangeProperties), NULL, this);
2412  m_buttonInsert->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(SwitchingFormBase::OnInsertButtonClick), NULL, this);
2413  m_buttonRemove->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(SwitchingFormBase::OnRemoveButtonClick), NULL, this);
2414  m_buttonUp->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(SwitchingFormBase::OnUpButtonClick), NULL, this);
2415  m_buttonDown->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(SwitchingFormBase::OnDownButtonClick), NULL, this);
2416  m_listCtrlSwitchings->Disconnect(wxEVT_COMMAND_LIST_ITEM_SELECTED, wxListEventHandler(SwitchingFormBase::OnSelectItem), NULL, this);
2417  m_buttonOK->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(SwitchingFormBase::OnOKButtonClick), NULL, this);
2418  m_buttonCancel->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(SwitchingFormBase::OnCancelButtonClick), NULL, this);
2419 
2420 }
2421 
2422 IndMotorFormBase::IndMotorFormBase(wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style)
2423  : wxDialog(parent, id, title, pos, size, style)
2424 {
2425  if ( !bBitmapLoaded ) {
2426  // We need to initialise the default bitmap handler
2427  wxXmlResource::Get()->AddHandler(new wxBitmapXmlHandler);
2428  wxC9EE9InitBitmapResources();
2429  bBitmapLoaded = true;
2430  }
2431 
2432  wxBoxSizer* boxSizerLvl1_1 = new wxBoxSizer(wxVERTICAL);
2433  this->SetSizer(boxSizerLvl1_1);
2434 
2435  m_notebook = new wxNotebook(this, wxID_ANY, wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), wxBK_DEFAULT);
2436  m_notebook->SetName(wxT("m_notebook"));
2437 
2438  boxSizerLvl1_1->Add(m_notebook, 1, wxEXPAND, WXC_FROM_DIP(5));
2439 
2440  m_panelGeneral = new wxPanel(m_notebook, wxID_ANY, wxDefaultPosition, wxDLG_UNIT(m_notebook, wxSize(-1,-1)), wxTAB_TRAVERSAL);
2441  m_notebook->AddPage(m_panelGeneral, _("General"), false);
2442 
2443  wxBoxSizer* boxSizerLvl2_1 = new wxBoxSizer(wxVERTICAL);
2444  m_panelGeneral->SetSizer(boxSizerLvl2_1);
2445 
2446  m_staticTextName = new wxStaticText(m_panelGeneral, wxID_ANY, _("Name"), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
2447 
2448  boxSizerLvl2_1->Add(m_staticTextName, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
2449 
2450  m_textCtrlName = new wxTextCtrl(m_panelGeneral, wxID_ANY, wxT(""), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
2451  #if wxVERSION_NUMBER >= 3000
2452  m_textCtrlName->SetHint(wxT(""));
2453  #endif
2454 
2455  boxSizerLvl2_1->Add(m_textCtrlName, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxEXPAND|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
2456  m_textCtrlName->SetMinSize(wxSize(300,-1));
2457 
2458  wxGridSizer* gridSizerLvl3_1 = new wxGridSizer(0, 2, 0, 0);
2459 
2460  boxSizerLvl2_1->Add(gridSizerLvl3_1, 0, wxEXPAND, WXC_FROM_DIP(5));
2461 
2462  wxBoxSizer* boxSizerLvl4_1 = new wxBoxSizer(wxVERTICAL);
2463 
2464  gridSizerLvl3_1->Add(boxSizerLvl4_1, 0, wxEXPAND, WXC_FROM_DIP(5));
2465 
2466  m_staticTextActivePower = new wxStaticText(m_panelGeneral, wxID_ANY, _("Active power"), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
2467 
2468  boxSizerLvl4_1->Add(m_staticTextActivePower, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
2469 
2470  wxBoxSizer* boxSizerLvl5_1 = new wxBoxSizer(wxHORIZONTAL);
2471 
2472  boxSizerLvl4_1->Add(boxSizerLvl5_1, 0, wxEXPAND, WXC_FROM_DIP(5));
2473 
2474  m_textCtrlActivePower = new wxTextCtrl(m_panelGeneral, wxID_ANY, wxT(""), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
2475  #if wxVERSION_NUMBER >= 3000
2476  m_textCtrlActivePower->SetHint(wxT(""));
2477  #endif
2478 
2479  boxSizerLvl5_1->Add(m_textCtrlActivePower, 1, wxLEFT|wxRIGHT|wxBOTTOM|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
2480 
2481  wxArrayString m_choiceActivePowerArr;
2482  m_choiceActivePowerArr.Add(wxT("p.u."));
2483  m_choiceActivePowerArr.Add(wxT("W"));
2484  m_choiceActivePowerArr.Add(wxT("kW"));
2485  m_choiceActivePowerArr.Add(wxT("MW"));
2486  m_choiceActivePower = new wxChoice(m_panelGeneral, wxID_ANY, wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), m_choiceActivePowerArr, 0);
2487  m_choiceActivePower->SetSelection(3);
2488 
2489  boxSizerLvl5_1->Add(m_choiceActivePower, 0, wxLEFT|wxRIGHT|wxBOTTOM, WXC_FROM_DIP(5));
2490 
2491  wxBoxSizer* boxSizerLvl4_2 = new wxBoxSizer(wxVERTICAL);
2492 
2493  gridSizerLvl3_1->Add(boxSizerLvl4_2, 0, wxEXPAND, WXC_FROM_DIP(5));
2494 
2495  m_staticTextReactivePower = new wxStaticText(m_panelGeneral, wxID_ANY, _("Reactive power"), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
2496 
2497  boxSizerLvl4_2->Add(m_staticTextReactivePower, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
2498 
2499  wxBoxSizer* boxSizerLvl5_2 = new wxBoxSizer(wxHORIZONTAL);
2500 
2501  boxSizerLvl4_2->Add(boxSizerLvl5_2, 0, wxEXPAND, WXC_FROM_DIP(5));
2502 
2503  m_textCtrlReactivePower = new wxTextCtrl(m_panelGeneral, wxID_ANY, wxT(""), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
2504  #if wxVERSION_NUMBER >= 3000
2505  m_textCtrlReactivePower->SetHint(wxT(""));
2506  #endif
2507 
2508  boxSizerLvl5_2->Add(m_textCtrlReactivePower, 1, wxLEFT|wxRIGHT|wxBOTTOM|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
2509 
2510  wxArrayString m_choiceReactivePowerArr;
2511  m_choiceReactivePowerArr.Add(wxT("p.u."));
2512  m_choiceReactivePowerArr.Add(wxT("VAr"));
2513  m_choiceReactivePowerArr.Add(wxT("kVAr"));
2514  m_choiceReactivePowerArr.Add(wxT("MVAr"));
2515  m_choiceReactivePower = new wxChoice(m_panelGeneral, wxID_ANY, wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), m_choiceReactivePowerArr, 0);
2516  m_choiceReactivePower->SetSelection(3);
2517 
2518  boxSizerLvl5_2->Add(m_choiceReactivePower, 0, wxLEFT|wxRIGHT|wxBOTTOM, WXC_FROM_DIP(5));
2519 
2520  wxBoxSizer* boxSizerBottomButtons = new wxBoxSizer(wxHORIZONTAL);
2521 
2522  boxSizerLvl1_1->Add(boxSizerBottomButtons, 0, wxALL|wxEXPAND, WXC_FROM_DIP(5));
2523 
2524  m_buttonStabButton = new wxButton(this, wxID_ANY, _("Stability"), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
2525 
2526  boxSizerBottomButtons->Add(m_buttonStabButton, 0, wxALL|wxALIGN_LEFT, WXC_FROM_DIP(5));
2527 
2528  boxSizerBottomButtons->Add(0, 0, 1, wxALL, WXC_FROM_DIP(5));
2529 
2530  m_buttonOK = new wxButton(this, wxID_ANY, _("OK"), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
2531 
2532  boxSizerBottomButtons->Add(m_buttonOK, 0, wxALL|wxALIGN_RIGHT, WXC_FROM_DIP(5));
2533 
2534  m_ButtonCancel = new wxButton(this, wxID_ANY, _("Cancel"), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
2535 
2536  boxSizerBottomButtons->Add(m_ButtonCancel, 0, wxALL|wxALIGN_RIGHT, WXC_FROM_DIP(5));
2537 
2538 
2539  #if wxVERSION_NUMBER >= 2900
2540  if(!wxPersistenceManager::Get().Find(m_notebook)){
2541  wxPersistenceManager::Get().RegisterAndRestore(m_notebook);
2542  } else {
2543  wxPersistenceManager::Get().Restore(m_notebook);
2544  }
2545  #endif
2546 
2547  SetName(wxT("IndMotorFormBase"));
2548  SetSize(-1,-1);
2549  if (GetSizer()) {
2550  GetSizer()->Fit(this);
2551  }
2552  if(GetParent()) {
2553  CentreOnParent(wxBOTH);
2554  } else {
2555  CentreOnScreen(wxBOTH);
2556  }
2557 #if wxVERSION_NUMBER >= 2900
2558  if(!wxPersistenceManager::Get().Find(this)) {
2559  wxPersistenceManager::Get().RegisterAndRestore(this);
2560  } else {
2561  wxPersistenceManager::Get().Restore(this);
2562  }
2563 #endif
2564  // Connect events
2565  m_buttonStabButton->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(IndMotorFormBase::OnStabilityButtonClick), NULL, this);
2566  m_buttonOK->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(IndMotorFormBase::OnOKButtonClick), NULL, this);
2567  m_ButtonCancel->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(IndMotorFormBase::OnCancelButtonClick), NULL, this);
2568 
2569 }
2570 
2571 IndMotorFormBase::~IndMotorFormBase()
2572 {
2573  m_buttonStabButton->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(IndMotorFormBase::OnStabilityButtonClick), NULL, this);
2574  m_buttonOK->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(IndMotorFormBase::OnOKButtonClick), NULL, this);
2575  m_ButtonCancel->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(IndMotorFormBase::OnCancelButtonClick), NULL, this);
2576 
2577 }
2578 
2579 TextFormBase::TextFormBase(wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style)
2580  : wxDialog(parent, id, title, pos, size, style)
2581 {
2582  if ( !bBitmapLoaded ) {
2583  // We need to initialise the default bitmap handler
2584  wxXmlResource::Get()->AddHandler(new wxBitmapXmlHandler);
2585  wxC9EE9InitBitmapResources();
2586  bBitmapLoaded = true;
2587  }
2588 
2589  wxBoxSizer* boxSizerLvl1_1 = new wxBoxSizer(wxVERTICAL);
2590  this->SetSizer(boxSizerLvl1_1);
2591 
2592  m_notebook = new wxNotebook(this, wxID_ANY, wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), wxBK_DEFAULT);
2593  m_notebook->SetName(wxT("m_notebook"));
2594 
2595  boxSizerLvl1_1->Add(m_notebook, 1, wxEXPAND, WXC_FROM_DIP(5));
2596 
2597  m_panelGeneral = new wxPanel(m_notebook, wxID_ANY, wxDefaultPosition, wxDLG_UNIT(m_notebook, wxSize(-1,-1)), wxTAB_TRAVERSAL);
2598  m_notebook->AddPage(m_panelGeneral, _("General"), false);
2599 
2600  wxBoxSizer* boxSizerLvl2_1 = new wxBoxSizer(wxVERTICAL);
2601  m_panelGeneral->SetSizer(boxSizerLvl2_1);
2602 
2603  wxGridSizer* gridSizerLvl3_1 = new wxGridSizer(0, 3, 0, 0);
2604 
2605  boxSizerLvl2_1->Add(gridSizerLvl3_1, 0, wxEXPAND, WXC_FROM_DIP(5));
2606 
2607  wxBoxSizer* boxSizerLvl4_1 = new wxBoxSizer(wxVERTICAL);
2608 
2609  gridSizerLvl3_1->Add(boxSizerLvl4_1, 0, wxEXPAND, WXC_FROM_DIP(5));
2610 
2611  m_staticTextElement = new wxStaticText(m_panelGeneral, wxID_ANY, _("Element"), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
2612 
2613  boxSizerLvl4_1->Add(m_staticTextElement, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
2614 
2615  wxArrayString m_choiceElementArr;
2616  m_choiceElementArr.Add(wxT("Bus"));
2617  m_choiceElementArr.Add(wxT("Generator"));
2618  m_choiceElementArr.Add(wxT("Line"));
2619  m_choiceElementArr.Add(wxT("Transformer"));
2620  m_choiceElementArr.Add(wxT("Load"));
2621  m_choiceElementArr.Add(wxT("Capacitor"));
2622  m_choiceElementArr.Add(wxT("Inductor"));
2623  m_choiceElementArr.Add(wxT("Synchronous compensator"));
2624  m_choiceElementArr.Add(wxT("Induction motor"));
2625  m_choiceElement = new wxChoice(m_panelGeneral, wxID_ANY, wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), m_choiceElementArr, 0);
2626 
2627  boxSizerLvl4_1->Add(m_choiceElement, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxEXPAND, WXC_FROM_DIP(5));
2628 
2629  wxBoxSizer* boxSizerLvl4_2 = new wxBoxSizer(wxVERTICAL);
2630 
2631  gridSizerLvl3_1->Add(boxSizerLvl4_2, 0, wxEXPAND, WXC_FROM_DIP(5));
2632 
2633  m_staticTextName = new wxStaticText(m_panelGeneral, wxID_ANY, _("Element name"), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
2634 
2635  boxSizerLvl4_2->Add(m_staticTextName, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
2636 
2637  wxArrayString m_choiceNameArr;
2638  m_choiceName = new wxChoice(m_panelGeneral, wxID_ANY, wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), m_choiceNameArr, 0);
2639 
2640  boxSizerLvl4_2->Add(m_choiceName, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxEXPAND, WXC_FROM_DIP(5));
2641 
2642  wxBoxSizer* boxSizerLvl4_3 = new wxBoxSizer(wxVERTICAL);
2643 
2644  gridSizerLvl3_1->Add(boxSizerLvl4_3, 0, wxEXPAND, WXC_FROM_DIP(5));
2645 
2646  m_staticTextType = new wxStaticText(m_panelGeneral, wxID_ANY, _("Text type"), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
2647 
2648  boxSizerLvl4_3->Add(m_staticTextType, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
2649 
2650  wxArrayString m_choiceTextTypeArr;
2651  m_choiceTextType = new wxChoice(m_panelGeneral, wxID_ANY, wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), m_choiceTextTypeArr, 0);
2652 
2653  boxSizerLvl4_3->Add(m_choiceTextType, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxEXPAND, WXC_FROM_DIP(5));
2654 
2655  wxBoxSizer* boxSizerLvl4_4 = new wxBoxSizer(wxVERTICAL);
2656 
2657  gridSizerLvl3_1->Add(boxSizerLvl4_4, 0, wxEXPAND, WXC_FROM_DIP(5));
2658 
2659  m_staticTextFromBus = new wxStaticText(m_panelGeneral, wxID_ANY, _("From bus"), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
2660 
2661  boxSizerLvl4_4->Add(m_staticTextFromBus, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
2662 
2663  wxArrayString m_choiceTextFromBusArr;
2664  m_choiceTextFromBus = new wxChoice(m_panelGeneral, wxID_ANY, wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), m_choiceTextFromBusArr, 0);
2665 
2666  boxSizerLvl4_4->Add(m_choiceTextFromBus, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxEXPAND, WXC_FROM_DIP(5));
2667 
2668  wxBoxSizer* boxSizerLvl4_5 = new wxBoxSizer(wxVERTICAL);
2669 
2670  gridSizerLvl3_1->Add(boxSizerLvl4_5, 0, wxEXPAND, WXC_FROM_DIP(5));
2671 
2672  m_staticTextToBus = new wxStaticText(m_panelGeneral, wxID_ANY, _("To bus"), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
2673 
2674  boxSizerLvl4_5->Add(m_staticTextToBus, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
2675 
2676  wxArrayString m_choiceTextToBusArr;
2677  m_choiceTextToBus = new wxChoice(m_panelGeneral, wxID_ANY, wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), m_choiceTextToBusArr, 0);
2678 
2679  boxSizerLvl4_5->Add(m_choiceTextToBus, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxEXPAND, WXC_FROM_DIP(5));
2680 
2681  wxBoxSizer* boxSizerLvl4_6 = new wxBoxSizer(wxVERTICAL);
2682 
2683  gridSizerLvl3_1->Add(boxSizerLvl4_6, 0, wxEXPAND, WXC_FROM_DIP(5));
2684 
2685  m_staticTextUnit = new wxStaticText(m_panelGeneral, wxID_ANY, _("Unit"), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
2686 
2687  boxSizerLvl4_6->Add(m_staticTextUnit, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
2688 
2689  wxArrayString m_choiceTextUnitArr;
2690  m_choiceTextUnit = new wxChoice(m_panelGeneral, wxID_ANY, wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), m_choiceTextUnitArr, 0);
2691 
2692  boxSizerLvl4_6->Add(m_choiceTextUnit, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxEXPAND, WXC_FROM_DIP(5));
2693 
2694  wxBoxSizer* boxSizerLvl3_2 = new wxBoxSizer(wxHORIZONTAL);
2695 
2696  boxSizerLvl2_1->Add(boxSizerLvl3_2, 1, wxALL|wxEXPAND, WXC_FROM_DIP(5));
2697 
2698  m_staticTextDecimal = new wxStaticText(m_panelGeneral, wxID_ANY, _("Decimal places:"), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
2699 
2700  boxSizerLvl3_2->Add(m_staticTextDecimal, 0, wxALL|wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
2701 
2702  m_textCtrlDecimal = new wxTextCtrl(m_panelGeneral, wxID_ANY, wxT("2"), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), wxTE_PROCESS_ENTER);
2703  #if wxVERSION_NUMBER >= 3000
2704  m_textCtrlDecimal->SetHint(wxT(""));
2705  #endif
2706 
2707  boxSizerLvl3_2->Add(m_textCtrlDecimal, 0, wxALL|wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
2708 
2709  boxSizerLvl3_2->Add(0, 0, 0, wxALL, WXC_FROM_DIP(5));
2710 
2711  m_staticTextPreview = new wxStaticText(m_panelGeneral, wxID_ANY, _("Preview:"), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
2712 
2713  boxSizerLvl3_2->Add(m_staticTextPreview, 0, wxALL|wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
2714 
2715  m_textCtrlPreview = new wxTextCtrl(m_panelGeneral, wxID_ANY, wxT(""), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), wxTE_CENTRE);
2716  #if wxVERSION_NUMBER >= 3000
2717  m_textCtrlPreview->SetHint(wxT(""));
2718  #endif
2719 
2720  boxSizerLvl3_2->Add(m_textCtrlPreview, 1, wxALL|wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
2721 
2722  wxBoxSizer* boxSizerBottomButtons = new wxBoxSizer(wxHORIZONTAL);
2723 
2724  boxSizerLvl1_1->Add(boxSizerBottomButtons, 0, wxALL|wxEXPAND, WXC_FROM_DIP(5));
2725 
2726  boxSizerBottomButtons->Add(0, 0, 1, wxALL, WXC_FROM_DIP(5));
2727 
2728  m_buttonOK = new wxButton(this, wxID_ANY, _("OK"), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
2729 
2730  boxSizerBottomButtons->Add(m_buttonOK, 0, wxALL|wxALIGN_RIGHT, WXC_FROM_DIP(5));
2731 
2732  m_ButtonCancel = new wxButton(this, wxID_ANY, _("Cancel"), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
2733 
2734  boxSizerBottomButtons->Add(m_ButtonCancel, 0, wxALL|wxALIGN_RIGHT, WXC_FROM_DIP(5));
2735 
2736 
2737  #if wxVERSION_NUMBER >= 2900
2738  if(!wxPersistenceManager::Get().Find(m_notebook)){
2739  wxPersistenceManager::Get().RegisterAndRestore(m_notebook);
2740  } else {
2741  wxPersistenceManager::Get().Restore(m_notebook);
2742  }
2743  #endif
2744 
2745  SetName(wxT("TextFormBase"));
2746  SetSize(-1,-1);
2747  if (GetSizer()) {
2748  GetSizer()->Fit(this);
2749  }
2750  if(GetParent()) {
2751  CentreOnParent(wxBOTH);
2752  } else {
2753  CentreOnScreen(wxBOTH);
2754  }
2755 #if wxVERSION_NUMBER >= 2900
2756  if(!wxPersistenceManager::Get().Find(this)) {
2757  wxPersistenceManager::Get().RegisterAndRestore(this);
2758  } else {
2759  wxPersistenceManager::Get().Restore(this);
2760  }
2761 #endif
2762  // Connect events
2763  m_choiceElement->Connect(wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler(TextFormBase::OnElementChoiceSelected), NULL, this);
2764  m_choiceName->Connect(wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler(TextFormBase::OnNameChoiceSelected), NULL, this);
2765  m_choiceTextType->Connect(wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler(TextFormBase::OnTypeChoiceSelected), NULL, this);
2766  m_choiceTextFromBus->Connect(wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler(TextFormBase::OnFromBusChoiceSelected), NULL, this);
2767  m_choiceTextToBus->Connect(wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler(TextFormBase::OnToBusChoiceSelected), NULL, this);
2768  m_choiceTextUnit->Connect(wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler(TextFormBase::OnUnitChoiceSelected), NULL, this);
2769  m_textCtrlDecimal->Connect(wxEVT_COMMAND_TEXT_ENTER, wxCommandEventHandler(TextFormBase::OnTextEnter), NULL, this);
2770  m_buttonOK->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(TextFormBase::OnOKButtonClick), NULL, this);
2771  m_ButtonCancel->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(TextFormBase::OnCancelButtonClick), NULL, this);
2772 
2773 }
2774 
2775 TextFormBase::~TextFormBase()
2776 {
2777  m_choiceElement->Disconnect(wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler(TextFormBase::OnElementChoiceSelected), NULL, this);
2778  m_choiceName->Disconnect(wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler(TextFormBase::OnNameChoiceSelected), NULL, this);
2779  m_choiceTextType->Disconnect(wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler(TextFormBase::OnTypeChoiceSelected), NULL, this);
2780  m_choiceTextFromBus->Disconnect(wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler(TextFormBase::OnFromBusChoiceSelected), NULL, this);
2781  m_choiceTextToBus->Disconnect(wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler(TextFormBase::OnToBusChoiceSelected), NULL, this);
2782  m_choiceTextUnit->Disconnect(wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler(TextFormBase::OnUnitChoiceSelected), NULL, this);
2783  m_textCtrlDecimal->Disconnect(wxEVT_COMMAND_TEXT_ENTER, wxCommandEventHandler(TextFormBase::OnTextEnter), NULL, this);
2784  m_buttonOK->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(TextFormBase::OnOKButtonClick), NULL, this);
2785  m_ButtonCancel->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(TextFormBase::OnCancelButtonClick), NULL, this);
2786 
2787 }
2788 
2789 TransferFunctionFormBase::TransferFunctionFormBase(wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style)
2790  : wxDialog(parent, id, title, pos, size, style)
2791 {
2792  if ( !bBitmapLoaded ) {
2793  // We need to initialise the default bitmap handler
2794  wxXmlResource::Get()->AddHandler(new wxBitmapXmlHandler);
2795  wxC9EE9InitBitmapResources();
2796  bBitmapLoaded = true;
2797  }
2798 
2799  wxBoxSizer* boxSizerLvl1_1 = new wxBoxSizer(wxVERTICAL);
2800  this->SetSizer(boxSizerLvl1_1);
2801 
2802  m_notebook = new wxNotebook(this, wxID_ANY, wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), wxBK_DEFAULT);
2803  m_notebook->SetName(wxT("m_notebook"));
2804 
2805  boxSizerLvl1_1->Add(m_notebook, 1, wxEXPAND, WXC_FROM_DIP(5));
2806 
2807  m_panelGeneral = new wxPanel(m_notebook, wxID_ANY, wxDefaultPosition, wxDLG_UNIT(m_notebook, wxSize(-1,-1)), wxTAB_TRAVERSAL);
2808  m_notebook->AddPage(m_panelGeneral, _("General"), false);
2809 
2810  wxBoxSizer* boxSizerLvl2_1 = new wxBoxSizer(wxVERTICAL);
2811  m_panelGeneral->SetSizer(boxSizerLvl2_1);
2812 
2813  m_staticTextNumerator = new wxStaticText(m_panelGeneral, wxID_ANY, _("Numerator parameters"), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
2814 
2815  boxSizerLvl2_1->Add(m_staticTextNumerator, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
2816 
2817  m_textCtrlNumerator = new wxTextCtrl(m_panelGeneral, wxID_ANY, wxT(""), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
2818  #if wxVERSION_NUMBER >= 3000
2819  m_textCtrlNumerator->SetHint(wxT(""));
2820  #endif
2821 
2822  boxSizerLvl2_1->Add(m_textCtrlNumerator, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxEXPAND|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
2823  m_textCtrlNumerator->SetMinSize(wxSize(300,-1));
2824 
2825  m_staticTextDenominator = new wxStaticText(m_panelGeneral, wxID_ANY, _("Denominator parameters"), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
2826 
2827  boxSizerLvl2_1->Add(m_staticTextDenominator, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
2828 
2829  m_textCtrlDenominator = new wxTextCtrl(m_panelGeneral, wxID_ANY, wxT(""), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
2830  #if wxVERSION_NUMBER >= 3000
2831  m_textCtrlDenominator->SetHint(wxT(""));
2832  #endif
2833 
2834  boxSizerLvl2_1->Add(m_textCtrlDenominator, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxEXPAND|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
2835  m_textCtrlDenominator->SetMinSize(wxSize(300,-1));
2836 
2837  wxBoxSizer* boxSizerBottomButtons = new wxBoxSizer(wxHORIZONTAL);
2838 
2839  boxSizerLvl1_1->Add(boxSizerBottomButtons, 0, wxALL|wxEXPAND, WXC_FROM_DIP(5));
2840 
2841  boxSizerBottomButtons->Add(0, 0, 1, wxALL, WXC_FROM_DIP(5));
2842 
2843  m_buttonOK = new wxButton(this, wxID_ANY, _("OK"), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
2844 
2845  boxSizerBottomButtons->Add(m_buttonOK, 0, wxALL|wxALIGN_RIGHT, WXC_FROM_DIP(5));
2846 
2847  m_ButtonCancel = new wxButton(this, wxID_ANY, _("Cancel"), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
2848 
2849  boxSizerBottomButtons->Add(m_ButtonCancel, 0, wxALL|wxALIGN_RIGHT, WXC_FROM_DIP(5));
2850 
2851 
2852  #if wxVERSION_NUMBER >= 2900
2853  if(!wxPersistenceManager::Get().Find(m_notebook)){
2854  wxPersistenceManager::Get().RegisterAndRestore(m_notebook);
2855  } else {
2856  wxPersistenceManager::Get().Restore(m_notebook);
2857  }
2858  #endif
2859 
2860  SetName(wxT("TransferFunctionFormBase"));
2861  SetSize(-1,-1);
2862  if (GetSizer()) {
2863  GetSizer()->Fit(this);
2864  }
2865  if(GetParent()) {
2866  CentreOnParent(wxBOTH);
2867  } else {
2868  CentreOnScreen(wxBOTH);
2869  }
2870 #if wxVERSION_NUMBER >= 2900
2871  if(!wxPersistenceManager::Get().Find(this)) {
2872  wxPersistenceManager::Get().RegisterAndRestore(this);
2873  } else {
2874  wxPersistenceManager::Get().Restore(this);
2875  }
2876 #endif
2877  // Connect events
2878  m_buttonOK->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(TransferFunctionFormBase::OnOKClick), NULL, this);
2879  m_ButtonCancel->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(TransferFunctionFormBase::OnCancelClick), NULL, this);
2880 
2881 }
2882 
2883 TransferFunctionFormBase::~TransferFunctionFormBase()
2884 {
2885  m_buttonOK->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(TransferFunctionFormBase::OnOKClick), NULL, this);
2886  m_ButtonCancel->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(TransferFunctionFormBase::OnCancelClick), NULL, this);
2887 
2888 }
2889 
2890 SumFormBase::SumFormBase(wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style)
2891  : wxDialog(parent, id, title, pos, size, style)
2892 {
2893  if ( !bBitmapLoaded ) {
2894  // We need to initialise the default bitmap handler
2895  wxXmlResource::Get()->AddHandler(new wxBitmapXmlHandler);
2896  wxC9EE9InitBitmapResources();
2897  bBitmapLoaded = true;
2898  }
2899 
2900  wxBoxSizer* boxSizerLvl1_1 = new wxBoxSizer(wxVERTICAL);
2901  this->SetSizer(boxSizerLvl1_1);
2902 
2903  m_notebook = new wxNotebook(this, wxID_ANY, wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), wxBK_DEFAULT);
2904  m_notebook->SetName(wxT("m_notebook"));
2905 
2906  boxSizerLvl1_1->Add(m_notebook, 1, wxEXPAND, WXC_FROM_DIP(5));
2907 
2908  m_panelGeneral = new wxPanel(m_notebook, wxID_ANY, wxDefaultPosition, wxDLG_UNIT(m_notebook, wxSize(-1,-1)), wxTAB_TRAVERSAL);
2909  m_notebook->AddPage(m_panelGeneral, _("General"), false);
2910 
2911  wxBoxSizer* boxSizerLvl2_1 = new wxBoxSizer(wxVERTICAL);
2912  m_panelGeneral->SetSizer(boxSizerLvl2_1);
2913 
2914  m_staticTextSigns = new wxStaticText(m_panelGeneral, wxID_ANY, _("Signs"), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
2915 
2916  boxSizerLvl2_1->Add(m_staticTextSigns, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
2917 
2918  m_textCtrlSigns = new wxTextCtrl(m_panelGeneral, wxID_ANY, wxT(""), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
2919  #if wxVERSION_NUMBER >= 3000
2920  m_textCtrlSigns->SetHint(wxT(""));
2921  #endif
2922 
2923  boxSizerLvl2_1->Add(m_textCtrlSigns, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxEXPAND|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
2924  m_textCtrlSigns->SetMinSize(wxSize(300,-1));
2925 
2926  wxBoxSizer* boxSizerBottomButtons = new wxBoxSizer(wxHORIZONTAL);
2927 
2928  boxSizerLvl1_1->Add(boxSizerBottomButtons, 0, wxALL|wxEXPAND, WXC_FROM_DIP(5));
2929 
2930  boxSizerBottomButtons->Add(0, 0, 1, wxALL, WXC_FROM_DIP(5));
2931 
2932  m_buttonOK = new wxButton(this, wxID_ANY, _("OK"), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
2933 
2934  boxSizerBottomButtons->Add(m_buttonOK, 0, wxALL|wxALIGN_RIGHT, WXC_FROM_DIP(5));
2935 
2936  m_ButtonCancel = new wxButton(this, wxID_ANY, _("Cancel"), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
2937 
2938  boxSizerBottomButtons->Add(m_ButtonCancel, 0, wxALL|wxALIGN_RIGHT, WXC_FROM_DIP(5));
2939 
2940 
2941  #if wxVERSION_NUMBER >= 2900
2942  if(!wxPersistenceManager::Get().Find(m_notebook)){
2943  wxPersistenceManager::Get().RegisterAndRestore(m_notebook);
2944  } else {
2945  wxPersistenceManager::Get().Restore(m_notebook);
2946  }
2947  #endif
2948 
2949  SetName(wxT("SumFormBase"));
2950  SetSize(-1,-1);
2951  if (GetSizer()) {
2952  GetSizer()->Fit(this);
2953  }
2954  if(GetParent()) {
2955  CentreOnParent(wxBOTH);
2956  } else {
2957  CentreOnScreen(wxBOTH);
2958  }
2959 #if wxVERSION_NUMBER >= 2900
2960  if(!wxPersistenceManager::Get().Find(this)) {
2961  wxPersistenceManager::Get().RegisterAndRestore(this);
2962  } else {
2963  wxPersistenceManager::Get().Restore(this);
2964  }
2965 #endif
2966  // Connect events
2967  m_buttonOK->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(SumFormBase::OnOKClick), NULL, this);
2968  m_ButtonCancel->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(SumFormBase::OnCancelClick), NULL, this);
2969 
2970 }
2971 
2972 SumFormBase::~SumFormBase()
2973 {
2974  m_buttonOK->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(SumFormBase::OnOKClick), NULL, this);
2975  m_ButtonCancel->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(SumFormBase::OnCancelClick), NULL, this);
2976 
2977 }
2978 
2979 LimiterFormBase::LimiterFormBase(wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style)
2980  : wxDialog(parent, id, title, pos, size, style)
2981 {
2982  if ( !bBitmapLoaded ) {
2983  // We need to initialise the default bitmap handler
2984  wxXmlResource::Get()->AddHandler(new wxBitmapXmlHandler);
2985  wxC9EE9InitBitmapResources();
2986  bBitmapLoaded = true;
2987  }
2988 
2989  wxBoxSizer* boxSizerLvl1_1 = new wxBoxSizer(wxVERTICAL);
2990  this->SetSizer(boxSizerLvl1_1);
2991 
2992  m_notebook = new wxNotebook(this, wxID_ANY, wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), wxBK_DEFAULT);
2993  m_notebook->SetName(wxT("m_notebook"));
2994 
2995  boxSizerLvl1_1->Add(m_notebook, 1, wxEXPAND, WXC_FROM_DIP(5));
2996 
2997  m_panelGeneral = new wxPanel(m_notebook, wxID_ANY, wxDefaultPosition, wxDLG_UNIT(m_notebook, wxSize(-1,-1)), wxTAB_TRAVERSAL);
2998  m_notebook->AddPage(m_panelGeneral, _("General"), false);
2999 
3000  wxBoxSizer* boxSizerLvl2_1 = new wxBoxSizer(wxVERTICAL);
3001  m_panelGeneral->SetSizer(boxSizerLvl2_1);
3002 
3003  m_staticTextUpLimiter = new wxStaticText(m_panelGeneral, wxID_ANY, _("Upper limit"), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
3004 
3005  boxSizerLvl2_1->Add(m_staticTextUpLimiter, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
3006 
3007  m_textCtrlUpLimit = new wxTextCtrl(m_panelGeneral, wxID_ANY, wxT(""), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
3008  #if wxVERSION_NUMBER >= 3000
3009  m_textCtrlUpLimit->SetHint(wxT(""));
3010  #endif
3011 
3012  boxSizerLvl2_1->Add(m_textCtrlUpLimit, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxEXPAND|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
3013  m_textCtrlUpLimit->SetMinSize(wxSize(100,-1));
3014 
3015  m_staticTextLowLimit = new wxStaticText(m_panelGeneral, wxID_ANY, _("Lower limit"), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
3016 
3017  boxSizerLvl2_1->Add(m_staticTextLowLimit, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
3018 
3019  m_textCtrlLowLimit = new wxTextCtrl(m_panelGeneral, wxID_ANY, wxT(""), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
3020  #if wxVERSION_NUMBER >= 3000
3021  m_textCtrlLowLimit->SetHint(wxT(""));
3022  #endif
3023 
3024  boxSizerLvl2_1->Add(m_textCtrlLowLimit, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxEXPAND|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
3025  m_textCtrlLowLimit->SetMinSize(wxSize(100,-1));
3026 
3027  wxBoxSizer* boxSizerBottomButtons = new wxBoxSizer(wxHORIZONTAL);
3028 
3029  boxSizerLvl1_1->Add(boxSizerBottomButtons, 0, wxALL|wxEXPAND, WXC_FROM_DIP(5));
3030 
3031  boxSizerBottomButtons->Add(0, 0, 1, wxALL, WXC_FROM_DIP(5));
3032 
3033  m_buttonOK = new wxButton(this, wxID_ANY, _("OK"), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
3034 
3035  boxSizerBottomButtons->Add(m_buttonOK, 0, wxALL|wxALIGN_RIGHT, WXC_FROM_DIP(5));
3036 
3037  m_ButtonCancel = new wxButton(this, wxID_ANY, _("Cancel"), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
3038 
3039  boxSizerBottomButtons->Add(m_ButtonCancel, 0, wxALL|wxALIGN_RIGHT, WXC_FROM_DIP(5));
3040 
3041 
3042  #if wxVERSION_NUMBER >= 2900
3043  if(!wxPersistenceManager::Get().Find(m_notebook)){
3044  wxPersistenceManager::Get().RegisterAndRestore(m_notebook);
3045  } else {
3046  wxPersistenceManager::Get().Restore(m_notebook);
3047  }
3048  #endif
3049 
3050  SetName(wxT("LimiterFormBase"));
3051  SetSize(-1,-1);
3052  if (GetSizer()) {
3053  GetSizer()->Fit(this);
3054  }
3055  if(GetParent()) {
3056  CentreOnParent(wxBOTH);
3057  } else {
3058  CentreOnScreen(wxBOTH);
3059  }
3060 #if wxVERSION_NUMBER >= 2900
3061  if(!wxPersistenceManager::Get().Find(this)) {
3062  wxPersistenceManager::Get().RegisterAndRestore(this);
3063  } else {
3064  wxPersistenceManager::Get().Restore(this);
3065  }
3066 #endif
3067  // Connect events
3068  m_buttonOK->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(LimiterFormBase::OnOKButtonClick), NULL, this);
3069  m_ButtonCancel->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(LimiterFormBase::OnCancelButtonClick), NULL, this);
3070 
3071 }
3072 
3073 LimiterFormBase::~LimiterFormBase()
3074 {
3075  m_buttonOK->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(LimiterFormBase::OnOKButtonClick), NULL, this);
3076  m_ButtonCancel->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(LimiterFormBase::OnCancelButtonClick), NULL, this);
3077 
3078 }
3079 
3080 RateLimiterFormBase::RateLimiterFormBase(wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style)
3081  : wxDialog(parent, id, title, pos, size, style)
3082 {
3083  if ( !bBitmapLoaded ) {
3084  // We need to initialise the default bitmap handler
3085  wxXmlResource::Get()->AddHandler(new wxBitmapXmlHandler);
3086  wxC9EE9InitBitmapResources();
3087  bBitmapLoaded = true;
3088  }
3089 
3090  wxBoxSizer* boxSizerLvl1_1 = new wxBoxSizer(wxVERTICAL);
3091  this->SetSizer(boxSizerLvl1_1);
3092 
3093  m_notebook = new wxNotebook(this, wxID_ANY, wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), wxBK_DEFAULT);
3094  m_notebook->SetName(wxT("m_notebook"));
3095 
3096  boxSizerLvl1_1->Add(m_notebook, 1, wxEXPAND, WXC_FROM_DIP(5));
3097 
3098  m_panelGeneral = new wxPanel(m_notebook, wxID_ANY, wxDefaultPosition, wxDLG_UNIT(m_notebook, wxSize(-1,-1)), wxTAB_TRAVERSAL);
3099  m_notebook->AddPage(m_panelGeneral, _("General"), false);
3100 
3101  wxBoxSizer* boxSizerLvl2_1 = new wxBoxSizer(wxVERTICAL);
3102  m_panelGeneral->SetSizer(boxSizerLvl2_1);
3103 
3104  m_staticTextUpLimiter = new wxStaticText(m_panelGeneral, wxID_ANY, _("Upper limit"), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
3105 
3106  boxSizerLvl2_1->Add(m_staticTextUpLimiter, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
3107 
3108  m_textCtrlUpLimit = new wxTextCtrl(m_panelGeneral, wxID_ANY, wxT(""), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
3109  #if wxVERSION_NUMBER >= 3000
3110  m_textCtrlUpLimit->SetHint(wxT(""));
3111  #endif
3112 
3113  boxSizerLvl2_1->Add(m_textCtrlUpLimit, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxEXPAND|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
3114  m_textCtrlUpLimit->SetMinSize(wxSize(100,-1));
3115 
3116  m_staticTextLowLimit = new wxStaticText(m_panelGeneral, wxID_ANY, _("Lower limit"), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
3117 
3118  boxSizerLvl2_1->Add(m_staticTextLowLimit, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
3119 
3120  m_textCtrlLowLimit = new wxTextCtrl(m_panelGeneral, wxID_ANY, wxT(""), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
3121  #if wxVERSION_NUMBER >= 3000
3122  m_textCtrlLowLimit->SetHint(wxT(""));
3123  #endif
3124 
3125  boxSizerLvl2_1->Add(m_textCtrlLowLimit, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxEXPAND|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
3126  m_textCtrlLowLimit->SetMinSize(wxSize(100,-1));
3127 
3128  wxBoxSizer* boxSizerBottomButtons = new wxBoxSizer(wxHORIZONTAL);
3129 
3130  boxSizerLvl1_1->Add(boxSizerBottomButtons, 0, wxALL|wxEXPAND, WXC_FROM_DIP(5));
3131 
3132  boxSizerBottomButtons->Add(0, 0, 1, wxALL, WXC_FROM_DIP(5));
3133 
3134  m_buttonOK = new wxButton(this, wxID_ANY, _("OK"), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
3135 
3136  boxSizerBottomButtons->Add(m_buttonOK, 0, wxALL|wxALIGN_RIGHT, WXC_FROM_DIP(5));
3137 
3138  m_ButtonCancel = new wxButton(this, wxID_ANY, _("Cancel"), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
3139 
3140  boxSizerBottomButtons->Add(m_ButtonCancel, 0, wxALL|wxALIGN_RIGHT, WXC_FROM_DIP(5));
3141 
3142 
3143  #if wxVERSION_NUMBER >= 2900
3144  if(!wxPersistenceManager::Get().Find(m_notebook)){
3145  wxPersistenceManager::Get().RegisterAndRestore(m_notebook);
3146  } else {
3147  wxPersistenceManager::Get().Restore(m_notebook);
3148  }
3149  #endif
3150 
3151  SetName(wxT("RateLimiterFormBase"));
3152  SetSize(-1,-1);
3153  if (GetSizer()) {
3154  GetSizer()->Fit(this);
3155  }
3156  if(GetParent()) {
3157  CentreOnParent(wxBOTH);
3158  } else {
3159  CentreOnScreen(wxBOTH);
3160  }
3161 #if wxVERSION_NUMBER >= 2900
3162  if(!wxPersistenceManager::Get().Find(this)) {
3163  wxPersistenceManager::Get().RegisterAndRestore(this);
3164  } else {
3165  wxPersistenceManager::Get().Restore(this);
3166  }
3167 #endif
3168  // Connect events
3169  m_buttonOK->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(RateLimiterFormBase::OnOKButtonClick), NULL, this);
3170  m_ButtonCancel->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(RateLimiterFormBase::OnCancelButtonClick), NULL, this);
3171 
3172 }
3173 
3174 RateLimiterFormBase::~RateLimiterFormBase()
3175 {
3176  m_buttonOK->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(RateLimiterFormBase::OnOKButtonClick), NULL, this);
3177  m_ButtonCancel->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(RateLimiterFormBase::OnCancelButtonClick), NULL, this);
3178 
3179 }
3180 
3181 ExponentialFormBase::ExponentialFormBase(wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style)
3182  : wxDialog(parent, id, title, pos, size, style)
3183 {
3184  if ( !bBitmapLoaded ) {
3185  // We need to initialise the default bitmap handler
3186  wxXmlResource::Get()->AddHandler(new wxBitmapXmlHandler);
3187  wxC9EE9InitBitmapResources();
3188  bBitmapLoaded = true;
3189  }
3190 
3191  wxBoxSizer* boxSizerLvl1_1 = new wxBoxSizer(wxVERTICAL);
3192  this->SetSizer(boxSizerLvl1_1);
3193 
3194  m_notebook = new wxNotebook(this, wxID_ANY, wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), wxBK_DEFAULT);
3195  m_notebook->SetName(wxT("m_notebook"));
3196 
3197  boxSizerLvl1_1->Add(m_notebook, 1, wxEXPAND, WXC_FROM_DIP(5));
3198 
3199  m_panelGeneral = new wxPanel(m_notebook, wxID_ANY, wxDefaultPosition, wxDLG_UNIT(m_notebook, wxSize(-1,-1)), wxTAB_TRAVERSAL);
3200  m_notebook->AddPage(m_panelGeneral, _("General"), false);
3201 
3202  wxBoxSizer* boxSizerLvl2_1 = new wxBoxSizer(wxVERTICAL);
3203  m_panelGeneral->SetSizer(boxSizerLvl2_1);
3204 
3205  m_staticTextExp = new wxStaticText(m_panelGeneral, wxID_ANY, _("y = A.eB.x"), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), wxALIGN_CENTRE);
3206 
3207  boxSizerLvl2_1->Add(m_staticTextExp, 1, wxLEFT|wxRIGHT|wxTOP|wxEXPAND|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
3208 
3209  m_staticTextAValue = new wxStaticText(m_panelGeneral, wxID_ANY, _("A value"), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
3210 
3211  boxSizerLvl2_1->Add(m_staticTextAValue, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
3212 
3213  m_textCtrlAValue = new wxTextCtrl(m_panelGeneral, wxID_ANY, wxT(""), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
3214  #if wxVERSION_NUMBER >= 3000
3215  m_textCtrlAValue->SetHint(wxT(""));
3216  #endif
3217 
3218  boxSizerLvl2_1->Add(m_textCtrlAValue, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxEXPAND|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
3219  m_textCtrlAValue->SetMinSize(wxSize(100,-1));
3220 
3221  m_staticTextBValue = new wxStaticText(m_panelGeneral, wxID_ANY, _("B value"), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
3222 
3223  boxSizerLvl2_1->Add(m_staticTextBValue, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
3224 
3225  m_textCtrlBValue = new wxTextCtrl(m_panelGeneral, wxID_ANY, wxT(""), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
3226  #if wxVERSION_NUMBER >= 3000
3227  m_textCtrlBValue->SetHint(wxT(""));
3228  #endif
3229 
3230  boxSizerLvl2_1->Add(m_textCtrlBValue, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxEXPAND|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
3231  m_textCtrlBValue->SetMinSize(wxSize(100,-1));
3232 
3233  wxBoxSizer* boxSizerBottomButtons = new wxBoxSizer(wxHORIZONTAL);
3234 
3235  boxSizerLvl1_1->Add(boxSizerBottomButtons, 0, wxALL|wxEXPAND, WXC_FROM_DIP(5));
3236 
3237  boxSizerBottomButtons->Add(0, 0, 1, wxALL, WXC_FROM_DIP(5));
3238 
3239  m_buttonOK = new wxButton(this, wxID_ANY, _("OK"), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
3240 
3241  boxSizerBottomButtons->Add(m_buttonOK, 0, wxALL|wxALIGN_RIGHT, WXC_FROM_DIP(5));
3242 
3243  m_buttonCancel = new wxButton(this, wxID_ANY, _("Cancel"), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
3244 
3245  boxSizerBottomButtons->Add(m_buttonCancel, 0, wxALL|wxALIGN_RIGHT, WXC_FROM_DIP(5));
3246 
3247 
3248  #if wxVERSION_NUMBER >= 2900
3249  if(!wxPersistenceManager::Get().Find(m_notebook)){
3250  wxPersistenceManager::Get().RegisterAndRestore(m_notebook);
3251  } else {
3252  wxPersistenceManager::Get().Restore(m_notebook);
3253  }
3254  #endif
3255 
3256  SetName(wxT("ExponentialFormBase"));
3257  SetSize(-1,-1);
3258  if (GetSizer()) {
3259  GetSizer()->Fit(this);
3260  }
3261  if(GetParent()) {
3262  CentreOnParent(wxBOTH);
3263  } else {
3264  CentreOnScreen(wxBOTH);
3265  }
3266 #if wxVERSION_NUMBER >= 2900
3267  if(!wxPersistenceManager::Get().Find(this)) {
3268  wxPersistenceManager::Get().RegisterAndRestore(this);
3269  } else {
3270  wxPersistenceManager::Get().Restore(this);
3271  }
3272 #endif
3273  // Connect events
3274  m_buttonOK->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(ExponentialFormBase::OnOKButtonClick), NULL, this);
3275  m_buttonCancel->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(ExponentialFormBase::OnCancelButtonClick), NULL, this);
3276 
3277 }
3278 
3279 ExponentialFormBase::~ExponentialFormBase()
3280 {
3281  m_buttonOK->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(ExponentialFormBase::OnOKButtonClick), NULL, this);
3282  m_buttonCancel->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(ExponentialFormBase::OnCancelButtonClick), NULL, this);
3283 
3284 }
3285 
3286 ConstantFormBase::ConstantFormBase(wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style)
3287  : wxDialog(parent, id, title, pos, size, style)
3288 {
3289  if ( !bBitmapLoaded ) {
3290  // We need to initialise the default bitmap handler
3291  wxXmlResource::Get()->AddHandler(new wxBitmapXmlHandler);
3292  wxC9EE9InitBitmapResources();
3293  bBitmapLoaded = true;
3294  }
3295 
3296  wxBoxSizer* boxSizerLvl1_1 = new wxBoxSizer(wxVERTICAL);
3297  this->SetSizer(boxSizerLvl1_1);
3298 
3299  m_notebook = new wxNotebook(this, wxID_ANY, wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), wxBK_DEFAULT);
3300  m_notebook->SetName(wxT("m_notebook"));
3301 
3302  boxSizerLvl1_1->Add(m_notebook, 1, wxEXPAND, WXC_FROM_DIP(5));
3303 
3304  m_panelGeneral = new wxPanel(m_notebook, wxID_ANY, wxDefaultPosition, wxDLG_UNIT(m_notebook, wxSize(-1,-1)), wxTAB_TRAVERSAL);
3305  m_notebook->AddPage(m_panelGeneral, _("General"), false);
3306 
3307  wxBoxSizer* boxSizerLvl2_1 = new wxBoxSizer(wxVERTICAL);
3308  m_panelGeneral->SetSizer(boxSizerLvl2_1);
3309 
3310  m_staticTextValue = new wxStaticText(m_panelGeneral, wxID_ANY, _("Constant value"), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
3311 
3312  boxSizerLvl2_1->Add(m_staticTextValue, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
3313 
3314  m_textCtrlValue = new wxTextCtrl(m_panelGeneral, wxID_ANY, wxT(""), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
3315  #if wxVERSION_NUMBER >= 3000
3316  m_textCtrlValue->SetHint(wxT(""));
3317  #endif
3318 
3319  boxSizerLvl2_1->Add(m_textCtrlValue, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxEXPAND|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
3320  m_textCtrlValue->SetMinSize(wxSize(100,-1));
3321 
3322  wxBoxSizer* boxSizerBottomButtons = new wxBoxSizer(wxHORIZONTAL);
3323 
3324  boxSizerLvl1_1->Add(boxSizerBottomButtons, 0, wxALL|wxEXPAND, WXC_FROM_DIP(5));
3325 
3326  boxSizerBottomButtons->Add(0, 0, 1, wxALL, WXC_FROM_DIP(5));
3327 
3328  m_buttonOK = new wxButton(this, wxID_ANY, _("OK"), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
3329 
3330  boxSizerBottomButtons->Add(m_buttonOK, 0, wxALL|wxALIGN_RIGHT, WXC_FROM_DIP(5));
3331 
3332  m_buttonCancel = new wxButton(this, wxID_ANY, _("Cancel"), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
3333 
3334  boxSizerBottomButtons->Add(m_buttonCancel, 0, wxALL|wxALIGN_RIGHT, WXC_FROM_DIP(5));
3335 
3336 
3337  #if wxVERSION_NUMBER >= 2900
3338  if(!wxPersistenceManager::Get().Find(m_notebook)){
3339  wxPersistenceManager::Get().RegisterAndRestore(m_notebook);
3340  } else {
3341  wxPersistenceManager::Get().Restore(m_notebook);
3342  }
3343  #endif
3344 
3345  SetName(wxT("ConstantFormBase"));
3346  SetSize(-1,-1);
3347  if (GetSizer()) {
3348  GetSizer()->Fit(this);
3349  }
3350  if(GetParent()) {
3351  CentreOnParent(wxBOTH);
3352  } else {
3353  CentreOnScreen(wxBOTH);
3354  }
3355 #if wxVERSION_NUMBER >= 2900
3356  if(!wxPersistenceManager::Get().Find(this)) {
3357  wxPersistenceManager::Get().RegisterAndRestore(this);
3358  } else {
3359  wxPersistenceManager::Get().Restore(this);
3360  }
3361 #endif
3362  // Connect events
3363  m_buttonOK->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(ConstantFormBase::OnOKButtonClick), NULL, this);
3364  m_buttonCancel->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(ConstantFormBase::OnCancelButtonClick), NULL, this);
3365 
3366 }
3367 
3368 ConstantFormBase::~ConstantFormBase()
3369 {
3370  m_buttonOK->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(ConstantFormBase::OnOKButtonClick), NULL, this);
3371  m_buttonCancel->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(ConstantFormBase::OnCancelButtonClick), NULL, this);
3372 
3373 }
3374 
3375 GainFormBase::GainFormBase(wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style)
3376  : wxDialog(parent, id, title, pos, size, style)
3377 {
3378  if ( !bBitmapLoaded ) {
3379  // We need to initialise the default bitmap handler
3380  wxXmlResource::Get()->AddHandler(new wxBitmapXmlHandler);
3381  wxC9EE9InitBitmapResources();
3382  bBitmapLoaded = true;
3383  }
3384 
3385  wxBoxSizer* boxSizerLvl1_1 = new wxBoxSizer(wxVERTICAL);
3386  this->SetSizer(boxSizerLvl1_1);
3387 
3388  m_notebook = new wxNotebook(this, wxID_ANY, wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), wxBK_DEFAULT);
3389  m_notebook->SetName(wxT("m_notebook"));
3390 
3391  boxSizerLvl1_1->Add(m_notebook, 1, wxEXPAND, WXC_FROM_DIP(5));
3392 
3393  m_panelGeneral = new wxPanel(m_notebook, wxID_ANY, wxDefaultPosition, wxDLG_UNIT(m_notebook, wxSize(-1,-1)), wxTAB_TRAVERSAL);
3394  m_notebook->AddPage(m_panelGeneral, _("General"), false);
3395 
3396  wxBoxSizer* boxSizerLvl2_1 = new wxBoxSizer(wxVERTICAL);
3397  m_panelGeneral->SetSizer(boxSizerLvl2_1);
3398 
3399  m_staticTextValue = new wxStaticText(m_panelGeneral, wxID_ANY, _("Gain value"), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
3400 
3401  boxSizerLvl2_1->Add(m_staticTextValue, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
3402 
3403  m_textCtrlValue = new wxTextCtrl(m_panelGeneral, wxID_ANY, wxT(""), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
3404  #if wxVERSION_NUMBER >= 3000
3405  m_textCtrlValue->SetHint(wxT(""));
3406  #endif
3407 
3408  boxSizerLvl2_1->Add(m_textCtrlValue, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxEXPAND|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
3409  m_textCtrlValue->SetMinSize(wxSize(100,-1));
3410 
3411  wxBoxSizer* boxSizerBottomButtons = new wxBoxSizer(wxHORIZONTAL);
3412 
3413  boxSizerLvl1_1->Add(boxSizerBottomButtons, 0, wxALL|wxEXPAND, WXC_FROM_DIP(5));
3414 
3415  boxSizerBottomButtons->Add(0, 0, 1, wxALL, WXC_FROM_DIP(5));
3416 
3417  m_buttonOK = new wxButton(this, wxID_ANY, _("OK"), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
3418 
3419  boxSizerBottomButtons->Add(m_buttonOK, 0, wxALL|wxALIGN_RIGHT, WXC_FROM_DIP(5));
3420 
3421  m_buttonCancel = new wxButton(this, wxID_ANY, _("Cancel"), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
3422 
3423  boxSizerBottomButtons->Add(m_buttonCancel, 0, wxALL|wxALIGN_RIGHT, WXC_FROM_DIP(5));
3424 
3425 
3426  #if wxVERSION_NUMBER >= 2900
3427  if(!wxPersistenceManager::Get().Find(m_notebook)){
3428  wxPersistenceManager::Get().RegisterAndRestore(m_notebook);
3429  } else {
3430  wxPersistenceManager::Get().Restore(m_notebook);
3431  }
3432  #endif
3433 
3434  SetName(wxT("GainFormBase"));
3435  SetSize(-1,-1);
3436  if (GetSizer()) {
3437  GetSizer()->Fit(this);
3438  }
3439  if(GetParent()) {
3440  CentreOnParent(wxBOTH);
3441  } else {
3442  CentreOnScreen(wxBOTH);
3443  }
3444 #if wxVERSION_NUMBER >= 2900
3445  if(!wxPersistenceManager::Get().Find(this)) {
3446  wxPersistenceManager::Get().RegisterAndRestore(this);
3447  } else {
3448  wxPersistenceManager::Get().Restore(this);
3449  }
3450 #endif
3451  // Connect events
3452  m_buttonOK->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(GainFormBase::OnOKButtonClick), NULL, this);
3453  m_buttonCancel->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(GainFormBase::OnCancelButtonClick), NULL, this);
3454 
3455 }
3456 
3457 GainFormBase::~GainFormBase()
3458 {
3459  m_buttonOK->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(GainFormBase::OnOKButtonClick), NULL, this);
3460  m_buttonCancel->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(GainFormBase::OnCancelButtonClick), NULL, this);
3461 
3462 }
3463 
3464 IOControlFormBase::IOControlFormBase(wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style)
3465  : wxDialog(parent, id, title, pos, size, style)
3466 {
3467  if ( !bBitmapLoaded ) {
3468  // We need to initialise the default bitmap handler
3469  wxXmlResource::Get()->AddHandler(new wxBitmapXmlHandler);
3470  wxC9EE9InitBitmapResources();
3471  bBitmapLoaded = true;
3472  }
3473 
3474  wxBoxSizer* boxSizerLvl1_1 = new wxBoxSizer(wxVERTICAL);
3475  this->SetSizer(boxSizerLvl1_1);
3476 
3477  m_notebook = new wxNotebook(this, wxID_ANY, wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), wxBK_DEFAULT);
3478  m_notebook->SetName(wxT("m_notebook"));
3479 
3480  boxSizerLvl1_1->Add(m_notebook, 1, wxEXPAND, WXC_FROM_DIP(5));
3481 
3482  m_panelGeneral = new wxPanel(m_notebook, wxID_ANY, wxDefaultPosition, wxDLG_UNIT(m_notebook, wxSize(-1,-1)), wxTAB_TRAVERSAL);
3483  m_notebook->AddPage(m_panelGeneral, _("General"), false);
3484 
3485  wxBoxSizer* boxSizerLvl2_1 = new wxBoxSizer(wxVERTICAL);
3486  m_panelGeneral->SetSizer(boxSizerLvl2_1);
3487 
3488  m_checkBoxInput = new wxCheckBox(m_panelGeneral, wxID_ANY, _("Input"), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
3489  m_checkBoxInput->SetValue(false);
3490 
3491  boxSizerLvl2_1->Add(m_checkBoxInput, 0, wxLEFT|wxRIGHT|wxTOP, WXC_FROM_DIP(5));
3492 
3493  wxArrayString m_choiceInputArr;
3494  m_choiceInput = new wxChoice(m_panelGeneral, wxID_ANY, wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), m_choiceInputArr, 0);
3495 
3496  boxSizerLvl2_1->Add(m_choiceInput, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxEXPAND, WXC_FROM_DIP(5));
3497 
3498  m_checkBoxOutput = new wxCheckBox(m_panelGeneral, wxID_ANY, _("Output"), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
3499  m_checkBoxOutput->SetValue(false);
3500 
3501  boxSizerLvl2_1->Add(m_checkBoxOutput, 0, wxLEFT|wxRIGHT|wxTOP, WXC_FROM_DIP(5));
3502 
3503  wxArrayString m_choiceOutputArr;
3504  m_choiceOutput = new wxChoice(m_panelGeneral, wxID_ANY, wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), m_choiceOutputArr, 0);
3505 
3506  boxSizerLvl2_1->Add(m_choiceOutput, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxEXPAND, WXC_FROM_DIP(5));
3507 
3508  wxBoxSizer* boxSizerBottomButtons = new wxBoxSizer(wxHORIZONTAL);
3509 
3510  boxSizerLvl1_1->Add(boxSizerBottomButtons, 0, wxALL|wxEXPAND, WXC_FROM_DIP(5));
3511 
3512  boxSizerBottomButtons->Add(0, 0, 1, wxALL, WXC_FROM_DIP(5));
3513 
3514  m_buttonOK = new wxButton(this, wxID_ANY, _("OK"), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
3515 
3516  boxSizerBottomButtons->Add(m_buttonOK, 0, wxALL|wxALIGN_RIGHT, WXC_FROM_DIP(5));
3517 
3518  m_ButtonCancel = new wxButton(this, wxID_ANY, _("Cancel"), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
3519 
3520  boxSizerBottomButtons->Add(m_ButtonCancel, 0, wxALL|wxALIGN_RIGHT, WXC_FROM_DIP(5));
3521 
3522 
3523  #if wxVERSION_NUMBER >= 2900
3524  if(!wxPersistenceManager::Get().Find(m_notebook)){
3525  wxPersistenceManager::Get().RegisterAndRestore(m_notebook);
3526  } else {
3527  wxPersistenceManager::Get().Restore(m_notebook);
3528  }
3529  #endif
3530 
3531  SetName(wxT("IOControlFormBase"));
3532  SetSize(-1,-1);
3533  if (GetSizer()) {
3534  GetSizer()->Fit(this);
3535  }
3536  if(GetParent()) {
3537  CentreOnParent(wxBOTH);
3538  } else {
3539  CentreOnScreen(wxBOTH);
3540  }
3541 #if wxVERSION_NUMBER >= 2900
3542  if(!wxPersistenceManager::Get().Find(this)) {
3543  wxPersistenceManager::Get().RegisterAndRestore(this);
3544  } else {
3545  wxPersistenceManager::Get().Restore(this);
3546  }
3547 #endif
3548  // Connect events
3549  m_checkBoxInput->Connect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler(IOControlFormBase::OnInputChecked), NULL, this);
3550  m_checkBoxOutput->Connect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler(IOControlFormBase::OnOutputChecked), NULL, this);
3551  m_buttonOK->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(IOControlFormBase::OnOKButtonClick), NULL, this);
3552  m_ButtonCancel->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(IOControlFormBase::OnCancelButtonClick), NULL, this);
3553 
3554 }
3555 
3556 IOControlFormBase::~IOControlFormBase()
3557 {
3558  m_checkBoxInput->Disconnect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler(IOControlFormBase::OnInputChecked), NULL, this);
3559  m_checkBoxOutput->Disconnect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler(IOControlFormBase::OnOutputChecked), NULL, this);
3560  m_buttonOK->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(IOControlFormBase::OnOKButtonClick), NULL, this);
3561  m_ButtonCancel->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(IOControlFormBase::OnCancelButtonClick), NULL, this);
3562 
3563 }
+
1 // This file was auto-generated by codelite's wxCrafter Plugin
3 // wxCrafter project file: ElementForm.wxcp
4 // Do not modify this file by hand!
6 
7 #include "ElementForm.h"
8 
9 
10 // Declare the bitmap loading function
11 extern void wxC9EE9InitBitmapResources();
12 
13 static bool bBitmapLoaded = false;
14 
15 
16 BusFormBase::BusFormBase(wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style)
17  : wxDialog(parent, id, title, pos, size, style)
18 {
19  if ( !bBitmapLoaded ) {
20  // We need to initialise the default bitmap handler
21  wxXmlResource::Get()->AddHandler(new wxBitmapXmlHandler);
22  wxC9EE9InitBitmapResources();
23  bBitmapLoaded = true;
24  }
25 
26  wxBoxSizer* boxSizerLvl1_1 = new wxBoxSizer(wxVERTICAL);
27  this->SetSizer(boxSizerLvl1_1);
28 
29  m_notebook = new wxNotebook(this, wxID_ANY, wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), wxBK_DEFAULT);
30  m_notebook->SetName(wxT("m_notebook"));
31 
32  boxSizerLvl1_1->Add(m_notebook, 1, wxEXPAND, WXC_FROM_DIP(5));
33 
34  m_panelGeneral = new wxPanel(m_notebook, wxID_ANY, wxDefaultPosition, wxDLG_UNIT(m_notebook, wxSize(-1,-1)), wxTAB_TRAVERSAL);
35  m_notebook->AddPage(m_panelGeneral, _("General"), false);
36 
37  wxBoxSizer* boxSizerLvl2_1 = new wxBoxSizer(wxVERTICAL);
38  m_panelGeneral->SetSizer(boxSizerLvl2_1);
39 
40  m_staticTextName = new wxStaticText(m_panelGeneral, wxID_ANY, _("Name"), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
41 
42  boxSizerLvl2_1->Add(m_staticTextName, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
43 
44  m_textCtrlName = new wxTextCtrl(m_panelGeneral, wxID_ANY, wxT(""), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
45  #if wxVERSION_NUMBER >= 3000
46  m_textCtrlName->SetHint(wxT(""));
47  #endif
48 
49  boxSizerLvl2_1->Add(m_textCtrlName, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxEXPAND|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
50  m_textCtrlName->SetMinSize(wxSize(300,-1));
51 
52  wxGridSizer* gridSizerLvl3_1 = new wxGridSizer(0, 2, 0, 0);
53 
54  boxSizerLvl2_1->Add(gridSizerLvl3_1, 0, wxEXPAND, WXC_FROM_DIP(5));
55 
56  wxBoxSizer* boxSizerLvl4_1 = new wxBoxSizer(wxVERTICAL);
57 
58  gridSizerLvl3_1->Add(boxSizerLvl4_1, 0, wxEXPAND, WXC_FROM_DIP(5));
59 
60  m_staticTextNomVoltage = new wxStaticText(m_panelGeneral, wxID_ANY, _("Rated voltage"), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
61 
62  boxSizerLvl4_1->Add(m_staticTextNomVoltage, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
63 
64  wxBoxSizer* boxSizerLvl5_1 = new wxBoxSizer(wxHORIZONTAL);
65 
66  boxSizerLvl4_1->Add(boxSizerLvl5_1, 0, wxEXPAND, WXC_FROM_DIP(5));
67 
68  m_textCtrlNomVoltage = new wxTextCtrl(m_panelGeneral, wxID_ANY, wxT(""), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
69  #if wxVERSION_NUMBER >= 3000
70  m_textCtrlNomVoltage->SetHint(wxT(""));
71  #endif
72 
73  boxSizerLvl5_1->Add(m_textCtrlNomVoltage, 1, wxLEFT|wxRIGHT|wxBOTTOM|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
74 
75  wxArrayString m_choiceNomVoltageArr;
76  m_choiceNomVoltageArr.Add(wxT("V"));
77  m_choiceNomVoltageArr.Add(wxT("kV"));
78  m_choiceNomVoltage = new wxChoice(m_panelGeneral, wxID_ANY, wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), m_choiceNomVoltageArr, 0);
79  m_choiceNomVoltage->SetSelection(1);
80 
81  boxSizerLvl5_1->Add(m_choiceNomVoltage, 0, wxLEFT|wxRIGHT|wxBOTTOM, WXC_FROM_DIP(5));
82 
83  wxBoxSizer* boxSizerLvl4_2 = new wxBoxSizer(wxVERTICAL);
84 
85  gridSizerLvl3_1->Add(boxSizerLvl4_2, 0, wxEXPAND, WXC_FROM_DIP(5));
86 
87  m_checkBoxCtrlVoltage = new wxCheckBox(m_panelGeneral, wxID_ANY, _("Controlled voltage"), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
88  m_checkBoxCtrlVoltage->SetValue(false);
89 
90  boxSizerLvl4_2->Add(m_checkBoxCtrlVoltage, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
91 
92  wxBoxSizer* boxSizerLvl5_2 = new wxBoxSizer(wxHORIZONTAL);
93 
94  boxSizerLvl4_2->Add(boxSizerLvl5_2, 0, wxEXPAND, WXC_FROM_DIP(5));
95 
96  m_textCtrlCtrlVoltage = new wxTextCtrl(m_panelGeneral, wxID_ANY, wxT(""), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
97  #if wxVERSION_NUMBER >= 3000
98  m_textCtrlCtrlVoltage->SetHint(wxT(""));
99  #endif
100 
101  boxSizerLvl5_2->Add(m_textCtrlCtrlVoltage, 1, wxLEFT|wxRIGHT|wxBOTTOM|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
102 
103  wxArrayString m_choiceCtrlVoltageArr;
104  m_choiceCtrlVoltageArr.Add(wxT("p.u."));
105  m_choiceCtrlVoltageArr.Add(wxT("kV"));
106  m_choiceCtrlVoltage = new wxChoice(m_panelGeneral, wxID_ANY, wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), m_choiceCtrlVoltageArr, 0);
107  m_choiceCtrlVoltage->SetSelection(0);
108 
109  boxSizerLvl5_2->Add(m_choiceCtrlVoltage, 0, wxLEFT|wxRIGHT|wxBOTTOM, WXC_FROM_DIP(5));
110 
111  m_checkBoxSlackBus = new wxCheckBox(m_panelGeneral, wxID_ANY, _("Slack Bus"), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
112  m_checkBoxSlackBus->SetValue(false);
113 
114  boxSizerLvl2_1->Add(m_checkBoxSlackBus, 0, wxALL|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
115 
116  m_panelFault = new wxPanel(m_notebook, wxID_ANY, wxDefaultPosition, wxDLG_UNIT(m_notebook, wxSize(-1,-1)), wxTAB_TRAVERSAL);
117  m_notebook->AddPage(m_panelFault, _("Fault"), false);
118 
119  wxBoxSizer* boxSizerLvl2_2 = new wxBoxSizer(wxVERTICAL);
120  m_panelFault->SetSizer(boxSizerLvl2_2);
121 
122  m_checkBoxFault = new wxCheckBox(m_panelFault, wxID_ANY, _("Insert fault in the bus"), wxDefaultPosition, wxDLG_UNIT(m_panelFault, wxSize(-1,-1)), 0);
123  m_checkBoxFault->SetValue(false);
124 
125  boxSizerLvl2_2->Add(m_checkBoxFault, 0, wxALL|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
126 
127  wxGridSizer* gridSizerLvl3_2 = new wxGridSizer(0, 2, 0, 0);
128 
129  boxSizerLvl2_2->Add(gridSizerLvl3_2, 0, wxEXPAND, WXC_FROM_DIP(5));
130 
131  wxBoxSizer* boxSizerLvl4_3 = new wxBoxSizer(wxVERTICAL);
132 
133  gridSizerLvl3_2->Add(boxSizerLvl4_3, 0, wxEXPAND, WXC_FROM_DIP(5));
134 
135  m_staticTextFaultType = new wxStaticText(m_panelFault, wxID_ANY, _("Fault type"), wxDefaultPosition, wxDLG_UNIT(m_panelFault, wxSize(-1,-1)), 0);
136 
137  boxSizerLvl4_3->Add(m_staticTextFaultType, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
138 
139  wxArrayString m_choiceFaultTypeArr;
140  m_choiceFaultTypeArr.Add(wxT("Three-phase"));
141  m_choiceFaultTypeArr.Add(wxT("Line-to-line"));
142  m_choiceFaultTypeArr.Add(wxT("Double line-to-ground"));
143  m_choiceFaultTypeArr.Add(wxT("Line-to-ground"));
144  m_choiceFaultType = new wxChoice(m_panelFault, wxID_ANY, wxDefaultPosition, wxDLG_UNIT(m_panelFault, wxSize(-1,-1)), m_choiceFaultTypeArr, 0);
145  m_choiceFaultType->SetSelection(0);
146 
147  boxSizerLvl4_3->Add(m_choiceFaultType, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxEXPAND|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
148 
149  wxBoxSizer* boxSizerLvl4_4 = new wxBoxSizer(wxVERTICAL);
150 
151  gridSizerLvl3_2->Add(boxSizerLvl4_4, 0, wxEXPAND, WXC_FROM_DIP(5));
152 
153  m_staticTextFaultPlace = new wxStaticText(m_panelFault, wxID_ANY, _("Fault place"), wxDefaultPosition, wxDLG_UNIT(m_panelFault, wxSize(-1,-1)), 0);
154 
155  boxSizerLvl4_4->Add(m_staticTextFaultPlace, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
156 
157  wxArrayString m_choiceFaultPlaceArr;
158  m_choiceFaultPlaceArr.Add(wxT("Line A"));
159  m_choiceFaultPlaceArr.Add(wxT("Line B"));
160  m_choiceFaultPlaceArr.Add(wxT("Line C"));
161  m_choiceFaultPlace = new wxChoice(m_panelFault, wxID_ANY, wxDefaultPosition, wxDLG_UNIT(m_panelFault, wxSize(-1,-1)), m_choiceFaultPlaceArr, 0);
162  m_choiceFaultPlace->SetSelection(0);
163 
164  boxSizerLvl4_4->Add(m_choiceFaultPlace, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxEXPAND|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
165 
166  wxBoxSizer* boxSizerLvl4_5 = new wxBoxSizer(wxVERTICAL);
167 
168  gridSizerLvl3_2->Add(boxSizerLvl4_5, 0, wxEXPAND, WXC_FROM_DIP(5));
169 
170  m_staticTextFaultResistance = new wxStaticText(m_panelFault, wxID_ANY, _("Fault resistance (R)"), wxDefaultPosition, wxDLG_UNIT(m_panelFault, wxSize(-1,-1)), 0);
171 
172  boxSizerLvl4_5->Add(m_staticTextFaultResistance, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
173 
174  wxBoxSizer* boxSizerLvl5_3 = new wxBoxSizer(wxHORIZONTAL);
175 
176  boxSizerLvl4_5->Add(boxSizerLvl5_3, 0, wxEXPAND, WXC_FROM_DIP(5));
177 
178  m_textCtrlFaultResistance = new wxTextCtrl(m_panelFault, wxID_ANY, wxT(""), wxDefaultPosition, wxDLG_UNIT(m_panelFault, wxSize(-1,-1)), 0);
179  #if wxVERSION_NUMBER >= 3000
180  m_textCtrlFaultResistance->SetHint(wxT(""));
181  #endif
182 
183  boxSizerLvl5_3->Add(m_textCtrlFaultResistance, 1, wxLEFT|wxRIGHT|wxBOTTOM|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
184 
185  m_staticTextPU_1 = new wxStaticText(m_panelFault, wxID_ANY, _("p.u."), wxDefaultPosition, wxDLG_UNIT(m_panelFault, wxSize(-1,-1)), 0);
186 
187  boxSizerLvl5_3->Add(m_staticTextPU_1, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
188 
189  wxBoxSizer* boxSizerLvl4_6 = new wxBoxSizer(wxVERTICAL);
190 
191  gridSizerLvl3_2->Add(boxSizerLvl4_6, 0, wxEXPAND, WXC_FROM_DIP(5));
192 
193  m_staticTextReactance = new wxStaticText(m_panelFault, wxID_ANY, _("Fault reactance (Xl)"), wxDefaultPosition, wxDLG_UNIT(m_panelFault, wxSize(-1,-1)), 0);
194 
195  boxSizerLvl4_6->Add(m_staticTextReactance, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
196 
197  wxBoxSizer* boxSizerLvl5_4 = new wxBoxSizer(wxHORIZONTAL);
198 
199  boxSizerLvl4_6->Add(boxSizerLvl5_4, 0, wxEXPAND, WXC_FROM_DIP(5));
200 
201  m_textCtrlFaultReactance = new wxTextCtrl(m_panelFault, wxID_ANY, wxT(""), wxDefaultPosition, wxDLG_UNIT(m_panelFault, wxSize(-1,-1)), 0);
202  #if wxVERSION_NUMBER >= 3000
203  m_textCtrlFaultReactance->SetHint(wxT(""));
204  #endif
205 
206  boxSizerLvl5_4->Add(m_textCtrlFaultReactance, 1, wxLEFT|wxRIGHT|wxBOTTOM|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
207 
208  m_staticTextPU_2 = new wxStaticText(m_panelFault, wxID_ANY, _("p.u."), wxDefaultPosition, wxDLG_UNIT(m_panelFault, wxSize(-1,-1)), 0);
209 
210  boxSizerLvl5_4->Add(m_staticTextPU_2, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
211 
212  m_panelStability = new wxPanel(m_notebook, wxID_ANY, wxDefaultPosition, wxDLG_UNIT(m_notebook, wxSize(-1,-1)), wxTAB_TRAVERSAL);
213  m_notebook->AddPage(m_panelStability, _("Stability"), false);
214 
215  wxBoxSizer* boxSizerLvl2_3 = new wxBoxSizer(wxVERTICAL);
216  m_panelStability->SetSizer(boxSizerLvl2_3);
217 
218  m_checkBoxPlotData = new wxCheckBox(m_panelStability, wxID_ANY, _("Plot bus data"), wxDefaultPosition, wxDLG_UNIT(m_panelStability, wxSize(-1,-1)), 0);
219  m_checkBoxPlotData->SetValue(false);
220 
221  boxSizerLvl2_3->Add(m_checkBoxPlotData, 0, wxALL|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
222 
223  m_checkBoxStabFault = new wxCheckBox(m_panelStability, wxID_ANY, _("Insert fault in the bus"), wxDefaultPosition, wxDLG_UNIT(m_panelStability, wxSize(-1,-1)), 0);
224  m_checkBoxStabFault->SetValue(false);
225 
226  boxSizerLvl2_3->Add(m_checkBoxStabFault, 0, wxALL|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
227 
228  wxGridSizer* gridSizerLvl3_3 = new wxGridSizer(0, 2, 0, 0);
229 
230  boxSizerLvl2_3->Add(gridSizerLvl3_3, 0, wxEXPAND, WXC_FROM_DIP(5));
231 
232  wxBoxSizer* boxSizerLvl4_7 = new wxBoxSizer(wxVERTICAL);
233 
234  gridSizerLvl3_3->Add(boxSizerLvl4_7, 0, wxEXPAND, WXC_FROM_DIP(5));
235 
236  m_staticTextStabFaultTime = new wxStaticText(m_panelStability, wxID_ANY, _("Time"), wxDefaultPosition, wxDLG_UNIT(m_panelStability, wxSize(-1,-1)), 0);
237 
238  boxSizerLvl4_7->Add(m_staticTextStabFaultTime, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
239 
240  wxBoxSizer* boxSizerLvl5_5 = new wxBoxSizer(wxHORIZONTAL);
241 
242  boxSizerLvl4_7->Add(boxSizerLvl5_5, 0, wxEXPAND, WXC_FROM_DIP(5));
243 
244  m_textCtrlStabFaultTime = new wxTextCtrl(m_panelStability, wxID_ANY, wxT(""), wxDefaultPosition, wxDLG_UNIT(m_panelStability, wxSize(-1,-1)), 0);
245  #if wxVERSION_NUMBER >= 3000
246  m_textCtrlStabFaultTime->SetHint(wxT(""));
247  #endif
248 
249  boxSizerLvl5_5->Add(m_textCtrlStabFaultTime, 1, wxLEFT|wxRIGHT|wxBOTTOM|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
250 
251  m_staticTextS_1 = new wxStaticText(m_panelStability, wxID_ANY, _("s"), wxDefaultPosition, wxDLG_UNIT(m_panelStability, wxSize(-1,-1)), 0);
252 
253  boxSizerLvl5_5->Add(m_staticTextS_1, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
254 
255  wxBoxSizer* boxSizerLvl4_8 = new wxBoxSizer(wxVERTICAL);
256 
257  gridSizerLvl3_3->Add(boxSizerLvl4_8, 0, wxEXPAND, WXC_FROM_DIP(5));
258 
259  m_staticTextStabFaultLength = new wxStaticText(m_panelStability, wxID_ANY, _("Fault length"), wxDefaultPosition, wxDLG_UNIT(m_panelStability, wxSize(-1,-1)), 0);
260 
261  boxSizerLvl4_8->Add(m_staticTextStabFaultLength, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
262 
263  wxBoxSizer* boxSizerLvl5_6 = new wxBoxSizer(wxHORIZONTAL);
264 
265  boxSizerLvl4_8->Add(boxSizerLvl5_6, 0, wxEXPAND, WXC_FROM_DIP(5));
266 
267  m_textCtrlStabFaultLength = new wxTextCtrl(m_panelStability, wxID_ANY, wxT(""), wxDefaultPosition, wxDLG_UNIT(m_panelStability, wxSize(-1,-1)), 0);
268  #if wxVERSION_NUMBER >= 3000
269  m_textCtrlStabFaultLength->SetHint(wxT(""));
270  #endif
271 
272  boxSizerLvl5_6->Add(m_textCtrlStabFaultLength, 1, wxLEFT|wxRIGHT|wxBOTTOM|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
273 
274  m_staticTextS_2 = new wxStaticText(m_panelStability, wxID_ANY, _("s"), wxDefaultPosition, wxDLG_UNIT(m_panelStability, wxSize(-1,-1)), 0);
275 
276  boxSizerLvl5_6->Add(m_staticTextS_2, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
277 
278  wxBoxSizer* boxSizerLvl4_9 = new wxBoxSizer(wxVERTICAL);
279 
280  gridSizerLvl3_3->Add(boxSizerLvl4_9, 0, wxEXPAND, WXC_FROM_DIP(5));
281 
282  m_staticTextStabFaultResistance = new wxStaticText(m_panelStability, wxID_ANY, _("Fault resistance (R)"), wxDefaultPosition, wxDLG_UNIT(m_panelStability, wxSize(-1,-1)), 0);
283 
284  boxSizerLvl4_9->Add(m_staticTextStabFaultResistance, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
285 
286  wxBoxSizer* boxSizerLvl5_7 = new wxBoxSizer(wxHORIZONTAL);
287 
288  boxSizerLvl4_9->Add(boxSizerLvl5_7, 0, wxEXPAND, WXC_FROM_DIP(5));
289 
290  m_textCtrlStabFaultResistance = new wxTextCtrl(m_panelStability, wxID_ANY, wxT(""), wxDefaultPosition, wxDLG_UNIT(m_panelStability, wxSize(-1,-1)), 0);
291  #if wxVERSION_NUMBER >= 3000
292  m_textCtrlStabFaultResistance->SetHint(wxT(""));
293  #endif
294 
295  boxSizerLvl5_7->Add(m_textCtrlStabFaultResistance, 1, wxLEFT|wxRIGHT|wxBOTTOM|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
296 
297  m_staticTextPU_3 = new wxStaticText(m_panelStability, wxID_ANY, _("p.u."), wxDefaultPosition, wxDLG_UNIT(m_panelStability, wxSize(-1,-1)), 0);
298 
299  boxSizerLvl5_7->Add(m_staticTextPU_3, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
300 
301  wxBoxSizer* boxSizerLvl4_10 = new wxBoxSizer(wxVERTICAL);
302 
303  gridSizerLvl3_3->Add(boxSizerLvl4_10, 0, wxEXPAND, WXC_FROM_DIP(5));
304 
305  m_staticTextStabFaultReactance = new wxStaticText(m_panelStability, wxID_ANY, _("Fault reactance (Xl)"), wxDefaultPosition, wxDLG_UNIT(m_panelStability, wxSize(-1,-1)), 0);
306 
307  boxSizerLvl4_10->Add(m_staticTextStabFaultReactance, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
308 
309  wxBoxSizer* boxSizerLvl5_8 = new wxBoxSizer(wxHORIZONTAL);
310 
311  boxSizerLvl4_10->Add(boxSizerLvl5_8, 0, wxEXPAND, WXC_FROM_DIP(5));
312 
313  m_textCtrlStabFaultReactance = new wxTextCtrl(m_panelStability, wxID_ANY, wxT(""), wxDefaultPosition, wxDLG_UNIT(m_panelStability, wxSize(-1,-1)), 0);
314  #if wxVERSION_NUMBER >= 3000
315  m_textCtrlStabFaultReactance->SetHint(wxT(""));
316  #endif
317 
318  boxSizerLvl5_8->Add(m_textCtrlStabFaultReactance, 1, wxLEFT|wxRIGHT|wxBOTTOM|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
319 
320  m_staticTextPU_4 = new wxStaticText(m_panelStability, wxID_ANY, _("p.u."), wxDefaultPosition, wxDLG_UNIT(m_panelStability, wxSize(-1,-1)), 0);
321 
322  boxSizerLvl5_8->Add(m_staticTextPU_4, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
323 
324  wxBoxSizer* boxSizerOkCancel = new wxBoxSizer(wxHORIZONTAL);
325 
326  boxSizerLvl1_1->Add(boxSizerOkCancel, 0, wxALL|wxALIGN_RIGHT, WXC_FROM_DIP(5));
327 
328  m_buttonOK = new wxButton(this, wxID_ANY, _("OK"), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
329 
330  boxSizerOkCancel->Add(m_buttonOK, 0, wxALL|wxALIGN_RIGHT, WXC_FROM_DIP(5));
331 
332  m_ButtonCancel = new wxButton(this, wxID_ANY, _("Cancel"), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
333 
334  boxSizerOkCancel->Add(m_ButtonCancel, 0, wxALL|wxALIGN_RIGHT, WXC_FROM_DIP(5));
335 
336 
337  #if wxVERSION_NUMBER >= 2900
338  if(!wxPersistenceManager::Get().Find(m_notebook)){
339  wxPersistenceManager::Get().RegisterAndRestore(m_notebook);
340  } else {
341  wxPersistenceManager::Get().Restore(m_notebook);
342  }
343  #endif
344 
345  SetName(wxT("BusFormBase"));
346  SetSize(-1,-1);
347  if (GetSizer()) {
348  GetSizer()->Fit(this);
349  }
350  if(GetParent()) {
351  CentreOnParent(wxVERTICAL);
352  } else {
353  CentreOnScreen(wxVERTICAL);
354  }
355 #if wxVERSION_NUMBER >= 2900
356  if(!wxPersistenceManager::Get().Find(this)) {
357  wxPersistenceManager::Get().RegisterAndRestore(this);
358  } else {
359  wxPersistenceManager::Get().Restore(this);
360  }
361 #endif
362  // Connect events
363  m_choiceNomVoltage->Connect(wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler(BusFormBase::OnNominalVoltageChoice), NULL, this);
364  m_checkBoxCtrlVoltage->Connect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler(BusFormBase::OnControlledVoltageClick), NULL, this);
365  m_checkBoxFault->Connect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler(BusFormBase::OnInsertFaultClick), NULL, this);
366  m_choiceFaultType->Connect(wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler(BusFormBase::OnFaultTypeChoice), NULL, this);
367  m_checkBoxStabFault->Connect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler(BusFormBase::OnInsertStabFaultClick), NULL, this);
368  m_buttonOK->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(BusFormBase::OnButtonOKClick), NULL, this);
369  m_ButtonCancel->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(BusFormBase::OnButtonCancelClick), NULL, this);
370 
371 }
372 
373 BusFormBase::~BusFormBase()
374 {
375  m_choiceNomVoltage->Disconnect(wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler(BusFormBase::OnNominalVoltageChoice), NULL, this);
376  m_checkBoxCtrlVoltage->Disconnect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler(BusFormBase::OnControlledVoltageClick), NULL, this);
377  m_checkBoxFault->Disconnect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler(BusFormBase::OnInsertFaultClick), NULL, this);
378  m_choiceFaultType->Disconnect(wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler(BusFormBase::OnFaultTypeChoice), NULL, this);
379  m_checkBoxStabFault->Disconnect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler(BusFormBase::OnInsertStabFaultClick), NULL, this);
380  m_buttonOK->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(BusFormBase::OnButtonOKClick), NULL, this);
381  m_ButtonCancel->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(BusFormBase::OnButtonCancelClick), NULL, this);
382 
383 }
384 
385 SyncMachineFormBase::SyncMachineFormBase(wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style)
386  : wxDialog(parent, id, title, pos, size, style)
387 {
388  if ( !bBitmapLoaded ) {
389  // We need to initialise the default bitmap handler
390  wxXmlResource::Get()->AddHandler(new wxBitmapXmlHandler);
391  wxC9EE9InitBitmapResources();
392  bBitmapLoaded = true;
393  }
394 
395  wxBoxSizer* boxSizerLvl1_1 = new wxBoxSizer(wxVERTICAL);
396  this->SetSizer(boxSizerLvl1_1);
397 
398  m_notebook = new wxNotebook(this, wxID_ANY, wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), wxBK_DEFAULT);
399  m_notebook->SetName(wxT("m_notebook"));
400 
401  boxSizerLvl1_1->Add(m_notebook, 1, wxEXPAND, WXC_FROM_DIP(5));
402 
403  m_panelGeneral = new wxPanel(m_notebook, wxID_ANY, wxDefaultPosition, wxDLG_UNIT(m_notebook, wxSize(-1,-1)), wxTAB_TRAVERSAL);
404  m_notebook->AddPage(m_panelGeneral, _("General"), false);
405 
406  wxBoxSizer* boxSizerLvl2_1 = new wxBoxSizer(wxVERTICAL);
407  m_panelGeneral->SetSizer(boxSizerLvl2_1);
408 
409  m_staticTextName = new wxStaticText(m_panelGeneral, wxID_ANY, _("Name"), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
410 
411  boxSizerLvl2_1->Add(m_staticTextName, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
412 
413  m_textCtrlName = new wxTextCtrl(m_panelGeneral, wxID_ANY, wxT(""), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
414  #if wxVERSION_NUMBER >= 3000
415  m_textCtrlName->SetHint(wxT(""));
416  #endif
417 
418  boxSizerLvl2_1->Add(m_textCtrlName, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxEXPAND|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
419  m_textCtrlName->SetMinSize(wxSize(300,-1));
420 
421  wxGridSizer* gridSizerLvl3_1 = new wxGridSizer(0, 2, 0, 0);
422 
423  boxSizerLvl2_1->Add(gridSizerLvl3_1, 0, wxEXPAND, WXC_FROM_DIP(5));
424 
425  wxBoxSizer* boxSizerLvl4_5 = new wxBoxSizer(wxVERTICAL);
426 
427  gridSizerLvl3_1->Add(boxSizerLvl4_5, 0, wxEXPAND, WXC_FROM_DIP(5));
428 
429  m_staticTextNominalPower = new wxStaticText(m_panelGeneral, wxID_ANY, _("Rated power"), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
430 
431  boxSizerLvl4_5->Add(m_staticTextNominalPower, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
432 
433  wxBoxSizer* boxSizerLvl5_5 = new wxBoxSizer(wxHORIZONTAL);
434 
435  boxSizerLvl4_5->Add(boxSizerLvl5_5, 0, wxEXPAND, WXC_FROM_DIP(5));
436 
437  m_textCtrlnominalPower = new wxTextCtrl(m_panelGeneral, wxID_ANY, wxT(""), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
438  #if wxVERSION_NUMBER >= 3000
439  m_textCtrlnominalPower->SetHint(wxT(""));
440  #endif
441 
442  boxSizerLvl5_5->Add(m_textCtrlnominalPower, 1, wxLEFT|wxRIGHT|wxBOTTOM|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
443 
444  wxArrayString m_choiceNominalPowerArr;
445  m_choiceNominalPowerArr.Add(wxT("VA"));
446  m_choiceNominalPowerArr.Add(wxT("kVA"));
447  m_choiceNominalPowerArr.Add(wxT("MVA"));
448  m_choiceNominalPower = new wxChoice(m_panelGeneral, wxID_ANY, wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), m_choiceNominalPowerArr, 0);
449  m_choiceNominalPower->SetSelection(2);
450 
451  boxSizerLvl5_5->Add(m_choiceNominalPower, 0, wxLEFT|wxRIGHT|wxBOTTOM, WXC_FROM_DIP(5));
452 
453  gridSizerLvl3_1->Add(0, 0, 1, wxALL|wxEXPAND, WXC_FROM_DIP(5));
454 
455  wxBoxSizer* boxSizerLvl4_1 = new wxBoxSizer(wxVERTICAL);
456 
457  gridSizerLvl3_1->Add(boxSizerLvl4_1, 0, wxEXPAND, WXC_FROM_DIP(5));
458 
459  m_staticTextActivePower = new wxStaticText(m_panelGeneral, wxID_ANY, _("Active power"), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
460 
461  boxSizerLvl4_1->Add(m_staticTextActivePower, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
462 
463  wxBoxSizer* boxSizerLvl5_1 = new wxBoxSizer(wxHORIZONTAL);
464 
465  boxSizerLvl4_1->Add(boxSizerLvl5_1, 0, wxEXPAND, WXC_FROM_DIP(5));
466 
467  m_textCtrlActivePower = new wxTextCtrl(m_panelGeneral, wxID_ANY, wxT(""), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
468  #if wxVERSION_NUMBER >= 3000
469  m_textCtrlActivePower->SetHint(wxT(""));
470  #endif
471 
472  boxSizerLvl5_1->Add(m_textCtrlActivePower, 1, wxLEFT|wxRIGHT|wxBOTTOM|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
473 
474  wxArrayString m_choiceActivePowerArr;
475  m_choiceActivePowerArr.Add(wxT("p.u."));
476  m_choiceActivePowerArr.Add(wxT("W"));
477  m_choiceActivePowerArr.Add(wxT("kW"));
478  m_choiceActivePowerArr.Add(wxT("MW"));
479  m_choiceActivePower = new wxChoice(m_panelGeneral, wxID_ANY, wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), m_choiceActivePowerArr, 0);
480  m_choiceActivePower->SetSelection(3);
481 
482  boxSizerLvl5_1->Add(m_choiceActivePower, 0, wxLEFT|wxRIGHT|wxBOTTOM, WXC_FROM_DIP(5));
483 
484  wxBoxSizer* boxSizerLvl4_2 = new wxBoxSizer(wxVERTICAL);
485 
486  gridSizerLvl3_1->Add(boxSizerLvl4_2, 0, wxEXPAND, WXC_FROM_DIP(5));
487 
488  m_staticTextReactivePower = new wxStaticText(m_panelGeneral, wxID_ANY, _("Reactive power"), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
489 
490  boxSizerLvl4_2->Add(m_staticTextReactivePower, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
491 
492  wxBoxSizer* boxSizerLvl5_2 = new wxBoxSizer(wxHORIZONTAL);
493 
494  boxSizerLvl4_2->Add(boxSizerLvl5_2, 0, wxEXPAND, WXC_FROM_DIP(5));
495 
496  m_textCtrlReactivePower = new wxTextCtrl(m_panelGeneral, wxID_ANY, wxT(""), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
497  #if wxVERSION_NUMBER >= 3000
498  m_textCtrlReactivePower->SetHint(wxT(""));
499  #endif
500 
501  boxSizerLvl5_2->Add(m_textCtrlReactivePower, 1, wxLEFT|wxRIGHT|wxBOTTOM|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
502 
503  wxArrayString m_choiceReactivePowerArr;
504  m_choiceReactivePowerArr.Add(wxT("p.u."));
505  m_choiceReactivePowerArr.Add(wxT("VAr"));
506  m_choiceReactivePowerArr.Add(wxT("kVAr"));
507  m_choiceReactivePowerArr.Add(wxT("MVAr"));
508  m_choiceReactivePower = new wxChoice(m_panelGeneral, wxID_ANY, wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), m_choiceReactivePowerArr, 0);
509  m_choiceReactivePower->SetSelection(3);
510 
511  boxSizerLvl5_2->Add(m_choiceReactivePower, 0, wxLEFT|wxRIGHT|wxBOTTOM, WXC_FROM_DIP(5));
512 
513  wxBoxSizer* boxSizerLvl4_3 = new wxBoxSizer(wxVERTICAL);
514 
515  gridSizerLvl3_1->Add(boxSizerLvl4_3, 0, wxEXPAND, WXC_FROM_DIP(5));
516 
517  m_checkBoxMaxReactive = new wxCheckBox(m_panelGeneral, wxID_ANY, _("Max reactive power"), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
518  m_checkBoxMaxReactive->SetValue(false);
519 
520  boxSizerLvl4_3->Add(m_checkBoxMaxReactive, 0, wxALL, WXC_FROM_DIP(5));
521 
522  wxBoxSizer* boxSizerLvl5_3 = new wxBoxSizer(wxHORIZONTAL);
523 
524  boxSizerLvl4_3->Add(boxSizerLvl5_3, 0, wxEXPAND, WXC_FROM_DIP(5));
525 
526  m_textCtrlMaxRectivePower = new wxTextCtrl(m_panelGeneral, wxID_ANY, wxT(""), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
527  #if wxVERSION_NUMBER >= 3000
528  m_textCtrlMaxRectivePower->SetHint(wxT(""));
529  #endif
530 
531  boxSizerLvl5_3->Add(m_textCtrlMaxRectivePower, 1, wxLEFT|wxRIGHT|wxBOTTOM|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
532 
533  wxArrayString m_choiceMaxRectivePowerArr;
534  m_choiceMaxRectivePowerArr.Add(wxT("p.u."));
535  m_choiceMaxRectivePowerArr.Add(wxT("VAr"));
536  m_choiceMaxRectivePowerArr.Add(wxT("kVAr"));
537  m_choiceMaxRectivePowerArr.Add(wxT("MVAr"));
538  m_choiceMaxRectivePower = new wxChoice(m_panelGeneral, wxID_ANY, wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), m_choiceMaxRectivePowerArr, 0);
539  m_choiceMaxRectivePower->SetSelection(3);
540 
541  boxSizerLvl5_3->Add(m_choiceMaxRectivePower, 0, wxLEFT|wxRIGHT|wxBOTTOM, WXC_FROM_DIP(5));
542 
543  wxBoxSizer* boxSizerLvl4_4 = new wxBoxSizer(wxVERTICAL);
544 
545  gridSizerLvl3_1->Add(boxSizerLvl4_4, 0, wxEXPAND, WXC_FROM_DIP(5));
546 
547  m_checkBoxMinReactive = new wxCheckBox(m_panelGeneral, wxID_ANY, _("Min reactive power"), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
548  m_checkBoxMinReactive->SetValue(false);
549 
550  boxSizerLvl4_4->Add(m_checkBoxMinReactive, 0, wxALL, WXC_FROM_DIP(5));
551 
552  wxBoxSizer* boxSizerLvl5_4 = new wxBoxSizer(wxHORIZONTAL);
553 
554  boxSizerLvl4_4->Add(boxSizerLvl5_4, 0, wxEXPAND, WXC_FROM_DIP(5));
555 
556  m_textCtrlMinRectivePower = new wxTextCtrl(m_panelGeneral, wxID_ANY, wxT(""), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
557  #if wxVERSION_NUMBER >= 3000
558  m_textCtrlMinRectivePower->SetHint(wxT(""));
559  #endif
560 
561  boxSizerLvl5_4->Add(m_textCtrlMinRectivePower, 1, wxLEFT|wxRIGHT|wxBOTTOM|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
562 
563  wxArrayString m_choiceMinRectivePowerArr;
564  m_choiceMinRectivePowerArr.Add(wxT("p.u."));
565  m_choiceMinRectivePowerArr.Add(wxT("VAr"));
566  m_choiceMinRectivePowerArr.Add(wxT("kVAr"));
567  m_choiceMinRectivePowerArr.Add(wxT("MVAr"));
568  m_choiceMinRectivePower = new wxChoice(m_panelGeneral, wxID_ANY, wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), m_choiceMinRectivePowerArr, 0);
569  m_choiceMinRectivePower->SetSelection(3);
570 
571  boxSizerLvl5_4->Add(m_choiceMinRectivePower, 0, wxLEFT|wxRIGHT|wxBOTTOM, WXC_FROM_DIP(5));
572 
573  m_checkBoxUseMachinePower = new wxCheckBox(m_panelGeneral, wxID_ANY, _("Use machine rated power as base"), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
574  m_checkBoxUseMachinePower->SetValue(false);
575 
576  boxSizerLvl2_1->Add(m_checkBoxUseMachinePower, 0, wxALL|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
577 
578  m_panelFault = new wxPanel(m_notebook, wxID_ANY, wxDefaultPosition, wxDLG_UNIT(m_notebook, wxSize(-1,-1)), wxTAB_TRAVERSAL);
579  m_notebook->AddPage(m_panelFault, _("Fault"), false);
580 
581  wxBoxSizer* boxSizerLvl2_2 = new wxBoxSizer(wxVERTICAL);
582  m_panelFault->SetSizer(boxSizerLvl2_2);
583 
584  wxStaticBoxSizer* staticBoxSizerLvl3_1 = new wxStaticBoxSizer( new wxStaticBox(m_panelFault, wxID_ANY, _("Sequence impedances (p.u.)")), wxVERTICAL);
585 
586  boxSizerLvl2_2->Add(staticBoxSizerLvl3_1, 0, wxALL|wxEXPAND, WXC_FROM_DIP(5));
587 
588  wxGridSizer* gridSizerLvl4_2 = new wxGridSizer(0, 2, 0, 0);
589 
590  staticBoxSizerLvl3_1->Add(gridSizerLvl4_2, 0, wxEXPAND, WXC_FROM_DIP(5));
591 
592  wxBoxSizer* boxSizerLvl5_6 = new wxBoxSizer(wxVERTICAL);
593 
594  gridSizerLvl4_2->Add(boxSizerLvl5_6, 0, wxEXPAND, WXC_FROM_DIP(5));
595 
596  m_staticTextPosResistance = new wxStaticText(m_panelFault, wxID_ANY, _("Positive resistance (R1)"), wxDefaultPosition, wxDLG_UNIT(m_panelFault, wxSize(-1,-1)), 0);
597 
598  boxSizerLvl5_6->Add(m_staticTextPosResistance, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
599 
600  m_textCtrlPosResistance = new wxTextCtrl(m_panelFault, wxID_ANY, wxT(""), wxDefaultPosition, wxDLG_UNIT(m_panelFault, wxSize(-1,-1)), 0);
601  #if wxVERSION_NUMBER >= 3000
602  m_textCtrlPosResistance->SetHint(wxT(""));
603  #endif
604 
605  boxSizerLvl5_6->Add(m_textCtrlPosResistance, 1, wxLEFT|wxRIGHT|wxBOTTOM|wxEXPAND|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
606 
607  wxBoxSizer* boxSizerLvl5_7 = new wxBoxSizer(wxVERTICAL);
608 
609  gridSizerLvl4_2->Add(boxSizerLvl5_7, 0, wxEXPAND, WXC_FROM_DIP(5));
610 
611  m_staticTextPosReactance = new wxStaticText(m_panelFault, wxID_ANY, _("Positive reactance (X1)"), wxDefaultPosition, wxDLG_UNIT(m_panelFault, wxSize(-1,-1)), 0);
612 
613  boxSizerLvl5_7->Add(m_staticTextPosReactance, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
614 
615  m_textCtrlPosReactance = new wxTextCtrl(m_panelFault, wxID_ANY, wxT(""), wxDefaultPosition, wxDLG_UNIT(m_panelFault, wxSize(-1,-1)), 0);
616  #if wxVERSION_NUMBER >= 3000
617  m_textCtrlPosReactance->SetHint(wxT(""));
618  #endif
619 
620  boxSizerLvl5_7->Add(m_textCtrlPosReactance, 1, wxLEFT|wxRIGHT|wxBOTTOM|wxEXPAND|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
621 
622  wxBoxSizer* boxSizerLvl5_8 = new wxBoxSizer(wxVERTICAL);
623 
624  gridSizerLvl4_2->Add(boxSizerLvl5_8, 0, wxEXPAND, WXC_FROM_DIP(5));
625 
626  m_staticTextNegResistance = new wxStaticText(m_panelFault, wxID_ANY, _("Negative resistance (R2)"), wxDefaultPosition, wxDLG_UNIT(m_panelFault, wxSize(-1,-1)), 0);
627 
628  boxSizerLvl5_8->Add(m_staticTextNegResistance, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
629 
630  m_textCtrlNegResistance = new wxTextCtrl(m_panelFault, wxID_ANY, wxT(""), wxDefaultPosition, wxDLG_UNIT(m_panelFault, wxSize(-1,-1)), 0);
631  #if wxVERSION_NUMBER >= 3000
632  m_textCtrlNegResistance->SetHint(wxT(""));
633  #endif
634 
635  boxSizerLvl5_8->Add(m_textCtrlNegResistance, 1, wxLEFT|wxRIGHT|wxBOTTOM|wxEXPAND|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
636 
637  wxBoxSizer* boxSizerLvl5_9 = new wxBoxSizer(wxVERTICAL);
638 
639  gridSizerLvl4_2->Add(boxSizerLvl5_9, 0, wxEXPAND, WXC_FROM_DIP(5));
640 
641  m_staticTextNegReactance = new wxStaticText(m_panelFault, wxID_ANY, _("Negative reactance (X2)"), wxDefaultPosition, wxDLG_UNIT(m_panelFault, wxSize(-1,-1)), 0);
642 
643  boxSizerLvl5_9->Add(m_staticTextNegReactance, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
644 
645  m_textCtrlNegReactance = new wxTextCtrl(m_panelFault, wxID_ANY, wxT(""), wxDefaultPosition, wxDLG_UNIT(m_panelFault, wxSize(-1,-1)), 0);
646  #if wxVERSION_NUMBER >= 3000
647  m_textCtrlNegReactance->SetHint(wxT(""));
648  #endif
649 
650  boxSizerLvl5_9->Add(m_textCtrlNegReactance, 1, wxLEFT|wxRIGHT|wxBOTTOM|wxEXPAND|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
651 
652  wxBoxSizer* boxSizerLvl5_10 = new wxBoxSizer(wxVERTICAL);
653 
654  gridSizerLvl4_2->Add(boxSizerLvl5_10, 0, wxEXPAND, WXC_FROM_DIP(5));
655 
656  m_staticTextZeroResistance = new wxStaticText(m_panelFault, wxID_ANY, _("Zero resistance (R0)"), wxDefaultPosition, wxDLG_UNIT(m_panelFault, wxSize(-1,-1)), 0);
657 
658  boxSizerLvl5_10->Add(m_staticTextZeroResistance, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
659 
660  m_textCtrlZeroResistance = new wxTextCtrl(m_panelFault, wxID_ANY, wxT(""), wxDefaultPosition, wxDLG_UNIT(m_panelFault, wxSize(-1,-1)), 0);
661  #if wxVERSION_NUMBER >= 3000
662  m_textCtrlZeroResistance->SetHint(wxT(""));
663  #endif
664 
665  boxSizerLvl5_10->Add(m_textCtrlZeroResistance, 1, wxLEFT|wxRIGHT|wxBOTTOM|wxEXPAND|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
666 
667  wxBoxSizer* boxSizerLvl5_11 = new wxBoxSizer(wxVERTICAL);
668 
669  gridSizerLvl4_2->Add(boxSizerLvl5_11, 0, wxEXPAND, WXC_FROM_DIP(5));
670 
671  m_staticTextZeroReactance = new wxStaticText(m_panelFault, wxID_ANY, _("Zero reactance (X0)"), wxDefaultPosition, wxDLG_UNIT(m_panelFault, wxSize(-1,-1)), 0);
672 
673  boxSizerLvl5_11->Add(m_staticTextZeroReactance, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
674 
675  m_textCtrlZeroReactance = new wxTextCtrl(m_panelFault, wxID_ANY, wxT(""), wxDefaultPosition, wxDLG_UNIT(m_panelFault, wxSize(-1,-1)), 0);
676  #if wxVERSION_NUMBER >= 3000
677  m_textCtrlZeroReactance->SetHint(wxT(""));
678  #endif
679 
680  boxSizerLvl5_11->Add(m_textCtrlZeroReactance, 1, wxLEFT|wxRIGHT|wxBOTTOM|wxEXPAND|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
681 
682  wxGridSizer* gridSizerLvl3_3 = new wxGridSizer(0, 2, 0, 0);
683 
684  boxSizerLvl2_2->Add(gridSizerLvl3_3, 0, wxEXPAND, WXC_FROM_DIP(5));
685 
686  wxBoxSizer* boxSizerLvl4_12 = new wxBoxSizer(wxVERTICAL);
687 
688  gridSizerLvl3_3->Add(boxSizerLvl4_12, 0, wxEXPAND, WXC_FROM_DIP(5));
689 
690  m_staticTextGrdResistance = new wxStaticText(m_panelFault, wxID_ANY, _("Ground resistance (p.u.)"), wxDefaultPosition, wxDLG_UNIT(m_panelFault, wxSize(-1,-1)), 0);
691 
692  boxSizerLvl4_12->Add(m_staticTextGrdResistance, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
693 
694  m_textCtrlGrdResistance = new wxTextCtrl(m_panelFault, wxID_ANY, wxT(""), wxDefaultPosition, wxDLG_UNIT(m_panelFault, wxSize(-1,-1)), 0);
695  #if wxVERSION_NUMBER >= 3000
696  m_textCtrlGrdResistance->SetHint(wxT(""));
697  #endif
698 
699  boxSizerLvl4_12->Add(m_textCtrlGrdResistance, 1, wxLEFT|wxRIGHT|wxBOTTOM|wxEXPAND|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
700 
701  wxBoxSizer* boxSizerLvl4_13 = new wxBoxSizer(wxVERTICAL);
702 
703  gridSizerLvl3_3->Add(boxSizerLvl4_13, 0, wxEXPAND, WXC_FROM_DIP(5));
704 
705  m_staticTextGrdReactance = new wxStaticText(m_panelFault, wxID_ANY, _("Ground reactance (p.u.)"), wxDefaultPosition, wxDLG_UNIT(m_panelFault, wxSize(-1,-1)), 0);
706 
707  boxSizerLvl4_13->Add(m_staticTextGrdReactance, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
708 
709  m_textCtrlGrdReactance = new wxTextCtrl(m_panelFault, wxID_ANY, wxT(""), wxDefaultPosition, wxDLG_UNIT(m_panelFault, wxSize(-1,-1)), 0);
710  #if wxVERSION_NUMBER >= 3000
711  m_textCtrlGrdReactance->SetHint(wxT(""));
712  #endif
713 
714  boxSizerLvl4_13->Add(m_textCtrlGrdReactance, 1, wxLEFT|wxRIGHT|wxBOTTOM|wxEXPAND|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
715 
716  m_checkBoxGroundNeutral = new wxCheckBox(m_panelFault, wxID_ANY, _("Grounded neutral"), wxDefaultPosition, wxDLG_UNIT(m_panelFault, wxSize(-1,-1)), 0);
717  m_checkBoxGroundNeutral->SetValue(true);
718 
719  boxSizerLvl2_2->Add(m_checkBoxGroundNeutral, 0, wxALL, WXC_FROM_DIP(5));
720 
721  wxBoxSizer* boxSizerBottomButtons = new wxBoxSizer(wxHORIZONTAL);
722 
723  boxSizerLvl1_1->Add(boxSizerBottomButtons, 0, wxALL|wxEXPAND, WXC_FROM_DIP(5));
724 
725  m_buttonStab = new wxButton(this, wxID_ANY, _("Stability"), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
726 
727  boxSizerBottomButtons->Add(m_buttonStab, 0, wxALL|wxALIGN_LEFT, WXC_FROM_DIP(5));
728 
729  boxSizerBottomButtons->Add(0, 0, 1, wxALL|wxEXPAND, WXC_FROM_DIP(5));
730 
731  m_buttonOK = new wxButton(this, wxID_ANY, _("OK"), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
732 
733  boxSizerBottomButtons->Add(m_buttonOK, 0, wxALL|wxALIGN_RIGHT, WXC_FROM_DIP(5));
734 
735  m_ButtonCancel = new wxButton(this, wxID_ANY, _("Cancel"), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
736 
737  boxSizerBottomButtons->Add(m_ButtonCancel, 0, wxALL|wxALIGN_RIGHT, WXC_FROM_DIP(5));
738 
739 
740  #if wxVERSION_NUMBER >= 2900
741  if(!wxPersistenceManager::Get().Find(m_notebook)){
742  wxPersistenceManager::Get().RegisterAndRestore(m_notebook);
743  } else {
744  wxPersistenceManager::Get().Restore(m_notebook);
745  }
746  #endif
747 
748  SetName(wxT("SyncMachineFormBase"));
749  SetSize(-1,-1);
750  if (GetSizer()) {
751  GetSizer()->Fit(this);
752  }
753  if(GetParent()) {
754  CentreOnParent(wxBOTH);
755  } else {
756  CentreOnScreen(wxBOTH);
757  }
758 #if wxVERSION_NUMBER >= 2900
759  if(!wxPersistenceManager::Get().Find(this)) {
760  wxPersistenceManager::Get().RegisterAndRestore(this);
761  } else {
762  wxPersistenceManager::Get().Restore(this);
763  }
764 #endif
765  // Connect events
766  m_checkBoxMaxReactive->Connect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler(SyncMachineFormBase::OnCheckMaxReactive), NULL, this);
767  m_checkBoxMinReactive->Connect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler(SyncMachineFormBase::OnCheckMinReactive), NULL, this);
768  m_buttonStab->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(SyncMachineFormBase::OnStabilityButtonClick), NULL, this);
769  m_buttonOK->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(SyncMachineFormBase::OnOKButtonClick), NULL, this);
770  m_ButtonCancel->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(SyncMachineFormBase::OnCancelButtonClick), NULL, this);
771 
772 }
773 
774 SyncMachineFormBase::~SyncMachineFormBase()
775 {
776  m_checkBoxMaxReactive->Disconnect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler(SyncMachineFormBase::OnCheckMaxReactive), NULL, this);
777  m_checkBoxMinReactive->Disconnect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler(SyncMachineFormBase::OnCheckMinReactive), NULL, this);
778  m_buttonStab->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(SyncMachineFormBase::OnStabilityButtonClick), NULL, this);
779  m_buttonOK->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(SyncMachineFormBase::OnOKButtonClick), NULL, this);
780  m_ButtonCancel->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(SyncMachineFormBase::OnCancelButtonClick), NULL, this);
781 
782 }
783 
784 GeneratorStabFormBase::GeneratorStabFormBase(wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style)
785  : wxDialog(parent, id, title, pos, size, style)
786 {
787  if ( !bBitmapLoaded ) {
788  // We need to initialise the default bitmap handler
789  wxXmlResource::Get()->AddHandler(new wxBitmapXmlHandler);
790  wxC9EE9InitBitmapResources();
791  bBitmapLoaded = true;
792  }
793 
794  wxBoxSizer* boxSizerLvl1_1 = new wxBoxSizer(wxVERTICAL);
795  this->SetSizer(boxSizerLvl1_1);
796 
797  wxBoxSizer* boxSizerLvl2_1 = new wxBoxSizer(wxVERTICAL);
798 
799  boxSizerLvl1_1->Add(boxSizerLvl2_1, 1, wxALL|wxEXPAND, WXC_FROM_DIP(5));
800 
801  m_checkBoxPlotSyncMachine = new wxCheckBox(this, wxID_ANY, _("Plot synchronous machine data"), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
802  m_checkBoxPlotSyncMachine->SetValue(false);
803 
804  boxSizerLvl2_1->Add(m_checkBoxPlotSyncMachine, 0, wxALL|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
805 
806  wxGridSizer* gridSizerLvl3_1 = new wxGridSizer(0, 2, 0, 0);
807 
808  boxSizerLvl2_1->Add(gridSizerLvl3_1, 0, wxEXPAND, WXC_FROM_DIP(5));
809 
810  wxBoxSizer* boxSizerLvl4_1 = new wxBoxSizer(wxVERTICAL);
811 
812  gridSizerLvl3_1->Add(boxSizerLvl4_1, 0, wxEXPAND, WXC_FROM_DIP(5));
813 
814  m_staticTextInertia = new wxStaticText(this, wxID_ANY, _("Inertia (H)"), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
815 
816  boxSizerLvl4_1->Add(m_staticTextInertia, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
817 
818  wxBoxSizer* boxSizerLvl5_1 = new wxBoxSizer(wxHORIZONTAL);
819 
820  boxSizerLvl4_1->Add(boxSizerLvl5_1, 0, wxEXPAND, WXC_FROM_DIP(5));
821 
822  m_textCtrlInertia = new wxTextCtrl(this, wxID_ANY, wxT(""), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
823  #if wxVERSION_NUMBER >= 3000
824  m_textCtrlInertia->SetHint(wxT(""));
825  #endif
826 
827  boxSizerLvl5_1->Add(m_textCtrlInertia, 1, wxLEFT|wxRIGHT|wxBOTTOM|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
828 
829  m_staticTextS_1 = new wxStaticText(this, wxID_ANY, _("s"), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
830 
831  boxSizerLvl5_1->Add(m_staticTextS_1, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
832 
833  wxBoxSizer* boxSizerLvl4_2 = new wxBoxSizer(wxVERTICAL);
834 
835  gridSizerLvl3_1->Add(boxSizerLvl4_2, 0, wxEXPAND, WXC_FROM_DIP(5));
836 
837  m_staticTextDamping = new wxStaticText(this, wxID_ANY, _("Damping factor"), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
838 
839  boxSizerLvl4_2->Add(m_staticTextDamping, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
840 
841  wxBoxSizer* boxSizerLvl5_2 = new wxBoxSizer(wxHORIZONTAL);
842 
843  boxSizerLvl4_2->Add(boxSizerLvl5_2, 0, wxEXPAND, WXC_FROM_DIP(5));
844 
845  m_textCtrlDamping = new wxTextCtrl(this, wxID_ANY, wxT(""), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
846  #if wxVERSION_NUMBER >= 3000
847  m_textCtrlDamping->SetHint(wxT(""));
848  #endif
849 
850  boxSizerLvl5_2->Add(m_textCtrlDamping, 1, wxLEFT|wxRIGHT|wxBOTTOM|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
851 
852  m_staticTextPU_1 = new wxStaticText(this, wxID_ANY, _("p.u."), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
853 
854  boxSizerLvl5_2->Add(m_staticTextPU_1, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
855 
856  wxBoxSizer* boxSizerLvl4_3 = new wxBoxSizer(wxVERTICAL);
857 
858  gridSizerLvl3_1->Add(boxSizerLvl4_3, 0, wxEXPAND, WXC_FROM_DIP(5));
859 
860  m_checkBoxUseAVR = new wxCheckBox(this, wxID_ANY, _("Use AVR"), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
861  m_checkBoxUseAVR->SetValue(false);
862 
863  boxSizerLvl4_3->Add(m_checkBoxUseAVR, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
864 
865  m_buttonEditAVR = new wxButton(this, wxID_ANY, _("Edit AVR"), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
866 
867  boxSizerLvl4_3->Add(m_buttonEditAVR, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxEXPAND|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
868 
869  wxBoxSizer* boxSizerLvl4_4 = new wxBoxSizer(wxVERTICAL);
870 
871  gridSizerLvl3_1->Add(boxSizerLvl4_4, 0, wxEXPAND, WXC_FROM_DIP(5));
872 
873  m_checkBoxUseSG = new wxCheckBox(this, wxID_ANY, _("Use speed governor"), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
874  m_checkBoxUseSG->SetValue(false);
875 
876  boxSizerLvl4_4->Add(m_checkBoxUseSG, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
877 
878  m_buttonEditSG = new wxButton(this, wxID_ANY, _("Edit speed governor"), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
879 
880  boxSizerLvl4_4->Add(m_buttonEditSG, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxEXPAND|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
881 
882  m_staticLine_1 = new wxStaticLine(this, wxID_ANY, wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), wxLI_HORIZONTAL);
883 
884  boxSizerLvl2_1->Add(m_staticLine_1, 0, wxALL|wxEXPAND, WXC_FROM_DIP(5));
885 
886  wxGridSizer* gridSizerLvl3_2 = new wxGridSizer(0, 2, 0, 0);
887 
888  boxSizerLvl2_1->Add(gridSizerLvl3_2, 1, wxEXPAND, WXC_FROM_DIP(5));
889 
890  wxBoxSizer* boxSizerLvl4_5 = new wxBoxSizer(wxVERTICAL);
891 
892  gridSizerLvl3_2->Add(boxSizerLvl4_5, 0, wxEXPAND, WXC_FROM_DIP(5));
893 
894  m_staticTextRa = new wxStaticText(this, wxID_ANY, _("Armature resistance (Ra)"), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
895 
896  boxSizerLvl4_5->Add(m_staticTextRa, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
897 
898  wxBoxSizer* boxSizerLvl5_3 = new wxBoxSizer(wxHORIZONTAL);
899 
900  boxSizerLvl4_5->Add(boxSizerLvl5_3, 0, wxEXPAND, WXC_FROM_DIP(5));
901 
902  m_textCtrlRa = new wxTextCtrl(this, wxID_ANY, wxT(""), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
903  #if wxVERSION_NUMBER >= 3000
904  m_textCtrlRa->SetHint(wxT(""));
905  #endif
906 
907  boxSizerLvl5_3->Add(m_textCtrlRa, 1, wxLEFT|wxRIGHT|wxBOTTOM|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
908 
909  m_staticTextPU_2 = new wxStaticText(this, wxID_ANY, _("p.u."), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
910 
911  boxSizerLvl5_3->Add(m_staticTextPU_2, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
912 
913  wxBoxSizer* boxSizerLvl4_6 = new wxBoxSizer(wxVERTICAL);
914 
915  gridSizerLvl3_2->Add(boxSizerLvl4_6, 0, wxEXPAND, WXC_FROM_DIP(5));
916 
917  m_staticTextXp = new wxStaticText(this, wxID_ANY, _("Potier reactance (Xp)"), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
918 
919  boxSizerLvl4_6->Add(m_staticTextXp, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
920 
921  wxBoxSizer* boxSizerLvl5_14 = new wxBoxSizer(wxHORIZONTAL);
922 
923  boxSizerLvl4_6->Add(boxSizerLvl5_14, 0, wxEXPAND, WXC_FROM_DIP(5));
924 
925  m_textCtrlXp = new wxTextCtrl(this, wxID_ANY, wxT(""), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
926  #if wxVERSION_NUMBER >= 3000
927  m_textCtrlXp->SetHint(wxT(""));
928  #endif
929 
930  boxSizerLvl5_14->Add(m_textCtrlXp, 1, wxLEFT|wxRIGHT|wxBOTTOM|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
931 
932  m_staticTextPU_9 = new wxStaticText(this, wxID_ANY, _("p.u."), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
933 
934  boxSizerLvl5_14->Add(m_staticTextPU_9, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
935 
936  wxBoxSizer* boxSizerLvl4_7 = new wxBoxSizer(wxVERTICAL);
937 
938  gridSizerLvl3_2->Add(boxSizerLvl4_7, 0, wxEXPAND, WXC_FROM_DIP(5));
939 
940  m_staticTextSat = new wxStaticText(this, wxID_ANY, _("Saturation factor"), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
941 
942  boxSizerLvl4_7->Add(m_staticTextSat, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
943 
944  wxBoxSizer* boxSizerLvl5_15 = new wxBoxSizer(wxHORIZONTAL);
945 
946  boxSizerLvl4_7->Add(boxSizerLvl5_15, 0, wxEXPAND, WXC_FROM_DIP(5));
947 
948  m_textCtrlSat = new wxTextCtrl(this, wxID_ANY, wxT(""), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
949  #if wxVERSION_NUMBER >= 3000
950  m_textCtrlSat->SetHint(wxT(""));
951  #endif
952 
953  boxSizerLvl5_15->Add(m_textCtrlSat, 1, wxLEFT|wxRIGHT|wxBOTTOM|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
954 
955  m_staticTextPU_10 = new wxStaticText(this, wxID_ANY, _("p.u."), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
956 
957  boxSizerLvl5_15->Add(m_staticTextPU_10, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
958 
959  wxStaticBoxSizer* staticBoxSizerSyncronous = new wxStaticBoxSizer( new wxStaticBox(this, wxID_ANY, _("Syncronous")), wxVERTICAL);
960 
961  boxSizerLvl2_1->Add(staticBoxSizerSyncronous, 0, wxALL|wxEXPAND, WXC_FROM_DIP(5));
962 
963  wxGridSizer* gridSizerLvl4_3 = new wxGridSizer(0, 2, 0, 0);
964 
965  staticBoxSizerSyncronous->Add(gridSizerLvl4_3, 1, wxEXPAND, WXC_FROM_DIP(5));
966 
967  wxBoxSizer* boxSizerLvl5_4 = new wxBoxSizer(wxVERTICAL);
968 
969  gridSizerLvl4_3->Add(boxSizerLvl5_4, 0, wxEXPAND, WXC_FROM_DIP(5));
970 
971  m_staticTextSyncXd = new wxStaticText(this, wxID_ANY, _("Direct-axis reactance (Xd)"), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
972 
973  boxSizerLvl5_4->Add(m_staticTextSyncXd, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
974 
975  wxBoxSizer* boxSizerLvl6_1 = new wxBoxSizer(wxHORIZONTAL);
976 
977  boxSizerLvl5_4->Add(boxSizerLvl6_1, 0, wxEXPAND, WXC_FROM_DIP(5));
978 
979  m_textCtrlSyncXd = new wxTextCtrl(this, wxID_ANY, wxT(""), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
980  #if wxVERSION_NUMBER >= 3000
981  m_textCtrlSyncXd->SetHint(wxT(""));
982  #endif
983 
984  boxSizerLvl6_1->Add(m_textCtrlSyncXd, 1, wxLEFT|wxRIGHT|wxBOTTOM|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
985 
986  m_staticTextPU_3 = new wxStaticText(this, wxID_ANY, _("p.u."), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
987 
988  boxSizerLvl6_1->Add(m_staticTextPU_3, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
989 
990  wxBoxSizer* boxSizerLvl5_5 = new wxBoxSizer(wxVERTICAL);
991 
992  gridSizerLvl4_3->Add(boxSizerLvl5_5, 0, wxEXPAND, WXC_FROM_DIP(5));
993 
994  m_staticTextSyncXq = new wxStaticText(this, wxID_ANY, _("Quadrature-axis reactance (Xq)"), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
995 
996  boxSizerLvl5_5->Add(m_staticTextSyncXq, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
997 
998  wxBoxSizer* boxSizerLvl6_2 = new wxBoxSizer(wxHORIZONTAL);
999 
1000  boxSizerLvl5_5->Add(boxSizerLvl6_2, 0, wxEXPAND, WXC_FROM_DIP(5));
1001 
1002  m_textCtrlSyncXq = new wxTextCtrl(this, wxID_ANY, wxT(""), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
1003  #if wxVERSION_NUMBER >= 3000
1004  m_textCtrlSyncXq->SetHint(wxT(""));
1005  #endif
1006 
1007  boxSizerLvl6_2->Add(m_textCtrlSyncXq, 1, wxLEFT|wxRIGHT|wxBOTTOM|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
1008 
1009  m_staticTextPU_4 = new wxStaticText(this, wxID_ANY, _("p.u."), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
1010 
1011  boxSizerLvl6_2->Add(m_staticTextPU_4, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
1012 
1013  wxStaticBoxSizer* staticBoxSizerTransient = new wxStaticBoxSizer( new wxStaticBox(this, wxID_ANY, _("Transient")), wxVERTICAL);
1014 
1015  boxSizerLvl2_1->Add(staticBoxSizerTransient, 0, wxALL|wxEXPAND, WXC_FROM_DIP(5));
1016 
1017  wxGridSizer* gridSizerLvl4_4 = new wxGridSizer(0, 2, 0, 0);
1018 
1019  staticBoxSizerTransient->Add(gridSizerLvl4_4, 1, wxEXPAND, WXC_FROM_DIP(5));
1020 
1021  wxBoxSizer* boxSizerLvl5_6 = new wxBoxSizer(wxVERTICAL);
1022 
1023  gridSizerLvl4_4->Add(boxSizerLvl5_6, 0, wxEXPAND, WXC_FROM_DIP(5));
1024 
1025  m_staticTextTranXd = new wxStaticText(this, wxID_ANY, _("Direct-axis reactance (X'd)"), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
1026 
1027  boxSizerLvl5_6->Add(m_staticTextTranXd, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
1028 
1029  wxBoxSizer* boxSizerLvl6_3 = new wxBoxSizer(wxHORIZONTAL);
1030 
1031  boxSizerLvl5_6->Add(boxSizerLvl6_3, 0, wxEXPAND, WXC_FROM_DIP(5));
1032 
1033  m_textCtrlTranXd = new wxTextCtrl(this, wxID_ANY, wxT(""), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
1034  #if wxVERSION_NUMBER >= 3000
1035  m_textCtrlTranXd->SetHint(wxT(""));
1036  #endif
1037 
1038  boxSizerLvl6_3->Add(m_textCtrlTranXd, 1, wxLEFT|wxRIGHT|wxBOTTOM|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
1039 
1040  m_staticTextPU_5 = new wxStaticText(this, wxID_ANY, _("p.u."), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
1041 
1042  boxSizerLvl6_3->Add(m_staticTextPU_5, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
1043 
1044  wxBoxSizer* boxSizerLvl5_7 = new wxBoxSizer(wxVERTICAL);
1045 
1046  gridSizerLvl4_4->Add(boxSizerLvl5_7, 0, wxEXPAND, WXC_FROM_DIP(5));
1047 
1048  m_staticTextTranXq = new wxStaticText(this, wxID_ANY, _("Quadrature-axis reactance (X'q)"), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
1049 
1050  boxSizerLvl5_7->Add(m_staticTextTranXq, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
1051 
1052  wxBoxSizer* boxSizerLvl6_4 = new wxBoxSizer(wxHORIZONTAL);
1053 
1054  boxSizerLvl5_7->Add(boxSizerLvl6_4, 0, wxEXPAND, WXC_FROM_DIP(5));
1055 
1056  m_textCtrlTranXq = new wxTextCtrl(this, wxID_ANY, wxT(""), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
1057  #if wxVERSION_NUMBER >= 3000
1058  m_textCtrlTranXq->SetHint(wxT(""));
1059  #endif
1060 
1061  boxSizerLvl6_4->Add(m_textCtrlTranXq, 1, wxLEFT|wxRIGHT|wxBOTTOM|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
1062 
1063  m_staticTextPU_6 = new wxStaticText(this, wxID_ANY, _("p.u."), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
1064 
1065  boxSizerLvl6_4->Add(m_staticTextPU_6, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
1066 
1067  wxBoxSizer* boxSizerLvl5_8 = new wxBoxSizer(wxVERTICAL);
1068 
1069  gridSizerLvl4_4->Add(boxSizerLvl5_8, 0, wxEXPAND, WXC_FROM_DIP(5));
1070 
1071  m_staticTextTranTd0 = new wxStaticText(this, wxID_ANY, _("Direct-axis time constant (T'd0)"), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
1072 
1073  boxSizerLvl5_8->Add(m_staticTextTranTd0, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
1074 
1075  wxBoxSizer* boxSizerLvl6_5 = new wxBoxSizer(wxHORIZONTAL);
1076 
1077  boxSizerLvl5_8->Add(boxSizerLvl6_5, 0, wxEXPAND, WXC_FROM_DIP(5));
1078 
1079  m_textCtrlTranTd0 = new wxTextCtrl(this, wxID_ANY, wxT(""), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
1080  #if wxVERSION_NUMBER >= 3000
1081  m_textCtrlTranTd0->SetHint(wxT(""));
1082  #endif
1083 
1084  boxSizerLvl6_5->Add(m_textCtrlTranTd0, 1, wxLEFT|wxRIGHT|wxBOTTOM|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
1085 
1086  m_staticTextS_2 = new wxStaticText(this, wxID_ANY, _("s"), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
1087 
1088  boxSizerLvl6_5->Add(m_staticTextS_2, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
1089 
1090  wxBoxSizer* boxSizerLvl5_9 = new wxBoxSizer(wxVERTICAL);
1091 
1092  gridSizerLvl4_4->Add(boxSizerLvl5_9, 0, wxEXPAND, WXC_FROM_DIP(5));
1093 
1094  m_staticTextTranTq0 = new wxStaticText(this, wxID_ANY, _("Quadrature-axis time constant (T'q0)"), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
1095 
1096  boxSizerLvl5_9->Add(m_staticTextTranTq0, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
1097 
1098  wxBoxSizer* boxSizerLvl6_6 = new wxBoxSizer(wxHORIZONTAL);
1099 
1100  boxSizerLvl5_9->Add(boxSizerLvl6_6, 0, wxEXPAND, WXC_FROM_DIP(5));
1101 
1102  m_textCtrlTranTq0 = new wxTextCtrl(this, wxID_ANY, wxT(""), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
1103  #if wxVERSION_NUMBER >= 3000
1104  m_textCtrlTranTq0->SetHint(wxT(""));
1105  #endif
1106 
1107  boxSizerLvl6_6->Add(m_textCtrlTranTq0, 1, wxLEFT|wxRIGHT|wxBOTTOM|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
1108 
1109  m_staticTextS_3 = new wxStaticText(this, wxID_ANY, _("s"), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
1110 
1111  boxSizerLvl6_6->Add(m_staticTextS_3, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
1112 
1113  wxStaticBoxSizer* staticBoxSizerSubtransient = new wxStaticBoxSizer( new wxStaticBox(this, wxID_ANY, _("Sub-transient")), wxVERTICAL);
1114 
1115  boxSizerLvl2_1->Add(staticBoxSizerSubtransient, 0, wxALL|wxEXPAND, WXC_FROM_DIP(5));
1116 
1117  wxGridSizer* gridSizerLvl4_5 = new wxGridSizer(0, 2, 0, 0);
1118 
1119  staticBoxSizerSubtransient->Add(gridSizerLvl4_5, 1, wxEXPAND, WXC_FROM_DIP(5));
1120 
1121  wxBoxSizer* boxSizerLvl5_10 = new wxBoxSizer(wxVERTICAL);
1122 
1123  gridSizerLvl4_5->Add(boxSizerLvl5_10, 0, wxEXPAND, WXC_FROM_DIP(5));
1124 
1125  m_staticTextSubXd = new wxStaticText(this, wxID_ANY, _("Direct-axis reactance (X''d)"), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
1126 
1127  boxSizerLvl5_10->Add(m_staticTextSubXd, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
1128 
1129  wxBoxSizer* boxSizerLvl6_7 = new wxBoxSizer(wxHORIZONTAL);
1130 
1131  boxSizerLvl5_10->Add(boxSizerLvl6_7, 0, wxEXPAND, WXC_FROM_DIP(5));
1132 
1133  m_textCtrlSubXd = new wxTextCtrl(this, wxID_ANY, wxT(""), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
1134  #if wxVERSION_NUMBER >= 3000
1135  m_textCtrlSubXd->SetHint(wxT(""));
1136  #endif
1137 
1138  boxSizerLvl6_7->Add(m_textCtrlSubXd, 1, wxLEFT|wxRIGHT|wxBOTTOM|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
1139 
1140  m_staticTextPU_7 = new wxStaticText(this, wxID_ANY, _("p.u."), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
1141 
1142  boxSizerLvl6_7->Add(m_staticTextPU_7, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
1143 
1144  wxBoxSizer* boxSizerLvl5_11 = new wxBoxSizer(wxVERTICAL);
1145 
1146  gridSizerLvl4_5->Add(boxSizerLvl5_11, 0, wxEXPAND, WXC_FROM_DIP(5));
1147 
1148  m_staticTextSubXq = new wxStaticText(this, wxID_ANY, _("Quadrature-axis reactance (X''q)"), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
1149 
1150  boxSizerLvl5_11->Add(m_staticTextSubXq, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
1151 
1152  wxBoxSizer* boxSizerLvl6_8 = new wxBoxSizer(wxHORIZONTAL);
1153 
1154  boxSizerLvl5_11->Add(boxSizerLvl6_8, 0, wxEXPAND, WXC_FROM_DIP(5));
1155 
1156  m_textCtrlSubXq = new wxTextCtrl(this, wxID_ANY, wxT(""), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
1157  #if wxVERSION_NUMBER >= 3000
1158  m_textCtrlSubXq->SetHint(wxT(""));
1159  #endif
1160 
1161  boxSizerLvl6_8->Add(m_textCtrlSubXq, 1, wxLEFT|wxRIGHT|wxBOTTOM|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
1162 
1163  m_staticTextPU_8 = new wxStaticText(this, wxID_ANY, _("p.u."), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
1164 
1165  boxSizerLvl6_8->Add(m_staticTextPU_8, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
1166 
1167  wxBoxSizer* boxSizerLvl5_12 = new wxBoxSizer(wxVERTICAL);
1168 
1169  gridSizerLvl4_5->Add(boxSizerLvl5_12, 0, wxEXPAND, WXC_FROM_DIP(5));
1170 
1171  m_staticTextSubTd0 = new wxStaticText(this, wxID_ANY, _("Direct-axis time constant (T''d0)"), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
1172 
1173  boxSizerLvl5_12->Add(m_staticTextSubTd0, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
1174 
1175  wxBoxSizer* boxSizerLvl6_9 = new wxBoxSizer(wxHORIZONTAL);
1176 
1177  boxSizerLvl5_12->Add(boxSizerLvl6_9, 0, wxEXPAND, WXC_FROM_DIP(5));
1178 
1179  m_textCtrlSubTd0 = new wxTextCtrl(this, wxID_ANY, wxT(""), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
1180  #if wxVERSION_NUMBER >= 3000
1181  m_textCtrlSubTd0->SetHint(wxT(""));
1182  #endif
1183 
1184  boxSizerLvl6_9->Add(m_textCtrlSubTd0, 1, wxLEFT|wxRIGHT|wxBOTTOM|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
1185 
1186  m_staticTextS_4 = new wxStaticText(this, wxID_ANY, _("s"), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
1187 
1188  boxSizerLvl6_9->Add(m_staticTextS_4, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
1189 
1190  wxBoxSizer* boxSizerLvl5_13 = new wxBoxSizer(wxVERTICAL);
1191 
1192  gridSizerLvl4_5->Add(boxSizerLvl5_13, 0, wxEXPAND, WXC_FROM_DIP(5));
1193 
1194  m_staticTextSubTq0 = new wxStaticText(this, wxID_ANY, _("Quadrature-axis time constant (T''q0)"), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
1195 
1196  boxSizerLvl5_13->Add(m_staticTextSubTq0, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
1197 
1198  wxBoxSizer* boxSizerLvl6_10 = new wxBoxSizer(wxHORIZONTAL);
1199 
1200  boxSizerLvl5_13->Add(boxSizerLvl6_10, 0, wxEXPAND, WXC_FROM_DIP(5));
1201 
1202  m_textCtrlSubTq0 = new wxTextCtrl(this, wxID_ANY, wxT(""), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
1203  #if wxVERSION_NUMBER >= 3000
1204  m_textCtrlSubTq0->SetHint(wxT(""));
1205  #endif
1206 
1207  boxSizerLvl6_10->Add(m_textCtrlSubTq0, 1, wxLEFT|wxRIGHT|wxBOTTOM|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
1208 
1209  m_staticTextS_5 = new wxStaticText(this, wxID_ANY, _("s"), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
1210 
1211  boxSizerLvl6_10->Add(m_staticTextS_5, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
1212 
1213  wxBoxSizer* boxSizerVDivider = new wxBoxSizer(wxVERTICAL);
1214 
1215  boxSizerLvl2_1->Add(boxSizerVDivider, 1, wxALL|wxEXPAND, WXC_FROM_DIP(5));
1216 
1217  wxBoxSizer* boxSizerSection_2 = new wxBoxSizer(wxVERTICAL);
1218 
1219  boxSizerVDivider->Add(boxSizerSection_2, 1, wxALL|wxEXPAND, WXC_FROM_DIP(5));
1220 
1221  wxBoxSizer* boxSizerSection_1 = new wxBoxSizer(wxVERTICAL);
1222 
1223  boxSizerVDivider->Add(boxSizerSection_1, 1, wxALL|wxEXPAND, WXC_FROM_DIP(5));
1224 
1225  wxBoxSizer* boxSizerBottomButtons = new wxBoxSizer(wxHORIZONTAL);
1226 
1227  boxSizerLvl1_1->Add(boxSizerBottomButtons, 0, wxALL|wxEXPAND, WXC_FROM_DIP(5));
1228 
1229  m_buttonSwitching = new wxButton(this, wxID_ANY, _("Switching"), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
1230 
1231  boxSizerBottomButtons->Add(m_buttonSwitching, 0, wxALL|wxALIGN_LEFT, WXC_FROM_DIP(5));
1232 
1233  boxSizerBottomButtons->Add(0, 0, 1, wxALL|wxEXPAND, WXC_FROM_DIP(5));
1234 
1235  m_buttonOK = new wxButton(this, wxID_ANY, _("OK"), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
1236 
1237  boxSizerBottomButtons->Add(m_buttonOK, 0, wxALL|wxALIGN_RIGHT, WXC_FROM_DIP(5));
1238 
1239  m_ButtonCancel = new wxButton(this, wxID_ANY, _("Cancel"), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
1240 
1241  boxSizerBottomButtons->Add(m_ButtonCancel, 0, wxALL|wxALIGN_RIGHT, WXC_FROM_DIP(5));
1242 
1243  SetName(wxT("GeneratorStabFormBase"));
1244  SetSize(-1,-1);
1245  if (GetSizer()) {
1246  GetSizer()->Fit(this);
1247  }
1248  if(GetParent()) {
1249  CentreOnParent(wxBOTH);
1250  } else {
1251  CentreOnScreen(wxBOTH);
1252  }
1253 #if wxVERSION_NUMBER >= 2900
1254  if(!wxPersistenceManager::Get().Find(this)) {
1255  wxPersistenceManager::Get().RegisterAndRestore(this);
1256  } else {
1257  wxPersistenceManager::Get().Restore(this);
1258  }
1259 #endif
1260  // Connect events
1261  m_checkBoxUseAVR->Connect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler(GeneratorStabFormBase::UseAVRClick), NULL, this);
1262  m_buttonEditAVR->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(GeneratorStabFormBase::OnEditAVRButtonClick), NULL, this);
1263  m_checkBoxUseSG->Connect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler(GeneratorStabFormBase::UseSGClick), NULL, this);
1264  m_buttonEditSG->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(GeneratorStabFormBase::OnSpeedGovernorButtonClick), NULL, this);
1265  m_buttonSwitching->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(GeneratorStabFormBase::OnSwitchingButtonClick), NULL, this);
1266  m_buttonOK->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(GeneratorStabFormBase::OnOKButtonClick), NULL, this);
1267  m_ButtonCancel->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(GeneratorStabFormBase::OnCancelButtonClick), NULL, this);
1268 
1269 }
1270 
1271 GeneratorStabFormBase::~GeneratorStabFormBase()
1272 {
1273  m_checkBoxUseAVR->Disconnect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler(GeneratorStabFormBase::UseAVRClick), NULL, this);
1274  m_buttonEditAVR->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(GeneratorStabFormBase::OnEditAVRButtonClick), NULL, this);
1275  m_checkBoxUseSG->Disconnect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler(GeneratorStabFormBase::UseSGClick), NULL, this);
1276  m_buttonEditSG->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(GeneratorStabFormBase::OnSpeedGovernorButtonClick), NULL, this);
1277  m_buttonSwitching->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(GeneratorStabFormBase::OnSwitchingButtonClick), NULL, this);
1278  m_buttonOK->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(GeneratorStabFormBase::OnOKButtonClick), NULL, this);
1279  m_ButtonCancel->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(GeneratorStabFormBase::OnCancelButtonClick), NULL, this);
1280 
1281 }
1282 
1283 LineFormBase::LineFormBase(wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style)
1284  : wxDialog(parent, id, title, pos, size, style)
1285 {
1286  if ( !bBitmapLoaded ) {
1287  // We need to initialise the default bitmap handler
1288  wxXmlResource::Get()->AddHandler(new wxBitmapXmlHandler);
1289  wxC9EE9InitBitmapResources();
1290  bBitmapLoaded = true;
1291  }
1292 
1293  wxBoxSizer* boxSizerLvl1_1 = new wxBoxSizer(wxVERTICAL);
1294  this->SetSizer(boxSizerLvl1_1);
1295 
1296  m_notebook = new wxNotebook(this, wxID_ANY, wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), wxBK_DEFAULT);
1297  m_notebook->SetName(wxT("m_notebook"));
1298 
1299  boxSizerLvl1_1->Add(m_notebook, 1, wxEXPAND, WXC_FROM_DIP(5));
1300 
1301  m_panelGeneral = new wxPanel(m_notebook, wxID_ANY, wxDefaultPosition, wxDLG_UNIT(m_notebook, wxSize(-1,-1)), wxTAB_TRAVERSAL);
1302  m_notebook->AddPage(m_panelGeneral, _("General"), false);
1303 
1304  wxBoxSizer* boxSizerLvl2_1 = new wxBoxSizer(wxVERTICAL);
1305  m_panelGeneral->SetSizer(boxSizerLvl2_1);
1306 
1307  m_staticTextName = new wxStaticText(m_panelGeneral, wxID_ANY, _("Name"), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
1308 
1309  boxSizerLvl2_1->Add(m_staticTextName, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
1310 
1311  m_textCtrlName = new wxTextCtrl(m_panelGeneral, wxID_ANY, wxT(""), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
1312  #if wxVERSION_NUMBER >= 3000
1313  m_textCtrlName->SetHint(wxT(""));
1314  #endif
1315 
1316  boxSizerLvl2_1->Add(m_textCtrlName, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxEXPAND|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
1317  m_textCtrlName->SetMinSize(wxSize(300,-1));
1318 
1319  wxGridSizer* gridSizerLvl3_1 = new wxGridSizer(0, 2, 0, 0);
1320 
1321  boxSizerLvl2_1->Add(gridSizerLvl3_1, 0, wxEXPAND, WXC_FROM_DIP(5));
1322 
1323  wxBoxSizer* boxSizerLvl4_9 = new wxBoxSizer(wxVERTICAL);
1324 
1325  gridSizerLvl3_1->Add(boxSizerLvl4_9, 0, wxEXPAND, WXC_FROM_DIP(5));
1326 
1327  m_staticTextNominalVoltage = new wxStaticText(m_panelGeneral, wxID_ANY, _("Rated voltage"), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
1328 
1329  boxSizerLvl4_9->Add(m_staticTextNominalVoltage, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
1330 
1331  m_staticTextNominalVoltageValue = new wxStaticText(m_panelGeneral, wxID_ANY, _("138 kV"), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
1332  wxFont m_staticTextNominalVoltageValueFont = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT);
1333  m_staticTextNominalVoltageValueFont.SetWeight(wxFONTWEIGHT_BOLD);
1334  m_staticTextNominalVoltageValue->SetFont(m_staticTextNominalVoltageValueFont);
1335 
1336  boxSizerLvl4_9->Add(m_staticTextNominalVoltageValue, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
1337 
1338  wxBoxSizer* boxSizerLvl4_8 = new wxBoxSizer(wxVERTICAL);
1339 
1340  gridSizerLvl3_1->Add(boxSizerLvl4_8, 0, wxEXPAND, WXC_FROM_DIP(5));
1341 
1342  m_staticTextNominalPower = new wxStaticText(m_panelGeneral, wxID_ANY, _("Rated power"), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
1343 
1344  boxSizerLvl4_8->Add(m_staticTextNominalPower, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
1345 
1346  wxBoxSizer* boxSizerLvl5_5 = new wxBoxSizer(wxHORIZONTAL);
1347 
1348  boxSizerLvl4_8->Add(boxSizerLvl5_5, 0, wxEXPAND, WXC_FROM_DIP(5));
1349 
1350  m_textCtrlNominalPower = new wxTextCtrl(m_panelGeneral, wxID_ANY, wxT(""), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
1351  #if wxVERSION_NUMBER >= 3000
1352  m_textCtrlNominalPower->SetHint(wxT(""));
1353  #endif
1354 
1355  boxSizerLvl5_5->Add(m_textCtrlNominalPower, 1, wxLEFT|wxRIGHT|wxBOTTOM|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
1356 
1357  wxArrayString m_choiceNominalPowerArr;
1358  m_choiceNominalPowerArr.Add(wxT("VA"));
1359  m_choiceNominalPowerArr.Add(wxT("kVA"));
1360  m_choiceNominalPowerArr.Add(wxT("MVA"));
1361  m_choiceNominalPower = new wxChoice(m_panelGeneral, wxID_ANY, wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), m_choiceNominalPowerArr, 0);
1362  m_choiceNominalPower->SetSelection(2);
1363 
1364  boxSizerLvl5_5->Add(m_choiceNominalPower, 0, wxLEFT|wxRIGHT|wxBOTTOM, WXC_FROM_DIP(5));
1365 
1366  wxBoxSizer* boxSizerLvl4_1 = new wxBoxSizer(wxVERTICAL);
1367 
1368  gridSizerLvl3_1->Add(boxSizerLvl4_1, 0, wxEXPAND, WXC_FROM_DIP(5));
1369 
1370  m_staticTextResistance = new wxStaticText(m_panelGeneral, wxID_ANY, _("Resistance (R)"), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
1371 
1372  boxSizerLvl4_1->Add(m_staticTextResistance, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
1373 
1374  wxBoxSizer* boxSizerLvl5_1 = new wxBoxSizer(wxHORIZONTAL);
1375 
1376  boxSizerLvl4_1->Add(boxSizerLvl5_1, 0, wxEXPAND, WXC_FROM_DIP(5));
1377 
1378  m_textCtrlResistance = new wxTextCtrl(m_panelGeneral, wxID_ANY, wxT(""), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
1379  #if wxVERSION_NUMBER >= 3000
1380  m_textCtrlResistance->SetHint(wxT(""));
1381  #endif
1382 
1383  boxSizerLvl5_1->Add(m_textCtrlResistance, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxEXPAND|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
1384 
1385  wxArrayString m_choiceResistanceArr;
1386  m_choiceResistanceArr.Add(wxT("p.u."));
1387  m_choiceResistanceArr.Add(wxT("Ohm"));
1388  m_choiceResistanceArr.Add(wxT("Ohm/km"));
1389  m_choiceResistance = new wxChoice(m_panelGeneral, wxID_ANY, wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), m_choiceResistanceArr, 0);
1390  m_choiceResistance->SetSelection(0);
1391 
1392  boxSizerLvl5_1->Add(m_choiceResistance, 0, wxLEFT|wxRIGHT|wxBOTTOM, WXC_FROM_DIP(5));
1393 
1394  wxBoxSizer* boxSizerLvl4_2 = new wxBoxSizer(wxVERTICAL);
1395 
1396  gridSizerLvl3_1->Add(boxSizerLvl4_2, 0, wxEXPAND, WXC_FROM_DIP(5));
1397 
1398  m_staticTextReactance = new wxStaticText(m_panelGeneral, wxID_ANY, _("Indutive reactance (XL)"), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
1399 
1400  boxSizerLvl4_2->Add(m_staticTextReactance, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
1401 
1402  wxBoxSizer* boxSizerLvl5_2 = new wxBoxSizer(wxHORIZONTAL);
1403 
1404  boxSizerLvl4_2->Add(boxSizerLvl5_2, 0, wxEXPAND, WXC_FROM_DIP(5));
1405 
1406  m_textCtrlReactance = new wxTextCtrl(m_panelGeneral, wxID_ANY, wxT(""), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
1407  #if wxVERSION_NUMBER >= 3000
1408  m_textCtrlReactance->SetHint(wxT(""));
1409  #endif
1410 
1411  boxSizerLvl5_2->Add(m_textCtrlReactance, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxEXPAND|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
1412 
1413  wxArrayString m_choiceReactanceArr;
1414  m_choiceReactanceArr.Add(wxT("p.u."));
1415  m_choiceReactanceArr.Add(wxT("Ohm"));
1416  m_choiceReactanceArr.Add(wxT("Ohm/km"));
1417  m_choiceReactance = new wxChoice(m_panelGeneral, wxID_ANY, wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), m_choiceReactanceArr, 0);
1418  m_choiceReactance->SetSelection(0);
1419 
1420  boxSizerLvl5_2->Add(m_choiceReactance, 0, wxLEFT|wxRIGHT|wxBOTTOM, WXC_FROM_DIP(5));
1421 
1422  wxBoxSizer* boxSizerLvl4_3 = new wxBoxSizer(wxVERTICAL);
1423 
1424  gridSizerLvl3_1->Add(boxSizerLvl4_3, 0, wxEXPAND, WXC_FROM_DIP(5));
1425 
1426  m_staticTextSusceptance = new wxStaticText(m_panelGeneral, wxID_ANY, _("Capacitive susceptance (B)"), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
1427 
1428  boxSizerLvl4_3->Add(m_staticTextSusceptance, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
1429 
1430  wxBoxSizer* boxSizerLvl5_3 = new wxBoxSizer(wxHORIZONTAL);
1431 
1432  boxSizerLvl4_3->Add(boxSizerLvl5_3, 0, wxEXPAND, WXC_FROM_DIP(5));
1433 
1434  m_textCtrlSusceptance = new wxTextCtrl(m_panelGeneral, wxID_ANY, wxT(""), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
1435  #if wxVERSION_NUMBER >= 3000
1436  m_textCtrlSusceptance->SetHint(wxT(""));
1437  #endif
1438 
1439  boxSizerLvl5_3->Add(m_textCtrlSusceptance, 1, wxLEFT|wxRIGHT|wxBOTTOM|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
1440 
1441  wxArrayString m_choiceSusceptanceArr;
1442  m_choiceSusceptanceArr.Add(wxT("p.u."));
1443  m_choiceSusceptanceArr.Add(wxT("S"));
1444  m_choiceSusceptanceArr.Add(wxT("S/km"));
1445  m_choiceSusceptance = new wxChoice(m_panelGeneral, wxID_ANY, wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), m_choiceSusceptanceArr, 0);
1446  m_choiceSusceptance->SetSelection(0);
1447 
1448  boxSizerLvl5_3->Add(m_choiceSusceptance, 0, wxLEFT|wxRIGHT|wxBOTTOM, WXC_FROM_DIP(5));
1449 
1450  wxBoxSizer* boxSizerLvl4_4 = new wxBoxSizer(wxVERTICAL);
1451 
1452  gridSizerLvl3_1->Add(boxSizerLvl4_4, 0, wxEXPAND, WXC_FROM_DIP(5));
1453 
1454  m_staticTextLineSize = new wxStaticText(m_panelGeneral, wxID_ANY, _("Line size"), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
1455 
1456  boxSizerLvl4_4->Add(m_staticTextLineSize, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
1457 
1458  wxBoxSizer* boxSizerLvl5_4 = new wxBoxSizer(wxHORIZONTAL);
1459 
1460  boxSizerLvl4_4->Add(boxSizerLvl5_4, 0, wxEXPAND, WXC_FROM_DIP(5));
1461 
1462  m_textCtrlLineSize = new wxTextCtrl(m_panelGeneral, wxID_ANY, wxT(""), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
1463  #if wxVERSION_NUMBER >= 3000
1464  m_textCtrlLineSize->SetHint(wxT(""));
1465  #endif
1466 
1467  boxSizerLvl5_4->Add(m_textCtrlLineSize, 1, wxLEFT|wxRIGHT|wxBOTTOM|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
1468 
1469  m_staticTextKM = new wxStaticText(m_panelGeneral, wxID_ANY, _("km"), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
1470 
1471  boxSizerLvl5_4->Add(m_staticTextKM, 0, wxALL, WXC_FROM_DIP(5));
1472 
1473  m_checkUseLinePower = new wxCheckBox(m_panelGeneral, wxID_ANY, _("Use line rated power as base"), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
1474  m_checkUseLinePower->SetValue(false);
1475 
1476  boxSizerLvl2_1->Add(m_checkUseLinePower, 0, wxALL, WXC_FROM_DIP(5));
1477 
1478  m_panelFault = new wxPanel(m_notebook, wxID_ANY, wxDefaultPosition, wxDLG_UNIT(m_notebook, wxSize(-1,-1)), wxTAB_TRAVERSAL);
1479  m_notebook->AddPage(m_panelFault, _("Fault"), false);
1480 
1481  wxBoxSizer* boxSizerLvl2_2 = new wxBoxSizer(wxVERTICAL);
1482  m_panelFault->SetSizer(boxSizerLvl2_2);
1483 
1484  wxStaticBoxSizer* staticBoxSizerZeroImpSeq = new wxStaticBoxSizer( new wxStaticBox(m_panelFault, wxID_ANY, _("Zero-sequence impedances (p.u.)")), wxVERTICAL);
1485 
1486  boxSizerLvl2_2->Add(staticBoxSizerZeroImpSeq, 0, wxALL|wxEXPAND, WXC_FROM_DIP(5));
1487 
1488  wxGridSizer* gridSizerLvl3_2 = new wxGridSizer(0, 2, 0, 0);
1489 
1490  staticBoxSizerZeroImpSeq->Add(gridSizerLvl3_2, 0, wxEXPAND, WXC_FROM_DIP(5));
1491 
1492  wxBoxSizer* boxSizerLvl4_5 = new wxBoxSizer(wxVERTICAL);
1493 
1494  gridSizerLvl3_2->Add(boxSizerLvl4_5, 0, wxEXPAND, WXC_FROM_DIP(5));
1495 
1496  m_staticTextZeroResistance = new wxStaticText(m_panelFault, wxID_ANY, _("Resistance (R0)"), wxDefaultPosition, wxDLG_UNIT(m_panelFault, wxSize(-1,-1)), 0);
1497 
1498  boxSizerLvl4_5->Add(m_staticTextZeroResistance, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
1499 
1500  m_textCtrlZeroResistance = new wxTextCtrl(m_panelFault, wxID_ANY, wxT(""), wxDefaultPosition, wxDLG_UNIT(m_panelFault, wxSize(-1,-1)), 0);
1501  #if wxVERSION_NUMBER >= 3000
1502  m_textCtrlZeroResistance->SetHint(wxT(""));
1503  #endif
1504 
1505  boxSizerLvl4_5->Add(m_textCtrlZeroResistance, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxEXPAND|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
1506 
1507  wxBoxSizer* boxSizerLvl4_6 = new wxBoxSizer(wxVERTICAL);
1508 
1509  gridSizerLvl3_2->Add(boxSizerLvl4_6, 0, wxEXPAND, WXC_FROM_DIP(5));
1510 
1511  m_staticTextZeroReactance = new wxStaticText(m_panelFault, wxID_ANY, _("Indutive reactance (X0)"), wxDefaultPosition, wxDLG_UNIT(m_panelFault, wxSize(-1,-1)), 0);
1512 
1513  boxSizerLvl4_6->Add(m_staticTextZeroReactance, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
1514 
1515  m_textCtrlZeroReactance = new wxTextCtrl(m_panelFault, wxID_ANY, wxT(""), wxDefaultPosition, wxDLG_UNIT(m_panelFault, wxSize(-1,-1)), 0);
1516  #if wxVERSION_NUMBER >= 3000
1517  m_textCtrlZeroReactance->SetHint(wxT(""));
1518  #endif
1519 
1520  boxSizerLvl4_6->Add(m_textCtrlZeroReactance, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxEXPAND|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
1521 
1522  wxBoxSizer* boxSizerLvl4_7 = new wxBoxSizer(wxVERTICAL);
1523 
1524  gridSizerLvl3_2->Add(boxSizerLvl4_7, 0, wxEXPAND, WXC_FROM_DIP(5));
1525 
1526  m_staticTextZeroSusceptance = new wxStaticText(m_panelFault, wxID_ANY, _("Capacitive susceptance (B0)"), wxDefaultPosition, wxDLG_UNIT(m_panelFault, wxSize(-1,-1)), 0);
1527 
1528  boxSizerLvl4_7->Add(m_staticTextZeroSusceptance, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
1529 
1530  m_textCtrlZeroSusceptance = new wxTextCtrl(m_panelFault, wxID_ANY, wxT(""), wxDefaultPosition, wxDLG_UNIT(m_panelFault, wxSize(-1,-1)), 0);
1531  #if wxVERSION_NUMBER >= 3000
1532  m_textCtrlZeroSusceptance->SetHint(wxT(""));
1533  #endif
1534 
1535  boxSizerLvl4_7->Add(m_textCtrlZeroSusceptance, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxEXPAND|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
1536 
1537  wxBoxSizer* boxSizerBottomButtons = new wxBoxSizer(wxHORIZONTAL);
1538 
1539  boxSizerLvl1_1->Add(boxSizerBottomButtons, 0, wxALL|wxEXPAND, WXC_FROM_DIP(5));
1540 
1541  m_buttonStability = new wxButton(this, wxID_ANY, _("Stability"), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
1542 
1543  boxSizerBottomButtons->Add(m_buttonStability, 0, wxALL|wxALIGN_LEFT, WXC_FROM_DIP(5));
1544 
1545  boxSizerBottomButtons->Add(0, 0, 1, wxALL|wxEXPAND, WXC_FROM_DIP(5));
1546 
1547  m_buttonOK = new wxButton(this, wxID_ANY, _("OK"), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
1548 
1549  boxSizerBottomButtons->Add(m_buttonOK, 0, wxALL|wxALIGN_RIGHT, WXC_FROM_DIP(5));
1550 
1551  m_buttonCancel = new wxButton(this, wxID_ANY, _("Cancel"), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
1552 
1553  boxSizerBottomButtons->Add(m_buttonCancel, 0, wxALL|wxALIGN_RIGHT, WXC_FROM_DIP(5));
1554 
1555 
1556  #if wxVERSION_NUMBER >= 2900
1557  if(!wxPersistenceManager::Get().Find(m_notebook)){
1558  wxPersistenceManager::Get().RegisterAndRestore(m_notebook);
1559  } else {
1560  wxPersistenceManager::Get().Restore(m_notebook);
1561  }
1562  #endif
1563 
1564  SetName(wxT("LineFormBase"));
1565  SetSize(-1,-1);
1566  if (GetSizer()) {
1567  GetSizer()->Fit(this);
1568  }
1569  if(GetParent()) {
1570  CentreOnParent(wxBOTH);
1571  } else {
1572  CentreOnScreen(wxBOTH);
1573  }
1574 #if wxVERSION_NUMBER >= 2900
1575  if(!wxPersistenceManager::Get().Find(this)) {
1576  wxPersistenceManager::Get().RegisterAndRestore(this);
1577  } else {
1578  wxPersistenceManager::Get().Restore(this);
1579  }
1580 #endif
1581  // Connect events
1582  m_buttonStability->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(LineFormBase::OnStabilityButtonClick), NULL, this);
1583  m_buttonOK->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(LineFormBase::OnOKButtonClick), NULL, this);
1584  m_buttonCancel->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(LineFormBase::OnCancelButtonClick), NULL, this);
1585 
1586 }
1587 
1588 LineFormBase::~LineFormBase()
1589 {
1590  m_buttonStability->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(LineFormBase::OnStabilityButtonClick), NULL, this);
1591  m_buttonOK->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(LineFormBase::OnOKButtonClick), NULL, this);
1592  m_buttonCancel->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(LineFormBase::OnCancelButtonClick), NULL, this);
1593 
1594 }
1595 
1596 TransformerFormBase::TransformerFormBase(wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style)
1597  : wxDialog(parent, id, title, pos, size, style)
1598 {
1599  if ( !bBitmapLoaded ) {
1600  // We need to initialise the default bitmap handler
1601  wxXmlResource::Get()->AddHandler(new wxBitmapXmlHandler);
1602  wxC9EE9InitBitmapResources();
1603  bBitmapLoaded = true;
1604  }
1605 
1606  wxBoxSizer* boxSizerLvl1_1 = new wxBoxSizer(wxVERTICAL);
1607  this->SetSizer(boxSizerLvl1_1);
1608 
1609  m_notebook = new wxNotebook(this, wxID_ANY, wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), wxBK_DEFAULT);
1610  m_notebook->SetName(wxT("m_notebook"));
1611 
1612  boxSizerLvl1_1->Add(m_notebook, 1, wxEXPAND, WXC_FROM_DIP(5));
1613 
1614  m_panelGeneral = new wxPanel(m_notebook, wxID_ANY, wxDefaultPosition, wxDLG_UNIT(m_notebook, wxSize(-1,-1)), wxTAB_TRAVERSAL);
1615  m_notebook->AddPage(m_panelGeneral, _("General"), false);
1616 
1617  wxBoxSizer* boxSizerLvl2_1 = new wxBoxSizer(wxVERTICAL);
1618  m_panelGeneral->SetSizer(boxSizerLvl2_1);
1619 
1620  m_staticTextName = new wxStaticText(m_panelGeneral, wxID_ANY, _("Name"), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
1621 
1622  boxSizerLvl2_1->Add(m_staticTextName, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
1623 
1624  m_textCtrlName = new wxTextCtrl(m_panelGeneral, wxID_ANY, wxT(""), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
1625  #if wxVERSION_NUMBER >= 3000
1626  m_textCtrlName->SetHint(wxT(""));
1627  #endif
1628 
1629  boxSizerLvl2_1->Add(m_textCtrlName, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxEXPAND|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
1630  m_textCtrlName->SetMinSize(wxSize(300,-1));
1631 
1632  wxGridSizer* gridSizerLvl3_1 = new wxGridSizer(0, 2, 0, 0);
1633 
1634  boxSizerLvl2_1->Add(gridSizerLvl3_1, 0, wxEXPAND, WXC_FROM_DIP(5));
1635 
1636  wxBoxSizer* boxSizerLvl4_1 = new wxBoxSizer(wxVERTICAL);
1637 
1638  gridSizerLvl3_1->Add(boxSizerLvl4_1, 0, wxEXPAND, WXC_FROM_DIP(5));
1639 
1640  m_staticTextNominalVoltage = new wxStaticText(m_panelGeneral, wxID_ANY, _("Rated voltage"), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
1641 
1642  boxSizerLvl4_1->Add(m_staticTextNominalVoltage, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
1643 
1644  m_staticTextNominalVoltageValue = new wxStaticText(m_panelGeneral, wxID_ANY, _("138 kV / 138 kV"), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
1645  wxFont m_staticTextNominalVoltageValueFont = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT);
1646  m_staticTextNominalVoltageValueFont.SetWeight(wxFONTWEIGHT_BOLD);
1647  m_staticTextNominalVoltageValue->SetFont(m_staticTextNominalVoltageValueFont);
1648 
1649  boxSizerLvl4_1->Add(m_staticTextNominalVoltageValue, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
1650 
1651  wxBoxSizer* boxSizerLvl4_5 = new wxBoxSizer(wxVERTICAL);
1652 
1653  gridSizerLvl3_1->Add(boxSizerLvl4_5, 0, wxEXPAND, WXC_FROM_DIP(5));
1654 
1655  m_staticTextBaseVoltage = new wxStaticText(m_panelGeneral, wxID_ANY, _("Base voltage"), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
1656 
1657  boxSizerLvl4_5->Add(m_staticTextBaseVoltage, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
1658 
1659  wxArrayString m_choiceBaseVoltageArr;
1660  m_choiceBaseVoltageArr.Add(wxT("138 kV"));
1661  m_choiceBaseVoltageArr.Add(wxT("138 kV"));
1662  m_choiceBaseVoltage = new wxChoice(m_panelGeneral, wxID_ANY, wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), m_choiceBaseVoltageArr, 0);
1663  m_choiceBaseVoltage->SetSelection(0);
1664 
1665  boxSizerLvl4_5->Add(m_choiceBaseVoltage, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxEXPAND, WXC_FROM_DIP(5));
1666 
1667  wxBoxSizer* boxSizerLvl4_2 = new wxBoxSizer(wxVERTICAL);
1668 
1669  gridSizerLvl3_1->Add(boxSizerLvl4_2, 0, wxEXPAND, WXC_FROM_DIP(5));
1670 
1671  m_staticTextNominalPower = new wxStaticText(m_panelGeneral, wxID_ANY, _("Rated power"), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
1672 
1673  boxSizerLvl4_2->Add(m_staticTextNominalPower, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
1674 
1675  wxBoxSizer* boxSizerLvl5_1 = new wxBoxSizer(wxHORIZONTAL);
1676 
1677  boxSizerLvl4_2->Add(boxSizerLvl5_1, 0, wxEXPAND, WXC_FROM_DIP(5));
1678 
1679  m_textCtrlNominalPower = new wxTextCtrl(m_panelGeneral, wxID_ANY, wxT(""), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
1680  #if wxVERSION_NUMBER >= 3000
1681  m_textCtrlNominalPower->SetHint(wxT(""));
1682  #endif
1683 
1684  boxSizerLvl5_1->Add(m_textCtrlNominalPower, 1, wxLEFT|wxRIGHT|wxBOTTOM|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
1685 
1686  wxArrayString m_choiceNominalPowerArr;
1687  m_choiceNominalPowerArr.Add(wxT("VA"));
1688  m_choiceNominalPowerArr.Add(wxT("kVA"));
1689  m_choiceNominalPowerArr.Add(wxT("MVA"));
1690  m_choiceNominalPower = new wxChoice(m_panelGeneral, wxID_ANY, wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), m_choiceNominalPowerArr, 0);
1691  m_choiceNominalPower->SetSelection(2);
1692 
1693  boxSizerLvl5_1->Add(m_choiceNominalPower, 0, wxLEFT|wxRIGHT|wxBOTTOM, WXC_FROM_DIP(5));
1694 
1695  gridSizerLvl3_1->Add(0, 0, 1, wxALL, WXC_FROM_DIP(5));
1696 
1697  wxBoxSizer* boxSizerLvl4_3 = new wxBoxSizer(wxVERTICAL);
1698 
1699  gridSizerLvl3_1->Add(boxSizerLvl4_3, 0, wxEXPAND, WXC_FROM_DIP(5));
1700 
1701  m_staticTextResistance = new wxStaticText(m_panelGeneral, wxID_ANY, _("Resistance (R)"), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
1702 
1703  boxSizerLvl4_3->Add(m_staticTextResistance, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
1704 
1705  wxBoxSizer* boxSizerLvl5_2 = new wxBoxSizer(wxHORIZONTAL);
1706 
1707  boxSizerLvl4_3->Add(boxSizerLvl5_2, 0, wxEXPAND, WXC_FROM_DIP(5));
1708 
1709  m_textCtrlResistance = new wxTextCtrl(m_panelGeneral, wxID_ANY, wxT(""), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
1710  #if wxVERSION_NUMBER >= 3000
1711  m_textCtrlResistance->SetHint(wxT(""));
1712  #endif
1713 
1714  boxSizerLvl5_2->Add(m_textCtrlResistance, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxEXPAND|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
1715 
1716  wxArrayString m_choiceResistanceArr;
1717  m_choiceResistanceArr.Add(wxT("p.u."));
1718  m_choiceResistanceArr.Add(wxT("Ohm"));
1719  m_choiceResistance = new wxChoice(m_panelGeneral, wxID_ANY, wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), m_choiceResistanceArr, 0);
1720  m_choiceResistance->SetSelection(0);
1721 
1722  boxSizerLvl5_2->Add(m_choiceResistance, 0, wxLEFT|wxRIGHT|wxBOTTOM, WXC_FROM_DIP(5));
1723 
1724  wxBoxSizer* boxSizerLvl4_4 = new wxBoxSizer(wxVERTICAL);
1725 
1726  gridSizerLvl3_1->Add(boxSizerLvl4_4, 0, wxEXPAND, WXC_FROM_DIP(5));
1727 
1728  m_staticTextReactance = new wxStaticText(m_panelGeneral, wxID_ANY, _("Indutive reactance (XL)"), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
1729 
1730  boxSizerLvl4_4->Add(m_staticTextReactance, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
1731 
1732  wxBoxSizer* boxSizerLvl5_3 = new wxBoxSizer(wxHORIZONTAL);
1733 
1734  boxSizerLvl4_4->Add(boxSizerLvl5_3, 0, wxEXPAND, WXC_FROM_DIP(5));
1735 
1736  m_textCtrlReactance = new wxTextCtrl(m_panelGeneral, wxID_ANY, wxT(""), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
1737  #if wxVERSION_NUMBER >= 3000
1738  m_textCtrlReactance->SetHint(wxT(""));
1739  #endif
1740 
1741  boxSizerLvl5_3->Add(m_textCtrlReactance, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxEXPAND|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
1742 
1743  wxArrayString m_choiceReactanceArr;
1744  m_choiceReactanceArr.Add(wxT("p.u."));
1745  m_choiceReactanceArr.Add(wxT("Ohm"));
1746  m_choiceReactance = new wxChoice(m_panelGeneral, wxID_ANY, wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), m_choiceReactanceArr, 0);
1747  m_choiceReactance->SetSelection(0);
1748 
1749  boxSizerLvl5_3->Add(m_choiceReactance, 0, wxLEFT|wxRIGHT|wxBOTTOM, WXC_FROM_DIP(5));
1750 
1751  m_staticLine_1 = new wxStaticLine(m_panelGeneral, wxID_ANY, wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), wxLI_HORIZONTAL);
1752 
1753  boxSizerLvl2_1->Add(m_staticLine_1, 0, wxALL|wxEXPAND, WXC_FROM_DIP(5));
1754 
1755  wxBoxSizer* boxSizerLvl3_1 = new wxBoxSizer(wxVERTICAL);
1756 
1757  boxSizerLvl2_1->Add(boxSizerLvl3_1, 0, wxEXPAND, WXC_FROM_DIP(5));
1758 
1759  m_staticTextConnection = new wxStaticText(m_panelGeneral, wxID_ANY, _("Connection"), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
1760 
1761  boxSizerLvl3_1->Add(m_staticTextConnection, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
1762 
1763  wxArrayString m_choiceConnectionArr;
1764  m_choiceConnectionArr.Add(wxT("Grounded Wye - Grounded Wye"));
1765  m_choiceConnectionArr.Add(wxT("Wye - Grounded Wye"));
1766  m_choiceConnectionArr.Add(wxT("Grounded Wye - Wye"));
1767  m_choiceConnectionArr.Add(wxT("Wye - Wye"));
1768  m_choiceConnectionArr.Add(wxT("Delta - Grounded Wye"));
1769  m_choiceConnectionArr.Add(wxT("Delta - Wye"));
1770  m_choiceConnectionArr.Add(wxT("Grounded Wye - Delta"));
1771  m_choiceConnectionArr.Add(wxT("Wye - Delta"));
1772  m_choiceConnectionArr.Add(wxT("Delta - Delta"));
1773  m_choiceConnection = new wxChoice(m_panelGeneral, wxID_ANY, wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), m_choiceConnectionArr, 0);
1774  m_choiceConnection->SetSelection(0);
1775 
1776  boxSizerLvl3_1->Add(m_choiceConnection, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxEXPAND, WXC_FROM_DIP(5));
1777 
1778  wxGridSizer* gridSizerLvl3_2 = new wxGridSizer(0, 2, 0, 0);
1779 
1780  boxSizerLvl2_1->Add(gridSizerLvl3_2, 0, wxEXPAND, WXC_FROM_DIP(5));
1781 
1782  wxBoxSizer* boxSizerLvl4_6 = new wxBoxSizer(wxVERTICAL);
1783 
1784  gridSizerLvl3_2->Add(boxSizerLvl4_6, 0, wxEXPAND, WXC_FROM_DIP(5));
1785 
1786  m_staticTextTurnsRatio = new wxStaticText(m_panelGeneral, wxID_ANY, _("Turns ratio"), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
1787 
1788  boxSizerLvl4_6->Add(m_staticTextTurnsRatio, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
1789 
1790  m_textCtrlTurnRatio = new wxTextCtrl(m_panelGeneral, wxID_ANY, wxT(""), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
1791  #if wxVERSION_NUMBER >= 3000
1792  m_textCtrlTurnRatio->SetHint(wxT(""));
1793  #endif
1794 
1795  boxSizerLvl4_6->Add(m_textCtrlTurnRatio, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxEXPAND|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
1796 
1797  wxBoxSizer* boxSizerLvl4_7 = new wxBoxSizer(wxVERTICAL);
1798 
1799  gridSizerLvl3_2->Add(boxSizerLvl4_7, 0, wxEXPAND, WXC_FROM_DIP(5));
1800 
1801  m_staticTextPhaseShift = new wxStaticText(m_panelGeneral, wxID_ANY, _("Phase shift"), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
1802 
1803  boxSizerLvl4_7->Add(m_staticTextPhaseShift, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
1804 
1805  wxBoxSizer* boxSizerLvl5_4 = new wxBoxSizer(wxHORIZONTAL);
1806 
1807  boxSizerLvl4_7->Add(boxSizerLvl5_4, 0, wxEXPAND, WXC_FROM_DIP(5));
1808 
1809  m_textCtrlPhaseShift = new wxTextCtrl(m_panelGeneral, wxID_ANY, wxT(""), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
1810  #if wxVERSION_NUMBER >= 3000
1811  m_textCtrlPhaseShift->SetHint(wxT(""));
1812  #endif
1813 
1814  boxSizerLvl5_4->Add(m_textCtrlPhaseShift, 1, wxLEFT|wxRIGHT|wxBOTTOM|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
1815 
1816  m_staticTextDeg = new wxStaticText(m_panelGeneral, wxID_ANY, _("degrees"), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
1817 
1818  boxSizerLvl5_4->Add(m_staticTextDeg, 0, wxALL, WXC_FROM_DIP(5));
1819 
1820  m_checkUseTransformerPower = new wxCheckBox(m_panelGeneral, wxID_ANY, _("Use transformer rated power as base"), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
1821  m_checkUseTransformerPower->SetValue(false);
1822 
1823  boxSizerLvl2_1->Add(m_checkUseTransformerPower, 0, wxALL, WXC_FROM_DIP(5));
1824 
1825  m_panelFault = new wxPanel(m_notebook, wxID_ANY, wxDefaultPosition, wxDLG_UNIT(m_notebook, wxSize(-1,-1)), wxTAB_TRAVERSAL);
1826  m_notebook->AddPage(m_panelFault, _("Fault"), false);
1827 
1828  wxBoxSizer* boxSizerLvl2_2 = new wxBoxSizer(wxVERTICAL);
1829  m_panelFault->SetSizer(boxSizerLvl2_2);
1830 
1831  wxStaticBoxSizer* staticBoxSizerZeroImpSeq = new wxStaticBoxSizer( new wxStaticBox(m_panelFault, wxID_ANY, _("Zero-sequence impedances (p.u.)")), wxVERTICAL);
1832 
1833  boxSizerLvl2_2->Add(staticBoxSizerZeroImpSeq, 0, wxALL|wxEXPAND, WXC_FROM_DIP(5));
1834 
1835  wxGridSizer* gridSizerLvl3_3 = new wxGridSizer(0, 2, 0, 0);
1836 
1837  staticBoxSizerZeroImpSeq->Add(gridSizerLvl3_3, 0, wxEXPAND, WXC_FROM_DIP(5));
1838 
1839  wxBoxSizer* boxSizerLvl4_8 = new wxBoxSizer(wxVERTICAL);
1840 
1841  gridSizerLvl3_3->Add(boxSizerLvl4_8, 0, wxEXPAND, WXC_FROM_DIP(5));
1842 
1843  m_staticTextZeroResistance = new wxStaticText(m_panelFault, wxID_ANY, _("Resistance (R0)"), wxDefaultPosition, wxDLG_UNIT(m_panelFault, wxSize(-1,-1)), 0);
1844 
1845  boxSizerLvl4_8->Add(m_staticTextZeroResistance, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
1846 
1847  m_textCtrlZeroResistance = new wxTextCtrl(m_panelFault, wxID_ANY, wxT(""), wxDefaultPosition, wxDLG_UNIT(m_panelFault, wxSize(-1,-1)), 0);
1848  #if wxVERSION_NUMBER >= 3000
1849  m_textCtrlZeroResistance->SetHint(wxT(""));
1850  #endif
1851 
1852  boxSizerLvl4_8->Add(m_textCtrlZeroResistance, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxEXPAND|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
1853 
1854  wxBoxSizer* boxSizerLvl4_9 = new wxBoxSizer(wxVERTICAL);
1855 
1856  gridSizerLvl3_3->Add(boxSizerLvl4_9, 0, wxEXPAND, WXC_FROM_DIP(5));
1857 
1858  m_staticTextZeroReactance = new wxStaticText(m_panelFault, wxID_ANY, _("Indutive reactance (X0)"), wxDefaultPosition, wxDLG_UNIT(m_panelFault, wxSize(-1,-1)), 0);
1859 
1860  boxSizerLvl4_9->Add(m_staticTextZeroReactance, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
1861 
1862  m_textCtrlZeroReactance = new wxTextCtrl(m_panelFault, wxID_ANY, wxT(""), wxDefaultPosition, wxDLG_UNIT(m_panelFault, wxSize(-1,-1)), 0);
1863  #if wxVERSION_NUMBER >= 3000
1864  m_textCtrlZeroReactance->SetHint(wxT(""));
1865  #endif
1866 
1867  boxSizerLvl4_9->Add(m_textCtrlZeroReactance, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxEXPAND|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
1868 
1869  wxStaticBoxSizer* staticBoxSizerGroundImpedances = new wxStaticBoxSizer( new wxStaticBox(m_panelFault, wxID_ANY, _("Ground impedances (p.u.)")), wxVERTICAL);
1870 
1871  boxSizerLvl2_2->Add(staticBoxSizerGroundImpedances, 0, wxALL|wxEXPAND, WXC_FROM_DIP(5));
1872 
1873  wxGridSizer* gridSizerLvl3_4 = new wxGridSizer(0, 2, 0, 0);
1874 
1875  staticBoxSizerGroundImpedances->Add(gridSizerLvl3_4, 0, wxEXPAND, WXC_FROM_DIP(5));
1876 
1877  wxBoxSizer* boxSizerLvl4_10 = new wxBoxSizer(wxVERTICAL);
1878 
1879  gridSizerLvl3_4->Add(boxSizerLvl4_10, 0, wxEXPAND, WXC_FROM_DIP(5));
1880 
1881  m_staticTextPrimResistance = new wxStaticText(m_panelFault, wxID_ANY, _("Primary resistance"), wxDefaultPosition, wxDLG_UNIT(m_panelFault, wxSize(-1,-1)), 0);
1882 
1883  boxSizerLvl4_10->Add(m_staticTextPrimResistance, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
1884 
1885  m_textCtrlPrimResistance = new wxTextCtrl(m_panelFault, wxID_ANY, wxT(""), wxDefaultPosition, wxDLG_UNIT(m_panelFault, wxSize(-1,-1)), 0);
1886  #if wxVERSION_NUMBER >= 3000
1887  m_textCtrlPrimResistance->SetHint(wxT(""));
1888  #endif
1889 
1890  boxSizerLvl4_10->Add(m_textCtrlPrimResistance, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxEXPAND|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
1891 
1892  wxBoxSizer* boxSizerLvl4_11 = new wxBoxSizer(wxVERTICAL);
1893 
1894  gridSizerLvl3_4->Add(boxSizerLvl4_11, 0, wxEXPAND, WXC_FROM_DIP(5));
1895 
1896  m_staticTextPrimReactance = new wxStaticText(m_panelFault, wxID_ANY, _("Primary reactance"), wxDefaultPosition, wxDLG_UNIT(m_panelFault, wxSize(-1,-1)), 0);
1897 
1898  boxSizerLvl4_11->Add(m_staticTextPrimReactance, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
1899 
1900  m_textCtrlPrimReactance = new wxTextCtrl(m_panelFault, wxID_ANY, wxT(""), wxDefaultPosition, wxDLG_UNIT(m_panelFault, wxSize(-1,-1)), 0);
1901  #if wxVERSION_NUMBER >= 3000
1902  m_textCtrlPrimReactance->SetHint(wxT(""));
1903  #endif
1904 
1905  boxSizerLvl4_11->Add(m_textCtrlPrimReactance, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxEXPAND|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
1906 
1907  wxBoxSizer* boxSizerLvl4_12 = new wxBoxSizer(wxVERTICAL);
1908 
1909  gridSizerLvl3_4->Add(boxSizerLvl4_12, 0, wxEXPAND, WXC_FROM_DIP(5));
1910 
1911  m_staticTextSecResistance = new wxStaticText(m_panelFault, wxID_ANY, _("Secondary resistance"), wxDefaultPosition, wxDLG_UNIT(m_panelFault, wxSize(-1,-1)), 0);
1912 
1913  boxSizerLvl4_12->Add(m_staticTextSecResistance, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
1914 
1915  m_textCtrlSecResistance = new wxTextCtrl(m_panelFault, wxID_ANY, wxT(""), wxDefaultPosition, wxDLG_UNIT(m_panelFault, wxSize(-1,-1)), 0);
1916  #if wxVERSION_NUMBER >= 3000
1917  m_textCtrlSecResistance->SetHint(wxT(""));
1918  #endif
1919 
1920  boxSizerLvl4_12->Add(m_textCtrlSecResistance, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxEXPAND|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
1921 
1922  wxBoxSizer* boxSizerLvl4_13 = new wxBoxSizer(wxVERTICAL);
1923 
1924  gridSizerLvl3_4->Add(boxSizerLvl4_13, 0, wxEXPAND, WXC_FROM_DIP(5));
1925 
1926  m_staticTextSecReactance = new wxStaticText(m_panelFault, wxID_ANY, _("Secondary reactance"), wxDefaultPosition, wxDLG_UNIT(m_panelFault, wxSize(-1,-1)), 0);
1927 
1928  boxSizerLvl4_13->Add(m_staticTextSecReactance, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
1929 
1930  m_textCtrlSecReactance = new wxTextCtrl(m_panelFault, wxID_ANY, wxT(""), wxDefaultPosition, wxDLG_UNIT(m_panelFault, wxSize(-1,-1)), 0);
1931  #if wxVERSION_NUMBER >= 3000
1932  m_textCtrlSecReactance->SetHint(wxT(""));
1933  #endif
1934 
1935  boxSizerLvl4_13->Add(m_textCtrlSecReactance, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxEXPAND|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
1936 
1937  wxBoxSizer* boxSizerBottomButtons = new wxBoxSizer(wxHORIZONTAL);
1938 
1939  boxSizerLvl1_1->Add(boxSizerBottomButtons, 0, wxALL|wxEXPAND, WXC_FROM_DIP(5));
1940 
1941  m_buttonStability = new wxButton(this, wxID_ANY, _("Stability"), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
1942 
1943  boxSizerBottomButtons->Add(m_buttonStability, 0, wxALL|wxALIGN_LEFT, WXC_FROM_DIP(5));
1944 
1945  boxSizerBottomButtons->Add(0, 0, 1, wxALL|wxEXPAND, WXC_FROM_DIP(5));
1946 
1947  m_buttonOK = new wxButton(this, wxID_ANY, _("OK"), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
1948 
1949  boxSizerBottomButtons->Add(m_buttonOK, 0, wxALL|wxALIGN_RIGHT, WXC_FROM_DIP(5));
1950 
1951  m_buttonCancel = new wxButton(this, wxID_ANY, _("Cancel"), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
1952 
1953  boxSizerBottomButtons->Add(m_buttonCancel, 0, wxALL|wxALIGN_RIGHT, WXC_FROM_DIP(5));
1954 
1955 
1956  #if wxVERSION_NUMBER >= 2900
1957  if(!wxPersistenceManager::Get().Find(m_notebook)){
1958  wxPersistenceManager::Get().RegisterAndRestore(m_notebook);
1959  } else {
1960  wxPersistenceManager::Get().Restore(m_notebook);
1961  }
1962  #endif
1963 
1964  SetName(wxT("TransformerFormBase"));
1965  SetSize(-1,-1);
1966  if (GetSizer()) {
1967  GetSizer()->Fit(this);
1968  }
1969  if(GetParent()) {
1970  CentreOnParent(wxBOTH);
1971  } else {
1972  CentreOnScreen(wxBOTH);
1973  }
1974 #if wxVERSION_NUMBER >= 2900
1975  if(!wxPersistenceManager::Get().Find(this)) {
1976  wxPersistenceManager::Get().RegisterAndRestore(this);
1977  } else {
1978  wxPersistenceManager::Get().Restore(this);
1979  }
1980 #endif
1981  // Connect events
1982  m_buttonStability->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(TransformerFormBase::OnStabilityButtonClick), NULL, this);
1983  m_buttonOK->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(TransformerFormBase::OnOKButtonClick), NULL, this);
1984  m_buttonCancel->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(TransformerFormBase::OnCancelButtonClick), NULL, this);
1985 
1986 }
1987 
1988 TransformerFormBase::~TransformerFormBase()
1989 {
1990  m_buttonStability->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(TransformerFormBase::OnStabilityButtonClick), NULL, this);
1991  m_buttonOK->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(TransformerFormBase::OnOKButtonClick), NULL, this);
1992  m_buttonCancel->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(TransformerFormBase::OnCancelButtonClick), NULL, this);
1993 
1994 }
1995 
1996 LoadFormBase::LoadFormBase(wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style)
1997  : wxDialog(parent, id, title, pos, size, style)
1998 {
1999  if ( !bBitmapLoaded ) {
2000  // We need to initialise the default bitmap handler
2001  wxXmlResource::Get()->AddHandler(new wxBitmapXmlHandler);
2002  wxC9EE9InitBitmapResources();
2003  bBitmapLoaded = true;
2004  }
2005 
2006  wxBoxSizer* boxSizerLvl1_1 = new wxBoxSizer(wxVERTICAL);
2007  this->SetSizer(boxSizerLvl1_1);
2008 
2009  m_notebook = new wxNotebook(this, wxID_ANY, wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), wxBK_DEFAULT);
2010  m_notebook->SetName(wxT("m_notebook"));
2011 
2012  boxSizerLvl1_1->Add(m_notebook, 1, wxEXPAND, WXC_FROM_DIP(5));
2013 
2014  m_panelGeneral = new wxPanel(m_notebook, wxID_ANY, wxDefaultPosition, wxDLG_UNIT(m_notebook, wxSize(-1,-1)), wxTAB_TRAVERSAL);
2015  m_notebook->AddPage(m_panelGeneral, _("General"), false);
2016 
2017  wxBoxSizer* boxSizerLvl2_1 = new wxBoxSizer(wxVERTICAL);
2018  m_panelGeneral->SetSizer(boxSizerLvl2_1);
2019 
2020  m_staticTextName = new wxStaticText(m_panelGeneral, wxID_ANY, _("Name"), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
2021 
2022  boxSizerLvl2_1->Add(m_staticTextName, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
2023 
2024  m_textCtrlName = new wxTextCtrl(m_panelGeneral, wxID_ANY, wxT(""), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
2025  #if wxVERSION_NUMBER >= 3000
2026  m_textCtrlName->SetHint(wxT(""));
2027  #endif
2028 
2029  boxSizerLvl2_1->Add(m_textCtrlName, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxEXPAND|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
2030  m_textCtrlName->SetMinSize(wxSize(300,-1));
2031 
2032  wxGridSizer* gridSizerLvl3_1 = new wxGridSizer(0, 2, 0, 0);
2033 
2034  boxSizerLvl2_1->Add(gridSizerLvl3_1, 0, wxEXPAND, WXC_FROM_DIP(5));
2035 
2036  wxBoxSizer* boxSizerLvl4_1 = new wxBoxSizer(wxVERTICAL);
2037 
2038  gridSizerLvl3_1->Add(boxSizerLvl4_1, 0, wxEXPAND, WXC_FROM_DIP(5));
2039 
2040  m_staticTextActivePower = new wxStaticText(m_panelGeneral, wxID_ANY, _("Active power"), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
2041 
2042  boxSizerLvl4_1->Add(m_staticTextActivePower, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
2043 
2044  wxBoxSizer* boxSizerLvl5_1 = new wxBoxSizer(wxHORIZONTAL);
2045 
2046  boxSizerLvl4_1->Add(boxSizerLvl5_1, 0, wxEXPAND, WXC_FROM_DIP(5));
2047 
2048  m_textCtrlActivePower = new wxTextCtrl(m_panelGeneral, wxID_ANY, wxT(""), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
2049  #if wxVERSION_NUMBER >= 3000
2050  m_textCtrlActivePower->SetHint(wxT(""));
2051  #endif
2052 
2053  boxSizerLvl5_1->Add(m_textCtrlActivePower, 1, wxLEFT|wxRIGHT|wxBOTTOM|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
2054 
2055  wxArrayString m_choiceActivePowerArr;
2056  m_choiceActivePowerArr.Add(wxT("p.u."));
2057  m_choiceActivePowerArr.Add(wxT("W"));
2058  m_choiceActivePowerArr.Add(wxT("kW"));
2059  m_choiceActivePowerArr.Add(wxT("MW"));
2060  m_choiceActivePower = new wxChoice(m_panelGeneral, wxID_ANY, wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), m_choiceActivePowerArr, 0);
2061  m_choiceActivePower->SetSelection(3);
2062 
2063  boxSizerLvl5_1->Add(m_choiceActivePower, 0, wxLEFT|wxRIGHT|wxBOTTOM, WXC_FROM_DIP(5));
2064 
2065  wxBoxSizer* boxSizerLvl4_2 = new wxBoxSizer(wxVERTICAL);
2066 
2067  gridSizerLvl3_1->Add(boxSizerLvl4_2, 0, wxEXPAND, WXC_FROM_DIP(5));
2068 
2069  m_staticTextReactivePower = new wxStaticText(m_panelGeneral, wxID_ANY, _("Reactive power"), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
2070 
2071  boxSizerLvl4_2->Add(m_staticTextReactivePower, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
2072 
2073  wxBoxSizer* boxSizerLvl5_2 = new wxBoxSizer(wxHORIZONTAL);
2074 
2075  boxSizerLvl4_2->Add(boxSizerLvl5_2, 0, wxEXPAND, WXC_FROM_DIP(5));
2076 
2077  m_textCtrlReactivePower = new wxTextCtrl(m_panelGeneral, wxID_ANY, wxT(""), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
2078  #if wxVERSION_NUMBER >= 3000
2079  m_textCtrlReactivePower->SetHint(wxT(""));
2080  #endif
2081 
2082  boxSizerLvl5_2->Add(m_textCtrlReactivePower, 1, wxLEFT|wxRIGHT|wxBOTTOM|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
2083 
2084  wxArrayString m_choiceReactivePowerArr;
2085  m_choiceReactivePowerArr.Add(wxT("p.u."));
2086  m_choiceReactivePowerArr.Add(wxT("VAr"));
2087  m_choiceReactivePowerArr.Add(wxT("kVAr"));
2088  m_choiceReactivePowerArr.Add(wxT("MVAr"));
2089  m_choiceReactivePower = new wxChoice(m_panelGeneral, wxID_ANY, wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), m_choiceReactivePowerArr, 0);
2090  m_choiceReactivePower->SetSelection(3);
2091 
2092  boxSizerLvl5_2->Add(m_choiceReactivePower, 0, wxLEFT|wxRIGHT|wxBOTTOM, WXC_FROM_DIP(5));
2093 
2094  m_staticTextType = new wxStaticText(m_panelGeneral, wxID_ANY, _("Load type (power flow)"), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
2095 
2096  boxSizerLvl2_1->Add(m_staticTextType, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
2097 
2098  wxArrayString m_choiceTypeArr;
2099  m_choiceTypeArr.Add(wxT("Constant power"));
2100  m_choiceTypeArr.Add(wxT("Constant impedance"));
2101  m_choiceType = new wxChoice(m_panelGeneral, wxID_ANY, wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), m_choiceTypeArr, 0);
2102  m_choiceType->SetSelection(0);
2103 
2104  boxSizerLvl2_1->Add(m_choiceType, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxEXPAND, WXC_FROM_DIP(5));
2105 
2106  m_panelStability = new wxPanel(m_notebook, wxID_ANY, wxDefaultPosition, wxDLG_UNIT(m_notebook, wxSize(-1,-1)), wxTAB_TRAVERSAL);
2107  m_notebook->AddPage(m_panelStability, _("Stability"), false);
2108 
2109  wxBoxSizer* boxSizerLvl2_2 = new wxBoxSizer(wxVERTICAL);
2110  m_panelStability->SetSizer(boxSizerLvl2_2);
2111 
2112  m_checkBoxPlotData = new wxCheckBox(m_panelStability, wxID_ANY, _("Plot load data"), wxDefaultPosition, wxDLG_UNIT(m_panelStability, wxSize(-1,-1)), 0);
2113  m_checkBoxPlotData->SetValue(false);
2114 
2115  boxSizerLvl2_2->Add(m_checkBoxPlotData, 0, wxALL|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
2116 
2117  m_checkBoxUseCompLoad = new wxCheckBox(m_panelStability, wxID_ANY, _("Use ZIP load composition"), wxDefaultPosition, wxDLG_UNIT(m_panelStability, wxSize(-1,-1)), 0);
2118  m_checkBoxUseCompLoad->SetValue(false);
2119 
2120  boxSizerLvl2_2->Add(m_checkBoxUseCompLoad, 0, wxALL, WXC_FROM_DIP(5));
2121 
2122  wxGridSizer* gridSizerLvl3_2 = new wxGridSizer(0, 2, 0, 0);
2123 
2124  boxSizerLvl2_2->Add(gridSizerLvl3_2, 1, wxEXPAND, WXC_FROM_DIP(5));
2125 
2126  wxStaticBoxSizer* staticBoxSizerLvl4_3 = new wxStaticBoxSizer( new wxStaticBox(m_panelStability, wxID_ANY, _("Active power")), wxVERTICAL);
2127 
2128  gridSizerLvl3_2->Add(staticBoxSizerLvl4_3, 0, wxALL|wxEXPAND, WXC_FROM_DIP(5));
2129 
2130  wxBoxSizer* boxSizerLvl5_3 = new wxBoxSizer(wxVERTICAL);
2131 
2132  staticBoxSizerLvl4_3->Add(boxSizerLvl5_3, 0, wxEXPAND, WXC_FROM_DIP(5));
2133 
2134  m_staticTextActivePowerImp = new wxStaticText(m_panelStability, wxID_ANY, _("Constant impedance"), wxDefaultPosition, wxDLG_UNIT(m_panelStability, wxSize(-1,-1)), 0);
2135 
2136  boxSizerLvl5_3->Add(m_staticTextActivePowerImp, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
2137 
2138  wxBoxSizer* boxSizerLvl6_1 = new wxBoxSizer(wxHORIZONTAL);
2139 
2140  boxSizerLvl5_3->Add(boxSizerLvl6_1, 0, wxEXPAND, WXC_FROM_DIP(5));
2141 
2142  m_textCtrlActivePowerImp = new wxTextCtrl(m_panelStability, wxID_ANY, wxT("100"), wxDefaultPosition, wxDLG_UNIT(m_panelStability, wxSize(-1,-1)), 0);
2143  #if wxVERSION_NUMBER >= 3000
2144  m_textCtrlActivePowerImp->SetHint(wxT(""));
2145  #endif
2146 
2147  boxSizerLvl6_1->Add(m_textCtrlActivePowerImp, 1, wxLEFT|wxRIGHT|wxBOTTOM|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
2148 
2149  m_staticTextPerc_1 = new wxStaticText(m_panelStability, wxID_ANY, _("%"), wxDefaultPosition, wxDLG_UNIT(m_panelStability, wxSize(-1,-1)), 0);
2150 
2151  boxSizerLvl6_1->Add(m_staticTextPerc_1, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
2152 
2153  wxBoxSizer* boxSizerLvl5_4 = new wxBoxSizer(wxVERTICAL);
2154 
2155  staticBoxSizerLvl4_3->Add(boxSizerLvl5_4, 0, wxEXPAND, WXC_FROM_DIP(5));
2156 
2157  m_staticTextActivePowerCur = new wxStaticText(m_panelStability, wxID_ANY, _("Constant current"), wxDefaultPosition, wxDLG_UNIT(m_panelStability, wxSize(-1,-1)), 0);
2158 
2159  boxSizerLvl5_4->Add(m_staticTextActivePowerCur, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
2160 
2161  wxBoxSizer* boxSizerLvl6_2 = new wxBoxSizer(wxHORIZONTAL);
2162 
2163  boxSizerLvl5_4->Add(boxSizerLvl6_2, 0, wxEXPAND, WXC_FROM_DIP(5));
2164 
2165  m_textCtrlActivePowerCur = new wxTextCtrl(m_panelStability, wxID_ANY, wxT("0"), wxDefaultPosition, wxDLG_UNIT(m_panelStability, wxSize(-1,-1)), 0);
2166  #if wxVERSION_NUMBER >= 3000
2167  m_textCtrlActivePowerCur->SetHint(wxT(""));
2168  #endif
2169 
2170  boxSizerLvl6_2->Add(m_textCtrlActivePowerCur, 1, wxLEFT|wxRIGHT|wxBOTTOM|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
2171 
2172  m_staticTextPerc_2 = new wxStaticText(m_panelStability, wxID_ANY, _("%"), wxDefaultPosition, wxDLG_UNIT(m_panelStability, wxSize(-1,-1)), 0);
2173 
2174  boxSizerLvl6_2->Add(m_staticTextPerc_2, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
2175 
2176  wxBoxSizer* boxSizerLvl5_5 = new wxBoxSizer(wxVERTICAL);
2177 
2178  staticBoxSizerLvl4_3->Add(boxSizerLvl5_5, 0, wxEXPAND, WXC_FROM_DIP(5));
2179 
2180  m_staticTextActivePowerPow = new wxStaticText(m_panelStability, wxID_ANY, _("Constant power"), wxDefaultPosition, wxDLG_UNIT(m_panelStability, wxSize(-1,-1)), 0);
2181 
2182  boxSizerLvl5_5->Add(m_staticTextActivePowerPow, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
2183 
2184  wxBoxSizer* boxSizerLvl6_3 = new wxBoxSizer(wxHORIZONTAL);
2185 
2186  boxSizerLvl5_5->Add(boxSizerLvl6_3, 0, wxEXPAND, WXC_FROM_DIP(5));
2187 
2188  m_textCtrlActivePowerPow = new wxTextCtrl(m_panelStability, wxID_ANY, wxT("0"), wxDefaultPosition, wxDLG_UNIT(m_panelStability, wxSize(-1,-1)), 0);
2189  #if wxVERSION_NUMBER >= 3000
2190  m_textCtrlActivePowerPow->SetHint(wxT(""));
2191  #endif
2192 
2193  boxSizerLvl6_3->Add(m_textCtrlActivePowerPow, 1, wxLEFT|wxRIGHT|wxBOTTOM|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
2194 
2195  m_staticTextPerc_3 = new wxStaticText(m_panelStability, wxID_ANY, _("%"), wxDefaultPosition, wxDLG_UNIT(m_panelStability, wxSize(-1,-1)), 0);
2196 
2197  boxSizerLvl6_3->Add(m_staticTextPerc_3, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
2198 
2199  wxStaticBoxSizer* staticBoxSizerLvl4_4 = new wxStaticBoxSizer( new wxStaticBox(m_panelStability, wxID_ANY, _("Reactive power")), wxVERTICAL);
2200 
2201  gridSizerLvl3_2->Add(staticBoxSizerLvl4_4, 0, wxALL|wxEXPAND, WXC_FROM_DIP(5));
2202 
2203  wxBoxSizer* boxSizerLvl5_6 = new wxBoxSizer(wxVERTICAL);
2204 
2205  staticBoxSizerLvl4_4->Add(boxSizerLvl5_6, 0, wxEXPAND, WXC_FROM_DIP(5));
2206 
2207  m_staticTextReactivePowerImp = new wxStaticText(m_panelStability, wxID_ANY, _("Constant impedance"), wxDefaultPosition, wxDLG_UNIT(m_panelStability, wxSize(-1,-1)), 0);
2208 
2209  boxSizerLvl5_6->Add(m_staticTextReactivePowerImp, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
2210 
2211  wxBoxSizer* boxSizerLvl6_4 = new wxBoxSizer(wxHORIZONTAL);
2212 
2213  boxSizerLvl5_6->Add(boxSizerLvl6_4, 0, wxEXPAND, WXC_FROM_DIP(5));
2214 
2215  m_textCtrlReactivePowerImp = new wxTextCtrl(m_panelStability, wxID_ANY, wxT("100"), wxDefaultPosition, wxDLG_UNIT(m_panelStability, wxSize(-1,-1)), 0);
2216  #if wxVERSION_NUMBER >= 3000
2217  m_textCtrlReactivePowerImp->SetHint(wxT(""));
2218  #endif
2219 
2220  boxSizerLvl6_4->Add(m_textCtrlReactivePowerImp, 1, wxLEFT|wxRIGHT|wxBOTTOM|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
2221 
2222  m_staticTextPerc_4 = new wxStaticText(m_panelStability, wxID_ANY, _("%"), wxDefaultPosition, wxDLG_UNIT(m_panelStability, wxSize(-1,-1)), 0);
2223 
2224  boxSizerLvl6_4->Add(m_staticTextPerc_4, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
2225 
2226  wxBoxSizer* boxSizerLvl5_7 = new wxBoxSizer(wxVERTICAL);
2227 
2228  staticBoxSizerLvl4_4->Add(boxSizerLvl5_7, 0, wxEXPAND, WXC_FROM_DIP(5));
2229 
2230  m_staticTextReactivePowerCur = new wxStaticText(m_panelStability, wxID_ANY, _("Constant current"), wxDefaultPosition, wxDLG_UNIT(m_panelStability, wxSize(-1,-1)), 0);
2231 
2232  boxSizerLvl5_7->Add(m_staticTextReactivePowerCur, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
2233 
2234  wxBoxSizer* boxSizerLvl6_5 = new wxBoxSizer(wxHORIZONTAL);
2235 
2236  boxSizerLvl5_7->Add(boxSizerLvl6_5, 0, wxEXPAND, WXC_FROM_DIP(5));
2237 
2238  m_textCtrlReactivePowerCur = new wxTextCtrl(m_panelStability, wxID_ANY, wxT("0"), wxDefaultPosition, wxDLG_UNIT(m_panelStability, wxSize(-1,-1)), 0);
2239  #if wxVERSION_NUMBER >= 3000
2240  m_textCtrlReactivePowerCur->SetHint(wxT(""));
2241  #endif
2242 
2243  boxSizerLvl6_5->Add(m_textCtrlReactivePowerCur, 1, wxLEFT|wxRIGHT|wxBOTTOM|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
2244 
2245  m_staticTextPerc_5 = new wxStaticText(m_panelStability, wxID_ANY, _("%"), wxDefaultPosition, wxDLG_UNIT(m_panelStability, wxSize(-1,-1)), 0);
2246 
2247  boxSizerLvl6_5->Add(m_staticTextPerc_5, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
2248 
2249  wxBoxSizer* boxSizerLvl5_8 = new wxBoxSizer(wxVERTICAL);
2250 
2251  staticBoxSizerLvl4_4->Add(boxSizerLvl5_8, 0, wxEXPAND, WXC_FROM_DIP(5));
2252 
2253  m_staticTextReactivePowerPow = new wxStaticText(m_panelStability, wxID_ANY, _("Constant power"), wxDefaultPosition, wxDLG_UNIT(m_panelStability, wxSize(-1,-1)), 0);
2254 
2255  boxSizerLvl5_8->Add(m_staticTextReactivePowerPow, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
2256 
2257  wxBoxSizer* boxSizerLvl6_6 = new wxBoxSizer(wxHORIZONTAL);
2258 
2259  boxSizerLvl5_8->Add(boxSizerLvl6_6, 0, wxEXPAND, WXC_FROM_DIP(5));
2260 
2261  m_textCtrlReactivePowerPow = new wxTextCtrl(m_panelStability, wxID_ANY, wxT("0"), wxDefaultPosition, wxDLG_UNIT(m_panelStability, wxSize(-1,-1)), 0);
2262  #if wxVERSION_NUMBER >= 3000
2263  m_textCtrlReactivePowerPow->SetHint(wxT(""));
2264  #endif
2265 
2266  boxSizerLvl6_6->Add(m_textCtrlReactivePowerPow, 1, wxLEFT|wxRIGHT|wxBOTTOM|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
2267 
2268  m_staticTextPerc_6 = new wxStaticText(m_panelStability, wxID_ANY, _("%"), wxDefaultPosition, wxDLG_UNIT(m_panelStability, wxSize(-1,-1)), 0);
2269 
2270  boxSizerLvl6_6->Add(m_staticTextPerc_6, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
2271 
2272  wxBoxSizer* boxSizerBottomButtons = new wxBoxSizer(wxHORIZONTAL);
2273 
2274  boxSizerLvl1_1->Add(boxSizerBottomButtons, 0, wxALL|wxEXPAND, WXC_FROM_DIP(5));
2275 
2276  m_buttonStabButton = new wxButton(this, wxID_ANY, _("Switching"), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
2277 
2278  boxSizerBottomButtons->Add(m_buttonStabButton, 0, wxALL|wxALIGN_LEFT, WXC_FROM_DIP(5));
2279 
2280  boxSizerBottomButtons->Add(0, 0, 1, wxALL, WXC_FROM_DIP(5));
2281 
2282  m_buttonOK = new wxButton(this, wxID_ANY, _("OK"), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
2283 
2284  boxSizerBottomButtons->Add(m_buttonOK, 0, wxALL|wxALIGN_RIGHT, WXC_FROM_DIP(5));
2285 
2286  m_ButtonCancel = new wxButton(this, wxID_ANY, _("Cancel"), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
2287 
2288  boxSizerBottomButtons->Add(m_ButtonCancel, 0, wxALL|wxALIGN_RIGHT, WXC_FROM_DIP(5));
2289 
2290 
2291  #if wxVERSION_NUMBER >= 2900
2292  if(!wxPersistenceManager::Get().Find(m_notebook)){
2293  wxPersistenceManager::Get().RegisterAndRestore(m_notebook);
2294  } else {
2295  wxPersistenceManager::Get().Restore(m_notebook);
2296  }
2297  #endif
2298 
2299  SetName(wxT("LoadFormBase"));
2300  SetSize(-1,-1);
2301  if (GetSizer()) {
2302  GetSizer()->Fit(this);
2303  }
2304  if(GetParent()) {
2305  CentreOnParent(wxBOTH);
2306  } else {
2307  CentreOnScreen(wxBOTH);
2308  }
2309 #if wxVERSION_NUMBER >= 2900
2310  if(!wxPersistenceManager::Get().Find(this)) {
2311  wxPersistenceManager::Get().RegisterAndRestore(this);
2312  } else {
2313  wxPersistenceManager::Get().Restore(this);
2314  }
2315 #endif
2316  // Connect events
2317  m_checkBoxUseCompLoad->Connect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler(LoadFormBase::OnCheckBoxCompLoadClick), NULL, this);
2318  m_buttonStabButton->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(LoadFormBase::OnStabilityButtonClick), NULL, this);
2319  m_buttonOK->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(LoadFormBase::OnOnButtonClick), NULL, this);
2320  m_ButtonCancel->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(LoadFormBase::OnCancelButtonClick), NULL, this);
2321 
2322 }
2323 
2324 LoadFormBase::~LoadFormBase()
2325 {
2326  m_checkBoxUseCompLoad->Disconnect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler(LoadFormBase::OnCheckBoxCompLoadClick), NULL, this);
2327  m_buttonStabButton->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(LoadFormBase::OnStabilityButtonClick), NULL, this);
2328  m_buttonOK->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(LoadFormBase::OnOnButtonClick), NULL, this);
2329  m_ButtonCancel->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(LoadFormBase::OnCancelButtonClick), NULL, this);
2330 
2331 }
2332 
2333 ReactiveShuntElementFormBase::ReactiveShuntElementFormBase(wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style)
2334  : wxDialog(parent, id, title, pos, size, style)
2335 {
2336  if ( !bBitmapLoaded ) {
2337  // We need to initialise the default bitmap handler
2338  wxXmlResource::Get()->AddHandler(new wxBitmapXmlHandler);
2339  wxC9EE9InitBitmapResources();
2340  bBitmapLoaded = true;
2341  }
2342 
2343  wxBoxSizer* boxSizerLvl1_1 = new wxBoxSizer(wxVERTICAL);
2344  this->SetSizer(boxSizerLvl1_1);
2345 
2346  m_notebook = new wxNotebook(this, wxID_ANY, wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), wxBK_DEFAULT);
2347  m_notebook->SetName(wxT("m_notebook"));
2348 
2349  boxSizerLvl1_1->Add(m_notebook, 1, wxEXPAND, WXC_FROM_DIP(5));
2350 
2351  m_panelGeneral = new wxPanel(m_notebook, wxID_ANY, wxDefaultPosition, wxDLG_UNIT(m_notebook, wxSize(-1,-1)), wxTAB_TRAVERSAL);
2352  m_notebook->AddPage(m_panelGeneral, _("General"), false);
2353 
2354  wxBoxSizer* boxSizerLvl2_1 = new wxBoxSizer(wxVERTICAL);
2355  m_panelGeneral->SetSizer(boxSizerLvl2_1);
2356 
2357  m_staticTextName = new wxStaticText(m_panelGeneral, wxID_ANY, _("Name"), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
2358 
2359  boxSizerLvl2_1->Add(m_staticTextName, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
2360 
2361  m_textCtrlName = new wxTextCtrl(m_panelGeneral, wxID_ANY, wxT(""), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
2362  #if wxVERSION_NUMBER >= 3000
2363  m_textCtrlName->SetHint(wxT(""));
2364  #endif
2365 
2366  boxSizerLvl2_1->Add(m_textCtrlName, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxEXPAND|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
2367  m_textCtrlName->SetMinSize(wxSize(300,-1));
2368 
2369  wxGridSizer* gridSizerLvl3_1 = new wxGridSizer(0, 2, 0, 0);
2370 
2371  boxSizerLvl2_1->Add(gridSizerLvl3_1, 0, wxEXPAND, WXC_FROM_DIP(5));
2372 
2373  wxBoxSizer* boxSizerLvl4_2 = new wxBoxSizer(wxVERTICAL);
2374 
2375  gridSizerLvl3_1->Add(boxSizerLvl4_2, 0, wxEXPAND, WXC_FROM_DIP(5));
2376 
2377  m_staticTextReactivePower = new wxStaticText(m_panelGeneral, wxID_ANY, _("Reactive power"), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
2378 
2379  boxSizerLvl4_2->Add(m_staticTextReactivePower, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
2380 
2381  wxBoxSizer* boxSizerLvl5_2 = new wxBoxSizer(wxHORIZONTAL);
2382 
2383  boxSizerLvl4_2->Add(boxSizerLvl5_2, 0, wxEXPAND, WXC_FROM_DIP(5));
2384 
2385  m_textCtrlReactivePower = new wxTextCtrl(m_panelGeneral, wxID_ANY, wxT(""), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
2386  #if wxVERSION_NUMBER >= 3000
2387  m_textCtrlReactivePower->SetHint(wxT(""));
2388  #endif
2389 
2390  boxSizerLvl5_2->Add(m_textCtrlReactivePower, 1, wxLEFT|wxRIGHT|wxBOTTOM|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
2391 
2392  wxArrayString m_choiceReactivePowerArr;
2393  m_choiceReactivePowerArr.Add(wxT("p.u."));
2394  m_choiceReactivePowerArr.Add(wxT("VAr"));
2395  m_choiceReactivePowerArr.Add(wxT("kVAr"));
2396  m_choiceReactivePowerArr.Add(wxT("MVAr"));
2397  m_choiceReactivePower = new wxChoice(m_panelGeneral, wxID_ANY, wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), m_choiceReactivePowerArr, 0);
2398  m_choiceReactivePower->SetSelection(3);
2399 
2400  boxSizerLvl5_2->Add(m_choiceReactivePower, 0, wxLEFT|wxRIGHT|wxBOTTOM, WXC_FROM_DIP(5));
2401 
2402  wxBoxSizer* boxSizerBottomButtons = new wxBoxSizer(wxHORIZONTAL);
2403 
2404  boxSizerLvl1_1->Add(boxSizerBottomButtons, 0, wxALL|wxEXPAND, WXC_FROM_DIP(5));
2405 
2406  m_buttonStabButton = new wxButton(this, wxID_ANY, _("Stability"), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
2407 
2408  boxSizerBottomButtons->Add(m_buttonStabButton, 0, wxALL|wxALIGN_LEFT, WXC_FROM_DIP(5));
2409 
2410  boxSizerBottomButtons->Add(0, 0, 1, wxALL, WXC_FROM_DIP(5));
2411 
2412  m_buttonOK = new wxButton(this, wxID_ANY, _("OK"), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
2413 
2414  boxSizerBottomButtons->Add(m_buttonOK, 0, wxALL|wxALIGN_RIGHT, WXC_FROM_DIP(5));
2415 
2416  m_buttonCancel = new wxButton(this, wxID_ANY, _("Cancel"), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
2417 
2418  boxSizerBottomButtons->Add(m_buttonCancel, 0, wxALL|wxALIGN_RIGHT, WXC_FROM_DIP(5));
2419 
2420 
2421  #if wxVERSION_NUMBER >= 2900
2422  if(!wxPersistenceManager::Get().Find(m_notebook)){
2423  wxPersistenceManager::Get().RegisterAndRestore(m_notebook);
2424  } else {
2425  wxPersistenceManager::Get().Restore(m_notebook);
2426  }
2427  #endif
2428 
2429  SetName(wxT("ReactiveShuntElementFormBase"));
2430  SetSize(-1,-1);
2431  if (GetSizer()) {
2432  GetSizer()->Fit(this);
2433  }
2434  if(GetParent()) {
2435  CentreOnParent(wxBOTH);
2436  } else {
2437  CentreOnScreen(wxBOTH);
2438  }
2439 #if wxVERSION_NUMBER >= 2900
2440  if(!wxPersistenceManager::Get().Find(this)) {
2441  wxPersistenceManager::Get().RegisterAndRestore(this);
2442  } else {
2443  wxPersistenceManager::Get().Restore(this);
2444  }
2445 #endif
2446  // Connect events
2447  m_buttonStabButton->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(ReactiveShuntElementFormBase::OnStabilityButtonClick), NULL, this);
2448  m_buttonOK->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(ReactiveShuntElementFormBase::OnOKButtonClick), NULL, this);
2449  m_buttonCancel->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(ReactiveShuntElementFormBase::OnCancelButtonClick), NULL, this);
2450 
2451 }
2452 
2453 ReactiveShuntElementFormBase::~ReactiveShuntElementFormBase()
2454 {
2455  m_buttonStabButton->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(ReactiveShuntElementFormBase::OnStabilityButtonClick), NULL, this);
2456  m_buttonOK->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(ReactiveShuntElementFormBase::OnOKButtonClick), NULL, this);
2457  m_buttonCancel->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(ReactiveShuntElementFormBase::OnCancelButtonClick), NULL, this);
2458 
2459 }
2460 
2461 SwitchingFormBase::SwitchingFormBase(wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style)
2462  : wxDialog(parent, id, title, pos, size, style)
2463 {
2464  if ( !bBitmapLoaded ) {
2465  // We need to initialise the default bitmap handler
2466  wxXmlResource::Get()->AddHandler(new wxBitmapXmlHandler);
2467  wxC9EE9InitBitmapResources();
2468  bBitmapLoaded = true;
2469  }
2470 
2471  wxBoxSizer* boxSizerLvl1_1 = new wxBoxSizer(wxVERTICAL);
2472  this->SetSizer(boxSizerLvl1_1);
2473 
2474  wxBoxSizer* boxSizerLvl2_1 = new wxBoxSizer(wxHORIZONTAL);
2475 
2476  boxSizerLvl1_1->Add(boxSizerLvl2_1, 0, wxALL, WXC_FROM_DIP(5));
2477 
2478  wxBoxSizer* boxSizerLvl3_1 = new wxBoxSizer(wxVERTICAL);
2479 
2480  boxSizerLvl2_1->Add(boxSizerLvl3_1, 0, wxALL|wxEXPAND, WXC_FROM_DIP(5));
2481 
2482  wxArrayString m_pgMgrSwitchingsPropArr;
2483  wxUnusedVar(m_pgMgrSwitchingsPropArr);
2484  wxArrayInt m_pgMgrSwitchingsPropIntArr;
2485  wxUnusedVar(m_pgMgrSwitchingsPropIntArr);
2486  m_pgMgrSwitchingsProp = new wxPropertyGridManager(this, wxID_ANY, wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), wxPG_STATIC_LAYOUT|wxPG_SPLITTER_AUTO_CENTER|wxPG_BOLD_MODIFIED);
2487 
2488  boxSizerLvl3_1->Add(m_pgMgrSwitchingsProp, 1, wxALL, WXC_FROM_DIP(5));
2489 
2490  m_pgPropTitle = m_pgMgrSwitchingsProp->Append( new wxPropertyCategory( _("Switching properties") ) );
2491  m_pgPropTitle->SetHelpString(wxT(""));
2492 
2493  m_pgMgrSwitchingsPropArr.Clear();
2494  m_pgMgrSwitchingsPropIntArr.Clear();
2495  m_pgMgrSwitchingsPropArr.Add(_("Insert"));
2496  m_pgMgrSwitchingsPropArr.Add(_("Remove"));
2497  m_pgPropType = m_pgMgrSwitchingsProp->Append( new wxEnumProperty( _("Type"), wxPG_LABEL, m_pgMgrSwitchingsPropArr, m_pgMgrSwitchingsPropIntArr, 0) );
2498  m_pgPropType->SetHelpString(wxT(""));
2499 
2500  m_pgPropTime = m_pgMgrSwitchingsProp->Append( new wxFloatProperty( _("Time (s)"), wxPG_LABEL, 0) );
2501  m_pgPropTime->SetHelpString(wxT(""));
2502  m_pgMgrSwitchingsProp->SetMinSize(wxSize(150,-1));
2503 
2504  wxBoxSizer* boxSizerLvl3_3 = new wxBoxSizer(wxVERTICAL);
2505 
2506  boxSizerLvl2_1->Add(boxSizerLvl3_3, 0, wxALL|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
2507 
2508  m_buttonInsert = new wxButton(this, wxID_ANY, _("Add"), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
2509 
2510  boxSizerLvl3_3->Add(m_buttonInsert, 0, wxALL|wxALIGN_RIGHT, WXC_FROM_DIP(5));
2511 
2512  m_buttonRemove = new wxButton(this, wxID_ANY, _("Remove"), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
2513 
2514  boxSizerLvl3_3->Add(m_buttonRemove, 0, wxALL|wxALIGN_RIGHT, WXC_FROM_DIP(5));
2515 
2516  m_buttonUp = new wxButton(this, wxID_ANY, _("Up"), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
2517 
2518  boxSizerLvl3_3->Add(m_buttonUp, 0, wxALL|wxALIGN_RIGHT, WXC_FROM_DIP(5));
2519 
2520  m_buttonDown = new wxButton(this, wxID_ANY, _("Down"), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
2521 
2522  boxSizerLvl3_3->Add(m_buttonDown, 0, wxALL|wxALIGN_RIGHT, WXC_FROM_DIP(5));
2523 
2524  wxBoxSizer* boxSizerLvl3_2 = new wxBoxSizer(wxVERTICAL);
2525 
2526  boxSizerLvl2_1->Add(boxSizerLvl3_2, 0, wxALL, WXC_FROM_DIP(5));
2527 
2528  m_staticTextSwList = new wxStaticText(this, wxID_ANY, _("Switching list"), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
2529 
2530  boxSizerLvl3_2->Add(m_staticTextSwList, 0, wxLEFT|wxRIGHT|wxTOP, WXC_FROM_DIP(5));
2531 
2532  m_listCtrlSwitchings = new wxListCtrl(this, wxID_ANY, wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), wxLC_REPORT);
2533 
2534  boxSizerLvl3_2->Add(m_listCtrlSwitchings, 0, wxLEFT|wxRIGHT|wxBOTTOM, WXC_FROM_DIP(5));
2535 
2536  wxBoxSizer* boxSizerBottomButtons = new wxBoxSizer(wxHORIZONTAL);
2537 
2538  boxSizerLvl1_1->Add(boxSizerBottomButtons, 0, wxALL|wxALIGN_RIGHT, WXC_FROM_DIP(5));
2539 
2540  m_buttonOK = new wxButton(this, wxID_ANY, _("OK"), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
2541 
2542  boxSizerBottomButtons->Add(m_buttonOK, 0, wxALL|wxALIGN_RIGHT, WXC_FROM_DIP(5));
2543 
2544  m_buttonCancel = new wxButton(this, wxID_ANY, _("Cancel"), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
2545 
2546  boxSizerBottomButtons->Add(m_buttonCancel, 0, wxALL|wxALIGN_RIGHT, WXC_FROM_DIP(5));
2547 
2548  SetName(wxT("SwitchingFormBase"));
2549  SetSize(-1,-1);
2550  if (GetSizer()) {
2551  GetSizer()->Fit(this);
2552  }
2553  if(GetParent()) {
2554  CentreOnParent(wxBOTH);
2555  } else {
2556  CentreOnScreen(wxBOTH);
2557  }
2558 #if wxVERSION_NUMBER >= 2900
2559  if(!wxPersistenceManager::Get().Find(this)) {
2560  wxPersistenceManager::Get().RegisterAndRestore(this);
2561  } else {
2562  wxPersistenceManager::Get().Restore(this);
2563  }
2564 #endif
2565  // Connect events
2566  m_pgMgrSwitchingsProp->Connect(wxEVT_PG_CHANGED, wxPropertyGridEventHandler(SwitchingFormBase::OnChangeProperties), NULL, this);
2567  m_buttonInsert->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(SwitchingFormBase::OnInsertButtonClick), NULL, this);
2568  m_buttonRemove->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(SwitchingFormBase::OnRemoveButtonClick), NULL, this);
2569  m_buttonUp->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(SwitchingFormBase::OnUpButtonClick), NULL, this);
2570  m_buttonDown->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(SwitchingFormBase::OnDownButtonClick), NULL, this);
2571  m_listCtrlSwitchings->Connect(wxEVT_COMMAND_LIST_ITEM_SELECTED, wxListEventHandler(SwitchingFormBase::OnSelectItem), NULL, this);
2572  m_buttonOK->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(SwitchingFormBase::OnOKButtonClick), NULL, this);
2573  m_buttonCancel->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(SwitchingFormBase::OnCancelButtonClick), NULL, this);
2574 
2575 }
2576 
2577 SwitchingFormBase::~SwitchingFormBase()
2578 {
2579  m_pgMgrSwitchingsProp->Disconnect(wxEVT_PG_CHANGED, wxPropertyGridEventHandler(SwitchingFormBase::OnChangeProperties), NULL, this);
2580  m_buttonInsert->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(SwitchingFormBase::OnInsertButtonClick), NULL, this);
2581  m_buttonRemove->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(SwitchingFormBase::OnRemoveButtonClick), NULL, this);
2582  m_buttonUp->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(SwitchingFormBase::OnUpButtonClick), NULL, this);
2583  m_buttonDown->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(SwitchingFormBase::OnDownButtonClick), NULL, this);
2584  m_listCtrlSwitchings->Disconnect(wxEVT_COMMAND_LIST_ITEM_SELECTED, wxListEventHandler(SwitchingFormBase::OnSelectItem), NULL, this);
2585  m_buttonOK->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(SwitchingFormBase::OnOKButtonClick), NULL, this);
2586  m_buttonCancel->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(SwitchingFormBase::OnCancelButtonClick), NULL, this);
2587 
2588 }
2589 
2590 IndMotorFormBase::IndMotorFormBase(wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style)
2591  : wxDialog(parent, id, title, pos, size, style)
2592 {
2593  if ( !bBitmapLoaded ) {
2594  // We need to initialise the default bitmap handler
2595  wxXmlResource::Get()->AddHandler(new wxBitmapXmlHandler);
2596  wxC9EE9InitBitmapResources();
2597  bBitmapLoaded = true;
2598  }
2599 
2600  wxBoxSizer* boxSizerLvl1_1 = new wxBoxSizer(wxVERTICAL);
2601  this->SetSizer(boxSizerLvl1_1);
2602 
2603  m_notebook = new wxNotebook(this, wxID_ANY, wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), wxBK_DEFAULT);
2604  m_notebook->SetName(wxT("m_notebook"));
2605 
2606  boxSizerLvl1_1->Add(m_notebook, 1, wxEXPAND, WXC_FROM_DIP(5));
2607 
2608  m_panelGeneral = new wxPanel(m_notebook, wxID_ANY, wxDefaultPosition, wxDLG_UNIT(m_notebook, wxSize(-1,-1)), wxTAB_TRAVERSAL);
2609  m_notebook->AddPage(m_panelGeneral, _("General"), false);
2610 
2611  wxBoxSizer* boxSizerLvl2_1 = new wxBoxSizer(wxVERTICAL);
2612  m_panelGeneral->SetSizer(boxSizerLvl2_1);
2613 
2614  m_staticTextName = new wxStaticText(m_panelGeneral, wxID_ANY, _("Name"), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
2615 
2616  boxSizerLvl2_1->Add(m_staticTextName, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
2617 
2618  m_textCtrlName = new wxTextCtrl(m_panelGeneral, wxID_ANY, wxT(""), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
2619  #if wxVERSION_NUMBER >= 3000
2620  m_textCtrlName->SetHint(wxT(""));
2621  #endif
2622 
2623  boxSizerLvl2_1->Add(m_textCtrlName, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxEXPAND|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
2624  m_textCtrlName->SetMinSize(wxSize(300,-1));
2625 
2626  wxGridSizer* gridSizerLvl3_1 = new wxGridSizer(0, 2, 0, 0);
2627 
2628  boxSizerLvl2_1->Add(gridSizerLvl3_1, 0, wxEXPAND, WXC_FROM_DIP(5));
2629 
2630  wxBoxSizer* boxSizerLvl4_1 = new wxBoxSizer(wxVERTICAL);
2631 
2632  gridSizerLvl3_1->Add(boxSizerLvl4_1, 0, wxEXPAND, WXC_FROM_DIP(5));
2633 
2634  m_staticTextActivePower = new wxStaticText(m_panelGeneral, wxID_ANY, _("Active power"), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
2635 
2636  boxSizerLvl4_1->Add(m_staticTextActivePower, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
2637 
2638  wxBoxSizer* boxSizerLvl5_1 = new wxBoxSizer(wxHORIZONTAL);
2639 
2640  boxSizerLvl4_1->Add(boxSizerLvl5_1, 0, wxEXPAND, WXC_FROM_DIP(5));
2641 
2642  m_textCtrlActivePower = new wxTextCtrl(m_panelGeneral, wxID_ANY, wxT(""), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
2643  #if wxVERSION_NUMBER >= 3000
2644  m_textCtrlActivePower->SetHint(wxT(""));
2645  #endif
2646 
2647  boxSizerLvl5_1->Add(m_textCtrlActivePower, 1, wxLEFT|wxRIGHT|wxBOTTOM|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
2648 
2649  wxArrayString m_choiceActivePowerArr;
2650  m_choiceActivePowerArr.Add(wxT("p.u."));
2651  m_choiceActivePowerArr.Add(wxT("W"));
2652  m_choiceActivePowerArr.Add(wxT("kW"));
2653  m_choiceActivePowerArr.Add(wxT("MW"));
2654  m_choiceActivePower = new wxChoice(m_panelGeneral, wxID_ANY, wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), m_choiceActivePowerArr, 0);
2655  m_choiceActivePower->SetSelection(3);
2656 
2657  boxSizerLvl5_1->Add(m_choiceActivePower, 0, wxLEFT|wxRIGHT|wxBOTTOM, WXC_FROM_DIP(5));
2658 
2659  wxBoxSizer* boxSizerLvl4_2 = new wxBoxSizer(wxVERTICAL);
2660 
2661  gridSizerLvl3_1->Add(boxSizerLvl4_2, 0, wxEXPAND, WXC_FROM_DIP(5));
2662 
2663  m_staticTextReactivePower = new wxStaticText(m_panelGeneral, wxID_ANY, _("Reactive power"), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
2664 
2665  boxSizerLvl4_2->Add(m_staticTextReactivePower, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
2666 
2667  wxBoxSizer* boxSizerLvl5_2 = new wxBoxSizer(wxHORIZONTAL);
2668 
2669  boxSizerLvl4_2->Add(boxSizerLvl5_2, 0, wxEXPAND, WXC_FROM_DIP(5));
2670 
2671  m_textCtrlReactivePower = new wxTextCtrl(m_panelGeneral, wxID_ANY, wxT(""), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
2672  #if wxVERSION_NUMBER >= 3000
2673  m_textCtrlReactivePower->SetHint(wxT(""));
2674  #endif
2675 
2676  boxSizerLvl5_2->Add(m_textCtrlReactivePower, 1, wxLEFT|wxRIGHT|wxBOTTOM|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
2677 
2678  wxArrayString m_choiceReactivePowerArr;
2679  m_choiceReactivePowerArr.Add(wxT("p.u."));
2680  m_choiceReactivePowerArr.Add(wxT("VAr"));
2681  m_choiceReactivePowerArr.Add(wxT("kVAr"));
2682  m_choiceReactivePowerArr.Add(wxT("MVAr"));
2683  m_choiceReactivePower = new wxChoice(m_panelGeneral, wxID_ANY, wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), m_choiceReactivePowerArr, 0);
2684  m_choiceReactivePower->SetSelection(3);
2685 
2686  boxSizerLvl5_2->Add(m_choiceReactivePower, 0, wxLEFT|wxRIGHT|wxBOTTOM, WXC_FROM_DIP(5));
2687 
2688  wxBoxSizer* boxSizerBottomButtons = new wxBoxSizer(wxHORIZONTAL);
2689 
2690  boxSizerLvl1_1->Add(boxSizerBottomButtons, 0, wxALL|wxEXPAND, WXC_FROM_DIP(5));
2691 
2692  m_buttonStabButton = new wxButton(this, wxID_ANY, _("Stability"), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
2693 
2694  boxSizerBottomButtons->Add(m_buttonStabButton, 0, wxALL|wxALIGN_LEFT, WXC_FROM_DIP(5));
2695 
2696  boxSizerBottomButtons->Add(0, 0, 1, wxALL, WXC_FROM_DIP(5));
2697 
2698  m_buttonOK = new wxButton(this, wxID_ANY, _("OK"), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
2699 
2700  boxSizerBottomButtons->Add(m_buttonOK, 0, wxALL|wxALIGN_RIGHT, WXC_FROM_DIP(5));
2701 
2702  m_ButtonCancel = new wxButton(this, wxID_ANY, _("Cancel"), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
2703 
2704  boxSizerBottomButtons->Add(m_ButtonCancel, 0, wxALL|wxALIGN_RIGHT, WXC_FROM_DIP(5));
2705 
2706 
2707  #if wxVERSION_NUMBER >= 2900
2708  if(!wxPersistenceManager::Get().Find(m_notebook)){
2709  wxPersistenceManager::Get().RegisterAndRestore(m_notebook);
2710  } else {
2711  wxPersistenceManager::Get().Restore(m_notebook);
2712  }
2713  #endif
2714 
2715  SetName(wxT("IndMotorFormBase"));
2716  SetSize(-1,-1);
2717  if (GetSizer()) {
2718  GetSizer()->Fit(this);
2719  }
2720  if(GetParent()) {
2721  CentreOnParent(wxBOTH);
2722  } else {
2723  CentreOnScreen(wxBOTH);
2724  }
2725 #if wxVERSION_NUMBER >= 2900
2726  if(!wxPersistenceManager::Get().Find(this)) {
2727  wxPersistenceManager::Get().RegisterAndRestore(this);
2728  } else {
2729  wxPersistenceManager::Get().Restore(this);
2730  }
2731 #endif
2732  // Connect events
2733  m_buttonStabButton->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(IndMotorFormBase::OnStabilityButtonClick), NULL, this);
2734  m_buttonOK->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(IndMotorFormBase::OnOKButtonClick), NULL, this);
2735  m_ButtonCancel->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(IndMotorFormBase::OnCancelButtonClick), NULL, this);
2736 
2737 }
2738 
2739 IndMotorFormBase::~IndMotorFormBase()
2740 {
2741  m_buttonStabButton->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(IndMotorFormBase::OnStabilityButtonClick), NULL, this);
2742  m_buttonOK->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(IndMotorFormBase::OnOKButtonClick), NULL, this);
2743  m_ButtonCancel->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(IndMotorFormBase::OnCancelButtonClick), NULL, this);
2744 
2745 }
2746 
2747 TextFormBase::TextFormBase(wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style)
2748  : wxDialog(parent, id, title, pos, size, style)
2749 {
2750  if ( !bBitmapLoaded ) {
2751  // We need to initialise the default bitmap handler
2752  wxXmlResource::Get()->AddHandler(new wxBitmapXmlHandler);
2753  wxC9EE9InitBitmapResources();
2754  bBitmapLoaded = true;
2755  }
2756 
2757  wxBoxSizer* boxSizerLvl1_1 = new wxBoxSizer(wxVERTICAL);
2758  this->SetSizer(boxSizerLvl1_1);
2759 
2760  m_notebook = new wxNotebook(this, wxID_ANY, wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), wxBK_DEFAULT);
2761  m_notebook->SetName(wxT("m_notebook"));
2762 
2763  boxSizerLvl1_1->Add(m_notebook, 1, wxEXPAND, WXC_FROM_DIP(5));
2764 
2765  m_panelGeneral = new wxPanel(m_notebook, wxID_ANY, wxDefaultPosition, wxDLG_UNIT(m_notebook, wxSize(-1,-1)), wxTAB_TRAVERSAL);
2766  m_notebook->AddPage(m_panelGeneral, _("General"), false);
2767 
2768  wxBoxSizer* boxSizerLvl2_1 = new wxBoxSizer(wxVERTICAL);
2769  m_panelGeneral->SetSizer(boxSizerLvl2_1);
2770 
2771  wxGridSizer* gridSizerLvl3_1 = new wxGridSizer(0, 3, 0, 0);
2772 
2773  boxSizerLvl2_1->Add(gridSizerLvl3_1, 0, wxEXPAND, WXC_FROM_DIP(5));
2774 
2775  wxBoxSizer* boxSizerLvl4_1 = new wxBoxSizer(wxVERTICAL);
2776 
2777  gridSizerLvl3_1->Add(boxSizerLvl4_1, 0, wxEXPAND, WXC_FROM_DIP(5));
2778 
2779  m_staticTextElement = new wxStaticText(m_panelGeneral, wxID_ANY, _("Element"), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
2780 
2781  boxSizerLvl4_1->Add(m_staticTextElement, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
2782 
2783  wxArrayString m_choiceElementArr;
2784  m_choiceElementArr.Add(wxT("Bus"));
2785  m_choiceElementArr.Add(wxT("Generator"));
2786  m_choiceElementArr.Add(wxT("Line"));
2787  m_choiceElementArr.Add(wxT("Transformer"));
2788  m_choiceElementArr.Add(wxT("Load"));
2789  m_choiceElementArr.Add(wxT("Capacitor"));
2790  m_choiceElementArr.Add(wxT("Inductor"));
2791  m_choiceElementArr.Add(wxT("Synchronous compensator"));
2792  m_choiceElementArr.Add(wxT("Induction motor"));
2793  m_choiceElement = new wxChoice(m_panelGeneral, wxID_ANY, wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), m_choiceElementArr, 0);
2794 
2795  boxSizerLvl4_1->Add(m_choiceElement, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxEXPAND, WXC_FROM_DIP(5));
2796 
2797  wxBoxSizer* boxSizerLvl4_2 = new wxBoxSizer(wxVERTICAL);
2798 
2799  gridSizerLvl3_1->Add(boxSizerLvl4_2, 0, wxEXPAND, WXC_FROM_DIP(5));
2800 
2801  m_staticTextName = new wxStaticText(m_panelGeneral, wxID_ANY, _("Element name"), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
2802 
2803  boxSizerLvl4_2->Add(m_staticTextName, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
2804 
2805  wxArrayString m_choiceNameArr;
2806  m_choiceName = new wxChoice(m_panelGeneral, wxID_ANY, wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), m_choiceNameArr, 0);
2807 
2808  boxSizerLvl4_2->Add(m_choiceName, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxEXPAND, WXC_FROM_DIP(5));
2809 
2810  wxBoxSizer* boxSizerLvl4_3 = new wxBoxSizer(wxVERTICAL);
2811 
2812  gridSizerLvl3_1->Add(boxSizerLvl4_3, 0, wxEXPAND, WXC_FROM_DIP(5));
2813 
2814  m_staticTextType = new wxStaticText(m_panelGeneral, wxID_ANY, _("Text type"), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
2815 
2816  boxSizerLvl4_3->Add(m_staticTextType, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
2817 
2818  wxArrayString m_choiceTextTypeArr;
2819  m_choiceTextType = new wxChoice(m_panelGeneral, wxID_ANY, wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), m_choiceTextTypeArr, 0);
2820 
2821  boxSizerLvl4_3->Add(m_choiceTextType, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxEXPAND, WXC_FROM_DIP(5));
2822 
2823  wxBoxSizer* boxSizerLvl4_4 = new wxBoxSizer(wxVERTICAL);
2824 
2825  gridSizerLvl3_1->Add(boxSizerLvl4_4, 0, wxEXPAND, WXC_FROM_DIP(5));
2826 
2827  m_staticTextFromBus = new wxStaticText(m_panelGeneral, wxID_ANY, _("From bus"), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
2828 
2829  boxSizerLvl4_4->Add(m_staticTextFromBus, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
2830 
2831  wxArrayString m_choiceTextFromBusArr;
2832  m_choiceTextFromBus = new wxChoice(m_panelGeneral, wxID_ANY, wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), m_choiceTextFromBusArr, 0);
2833 
2834  boxSizerLvl4_4->Add(m_choiceTextFromBus, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxEXPAND, WXC_FROM_DIP(5));
2835 
2836  wxBoxSizer* boxSizerLvl4_5 = new wxBoxSizer(wxVERTICAL);
2837 
2838  gridSizerLvl3_1->Add(boxSizerLvl4_5, 0, wxEXPAND, WXC_FROM_DIP(5));
2839 
2840  m_staticTextToBus = new wxStaticText(m_panelGeneral, wxID_ANY, _("To bus"), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
2841 
2842  boxSizerLvl4_5->Add(m_staticTextToBus, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
2843 
2844  wxArrayString m_choiceTextToBusArr;
2845  m_choiceTextToBus = new wxChoice(m_panelGeneral, wxID_ANY, wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), m_choiceTextToBusArr, 0);
2846 
2847  boxSizerLvl4_5->Add(m_choiceTextToBus, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxEXPAND, WXC_FROM_DIP(5));
2848 
2849  wxBoxSizer* boxSizerLvl4_6 = new wxBoxSizer(wxVERTICAL);
2850 
2851  gridSizerLvl3_1->Add(boxSizerLvl4_6, 0, wxEXPAND, WXC_FROM_DIP(5));
2852 
2853  m_staticTextUnit = new wxStaticText(m_panelGeneral, wxID_ANY, _("Unit"), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
2854 
2855  boxSizerLvl4_6->Add(m_staticTextUnit, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
2856 
2857  wxArrayString m_choiceTextUnitArr;
2858  m_choiceTextUnit = new wxChoice(m_panelGeneral, wxID_ANY, wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), m_choiceTextUnitArr, 0);
2859 
2860  boxSizerLvl4_6->Add(m_choiceTextUnit, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxEXPAND, WXC_FROM_DIP(5));
2861 
2862  wxBoxSizer* boxSizerLvl3_2 = new wxBoxSizer(wxHORIZONTAL);
2863 
2864  boxSizerLvl2_1->Add(boxSizerLvl3_2, 1, wxALL|wxEXPAND, WXC_FROM_DIP(5));
2865 
2866  m_staticTextDecimal = new wxStaticText(m_panelGeneral, wxID_ANY, _("Decimal places:"), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
2867 
2868  boxSizerLvl3_2->Add(m_staticTextDecimal, 0, wxALL|wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
2869 
2870  m_textCtrlDecimal = new wxTextCtrl(m_panelGeneral, wxID_ANY, wxT("2"), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), wxTE_PROCESS_ENTER);
2871  #if wxVERSION_NUMBER >= 3000
2872  m_textCtrlDecimal->SetHint(wxT(""));
2873  #endif
2874 
2875  boxSizerLvl3_2->Add(m_textCtrlDecimal, 0, wxALL|wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
2876 
2877  boxSizerLvl3_2->Add(0, 0, 0, wxALL, WXC_FROM_DIP(5));
2878 
2879  m_staticTextPreview = new wxStaticText(m_panelGeneral, wxID_ANY, _("Preview:"), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
2880 
2881  boxSizerLvl3_2->Add(m_staticTextPreview, 0, wxALL|wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
2882 
2883  m_textCtrlPreview = new wxTextCtrl(m_panelGeneral, wxID_ANY, wxT(""), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), wxTE_CENTRE);
2884  #if wxVERSION_NUMBER >= 3000
2885  m_textCtrlPreview->SetHint(wxT(""));
2886  #endif
2887 
2888  boxSizerLvl3_2->Add(m_textCtrlPreview, 1, wxALL|wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
2889 
2890  wxBoxSizer* boxSizerBottomButtons = new wxBoxSizer(wxHORIZONTAL);
2891 
2892  boxSizerLvl1_1->Add(boxSizerBottomButtons, 0, wxALL|wxEXPAND, WXC_FROM_DIP(5));
2893 
2894  boxSizerBottomButtons->Add(0, 0, 1, wxALL, WXC_FROM_DIP(5));
2895 
2896  m_buttonOK = new wxButton(this, wxID_ANY, _("OK"), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
2897 
2898  boxSizerBottomButtons->Add(m_buttonOK, 0, wxALL|wxALIGN_RIGHT, WXC_FROM_DIP(5));
2899 
2900  m_ButtonCancel = new wxButton(this, wxID_ANY, _("Cancel"), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
2901 
2902  boxSizerBottomButtons->Add(m_ButtonCancel, 0, wxALL|wxALIGN_RIGHT, WXC_FROM_DIP(5));
2903 
2904 
2905  #if wxVERSION_NUMBER >= 2900
2906  if(!wxPersistenceManager::Get().Find(m_notebook)){
2907  wxPersistenceManager::Get().RegisterAndRestore(m_notebook);
2908  } else {
2909  wxPersistenceManager::Get().Restore(m_notebook);
2910  }
2911  #endif
2912 
2913  SetName(wxT("TextFormBase"));
2914  SetSize(-1,-1);
2915  if (GetSizer()) {
2916  GetSizer()->Fit(this);
2917  }
2918  if(GetParent()) {
2919  CentreOnParent(wxBOTH);
2920  } else {
2921  CentreOnScreen(wxBOTH);
2922  }
2923 #if wxVERSION_NUMBER >= 2900
2924  if(!wxPersistenceManager::Get().Find(this)) {
2925  wxPersistenceManager::Get().RegisterAndRestore(this);
2926  } else {
2927  wxPersistenceManager::Get().Restore(this);
2928  }
2929 #endif
2930  // Connect events
2931  m_choiceElement->Connect(wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler(TextFormBase::OnElementChoiceSelected), NULL, this);
2932  m_choiceName->Connect(wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler(TextFormBase::OnNameChoiceSelected), NULL, this);
2933  m_choiceTextType->Connect(wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler(TextFormBase::OnTypeChoiceSelected), NULL, this);
2934  m_choiceTextFromBus->Connect(wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler(TextFormBase::OnFromBusChoiceSelected), NULL, this);
2935  m_choiceTextToBus->Connect(wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler(TextFormBase::OnToBusChoiceSelected), NULL, this);
2936  m_choiceTextUnit->Connect(wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler(TextFormBase::OnUnitChoiceSelected), NULL, this);
2937  m_textCtrlDecimal->Connect(wxEVT_COMMAND_TEXT_ENTER, wxCommandEventHandler(TextFormBase::OnTextEnter), NULL, this);
2938  m_buttonOK->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(TextFormBase::OnOKButtonClick), NULL, this);
2939  m_ButtonCancel->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(TextFormBase::OnCancelButtonClick), NULL, this);
2940 
2941 }
2942 
2943 TextFormBase::~TextFormBase()
2944 {
2945  m_choiceElement->Disconnect(wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler(TextFormBase::OnElementChoiceSelected), NULL, this);
2946  m_choiceName->Disconnect(wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler(TextFormBase::OnNameChoiceSelected), NULL, this);
2947  m_choiceTextType->Disconnect(wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler(TextFormBase::OnTypeChoiceSelected), NULL, this);
2948  m_choiceTextFromBus->Disconnect(wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler(TextFormBase::OnFromBusChoiceSelected), NULL, this);
2949  m_choiceTextToBus->Disconnect(wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler(TextFormBase::OnToBusChoiceSelected), NULL, this);
2950  m_choiceTextUnit->Disconnect(wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler(TextFormBase::OnUnitChoiceSelected), NULL, this);
2951  m_textCtrlDecimal->Disconnect(wxEVT_COMMAND_TEXT_ENTER, wxCommandEventHandler(TextFormBase::OnTextEnter), NULL, this);
2952  m_buttonOK->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(TextFormBase::OnOKButtonClick), NULL, this);
2953  m_ButtonCancel->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(TextFormBase::OnCancelButtonClick), NULL, this);
2954 
2955 }
2956 
2957 TransferFunctionFormBase::TransferFunctionFormBase(wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style)
2958  : wxDialog(parent, id, title, pos, size, style)
2959 {
2960  if ( !bBitmapLoaded ) {
2961  // We need to initialise the default bitmap handler
2962  wxXmlResource::Get()->AddHandler(new wxBitmapXmlHandler);
2963  wxC9EE9InitBitmapResources();
2964  bBitmapLoaded = true;
2965  }
2966 
2967  wxBoxSizer* boxSizerLvl1_1 = new wxBoxSizer(wxVERTICAL);
2968  this->SetSizer(boxSizerLvl1_1);
2969 
2970  m_notebook = new wxNotebook(this, wxID_ANY, wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), wxBK_DEFAULT);
2971  m_notebook->SetName(wxT("m_notebook"));
2972 
2973  boxSizerLvl1_1->Add(m_notebook, 1, wxEXPAND, WXC_FROM_DIP(5));
2974 
2975  m_panelGeneral = new wxPanel(m_notebook, wxID_ANY, wxDefaultPosition, wxDLG_UNIT(m_notebook, wxSize(-1,-1)), wxTAB_TRAVERSAL);
2976  m_notebook->AddPage(m_panelGeneral, _("General"), false);
2977 
2978  wxBoxSizer* boxSizerLvl2_1 = new wxBoxSizer(wxVERTICAL);
2979  m_panelGeneral->SetSizer(boxSizerLvl2_1);
2980 
2981  m_staticTextNumerator = new wxStaticText(m_panelGeneral, wxID_ANY, _("Numerator parameters"), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
2982 
2983  boxSizerLvl2_1->Add(m_staticTextNumerator, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
2984 
2985  m_textCtrlNumerator = new wxTextCtrl(m_panelGeneral, wxID_ANY, wxT(""), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
2986  #if wxVERSION_NUMBER >= 3000
2987  m_textCtrlNumerator->SetHint(wxT(""));
2988  #endif
2989 
2990  boxSizerLvl2_1->Add(m_textCtrlNumerator, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxEXPAND|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
2991  m_textCtrlNumerator->SetMinSize(wxSize(300,-1));
2992 
2993  m_staticTextDenominator = new wxStaticText(m_panelGeneral, wxID_ANY, _("Denominator parameters"), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
2994 
2995  boxSizerLvl2_1->Add(m_staticTextDenominator, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
2996 
2997  m_textCtrlDenominator = new wxTextCtrl(m_panelGeneral, wxID_ANY, wxT(""), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
2998  #if wxVERSION_NUMBER >= 3000
2999  m_textCtrlDenominator->SetHint(wxT(""));
3000  #endif
3001 
3002  boxSizerLvl2_1->Add(m_textCtrlDenominator, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxEXPAND|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
3003  m_textCtrlDenominator->SetMinSize(wxSize(300,-1));
3004 
3005  wxBoxSizer* boxSizerBottomButtons = new wxBoxSizer(wxHORIZONTAL);
3006 
3007  boxSizerLvl1_1->Add(boxSizerBottomButtons, 0, wxALL|wxEXPAND, WXC_FROM_DIP(5));
3008 
3009  boxSizerBottomButtons->Add(0, 0, 1, wxALL, WXC_FROM_DIP(5));
3010 
3011  m_buttonOK = new wxButton(this, wxID_ANY, _("OK"), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
3012 
3013  boxSizerBottomButtons->Add(m_buttonOK, 0, wxALL|wxALIGN_RIGHT, WXC_FROM_DIP(5));
3014 
3015  m_ButtonCancel = new wxButton(this, wxID_ANY, _("Cancel"), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
3016 
3017  boxSizerBottomButtons->Add(m_ButtonCancel, 0, wxALL|wxALIGN_RIGHT, WXC_FROM_DIP(5));
3018 
3019 
3020  #if wxVERSION_NUMBER >= 2900
3021  if(!wxPersistenceManager::Get().Find(m_notebook)){
3022  wxPersistenceManager::Get().RegisterAndRestore(m_notebook);
3023  } else {
3024  wxPersistenceManager::Get().Restore(m_notebook);
3025  }
3026  #endif
3027 
3028  SetName(wxT("TransferFunctionFormBase"));
3029  SetSize(-1,-1);
3030  if (GetSizer()) {
3031  GetSizer()->Fit(this);
3032  }
3033  if(GetParent()) {
3034  CentreOnParent(wxBOTH);
3035  } else {
3036  CentreOnScreen(wxBOTH);
3037  }
3038 #if wxVERSION_NUMBER >= 2900
3039  if(!wxPersistenceManager::Get().Find(this)) {
3040  wxPersistenceManager::Get().RegisterAndRestore(this);
3041  } else {
3042  wxPersistenceManager::Get().Restore(this);
3043  }
3044 #endif
3045  // Connect events
3046  m_buttonOK->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(TransferFunctionFormBase::OnOKClick), NULL, this);
3047  m_ButtonCancel->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(TransferFunctionFormBase::OnCancelClick), NULL, this);
3048 
3049 }
3050 
3051 TransferFunctionFormBase::~TransferFunctionFormBase()
3052 {
3053  m_buttonOK->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(TransferFunctionFormBase::OnOKClick), NULL, this);
3054  m_ButtonCancel->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(TransferFunctionFormBase::OnCancelClick), NULL, this);
3055 
3056 }
3057 
3058 SumFormBase::SumFormBase(wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style)
3059  : wxDialog(parent, id, title, pos, size, style)
3060 {
3061  if ( !bBitmapLoaded ) {
3062  // We need to initialise the default bitmap handler
3063  wxXmlResource::Get()->AddHandler(new wxBitmapXmlHandler);
3064  wxC9EE9InitBitmapResources();
3065  bBitmapLoaded = true;
3066  }
3067 
3068  wxBoxSizer* boxSizerLvl1_1 = new wxBoxSizer(wxVERTICAL);
3069  this->SetSizer(boxSizerLvl1_1);
3070 
3071  m_notebook = new wxNotebook(this, wxID_ANY, wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), wxBK_DEFAULT);
3072  m_notebook->SetName(wxT("m_notebook"));
3073 
3074  boxSizerLvl1_1->Add(m_notebook, 1, wxEXPAND, WXC_FROM_DIP(5));
3075 
3076  m_panelGeneral = new wxPanel(m_notebook, wxID_ANY, wxDefaultPosition, wxDLG_UNIT(m_notebook, wxSize(-1,-1)), wxTAB_TRAVERSAL);
3077  m_notebook->AddPage(m_panelGeneral, _("General"), false);
3078 
3079  wxBoxSizer* boxSizerLvl2_1 = new wxBoxSizer(wxVERTICAL);
3080  m_panelGeneral->SetSizer(boxSizerLvl2_1);
3081 
3082  m_staticTextSigns = new wxStaticText(m_panelGeneral, wxID_ANY, _("Signs"), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
3083 
3084  boxSizerLvl2_1->Add(m_staticTextSigns, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
3085 
3086  m_textCtrlSigns = new wxTextCtrl(m_panelGeneral, wxID_ANY, wxT(""), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
3087  #if wxVERSION_NUMBER >= 3000
3088  m_textCtrlSigns->SetHint(wxT(""));
3089  #endif
3090 
3091  boxSizerLvl2_1->Add(m_textCtrlSigns, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxEXPAND|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
3092  m_textCtrlSigns->SetMinSize(wxSize(300,-1));
3093 
3094  wxBoxSizer* boxSizerBottomButtons = new wxBoxSizer(wxHORIZONTAL);
3095 
3096  boxSizerLvl1_1->Add(boxSizerBottomButtons, 0, wxALL|wxEXPAND, WXC_FROM_DIP(5));
3097 
3098  boxSizerBottomButtons->Add(0, 0, 1, wxALL, WXC_FROM_DIP(5));
3099 
3100  m_buttonOK = new wxButton(this, wxID_ANY, _("OK"), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
3101 
3102  boxSizerBottomButtons->Add(m_buttonOK, 0, wxALL|wxALIGN_RIGHT, WXC_FROM_DIP(5));
3103 
3104  m_ButtonCancel = new wxButton(this, wxID_ANY, _("Cancel"), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
3105 
3106  boxSizerBottomButtons->Add(m_ButtonCancel, 0, wxALL|wxALIGN_RIGHT, WXC_FROM_DIP(5));
3107 
3108 
3109  #if wxVERSION_NUMBER >= 2900
3110  if(!wxPersistenceManager::Get().Find(m_notebook)){
3111  wxPersistenceManager::Get().RegisterAndRestore(m_notebook);
3112  } else {
3113  wxPersistenceManager::Get().Restore(m_notebook);
3114  }
3115  #endif
3116 
3117  SetName(wxT("SumFormBase"));
3118  SetSize(-1,-1);
3119  if (GetSizer()) {
3120  GetSizer()->Fit(this);
3121  }
3122  if(GetParent()) {
3123  CentreOnParent(wxBOTH);
3124  } else {
3125  CentreOnScreen(wxBOTH);
3126  }
3127 #if wxVERSION_NUMBER >= 2900
3128  if(!wxPersistenceManager::Get().Find(this)) {
3129  wxPersistenceManager::Get().RegisterAndRestore(this);
3130  } else {
3131  wxPersistenceManager::Get().Restore(this);
3132  }
3133 #endif
3134  // Connect events
3135  m_buttonOK->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(SumFormBase::OnOKClick), NULL, this);
3136  m_ButtonCancel->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(SumFormBase::OnCancelClick), NULL, this);
3137 
3138 }
3139 
3140 SumFormBase::~SumFormBase()
3141 {
3142  m_buttonOK->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(SumFormBase::OnOKClick), NULL, this);
3143  m_ButtonCancel->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(SumFormBase::OnCancelClick), NULL, this);
3144 
3145 }
3146 
3147 LimiterFormBase::LimiterFormBase(wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style)
3148  : wxDialog(parent, id, title, pos, size, style)
3149 {
3150  if ( !bBitmapLoaded ) {
3151  // We need to initialise the default bitmap handler
3152  wxXmlResource::Get()->AddHandler(new wxBitmapXmlHandler);
3153  wxC9EE9InitBitmapResources();
3154  bBitmapLoaded = true;
3155  }
3156 
3157  wxBoxSizer* boxSizerLvl1_1 = new wxBoxSizer(wxVERTICAL);
3158  this->SetSizer(boxSizerLvl1_1);
3159 
3160  m_notebook = new wxNotebook(this, wxID_ANY, wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), wxBK_DEFAULT);
3161  m_notebook->SetName(wxT("m_notebook"));
3162 
3163  boxSizerLvl1_1->Add(m_notebook, 1, wxEXPAND, WXC_FROM_DIP(5));
3164 
3165  m_panelGeneral = new wxPanel(m_notebook, wxID_ANY, wxDefaultPosition, wxDLG_UNIT(m_notebook, wxSize(-1,-1)), wxTAB_TRAVERSAL);
3166  m_notebook->AddPage(m_panelGeneral, _("General"), false);
3167 
3168  wxBoxSizer* boxSizerLvl2_1 = new wxBoxSizer(wxVERTICAL);
3169  m_panelGeneral->SetSizer(boxSizerLvl2_1);
3170 
3171  m_staticTextUpLimiter = new wxStaticText(m_panelGeneral, wxID_ANY, _("Upper limit"), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
3172 
3173  boxSizerLvl2_1->Add(m_staticTextUpLimiter, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
3174 
3175  m_textCtrlUpLimit = new wxTextCtrl(m_panelGeneral, wxID_ANY, wxT(""), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
3176  #if wxVERSION_NUMBER >= 3000
3177  m_textCtrlUpLimit->SetHint(wxT(""));
3178  #endif
3179 
3180  boxSizerLvl2_1->Add(m_textCtrlUpLimit, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxEXPAND|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
3181  m_textCtrlUpLimit->SetMinSize(wxSize(100,-1));
3182 
3183  m_staticTextLowLimit = new wxStaticText(m_panelGeneral, wxID_ANY, _("Lower limit"), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
3184 
3185  boxSizerLvl2_1->Add(m_staticTextLowLimit, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
3186 
3187  m_textCtrlLowLimit = new wxTextCtrl(m_panelGeneral, wxID_ANY, wxT(""), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
3188  #if wxVERSION_NUMBER >= 3000
3189  m_textCtrlLowLimit->SetHint(wxT(""));
3190  #endif
3191 
3192  boxSizerLvl2_1->Add(m_textCtrlLowLimit, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxEXPAND|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
3193  m_textCtrlLowLimit->SetMinSize(wxSize(100,-1));
3194 
3195  wxBoxSizer* boxSizerBottomButtons = new wxBoxSizer(wxHORIZONTAL);
3196 
3197  boxSizerLvl1_1->Add(boxSizerBottomButtons, 0, wxALL|wxEXPAND, WXC_FROM_DIP(5));
3198 
3199  boxSizerBottomButtons->Add(0, 0, 1, wxALL, WXC_FROM_DIP(5));
3200 
3201  m_buttonOK = new wxButton(this, wxID_ANY, _("OK"), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
3202 
3203  boxSizerBottomButtons->Add(m_buttonOK, 0, wxALL|wxALIGN_RIGHT, WXC_FROM_DIP(5));
3204 
3205  m_ButtonCancel = new wxButton(this, wxID_ANY, _("Cancel"), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
3206 
3207  boxSizerBottomButtons->Add(m_ButtonCancel, 0, wxALL|wxALIGN_RIGHT, WXC_FROM_DIP(5));
3208 
3209 
3210  #if wxVERSION_NUMBER >= 2900
3211  if(!wxPersistenceManager::Get().Find(m_notebook)){
3212  wxPersistenceManager::Get().RegisterAndRestore(m_notebook);
3213  } else {
3214  wxPersistenceManager::Get().Restore(m_notebook);
3215  }
3216  #endif
3217 
3218  SetName(wxT("LimiterFormBase"));
3219  SetSize(-1,-1);
3220  if (GetSizer()) {
3221  GetSizer()->Fit(this);
3222  }
3223  if(GetParent()) {
3224  CentreOnParent(wxBOTH);
3225  } else {
3226  CentreOnScreen(wxBOTH);
3227  }
3228 #if wxVERSION_NUMBER >= 2900
3229  if(!wxPersistenceManager::Get().Find(this)) {
3230  wxPersistenceManager::Get().RegisterAndRestore(this);
3231  } else {
3232  wxPersistenceManager::Get().Restore(this);
3233  }
3234 #endif
3235  // Connect events
3236  m_buttonOK->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(LimiterFormBase::OnOKButtonClick), NULL, this);
3237  m_ButtonCancel->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(LimiterFormBase::OnCancelButtonClick), NULL, this);
3238 
3239 }
3240 
3241 LimiterFormBase::~LimiterFormBase()
3242 {
3243  m_buttonOK->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(LimiterFormBase::OnOKButtonClick), NULL, this);
3244  m_ButtonCancel->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(LimiterFormBase::OnCancelButtonClick), NULL, this);
3245 
3246 }
3247 
3248 RateLimiterFormBase::RateLimiterFormBase(wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style)
3249  : wxDialog(parent, id, title, pos, size, style)
3250 {
3251  if ( !bBitmapLoaded ) {
3252  // We need to initialise the default bitmap handler
3253  wxXmlResource::Get()->AddHandler(new wxBitmapXmlHandler);
3254  wxC9EE9InitBitmapResources();
3255  bBitmapLoaded = true;
3256  }
3257 
3258  wxBoxSizer* boxSizerLvl1_1 = new wxBoxSizer(wxVERTICAL);
3259  this->SetSizer(boxSizerLvl1_1);
3260 
3261  m_notebook = new wxNotebook(this, wxID_ANY, wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), wxBK_DEFAULT);
3262  m_notebook->SetName(wxT("m_notebook"));
3263 
3264  boxSizerLvl1_1->Add(m_notebook, 1, wxEXPAND, WXC_FROM_DIP(5));
3265 
3266  m_panelGeneral = new wxPanel(m_notebook, wxID_ANY, wxDefaultPosition, wxDLG_UNIT(m_notebook, wxSize(-1,-1)), wxTAB_TRAVERSAL);
3267  m_notebook->AddPage(m_panelGeneral, _("General"), false);
3268 
3269  wxBoxSizer* boxSizerLvl2_1 = new wxBoxSizer(wxVERTICAL);
3270  m_panelGeneral->SetSizer(boxSizerLvl2_1);
3271 
3272  m_staticTextUpLimiter = new wxStaticText(m_panelGeneral, wxID_ANY, _("Upper limit"), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
3273 
3274  boxSizerLvl2_1->Add(m_staticTextUpLimiter, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
3275 
3276  m_textCtrlUpLimit = new wxTextCtrl(m_panelGeneral, wxID_ANY, wxT(""), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
3277  #if wxVERSION_NUMBER >= 3000
3278  m_textCtrlUpLimit->SetHint(wxT(""));
3279  #endif
3280 
3281  boxSizerLvl2_1->Add(m_textCtrlUpLimit, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxEXPAND|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
3282  m_textCtrlUpLimit->SetMinSize(wxSize(100,-1));
3283 
3284  m_staticTextLowLimit = new wxStaticText(m_panelGeneral, wxID_ANY, _("Lower limit"), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
3285 
3286  boxSizerLvl2_1->Add(m_staticTextLowLimit, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
3287 
3288  m_textCtrlLowLimit = new wxTextCtrl(m_panelGeneral, wxID_ANY, wxT(""), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
3289  #if wxVERSION_NUMBER >= 3000
3290  m_textCtrlLowLimit->SetHint(wxT(""));
3291  #endif
3292 
3293  boxSizerLvl2_1->Add(m_textCtrlLowLimit, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxEXPAND|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
3294  m_textCtrlLowLimit->SetMinSize(wxSize(100,-1));
3295 
3296  wxBoxSizer* boxSizerBottomButtons = new wxBoxSizer(wxHORIZONTAL);
3297 
3298  boxSizerLvl1_1->Add(boxSizerBottomButtons, 0, wxALL|wxEXPAND, WXC_FROM_DIP(5));
3299 
3300  boxSizerBottomButtons->Add(0, 0, 1, wxALL, WXC_FROM_DIP(5));
3301 
3302  m_buttonOK = new wxButton(this, wxID_ANY, _("OK"), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
3303 
3304  boxSizerBottomButtons->Add(m_buttonOK, 0, wxALL|wxALIGN_RIGHT, WXC_FROM_DIP(5));
3305 
3306  m_ButtonCancel = new wxButton(this, wxID_ANY, _("Cancel"), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
3307 
3308  boxSizerBottomButtons->Add(m_ButtonCancel, 0, wxALL|wxALIGN_RIGHT, WXC_FROM_DIP(5));
3309 
3310 
3311  #if wxVERSION_NUMBER >= 2900
3312  if(!wxPersistenceManager::Get().Find(m_notebook)){
3313  wxPersistenceManager::Get().RegisterAndRestore(m_notebook);
3314  } else {
3315  wxPersistenceManager::Get().Restore(m_notebook);
3316  }
3317  #endif
3318 
3319  SetName(wxT("RateLimiterFormBase"));
3320  SetSize(-1,-1);
3321  if (GetSizer()) {
3322  GetSizer()->Fit(this);
3323  }
3324  if(GetParent()) {
3325  CentreOnParent(wxBOTH);
3326  } else {
3327  CentreOnScreen(wxBOTH);
3328  }
3329 #if wxVERSION_NUMBER >= 2900
3330  if(!wxPersistenceManager::Get().Find(this)) {
3331  wxPersistenceManager::Get().RegisterAndRestore(this);
3332  } else {
3333  wxPersistenceManager::Get().Restore(this);
3334  }
3335 #endif
3336  // Connect events
3337  m_buttonOK->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(RateLimiterFormBase::OnOKButtonClick), NULL, this);
3338  m_ButtonCancel->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(RateLimiterFormBase::OnCancelButtonClick), NULL, this);
3339 
3340 }
3341 
3342 RateLimiterFormBase::~RateLimiterFormBase()
3343 {
3344  m_buttonOK->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(RateLimiterFormBase::OnOKButtonClick), NULL, this);
3345  m_ButtonCancel->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(RateLimiterFormBase::OnCancelButtonClick), NULL, this);
3346 
3347 }
3348 
3349 ExponentialFormBase::ExponentialFormBase(wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style)
3350  : wxDialog(parent, id, title, pos, size, style)
3351 {
3352  if ( !bBitmapLoaded ) {
3353  // We need to initialise the default bitmap handler
3354  wxXmlResource::Get()->AddHandler(new wxBitmapXmlHandler);
3355  wxC9EE9InitBitmapResources();
3356  bBitmapLoaded = true;
3357  }
3358 
3359  wxBoxSizer* boxSizerLvl1_1 = new wxBoxSizer(wxVERTICAL);
3360  this->SetSizer(boxSizerLvl1_1);
3361 
3362  m_notebook = new wxNotebook(this, wxID_ANY, wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), wxBK_DEFAULT);
3363  m_notebook->SetName(wxT("m_notebook"));
3364 
3365  boxSizerLvl1_1->Add(m_notebook, 1, wxEXPAND, WXC_FROM_DIP(5));
3366 
3367  m_panelGeneral = new wxPanel(m_notebook, wxID_ANY, wxDefaultPosition, wxDLG_UNIT(m_notebook, wxSize(-1,-1)), wxTAB_TRAVERSAL);
3368  m_notebook->AddPage(m_panelGeneral, _("General"), false);
3369 
3370  wxBoxSizer* boxSizerLvl2_1 = new wxBoxSizer(wxVERTICAL);
3371  m_panelGeneral->SetSizer(boxSizerLvl2_1);
3372 
3373  m_staticTextExp = new wxStaticText(m_panelGeneral, wxID_ANY, _("y = A.eB.x"), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), wxALIGN_CENTRE);
3374 
3375  boxSizerLvl2_1->Add(m_staticTextExp, 1, wxLEFT|wxRIGHT|wxTOP|wxEXPAND|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
3376 
3377  m_staticTextAValue = new wxStaticText(m_panelGeneral, wxID_ANY, _("A value"), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
3378 
3379  boxSizerLvl2_1->Add(m_staticTextAValue, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
3380 
3381  m_textCtrlAValue = new wxTextCtrl(m_panelGeneral, wxID_ANY, wxT(""), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
3382  #if wxVERSION_NUMBER >= 3000
3383  m_textCtrlAValue->SetHint(wxT(""));
3384  #endif
3385 
3386  boxSizerLvl2_1->Add(m_textCtrlAValue, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxEXPAND|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
3387  m_textCtrlAValue->SetMinSize(wxSize(100,-1));
3388 
3389  m_staticTextBValue = new wxStaticText(m_panelGeneral, wxID_ANY, _("B value"), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
3390 
3391  boxSizerLvl2_1->Add(m_staticTextBValue, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
3392 
3393  m_textCtrlBValue = new wxTextCtrl(m_panelGeneral, wxID_ANY, wxT(""), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
3394  #if wxVERSION_NUMBER >= 3000
3395  m_textCtrlBValue->SetHint(wxT(""));
3396  #endif
3397 
3398  boxSizerLvl2_1->Add(m_textCtrlBValue, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxEXPAND|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
3399  m_textCtrlBValue->SetMinSize(wxSize(100,-1));
3400 
3401  wxBoxSizer* boxSizerBottomButtons = new wxBoxSizer(wxHORIZONTAL);
3402 
3403  boxSizerLvl1_1->Add(boxSizerBottomButtons, 0, wxALL|wxEXPAND, WXC_FROM_DIP(5));
3404 
3405  boxSizerBottomButtons->Add(0, 0, 1, wxALL, WXC_FROM_DIP(5));
3406 
3407  m_buttonOK = new wxButton(this, wxID_ANY, _("OK"), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
3408 
3409  boxSizerBottomButtons->Add(m_buttonOK, 0, wxALL|wxALIGN_RIGHT, WXC_FROM_DIP(5));
3410 
3411  m_buttonCancel = new wxButton(this, wxID_ANY, _("Cancel"), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
3412 
3413  boxSizerBottomButtons->Add(m_buttonCancel, 0, wxALL|wxALIGN_RIGHT, WXC_FROM_DIP(5));
3414 
3415 
3416  #if wxVERSION_NUMBER >= 2900
3417  if(!wxPersistenceManager::Get().Find(m_notebook)){
3418  wxPersistenceManager::Get().RegisterAndRestore(m_notebook);
3419  } else {
3420  wxPersistenceManager::Get().Restore(m_notebook);
3421  }
3422  #endif
3423 
3424  SetName(wxT("ExponentialFormBase"));
3425  SetSize(-1,-1);
3426  if (GetSizer()) {
3427  GetSizer()->Fit(this);
3428  }
3429  if(GetParent()) {
3430  CentreOnParent(wxBOTH);
3431  } else {
3432  CentreOnScreen(wxBOTH);
3433  }
3434 #if wxVERSION_NUMBER >= 2900
3435  if(!wxPersistenceManager::Get().Find(this)) {
3436  wxPersistenceManager::Get().RegisterAndRestore(this);
3437  } else {
3438  wxPersistenceManager::Get().Restore(this);
3439  }
3440 #endif
3441  // Connect events
3442  m_buttonOK->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(ExponentialFormBase::OnOKButtonClick), NULL, this);
3443  m_buttonCancel->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(ExponentialFormBase::OnCancelButtonClick), NULL, this);
3444 
3445 }
3446 
3447 ExponentialFormBase::~ExponentialFormBase()
3448 {
3449  m_buttonOK->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(ExponentialFormBase::OnOKButtonClick), NULL, this);
3450  m_buttonCancel->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(ExponentialFormBase::OnCancelButtonClick), NULL, this);
3451 
3452 }
3453 
3454 ConstantFormBase::ConstantFormBase(wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style)
3455  : wxDialog(parent, id, title, pos, size, style)
3456 {
3457  if ( !bBitmapLoaded ) {
3458  // We need to initialise the default bitmap handler
3459  wxXmlResource::Get()->AddHandler(new wxBitmapXmlHandler);
3460  wxC9EE9InitBitmapResources();
3461  bBitmapLoaded = true;
3462  }
3463 
3464  wxBoxSizer* boxSizerLvl1_1 = new wxBoxSizer(wxVERTICAL);
3465  this->SetSizer(boxSizerLvl1_1);
3466 
3467  m_notebook = new wxNotebook(this, wxID_ANY, wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), wxBK_DEFAULT);
3468  m_notebook->SetName(wxT("m_notebook"));
3469 
3470  boxSizerLvl1_1->Add(m_notebook, 1, wxEXPAND, WXC_FROM_DIP(5));
3471 
3472  m_panelGeneral = new wxPanel(m_notebook, wxID_ANY, wxDefaultPosition, wxDLG_UNIT(m_notebook, wxSize(-1,-1)), wxTAB_TRAVERSAL);
3473  m_notebook->AddPage(m_panelGeneral, _("General"), false);
3474 
3475  wxBoxSizer* boxSizerLvl2_1 = new wxBoxSizer(wxVERTICAL);
3476  m_panelGeneral->SetSizer(boxSizerLvl2_1);
3477 
3478  m_staticTextValue = new wxStaticText(m_panelGeneral, wxID_ANY, _("Constant value"), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
3479 
3480  boxSizerLvl2_1->Add(m_staticTextValue, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
3481 
3482  m_textCtrlValue = new wxTextCtrl(m_panelGeneral, wxID_ANY, wxT(""), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
3483  #if wxVERSION_NUMBER >= 3000
3484  m_textCtrlValue->SetHint(wxT(""));
3485  #endif
3486 
3487  boxSizerLvl2_1->Add(m_textCtrlValue, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxEXPAND|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
3488  m_textCtrlValue->SetMinSize(wxSize(100,-1));
3489 
3490  wxBoxSizer* boxSizerBottomButtons = new wxBoxSizer(wxHORIZONTAL);
3491 
3492  boxSizerLvl1_1->Add(boxSizerBottomButtons, 0, wxALL|wxEXPAND, WXC_FROM_DIP(5));
3493 
3494  boxSizerBottomButtons->Add(0, 0, 1, wxALL, WXC_FROM_DIP(5));
3495 
3496  m_buttonOK = new wxButton(this, wxID_ANY, _("OK"), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
3497 
3498  boxSizerBottomButtons->Add(m_buttonOK, 0, wxALL|wxALIGN_RIGHT, WXC_FROM_DIP(5));
3499 
3500  m_buttonCancel = new wxButton(this, wxID_ANY, _("Cancel"), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
3501 
3502  boxSizerBottomButtons->Add(m_buttonCancel, 0, wxALL|wxALIGN_RIGHT, WXC_FROM_DIP(5));
3503 
3504 
3505  #if wxVERSION_NUMBER >= 2900
3506  if(!wxPersistenceManager::Get().Find(m_notebook)){
3507  wxPersistenceManager::Get().RegisterAndRestore(m_notebook);
3508  } else {
3509  wxPersistenceManager::Get().Restore(m_notebook);
3510  }
3511  #endif
3512 
3513  SetName(wxT("ConstantFormBase"));
3514  SetSize(-1,-1);
3515  if (GetSizer()) {
3516  GetSizer()->Fit(this);
3517  }
3518  if(GetParent()) {
3519  CentreOnParent(wxBOTH);
3520  } else {
3521  CentreOnScreen(wxBOTH);
3522  }
3523 #if wxVERSION_NUMBER >= 2900
3524  if(!wxPersistenceManager::Get().Find(this)) {
3525  wxPersistenceManager::Get().RegisterAndRestore(this);
3526  } else {
3527  wxPersistenceManager::Get().Restore(this);
3528  }
3529 #endif
3530  // Connect events
3531  m_buttonOK->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(ConstantFormBase::OnOKButtonClick), NULL, this);
3532  m_buttonCancel->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(ConstantFormBase::OnCancelButtonClick), NULL, this);
3533 
3534 }
3535 
3536 ConstantFormBase::~ConstantFormBase()
3537 {
3538  m_buttonOK->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(ConstantFormBase::OnOKButtonClick), NULL, this);
3539  m_buttonCancel->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(ConstantFormBase::OnCancelButtonClick), NULL, this);
3540 
3541 }
3542 
3543 GainFormBase::GainFormBase(wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style)
3544  : wxDialog(parent, id, title, pos, size, style)
3545 {
3546  if ( !bBitmapLoaded ) {
3547  // We need to initialise the default bitmap handler
3548  wxXmlResource::Get()->AddHandler(new wxBitmapXmlHandler);
3549  wxC9EE9InitBitmapResources();
3550  bBitmapLoaded = true;
3551  }
3552 
3553  wxBoxSizer* boxSizerLvl1_1 = new wxBoxSizer(wxVERTICAL);
3554  this->SetSizer(boxSizerLvl1_1);
3555 
3556  m_notebook = new wxNotebook(this, wxID_ANY, wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), wxBK_DEFAULT);
3557  m_notebook->SetName(wxT("m_notebook"));
3558 
3559  boxSizerLvl1_1->Add(m_notebook, 1, wxEXPAND, WXC_FROM_DIP(5));
3560 
3561  m_panelGeneral = new wxPanel(m_notebook, wxID_ANY, wxDefaultPosition, wxDLG_UNIT(m_notebook, wxSize(-1,-1)), wxTAB_TRAVERSAL);
3562  m_notebook->AddPage(m_panelGeneral, _("General"), false);
3563 
3564  wxBoxSizer* boxSizerLvl2_1 = new wxBoxSizer(wxVERTICAL);
3565  m_panelGeneral->SetSizer(boxSizerLvl2_1);
3566 
3567  m_staticTextValue = new wxStaticText(m_panelGeneral, wxID_ANY, _("Gain value"), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
3568 
3569  boxSizerLvl2_1->Add(m_staticTextValue, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
3570 
3571  m_textCtrlValue = new wxTextCtrl(m_panelGeneral, wxID_ANY, wxT(""), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
3572  #if wxVERSION_NUMBER >= 3000
3573  m_textCtrlValue->SetHint(wxT(""));
3574  #endif
3575 
3576  boxSizerLvl2_1->Add(m_textCtrlValue, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxEXPAND|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
3577  m_textCtrlValue->SetMinSize(wxSize(100,-1));
3578 
3579  wxBoxSizer* boxSizerBottomButtons = new wxBoxSizer(wxHORIZONTAL);
3580 
3581  boxSizerLvl1_1->Add(boxSizerBottomButtons, 0, wxALL|wxEXPAND, WXC_FROM_DIP(5));
3582 
3583  boxSizerBottomButtons->Add(0, 0, 1, wxALL, WXC_FROM_DIP(5));
3584 
3585  m_buttonOK = new wxButton(this, wxID_ANY, _("OK"), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
3586 
3587  boxSizerBottomButtons->Add(m_buttonOK, 0, wxALL|wxALIGN_RIGHT, WXC_FROM_DIP(5));
3588 
3589  m_buttonCancel = new wxButton(this, wxID_ANY, _("Cancel"), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
3590 
3591  boxSizerBottomButtons->Add(m_buttonCancel, 0, wxALL|wxALIGN_RIGHT, WXC_FROM_DIP(5));
3592 
3593 
3594  #if wxVERSION_NUMBER >= 2900
3595  if(!wxPersistenceManager::Get().Find(m_notebook)){
3596  wxPersistenceManager::Get().RegisterAndRestore(m_notebook);
3597  } else {
3598  wxPersistenceManager::Get().Restore(m_notebook);
3599  }
3600  #endif
3601 
3602  SetName(wxT("GainFormBase"));
3603  SetSize(-1,-1);
3604  if (GetSizer()) {
3605  GetSizer()->Fit(this);
3606  }
3607  if(GetParent()) {
3608  CentreOnParent(wxBOTH);
3609  } else {
3610  CentreOnScreen(wxBOTH);
3611  }
3612 #if wxVERSION_NUMBER >= 2900
3613  if(!wxPersistenceManager::Get().Find(this)) {
3614  wxPersistenceManager::Get().RegisterAndRestore(this);
3615  } else {
3616  wxPersistenceManager::Get().Restore(this);
3617  }
3618 #endif
3619  // Connect events
3620  m_buttonOK->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(GainFormBase::OnOKButtonClick), NULL, this);
3621  m_buttonCancel->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(GainFormBase::OnCancelButtonClick), NULL, this);
3622 
3623 }
3624 
3625 GainFormBase::~GainFormBase()
3626 {
3627  m_buttonOK->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(GainFormBase::OnOKButtonClick), NULL, this);
3628  m_buttonCancel->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(GainFormBase::OnCancelButtonClick), NULL, this);
3629 
3630 }
3631 
3632 IOControlFormBase::IOControlFormBase(wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style)
3633  : wxDialog(parent, id, title, pos, size, style)
3634 {
3635  if ( !bBitmapLoaded ) {
3636  // We need to initialise the default bitmap handler
3637  wxXmlResource::Get()->AddHandler(new wxBitmapXmlHandler);
3638  wxC9EE9InitBitmapResources();
3639  bBitmapLoaded = true;
3640  }
3641 
3642  wxBoxSizer* boxSizerLvl1_1 = new wxBoxSizer(wxVERTICAL);
3643  this->SetSizer(boxSizerLvl1_1);
3644 
3645  m_notebook = new wxNotebook(this, wxID_ANY, wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), wxBK_DEFAULT);
3646  m_notebook->SetName(wxT("m_notebook"));
3647 
3648  boxSizerLvl1_1->Add(m_notebook, 1, wxEXPAND, WXC_FROM_DIP(5));
3649 
3650  m_panelGeneral = new wxPanel(m_notebook, wxID_ANY, wxDefaultPosition, wxDLG_UNIT(m_notebook, wxSize(-1,-1)), wxTAB_TRAVERSAL);
3651  m_notebook->AddPage(m_panelGeneral, _("General"), false);
3652 
3653  wxBoxSizer* boxSizerLvl2_1 = new wxBoxSizer(wxVERTICAL);
3654  m_panelGeneral->SetSizer(boxSizerLvl2_1);
3655 
3656  m_checkBoxInput = new wxCheckBox(m_panelGeneral, wxID_ANY, _("Input"), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
3657  m_checkBoxInput->SetValue(false);
3658 
3659  boxSizerLvl2_1->Add(m_checkBoxInput, 0, wxLEFT|wxRIGHT|wxTOP, WXC_FROM_DIP(5));
3660 
3661  wxArrayString m_choiceInputArr;
3662  m_choiceInput = new wxChoice(m_panelGeneral, wxID_ANY, wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), m_choiceInputArr, 0);
3663 
3664  boxSizerLvl2_1->Add(m_choiceInput, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxEXPAND, WXC_FROM_DIP(5));
3665 
3666  m_checkBoxOutput = new wxCheckBox(m_panelGeneral, wxID_ANY, _("Output"), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
3667  m_checkBoxOutput->SetValue(false);
3668 
3669  boxSizerLvl2_1->Add(m_checkBoxOutput, 0, wxLEFT|wxRIGHT|wxTOP, WXC_FROM_DIP(5));
3670 
3671  wxArrayString m_choiceOutputArr;
3672  m_choiceOutput = new wxChoice(m_panelGeneral, wxID_ANY, wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), m_choiceOutputArr, 0);
3673 
3674  boxSizerLvl2_1->Add(m_choiceOutput, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxEXPAND, WXC_FROM_DIP(5));
3675 
3676  wxBoxSizer* boxSizerBottomButtons = new wxBoxSizer(wxHORIZONTAL);
3677 
3678  boxSizerLvl1_1->Add(boxSizerBottomButtons, 0, wxALL|wxEXPAND, WXC_FROM_DIP(5));
3679 
3680  boxSizerBottomButtons->Add(0, 0, 1, wxALL, WXC_FROM_DIP(5));
3681 
3682  m_buttonOK = new wxButton(this, wxID_ANY, _("OK"), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
3683 
3684  boxSizerBottomButtons->Add(m_buttonOK, 0, wxALL|wxALIGN_RIGHT, WXC_FROM_DIP(5));
3685 
3686  m_ButtonCancel = new wxButton(this, wxID_ANY, _("Cancel"), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
3687 
3688  boxSizerBottomButtons->Add(m_ButtonCancel, 0, wxALL|wxALIGN_RIGHT, WXC_FROM_DIP(5));
3689 
3690 
3691  #if wxVERSION_NUMBER >= 2900
3692  if(!wxPersistenceManager::Get().Find(m_notebook)){
3693  wxPersistenceManager::Get().RegisterAndRestore(m_notebook);
3694  } else {
3695  wxPersistenceManager::Get().Restore(m_notebook);
3696  }
3697  #endif
3698 
3699  SetName(wxT("IOControlFormBase"));
3700  SetSize(-1,-1);
3701  if (GetSizer()) {
3702  GetSizer()->Fit(this);
3703  }
3704  if(GetParent()) {
3705  CentreOnParent(wxBOTH);
3706  } else {
3707  CentreOnScreen(wxBOTH);
3708  }
3709 #if wxVERSION_NUMBER >= 2900
3710  if(!wxPersistenceManager::Get().Find(this)) {
3711  wxPersistenceManager::Get().RegisterAndRestore(this);
3712  } else {
3713  wxPersistenceManager::Get().Restore(this);
3714  }
3715 #endif
3716  // Connect events
3717  m_checkBoxInput->Connect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler(IOControlFormBase::OnInputChecked), NULL, this);
3718  m_checkBoxOutput->Connect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler(IOControlFormBase::OnOutputChecked), NULL, this);
3719  m_buttonOK->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(IOControlFormBase::OnOKButtonClick), NULL, this);
3720  m_ButtonCancel->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(IOControlFormBase::OnCancelButtonClick), NULL, this);
3721 
3722 }
3723 
3724 IOControlFormBase::~IOControlFormBase()
3725 {
3726  m_checkBoxInput->Disconnect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler(IOControlFormBase::OnInputChecked), NULL, this);
3727  m_checkBoxOutput->Disconnect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler(IOControlFormBase::OnOutputChecked), NULL, this);
3728  m_buttonOK->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(IOControlFormBase::OnOKButtonClick), NULL, this);
3729  m_ButtonCancel->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(IOControlFormBase::OnCancelButtonClick), NULL, this);
3730 
3731 }
-
1 // This file was auto-generated by codelite's wxCrafter Plugin
3 // wxCrafter project file: ElementForm.wxcp
4 // Do not modify this file by hand!
6 
7 #ifndef _PSP_PROJECT_ELEMENTFORM_BASE_CLASSES_H
8 #define _PSP_PROJECT_ELEMENTFORM_BASE_CLASSES_H
9 
10 #include <wx/settings.h>
11 #include <wx/xrc/xmlres.h>
12 #include <wx/xrc/xh_bmp.h>
13 #include <wx/dialog.h>
14 #include <wx/iconbndl.h>
15 #include <wx/artprov.h>
16 #include <wx/sizer.h>
17 #include <wx/notebook.h>
18 #include <wx/panel.h>
19 #include <wx/imaglist.h>
20 #include <wx/stattext.h>
21 #include <wx/textctrl.h>
22 #include <wx/choice.h>
23 #include <wx/arrstr.h>
24 #include <wx/checkbox.h>
25 #include <wx/button.h>
26 #include <wx/statbox.h>
27 #include <wx/statline.h>
28 #include <wx/propgrid/manager.h>
29 #include <wx/propgrid/property.h>
30 #include <wx/propgrid/advprops.h>
31 #include <wx/listctrl.h>
32 #if wxVERSION_NUMBER >= 2900
33 #include <wx/persist.h>
34 #include <wx/persist/toplevel.h>
35 #include <wx/persist/bookctrl.h>
36 #include <wx/persist/treebook.h>
37 #endif
38 
39 #ifdef WXC_FROM_DIP
40 #undef WXC_FROM_DIP
41 #endif
42 #if wxVERSION_NUMBER >= 3100
43 #define WXC_FROM_DIP(x) wxWindow::FromDIP(x, NULL)
44 #else
45 #define WXC_FROM_DIP(x) x
46 #endif
47 
48 
49 class BusFormBase : public wxDialog
50 {
51 protected:
52  wxNotebook* m_notebook;
53  wxPanel* m_panelGeneral;
54  wxStaticText* m_staticTextName;
55  wxTextCtrl* m_textCtrlName;
56  wxStaticText* m_staticTextNomVoltage;
57  wxTextCtrl* m_textCtrlNomVoltage;
58  wxChoice* m_choiceNomVoltage;
59  wxCheckBox* m_checkBoxCtrlVoltage;
60  wxTextCtrl* m_textCtrlCtrlVoltage;
61  wxChoice* m_choiceCtrlVoltage;
62  wxCheckBox* m_checkBoxSlackBus;
63  wxPanel* m_panelFault;
64  wxCheckBox* m_checkBoxFault;
65  wxStaticText* m_staticTextFaultType;
66  wxChoice* m_choiceFaultType;
67  wxStaticText* m_staticTextFaultPlace;
68  wxChoice* m_choiceFaultPlace;
69  wxStaticText* m_staticTextFaultResistance;
70  wxTextCtrl* m_textCtrlFaultResistance;
71  wxStaticText* m_staticTextPU_1;
72  wxStaticText* m_staticTextReactance;
73  wxTextCtrl* m_textCtrlFaultReactance;
74  wxStaticText* m_staticTextPU_2;
75  wxPanel* m_panelStability;
76  wxCheckBox* m_checkBoxPlotData;
77  wxCheckBox* m_checkBoxStabFault;
78  wxStaticText* m_staticTextStabFaultTime;
79  wxTextCtrl* m_textCtrlStabFaultTime;
80  wxStaticText* m_staticTextS_1;
81  wxStaticText* m_staticTextStabFaultLength;
82  wxTextCtrl* m_textCtrlStabFaultLength;
83  wxStaticText* m_staticTextS_2;
84  wxStaticText* m_staticTextStabFaultResistance;
85  wxTextCtrl* m_textCtrlStabFaultResistance;
86  wxStaticText* m_staticTextPU_3;
87  wxStaticText* m_staticTextStabFaultReactance;
88  wxTextCtrl* m_textCtrlStabFaultReactance;
89  wxStaticText* m_staticTextPU_4;
90  wxButton* m_buttonOK;
91  wxButton* m_ButtonCancel;
92 
93 protected:
94  virtual void OnNominalVoltageChoice(wxCommandEvent& event) { event.Skip(); }
95  virtual void OnControlledVoltageClick(wxCommandEvent& event) { event.Skip(); }
96  virtual void OnInsertFaultClick(wxCommandEvent& event) { event.Skip(); }
97  virtual void OnFaultTypeChoice(wxCommandEvent& event) { event.Skip(); }
98  virtual void OnInsertStabFaultClick(wxCommandEvent& event) { event.Skip(); }
99  virtual void OnButtonOKClick(wxCommandEvent& event) { event.Skip(); }
100  virtual void OnButtonCancelClick(wxCommandEvent& event) { event.Skip(); }
101 
102 public:
103  wxStaticText* GetStaticTextName() { return m_staticTextName; }
104  wxTextCtrl* GetTextCtrlName() { return m_textCtrlName; }
105  wxStaticText* GetStaticTextNomVoltage() { return m_staticTextNomVoltage; }
106  wxTextCtrl* GetTextCtrlNomVoltage() { return m_textCtrlNomVoltage; }
107  wxChoice* GetChoiceNomVoltage() { return m_choiceNomVoltage; }
108  wxCheckBox* GetCheckBoxCtrlVoltage() { return m_checkBoxCtrlVoltage; }
109  wxTextCtrl* GetTextCtrlCtrlVoltage() { return m_textCtrlCtrlVoltage; }
110  wxChoice* GetChoiceCtrlVoltage() { return m_choiceCtrlVoltage; }
111  wxCheckBox* GetCheckBoxSlackBus() { return m_checkBoxSlackBus; }
112  wxPanel* GetPanelGeneral() { return m_panelGeneral; }
113  wxCheckBox* GetCheckBoxFault() { return m_checkBoxFault; }
114  wxStaticText* GetStaticTextFaultType() { return m_staticTextFaultType; }
115  wxChoice* GetChoiceFaultType() { return m_choiceFaultType; }
116  wxStaticText* GetStaticTextFaultPlace() { return m_staticTextFaultPlace; }
117  wxChoice* GetChoiceFaultPlace() { return m_choiceFaultPlace; }
118  wxStaticText* GetStaticTextFaultResistance() { return m_staticTextFaultResistance; }
119  wxTextCtrl* GetTextCtrlFaultResistance() { return m_textCtrlFaultResistance; }
120  wxStaticText* GetStaticTextPU_1() { return m_staticTextPU_1; }
121  wxStaticText* GetStaticTextReactance() { return m_staticTextReactance; }
122  wxTextCtrl* GetTextCtrlFaultReactance() { return m_textCtrlFaultReactance; }
123  wxStaticText* GetStaticTextPU_2() { return m_staticTextPU_2; }
124  wxPanel* GetPanelFault() { return m_panelFault; }
125  wxCheckBox* GetCheckBoxPlotData() { return m_checkBoxPlotData; }
126  wxCheckBox* GetCheckBoxStabFault() { return m_checkBoxStabFault; }
127  wxStaticText* GetStaticTextStabFaultTime() { return m_staticTextStabFaultTime; }
128  wxTextCtrl* GetTextCtrlStabFaultTime() { return m_textCtrlStabFaultTime; }
129  wxStaticText* GetStaticTextS_1() { return m_staticTextS_1; }
130  wxStaticText* GetStaticTextStabFaultLength() { return m_staticTextStabFaultLength; }
131  wxTextCtrl* GetTextCtrlStabFaultLength() { return m_textCtrlStabFaultLength; }
132  wxStaticText* GetStaticTextS_2() { return m_staticTextS_2; }
133  wxStaticText* GetStaticTextStabFaultResistance() { return m_staticTextStabFaultResistance; }
134  wxTextCtrl* GetTextCtrlStabFaultResistance() { return m_textCtrlStabFaultResistance; }
135  wxStaticText* GetStaticTextPU_3() { return m_staticTextPU_3; }
136  wxStaticText* GetStaticTextStabFaultReactance() { return m_staticTextStabFaultReactance; }
137  wxTextCtrl* GetTextCtrlStabFaultReactance() { return m_textCtrlStabFaultReactance; }
138  wxStaticText* GetStaticTextPU_4() { return m_staticTextPU_4; }
139  wxPanel* GetPanelStability() { return m_panelStability; }
140  wxNotebook* GetNotebook() { return m_notebook; }
141  wxButton* GetButtonOK() { return m_buttonOK; }
142  wxButton* GetButtonCancel() { return m_ButtonCancel; }
143  BusFormBase(wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Bus"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize(-1,-1), long style = wxDEFAULT_DIALOG_STYLE);
144  virtual ~BusFormBase();
145 };
146 
147 
148 class SyncMachineFormBase : public wxDialog
149 {
150 protected:
151  wxNotebook* m_notebook;
152  wxPanel* m_panelGeneral;
153  wxStaticText* m_staticTextName;
154  wxTextCtrl* m_textCtrlName;
155  wxStaticText* m_staticTextNominalPower;
156  wxTextCtrl* m_textCtrlnominalPower;
157  wxChoice* m_choiceNominalPower;
158  wxStaticText* m_staticTextActivePower;
159  wxTextCtrl* m_textCtrlActivePower;
160  wxChoice* m_choiceActivePower;
161  wxStaticText* m_staticTextReactivePower;
162  wxTextCtrl* m_textCtrlReactivePower;
163  wxChoice* m_choiceReactivePower;
164  wxCheckBox* m_checkBoxMaxReactive;
165  wxTextCtrl* m_textCtrlMaxRectivePower;
166  wxChoice* m_choiceMaxRectivePower;
167  wxCheckBox* m_checkBoxMinReactive;
168  wxTextCtrl* m_textCtrlMinRectivePower;
169  wxChoice* m_choiceMinRectivePower;
170  wxCheckBox* m_checkBoxUseMachinePower;
171  wxPanel* m_panelFault;
172  wxStaticText* m_staticTextPosResistance;
173  wxTextCtrl* m_textCtrlPosResistance;
174  wxStaticText* m_staticTextPosReactance;
175  wxTextCtrl* m_textCtrlPosReactance;
176  wxStaticText* m_staticTextNegResistance;
177  wxTextCtrl* m_textCtrlNegResistance;
178  wxStaticText* m_staticTextNegReactance;
179  wxTextCtrl* m_textCtrlNegReactance;
180  wxStaticText* m_staticTextZeroResistance;
181  wxTextCtrl* m_textCtrlZeroResistance;
182  wxStaticText* m_staticTextZeroReactance;
183  wxTextCtrl* m_textCtrlZeroReactance;
184  wxStaticText* m_staticTextGrdResistance;
185  wxTextCtrl* m_textCtrlGrdResistance;
186  wxStaticText* m_staticTextGrdReactance;
187  wxTextCtrl* m_textCtrlGrdReactance;
188  wxCheckBox* m_checkBoxGroundNeutral;
189  wxButton* m_buttonStab;
190  wxButton* m_buttonOK;
191  wxButton* m_ButtonCancel;
192 
193 protected:
194  virtual void OnCheckMaxReactive(wxCommandEvent& event) { event.Skip(); }
195  virtual void OnCheckMinReactive(wxCommandEvent& event) { event.Skip(); }
196  virtual void OnStabilityButtonClick(wxCommandEvent& event) { event.Skip(); }
197  virtual void OnOKButtonClick(wxCommandEvent& event) { event.Skip(); }
198  virtual void OnCancelButtonClick(wxCommandEvent& event) { event.Skip(); }
199 
200 public:
201  wxStaticText* GetStaticTextName() { return m_staticTextName; }
202  wxTextCtrl* GetTextCtrlName() { return m_textCtrlName; }
203  wxStaticText* GetStaticTextNominalPower() { return m_staticTextNominalPower; }
204  wxTextCtrl* GetTextCtrlnominalPower() { return m_textCtrlnominalPower; }
205  wxChoice* GetChoiceNominalPower() { return m_choiceNominalPower; }
206  wxStaticText* GetStaticTextActivePower() { return m_staticTextActivePower; }
207  wxTextCtrl* GetTextCtrlActivePower() { return m_textCtrlActivePower; }
208  wxChoice* GetChoiceActivePower() { return m_choiceActivePower; }
209  wxStaticText* GetStaticTextReactivePower() { return m_staticTextReactivePower; }
210  wxTextCtrl* GetTextCtrlReactivePower() { return m_textCtrlReactivePower; }
211  wxChoice* GetChoiceReactivePower() { return m_choiceReactivePower; }
212  wxCheckBox* GetCheckBoxMaxReactive() { return m_checkBoxMaxReactive; }
213  wxTextCtrl* GetTextCtrlMaxRectivePower() { return m_textCtrlMaxRectivePower; }
214  wxChoice* GetChoiceMaxRectivePower() { return m_choiceMaxRectivePower; }
215  wxCheckBox* GetCheckBoxMinReactive() { return m_checkBoxMinReactive; }
216  wxTextCtrl* GetTextCtrlMinRectivePower() { return m_textCtrlMinRectivePower; }
217  wxChoice* GetChoiceMinRectivePower() { return m_choiceMinRectivePower; }
218  wxCheckBox* GetCheckBoxUseMachinePower() { return m_checkBoxUseMachinePower; }
219  wxPanel* GetPanelGeneral() { return m_panelGeneral; }
220  wxStaticText* GetStaticTextPosResistance() { return m_staticTextPosResistance; }
221  wxTextCtrl* GetTextCtrlPosResistance() { return m_textCtrlPosResistance; }
222  wxStaticText* GetStaticTextPosReactance() { return m_staticTextPosReactance; }
223  wxTextCtrl* GetTextCtrlPosReactance() { return m_textCtrlPosReactance; }
224  wxStaticText* GetStaticTextNegResistance() { return m_staticTextNegResistance; }
225  wxTextCtrl* GetTextCtrlNegResistance() { return m_textCtrlNegResistance; }
226  wxStaticText* GetStaticTextNegReactance() { return m_staticTextNegReactance; }
227  wxTextCtrl* GetTextCtrlNegReactance() { return m_textCtrlNegReactance; }
228  wxStaticText* GetStaticTextZeroResistance() { return m_staticTextZeroResistance; }
229  wxTextCtrl* GetTextCtrlZeroResistance() { return m_textCtrlZeroResistance; }
230  wxStaticText* GetStaticTextZeroReactance() { return m_staticTextZeroReactance; }
231  wxTextCtrl* GetTextCtrlZeroReactance() { return m_textCtrlZeroReactance; }
232  wxStaticText* GetStaticTextGrdResistance() { return m_staticTextGrdResistance; }
233  wxTextCtrl* GetTextCtrlGrdResistance() { return m_textCtrlGrdResistance; }
234  wxStaticText* GetStaticTextGrdReactance() { return m_staticTextGrdReactance; }
235  wxTextCtrl* GetTextCtrlGrdReactance() { return m_textCtrlGrdReactance; }
236  wxCheckBox* GetCheckBoxGroundNeutral() { return m_checkBoxGroundNeutral; }
237  wxPanel* GetPanelFault() { return m_panelFault; }
238  wxNotebook* GetNotebook() { return m_notebook; }
239  wxButton* GetButtonStab() { return m_buttonStab; }
240  wxButton* GetButtonOK() { return m_buttonOK; }
241  wxButton* GetButtonCancel() { return m_ButtonCancel; }
242  SyncMachineFormBase(wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Generator"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize(-1,-1), long style = wxDEFAULT_DIALOG_STYLE);
243  virtual ~SyncMachineFormBase();
244 };
245 
246 
247 class GeneratorStabFormBase : public wxDialog
248 {
249 protected:
250  wxCheckBox* m_checkBoxPlotSyncMachine;
251  wxStaticText* m_staticTextInertia;
252  wxTextCtrl* m_textCtrlInertia;
253  wxStaticText* m_staticTextS_1;
254  wxStaticText* m_staticTextDamping;
255  wxTextCtrl* m_textCtrlDamping;
256  wxStaticText* m_staticTextPU_1;
257  wxCheckBox* m_checkBoxUseAVR;
258  wxButton* m_buttonEditAVR;
259  wxCheckBox* m_checkBoxUseSG;
260  wxButton* m_buttonEditSG;
261  wxStaticLine* m_staticLine_1;
262  wxStaticText* m_staticTextRa;
263  wxTextCtrl* m_textCtrlRa;
264  wxStaticText* m_staticTextPU_2;
265  wxStaticText* m_staticTextXp;
266  wxTextCtrl* m_textCtrlXp;
267  wxStaticText* m_staticTextPU_9;
268  wxStaticText* m_staticTextSat;
269  wxTextCtrl* m_textCtrlSat;
270  wxStaticText* m_staticTextPU_10;
271  wxStaticText* m_staticTextSyncXd;
272  wxTextCtrl* m_textCtrlSyncXd;
273  wxStaticText* m_staticTextPU_3;
274  wxStaticText* m_staticTextSyncXq;
275  wxTextCtrl* m_textCtrlSyncXq;
276  wxStaticText* m_staticTextPU_4;
277  wxStaticText* m_staticTextTranXd;
278  wxTextCtrl* m_textCtrlTranXd;
279  wxStaticText* m_staticTextPU_5;
280  wxStaticText* m_staticTextTranXq;
281  wxTextCtrl* m_textCtrlTranXq;
282  wxStaticText* m_staticTextPU_6;
283  wxStaticText* m_staticTextTranTd0;
284  wxTextCtrl* m_textCtrlTranTd0;
285  wxStaticText* m_staticTextS_2;
286  wxStaticText* m_staticTextTranTq0;
287  wxTextCtrl* m_textCtrlTranTq0;
288  wxStaticText* m_staticTextS_3;
289  wxStaticText* m_staticTextSubXd;
290  wxTextCtrl* m_textCtrlSubXd;
291  wxStaticText* m_staticTextPU_7;
292  wxStaticText* m_staticTextSubXq;
293  wxTextCtrl* m_textCtrlSubXq;
294  wxStaticText* m_staticTextPU_8;
295  wxStaticText* m_staticTextSubTd0;
296  wxTextCtrl* m_textCtrlSubTd0;
297  wxStaticText* m_staticTextS_4;
298  wxStaticText* m_staticTextSubTq0;
299  wxTextCtrl* m_textCtrlSubTq0;
300  wxStaticText* m_staticTextS_5;
301  wxButton* m_buttonSwitching;
302  wxButton* m_buttonOK;
303  wxButton* m_ButtonCancel;
304 
305 protected:
306  virtual void UseAVRClick(wxCommandEvent& event) { event.Skip(); }
307  virtual void OnEditAVRButtonClick(wxCommandEvent& event) { event.Skip(); }
308  virtual void UseSGClick(wxCommandEvent& event) { event.Skip(); }
309  virtual void OnSpeedGovernorButtonClick(wxCommandEvent& event) { event.Skip(); }
310  virtual void OnSwitchingButtonClick(wxCommandEvent& event) { event.Skip(); }
311  virtual void OnOKButtonClick(wxCommandEvent& event) { event.Skip(); }
312  virtual void OnCancelButtonClick(wxCommandEvent& event) { event.Skip(); }
313 
314 public:
315  wxCheckBox* GetCheckBoxPlotSyncMachine() { return m_checkBoxPlotSyncMachine; }
316  wxStaticText* GetStaticTextInertia() { return m_staticTextInertia; }
317  wxTextCtrl* GetTextCtrlInertia() { return m_textCtrlInertia; }
318  wxStaticText* GetStaticTextS_1() { return m_staticTextS_1; }
319  wxStaticText* GetStaticTextDamping() { return m_staticTextDamping; }
320  wxTextCtrl* GetTextCtrlDamping() { return m_textCtrlDamping; }
321  wxStaticText* GetStaticTextPU_1() { return m_staticTextPU_1; }
322  wxCheckBox* GetCheckBoxUseAVR() { return m_checkBoxUseAVR; }
323  wxButton* GetButtonEditAVR() { return m_buttonEditAVR; }
324  wxCheckBox* GetCheckBoxUseSG() { return m_checkBoxUseSG; }
325  wxButton* GetButtonEditSG() { return m_buttonEditSG; }
326  wxStaticLine* GetStaticLine_1() { return m_staticLine_1; }
327  wxStaticText* GetStaticTextRa() { return m_staticTextRa; }
328  wxTextCtrl* GetTextCtrlRa() { return m_textCtrlRa; }
329  wxStaticText* GetStaticTextPU_2() { return m_staticTextPU_2; }
330  wxStaticText* GetStaticTextXp() { return m_staticTextXp; }
331  wxTextCtrl* GetTextCtrlXp() { return m_textCtrlXp; }
332  wxStaticText* GetStaticTextPU_9() { return m_staticTextPU_9; }
333  wxStaticText* GetStaticTextSat() { return m_staticTextSat; }
334  wxTextCtrl* GetTextCtrlSat() { return m_textCtrlSat; }
335  wxStaticText* GetStaticTextPU_10() { return m_staticTextPU_10; }
336  wxStaticText* GetStaticTextSyncXd() { return m_staticTextSyncXd; }
337  wxTextCtrl* GetTextCtrlSyncXd() { return m_textCtrlSyncXd; }
338  wxStaticText* GetStaticTextPU_3() { return m_staticTextPU_3; }
339  wxStaticText* GetStaticTextSyncXq() { return m_staticTextSyncXq; }
340  wxTextCtrl* GetTextCtrlSyncXq() { return m_textCtrlSyncXq; }
341  wxStaticText* GetStaticTextPU_4() { return m_staticTextPU_4; }
342  wxStaticText* GetStaticTextTranXd() { return m_staticTextTranXd; }
343  wxTextCtrl* GetTextCtrlTranXd() { return m_textCtrlTranXd; }
344  wxStaticText* GetStaticTextPU_5() { return m_staticTextPU_5; }
345  wxStaticText* GetStaticTextTranXq() { return m_staticTextTranXq; }
346  wxTextCtrl* GetTextCtrlTranXq() { return m_textCtrlTranXq; }
347  wxStaticText* GetStaticTextPU_6() { return m_staticTextPU_6; }
348  wxStaticText* GetStaticTextTranTd0() { return m_staticTextTranTd0; }
349  wxTextCtrl* GetTextCtrlTranTd0() { return m_textCtrlTranTd0; }
350  wxStaticText* GetStaticTextS_2() { return m_staticTextS_2; }
351  wxStaticText* GetStaticTextTranTq0() { return m_staticTextTranTq0; }
352  wxTextCtrl* GetTextCtrlTranTq0() { return m_textCtrlTranTq0; }
353  wxStaticText* GetStaticTextS_3() { return m_staticTextS_3; }
354  wxStaticText* GetStaticTextSubXd() { return m_staticTextSubXd; }
355  wxTextCtrl* GetTextCtrlSubXd() { return m_textCtrlSubXd; }
356  wxStaticText* GetStaticTextPU_7() { return m_staticTextPU_7; }
357  wxStaticText* GetStaticTextSubXq() { return m_staticTextSubXq; }
358  wxTextCtrl* GetTextCtrlSubXq() { return m_textCtrlSubXq; }
359  wxStaticText* GetStaticTextPU_8() { return m_staticTextPU_8; }
360  wxStaticText* GetStaticTextSubTd0() { return m_staticTextSubTd0; }
361  wxTextCtrl* GetTextCtrlSubTd0() { return m_textCtrlSubTd0; }
362  wxStaticText* GetStaticTextS_4() { return m_staticTextS_4; }
363  wxStaticText* GetStaticTextSubTq0() { return m_staticTextSubTq0; }
364  wxTextCtrl* GetTextCtrlSubTq0() { return m_textCtrlSubTq0; }
365  wxStaticText* GetStaticTextS_5() { return m_staticTextS_5; }
366  wxButton* GetButtonSwitching() { return m_buttonSwitching; }
367  wxButton* GetButtonOK() { return m_buttonOK; }
368  wxButton* GetButtonCancel() { return m_ButtonCancel; }
369  GeneratorStabFormBase(wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Generator: Stability"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize(-1,-1), long style = wxDEFAULT_DIALOG_STYLE);
370  virtual ~GeneratorStabFormBase();
371 };
372 
373 
374 class LineFormBase : public wxDialog
375 {
376 protected:
377  wxNotebook* m_notebook;
378  wxPanel* m_panelGeneral;
379  wxStaticText* m_staticTextName;
380  wxTextCtrl* m_textCtrlName;
381  wxStaticText* m_staticTextNominalVoltage;
382  wxStaticText* m_staticTextNominalVoltageValue;
383  wxStaticText* m_staticTextNominalPower;
384  wxTextCtrl* m_textCtrlNominalPower;
385  wxChoice* m_choiceNominalPower;
386  wxStaticText* m_staticTextResistance;
387  wxTextCtrl* m_textCtrlResistance;
388  wxChoice* m_choiceResistance;
389  wxStaticText* m_staticTextReactance;
390  wxTextCtrl* m_textCtrlReactance;
391  wxChoice* m_choiceReactance;
392  wxStaticText* m_staticTextSusceptance;
393  wxTextCtrl* m_textCtrlSusceptance;
394  wxChoice* m_choiceSusceptance;
395  wxStaticText* m_staticTextLineSize;
396  wxTextCtrl* m_textCtrlLineSize;
397  wxStaticText* m_staticTextKM;
398  wxCheckBox* m_checkUseLinePower;
399  wxPanel* m_panelFault;
400  wxStaticText* m_staticTextZeroResistance;
401  wxTextCtrl* m_textCtrlZeroResistance;
402  wxStaticText* m_staticTextZeroReactance;
403  wxTextCtrl* m_textCtrlZeroReactance;
404  wxStaticText* m_staticTextZeroSusceptance;
405  wxTextCtrl* m_textCtrlZeroSusceptance;
406  wxButton* m_buttonStability;
407  wxButton* m_buttonOK;
408  wxButton* m_buttonCancel;
409 
410 protected:
411  virtual void OnStabilityButtonClick(wxCommandEvent& event) { event.Skip(); }
412  virtual void OnOKButtonClick(wxCommandEvent& event) { event.Skip(); }
413  virtual void OnCancelButtonClick(wxCommandEvent& event) { event.Skip(); }
414 
415 public:
416  wxStaticText* GetStaticTextName() { return m_staticTextName; }
417  wxTextCtrl* GetTextCtrlName() { return m_textCtrlName; }
418  wxStaticText* GetStaticTextNominalVoltage() { return m_staticTextNominalVoltage; }
419  wxStaticText* GetStaticTextNominalVoltageValue() { return m_staticTextNominalVoltageValue; }
420  wxStaticText* GetStaticTextNominalPower() { return m_staticTextNominalPower; }
421  wxTextCtrl* GetTextCtrlNominalPower() { return m_textCtrlNominalPower; }
422  wxChoice* GetChoiceNominalPower() { return m_choiceNominalPower; }
423  wxStaticText* GetStaticTextResistance() { return m_staticTextResistance; }
424  wxTextCtrl* GetTextCtrlResistance() { return m_textCtrlResistance; }
425  wxChoice* GetChoiceResistance() { return m_choiceResistance; }
426  wxStaticText* GetStaticTextReactance() { return m_staticTextReactance; }
427  wxTextCtrl* GetTextCtrlReactance() { return m_textCtrlReactance; }
428  wxChoice* GetChoiceReactance() { return m_choiceReactance; }
429  wxStaticText* GetStaticTextSusceptance() { return m_staticTextSusceptance; }
430  wxTextCtrl* GetTextCtrlSusceptance() { return m_textCtrlSusceptance; }
431  wxChoice* GetChoiceSusceptance() { return m_choiceSusceptance; }
432  wxStaticText* GetStaticTextLineSize() { return m_staticTextLineSize; }
433  wxTextCtrl* GetTextCtrlLineSize() { return m_textCtrlLineSize; }
434  wxStaticText* GetStaticTextKM() { return m_staticTextKM; }
435  wxCheckBox* GetCheckUseLinePower() { return m_checkUseLinePower; }
436  wxPanel* GetPanelGeneral() { return m_panelGeneral; }
437  wxStaticText* GetStaticTextZeroResistance() { return m_staticTextZeroResistance; }
438  wxTextCtrl* GetTextCtrlZeroResistance() { return m_textCtrlZeroResistance; }
439  wxStaticText* GetStaticTextZeroReactance() { return m_staticTextZeroReactance; }
440  wxTextCtrl* GetTextCtrlZeroReactance() { return m_textCtrlZeroReactance; }
441  wxStaticText* GetStaticTextZeroSusceptance() { return m_staticTextZeroSusceptance; }
442  wxTextCtrl* GetTextCtrlZeroSusceptance() { return m_textCtrlZeroSusceptance; }
443  wxPanel* GetPanelFault() { return m_panelFault; }
444  wxNotebook* GetNotebook() { return m_notebook; }
445  wxButton* GetButtonStability() { return m_buttonStability; }
446  wxButton* GetButtonOK() { return m_buttonOK; }
447  wxButton* GetButtonCancel() { return m_buttonCancel; }
448  LineFormBase(wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Line"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize(-1,-1), long style = wxDEFAULT_DIALOG_STYLE);
449  virtual ~LineFormBase();
450 };
451 
452 
453 class TransformerFormBase : public wxDialog
454 {
455 protected:
456  wxNotebook* m_notebook;
457  wxPanel* m_panelGeneral;
458  wxStaticText* m_staticTextName;
459  wxTextCtrl* m_textCtrlName;
460  wxStaticText* m_staticTextNominalVoltage;
461  wxStaticText* m_staticTextNominalVoltageValue;
462  wxStaticText* m_staticTextBaseVoltage;
463  wxChoice* m_choiceBaseVoltage;
464  wxStaticText* m_staticTextNominalPower;
465  wxTextCtrl* m_textCtrlNominalPower;
466  wxChoice* m_choiceNominalPower;
467  wxStaticText* m_staticTextResistance;
468  wxTextCtrl* m_textCtrlResistance;
469  wxChoice* m_choiceResistance;
470  wxStaticText* m_staticTextReactance;
471  wxTextCtrl* m_textCtrlReactance;
472  wxChoice* m_choiceReactance;
473  wxStaticLine* m_staticLine_1;
474  wxStaticText* m_staticTextConnection;
475  wxChoice* m_choiceConnection;
476  wxStaticText* m_staticTextTurnsRatio;
477  wxTextCtrl* m_textCtrlTurnRatio;
478  wxStaticText* m_staticTextPhaseShift;
479  wxTextCtrl* m_textCtrlPhaseShift;
480  wxStaticText* m_staticTextDeg;
481  wxCheckBox* m_checkUseTransformerPower;
482  wxPanel* m_panelFault;
483  wxStaticText* m_staticTextZeroResistance;
484  wxTextCtrl* m_textCtrlZeroResistance;
485  wxStaticText* m_staticTextZeroReactance;
486  wxTextCtrl* m_textCtrlZeroReactance;
487  wxStaticText* m_staticTextPrimResistance;
488  wxTextCtrl* m_textCtrlPrimResistance;
489  wxStaticText* m_staticTextPrimReactance;
490  wxTextCtrl* m_textCtrlPrimReactance;
491  wxStaticText* m_staticTextSecResistance;
492  wxTextCtrl* m_textCtrlSecResistance;
493  wxStaticText* m_staticTextSecReactance;
494  wxTextCtrl* m_textCtrlSecReactance;
495  wxButton* m_buttonStability;
496  wxButton* m_buttonOK;
497  wxButton* m_buttonCancel;
498 
499 protected:
500  virtual void OnStabilityButtonClick(wxCommandEvent& event) { event.Skip(); }
501  virtual void OnOKButtonClick(wxCommandEvent& event) { event.Skip(); }
502  virtual void OnCancelButtonClick(wxCommandEvent& event) { event.Skip(); }
503 
504 public:
505  wxStaticText* GetStaticTextName() { return m_staticTextName; }
506  wxTextCtrl* GetTextCtrlName() { return m_textCtrlName; }
507  wxStaticText* GetStaticTextNominalVoltage() { return m_staticTextNominalVoltage; }
508  wxStaticText* GetStaticTextNominalVoltageValue() { return m_staticTextNominalVoltageValue; }
509  wxStaticText* GetStaticTextBaseVoltage() { return m_staticTextBaseVoltage; }
510  wxChoice* GetChoiceBaseVoltage() { return m_choiceBaseVoltage; }
511  wxStaticText* GetStaticTextNominalPower() { return m_staticTextNominalPower; }
512  wxTextCtrl* GetTextCtrlNominalPower() { return m_textCtrlNominalPower; }
513  wxChoice* GetChoiceNominalPower() { return m_choiceNominalPower; }
514  wxStaticText* GetStaticTextResistance() { return m_staticTextResistance; }
515  wxTextCtrl* GetTextCtrlResistance() { return m_textCtrlResistance; }
516  wxChoice* GetChoiceResistance() { return m_choiceResistance; }
517  wxStaticText* GetStaticTextReactance() { return m_staticTextReactance; }
518  wxTextCtrl* GetTextCtrlReactance() { return m_textCtrlReactance; }
519  wxChoice* GetChoiceReactance() { return m_choiceReactance; }
520  wxStaticLine* GetStaticLine_1() { return m_staticLine_1; }
521  wxStaticText* GetStaticTextConnection() { return m_staticTextConnection; }
522  wxChoice* GetChoiceConnection() { return m_choiceConnection; }
523  wxStaticText* GetStaticTextTurnsRatio() { return m_staticTextTurnsRatio; }
524  wxTextCtrl* GetTextCtrlTurnRatio() { return m_textCtrlTurnRatio; }
525  wxStaticText* GetStaticTextPhaseShift() { return m_staticTextPhaseShift; }
526  wxTextCtrl* GetTextCtrlPhaseShift() { return m_textCtrlPhaseShift; }
527  wxStaticText* GetStaticTextDeg() { return m_staticTextDeg; }
528  wxCheckBox* GetCheckUseTransformerPower() { return m_checkUseTransformerPower; }
529  wxPanel* GetPanelGeneral() { return m_panelGeneral; }
530  wxStaticText* GetStaticTextZeroResistance() { return m_staticTextZeroResistance; }
531  wxTextCtrl* GetTextCtrlZeroResistance() { return m_textCtrlZeroResistance; }
532  wxStaticText* GetStaticTextZeroReactance() { return m_staticTextZeroReactance; }
533  wxTextCtrl* GetTextCtrlZeroReactance() { return m_textCtrlZeroReactance; }
534  wxStaticText* GetStaticTextPrimResistance() { return m_staticTextPrimResistance; }
535  wxTextCtrl* GetTextCtrlPrimResistance() { return m_textCtrlPrimResistance; }
536  wxStaticText* GetStaticTextPrimReactance() { return m_staticTextPrimReactance; }
537  wxTextCtrl* GetTextCtrlPrimReactance() { return m_textCtrlPrimReactance; }
538  wxStaticText* GetStaticTextSecResistance() { return m_staticTextSecResistance; }
539  wxTextCtrl* GetTextCtrlSecResistance() { return m_textCtrlSecResistance; }
540  wxStaticText* GetStaticTextSecReactance() { return m_staticTextSecReactance; }
541  wxTextCtrl* GetTextCtrlSecReactance() { return m_textCtrlSecReactance; }
542  wxPanel* GetPanelFault() { return m_panelFault; }
543  wxNotebook* GetNotebook() { return m_notebook; }
544  wxButton* GetButtonStability() { return m_buttonStability; }
545  wxButton* GetButtonOK() { return m_buttonOK; }
546  wxButton* GetButtonCancel() { return m_buttonCancel; }
547  TransformerFormBase(wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Transformer"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize(-1,-1), long style = wxDEFAULT_DIALOG_STYLE);
548  virtual ~TransformerFormBase();
549 };
550 
551 
552 class LoadFormBase : public wxDialog
553 {
554 protected:
555  wxNotebook* m_notebook;
556  wxPanel* m_panelGeneral;
557  wxStaticText* m_staticTextName;
558  wxTextCtrl* m_textCtrlName;
559  wxStaticText* m_staticTextActivePower;
560  wxTextCtrl* m_textCtrlActivePower;
561  wxChoice* m_choiceActivePower;
562  wxStaticText* m_staticTextReactivePower;
563  wxTextCtrl* m_textCtrlReactivePower;
564  wxChoice* m_choiceReactivePower;
565  wxStaticText* m_staticTextType;
566  wxChoice* m_choiceType;
567  wxButton* m_buttonStabButton;
568  wxButton* m_buttonOK;
569  wxButton* m_ButtonCancel;
570 
571 protected:
572  virtual void OnStabilityButtonClick(wxCommandEvent& event) { event.Skip(); }
573  virtual void OnOnButtonClick(wxCommandEvent& event) { event.Skip(); }
574  virtual void OnCancelButtonClick(wxCommandEvent& event) { event.Skip(); }
575 
576 public:
577  wxStaticText* GetStaticTextName() { return m_staticTextName; }
578  wxTextCtrl* GetTextCtrlName() { return m_textCtrlName; }
579  wxStaticText* GetStaticTextActivePower() { return m_staticTextActivePower; }
580  wxTextCtrl* GetTextCtrlActivePower() { return m_textCtrlActivePower; }
581  wxChoice* GetChoiceActivePower() { return m_choiceActivePower; }
582  wxStaticText* GetStaticTextReactivePower() { return m_staticTextReactivePower; }
583  wxTextCtrl* GetTextCtrlReactivePower() { return m_textCtrlReactivePower; }
584  wxChoice* GetChoiceReactivePower() { return m_choiceReactivePower; }
585  wxStaticText* GetStaticTextType() { return m_staticTextType; }
586  wxChoice* GetChoiceType() { return m_choiceType; }
587  wxPanel* GetPanelGeneral() { return m_panelGeneral; }
588  wxNotebook* GetNotebook() { return m_notebook; }
589  wxButton* GetButtonStabButton() { return m_buttonStabButton; }
590  wxButton* GetButtonOK() { return m_buttonOK; }
591  wxButton* GetButtonCancel() { return m_ButtonCancel; }
592  LoadFormBase(wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Load"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize(-1,-1), long style = wxDEFAULT_DIALOG_STYLE);
593  virtual ~LoadFormBase();
594 };
595 
596 
597 class ReactiveShuntElementFormBase : public wxDialog
598 {
599 protected:
600  wxNotebook* m_notebook;
601  wxPanel* m_panelGeneral;
602  wxStaticText* m_staticTextName;
603  wxTextCtrl* m_textCtrlName;
604  wxStaticText* m_staticTextReactivePower;
605  wxTextCtrl* m_textCtrlReactivePower;
606  wxChoice* m_choiceReactivePower;
607  wxButton* m_buttonStabButton;
608  wxButton* m_buttonOK;
609  wxButton* m_buttonCancel;
610 
611 protected:
612  virtual void OnStabilityButtonClick(wxCommandEvent& event) { event.Skip(); }
613  virtual void OnOKButtonClick(wxCommandEvent& event) { event.Skip(); }
614  virtual void OnCancelButtonClick(wxCommandEvent& event) { event.Skip(); }
615 
616 public:
617  wxStaticText* GetStaticTextName() { return m_staticTextName; }
618  wxTextCtrl* GetTextCtrlName() { return m_textCtrlName; }
619  wxStaticText* GetStaticTextReactivePower() { return m_staticTextReactivePower; }
620  wxTextCtrl* GetTextCtrlReactivePower() { return m_textCtrlReactivePower; }
621  wxChoice* GetChoiceReactivePower() { return m_choiceReactivePower; }
622  wxPanel* GetPanelGeneral() { return m_panelGeneral; }
623  wxNotebook* GetNotebook() { return m_notebook; }
624  wxButton* GetButtonStabButton() { return m_buttonStabButton; }
625  wxButton* GetButtonOK() { return m_buttonOK; }
626  wxButton* GetButtonCancel() { return m_buttonCancel; }
627  ReactiveShuntElementFormBase(wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Reactive shunt element"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize(-1,-1), long style = wxDEFAULT_DIALOG_STYLE);
628  virtual ~ReactiveShuntElementFormBase();
629 };
630 
631 
632 class SwitchingFormBase : public wxDialog
633 {
634 protected:
635  wxPropertyGridManager* m_pgMgrSwitchingsProp;
636  wxPGProperty* m_pgPropTitle;
637  wxPGProperty* m_pgPropType;
638  wxPGProperty* m_pgPropTime;
639  wxButton* m_buttonInsert;
640  wxButton* m_buttonRemove;
641  wxButton* m_buttonUp;
642  wxButton* m_buttonDown;
643  wxStaticText* m_staticTextSwList;
644  wxListCtrl* m_listCtrlSwitchings;
645  wxButton* m_buttonOK;
646  wxButton* m_buttonCancel;
647 
648 protected:
649  virtual void OnChangeProperties(wxPropertyGridEvent& event) { event.Skip(); }
650  virtual void OnInsertButtonClick(wxCommandEvent& event) { event.Skip(); }
651  virtual void OnRemoveButtonClick(wxCommandEvent& event) { event.Skip(); }
652  virtual void OnUpButtonClick(wxCommandEvent& event) { event.Skip(); }
653  virtual void OnDownButtonClick(wxCommandEvent& event) { event.Skip(); }
654  virtual void OnSelectItem(wxListEvent& event) { event.Skip(); }
655  virtual void OnOKButtonClick(wxCommandEvent& event) { event.Skip(); }
656  virtual void OnCancelButtonClick(wxCommandEvent& event) { event.Skip(); }
657 
658 public:
659  wxPropertyGridManager* GetPgMgrSwitchingsProp() { return m_pgMgrSwitchingsProp; }
660  wxButton* GetButtonInsert() { return m_buttonInsert; }
661  wxButton* GetButtonRemove() { return m_buttonRemove; }
662  wxButton* GetButtonUp() { return m_buttonUp; }
663  wxButton* GetButtonDown() { return m_buttonDown; }
664  wxStaticText* GetStaticTextSwList() { return m_staticTextSwList; }
665  wxListCtrl* GetListCtrlSwitchings() { return m_listCtrlSwitchings; }
666  wxButton* GetButtonOK() { return m_buttonOK; }
667  wxButton* GetButtonCancel() { return m_buttonCancel; }
668  SwitchingFormBase(wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Switching"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize(-1,-1), long style = wxDEFAULT_DIALOG_STYLE);
669  virtual ~SwitchingFormBase();
670 };
671 
672 
673 class IndMotorFormBase : public wxDialog
674 {
675 protected:
676  wxNotebook* m_notebook;
677  wxPanel* m_panelGeneral;
678  wxStaticText* m_staticTextName;
679  wxTextCtrl* m_textCtrlName;
680  wxStaticText* m_staticTextActivePower;
681  wxTextCtrl* m_textCtrlActivePower;
682  wxChoice* m_choiceActivePower;
683  wxStaticText* m_staticTextReactivePower;
684  wxTextCtrl* m_textCtrlReactivePower;
685  wxChoice* m_choiceReactivePower;
686  wxButton* m_buttonStabButton;
687  wxButton* m_buttonOK;
688  wxButton* m_ButtonCancel;
689 
690 protected:
691  virtual void OnStabilityButtonClick(wxCommandEvent& event) { event.Skip(); }
692  virtual void OnOKButtonClick(wxCommandEvent& event) { event.Skip(); }
693  virtual void OnCancelButtonClick(wxCommandEvent& event) { event.Skip(); }
694 
695 public:
696  wxStaticText* GetStaticTextName() { return m_staticTextName; }
697  wxTextCtrl* GetTextCtrlName() { return m_textCtrlName; }
698  wxStaticText* GetStaticTextActivePower() { return m_staticTextActivePower; }
699  wxTextCtrl* GetTextCtrlActivePower() { return m_textCtrlActivePower; }
700  wxChoice* GetChoiceActivePower() { return m_choiceActivePower; }
701  wxStaticText* GetStaticTextReactivePower() { return m_staticTextReactivePower; }
702  wxTextCtrl* GetTextCtrlReactivePower() { return m_textCtrlReactivePower; }
703  wxChoice* GetChoiceReactivePower() { return m_choiceReactivePower; }
704  wxPanel* GetPanelGeneral() { return m_panelGeneral; }
705  wxNotebook* GetNotebook() { return m_notebook; }
706  wxButton* GetButtonStabButton() { return m_buttonStabButton; }
707  wxButton* GetButtonOK() { return m_buttonOK; }
708  wxButton* GetButtonCancel() { return m_ButtonCancel; }
709  IndMotorFormBase(wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Motor"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize(-1,-1), long style = wxDEFAULT_DIALOG_STYLE);
710  virtual ~IndMotorFormBase();
711 };
712 
713 
714 class TextFormBase : public wxDialog
715 {
716 protected:
717  wxNotebook* m_notebook;
718  wxPanel* m_panelGeneral;
719  wxStaticText* m_staticTextElement;
720  wxChoice* m_choiceElement;
721  wxStaticText* m_staticTextName;
722  wxChoice* m_choiceName;
723  wxStaticText* m_staticTextType;
724  wxChoice* m_choiceTextType;
725  wxStaticText* m_staticTextFromBus;
726  wxChoice* m_choiceTextFromBus;
727  wxStaticText* m_staticTextToBus;
728  wxChoice* m_choiceTextToBus;
729  wxStaticText* m_staticTextUnit;
730  wxChoice* m_choiceTextUnit;
731  wxStaticText* m_staticTextDecimal;
732  wxTextCtrl* m_textCtrlDecimal;
733  wxStaticText* m_staticTextPreview;
734  wxTextCtrl* m_textCtrlPreview;
735  wxButton* m_buttonOK;
736  wxButton* m_ButtonCancel;
737 
738 protected:
739  virtual void OnElementChoiceSelected(wxCommandEvent& event) { event.Skip(); }
740  virtual void OnNameChoiceSelected(wxCommandEvent& event) { event.Skip(); }
741  virtual void OnTypeChoiceSelected(wxCommandEvent& event) { event.Skip(); }
742  virtual void OnFromBusChoiceSelected(wxCommandEvent& event) { event.Skip(); }
743  virtual void OnToBusChoiceSelected(wxCommandEvent& event) { event.Skip(); }
744  virtual void OnUnitChoiceSelected(wxCommandEvent& event) { event.Skip(); }
745  virtual void OnTextEnter(wxCommandEvent& event) { event.Skip(); }
746  virtual void OnOKButtonClick(wxCommandEvent& event) { event.Skip(); }
747  virtual void OnCancelButtonClick(wxCommandEvent& event) { event.Skip(); }
748 
749 public:
750  wxStaticText* GetStaticTextElement() { return m_staticTextElement; }
751  wxChoice* GetChoiceElement() { return m_choiceElement; }
752  wxStaticText* GetStaticTextName() { return m_staticTextName; }
753  wxChoice* GetChoiceName() { return m_choiceName; }
754  wxStaticText* GetStaticTextType() { return m_staticTextType; }
755  wxChoice* GetChoiceTextType() { return m_choiceTextType; }
756  wxStaticText* GetStaticTextFromBus() { return m_staticTextFromBus; }
757  wxChoice* GetChoiceTextFromBus() { return m_choiceTextFromBus; }
758  wxStaticText* GetStaticTextToBus() { return m_staticTextToBus; }
759  wxChoice* GetChoiceTextToBus() { return m_choiceTextToBus; }
760  wxStaticText* GetStaticTextUnit() { return m_staticTextUnit; }
761  wxChoice* GetChoiceTextUnit() { return m_choiceTextUnit; }
762  wxStaticText* GetStaticTextDecimal() { return m_staticTextDecimal; }
763  wxTextCtrl* GetTextCtrlDecimal() { return m_textCtrlDecimal; }
764  wxStaticText* GetStaticTextPreview() { return m_staticTextPreview; }
765  wxTextCtrl* GetTextCtrlPreview() { return m_textCtrlPreview; }
766  wxPanel* GetPanelGeneral() { return m_panelGeneral; }
767  wxNotebook* GetNotebook() { return m_notebook; }
768  wxButton* GetButtonOK() { return m_buttonOK; }
769  wxButton* GetButtonCancel() { return m_ButtonCancel; }
770  TextFormBase(wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Text"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize(-1,-1), long style = wxDEFAULT_DIALOG_STYLE);
771  virtual ~TextFormBase();
772 };
773 
774 
775 class TransferFunctionFormBase : public wxDialog
776 {
777 protected:
778  wxNotebook* m_notebook;
779  wxPanel* m_panelGeneral;
780  wxStaticText* m_staticTextNumerator;
781  wxTextCtrl* m_textCtrlNumerator;
782  wxStaticText* m_staticTextDenominator;
783  wxTextCtrl* m_textCtrlDenominator;
784  wxButton* m_buttonOK;
785  wxButton* m_ButtonCancel;
786 
787 protected:
788  virtual void OnOKClick(wxCommandEvent& event) { event.Skip(); }
789  virtual void OnCancelClick(wxCommandEvent& event) { event.Skip(); }
790 
791 public:
792  wxStaticText* GetStaticTextNumerator() { return m_staticTextNumerator; }
793  wxTextCtrl* GetTextCtrlNumerator() { return m_textCtrlNumerator; }
794  wxStaticText* GetStaticTextDenominator() { return m_staticTextDenominator; }
795  wxTextCtrl* GetTextCtrlDenominator() { return m_textCtrlDenominator; }
796  wxPanel* GetPanelGeneral() { return m_panelGeneral; }
797  wxNotebook* GetNotebook() { return m_notebook; }
798  wxButton* GetButtonOK() { return m_buttonOK; }
799  wxButton* GetButtonCancel() { return m_ButtonCancel; }
800  TransferFunctionFormBase(wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Transfer function"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize(-1,-1), long style = wxDEFAULT_DIALOG_STYLE);
801  virtual ~TransferFunctionFormBase();
802 };
803 
804 
805 class SumFormBase : public wxDialog
806 {
807 protected:
808  wxNotebook* m_notebook;
809  wxPanel* m_panelGeneral;
810  wxStaticText* m_staticTextSigns;
811  wxTextCtrl* m_textCtrlSigns;
812  wxButton* m_buttonOK;
813  wxButton* m_ButtonCancel;
814 
815 protected:
816  virtual void OnOKClick(wxCommandEvent& event) { event.Skip(); }
817  virtual void OnCancelClick(wxCommandEvent& event) { event.Skip(); }
818 
819 public:
820  wxStaticText* GetStaticTextSigns() { return m_staticTextSigns; }
821  wxTextCtrl* GetTextCtrlSigns() { return m_textCtrlSigns; }
822  wxPanel* GetPanelGeneral() { return m_panelGeneral; }
823  wxNotebook* GetNotebook() { return m_notebook; }
824  wxButton* GetButtonOK() { return m_buttonOK; }
825  wxButton* GetButtonCancel() { return m_ButtonCancel; }
826  SumFormBase(wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Sum"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize(-1,-1), long style = wxDEFAULT_DIALOG_STYLE);
827  virtual ~SumFormBase();
828 };
829 
830 
831 class LimiterFormBase : public wxDialog
832 {
833 protected:
834  wxNotebook* m_notebook;
835  wxPanel* m_panelGeneral;
836  wxStaticText* m_staticTextUpLimiter;
837  wxTextCtrl* m_textCtrlUpLimit;
838  wxStaticText* m_staticTextLowLimit;
839  wxTextCtrl* m_textCtrlLowLimit;
840  wxButton* m_buttonOK;
841  wxButton* m_ButtonCancel;
842 
843 protected:
844  virtual void OnOKButtonClick(wxCommandEvent& event) { event.Skip(); }
845  virtual void OnCancelButtonClick(wxCommandEvent& event) { event.Skip(); }
846 
847 public:
848  wxStaticText* GetStaticTextUpLimiter() { return m_staticTextUpLimiter; }
849  wxTextCtrl* GetTextCtrlUpLimit() { return m_textCtrlUpLimit; }
850  wxStaticText* GetStaticTextLowLimit() { return m_staticTextLowLimit; }
851  wxTextCtrl* GetTextCtrlLowLimit() { return m_textCtrlLowLimit; }
852  wxPanel* GetPanelGeneral() { return m_panelGeneral; }
853  wxNotebook* GetNotebook() { return m_notebook; }
854  wxButton* GetButtonOK() { return m_buttonOK; }
855  wxButton* GetButtonCancel() { return m_ButtonCancel; }
856  LimiterFormBase(wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Limiter"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize(-1,-1), long style = wxDEFAULT_DIALOG_STYLE);
857  virtual ~LimiterFormBase();
858 };
859 
860 
861 class RateLimiterFormBase : public wxDialog
862 {
863 protected:
864  wxNotebook* m_notebook;
865  wxPanel* m_panelGeneral;
866  wxStaticText* m_staticTextUpLimiter;
867  wxTextCtrl* m_textCtrlUpLimit;
868  wxStaticText* m_staticTextLowLimit;
869  wxTextCtrl* m_textCtrlLowLimit;
870  wxButton* m_buttonOK;
871  wxButton* m_ButtonCancel;
872 
873 protected:
874  virtual void OnOKButtonClick(wxCommandEvent& event) { event.Skip(); }
875  virtual void OnCancelButtonClick(wxCommandEvent& event) { event.Skip(); }
876 
877 public:
878  wxStaticText* GetStaticTextUpLimiter() { return m_staticTextUpLimiter; }
879  wxTextCtrl* GetTextCtrlUpLimit() { return m_textCtrlUpLimit; }
880  wxStaticText* GetStaticTextLowLimit() { return m_staticTextLowLimit; }
881  wxTextCtrl* GetTextCtrlLowLimit() { return m_textCtrlLowLimit; }
882  wxPanel* GetPanelGeneral() { return m_panelGeneral; }
883  wxNotebook* GetNotebook() { return m_notebook; }
884  wxButton* GetButtonOK() { return m_buttonOK; }
885  wxButton* GetButtonCancel() { return m_ButtonCancel; }
886  RateLimiterFormBase(wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Rate limiter"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize(-1,-1), long style = wxDEFAULT_DIALOG_STYLE);
887  virtual ~RateLimiterFormBase();
888 };
889 
890 
891 class ExponentialFormBase : public wxDialog
892 {
893 protected:
894  wxNotebook* m_notebook;
895  wxPanel* m_panelGeneral;
896  wxStaticText* m_staticTextExp;
897  wxStaticText* m_staticTextAValue;
898  wxTextCtrl* m_textCtrlAValue;
899  wxStaticText* m_staticTextBValue;
900  wxTextCtrl* m_textCtrlBValue;
901  wxButton* m_buttonOK;
902  wxButton* m_buttonCancel;
903 
904 protected:
905  virtual void OnOKButtonClick(wxCommandEvent& event) { event.Skip(); }
906  virtual void OnCancelButtonClick(wxCommandEvent& event) { event.Skip(); }
907 
908 public:
909  wxStaticText* GetStaticTextExp() { return m_staticTextExp; }
910  wxStaticText* GetStaticTextAValue() { return m_staticTextAValue; }
911  wxTextCtrl* GetTextCtrlAValue() { return m_textCtrlAValue; }
912  wxStaticText* GetStaticTextBValue() { return m_staticTextBValue; }
913  wxTextCtrl* GetTextCtrlBValue() { return m_textCtrlBValue; }
914  wxPanel* GetPanelGeneral() { return m_panelGeneral; }
915  wxNotebook* GetNotebook() { return m_notebook; }
916  wxButton* GetButtonOK() { return m_buttonOK; }
917  wxButton* GetButtonCancel() { return m_buttonCancel; }
918  ExponentialFormBase(wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Exponential"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize(-1,-1), long style = wxDEFAULT_DIALOG_STYLE);
919  virtual ~ExponentialFormBase();
920 };
921 
922 
923 class ConstantFormBase : public wxDialog
924 {
925 protected:
926  wxNotebook* m_notebook;
927  wxPanel* m_panelGeneral;
928  wxStaticText* m_staticTextValue;
929  wxTextCtrl* m_textCtrlValue;
930  wxButton* m_buttonOK;
931  wxButton* m_buttonCancel;
932 
933 protected:
934  virtual void OnOKButtonClick(wxCommandEvent& event) { event.Skip(); }
935  virtual void OnCancelButtonClick(wxCommandEvent& event) { event.Skip(); }
936 
937 public:
938  wxStaticText* GetStaticTextValue() { return m_staticTextValue; }
939  wxTextCtrl* GetTextCtrlValue() { return m_textCtrlValue; }
940  wxPanel* GetPanelGeneral() { return m_panelGeneral; }
941  wxNotebook* GetNotebook() { return m_notebook; }
942  wxButton* GetButtonOK() { return m_buttonOK; }
943  wxButton* GetButtonCancel() { return m_buttonCancel; }
944  ConstantFormBase(wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Constant"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize(-1,-1), long style = wxDEFAULT_DIALOG_STYLE);
945  virtual ~ConstantFormBase();
946 };
947 
948 
949 class GainFormBase : public wxDialog
950 {
951 protected:
952  wxNotebook* m_notebook;
953  wxPanel* m_panelGeneral;
954  wxStaticText* m_staticTextValue;
955  wxTextCtrl* m_textCtrlValue;
956  wxButton* m_buttonOK;
957  wxButton* m_buttonCancel;
958 
959 protected:
960  virtual void OnOKButtonClick(wxCommandEvent& event) { event.Skip(); }
961  virtual void OnCancelButtonClick(wxCommandEvent& event) { event.Skip(); }
962 
963 public:
964  wxStaticText* GetStaticTextValue() { return m_staticTextValue; }
965  wxTextCtrl* GetTextCtrlValue() { return m_textCtrlValue; }
966  wxPanel* GetPanelGeneral() { return m_panelGeneral; }
967  wxNotebook* GetNotebook() { return m_notebook; }
968  wxButton* GetButtonOK() { return m_buttonOK; }
969  wxButton* GetButtonCancel() { return m_buttonCancel; }
970  GainFormBase(wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Gain"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize(-1,-1), long style = wxDEFAULT_DIALOG_STYLE);
971  virtual ~GainFormBase();
972 };
973 
974 
975 class IOControlFormBase : public wxDialog
976 {
977 protected:
978  wxNotebook* m_notebook;
979  wxPanel* m_panelGeneral;
980  wxCheckBox* m_checkBoxInput;
981  wxChoice* m_choiceInput;
982  wxCheckBox* m_checkBoxOutput;
983  wxChoice* m_choiceOutput;
984  wxButton* m_buttonOK;
985  wxButton* m_ButtonCancel;
986 
987 protected:
988  virtual void OnInputChecked(wxCommandEvent& event) { event.Skip(); }
989  virtual void OnOutputChecked(wxCommandEvent& event) { event.Skip(); }
990  virtual void OnOKButtonClick(wxCommandEvent& event) { event.Skip(); }
991  virtual void OnCancelButtonClick(wxCommandEvent& event) { event.Skip(); }
992 
993 public:
994  wxCheckBox* GetCheckBoxInput() { return m_checkBoxInput; }
995  wxChoice* GetChoiceInput() { return m_choiceInput; }
996  wxCheckBox* GetCheckBoxOutput() { return m_checkBoxOutput; }
997  wxChoice* GetChoiceOutput() { return m_choiceOutput; }
998  wxPanel* GetPanelGeneral() { return m_panelGeneral; }
999  wxNotebook* GetNotebook() { return m_notebook; }
1000  wxButton* GetButtonOK() { return m_buttonOK; }
1001  wxButton* GetButtonCancel() { return m_ButtonCancel; }
1002  IOControlFormBase(wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Input / Output"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize(-1,-1), long style = wxDEFAULT_DIALOG_STYLE);
1003  virtual ~IOControlFormBase();
1004 };
1005 
1006 #endif
+
1 // This file was auto-generated by codelite's wxCrafter Plugin
3 // wxCrafter project file: ElementForm.wxcp
4 // Do not modify this file by hand!
6 
7 #ifndef _PSP_PROJECT_ELEMENTFORM_BASE_CLASSES_H
8 #define _PSP_PROJECT_ELEMENTFORM_BASE_CLASSES_H
9 
10 #include <wx/settings.h>
11 #include <wx/xrc/xmlres.h>
12 #include <wx/xrc/xh_bmp.h>
13 #include <wx/dialog.h>
14 #include <wx/iconbndl.h>
15 #include <wx/artprov.h>
16 #include <wx/sizer.h>
17 #include <wx/notebook.h>
18 #include <wx/panel.h>
19 #include <wx/imaglist.h>
20 #include <wx/stattext.h>
21 #include <wx/textctrl.h>
22 #include <wx/choice.h>
23 #include <wx/arrstr.h>
24 #include <wx/checkbox.h>
25 #include <wx/button.h>
26 #include <wx/statbox.h>
27 #include <wx/statline.h>
28 #include <wx/propgrid/manager.h>
29 #include <wx/propgrid/property.h>
30 #include <wx/propgrid/advprops.h>
31 #include <wx/listctrl.h>
32 #if wxVERSION_NUMBER >= 2900
33 #include <wx/persist.h>
34 #include <wx/persist/toplevel.h>
35 #include <wx/persist/bookctrl.h>
36 #include <wx/persist/treebook.h>
37 #endif
38 
39 #ifdef WXC_FROM_DIP
40 #undef WXC_FROM_DIP
41 #endif
42 #if wxVERSION_NUMBER >= 3100
43 #define WXC_FROM_DIP(x) wxWindow::FromDIP(x, NULL)
44 #else
45 #define WXC_FROM_DIP(x) x
46 #endif
47 
48 
49 class BusFormBase : public wxDialog
50 {
51 protected:
52  wxNotebook* m_notebook;
53  wxPanel* m_panelGeneral;
54  wxStaticText* m_staticTextName;
55  wxTextCtrl* m_textCtrlName;
56  wxStaticText* m_staticTextNomVoltage;
57  wxTextCtrl* m_textCtrlNomVoltage;
58  wxChoice* m_choiceNomVoltage;
59  wxCheckBox* m_checkBoxCtrlVoltage;
60  wxTextCtrl* m_textCtrlCtrlVoltage;
61  wxChoice* m_choiceCtrlVoltage;
62  wxCheckBox* m_checkBoxSlackBus;
63  wxPanel* m_panelFault;
64  wxCheckBox* m_checkBoxFault;
65  wxStaticText* m_staticTextFaultType;
66  wxChoice* m_choiceFaultType;
67  wxStaticText* m_staticTextFaultPlace;
68  wxChoice* m_choiceFaultPlace;
69  wxStaticText* m_staticTextFaultResistance;
70  wxTextCtrl* m_textCtrlFaultResistance;
71  wxStaticText* m_staticTextPU_1;
72  wxStaticText* m_staticTextReactance;
73  wxTextCtrl* m_textCtrlFaultReactance;
74  wxStaticText* m_staticTextPU_2;
75  wxPanel* m_panelStability;
76  wxCheckBox* m_checkBoxPlotData;
77  wxCheckBox* m_checkBoxStabFault;
78  wxStaticText* m_staticTextStabFaultTime;
79  wxTextCtrl* m_textCtrlStabFaultTime;
80  wxStaticText* m_staticTextS_1;
81  wxStaticText* m_staticTextStabFaultLength;
82  wxTextCtrl* m_textCtrlStabFaultLength;
83  wxStaticText* m_staticTextS_2;
84  wxStaticText* m_staticTextStabFaultResistance;
85  wxTextCtrl* m_textCtrlStabFaultResistance;
86  wxStaticText* m_staticTextPU_3;
87  wxStaticText* m_staticTextStabFaultReactance;
88  wxTextCtrl* m_textCtrlStabFaultReactance;
89  wxStaticText* m_staticTextPU_4;
90  wxButton* m_buttonOK;
91  wxButton* m_ButtonCancel;
92 
93 protected:
94  virtual void OnNominalVoltageChoice(wxCommandEvent& event) { event.Skip(); }
95  virtual void OnControlledVoltageClick(wxCommandEvent& event) { event.Skip(); }
96  virtual void OnInsertFaultClick(wxCommandEvent& event) { event.Skip(); }
97  virtual void OnFaultTypeChoice(wxCommandEvent& event) { event.Skip(); }
98  virtual void OnInsertStabFaultClick(wxCommandEvent& event) { event.Skip(); }
99  virtual void OnButtonOKClick(wxCommandEvent& event) { event.Skip(); }
100  virtual void OnButtonCancelClick(wxCommandEvent& event) { event.Skip(); }
101 
102 public:
103  wxStaticText* GetStaticTextName() { return m_staticTextName; }
104  wxTextCtrl* GetTextCtrlName() { return m_textCtrlName; }
105  wxStaticText* GetStaticTextNomVoltage() { return m_staticTextNomVoltage; }
106  wxTextCtrl* GetTextCtrlNomVoltage() { return m_textCtrlNomVoltage; }
107  wxChoice* GetChoiceNomVoltage() { return m_choiceNomVoltage; }
108  wxCheckBox* GetCheckBoxCtrlVoltage() { return m_checkBoxCtrlVoltage; }
109  wxTextCtrl* GetTextCtrlCtrlVoltage() { return m_textCtrlCtrlVoltage; }
110  wxChoice* GetChoiceCtrlVoltage() { return m_choiceCtrlVoltage; }
111  wxCheckBox* GetCheckBoxSlackBus() { return m_checkBoxSlackBus; }
112  wxPanel* GetPanelGeneral() { return m_panelGeneral; }
113  wxCheckBox* GetCheckBoxFault() { return m_checkBoxFault; }
114  wxStaticText* GetStaticTextFaultType() { return m_staticTextFaultType; }
115  wxChoice* GetChoiceFaultType() { return m_choiceFaultType; }
116  wxStaticText* GetStaticTextFaultPlace() { return m_staticTextFaultPlace; }
117  wxChoice* GetChoiceFaultPlace() { return m_choiceFaultPlace; }
118  wxStaticText* GetStaticTextFaultResistance() { return m_staticTextFaultResistance; }
119  wxTextCtrl* GetTextCtrlFaultResistance() { return m_textCtrlFaultResistance; }
120  wxStaticText* GetStaticTextPU_1() { return m_staticTextPU_1; }
121  wxStaticText* GetStaticTextReactance() { return m_staticTextReactance; }
122  wxTextCtrl* GetTextCtrlFaultReactance() { return m_textCtrlFaultReactance; }
123  wxStaticText* GetStaticTextPU_2() { return m_staticTextPU_2; }
124  wxPanel* GetPanelFault() { return m_panelFault; }
125  wxCheckBox* GetCheckBoxPlotData() { return m_checkBoxPlotData; }
126  wxCheckBox* GetCheckBoxStabFault() { return m_checkBoxStabFault; }
127  wxStaticText* GetStaticTextStabFaultTime() { return m_staticTextStabFaultTime; }
128  wxTextCtrl* GetTextCtrlStabFaultTime() { return m_textCtrlStabFaultTime; }
129  wxStaticText* GetStaticTextS_1() { return m_staticTextS_1; }
130  wxStaticText* GetStaticTextStabFaultLength() { return m_staticTextStabFaultLength; }
131  wxTextCtrl* GetTextCtrlStabFaultLength() { return m_textCtrlStabFaultLength; }
132  wxStaticText* GetStaticTextS_2() { return m_staticTextS_2; }
133  wxStaticText* GetStaticTextStabFaultResistance() { return m_staticTextStabFaultResistance; }
134  wxTextCtrl* GetTextCtrlStabFaultResistance() { return m_textCtrlStabFaultResistance; }
135  wxStaticText* GetStaticTextPU_3() { return m_staticTextPU_3; }
136  wxStaticText* GetStaticTextStabFaultReactance() { return m_staticTextStabFaultReactance; }
137  wxTextCtrl* GetTextCtrlStabFaultReactance() { return m_textCtrlStabFaultReactance; }
138  wxStaticText* GetStaticTextPU_4() { return m_staticTextPU_4; }
139  wxPanel* GetPanelStability() { return m_panelStability; }
140  wxNotebook* GetNotebook() { return m_notebook; }
141  wxButton* GetButtonOK() { return m_buttonOK; }
142  wxButton* GetButtonCancel() { return m_ButtonCancel; }
143  BusFormBase(wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Bus"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize(-1,-1), long style = wxDEFAULT_DIALOG_STYLE);
144  virtual ~BusFormBase();
145 };
146 
147 
148 class SyncMachineFormBase : public wxDialog
149 {
150 protected:
151  wxNotebook* m_notebook;
152  wxPanel* m_panelGeneral;
153  wxStaticText* m_staticTextName;
154  wxTextCtrl* m_textCtrlName;
155  wxStaticText* m_staticTextNominalPower;
156  wxTextCtrl* m_textCtrlnominalPower;
157  wxChoice* m_choiceNominalPower;
158  wxStaticText* m_staticTextActivePower;
159  wxTextCtrl* m_textCtrlActivePower;
160  wxChoice* m_choiceActivePower;
161  wxStaticText* m_staticTextReactivePower;
162  wxTextCtrl* m_textCtrlReactivePower;
163  wxChoice* m_choiceReactivePower;
164  wxCheckBox* m_checkBoxMaxReactive;
165  wxTextCtrl* m_textCtrlMaxRectivePower;
166  wxChoice* m_choiceMaxRectivePower;
167  wxCheckBox* m_checkBoxMinReactive;
168  wxTextCtrl* m_textCtrlMinRectivePower;
169  wxChoice* m_choiceMinRectivePower;
170  wxCheckBox* m_checkBoxUseMachinePower;
171  wxPanel* m_panelFault;
172  wxStaticText* m_staticTextPosResistance;
173  wxTextCtrl* m_textCtrlPosResistance;
174  wxStaticText* m_staticTextPosReactance;
175  wxTextCtrl* m_textCtrlPosReactance;
176  wxStaticText* m_staticTextNegResistance;
177  wxTextCtrl* m_textCtrlNegResistance;
178  wxStaticText* m_staticTextNegReactance;
179  wxTextCtrl* m_textCtrlNegReactance;
180  wxStaticText* m_staticTextZeroResistance;
181  wxTextCtrl* m_textCtrlZeroResistance;
182  wxStaticText* m_staticTextZeroReactance;
183  wxTextCtrl* m_textCtrlZeroReactance;
184  wxStaticText* m_staticTextGrdResistance;
185  wxTextCtrl* m_textCtrlGrdResistance;
186  wxStaticText* m_staticTextGrdReactance;
187  wxTextCtrl* m_textCtrlGrdReactance;
188  wxCheckBox* m_checkBoxGroundNeutral;
189  wxButton* m_buttonStab;
190  wxButton* m_buttonOK;
191  wxButton* m_ButtonCancel;
192 
193 protected:
194  virtual void OnCheckMaxReactive(wxCommandEvent& event) { event.Skip(); }
195  virtual void OnCheckMinReactive(wxCommandEvent& event) { event.Skip(); }
196  virtual void OnStabilityButtonClick(wxCommandEvent& event) { event.Skip(); }
197  virtual void OnOKButtonClick(wxCommandEvent& event) { event.Skip(); }
198  virtual void OnCancelButtonClick(wxCommandEvent& event) { event.Skip(); }
199 
200 public:
201  wxStaticText* GetStaticTextName() { return m_staticTextName; }
202  wxTextCtrl* GetTextCtrlName() { return m_textCtrlName; }
203  wxStaticText* GetStaticTextNominalPower() { return m_staticTextNominalPower; }
204  wxTextCtrl* GetTextCtrlnominalPower() { return m_textCtrlnominalPower; }
205  wxChoice* GetChoiceNominalPower() { return m_choiceNominalPower; }
206  wxStaticText* GetStaticTextActivePower() { return m_staticTextActivePower; }
207  wxTextCtrl* GetTextCtrlActivePower() { return m_textCtrlActivePower; }
208  wxChoice* GetChoiceActivePower() { return m_choiceActivePower; }
209  wxStaticText* GetStaticTextReactivePower() { return m_staticTextReactivePower; }
210  wxTextCtrl* GetTextCtrlReactivePower() { return m_textCtrlReactivePower; }
211  wxChoice* GetChoiceReactivePower() { return m_choiceReactivePower; }
212  wxCheckBox* GetCheckBoxMaxReactive() { return m_checkBoxMaxReactive; }
213  wxTextCtrl* GetTextCtrlMaxRectivePower() { return m_textCtrlMaxRectivePower; }
214  wxChoice* GetChoiceMaxRectivePower() { return m_choiceMaxRectivePower; }
215  wxCheckBox* GetCheckBoxMinReactive() { return m_checkBoxMinReactive; }
216  wxTextCtrl* GetTextCtrlMinRectivePower() { return m_textCtrlMinRectivePower; }
217  wxChoice* GetChoiceMinRectivePower() { return m_choiceMinRectivePower; }
218  wxCheckBox* GetCheckBoxUseMachinePower() { return m_checkBoxUseMachinePower; }
219  wxPanel* GetPanelGeneral() { return m_panelGeneral; }
220  wxStaticText* GetStaticTextPosResistance() { return m_staticTextPosResistance; }
221  wxTextCtrl* GetTextCtrlPosResistance() { return m_textCtrlPosResistance; }
222  wxStaticText* GetStaticTextPosReactance() { return m_staticTextPosReactance; }
223  wxTextCtrl* GetTextCtrlPosReactance() { return m_textCtrlPosReactance; }
224  wxStaticText* GetStaticTextNegResistance() { return m_staticTextNegResistance; }
225  wxTextCtrl* GetTextCtrlNegResistance() { return m_textCtrlNegResistance; }
226  wxStaticText* GetStaticTextNegReactance() { return m_staticTextNegReactance; }
227  wxTextCtrl* GetTextCtrlNegReactance() { return m_textCtrlNegReactance; }
228  wxStaticText* GetStaticTextZeroResistance() { return m_staticTextZeroResistance; }
229  wxTextCtrl* GetTextCtrlZeroResistance() { return m_textCtrlZeroResistance; }
230  wxStaticText* GetStaticTextZeroReactance() { return m_staticTextZeroReactance; }
231  wxTextCtrl* GetTextCtrlZeroReactance() { return m_textCtrlZeroReactance; }
232  wxStaticText* GetStaticTextGrdResistance() { return m_staticTextGrdResistance; }
233  wxTextCtrl* GetTextCtrlGrdResistance() { return m_textCtrlGrdResistance; }
234  wxStaticText* GetStaticTextGrdReactance() { return m_staticTextGrdReactance; }
235  wxTextCtrl* GetTextCtrlGrdReactance() { return m_textCtrlGrdReactance; }
236  wxCheckBox* GetCheckBoxGroundNeutral() { return m_checkBoxGroundNeutral; }
237  wxPanel* GetPanelFault() { return m_panelFault; }
238  wxNotebook* GetNotebook() { return m_notebook; }
239  wxButton* GetButtonStab() { return m_buttonStab; }
240  wxButton* GetButtonOK() { return m_buttonOK; }
241  wxButton* GetButtonCancel() { return m_ButtonCancel; }
242  SyncMachineFormBase(wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Generator"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize(-1,-1), long style = wxDEFAULT_DIALOG_STYLE);
243  virtual ~SyncMachineFormBase();
244 };
245 
246 
247 class GeneratorStabFormBase : public wxDialog
248 {
249 protected:
250  wxCheckBox* m_checkBoxPlotSyncMachine;
251  wxStaticText* m_staticTextInertia;
252  wxTextCtrl* m_textCtrlInertia;
253  wxStaticText* m_staticTextS_1;
254  wxStaticText* m_staticTextDamping;
255  wxTextCtrl* m_textCtrlDamping;
256  wxStaticText* m_staticTextPU_1;
257  wxCheckBox* m_checkBoxUseAVR;
258  wxButton* m_buttonEditAVR;
259  wxCheckBox* m_checkBoxUseSG;
260  wxButton* m_buttonEditSG;
261  wxStaticLine* m_staticLine_1;
262  wxStaticText* m_staticTextRa;
263  wxTextCtrl* m_textCtrlRa;
264  wxStaticText* m_staticTextPU_2;
265  wxStaticText* m_staticTextXp;
266  wxTextCtrl* m_textCtrlXp;
267  wxStaticText* m_staticTextPU_9;
268  wxStaticText* m_staticTextSat;
269  wxTextCtrl* m_textCtrlSat;
270  wxStaticText* m_staticTextPU_10;
271  wxStaticText* m_staticTextSyncXd;
272  wxTextCtrl* m_textCtrlSyncXd;
273  wxStaticText* m_staticTextPU_3;
274  wxStaticText* m_staticTextSyncXq;
275  wxTextCtrl* m_textCtrlSyncXq;
276  wxStaticText* m_staticTextPU_4;
277  wxStaticText* m_staticTextTranXd;
278  wxTextCtrl* m_textCtrlTranXd;
279  wxStaticText* m_staticTextPU_5;
280  wxStaticText* m_staticTextTranXq;
281  wxTextCtrl* m_textCtrlTranXq;
282  wxStaticText* m_staticTextPU_6;
283  wxStaticText* m_staticTextTranTd0;
284  wxTextCtrl* m_textCtrlTranTd0;
285  wxStaticText* m_staticTextS_2;
286  wxStaticText* m_staticTextTranTq0;
287  wxTextCtrl* m_textCtrlTranTq0;
288  wxStaticText* m_staticTextS_3;
289  wxStaticText* m_staticTextSubXd;
290  wxTextCtrl* m_textCtrlSubXd;
291  wxStaticText* m_staticTextPU_7;
292  wxStaticText* m_staticTextSubXq;
293  wxTextCtrl* m_textCtrlSubXq;
294  wxStaticText* m_staticTextPU_8;
295  wxStaticText* m_staticTextSubTd0;
296  wxTextCtrl* m_textCtrlSubTd0;
297  wxStaticText* m_staticTextS_4;
298  wxStaticText* m_staticTextSubTq0;
299  wxTextCtrl* m_textCtrlSubTq0;
300  wxStaticText* m_staticTextS_5;
301  wxButton* m_buttonSwitching;
302  wxButton* m_buttonOK;
303  wxButton* m_ButtonCancel;
304 
305 protected:
306  virtual void UseAVRClick(wxCommandEvent& event) { event.Skip(); }
307  virtual void OnEditAVRButtonClick(wxCommandEvent& event) { event.Skip(); }
308  virtual void UseSGClick(wxCommandEvent& event) { event.Skip(); }
309  virtual void OnSpeedGovernorButtonClick(wxCommandEvent& event) { event.Skip(); }
310  virtual void OnSwitchingButtonClick(wxCommandEvent& event) { event.Skip(); }
311  virtual void OnOKButtonClick(wxCommandEvent& event) { event.Skip(); }
312  virtual void OnCancelButtonClick(wxCommandEvent& event) { event.Skip(); }
313 
314 public:
315  wxCheckBox* GetCheckBoxPlotSyncMachine() { return m_checkBoxPlotSyncMachine; }
316  wxStaticText* GetStaticTextInertia() { return m_staticTextInertia; }
317  wxTextCtrl* GetTextCtrlInertia() { return m_textCtrlInertia; }
318  wxStaticText* GetStaticTextS_1() { return m_staticTextS_1; }
319  wxStaticText* GetStaticTextDamping() { return m_staticTextDamping; }
320  wxTextCtrl* GetTextCtrlDamping() { return m_textCtrlDamping; }
321  wxStaticText* GetStaticTextPU_1() { return m_staticTextPU_1; }
322  wxCheckBox* GetCheckBoxUseAVR() { return m_checkBoxUseAVR; }
323  wxButton* GetButtonEditAVR() { return m_buttonEditAVR; }
324  wxCheckBox* GetCheckBoxUseSG() { return m_checkBoxUseSG; }
325  wxButton* GetButtonEditSG() { return m_buttonEditSG; }
326  wxStaticLine* GetStaticLine_1() { return m_staticLine_1; }
327  wxStaticText* GetStaticTextRa() { return m_staticTextRa; }
328  wxTextCtrl* GetTextCtrlRa() { return m_textCtrlRa; }
329  wxStaticText* GetStaticTextPU_2() { return m_staticTextPU_2; }
330  wxStaticText* GetStaticTextXp() { return m_staticTextXp; }
331  wxTextCtrl* GetTextCtrlXp() { return m_textCtrlXp; }
332  wxStaticText* GetStaticTextPU_9() { return m_staticTextPU_9; }
333  wxStaticText* GetStaticTextSat() { return m_staticTextSat; }
334  wxTextCtrl* GetTextCtrlSat() { return m_textCtrlSat; }
335  wxStaticText* GetStaticTextPU_10() { return m_staticTextPU_10; }
336  wxStaticText* GetStaticTextSyncXd() { return m_staticTextSyncXd; }
337  wxTextCtrl* GetTextCtrlSyncXd() { return m_textCtrlSyncXd; }
338  wxStaticText* GetStaticTextPU_3() { return m_staticTextPU_3; }
339  wxStaticText* GetStaticTextSyncXq() { return m_staticTextSyncXq; }
340  wxTextCtrl* GetTextCtrlSyncXq() { return m_textCtrlSyncXq; }
341  wxStaticText* GetStaticTextPU_4() { return m_staticTextPU_4; }
342  wxStaticText* GetStaticTextTranXd() { return m_staticTextTranXd; }
343  wxTextCtrl* GetTextCtrlTranXd() { return m_textCtrlTranXd; }
344  wxStaticText* GetStaticTextPU_5() { return m_staticTextPU_5; }
345  wxStaticText* GetStaticTextTranXq() { return m_staticTextTranXq; }
346  wxTextCtrl* GetTextCtrlTranXq() { return m_textCtrlTranXq; }
347  wxStaticText* GetStaticTextPU_6() { return m_staticTextPU_6; }
348  wxStaticText* GetStaticTextTranTd0() { return m_staticTextTranTd0; }
349  wxTextCtrl* GetTextCtrlTranTd0() { return m_textCtrlTranTd0; }
350  wxStaticText* GetStaticTextS_2() { return m_staticTextS_2; }
351  wxStaticText* GetStaticTextTranTq0() { return m_staticTextTranTq0; }
352  wxTextCtrl* GetTextCtrlTranTq0() { return m_textCtrlTranTq0; }
353  wxStaticText* GetStaticTextS_3() { return m_staticTextS_3; }
354  wxStaticText* GetStaticTextSubXd() { return m_staticTextSubXd; }
355  wxTextCtrl* GetTextCtrlSubXd() { return m_textCtrlSubXd; }
356  wxStaticText* GetStaticTextPU_7() { return m_staticTextPU_7; }
357  wxStaticText* GetStaticTextSubXq() { return m_staticTextSubXq; }
358  wxTextCtrl* GetTextCtrlSubXq() { return m_textCtrlSubXq; }
359  wxStaticText* GetStaticTextPU_8() { return m_staticTextPU_8; }
360  wxStaticText* GetStaticTextSubTd0() { return m_staticTextSubTd0; }
361  wxTextCtrl* GetTextCtrlSubTd0() { return m_textCtrlSubTd0; }
362  wxStaticText* GetStaticTextS_4() { return m_staticTextS_4; }
363  wxStaticText* GetStaticTextSubTq0() { return m_staticTextSubTq0; }
364  wxTextCtrl* GetTextCtrlSubTq0() { return m_textCtrlSubTq0; }
365  wxStaticText* GetStaticTextS_5() { return m_staticTextS_5; }
366  wxButton* GetButtonSwitching() { return m_buttonSwitching; }
367  wxButton* GetButtonOK() { return m_buttonOK; }
368  wxButton* GetButtonCancel() { return m_ButtonCancel; }
369  GeneratorStabFormBase(wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Generator: Stability"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize(-1,-1), long style = wxDEFAULT_DIALOG_STYLE);
370  virtual ~GeneratorStabFormBase();
371 };
372 
373 
374 class LineFormBase : public wxDialog
375 {
376 protected:
377  wxNotebook* m_notebook;
378  wxPanel* m_panelGeneral;
379  wxStaticText* m_staticTextName;
380  wxTextCtrl* m_textCtrlName;
381  wxStaticText* m_staticTextNominalVoltage;
382  wxStaticText* m_staticTextNominalVoltageValue;
383  wxStaticText* m_staticTextNominalPower;
384  wxTextCtrl* m_textCtrlNominalPower;
385  wxChoice* m_choiceNominalPower;
386  wxStaticText* m_staticTextResistance;
387  wxTextCtrl* m_textCtrlResistance;
388  wxChoice* m_choiceResistance;
389  wxStaticText* m_staticTextReactance;
390  wxTextCtrl* m_textCtrlReactance;
391  wxChoice* m_choiceReactance;
392  wxStaticText* m_staticTextSusceptance;
393  wxTextCtrl* m_textCtrlSusceptance;
394  wxChoice* m_choiceSusceptance;
395  wxStaticText* m_staticTextLineSize;
396  wxTextCtrl* m_textCtrlLineSize;
397  wxStaticText* m_staticTextKM;
398  wxCheckBox* m_checkUseLinePower;
399  wxPanel* m_panelFault;
400  wxStaticText* m_staticTextZeroResistance;
401  wxTextCtrl* m_textCtrlZeroResistance;
402  wxStaticText* m_staticTextZeroReactance;
403  wxTextCtrl* m_textCtrlZeroReactance;
404  wxStaticText* m_staticTextZeroSusceptance;
405  wxTextCtrl* m_textCtrlZeroSusceptance;
406  wxButton* m_buttonStability;
407  wxButton* m_buttonOK;
408  wxButton* m_buttonCancel;
409 
410 protected:
411  virtual void OnStabilityButtonClick(wxCommandEvent& event) { event.Skip(); }
412  virtual void OnOKButtonClick(wxCommandEvent& event) { event.Skip(); }
413  virtual void OnCancelButtonClick(wxCommandEvent& event) { event.Skip(); }
414 
415 public:
416  wxStaticText* GetStaticTextName() { return m_staticTextName; }
417  wxTextCtrl* GetTextCtrlName() { return m_textCtrlName; }
418  wxStaticText* GetStaticTextNominalVoltage() { return m_staticTextNominalVoltage; }
419  wxStaticText* GetStaticTextNominalVoltageValue() { return m_staticTextNominalVoltageValue; }
420  wxStaticText* GetStaticTextNominalPower() { return m_staticTextNominalPower; }
421  wxTextCtrl* GetTextCtrlNominalPower() { return m_textCtrlNominalPower; }
422  wxChoice* GetChoiceNominalPower() { return m_choiceNominalPower; }
423  wxStaticText* GetStaticTextResistance() { return m_staticTextResistance; }
424  wxTextCtrl* GetTextCtrlResistance() { return m_textCtrlResistance; }
425  wxChoice* GetChoiceResistance() { return m_choiceResistance; }
426  wxStaticText* GetStaticTextReactance() { return m_staticTextReactance; }
427  wxTextCtrl* GetTextCtrlReactance() { return m_textCtrlReactance; }
428  wxChoice* GetChoiceReactance() { return m_choiceReactance; }
429  wxStaticText* GetStaticTextSusceptance() { return m_staticTextSusceptance; }
430  wxTextCtrl* GetTextCtrlSusceptance() { return m_textCtrlSusceptance; }
431  wxChoice* GetChoiceSusceptance() { return m_choiceSusceptance; }
432  wxStaticText* GetStaticTextLineSize() { return m_staticTextLineSize; }
433  wxTextCtrl* GetTextCtrlLineSize() { return m_textCtrlLineSize; }
434  wxStaticText* GetStaticTextKM() { return m_staticTextKM; }
435  wxCheckBox* GetCheckUseLinePower() { return m_checkUseLinePower; }
436  wxPanel* GetPanelGeneral() { return m_panelGeneral; }
437  wxStaticText* GetStaticTextZeroResistance() { return m_staticTextZeroResistance; }
438  wxTextCtrl* GetTextCtrlZeroResistance() { return m_textCtrlZeroResistance; }
439  wxStaticText* GetStaticTextZeroReactance() { return m_staticTextZeroReactance; }
440  wxTextCtrl* GetTextCtrlZeroReactance() { return m_textCtrlZeroReactance; }
441  wxStaticText* GetStaticTextZeroSusceptance() { return m_staticTextZeroSusceptance; }
442  wxTextCtrl* GetTextCtrlZeroSusceptance() { return m_textCtrlZeroSusceptance; }
443  wxPanel* GetPanelFault() { return m_panelFault; }
444  wxNotebook* GetNotebook() { return m_notebook; }
445  wxButton* GetButtonStability() { return m_buttonStability; }
446  wxButton* GetButtonOK() { return m_buttonOK; }
447  wxButton* GetButtonCancel() { return m_buttonCancel; }
448  LineFormBase(wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Line"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize(-1,-1), long style = wxDEFAULT_DIALOG_STYLE);
449  virtual ~LineFormBase();
450 };
451 
452 
453 class TransformerFormBase : public wxDialog
454 {
455 protected:
456  wxNotebook* m_notebook;
457  wxPanel* m_panelGeneral;
458  wxStaticText* m_staticTextName;
459  wxTextCtrl* m_textCtrlName;
460  wxStaticText* m_staticTextNominalVoltage;
461  wxStaticText* m_staticTextNominalVoltageValue;
462  wxStaticText* m_staticTextBaseVoltage;
463  wxChoice* m_choiceBaseVoltage;
464  wxStaticText* m_staticTextNominalPower;
465  wxTextCtrl* m_textCtrlNominalPower;
466  wxChoice* m_choiceNominalPower;
467  wxStaticText* m_staticTextResistance;
468  wxTextCtrl* m_textCtrlResistance;
469  wxChoice* m_choiceResistance;
470  wxStaticText* m_staticTextReactance;
471  wxTextCtrl* m_textCtrlReactance;
472  wxChoice* m_choiceReactance;
473  wxStaticLine* m_staticLine_1;
474  wxStaticText* m_staticTextConnection;
475  wxChoice* m_choiceConnection;
476  wxStaticText* m_staticTextTurnsRatio;
477  wxTextCtrl* m_textCtrlTurnRatio;
478  wxStaticText* m_staticTextPhaseShift;
479  wxTextCtrl* m_textCtrlPhaseShift;
480  wxStaticText* m_staticTextDeg;
481  wxCheckBox* m_checkUseTransformerPower;
482  wxPanel* m_panelFault;
483  wxStaticText* m_staticTextZeroResistance;
484  wxTextCtrl* m_textCtrlZeroResistance;
485  wxStaticText* m_staticTextZeroReactance;
486  wxTextCtrl* m_textCtrlZeroReactance;
487  wxStaticText* m_staticTextPrimResistance;
488  wxTextCtrl* m_textCtrlPrimResistance;
489  wxStaticText* m_staticTextPrimReactance;
490  wxTextCtrl* m_textCtrlPrimReactance;
491  wxStaticText* m_staticTextSecResistance;
492  wxTextCtrl* m_textCtrlSecResistance;
493  wxStaticText* m_staticTextSecReactance;
494  wxTextCtrl* m_textCtrlSecReactance;
495  wxButton* m_buttonStability;
496  wxButton* m_buttonOK;
497  wxButton* m_buttonCancel;
498 
499 protected:
500  virtual void OnStabilityButtonClick(wxCommandEvent& event) { event.Skip(); }
501  virtual void OnOKButtonClick(wxCommandEvent& event) { event.Skip(); }
502  virtual void OnCancelButtonClick(wxCommandEvent& event) { event.Skip(); }
503 
504 public:
505  wxStaticText* GetStaticTextName() { return m_staticTextName; }
506  wxTextCtrl* GetTextCtrlName() { return m_textCtrlName; }
507  wxStaticText* GetStaticTextNominalVoltage() { return m_staticTextNominalVoltage; }
508  wxStaticText* GetStaticTextNominalVoltageValue() { return m_staticTextNominalVoltageValue; }
509  wxStaticText* GetStaticTextBaseVoltage() { return m_staticTextBaseVoltage; }
510  wxChoice* GetChoiceBaseVoltage() { return m_choiceBaseVoltage; }
511  wxStaticText* GetStaticTextNominalPower() { return m_staticTextNominalPower; }
512  wxTextCtrl* GetTextCtrlNominalPower() { return m_textCtrlNominalPower; }
513  wxChoice* GetChoiceNominalPower() { return m_choiceNominalPower; }
514  wxStaticText* GetStaticTextResistance() { return m_staticTextResistance; }
515  wxTextCtrl* GetTextCtrlResistance() { return m_textCtrlResistance; }
516  wxChoice* GetChoiceResistance() { return m_choiceResistance; }
517  wxStaticText* GetStaticTextReactance() { return m_staticTextReactance; }
518  wxTextCtrl* GetTextCtrlReactance() { return m_textCtrlReactance; }
519  wxChoice* GetChoiceReactance() { return m_choiceReactance; }
520  wxStaticLine* GetStaticLine_1() { return m_staticLine_1; }
521  wxStaticText* GetStaticTextConnection() { return m_staticTextConnection; }
522  wxChoice* GetChoiceConnection() { return m_choiceConnection; }
523  wxStaticText* GetStaticTextTurnsRatio() { return m_staticTextTurnsRatio; }
524  wxTextCtrl* GetTextCtrlTurnRatio() { return m_textCtrlTurnRatio; }
525  wxStaticText* GetStaticTextPhaseShift() { return m_staticTextPhaseShift; }
526  wxTextCtrl* GetTextCtrlPhaseShift() { return m_textCtrlPhaseShift; }
527  wxStaticText* GetStaticTextDeg() { return m_staticTextDeg; }
528  wxCheckBox* GetCheckUseTransformerPower() { return m_checkUseTransformerPower; }
529  wxPanel* GetPanelGeneral() { return m_panelGeneral; }
530  wxStaticText* GetStaticTextZeroResistance() { return m_staticTextZeroResistance; }
531  wxTextCtrl* GetTextCtrlZeroResistance() { return m_textCtrlZeroResistance; }
532  wxStaticText* GetStaticTextZeroReactance() { return m_staticTextZeroReactance; }
533  wxTextCtrl* GetTextCtrlZeroReactance() { return m_textCtrlZeroReactance; }
534  wxStaticText* GetStaticTextPrimResistance() { return m_staticTextPrimResistance; }
535  wxTextCtrl* GetTextCtrlPrimResistance() { return m_textCtrlPrimResistance; }
536  wxStaticText* GetStaticTextPrimReactance() { return m_staticTextPrimReactance; }
537  wxTextCtrl* GetTextCtrlPrimReactance() { return m_textCtrlPrimReactance; }
538  wxStaticText* GetStaticTextSecResistance() { return m_staticTextSecResistance; }
539  wxTextCtrl* GetTextCtrlSecResistance() { return m_textCtrlSecResistance; }
540  wxStaticText* GetStaticTextSecReactance() { return m_staticTextSecReactance; }
541  wxTextCtrl* GetTextCtrlSecReactance() { return m_textCtrlSecReactance; }
542  wxPanel* GetPanelFault() { return m_panelFault; }
543  wxNotebook* GetNotebook() { return m_notebook; }
544  wxButton* GetButtonStability() { return m_buttonStability; }
545  wxButton* GetButtonOK() { return m_buttonOK; }
546  wxButton* GetButtonCancel() { return m_buttonCancel; }
547  TransformerFormBase(wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Transformer"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize(-1,-1), long style = wxDEFAULT_DIALOG_STYLE);
548  virtual ~TransformerFormBase();
549 };
550 
551 
552 class LoadFormBase : public wxDialog
553 {
554 protected:
555  wxNotebook* m_notebook;
556  wxPanel* m_panelGeneral;
557  wxStaticText* m_staticTextName;
558  wxTextCtrl* m_textCtrlName;
559  wxStaticText* m_staticTextActivePower;
560  wxTextCtrl* m_textCtrlActivePower;
561  wxChoice* m_choiceActivePower;
562  wxStaticText* m_staticTextReactivePower;
563  wxTextCtrl* m_textCtrlReactivePower;
564  wxChoice* m_choiceReactivePower;
565  wxStaticText* m_staticTextType;
566  wxChoice* m_choiceType;
567  wxPanel* m_panelStability;
568  wxCheckBox* m_checkBoxPlotData;
569  wxCheckBox* m_checkBoxUseCompLoad;
570  wxStaticText* m_staticTextActivePowerImp;
571  wxTextCtrl* m_textCtrlActivePowerImp;
572  wxStaticText* m_staticTextPerc_1;
573  wxStaticText* m_staticTextActivePowerCur;
574  wxTextCtrl* m_textCtrlActivePowerCur;
575  wxStaticText* m_staticTextPerc_2;
576  wxStaticText* m_staticTextActivePowerPow;
577  wxTextCtrl* m_textCtrlActivePowerPow;
578  wxStaticText* m_staticTextPerc_3;
579  wxStaticText* m_staticTextReactivePowerImp;
580  wxTextCtrl* m_textCtrlReactivePowerImp;
581  wxStaticText* m_staticTextPerc_4;
582  wxStaticText* m_staticTextReactivePowerCur;
583  wxTextCtrl* m_textCtrlReactivePowerCur;
584  wxStaticText* m_staticTextPerc_5;
585  wxStaticText* m_staticTextReactivePowerPow;
586  wxTextCtrl* m_textCtrlReactivePowerPow;
587  wxStaticText* m_staticTextPerc_6;
588  wxButton* m_buttonStabButton;
589  wxButton* m_buttonOK;
590  wxButton* m_ButtonCancel;
591 
592 protected:
593  virtual void OnCheckBoxCompLoadClick(wxCommandEvent& event) { event.Skip(); }
594  virtual void OnStabilityButtonClick(wxCommandEvent& event) { event.Skip(); }
595  virtual void OnOnButtonClick(wxCommandEvent& event) { event.Skip(); }
596  virtual void OnCancelButtonClick(wxCommandEvent& event) { event.Skip(); }
597 
598 public:
599  wxStaticText* GetStaticTextName() { return m_staticTextName; }
600  wxTextCtrl* GetTextCtrlName() { return m_textCtrlName; }
601  wxStaticText* GetStaticTextActivePower() { return m_staticTextActivePower; }
602  wxTextCtrl* GetTextCtrlActivePower() { return m_textCtrlActivePower; }
603  wxChoice* GetChoiceActivePower() { return m_choiceActivePower; }
604  wxStaticText* GetStaticTextReactivePower() { return m_staticTextReactivePower; }
605  wxTextCtrl* GetTextCtrlReactivePower() { return m_textCtrlReactivePower; }
606  wxChoice* GetChoiceReactivePower() { return m_choiceReactivePower; }
607  wxStaticText* GetStaticTextType() { return m_staticTextType; }
608  wxChoice* GetChoiceType() { return m_choiceType; }
609  wxPanel* GetPanelGeneral() { return m_panelGeneral; }
610  wxCheckBox* GetCheckBoxPlotData() { return m_checkBoxPlotData; }
611  wxCheckBox* GetCheckBoxUseCompLoad() { return m_checkBoxUseCompLoad; }
612  wxStaticText* GetStaticTextActivePowerImp() { return m_staticTextActivePowerImp; }
613  wxTextCtrl* GetTextCtrlActivePowerImp() { return m_textCtrlActivePowerImp; }
614  wxStaticText* GetStaticTextPerc_1() { return m_staticTextPerc_1; }
615  wxStaticText* GetStaticTextActivePowerCur() { return m_staticTextActivePowerCur; }
616  wxTextCtrl* GetTextCtrlActivePowerCur() { return m_textCtrlActivePowerCur; }
617  wxStaticText* GetStaticTextPerc_2() { return m_staticTextPerc_2; }
618  wxStaticText* GetStaticTextActivePowerPow() { return m_staticTextActivePowerPow; }
619  wxTextCtrl* GetTextCtrlActivePowerPow() { return m_textCtrlActivePowerPow; }
620  wxStaticText* GetStaticTextPerc_3() { return m_staticTextPerc_3; }
621  wxStaticText* GetStaticTextReactivePowerImp() { return m_staticTextReactivePowerImp; }
622  wxTextCtrl* GetTextCtrlReactivePowerImp() { return m_textCtrlReactivePowerImp; }
623  wxStaticText* GetStaticTextPerc_4() { return m_staticTextPerc_4; }
624  wxStaticText* GetStaticTextReactivePowerCur() { return m_staticTextReactivePowerCur; }
625  wxTextCtrl* GetTextCtrlReactivePowerCur() { return m_textCtrlReactivePowerCur; }
626  wxStaticText* GetStaticTextPerc_5() { return m_staticTextPerc_5; }
627  wxStaticText* GetStaticTextReactivePowerPow() { return m_staticTextReactivePowerPow; }
628  wxTextCtrl* GetTextCtrlReactivePowerPow() { return m_textCtrlReactivePowerPow; }
629  wxStaticText* GetStaticTextPerc_6() { return m_staticTextPerc_6; }
630  wxPanel* GetPanelStability() { return m_panelStability; }
631  wxNotebook* GetNotebook() { return m_notebook; }
632  wxButton* GetButtonStabButton() { return m_buttonStabButton; }
633  wxButton* GetButtonOK() { return m_buttonOK; }
634  wxButton* GetButtonCancel() { return m_ButtonCancel; }
635  LoadFormBase(wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Load"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize(-1,-1), long style = wxDEFAULT_DIALOG_STYLE);
636  virtual ~LoadFormBase();
637 };
638 
639 
640 class ReactiveShuntElementFormBase : public wxDialog
641 {
642 protected:
643  wxNotebook* m_notebook;
644  wxPanel* m_panelGeneral;
645  wxStaticText* m_staticTextName;
646  wxTextCtrl* m_textCtrlName;
647  wxStaticText* m_staticTextReactivePower;
648  wxTextCtrl* m_textCtrlReactivePower;
649  wxChoice* m_choiceReactivePower;
650  wxButton* m_buttonStabButton;
651  wxButton* m_buttonOK;
652  wxButton* m_buttonCancel;
653 
654 protected:
655  virtual void OnStabilityButtonClick(wxCommandEvent& event) { event.Skip(); }
656  virtual void OnOKButtonClick(wxCommandEvent& event) { event.Skip(); }
657  virtual void OnCancelButtonClick(wxCommandEvent& event) { event.Skip(); }
658 
659 public:
660  wxStaticText* GetStaticTextName() { return m_staticTextName; }
661  wxTextCtrl* GetTextCtrlName() { return m_textCtrlName; }
662  wxStaticText* GetStaticTextReactivePower() { return m_staticTextReactivePower; }
663  wxTextCtrl* GetTextCtrlReactivePower() { return m_textCtrlReactivePower; }
664  wxChoice* GetChoiceReactivePower() { return m_choiceReactivePower; }
665  wxPanel* GetPanelGeneral() { return m_panelGeneral; }
666  wxNotebook* GetNotebook() { return m_notebook; }
667  wxButton* GetButtonStabButton() { return m_buttonStabButton; }
668  wxButton* GetButtonOK() { return m_buttonOK; }
669  wxButton* GetButtonCancel() { return m_buttonCancel; }
670  ReactiveShuntElementFormBase(wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Reactive shunt element"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize(-1,-1), long style = wxDEFAULT_DIALOG_STYLE);
671  virtual ~ReactiveShuntElementFormBase();
672 };
673 
674 
675 class SwitchingFormBase : public wxDialog
676 {
677 protected:
678  wxPropertyGridManager* m_pgMgrSwitchingsProp;
679  wxPGProperty* m_pgPropTitle;
680  wxPGProperty* m_pgPropType;
681  wxPGProperty* m_pgPropTime;
682  wxButton* m_buttonInsert;
683  wxButton* m_buttonRemove;
684  wxButton* m_buttonUp;
685  wxButton* m_buttonDown;
686  wxStaticText* m_staticTextSwList;
687  wxListCtrl* m_listCtrlSwitchings;
688  wxButton* m_buttonOK;
689  wxButton* m_buttonCancel;
690 
691 protected:
692  virtual void OnChangeProperties(wxPropertyGridEvent& event) { event.Skip(); }
693  virtual void OnInsertButtonClick(wxCommandEvent& event) { event.Skip(); }
694  virtual void OnRemoveButtonClick(wxCommandEvent& event) { event.Skip(); }
695  virtual void OnUpButtonClick(wxCommandEvent& event) { event.Skip(); }
696  virtual void OnDownButtonClick(wxCommandEvent& event) { event.Skip(); }
697  virtual void OnSelectItem(wxListEvent& event) { event.Skip(); }
698  virtual void OnOKButtonClick(wxCommandEvent& event) { event.Skip(); }
699  virtual void OnCancelButtonClick(wxCommandEvent& event) { event.Skip(); }
700 
701 public:
702  wxPropertyGridManager* GetPgMgrSwitchingsProp() { return m_pgMgrSwitchingsProp; }
703  wxButton* GetButtonInsert() { return m_buttonInsert; }
704  wxButton* GetButtonRemove() { return m_buttonRemove; }
705  wxButton* GetButtonUp() { return m_buttonUp; }
706  wxButton* GetButtonDown() { return m_buttonDown; }
707  wxStaticText* GetStaticTextSwList() { return m_staticTextSwList; }
708  wxListCtrl* GetListCtrlSwitchings() { return m_listCtrlSwitchings; }
709  wxButton* GetButtonOK() { return m_buttonOK; }
710  wxButton* GetButtonCancel() { return m_buttonCancel; }
711  SwitchingFormBase(wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Switching"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize(-1,-1), long style = wxDEFAULT_DIALOG_STYLE);
712  virtual ~SwitchingFormBase();
713 };
714 
715 
716 class IndMotorFormBase : public wxDialog
717 {
718 protected:
719  wxNotebook* m_notebook;
720  wxPanel* m_panelGeneral;
721  wxStaticText* m_staticTextName;
722  wxTextCtrl* m_textCtrlName;
723  wxStaticText* m_staticTextActivePower;
724  wxTextCtrl* m_textCtrlActivePower;
725  wxChoice* m_choiceActivePower;
726  wxStaticText* m_staticTextReactivePower;
727  wxTextCtrl* m_textCtrlReactivePower;
728  wxChoice* m_choiceReactivePower;
729  wxButton* m_buttonStabButton;
730  wxButton* m_buttonOK;
731  wxButton* m_ButtonCancel;
732 
733 protected:
734  virtual void OnStabilityButtonClick(wxCommandEvent& event) { event.Skip(); }
735  virtual void OnOKButtonClick(wxCommandEvent& event) { event.Skip(); }
736  virtual void OnCancelButtonClick(wxCommandEvent& event) { event.Skip(); }
737 
738 public:
739  wxStaticText* GetStaticTextName() { return m_staticTextName; }
740  wxTextCtrl* GetTextCtrlName() { return m_textCtrlName; }
741  wxStaticText* GetStaticTextActivePower() { return m_staticTextActivePower; }
742  wxTextCtrl* GetTextCtrlActivePower() { return m_textCtrlActivePower; }
743  wxChoice* GetChoiceActivePower() { return m_choiceActivePower; }
744  wxStaticText* GetStaticTextReactivePower() { return m_staticTextReactivePower; }
745  wxTextCtrl* GetTextCtrlReactivePower() { return m_textCtrlReactivePower; }
746  wxChoice* GetChoiceReactivePower() { return m_choiceReactivePower; }
747  wxPanel* GetPanelGeneral() { return m_panelGeneral; }
748  wxNotebook* GetNotebook() { return m_notebook; }
749  wxButton* GetButtonStabButton() { return m_buttonStabButton; }
750  wxButton* GetButtonOK() { return m_buttonOK; }
751  wxButton* GetButtonCancel() { return m_ButtonCancel; }
752  IndMotorFormBase(wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Motor"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize(-1,-1), long style = wxDEFAULT_DIALOG_STYLE);
753  virtual ~IndMotorFormBase();
754 };
755 
756 
757 class TextFormBase : public wxDialog
758 {
759 protected:
760  wxNotebook* m_notebook;
761  wxPanel* m_panelGeneral;
762  wxStaticText* m_staticTextElement;
763  wxChoice* m_choiceElement;
764  wxStaticText* m_staticTextName;
765  wxChoice* m_choiceName;
766  wxStaticText* m_staticTextType;
767  wxChoice* m_choiceTextType;
768  wxStaticText* m_staticTextFromBus;
769  wxChoice* m_choiceTextFromBus;
770  wxStaticText* m_staticTextToBus;
771  wxChoice* m_choiceTextToBus;
772  wxStaticText* m_staticTextUnit;
773  wxChoice* m_choiceTextUnit;
774  wxStaticText* m_staticTextDecimal;
775  wxTextCtrl* m_textCtrlDecimal;
776  wxStaticText* m_staticTextPreview;
777  wxTextCtrl* m_textCtrlPreview;
778  wxButton* m_buttonOK;
779  wxButton* m_ButtonCancel;
780 
781 protected:
782  virtual void OnElementChoiceSelected(wxCommandEvent& event) { event.Skip(); }
783  virtual void OnNameChoiceSelected(wxCommandEvent& event) { event.Skip(); }
784  virtual void OnTypeChoiceSelected(wxCommandEvent& event) { event.Skip(); }
785  virtual void OnFromBusChoiceSelected(wxCommandEvent& event) { event.Skip(); }
786  virtual void OnToBusChoiceSelected(wxCommandEvent& event) { event.Skip(); }
787  virtual void OnUnitChoiceSelected(wxCommandEvent& event) { event.Skip(); }
788  virtual void OnTextEnter(wxCommandEvent& event) { event.Skip(); }
789  virtual void OnOKButtonClick(wxCommandEvent& event) { event.Skip(); }
790  virtual void OnCancelButtonClick(wxCommandEvent& event) { event.Skip(); }
791 
792 public:
793  wxStaticText* GetStaticTextElement() { return m_staticTextElement; }
794  wxChoice* GetChoiceElement() { return m_choiceElement; }
795  wxStaticText* GetStaticTextName() { return m_staticTextName; }
796  wxChoice* GetChoiceName() { return m_choiceName; }
797  wxStaticText* GetStaticTextType() { return m_staticTextType; }
798  wxChoice* GetChoiceTextType() { return m_choiceTextType; }
799  wxStaticText* GetStaticTextFromBus() { return m_staticTextFromBus; }
800  wxChoice* GetChoiceTextFromBus() { return m_choiceTextFromBus; }
801  wxStaticText* GetStaticTextToBus() { return m_staticTextToBus; }
802  wxChoice* GetChoiceTextToBus() { return m_choiceTextToBus; }
803  wxStaticText* GetStaticTextUnit() { return m_staticTextUnit; }
804  wxChoice* GetChoiceTextUnit() { return m_choiceTextUnit; }
805  wxStaticText* GetStaticTextDecimal() { return m_staticTextDecimal; }
806  wxTextCtrl* GetTextCtrlDecimal() { return m_textCtrlDecimal; }
807  wxStaticText* GetStaticTextPreview() { return m_staticTextPreview; }
808  wxTextCtrl* GetTextCtrlPreview() { return m_textCtrlPreview; }
809  wxPanel* GetPanelGeneral() { return m_panelGeneral; }
810  wxNotebook* GetNotebook() { return m_notebook; }
811  wxButton* GetButtonOK() { return m_buttonOK; }
812  wxButton* GetButtonCancel() { return m_ButtonCancel; }
813  TextFormBase(wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Text"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize(-1,-1), long style = wxDEFAULT_DIALOG_STYLE);
814  virtual ~TextFormBase();
815 };
816 
817 
818 class TransferFunctionFormBase : public wxDialog
819 {
820 protected:
821  wxNotebook* m_notebook;
822  wxPanel* m_panelGeneral;
823  wxStaticText* m_staticTextNumerator;
824  wxTextCtrl* m_textCtrlNumerator;
825  wxStaticText* m_staticTextDenominator;
826  wxTextCtrl* m_textCtrlDenominator;
827  wxButton* m_buttonOK;
828  wxButton* m_ButtonCancel;
829 
830 protected:
831  virtual void OnOKClick(wxCommandEvent& event) { event.Skip(); }
832  virtual void OnCancelClick(wxCommandEvent& event) { event.Skip(); }
833 
834 public:
835  wxStaticText* GetStaticTextNumerator() { return m_staticTextNumerator; }
836  wxTextCtrl* GetTextCtrlNumerator() { return m_textCtrlNumerator; }
837  wxStaticText* GetStaticTextDenominator() { return m_staticTextDenominator; }
838  wxTextCtrl* GetTextCtrlDenominator() { return m_textCtrlDenominator; }
839  wxPanel* GetPanelGeneral() { return m_panelGeneral; }
840  wxNotebook* GetNotebook() { return m_notebook; }
841  wxButton* GetButtonOK() { return m_buttonOK; }
842  wxButton* GetButtonCancel() { return m_ButtonCancel; }
843  TransferFunctionFormBase(wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Transfer function"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize(-1,-1), long style = wxDEFAULT_DIALOG_STYLE);
844  virtual ~TransferFunctionFormBase();
845 };
846 
847 
848 class SumFormBase : public wxDialog
849 {
850 protected:
851  wxNotebook* m_notebook;
852  wxPanel* m_panelGeneral;
853  wxStaticText* m_staticTextSigns;
854  wxTextCtrl* m_textCtrlSigns;
855  wxButton* m_buttonOK;
856  wxButton* m_ButtonCancel;
857 
858 protected:
859  virtual void OnOKClick(wxCommandEvent& event) { event.Skip(); }
860  virtual void OnCancelClick(wxCommandEvent& event) { event.Skip(); }
861 
862 public:
863  wxStaticText* GetStaticTextSigns() { return m_staticTextSigns; }
864  wxTextCtrl* GetTextCtrlSigns() { return m_textCtrlSigns; }
865  wxPanel* GetPanelGeneral() { return m_panelGeneral; }
866  wxNotebook* GetNotebook() { return m_notebook; }
867  wxButton* GetButtonOK() { return m_buttonOK; }
868  wxButton* GetButtonCancel() { return m_ButtonCancel; }
869  SumFormBase(wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Sum"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize(-1,-1), long style = wxDEFAULT_DIALOG_STYLE);
870  virtual ~SumFormBase();
871 };
872 
873 
874 class LimiterFormBase : public wxDialog
875 {
876 protected:
877  wxNotebook* m_notebook;
878  wxPanel* m_panelGeneral;
879  wxStaticText* m_staticTextUpLimiter;
880  wxTextCtrl* m_textCtrlUpLimit;
881  wxStaticText* m_staticTextLowLimit;
882  wxTextCtrl* m_textCtrlLowLimit;
883  wxButton* m_buttonOK;
884  wxButton* m_ButtonCancel;
885 
886 protected:
887  virtual void OnOKButtonClick(wxCommandEvent& event) { event.Skip(); }
888  virtual void OnCancelButtonClick(wxCommandEvent& event) { event.Skip(); }
889 
890 public:
891  wxStaticText* GetStaticTextUpLimiter() { return m_staticTextUpLimiter; }
892  wxTextCtrl* GetTextCtrlUpLimit() { return m_textCtrlUpLimit; }
893  wxStaticText* GetStaticTextLowLimit() { return m_staticTextLowLimit; }
894  wxTextCtrl* GetTextCtrlLowLimit() { return m_textCtrlLowLimit; }
895  wxPanel* GetPanelGeneral() { return m_panelGeneral; }
896  wxNotebook* GetNotebook() { return m_notebook; }
897  wxButton* GetButtonOK() { return m_buttonOK; }
898  wxButton* GetButtonCancel() { return m_ButtonCancel; }
899  LimiterFormBase(wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Limiter"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize(-1,-1), long style = wxDEFAULT_DIALOG_STYLE);
900  virtual ~LimiterFormBase();
901 };
902 
903 
904 class RateLimiterFormBase : public wxDialog
905 {
906 protected:
907  wxNotebook* m_notebook;
908  wxPanel* m_panelGeneral;
909  wxStaticText* m_staticTextUpLimiter;
910  wxTextCtrl* m_textCtrlUpLimit;
911  wxStaticText* m_staticTextLowLimit;
912  wxTextCtrl* m_textCtrlLowLimit;
913  wxButton* m_buttonOK;
914  wxButton* m_ButtonCancel;
915 
916 protected:
917  virtual void OnOKButtonClick(wxCommandEvent& event) { event.Skip(); }
918  virtual void OnCancelButtonClick(wxCommandEvent& event) { event.Skip(); }
919 
920 public:
921  wxStaticText* GetStaticTextUpLimiter() { return m_staticTextUpLimiter; }
922  wxTextCtrl* GetTextCtrlUpLimit() { return m_textCtrlUpLimit; }
923  wxStaticText* GetStaticTextLowLimit() { return m_staticTextLowLimit; }
924  wxTextCtrl* GetTextCtrlLowLimit() { return m_textCtrlLowLimit; }
925  wxPanel* GetPanelGeneral() { return m_panelGeneral; }
926  wxNotebook* GetNotebook() { return m_notebook; }
927  wxButton* GetButtonOK() { return m_buttonOK; }
928  wxButton* GetButtonCancel() { return m_ButtonCancel; }
929  RateLimiterFormBase(wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Rate limiter"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize(-1,-1), long style = wxDEFAULT_DIALOG_STYLE);
930  virtual ~RateLimiterFormBase();
931 };
932 
933 
934 class ExponentialFormBase : public wxDialog
935 {
936 protected:
937  wxNotebook* m_notebook;
938  wxPanel* m_panelGeneral;
939  wxStaticText* m_staticTextExp;
940  wxStaticText* m_staticTextAValue;
941  wxTextCtrl* m_textCtrlAValue;
942  wxStaticText* m_staticTextBValue;
943  wxTextCtrl* m_textCtrlBValue;
944  wxButton* m_buttonOK;
945  wxButton* m_buttonCancel;
946 
947 protected:
948  virtual void OnOKButtonClick(wxCommandEvent& event) { event.Skip(); }
949  virtual void OnCancelButtonClick(wxCommandEvent& event) { event.Skip(); }
950 
951 public:
952  wxStaticText* GetStaticTextExp() { return m_staticTextExp; }
953  wxStaticText* GetStaticTextAValue() { return m_staticTextAValue; }
954  wxTextCtrl* GetTextCtrlAValue() { return m_textCtrlAValue; }
955  wxStaticText* GetStaticTextBValue() { return m_staticTextBValue; }
956  wxTextCtrl* GetTextCtrlBValue() { return m_textCtrlBValue; }
957  wxPanel* GetPanelGeneral() { return m_panelGeneral; }
958  wxNotebook* GetNotebook() { return m_notebook; }
959  wxButton* GetButtonOK() { return m_buttonOK; }
960  wxButton* GetButtonCancel() { return m_buttonCancel; }
961  ExponentialFormBase(wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Exponential"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize(-1,-1), long style = wxDEFAULT_DIALOG_STYLE);
962  virtual ~ExponentialFormBase();
963 };
964 
965 
966 class ConstantFormBase : public wxDialog
967 {
968 protected:
969  wxNotebook* m_notebook;
970  wxPanel* m_panelGeneral;
971  wxStaticText* m_staticTextValue;
972  wxTextCtrl* m_textCtrlValue;
973  wxButton* m_buttonOK;
974  wxButton* m_buttonCancel;
975 
976 protected:
977  virtual void OnOKButtonClick(wxCommandEvent& event) { event.Skip(); }
978  virtual void OnCancelButtonClick(wxCommandEvent& event) { event.Skip(); }
979 
980 public:
981  wxStaticText* GetStaticTextValue() { return m_staticTextValue; }
982  wxTextCtrl* GetTextCtrlValue() { return m_textCtrlValue; }
983  wxPanel* GetPanelGeneral() { return m_panelGeneral; }
984  wxNotebook* GetNotebook() { return m_notebook; }
985  wxButton* GetButtonOK() { return m_buttonOK; }
986  wxButton* GetButtonCancel() { return m_buttonCancel; }
987  ConstantFormBase(wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Constant"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize(-1,-1), long style = wxDEFAULT_DIALOG_STYLE);
988  virtual ~ConstantFormBase();
989 };
990 
991 
992 class GainFormBase : public wxDialog
993 {
994 protected:
995  wxNotebook* m_notebook;
996  wxPanel* m_panelGeneral;
997  wxStaticText* m_staticTextValue;
998  wxTextCtrl* m_textCtrlValue;
999  wxButton* m_buttonOK;
1000  wxButton* m_buttonCancel;
1001 
1002 protected:
1003  virtual void OnOKButtonClick(wxCommandEvent& event) { event.Skip(); }
1004  virtual void OnCancelButtonClick(wxCommandEvent& event) { event.Skip(); }
1005 
1006 public:
1007  wxStaticText* GetStaticTextValue() { return m_staticTextValue; }
1008  wxTextCtrl* GetTextCtrlValue() { return m_textCtrlValue; }
1009  wxPanel* GetPanelGeneral() { return m_panelGeneral; }
1010  wxNotebook* GetNotebook() { return m_notebook; }
1011  wxButton* GetButtonOK() { return m_buttonOK; }
1012  wxButton* GetButtonCancel() { return m_buttonCancel; }
1013  GainFormBase(wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Gain"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize(-1,-1), long style = wxDEFAULT_DIALOG_STYLE);
1014  virtual ~GainFormBase();
1015 };
1016 
1017 
1018 class IOControlFormBase : public wxDialog
1019 {
1020 protected:
1021  wxNotebook* m_notebook;
1022  wxPanel* m_panelGeneral;
1023  wxCheckBox* m_checkBoxInput;
1024  wxChoice* m_choiceInput;
1025  wxCheckBox* m_checkBoxOutput;
1026  wxChoice* m_choiceOutput;
1027  wxButton* m_buttonOK;
1028  wxButton* m_ButtonCancel;
1029 
1030 protected:
1031  virtual void OnInputChecked(wxCommandEvent& event) { event.Skip(); }
1032  virtual void OnOutputChecked(wxCommandEvent& event) { event.Skip(); }
1033  virtual void OnOKButtonClick(wxCommandEvent& event) { event.Skip(); }
1034  virtual void OnCancelButtonClick(wxCommandEvent& event) { event.Skip(); }
1035 
1036 public:
1037  wxCheckBox* GetCheckBoxInput() { return m_checkBoxInput; }
1038  wxChoice* GetChoiceInput() { return m_choiceInput; }
1039  wxCheckBox* GetCheckBoxOutput() { return m_checkBoxOutput; }
1040  wxChoice* GetChoiceOutput() { return m_choiceOutput; }
1041  wxPanel* GetPanelGeneral() { return m_panelGeneral; }
1042  wxNotebook* GetNotebook() { return m_notebook; }
1043  wxButton* GetButtonOK() { return m_buttonOK; }
1044  wxButton* GetButtonCancel() { return m_ButtonCancel; }
1045  IOControlFormBase(wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Input / Output"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize(-1,-1), long style = wxDEFAULT_DIALOG_STYLE);
1046  virtual ~IOControlFormBase();
1047 };
1048 
1049 #endif
- - + + - - - + + + - - - - + + + + - - + +
diff --git a/docs/doxygen/html/_element_plot_data_8cpp_source.html b/docs/doxygen/html/_element_plot_data_8cpp_source.html index 865ea35..80d9705 100644 --- a/docs/doxygen/html/_element_plot_data_8cpp_source.html +++ b/docs/doxygen/html/_element_plot_data_8cpp_source.html @@ -88,7 +88,7 @@ $(document).ready(function(){initNavTree('_element_plot_data_8cpp_source.html','
ElementPlotData.cpp
-
1 /*
2  * Copyright (C) 2017 Thales Lima Oliveira <thales@ufu.br>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program. If not, see <https://www.gnu.org/licenses/>.
16  */
17 
18 #include "ElementPlotData.h"
19 
20 ElementPlotData::ElementPlotData(wxString name, CurveType curveType)
21 {
22  m_name = name;
23  m_curveType = curveType;
24 }
25 
26 ElementPlotData::~ElementPlotData() {}
27 void ElementPlotData::AddData(std::vector<double> values, wxString name)
28 {
29  PlotData* data = new PlotData();
30  data->SetName(name);
31  data->SetValues(values);
32  data->SetPlot(false);
33  data->SetAxis(0);
34  data->SetColour(*wxBLACK);
35  data->SetPenType(wxPENSTYLE_SOLID);
36  data->SetThick(2);
37 
38  m_elementData.push_back(data);
39 }
+
1 /*
2  * Copyright (C) 2017 Thales Lima Oliveira <thales@ufu.br>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program. If not, see <https://www.gnu.org/licenses/>.
16  */
17 
18 #include "ElementPlotData.h"
19 
20 ElementPlotData::ElementPlotData(wxString name, CurveType curveType)
21 {
22  m_name = name;
23  m_curveType = curveType;
24 }
25 
26 ElementPlotData::~ElementPlotData() {}
27 void ElementPlotData::AddData(std::vector<double> values, wxString name)
28 {
29  PlotData* data = new PlotData();
30  data->SetName(name);
31  data->SetValues(values);
32  data->SetPlot(false);
33  data->SetAxis(0);
34  data->SetColour(*wxBLACK);
35  data->SetPenType(wxPENSTYLE_SOLID);
36  data->SetThick(1);
37 
38  m_elementData.push_back(data);
39 }
This class is responsible to manage the graphical data of electromechanical result to be plotted on c...
diff --git a/docs/doxygen/html/_exponential_form_8cpp_source.html b/docs/doxygen/html/_exponential_form_8cpp_source.html index a4fb180..2fb0046 100644 --- a/docs/doxygen/html/_exponential_form_8cpp_source.html +++ b/docs/doxygen/html/_exponential_form_8cpp_source.html @@ -88,7 +88,7 @@ $(document).ready(function(){initNavTree('_exponential_form_8cpp_source.html',''
ExponentialForm.cpp
-
1 /*
2  * Copyright (C) 2017 Thales Lima Oliveira <thales@ufu.br>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program. If not, see <https://www.gnu.org/licenses/>.
16  */
17 
18 #include "ExponentialForm.h"
19 #include "Exponential.h"
20 
21 ExponentialForm::ExponentialForm(wxWindow* parent, Exponential* exponential) : ExponentialFormBase(parent)
22 {
23  SetSize(GetBestSize());
24 
25  wxString expSymbol = wxString::FromUTF8("\xF0\x9D\x91\x92");
26  wxString superscriptCapitalB = wxString::FromUTF8("\xE1\xB4\xAE");
27  wxString superscriptSmallX = wxString::FromUTF8("\xCB\xA3");
28  m_staticTextExp->SetLabel("y = A" + expSymbol + superscriptCapitalB + superscriptSmallX);
29 
30  wxFont font = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT);
31  font.SetPointSize(14);
32  m_staticTextExp->SetFont(font);
33 
34  m_parent = parent;
35  m_exponential = exponential;
36 
37  double a, b;
38  m_exponential->GetValues(a, b);
39  m_textCtrlAValue->SetValue(m_exponential->StringFromDouble(a));
40  m_textCtrlBValue->SetValue(m_exponential->StringFromDouble(b));
41 
42  SetInitialSize();
43  Layout();
44 }
45 
46 ExponentialForm::~ExponentialForm() {}
47 void ExponentialForm::OnOKButtonClick(wxCommandEvent& event)
48 {
49  if(ValidateData()) EndModal(wxID_OK);
50 }
51 
52 bool ExponentialForm::ValidateData()
53 {
54  double a, b;
55  if(!m_exponential->DoubleFromString(this, m_textCtrlAValue->GetValue(), a,
56  _("Value entered incorrectly in the field \"A value\".")))
57  return false;
58  if(!m_exponential->DoubleFromString(this, m_textCtrlBValue->GetValue(), b,
59  _("Value entered incorrectly in the field \"B value\".")))
60  return false;
61  m_exponential->SetValues(a, b);
62  return true;
63 }
+
1 /*
2  * Copyright (C) 2017 Thales Lima Oliveira <thales@ufu.br>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program. If not, see <https://www.gnu.org/licenses/>.
16  */
17 
18 #include "ExponentialForm.h"
19 #include "Exponential.h"
20 
21 ExponentialForm::ExponentialForm(wxWindow* parent, Exponential* exponential) : ExponentialFormBase(parent)
22 {
23  SetSize(GetBestSize());
24 
25  wxString expSymbol = wxString::FromUTF8("\xF0\x9D\x91\x92");
26  wxString superscriptCapitalB = wxString::FromUTF8("\xE1\xB4\xAE");
27  wxString superscriptSmallX = wxString::FromUTF8("\xCB\xA3");
28  m_staticTextExp->SetLabel("y = A" + expSymbol + superscriptCapitalB + superscriptSmallX);
29 
30  wxFont font = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT);
31  font.SetPointSize(14);
32  m_staticTextExp->SetFont(font);
33 
34  m_parent = parent;
35  m_exponential = exponential;
36 
37  double a, b;
38  m_exponential->GetValues(a, b);
39  m_textCtrlAValue->SetValue(m_exponential->StringFromDouble(a));
40  m_textCtrlBValue->SetValue(m_exponential->StringFromDouble(b));
41 
42  SetInitialSize();
43  Layout();
44 }
45 
46 ExponentialForm::~ExponentialForm() {}
47 void ExponentialForm::OnOKButtonClick(wxCommandEvent& event)
48 {
49  if(ValidateData()) EndModal(wxID_OK);
50 }
51 
52 bool ExponentialForm::ValidateData()
53 {
54  double a, b;
55  if(!m_exponential->DoubleFromString(this, m_textCtrlAValue->GetValue(), a,
56  _("Value entered incorrectly in the field \"A value\".")))
57  return false;
58  if(!m_exponential->DoubleFromString(this, m_textCtrlBValue->GetValue(), b,
59  _("Value entered incorrectly in the field \"B value\".")))
60  return false;
61  m_exponential->SetValues(a, b);
62  return true;
63 }
Generates an output following an exponential function.
Definition: Exponential.h:32
diff --git a/docs/doxygen/html/_exponential_form_8h_source.html b/docs/doxygen/html/_exponential_form_8h_source.html index 8f4f99e..6bdf2ee 100644 --- a/docs/doxygen/html/_exponential_form_8h_source.html +++ b/docs/doxygen/html/_exponential_form_8h_source.html @@ -88,7 +88,7 @@ $(document).ready(function(){initNavTree('_exponential_form_8h_source.html','');
ExponentialForm.h
-Go to the documentation of this file.
1 /*
2  * Copyright (C) 2017 Thales Lima Oliveira <thales@ufu.br>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program. If not, see <https://www.gnu.org/licenses/>.
16  */
17 
18 #ifndef EXPONENTIALFORM_H
19 #define EXPONENTIALFORM_H
20 #include "ElementForm.h"
21 
22 class Exponential;
23 
32 {
33  public:
34  ExponentialForm(wxWindow* parent, Exponential* exponential);
35  virtual ~ExponentialForm();
36  virtual bool ValidateData();
37 
38  protected:
39  virtual void OnCancelButtonClick(wxCommandEvent& event) { EndModal(wxID_CANCEL); }
40  virtual void OnOKButtonClick(wxCommandEvent& event);
41 
42  wxWindow* m_parent = NULL;
43  Exponential* m_exponential = NULL;
44 };
45 #endif // EXPONENTIALFORM_H
+Go to the documentation of this file.
1 /*
2  * Copyright (C) 2017 Thales Lima Oliveira <thales@ufu.br>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program. If not, see <https://www.gnu.org/licenses/>.
16  */
17 
18 #ifndef EXPONENTIALFORM_H
19 #define EXPONENTIALFORM_H
20 #include "ElementForm.h"
21 
22 class Exponential;
23 
32 {
33  public:
34  ExponentialForm(wxWindow* parent, Exponential* exponential);
35  virtual ~ExponentialForm();
36  virtual bool ValidateData();
37 
38  protected:
39  virtual void OnCancelButtonClick(wxCommandEvent& event) { EndModal(wxID_CANCEL); }
40  virtual void OnOKButtonClick(wxCommandEvent& event);
41 
42  wxWindow* m_parent = NULL;
43  Exponential* m_exponential = NULL;
44 };
45 #endif // EXPONENTIALFORM_H
Generates an output following an exponential function.
Definition: Exponential.h:32
Form to edit the exponential control data.
diff --git a/docs/doxygen/html/_file_handing_8cpp_source.html b/docs/doxygen/html/_file_handing_8cpp_source.html index 5f11b75..b70102d 100644 --- a/docs/doxygen/html/_file_handing_8cpp_source.html +++ b/docs/doxygen/html/_file_handing_8cpp_source.html @@ -88,8 +88,9 @@ $(document).ready(function(){initNavTree('_file_handing_8cpp_source.html','');})
FileHanding.cpp
-
1 /*
2  * Copyright (C) 2017 Thales Lima Oliveira <thales@ufu.br>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program. If not, see <https://www.gnu.org/licenses/>.
16  */
17 
18 #include "FileHanding.h"
19 
20 FileHanding::~FileHanding() {}
21 FileHanding::FileHanding(Workspace* workspace) { m_workspace = workspace; }
22 FileHanding::FileHanding(ControlEditor* controlEditor) { m_controlEditor = controlEditor; }
23 FileHanding::FileHanding() {}
24 void FileHanding::SaveProject(wxFileName path)
25 {
26  // Erase the file (if exists or not) and write the initial data
27  std::ofstream writeProjectsFile(path.GetFullPath());
28  writeProjectsFile.close();
29 
30  rapidxml::xml_document<> doc;
31  rapidxml::file<> xmlFile(path.GetFullPath().mb_str());
32  doc.parse<0>(xmlFile.data());
33 
34  rapidxml::xml_node<>* decl = doc.allocate_node(rapidxml::node_declaration);
35  rapidxml::xml_attribute<>* ver = doc.allocate_attribute("version", "1.0");
36  rapidxml::xml_attribute<>* encoding = doc.allocate_attribute("encoding", "utf-8");
37  decl->append_attribute(ver);
38  decl->append_attribute(encoding);
39  doc.append_node(decl);
40 
41  rapidxml::xml_node<>* rootNode = doc.allocate_node(rapidxml::node_element, "Project");
42  doc.append_node(rootNode);
43 
44  rapidxml::xml_node<>* projectNameNode = AppendNode(doc, rootNode, "Name");
45  SetNodeValue(doc, projectNameNode, path.GetName());
46 
47  auto elementsNode = AppendNode(doc, rootNode, "Elements");
48 
49  // Save all the data
50  ElectricCalculation allElements;
51  allElements.GetElementsFromList(m_workspace->GetElementList());
52 
53  //{ Buses
54  auto busesNode = AppendNode(doc, elementsNode, "BusList");
55  auto busList = allElements.GetBusList();
56  for(int i = 0; i < (int)busList.size(); i++) {
57  Bus* bus = busList[i];
58  auto busNode = AppendNode(doc, busesNode, "Bus");
59  SetNodeAttribute(doc, busNode, "ID", i);
60  auto cadProp = AppendNode(doc, busNode, "CADProperties");
61  auto position = AppendNode(doc, cadProp, "Position");
62  auto posX = AppendNode(doc, position, "X");
63  SetNodeValue(doc, posX, bus->GetPosition().m_x);
64  auto posY = AppendNode(doc, position, "Y");
65  SetNodeValue(doc, posY, bus->GetPosition().m_y);
66  auto size = AppendNode(doc, cadProp, "Size");
67  auto width = AppendNode(doc, size, "Width");
68  SetNodeValue(doc, width, bus->GetWidth());
69  auto height = AppendNode(doc, size, "Height");
70  SetNodeValue(doc, height, bus->GetHeight());
71  auto angle = AppendNode(doc, cadProp, "Angle");
72  SetNodeValue(doc, angle, bus->GetAngle());
73 
74  BusElectricalData data = bus->GetElectricalData();
75  auto electricalProp = AppendNode(doc, busNode, "ElectricalProperties");
76  auto name = AppendNode(doc, electricalProp, "Name");
77  SetNodeValue(doc, name, data.name);
78  auto nominalVoltage = AppendNode(doc, electricalProp, "NominalVoltage");
79  SetNodeValue(doc, nominalVoltage, data.nominalVoltage);
80  SetNodeAttribute(doc, nominalVoltage, "UnitID", data.nominalVoltageUnit);
81  auto isVoltageControlled = AppendNode(doc, electricalProp, "IsVoltageControlled");
82  SetNodeValue(doc, isVoltageControlled, data.isVoltageControlled);
83  auto controlledVoltage = AppendNode(doc, electricalProp, "ControlledVoltage");
84  SetNodeValue(doc, controlledVoltage, data.controlledVoltage);
85  SetNodeAttribute(doc, controlledVoltage, "Choice", data.controlledVoltageUnitChoice);
86  auto slackBus = AppendNode(doc, electricalProp, "SlackBus");
87  SetNodeValue(doc, slackBus, data.slackBus);
88 
89  auto fault = AppendNode(doc, electricalProp, "Fault");
90  auto hasFault = AppendNode(doc, fault, "HasFault");
91  SetNodeValue(doc, hasFault, data.hasFault);
92  auto faultType = AppendNode(doc, fault, "Type");
93  SetNodeValue(doc, faultType, data.faultType);
94  auto faultLocation = AppendNode(doc, fault, "Location");
95  SetNodeValue(doc, faultLocation, data.faultLocation);
96  auto faultResistance = AppendNode(doc, fault, "Resistance");
97  SetNodeValue(doc, faultResistance, data.faultResistance);
98  auto faultReactance = AppendNode(doc, fault, "Reactance");
99  SetNodeValue(doc, faultReactance, data.faultReactance);
100 
101  auto stability = AppendNode(doc, electricalProp, "Stability");
102  auto plotBus = AppendNode(doc, stability, "Plot");
103  SetNodeValue(doc, plotBus, data.plotBus);
104  auto stabHasFault = AppendNode(doc, stability, "HasFault");
105  SetNodeValue(doc, stabHasFault, data.stabHasFault);
106  auto stabFaultTime = AppendNode(doc, stability, "FaultTime");
107  SetNodeValue(doc, stabFaultTime, data.stabFaultTime);
108  auto stabFaultLength = AppendNode(doc, stability, "FaultLength");
109  SetNodeValue(doc, stabFaultLength, data.stabFaultLength);
110  auto stabFaultResistance = AppendNode(doc, stability, "FaultResistance");
111  SetNodeValue(doc, stabFaultResistance, data.stabFaultResistance);
112  auto stabFaultReactance = AppendNode(doc, stability, "FaultReactance");
113  SetNodeValue(doc, stabFaultReactance, data.stabFaultReactance);
114 
115  data.number = i;
116  bus->SetElectricalData(data);
117  } //}
118 
119  //{ Capacitor
120  auto capacitorsNode = AppendNode(doc, elementsNode, "CapacitorList");
121  auto capacitorList = allElements.GetCapacitorList();
122  for(int i = 0; i < (int)capacitorList.size(); i++) {
123  Capacitor* capacitor = capacitorList[i];
124  auto capacitorNode = AppendNode(doc, capacitorsNode, "Capacitor");
125  SetNodeAttribute(doc, capacitorNode, "ID", i);
126  auto cadProp = AppendNode(doc, capacitorNode, "CADProperties");
127  auto position = AppendNode(doc, cadProp, "Position");
128  auto posX = AppendNode(doc, position, "X");
129  SetNodeValue(doc, posX, capacitor->GetPosition().m_x);
130  auto posY = AppendNode(doc, position, "Y");
131  SetNodeValue(doc, posY, capacitor->GetPosition().m_y);
132  auto size = AppendNode(doc, cadProp, "Size");
133  auto width = AppendNode(doc, size, "Width");
134  SetNodeValue(doc, width, capacitor->GetWidth());
135  auto height = AppendNode(doc, size, "Height");
136  SetNodeValue(doc, height, capacitor->GetHeight());
137  auto angle = AppendNode(doc, cadProp, "Angle");
138  SetNodeValue(doc, angle, capacitor->GetAngle());
139  auto nodePos = AppendNode(doc, cadProp, "NodePosition");
140  auto nodePosX = AppendNode(doc, nodePos, "X");
141  SetNodeValue(doc, nodePosX, capacitor->GetPointList()[0].m_x);
142  auto nodePosY = AppendNode(doc, nodePos, "Y");
143  SetNodeValue(doc, nodePosY, capacitor->GetPointList()[0].m_y);
144  auto parentID = AppendNode(doc, cadProp, "ParentID");
145  Bus* parent = static_cast<Bus*>(capacitor->GetParentList()[0]);
146  if(parent) SetNodeValue(doc, parentID, parent->GetElectricalData().number);
147 
148  CapacitorElectricalData data = capacitor->GetElectricalData();
149  auto electricalProp = AppendNode(doc, capacitorNode, "ElectricalProperties");
150  auto isOnline = AppendNode(doc, electricalProp, "IsOnline");
151  SetNodeValue(doc, isOnline, capacitor->IsOnline());
152  auto name = AppendNode(doc, electricalProp, "Name");
153  SetNodeValue(doc, name, data.name);
154  auto reactivePower = AppendNode(doc, electricalProp, "ReactivePower");
155  SetNodeValue(doc, reactivePower, data.reactivePower);
156  SetNodeAttribute(doc, reactivePower, "UnitID", data.reactivePowerUnit);
157 
158  auto switchingList = AppendNode(doc, electricalProp, "SwitchingList");
159  SwitchingData swData = capacitor->GetSwitchingData();
160  for(int j = 0; j < (int)swData.swType.size(); j++) {
161  auto switching = AppendNode(doc, switchingList, "Switching");
162  SetNodeAttribute(doc, switching, "ID", j);
163  auto swType = AppendNode(doc, switching, "Type");
164  SetNodeValue(doc, swType, swData.swType[j]);
165  auto swTime = AppendNode(doc, switching, "Time");
166  SetNodeValue(doc, swTime, swData.swTime[j]);
167  }
168  } //}
169 
170  //{ IndMotor
171  auto indMotorsNode = AppendNode(doc, elementsNode, "IndMotorList");
172  auto indMotorList = allElements.GetIndMotorList();
173  for(int i = 0; i < (int)indMotorList.size(); i++) {
174  IndMotor* indMotor = indMotorList[i];
175  auto indMotorNode = AppendNode(doc, indMotorsNode, "IndMotor");
176  SetNodeAttribute(doc, indMotorNode, "ID", i);
177  auto cadProp = AppendNode(doc, indMotorNode, "CADProperties");
178  auto position = AppendNode(doc, cadProp, "Position");
179  auto posX = AppendNode(doc, position, "X");
180  SetNodeValue(doc, posX, indMotor->GetPosition().m_x);
181  auto posY = AppendNode(doc, position, "Y");
182  SetNodeValue(doc, posY, indMotor->GetPosition().m_y);
183  auto size = AppendNode(doc, cadProp, "Size");
184  auto width = AppendNode(doc, size, "Width");
185  SetNodeValue(doc, width, indMotor->GetWidth());
186  auto height = AppendNode(doc, size, "Height");
187  SetNodeValue(doc, height, indMotor->GetHeight());
188  auto angle = AppendNode(doc, cadProp, "Angle");
189  SetNodeValue(doc, angle, indMotor->GetAngle());
190  auto nodePos = AppendNode(doc, cadProp, "NodePosition");
191  auto nodePosX = AppendNode(doc, nodePos, "X");
192  SetNodeValue(doc, nodePosX, indMotor->GetPointList()[0].m_x);
193  auto nodePosY = AppendNode(doc, nodePos, "Y");
194  SetNodeValue(doc, nodePosY, indMotor->GetPointList()[0].m_y);
195  auto parentID = AppendNode(doc, cadProp, "ParentID");
196  Bus* parent = static_cast<Bus*>(indMotor->GetParentList()[0]);
197  if(parent) SetNodeValue(doc, parentID, parent->GetElectricalData().number);
198 
199  IndMotorElectricalData data = indMotor->GetElectricalData();
200  auto electricalProp = AppendNode(doc, indMotorNode, "ElectricalProperties");
201  auto isOnline = AppendNode(doc, electricalProp, "IsOnline");
202  SetNodeValue(doc, isOnline, indMotor->IsOnline());
203  auto name = AppendNode(doc, electricalProp, "Name");
204  SetNodeValue(doc, name, data.name);
205  auto activePower = AppendNode(doc, electricalProp, "ActivePower");
206  SetNodeValue(doc, activePower, data.activePower);
207  SetNodeAttribute(doc, activePower, "UnitID", data.activePowerUnit);
208  auto reactivePower = AppendNode(doc, electricalProp, "ReactivePower");
209  SetNodeValue(doc, reactivePower, data.reactivePower);
210  SetNodeAttribute(doc, reactivePower, "UnitID", data.reactivePowerUnit);
211  } //}
212 
213  //{ Inductor
214  auto inductorsNode = AppendNode(doc, elementsNode, "InductorList");
215  auto inductorList = allElements.GetInductorList();
216  for(int i = 0; i < (int)inductorList.size(); i++) {
217  Inductor* inductor = inductorList[i];
218  auto inductorNode = AppendNode(doc, inductorsNode, "Inductor");
219  SetNodeAttribute(doc, inductorNode, "ID", i);
220  auto cadProp = AppendNode(doc, inductorNode, "CADProperties");
221  auto position = AppendNode(doc, cadProp, "Position");
222  auto posX = AppendNode(doc, position, "X");
223  SetNodeValue(doc, posX, inductor->GetPosition().m_x);
224  auto posY = AppendNode(doc, position, "Y");
225  SetNodeValue(doc, posY, inductor->GetPosition().m_y);
226  auto size = AppendNode(doc, cadProp, "Size");
227  auto width = AppendNode(doc, size, "Width");
228  SetNodeValue(doc, width, inductor->GetWidth());
229  auto height = AppendNode(doc, size, "Height");
230  SetNodeValue(doc, height, inductor->GetHeight());
231  auto angle = AppendNode(doc, cadProp, "Angle");
232  SetNodeValue(doc, angle, inductor->GetAngle());
233  auto nodePos = AppendNode(doc, cadProp, "NodePosition");
234  auto nodePosX = AppendNode(doc, nodePos, "X");
235  SetNodeValue(doc, nodePosX, inductor->GetPointList()[0].m_x);
236  auto nodePosY = AppendNode(doc, nodePos, "Y");
237  SetNodeValue(doc, nodePosY, inductor->GetPointList()[0].m_y);
238  auto parentID = AppendNode(doc, cadProp, "ParentID");
239  Bus* parent = static_cast<Bus*>(inductor->GetParentList()[0]);
240  if(parent) SetNodeValue(doc, parentID, parent->GetElectricalData().number);
241 
242  InductorElectricalData data = inductor->GetElectricalData();
243  auto electricalProp = AppendNode(doc, inductorNode, "ElectricalProperties");
244  auto isOnline = AppendNode(doc, electricalProp, "IsOnline");
245  SetNodeValue(doc, isOnline, inductor->IsOnline());
246  auto name = AppendNode(doc, electricalProp, "Name");
247  SetNodeValue(doc, name, data.name);
248  auto reactivePower = AppendNode(doc, electricalProp, "ReactivePower");
249  SetNodeValue(doc, reactivePower, data.reactivePower);
250  SetNodeAttribute(doc, reactivePower, "UnitID", data.reactivePowerUnit);
251 
252  auto switchingList = AppendNode(doc, electricalProp, "SwitchingList");
253  SwitchingData swData = inductor->GetSwitchingData();
254  for(int j = 0; j < (int)swData.swType.size(); j++) {
255  auto switching = AppendNode(doc, switchingList, "Switching");
256  SetNodeAttribute(doc, switching, "ID", j);
257  auto swType = AppendNode(doc, switching, "Type");
258  SetNodeValue(doc, swType, swData.swType[j]);
259  auto swTime = AppendNode(doc, switching, "Time");
260  SetNodeValue(doc, swTime, swData.swTime[j]);
261  }
262  } //}
263 
264  //{ Line
265  auto linesNode = AppendNode(doc, elementsNode, "LineList");
266  auto lineList = allElements.GetLineList();
267  for(int i = 0; i < (int)lineList.size(); i++) {
268  Line* line = lineList[i];
269  auto lineNode = AppendNode(doc, linesNode, "Line");
270  SetNodeAttribute(doc, lineNode, "ID", i);
271  auto cadProp = AppendNode(doc, lineNode, "CADProperties");
272  auto nodeList = AppendNode(doc, cadProp, "NodeList");
273  auto ptList = line->GetPointList();
274  int nodeID = 0;
275  for(int j = 0; j < (int)ptList.size(); j++) {
276  if((j != 1) && (j != (int)ptList.size() - 2)) {
277  auto nodePos = AppendNode(doc, nodeList, "Node");
278  SetNodeAttribute(doc, nodePos, "ID", nodeID);
279  auto nodePosX = AppendNode(doc, nodePos, "X");
280  SetNodeValue(doc, nodePosX, ptList[j].m_x);
281  auto nodePosY = AppendNode(doc, nodePos, "Y");
282  SetNodeValue(doc, nodePosY, ptList[j].m_y);
283  nodeID++;
284  }
285  }
286 
287  auto parentIDList = AppendNode(doc, cadProp, "ParentIDList");
288  for(int j = 0; j < (int)line->GetParentList().size(); j++) {
289  Bus* parent = static_cast<Bus*>(line->GetParentList()[j]);
290  if(parent) {
291  auto parentID = AppendNode(doc, parentIDList, "ParentID");
292  SetNodeAttribute(doc, parentID, "ID", j);
293  SetNodeValue(doc, parentID, parent->GetElectricalData().number);
294  }
295  }
296 
297  LineElectricalData data = line->GetElectricalData();
298  auto electricalProp = AppendNode(doc, lineNode, "ElectricalProperties");
299  auto isOnline = AppendNode(doc, electricalProp, "IsOnline");
300  SetNodeValue(doc, isOnline, line->IsOnline());
301  auto name = AppendNode(doc, electricalProp, "Name");
302  SetNodeValue(doc, name, data.name);
303  auto nominalVoltage = AppendNode(doc, electricalProp, "NominalVoltage");
304  SetNodeValue(doc, nominalVoltage, data.nominalVoltage);
305  SetNodeAttribute(doc, nominalVoltage, "UnitID", data.nominalVoltageUnit);
306  auto nominalPower = AppendNode(doc, electricalProp, "NominalPower");
307  SetNodeValue(doc, nominalPower, data.nominalPower);
308  SetNodeAttribute(doc, nominalPower, "UnitID", data.nominalPowerUnit);
309  auto resistance = AppendNode(doc, electricalProp, "Resistance");
310  SetNodeValue(doc, resistance, data.resistance);
311  SetNodeAttribute(doc, resistance, "UnitID", data.resistanceUnit);
312  auto indReactance = AppendNode(doc, electricalProp, "IndReactance");
313  SetNodeValue(doc, indReactance, data.indReactance);
314  SetNodeAttribute(doc, indReactance, "UnitID", data.indReactanceUnit);
315  auto capSusceptance = AppendNode(doc, electricalProp, "CapSusceptance");
316  SetNodeValue(doc, capSusceptance, data.capSusceptance);
317  SetNodeAttribute(doc, capSusceptance, "UnitID", data.capSusceptanceUnit);
318  auto lineSize = AppendNode(doc, electricalProp, "LineSize");
319  SetNodeValue(doc, lineSize, data.lineSize);
320  auto useLinePower = AppendNode(doc, electricalProp, "UseLinePower");
321  SetNodeValue(doc, useLinePower, data.useLinePower);
322 
323  auto fault = AppendNode(doc, electricalProp, "Fault");
324  auto zeroResistance = AppendNode(doc, fault, "ZeroResistance");
325  SetNodeValue(doc, zeroResistance, data.zeroResistance);
326  auto zeroIndReactance = AppendNode(doc, fault, "ZeroIndReactance");
327  SetNodeValue(doc, zeroIndReactance, data.zeroIndReactance);
328  auto zeroCapSusceptance = AppendNode(doc, fault, "ZeroCapSusceptance");
329  SetNodeValue(doc, zeroCapSusceptance, data.zeroCapSusceptance);
330 
331  auto switchingList = AppendNode(doc, electricalProp, "SwitchingList");
332  SwitchingData swData = line->GetSwitchingData();
333  for(int j = 0; j < (int)swData.swType.size(); j++) {
334  auto switching = AppendNode(doc, switchingList, "Switching");
335  SetNodeAttribute(doc, switching, "ID", j);
336  auto swType = AppendNode(doc, switching, "Type");
337  SetNodeValue(doc, swType, swData.swType[j]);
338  auto swTime = AppendNode(doc, switching, "Time");
339  SetNodeValue(doc, swTime, swData.swTime[j]);
340  }
341  } //}
342 
343  //{ Load
344  auto loadsNode = AppendNode(doc, elementsNode, "LoadList");
345  auto loadList = allElements.GetLoadList();
346  for(int i = 0; i < (int)loadList.size(); i++) {
347  Load* load = loadList[i];
348  auto loadNode = AppendNode(doc, loadsNode, "Load");
349  SetNodeAttribute(doc, loadNode, "ID", i);
350  auto cadProp = AppendNode(doc, loadNode, "CADProperties");
351  auto position = AppendNode(doc, cadProp, "Position");
352  auto posX = AppendNode(doc, position, "X");
353  SetNodeValue(doc, posX, load->GetPosition().m_x);
354  auto posY = AppendNode(doc, position, "Y");
355  SetNodeValue(doc, posY, load->GetPosition().m_y);
356  auto size = AppendNode(doc, cadProp, "Size");
357  auto width = AppendNode(doc, size, "Width");
358  SetNodeValue(doc, width, load->GetWidth());
359  auto height = AppendNode(doc, size, "Height");
360  SetNodeValue(doc, height, load->GetHeight());
361  auto angle = AppendNode(doc, cadProp, "Angle");
362  SetNodeValue(doc, angle, load->GetAngle());
363  auto nodePos = AppendNode(doc, cadProp, "NodePosition");
364  auto nodePosX = AppendNode(doc, nodePos, "X");
365  SetNodeValue(doc, nodePosX, load->GetPointList()[0].m_x);
366  auto nodePosY = AppendNode(doc, nodePos, "Y");
367  SetNodeValue(doc, nodePosY, load->GetPointList()[0].m_y);
368  auto parentID = AppendNode(doc, cadProp, "ParentID");
369  Bus* parent = static_cast<Bus*>(load->GetParentList()[0]);
370  if(parent) SetNodeValue(doc, parentID, parent->GetElectricalData().number);
371 
372  LoadElectricalData data = load->GetElectricalData();
373  auto electricalProp = AppendNode(doc, loadNode, "ElectricalProperties");
374  auto isOnline = AppendNode(doc, electricalProp, "IsOnline");
375  SetNodeValue(doc, isOnline, load->IsOnline());
376  auto name = AppendNode(doc, electricalProp, "Name");
377  SetNodeValue(doc, name, data.name);
378  auto activePower = AppendNode(doc, electricalProp, "ActivePower");
379  SetNodeValue(doc, activePower, data.activePower);
380  SetNodeAttribute(doc, activePower, "UnitID", data.activePowerUnit);
381  auto reactivePower = AppendNode(doc, electricalProp, "ReactivePower");
382  SetNodeValue(doc, reactivePower, data.reactivePower);
383  SetNodeAttribute(doc, reactivePower, "UnitID", data.reactivePowerUnit);
384  auto loadType = AppendNode(doc, electricalProp, "LoadType");
385  SetNodeValue(doc, loadType, data.loadType);
386 
387  auto switchingList = AppendNode(doc, electricalProp, "SwitchingList");
388  SwitchingData swData = load->GetSwitchingData();
389  for(int j = 0; j < (int)swData.swType.size(); j++) {
390  auto switching = AppendNode(doc, switchingList, "Switching");
391  SetNodeAttribute(doc, switching, "ID", j);
392  auto swType = AppendNode(doc, switching, "Type");
393  SetNodeValue(doc, swType, swData.swType[j]);
394  auto swTime = AppendNode(doc, switching, "Time");
395  SetNodeValue(doc, swTime, swData.swTime[j]);
396  }
397  } //}
398 
399  //{ SyncGenerator
400  auto syncGeneratorsNode = AppendNode(doc, elementsNode, "SyncGeneratorList");
401  auto syncGeneratorList = allElements.GetSyncGeneratorList();
402  for(int i = 0; i < (int)syncGeneratorList.size(); i++) {
403  SyncGenerator* syncGenerator = syncGeneratorList[i];
404  auto syncGeneratorNode = AppendNode(doc, syncGeneratorsNode, "SyncGenerator");
405  SetNodeAttribute(doc, syncGeneratorNode, "ID", i);
406  auto cadProp = AppendNode(doc, syncGeneratorNode, "CADProperties");
407  auto position = AppendNode(doc, cadProp, "Position");
408  auto posX = AppendNode(doc, position, "X");
409  SetNodeValue(doc, posX, syncGenerator->GetPosition().m_x);
410  auto posY = AppendNode(doc, position, "Y");
411  SetNodeValue(doc, posY, syncGenerator->GetPosition().m_y);
412  auto size = AppendNode(doc, cadProp, "Size");
413  auto width = AppendNode(doc, size, "Width");
414  SetNodeValue(doc, width, syncGenerator->GetWidth());
415  auto height = AppendNode(doc, size, "Height");
416  SetNodeValue(doc, height, syncGenerator->GetHeight());
417  auto angle = AppendNode(doc, cadProp, "Angle");
418  SetNodeValue(doc, angle, syncGenerator->GetAngle());
419  auto nodePos = AppendNode(doc, cadProp, "NodePosition");
420  auto nodePosX = AppendNode(doc, nodePos, "X");
421  SetNodeValue(doc, nodePosX, syncGenerator->GetPointList()[0].m_x);
422  auto nodePosY = AppendNode(doc, nodePos, "Y");
423  SetNodeValue(doc, nodePosY, syncGenerator->GetPointList()[0].m_y);
424  auto parentID = AppendNode(doc, cadProp, "ParentID");
425  Bus* parent = static_cast<Bus*>(syncGenerator->GetParentList()[0]);
426  if(parent) SetNodeValue(doc, parentID, parent->GetElectricalData().number);
427 
428  SyncGeneratorElectricalData data = syncGenerator->GetElectricalData();
429  auto electricalProp = AppendNode(doc, syncGeneratorNode, "ElectricalProperties");
430  auto isOnline = AppendNode(doc, electricalProp, "IsOnline");
431  SetNodeValue(doc, isOnline, syncGenerator->IsOnline());
432  auto name = AppendNode(doc, electricalProp, "Name");
433  SetNodeValue(doc, name, data.name);
434  auto nominalPower = AppendNode(doc, electricalProp, "NominalPower");
435  SetNodeValue(doc, nominalPower, data.nominalPower);
436  SetNodeAttribute(doc, nominalPower, "UnitID", data.nominalPowerUnit);
437  auto nominalVoltage = AppendNode(doc, electricalProp, "NominalVoltage");
438  SetNodeValue(doc, nominalVoltage, data.nominalVoltage);
439  SetNodeAttribute(doc, nominalVoltage, "UnitID", data.nominalVoltageUnit);
440  auto activePower = AppendNode(doc, electricalProp, "ActivePower");
441  SetNodeValue(doc, activePower, data.activePower);
442  SetNodeAttribute(doc, activePower, "UnitID", data.activePowerUnit);
443  auto reactivePower = AppendNode(doc, electricalProp, "ReactivePower");
444  SetNodeValue(doc, reactivePower, data.reactivePower);
445  SetNodeAttribute(doc, reactivePower, "UnitID", data.reactivePowerUnit);
446  auto haveMaxReactive = AppendNode(doc, electricalProp, "HaveMaxReactive");
447  SetNodeValue(doc, haveMaxReactive, data.haveMaxReactive);
448  auto maxReactive = AppendNode(doc, electricalProp, "MaxReactive");
449  SetNodeValue(doc, maxReactive, data.maxReactive);
450  SetNodeAttribute(doc, maxReactive, "UnitID", data.maxReactiveUnit);
451  auto haveMinReactive = AppendNode(doc, electricalProp, "HaveMinReactive");
452  SetNodeValue(doc, haveMinReactive, data.haveMinReactive);
453  auto minReactive = AppendNode(doc, electricalProp, "MinReactive");
454  SetNodeValue(doc, minReactive, data.minReactive);
455  SetNodeAttribute(doc, minReactive, "UnitID", data.minReactiveUnit);
456  auto useMachineBase = AppendNode(doc, electricalProp, "UseMachineBase");
457  SetNodeValue(doc, useMachineBase, data.useMachineBase);
458 
459  auto fault = AppendNode(doc, electricalProp, "Fault");
460  auto positiveResistance = AppendNode(doc, fault, "PositiveResistance");
461  SetNodeValue(doc, positiveResistance, data.positiveResistance);
462  auto positiveReactance = AppendNode(doc, fault, "PositiveReactance");
463  SetNodeValue(doc, positiveReactance, data.positiveReactance);
464  auto negativeResistance = AppendNode(doc, fault, "NegativeResistance");
465  SetNodeValue(doc, negativeResistance, data.negativeResistance);
466  auto negativeReactance = AppendNode(doc, fault, "NegativeReactance");
467  SetNodeValue(doc, negativeReactance, data.negativeReactance);
468  auto zeroResistance = AppendNode(doc, fault, "ZeroResistance");
469  SetNodeValue(doc, zeroResistance, data.zeroResistance);
470  auto zeroReactance = AppendNode(doc, fault, "ZeroReactance");
471  SetNodeValue(doc, zeroReactance, data.zeroReactance);
472  auto groundResistance = AppendNode(doc, fault, "GroundResistance");
473  SetNodeValue(doc, groundResistance, data.groundResistance);
474  auto groundReactance = AppendNode(doc, fault, "GroundReactance");
475  SetNodeValue(doc, groundReactance, data.groundReactance);
476  auto groundNeutral = AppendNode(doc, fault, "GroundNeutral");
477  SetNodeValue(doc, groundNeutral, data.groundNeutral);
478 
479  auto stability = AppendNode(doc, electricalProp, "Stability");
480  auto plotSyncMachine = AppendNode(doc, stability, "PlotSyncMachine");
481  SetNodeValue(doc, plotSyncMachine, data.plotSyncMachine);
482  auto inertia = AppendNode(doc, stability, "Inertia");
483  SetNodeValue(doc, inertia, data.inertia);
484  auto damping = AppendNode(doc, stability, "Damping");
485  SetNodeValue(doc, damping, data.damping);
486  auto useAVR = AppendNode(doc, stability, "UseAVR");
487  SetNodeValue(doc, useAVR, data.useAVR);
488  auto useSpeedGovernor = AppendNode(doc, stability, "UseSpeedGovernor");
489  SetNodeValue(doc, useSpeedGovernor, data.useSpeedGovernor);
490  auto armResistance = AppendNode(doc, stability, "ArmResistance");
491  SetNodeValue(doc, armResistance, data.armResistance);
492  auto potierReactance = AppendNode(doc, stability, "PotierReactance");
493  SetNodeValue(doc, potierReactance, data.potierReactance);
494  auto satFactor = AppendNode(doc, stability, "SatFactor");
495  SetNodeValue(doc, satFactor, data.satFactor);
496  auto syncXd = AppendNode(doc, stability, "SyncXd");
497  SetNodeValue(doc, syncXd, data.syncXd);
498  auto syncXq = AppendNode(doc, stability, "SyncXq");
499  SetNodeValue(doc, syncXq, data.syncXq);
500  auto transXd = AppendNode(doc, stability, "TransXd");
501  SetNodeValue(doc, transXd, data.transXd);
502  auto transXq = AppendNode(doc, stability, "TransXq");
503  SetNodeValue(doc, transXq, data.transXq);
504  auto transTd0 = AppendNode(doc, stability, "TransTd0");
505  SetNodeValue(doc, transTd0, data.transTd0);
506  auto transTq0 = AppendNode(doc, stability, "TransTq0");
507  SetNodeValue(doc, transTq0, data.transTq0);
508  auto subXd = AppendNode(doc, stability, "SubXd");
509  SetNodeValue(doc, subXd, data.subXd);
510  auto subXq = AppendNode(doc, stability, "SubXq");
511  SetNodeValue(doc, subXq, data.subXq);
512  auto subTd0 = AppendNode(doc, stability, "SubTd0");
513  SetNodeValue(doc, subTd0, data.subTd0);
514  auto subTq0 = AppendNode(doc, stability, "SubTq0");
515  SetNodeValue(doc, subTq0, data.subTq0);
516 
517  auto avr = AppendNode(doc, stability, "AVR");
518  if(data.avr) SaveControlElements(doc, avr, data.avr);
519 
520  auto speedGov = AppendNode(doc, stability, "SpeedGovernor");
521  if(data.speedGov) SaveControlElements(doc, speedGov, data.speedGov);
522 
523  auto switchingList = AppendNode(doc, electricalProp, "SwitchingList");
524  SwitchingData swData = syncGenerator->GetSwitchingData();
525  for(int j = 0; j < (int)swData.swType.size(); j++) {
526  auto switching = AppendNode(doc, switchingList, "Switching");
527  SetNodeAttribute(doc, switching, "ID", j);
528  auto swType = AppendNode(doc, switching, "Type");
529  SetNodeValue(doc, swType, swData.swType[j]);
530  auto swTime = AppendNode(doc, switching, "Time");
531  SetNodeValue(doc, swTime, swData.swTime[j]);
532  }
533  } //}
534 
535  //{ SyncMotor
536  auto syncMotorsNode = AppendNode(doc, elementsNode, "SyncMotorList");
537  auto syncMotorList = allElements.GetSyncMotorList();
538  for(int i = 0; i < (int)syncMotorList.size(); i++) {
539  SyncMotor* syncMotor = syncMotorList[i];
540  auto syncMotorNode = AppendNode(doc, syncMotorsNode, "SyncMotor");
541  SetNodeAttribute(doc, syncMotorNode, "ID", i);
542  auto cadProp = AppendNode(doc, syncMotorNode, "CADProperties");
543  auto position = AppendNode(doc, cadProp, "Position");
544  auto posX = AppendNode(doc, position, "X");
545  SetNodeValue(doc, posX, syncMotor->GetPosition().m_x);
546  auto posY = AppendNode(doc, position, "Y");
547  SetNodeValue(doc, posY, syncMotor->GetPosition().m_y);
548  auto size = AppendNode(doc, cadProp, "Size");
549  auto width = AppendNode(doc, size, "Width");
550  SetNodeValue(doc, width, syncMotor->GetWidth());
551  auto height = AppendNode(doc, size, "Height");
552  SetNodeValue(doc, height, syncMotor->GetHeight());
553  auto angle = AppendNode(doc, cadProp, "Angle");
554  SetNodeValue(doc, angle, syncMotor->GetAngle());
555  auto nodePos = AppendNode(doc, cadProp, "NodePosition");
556  auto nodePosX = AppendNode(doc, nodePos, "X");
557  SetNodeValue(doc, nodePosX, syncMotor->GetPointList()[0].m_x);
558  auto nodePosY = AppendNode(doc, nodePos, "Y");
559  SetNodeValue(doc, nodePosY, syncMotor->GetPointList()[0].m_y);
560  auto parentID = AppendNode(doc, cadProp, "ParentID");
561  Bus* parent = static_cast<Bus*>(syncMotor->GetParentList()[0]);
562  if(parent) SetNodeValue(doc, parentID, parent->GetElectricalData().number);
563 
564  SyncMotorElectricalData data = syncMotor->GetElectricalData();
565  auto electricalProp = AppendNode(doc, syncMotorNode, "ElectricalProperties");
566  auto isOnline = AppendNode(doc, electricalProp, "IsOnline");
567  SetNodeValue(doc, isOnline, syncMotor->IsOnline());
568  auto name = AppendNode(doc, electricalProp, "Name");
569  SetNodeValue(doc, name, data.name);
570  auto nominalPower = AppendNode(doc, electricalProp, "NominalPower");
571  SetNodeValue(doc, nominalPower, data.nominalPower);
572  SetNodeAttribute(doc, nominalPower, "UnitID", data.nominalPowerUnit);
573  // auto nominalVoltage = AppendNode(doc, electricalProp, "NominalVoltage");
574  // SetNodeValue(doc, nominalVoltage, data.nominalVoltage);
575  // SetNodeAttribute(doc, nominalVoltage, "UnitID", data.nominalVoltageUnit);
576  auto activePower = AppendNode(doc, electricalProp, "ActivePower");
577  SetNodeValue(doc, activePower, data.activePower);
578  SetNodeAttribute(doc, activePower, "UnitID", data.activePowerUnit);
579  auto reactivePower = AppendNode(doc, electricalProp, "ReactivePower");
580  SetNodeValue(doc, reactivePower, data.reactivePower);
581  SetNodeAttribute(doc, reactivePower, "UnitID", data.reactivePowerUnit);
582  auto haveMaxReactive = AppendNode(doc, electricalProp, "HaveMaxReactive");
583  SetNodeValue(doc, haveMaxReactive, data.haveMaxReactive);
584  auto maxReactive = AppendNode(doc, electricalProp, "MaxReactive");
585  SetNodeValue(doc, maxReactive, data.maxReactive);
586  SetNodeAttribute(doc, maxReactive, "UnitID", data.maxReactiveUnit);
587  auto haveMinReactive = AppendNode(doc, electricalProp, "HaveMinReactive");
588  SetNodeValue(doc, haveMinReactive, data.haveMinReactive);
589  auto minReactive = AppendNode(doc, electricalProp, "MinReactive");
590  SetNodeValue(doc, minReactive, data.minReactive);
591  SetNodeAttribute(doc, minReactive, "UnitID", data.minReactiveUnit);
592  auto useMachineBase = AppendNode(doc, electricalProp, "UseMachineBase");
593  SetNodeValue(doc, useMachineBase, data.useMachineBase);
594 
595  auto fault = AppendNode(doc, electricalProp, "Fault");
596  auto positiveResistance = AppendNode(doc, fault, "PositiveResistance");
597  SetNodeValue(doc, positiveResistance, data.positiveResistance);
598  auto positiveReactance = AppendNode(doc, fault, "PositiveReactance");
599  SetNodeValue(doc, positiveReactance, data.positiveReactance);
600  auto negativeResistance = AppendNode(doc, fault, "NegativeResistance");
601  SetNodeValue(doc, negativeResistance, data.negativeResistance);
602  auto negativeReactance = AppendNode(doc, fault, "NegativeReactance");
603  SetNodeValue(doc, negativeReactance, data.negativeReactance);
604  auto zeroResistance = AppendNode(doc, fault, "ZeroResistance");
605  SetNodeValue(doc, zeroResistance, data.zeroResistance);
606  auto zeroReactance = AppendNode(doc, fault, "ZeroReactance");
607  SetNodeValue(doc, zeroReactance, data.zeroReactance);
608  auto groundResistance = AppendNode(doc, fault, "GroundResistance");
609  SetNodeValue(doc, groundResistance, data.groundResistance);
610  auto groundReactance = AppendNode(doc, fault, "GroundReactance");
611  SetNodeValue(doc, groundReactance, data.groundReactance);
612  auto groundNeutral = AppendNode(doc, fault, "GroundNeutral");
613  SetNodeValue(doc, groundNeutral, data.groundNeutral);
614 
615  // To future use...
616  /*auto stability = AppendNode(doc, electricalProp, "Stability");
617  auto plotSyncMachine = AppendNode(doc, stability, "PlotSyncMotor");
618  SetNodeValue(doc, plotSyncMachine, data.plotSyncMachine);
619  auto inertia = AppendNode(doc, stability, "Inertia");
620  SetNodeValue(doc, inertia, data.inertia);
621  auto damping = AppendNode(doc, stability, "Damping");
622  SetNodeValue(doc, damping, data.damping);
623  auto useAVR = AppendNode(doc, stability, "UseAVR");
624  SetNodeValue(doc, useAVR, data.useAVR);
625  auto armResistance = AppendNode(doc, stability, "ArmResistance");
626  SetNodeValue(doc, armResistance, data.armResistance);
627  auto potierReactance = AppendNode(doc, stability, "PotierReactance");
628  SetNodeValue(doc, potierReactance, data.potierReactance);
629  auto satFactor = AppendNode(doc, stability, "SatFactor");
630  SetNodeValue(doc, satFactor, data.satFactor);
631  auto syncXd = AppendNode(doc, stability, "SyncXd");
632  SetNodeValue(doc, syncXd, data.syncXd);
633  auto syncXq = AppendNode(doc, stability, "SyncXq");
634  SetNodeValue(doc, syncXq, data.syncXq);
635  auto transXd = AppendNode(doc, stability, "TransXd");
636  SetNodeValue(doc, transXd, data.transXd);
637  auto transXq = AppendNode(doc, stability, "TransXq");
638  SetNodeValue(doc, transXq, data.transXq);
639  auto transTd0 = AppendNode(doc, stability, "TransTd0");
640  SetNodeValue(doc, transTd0, data.transTd0);
641  auto transTq0 = AppendNode(doc, stability, "TransTq0");
642  SetNodeValue(doc, transTq0, data.transTq0);
643  auto subXd = AppendNode(doc, stability, "SubXd");
644  SetNodeValue(doc, subXd, data.subXd);
645  auto subXq = AppendNode(doc, stability, "SubXq");
646  SetNodeValue(doc, subXq, data.subXq);
647  auto subTd0 = AppendNode(doc, stability, "SubTd0");
648  SetNodeValue(doc, subTd0, data.subTd0);
649  auto subTq0 = AppendNode(doc, stability, "SubTq0");
650  SetNodeValue(doc, subTq0, data.subTq0);
651 
652  auto switchingList = AppendNode(doc, electricalProp, "SwitchingList");
653  SwitchingData swData = syncGenerator->GetSwitchingData();
654  for(int j = 0; j < (int)swData.swType.size(); j++) {
655  auto switching = AppendNode(doc, switchingList, "Switching");
656  SetNodeAttribute(doc, switching, "ID", j);
657  auto swType = AppendNode(doc, switching, "Type");
658  SetNodeValue(doc, swType, swData.swType[j]);
659  auto swTime = AppendNode(doc, switching, "Time");
660  SetNodeValue(doc, swTime, swData.swTime[j]);
661  }*/
662  } //}
663 
664  //{ Transfomer
665  auto transformersNode = AppendNode(doc, elementsNode, "TransformerList");
666  auto transformerList = allElements.GetTransformerList();
667  for(int i = 0; i < (int)transformerList.size(); i++) {
668  Transformer* transfomer = transformerList[i];
669  auto transformerNode = AppendNode(doc, transformersNode, "Transfomer");
670  SetNodeAttribute(doc, transformerNode, "ID", i);
671  auto cadProp = AppendNode(doc, transformerNode, "CADProperties");
672  auto position = AppendNode(doc, cadProp, "Position");
673  auto posX = AppendNode(doc, position, "X");
674  SetNodeValue(doc, posX, transfomer->GetPosition().m_x);
675  auto posY = AppendNode(doc, position, "Y");
676  SetNodeValue(doc, posY, transfomer->GetPosition().m_y);
677  auto size = AppendNode(doc, cadProp, "Size");
678  auto width = AppendNode(doc, size, "Width");
679  SetNodeValue(doc, width, transfomer->GetWidth());
680  auto height = AppendNode(doc, size, "Height");
681  SetNodeValue(doc, height, transfomer->GetHeight());
682  auto angle = AppendNode(doc, cadProp, "Angle");
683  SetNodeValue(doc, angle, transfomer->GetAngle());
684  auto nodeList = AppendNode(doc, cadProp, "NodeList");
685  auto nodePos1 = AppendNode(doc, nodeList, "Node");
686  SetNodeAttribute(doc, nodePos1, "ID", 0);
687  auto nodePosX1 = AppendNode(doc, nodePos1, "X");
688  SetNodeValue(doc, nodePosX1, transfomer->GetPointList()[0].m_x);
689  auto nodePosY1 = AppendNode(doc, nodePos1, "Y");
690  SetNodeValue(doc, nodePosY1, transfomer->GetPointList()[0].m_y);
691  auto nodePos2 = AppendNode(doc, nodeList, "Node");
692  SetNodeAttribute(doc, nodePos2, "ID", 1);
693  auto nodePosX2 = AppendNode(doc, nodePos2, "X");
694  SetNodeValue(doc, nodePosX2, transfomer->GetPointList()[transfomer->GetPointList().size() - 1].m_x);
695  auto nodePosY2 = AppendNode(doc, nodePos2, "Y");
696  SetNodeValue(doc, nodePosY2, transfomer->GetPointList()[transfomer->GetPointList().size() - 1].m_y);
697 
698  auto parentIDList = AppendNode(doc, cadProp, "ParentIDList");
699  for(int j = 0; j < (int)transfomer->GetParentList().size(); j++) {
700  Bus* parent = static_cast<Bus*>(transfomer->GetParentList()[j]);
701  if(parent) {
702  auto parentID = AppendNode(doc, parentIDList, "ParentID");
703  SetNodeAttribute(doc, parentID, "ID", j);
704  SetNodeValue(doc, parentID, parent->GetElectricalData().number);
705  }
706  }
707 
708  TransformerElectricalData data = transfomer->GetElectricalData();
709  auto electricalProp = AppendNode(doc, transformerNode, "ElectricalProperties");
710  auto isOnline = AppendNode(doc, electricalProp, "IsOnline");
711  SetNodeValue(doc, isOnline, transfomer->IsOnline());
712  auto name = AppendNode(doc, electricalProp, "Name");
713  SetNodeValue(doc, name, data.name);
714  auto primaryNominalVoltage = AppendNode(doc, electricalProp, "PrimaryNominalVoltage");
715  SetNodeValue(doc, primaryNominalVoltage, data.primaryNominalVoltage);
716  SetNodeAttribute(doc, primaryNominalVoltage, "UnitID", data.primaryNominalVoltageUnit);
717  auto secondaryNominalVoltage = AppendNode(doc, electricalProp, "SecondaryNominalVoltage");
718  SetNodeValue(doc, secondaryNominalVoltage, data.secondaryNominalVoltage);
719  SetNodeAttribute(doc, secondaryNominalVoltage, "UnitID", data.secondaryNominalVoltageUnit);
720  auto nominalPower = AppendNode(doc, electricalProp, "NominalPower");
721  SetNodeValue(doc, nominalPower, data.nominalPower);
722  SetNodeAttribute(doc, nominalPower, "UnitID", data.nominalPowerUnit);
723  auto resistance = AppendNode(doc, electricalProp, "Resistance");
724  SetNodeValue(doc, resistance, data.resistance);
725  SetNodeAttribute(doc, resistance, "UnitID", data.resistanceUnit);
726  auto indReactance = AppendNode(doc, electricalProp, "IndReactance");
727  SetNodeValue(doc, indReactance, data.indReactance);
728  SetNodeAttribute(doc, indReactance, "UnitID", data.indReactanceUnit);
729  auto connection = AppendNode(doc, electricalProp, "Connection");
730  SetNodeValue(doc, connection, data.connection);
731  auto turnsRatio = AppendNode(doc, electricalProp, "TurnsRatio");
732  SetNodeValue(doc, turnsRatio, data.turnsRatio);
733  auto phaseShift = AppendNode(doc, electricalProp, "PhaseShift");
734  SetNodeValue(doc, phaseShift, data.phaseShift);
735  auto useTransformerPower = AppendNode(doc, electricalProp, "UseTransfomerPower");
736  SetNodeValue(doc, useTransformerPower, data.useTransformerPower);
737 
738  auto fault = AppendNode(doc, electricalProp, "Fault");
739  auto zeroResistance = AppendNode(doc, fault, "ZeroResistance");
740  SetNodeValue(doc, zeroResistance, data.zeroResistance);
741  auto zeroIndReactance = AppendNode(doc, fault, "ZeroIndReactance");
742  SetNodeValue(doc, zeroIndReactance, data.zeroIndReactance);
743  auto primaryGrndResistance = AppendNode(doc, fault, "PrimaryGrndResistance");
744  SetNodeValue(doc, primaryGrndResistance, data.primaryGrndResistance);
745  auto primaryGrndReactance = AppendNode(doc, fault, "PrimaryGrndReactance");
746  SetNodeValue(doc, primaryGrndReactance, data.primaryGrndReactance);
747  auto secondaryGrndResistance = AppendNode(doc, fault, "SecondaryGrndResistance");
748  SetNodeValue(doc, secondaryGrndResistance, data.secondaryGrndResistance);
749  auto secondaryGrndReactance = AppendNode(doc, fault, "SecondaryGrndReactance");
750  SetNodeValue(doc, secondaryGrndReactance, data.secondaryGrndReactance);
751 
752  auto switchingList = AppendNode(doc, electricalProp, "SwitchingList");
753  SwitchingData swData = transfomer->GetSwitchingData();
754  for(int j = 0; j < (int)swData.swType.size(); j++) {
755  auto switching = AppendNode(doc, switchingList, "Switching");
756  SetNodeAttribute(doc, switching, "ID", j);
757  auto swType = AppendNode(doc, switching, "Type");
758  SetNodeValue(doc, swType, swData.swType[j]);
759  auto swTime = AppendNode(doc, switching, "Time");
760  SetNodeValue(doc, swTime, swData.swTime[j]);
761  }
762  } //}
763 
764  //{ Text
765  auto textsNode = AppendNode(doc, elementsNode, "TextList");
766  auto textList = m_workspace->GetTextList();
767  for(int i = 0; i < (int)textList.size(); i++) {
768  Text* text = textList[i];
769  auto textNode = AppendNode(doc, textsNode, "Text");
770  SetNodeAttribute(doc, textNode, "ID", i);
771  auto cadProp = AppendNode(doc, textNode, "CADProperties");
772  auto position = AppendNode(doc, cadProp, "Position");
773  auto posX = AppendNode(doc, position, "X");
774  SetNodeValue(doc, posX, text->GetPosition().m_x);
775  auto posY = AppendNode(doc, position, "Y");
776  SetNodeValue(doc, posY, text->GetPosition().m_y);
777  auto size = AppendNode(doc, cadProp, "Size");
778  auto width = AppendNode(doc, size, "Width");
779  SetNodeValue(doc, width, text->GetWidth());
780  auto height = AppendNode(doc, size, "Height");
781  SetNodeValue(doc, height, text->GetHeight());
782  auto angle = AppendNode(doc, cadProp, "Angle");
783  SetNodeValue(doc, angle, text->GetAngle());
784  auto textProperties = AppendNode(doc, textNode, "TextProperties");
785  auto elementType = AppendNode(doc, textProperties, "ElementType");
786  SetNodeValue(doc, elementType, text->GetElementType());
787  auto elementNumber = AppendNode(doc, textProperties, "ElementNumber");
788  SetNodeValue(doc, elementNumber, text->GetElementNumber());
789  auto dataType = AppendNode(doc, textProperties, "DataType");
790  SetNodeValue(doc, dataType, text->GetDataType());
791  auto dataUnit = AppendNode(doc, textProperties, "DataUnit");
792  SetNodeValue(doc, dataUnit, text->GetUnit());
793  auto direction = AppendNode(doc, textProperties, "Direction");
794  SetNodeValue(doc, direction, text->GetDirection());
795  auto decimalPlaces = AppendNode(doc, textProperties, "DecimalPlaces");
796  SetNodeValue(doc, decimalPlaces, text->GetDecimalPlaces());
797  }
798  //}
799 
800  std::ofstream writeXML(path.GetFullPath());
801  writeXML << doc;
802  writeXML.close();
803 }
804 
805 bool FileHanding::OpenProject(wxFileName path)
806 {
807  rapidxml::xml_document<> doc;
808  rapidxml::file<> xmlFile(path.GetFullPath().mb_str());
809 
810  doc.parse<0>(xmlFile.data());
811 
812  auto projectNode = doc.first_node("Project");
813  if(!projectNode) return false;
814  auto nameNode = projectNode->first_node("Name");
815  if(!nameNode) return false;
816  m_workspace->SetName(nameNode->value());
817 
818  // Open elements
819  auto elementsNode = projectNode->first_node("Elements");
820  if(!elementsNode) return false;
821  std::vector<Element*> elementList;
822  // Save lists individually to get parents
823  std::vector<Bus*> busList;
824  std::vector<Capacitor*> capacitorList;
825  std::vector<IndMotor*> indMotorList;
826  std::vector<Inductor*> inductorList;
827  std::vector<Line*> lineList;
828  std::vector<Load*> loadList;
829  std::vector<SyncGenerator*> syncGeneratorList;
830  std::vector<SyncMotor*> syncMotorList;
831  std::vector<Transformer*> transformerList;
832  std::vector<Text*> textList;
833 
834  //{ Bus
835  auto busListNode = elementsNode->first_node("BusList");
836  if(!busListNode) return false;
837  auto busNode = busListNode->first_node("Bus");
838  while(busNode) {
839  auto cadPropNode = busNode->first_node("CADProperties");
840  if(!cadPropNode) return false;
841 
842  auto position = cadPropNode->first_node("Position");
843  double posX = GetNodeValueDouble(position, "X");
844  double posY = GetNodeValueDouble(position, "Y");
845  Bus* bus = new Bus(wxPoint2DDouble(posX, posY));
846 
847  auto size = cadPropNode->first_node("Size");
848  double width = GetNodeValueDouble(size, "Width");
849  double height = GetNodeValueDouble(size, "Height");
850  double angle = GetNodeValueDouble(cadPropNode, "Angle");
851  bus->SetWidth(width);
852  bus->SetHeight(height);
853  bus->SetPosition(bus->GetPosition()); // Update bus rectangle.
854  int numRot = angle / bus->GetRotationAngle();
855  bool clockwise = true;
856  if(numRot < 0) {
857  numRot = std::abs(numRot);
858  clockwise = false;
859  }
860  for(int i = 0; i < numRot; i++) bus->Rotate(clockwise);
861 
862  BusElectricalData data = bus->GetElectricalData();
863  auto electricalProp = busNode->first_node("ElectricalProperties");
864  if(!electricalProp) return false;
865 
866  data.name = electricalProp->first_node("Name")->value();
867  data.nominalVoltage = GetNodeValueDouble(electricalProp, "NominalVoltage");
868  data.nominalVoltageUnit = (ElectricalUnit)GetAttributeValueInt(electricalProp, "NominalVoltage", "UnitID");
869  data.isVoltageControlled = GetNodeValueInt(electricalProp, "IsVoltageControlled");
870  data.controlledVoltage = GetNodeValueDouble(electricalProp, "ControlledVoltage");
871  data.controlledVoltageUnitChoice = GetAttributeValueInt(electricalProp, "ControlledVoltage", "Choice");
872  data.slackBus = GetNodeValueInt(electricalProp, "SlackBus");
873  auto fault = electricalProp->first_node("Fault");
874  data.hasFault = GetNodeValueInt(fault, "HasFault");
875  data.faultType = (FaultData)GetNodeValueInt(fault, "Type");
876  data.faultLocation = (FaultData)GetNodeValueInt(fault, "Location");
877  data.faultResistance = GetNodeValueDouble(fault, "Resistance");
878  data.faultReactance = GetNodeValueDouble(fault, "Reactance");
879  auto stability = electricalProp->first_node("Stability");
880  data.plotBus = GetNodeValueInt(stability, "Plot");
881  data.stabHasFault = GetNodeValueInt(stability, "HasFault");
882  data.stabFaultTime = GetNodeValueDouble(stability, "FaultTime");
883  data.stabFaultLength = GetNodeValueDouble(stability, "FaultLength");
884  data.stabFaultResistance = GetNodeValueDouble(stability, "FaultResistance");
885  data.stabFaultReactance = GetNodeValueDouble(stability, "FaultReactance");
886 
887  bus->SetElectricalData(data);
888 
889  if(data.stabHasFault) bus->SetDynamicEvent(true);
890 
891  elementList.push_back(bus);
892  busList.push_back(bus);
893  busNode = busNode->next_sibling("Bus");
894  } //}
895 
896  //{ Capacitor
897  auto capacitorListNode = elementsNode->first_node("CapacitorList");
898  if(!capacitorListNode) return false;
899  auto capacitorNode = capacitorListNode->first_node("Capacitor");
900  while(capacitorNode) {
901  Capacitor* capacitor = new Capacitor();
902 
903  auto cadPropNode = capacitorNode->first_node("CADProperties");
904  if(!cadPropNode) return false;
905 
906  auto position = cadPropNode->first_node("Position");
907  double posX = GetNodeValueDouble(position, "X");
908  double posY = GetNodeValueDouble(position, "Y");
909  auto size = cadPropNode->first_node("Size");
910  double width = GetNodeValueDouble(size, "Width");
911  double height = GetNodeValueDouble(size, "Height");
912  double angle = GetNodeValueDouble(cadPropNode, "Angle");
913  auto nodePosition = cadPropNode->first_node("NodePosition");
914  double nodePosX = GetNodeValueDouble(nodePosition, "X");
915  double nodePosY = GetNodeValueDouble(nodePosition, "Y");
916  int parentID = GetNodeValueInt(cadPropNode, "ParentID");
917  if(parentID == -1) {
918  // If the element has no parent, create a temporary one, remove and delete.
919  Bus* parent = new Bus(wxPoint2DDouble(nodePosX, nodePosY));
920  capacitor->AddParent(parent, wxPoint2DDouble(nodePosX, nodePosY));
921  capacitor->StartMove(capacitor->GetPosition());
922  capacitor->Move(wxPoint2DDouble(posX, posY));
923  capacitor->RemoveParent(parent);
924  delete parent;
925  } else {
926  Bus* parent = busList[parentID];
927  capacitor->AddParent(parent, wxPoint2DDouble(nodePosX, nodePosY));
928  capacitor->StartMove(capacitor->GetPosition());
929  capacitor->Move(wxPoint2DDouble(posX, posY));
930  }
931  capacitor->SetWidth(width);
932  capacitor->SetHeight(height);
933 
934  int numRot = angle / capacitor->GetRotationAngle();
935  bool clockwise = true;
936  if(numRot < 0) {
937  numRot = std::abs(numRot);
938  clockwise = false;
939  }
940  for(int i = 0; i < numRot; i++) capacitor->Rotate(clockwise);
941 
942  auto electricalProp = capacitorNode->first_node("ElectricalProperties");
943  if(!electricalProp) return false;
944 
945  capacitor->SetOnline(GetNodeValueInt(electricalProp, "IsOnline"));
946  CapacitorElectricalData data = capacitor->GetElectricalData();
947  data.name = electricalProp->first_node("Name")->value();
948  data.reactivePower = GetNodeValueDouble(electricalProp, "ReactivePower");
949  data.reactivePowerUnit = (ElectricalUnit)GetAttributeValueInt(electricalProp, "ReactivePower", "UnitID");
950 
951  SwitchingData swData;
952  auto switchingList = electricalProp->first_node("SwitchingList");
953  if(!switchingList) return false;
954  auto swNode = switchingList->first_node("Switching");
955  while(swNode) {
956  swData.swType.push_back((SwitchingType)GetNodeValueInt(swNode, "Type"));
957  swData.swTime.push_back(GetNodeValueDouble(swNode, "Time"));
958  swNode = swNode->next_sibling("Switching");
959  }
960  capacitor->SetSwitchingData(swData);
961 
962  capacitor->SetElectricalData(data);
963 
964  if(swData.swTime.size() != 0) capacitor->SetDynamicEvent(true);
965 
966  elementList.push_back(capacitor);
967  capacitorList.push_back(capacitor);
968  capacitorNode = capacitorNode->next_sibling("Capacitor");
969  } //}
970 
971  //{ IndMotor
972  auto indMotorListNode = elementsNode->first_node("IndMotorList");
973  if(!indMotorListNode) return false;
974  auto indMotorNode = indMotorListNode->first_node("IndMotor");
975  while(indMotorNode) {
976  IndMotor* indMotor = new IndMotor();
977 
978  auto cadPropNode = indMotorNode->first_node("CADProperties");
979  if(!cadPropNode) return false;
980 
981  auto position = cadPropNode->first_node("Position");
982  double posX = GetNodeValueDouble(position, "X");
983  double posY = GetNodeValueDouble(position, "Y");
984  auto size = cadPropNode->first_node("Size");
985  double width = GetNodeValueDouble(size, "Width");
986  double height = GetNodeValueDouble(size, "Height");
987  double angle = GetNodeValueDouble(cadPropNode, "Angle");
988  auto nodePosition = cadPropNode->first_node("NodePosition");
989  double nodePosX = GetNodeValueDouble(nodePosition, "X");
990  double nodePosY = GetNodeValueDouble(nodePosition, "Y");
991  int parentID = GetNodeValueInt(cadPropNode, "ParentID");
992  if(parentID == -1) {
993  // If the element has no parent, create a temporary one, remove and delete.
994  Bus* parent = new Bus(wxPoint2DDouble(nodePosX, nodePosY));
995  indMotor->AddParent(parent, wxPoint2DDouble(nodePosX, nodePosY));
996  indMotor->StartMove(indMotor->GetPosition());
997  indMotor->Move(wxPoint2DDouble(posX, posY));
998  indMotor->RemoveParent(parent);
999  delete parent;
1000  } else {
1001  Bus* parent = busList[parentID];
1002  indMotor->AddParent(parent, wxPoint2DDouble(nodePosX, nodePosY));
1003  indMotor->StartMove(indMotor->GetPosition());
1004  indMotor->Move(wxPoint2DDouble(posX, posY));
1005  }
1006  indMotor->SetWidth(width);
1007  indMotor->SetHeight(height);
1008 
1009  int numRot = angle / indMotor->GetRotationAngle();
1010  bool clockwise = true;
1011  if(numRot < 0) {
1012  numRot = std::abs(numRot);
1013  clockwise = false;
1014  }
1015  for(int i = 0; i < numRot; i++) indMotor->Rotate(clockwise);
1016 
1017  auto electricalProp = indMotorNode->first_node("ElectricalProperties");
1018  if(!electricalProp) return false;
1019 
1020  indMotor->SetOnline(GetNodeValueInt(electricalProp, "IsOnline"));
1021  IndMotorElectricalData data = indMotor->GetElectricalData();
1022  data.name = electricalProp->first_node("Name")->value();
1023  data.activePower = GetNodeValueDouble(electricalProp, "ActivePower");
1024  data.activePowerUnit = (ElectricalUnit)GetAttributeValueInt(electricalProp, "ActivePower", "UnitID");
1025  data.reactivePower = GetNodeValueDouble(electricalProp, "ReactivePower");
1026  data.reactivePowerUnit = (ElectricalUnit)GetAttributeValueInt(electricalProp, "ReactivePower", "UnitID");
1027 
1028  indMotor->SetElectricalData(data);
1029  elementList.push_back(indMotor);
1030  indMotorList.push_back(indMotor);
1031  indMotorNode = indMotorNode->next_sibling("IndMotor");
1032  } //}
1033 
1034  //{ Inductor
1035  auto inductorListNode = elementsNode->first_node("InductorList");
1036  if(!inductorListNode) return false;
1037  auto inductorNode = inductorListNode->first_node("Inductor");
1038  while(inductorNode) {
1039  Inductor* inductor = new Inductor();
1040 
1041  auto cadPropNode = inductorNode->first_node("CADProperties");
1042  if(!cadPropNode) return false;
1043 
1044  auto position = cadPropNode->first_node("Position");
1045  double posX = GetNodeValueDouble(position, "X");
1046  double posY = GetNodeValueDouble(position, "Y");
1047  auto size = cadPropNode->first_node("Size");
1048  double width = GetNodeValueDouble(size, "Width");
1049  double height = GetNodeValueDouble(size, "Height");
1050  double angle = GetNodeValueDouble(cadPropNode, "Angle");
1051  auto nodePosition = cadPropNode->first_node("NodePosition");
1052  double nodePosX = GetNodeValueDouble(nodePosition, "X");
1053  double nodePosY = GetNodeValueDouble(nodePosition, "Y");
1054  int parentID = GetNodeValueInt(cadPropNode, "ParentID");
1055  if(parentID == -1) {
1056  // If the element has no parent, create a temporary one, remove and delete.
1057  Bus* parent = new Bus(wxPoint2DDouble(nodePosX, nodePosY));
1058  inductor->AddParent(parent, wxPoint2DDouble(nodePosX, nodePosY));
1059  inductor->StartMove(inductor->GetPosition());
1060  inductor->Move(wxPoint2DDouble(posX, posY));
1061  inductor->RemoveParent(parent);
1062  delete parent;
1063  } else {
1064  Bus* parent = busList[parentID];
1065  inductor->AddParent(parent, wxPoint2DDouble(nodePosX, nodePosY));
1066  inductor->StartMove(inductor->GetPosition());
1067  inductor->Move(wxPoint2DDouble(posX, posY));
1068  }
1069  inductor->SetWidth(width);
1070  inductor->SetHeight(height);
1071 
1072  int numRot = angle / inductor->GetRotationAngle();
1073  bool clockwise = true;
1074  if(numRot < 0) {
1075  numRot = std::abs(numRot);
1076  clockwise = false;
1077  }
1078  for(int i = 0; i < numRot; i++) inductor->Rotate(clockwise);
1079 
1080  auto electricalProp = inductorNode->first_node("ElectricalProperties");
1081  if(!electricalProp) return false;
1082 
1083  inductor->SetOnline(GetNodeValueInt(electricalProp, "IsOnline"));
1084  InductorElectricalData data = inductor->GetElectricalData();
1085  data.name = electricalProp->first_node("Name")->value();
1086  data.reactivePower = GetNodeValueDouble(electricalProp, "ReactivePower");
1087  data.reactivePowerUnit = (ElectricalUnit)GetAttributeValueInt(electricalProp, "ReactivePower", "UnitID");
1088 
1089  SwitchingData swData;
1090  auto switchingList = electricalProp->first_node("SwitchingList");
1091  if(!switchingList) return false;
1092  auto swNode = switchingList->first_node("Switching");
1093  while(swNode) {
1094  swData.swType.push_back((SwitchingType)GetNodeValueInt(swNode, "Type"));
1095  swData.swTime.push_back(GetNodeValueDouble(swNode, "Time"));
1096  swNode = swNode->next_sibling("Switching");
1097  }
1098  inductor->SetSwitchingData(swData);
1099 
1100  inductor->SetElectricalData(data);
1101 
1102  if(swData.swTime.size() != 0) inductor->SetDynamicEvent(true);
1103 
1104  elementList.push_back(inductor);
1105  inductorList.push_back(inductor);
1106  inductorNode = inductorNode->next_sibling("Inductor");
1107  } //}
1108 
1109  //{ Line
1110  auto lineListNode = elementsNode->first_node("LineList");
1111  if(!lineListNode) return false;
1112  auto lineNode = lineListNode->first_node("Line");
1113  while(lineNode) {
1114  Line* line = new Line();
1115 
1116  auto cadPropNode = lineNode->first_node("CADProperties");
1117  if(!cadPropNode) return false;
1118 
1119  // Get nodes points
1120  std::vector<wxPoint2DDouble> ptsList;
1121  auto nodePosList = cadPropNode->first_node("NodeList");
1122  if(!nodePosList) return false;
1123  auto nodePos = nodePosList->first_node("Node");
1124  while(nodePos) {
1125  double nodePosX = GetNodeValueDouble(nodePos, "X");
1126  double nodePosY = GetNodeValueDouble(nodePos, "Y");
1127  ptsList.push_back(wxPoint2DDouble(nodePosX, nodePosY));
1128  nodePos = nodePos->next_sibling("Node");
1129  }
1130 
1131  // Get parents IDs
1132  auto parentIDList = cadPropNode->first_node("ParentIDList");
1133  if(!parentIDList) return false;
1134  auto parentNode = parentIDList->first_node("ParentID");
1135  long parentID[2] = {-1, -1};
1136  while(parentNode) {
1137  long index = 0;
1138  wxString(parentNode->first_attribute("ID")->value()).ToLong(&index);
1139  wxString(parentNode->value()).ToCLong(&parentID[index]);
1140  parentNode = parentNode->next_sibling("ParentID");
1141  }
1142 
1143  // Set parents (if have)
1144  Bus *parent1, *parent2;
1145  if(parentID[0] == -1) {
1146  parent1 = new Bus(ptsList[0]);
1147  line->AddParent(parent1, ptsList[0]);
1148  } else {
1149  parent1 = busList[parentID[0]];
1150  line->AddParent(parent1, ptsList[0]);
1151  }
1152  if(parentID[1] == -1) {
1153  parent2 = new Bus(ptsList[ptsList.size() - 1]);
1154  line->AddParent(parent2, ptsList[ptsList.size() - 1]);
1155  } else {
1156  parent2 = busList[parentID[1]];
1157  line->AddParent(parent2, ptsList[ptsList.size() - 1]);
1158  }
1159 
1160  // Add the others nodes (if have)
1161  std::vector<wxPoint2DDouble> midPts;
1162  for(int i = 1; i < (int)ptsList.size() - 1; i++) midPts.push_back(ptsList[i]);
1163  std::vector<wxPoint2DDouble> edgesPts = line->GetPointList();
1164  edgesPts.insert(edgesPts.begin() + 2, midPts.begin(), midPts.end());
1165  line->SetPointList(edgesPts);
1166 
1167  if(parentID[0] == -1) {
1168  line->RemoveParent(parent1);
1169  delete parent1;
1170  }
1171  if(parentID[1] == -1) {
1172  line->RemoveParent(parent2);
1173  delete parent2;
1174  }
1175 
1176  auto electricalProp = lineNode->first_node("ElectricalProperties");
1177  if(!electricalProp) return false;
1178 
1179  line->SetOnline(GetNodeValueInt(electricalProp, "IsOnline"));
1180  LineElectricalData data = line->GetElectricalData();
1181  data.name = electricalProp->first_node("Name")->value();
1182  data.nominalVoltage = GetNodeValueDouble(electricalProp, "NominalVoltage");
1183  data.nominalVoltageUnit = (ElectricalUnit)GetAttributeValueInt(electricalProp, "NominalVoltage", "UnitID");
1184  data.nominalPower = GetNodeValueDouble(electricalProp, "NominalPower");
1185  data.nominalPowerUnit = (ElectricalUnit)GetAttributeValueInt(electricalProp, "NominalPower", "UnitID");
1186  data.resistance = GetNodeValueDouble(electricalProp, "Resistance");
1187  data.resistanceUnit = (ElectricalUnit)GetAttributeValueInt(electricalProp, "Resistance", "UnitID");
1188  data.indReactance = GetNodeValueDouble(electricalProp, "IndReactance");
1189  data.indReactanceUnit = (ElectricalUnit)GetAttributeValueInt(electricalProp, "IndReactance", "UnitID");
1190  data.capSusceptance = GetNodeValueDouble(electricalProp, "CapSusceptance");
1191  data.capSusceptanceUnit = (ElectricalUnit)GetAttributeValueInt(electricalProp, "CapSusceptance", "UnitID");
1192  data.lineSize = GetNodeValueDouble(electricalProp, "LineSize");
1193  data.useLinePower = GetNodeValueInt(electricalProp, "UseLinePower");
1194 
1195  auto fault = electricalProp->first_node("Fault");
1196  data.zeroResistance = GetNodeValueDouble(fault, "ZeroResistance");
1197  data.zeroIndReactance = GetNodeValueDouble(fault, "ZeroIndReactance");
1198  data.zeroCapSusceptance = GetNodeValueDouble(fault, "ZeroCapSusceptance");
1199 
1200  SwitchingData swData;
1201  auto switchingList = electricalProp->first_node("SwitchingList");
1202  if(!switchingList) return false;
1203  auto swNode = switchingList->first_node("Switching");
1204  while(swNode) {
1205  swData.swType.push_back((SwitchingType)GetNodeValueInt(swNode, "Type"));
1206  swData.swTime.push_back(GetNodeValueDouble(swNode, "Time"));
1207  swNode = swNode->next_sibling("Switching");
1208  }
1209  line->SetSwitchingData(swData);
1210 
1211  line->SetElectricalData(data);
1212 
1213  if(swData.swTime.size() != 0) line->SetDynamicEvent(true);
1214 
1215  elementList.push_back(line);
1216  lineList.push_back(line);
1217  lineNode = lineNode->next_sibling("Line");
1218  } //}
1219 
1220  //{ Load
1221  auto loadListNode = elementsNode->first_node("LoadList");
1222  if(!loadListNode) return false;
1223  auto loadNode = loadListNode->first_node("Load");
1224  while(loadNode) {
1225  Load* load = new Load();
1226 
1227  auto cadPropNode = loadNode->first_node("CADProperties");
1228  if(!cadPropNode) return false;
1229 
1230  auto position = cadPropNode->first_node("Position");
1231  double posX = GetNodeValueDouble(position, "X");
1232  double posY = GetNodeValueDouble(position, "Y");
1233  auto size = cadPropNode->first_node("Size");
1234  double width = GetNodeValueDouble(size, "Width");
1235  double height = GetNodeValueDouble(size, "Height");
1236  double angle = GetNodeValueDouble(cadPropNode, "Angle");
1237  auto nodePosition = cadPropNode->first_node("NodePosition");
1238  double nodePosX = GetNodeValueDouble(nodePosition, "X");
1239  double nodePosY = GetNodeValueDouble(nodePosition, "Y");
1240  int parentID = GetNodeValueInt(cadPropNode, "ParentID");
1241  if(parentID == -1) {
1242  // If the element has no parent, create a temporary one, remove and delete.
1243  Bus* parent = new Bus(wxPoint2DDouble(nodePosX, nodePosY));
1244  load->AddParent(parent, wxPoint2DDouble(nodePosX, nodePosY));
1245  load->StartMove(load->GetPosition());
1246  load->Move(wxPoint2DDouble(posX, posY));
1247  load->RemoveParent(parent);
1248  delete parent;
1249  } else {
1250  Bus* parent = busList[parentID];
1251  load->AddParent(parent, wxPoint2DDouble(nodePosX, nodePosY));
1252  load->StartMove(load->GetPosition());
1253  load->Move(wxPoint2DDouble(posX, posY));
1254  }
1255  load->SetWidth(width);
1256  load->SetHeight(height);
1257 
1258  int numRot = angle / load->GetRotationAngle();
1259  bool clockwise = true;
1260  if(numRot < 0) {
1261  numRot = std::abs(numRot);
1262  clockwise = false;
1263  }
1264  for(int i = 0; i < numRot; i++) load->Rotate(clockwise);
1265 
1266  auto electricalProp = loadNode->first_node("ElectricalProperties");
1267  if(!electricalProp) return false;
1268 
1269  load->SetOnline(GetNodeValueInt(electricalProp, "IsOnline"));
1270  LoadElectricalData data = load->GetElectricalData();
1271  data.name = electricalProp->first_node("Name")->value();
1272  data.activePower = GetNodeValueDouble(electricalProp, "ActivePower");
1273  data.activePowerUnit = (ElectricalUnit)GetAttributeValueInt(electricalProp, "ActivePower", "UnitID");
1274  data.reactivePower = GetNodeValueDouble(electricalProp, "ReactivePower");
1275  data.reactivePowerUnit = (ElectricalUnit)GetAttributeValueInt(electricalProp, "ReactivePower", "UnitID");
1276  data.loadType = (LoadType)GetNodeValueInt(electricalProp, "LoadType");
1277 
1278  SwitchingData swData;
1279  auto switchingList = electricalProp->first_node("SwitchingList");
1280  if(!switchingList) return false;
1281  auto swNode = switchingList->first_node("Switching");
1282  while(swNode) {
1283  swData.swType.push_back((SwitchingType)GetNodeValueInt(swNode, "Type"));
1284  swData.swTime.push_back(GetNodeValueDouble(swNode, "Time"));
1285  swNode = swNode->next_sibling("Switching");
1286  }
1287  load->SetSwitchingData(swData);
1288 
1289  load->SetElectricalData(data);
1290 
1291  if(swData.swTime.size() != 0) load->SetDynamicEvent(true);
1292 
1293  elementList.push_back(load);
1294  loadList.push_back(load);
1295  loadNode = loadNode->next_sibling("Load");
1296  } //}
1297 
1298  //{ SyncGenerator
1299  auto syncGeneratorListNode = elementsNode->first_node("SyncGeneratorList");
1300  if(!syncGeneratorListNode) return false;
1301  auto syncGeneratorNode = syncGeneratorListNode->first_node("SyncGenerator");
1302  while(syncGeneratorNode) {
1303  SyncGenerator* syncGenerator = new SyncGenerator();
1304 
1305  auto cadPropNode = syncGeneratorNode->first_node("CADProperties");
1306  if(!cadPropNode) return false;
1307 
1308  auto position = cadPropNode->first_node("Position");
1309  double posX = GetNodeValueDouble(position, "X");
1310  double posY = GetNodeValueDouble(position, "Y");
1311  auto size = cadPropNode->first_node("Size");
1312  double width = GetNodeValueDouble(size, "Width");
1313  double height = GetNodeValueDouble(size, "Height");
1314  double angle = GetNodeValueDouble(cadPropNode, "Angle");
1315  auto nodePosition = cadPropNode->first_node("NodePosition");
1316  double nodePosX = GetNodeValueDouble(nodePosition, "X");
1317  double nodePosY = GetNodeValueDouble(nodePosition, "Y");
1318  int parentID = GetNodeValueInt(cadPropNode, "ParentID");
1319  if(parentID == -1) {
1320  // If the element has no parent, create a temporary one, remove and delete.
1321  Bus* parent = new Bus(wxPoint2DDouble(nodePosX, nodePosY));
1322  syncGenerator->AddParent(parent, wxPoint2DDouble(nodePosX, nodePosY));
1323  syncGenerator->StartMove(syncGenerator->GetPosition());
1324  syncGenerator->Move(wxPoint2DDouble(posX, posY));
1325  syncGenerator->RemoveParent(parent);
1326  delete parent;
1327  } else {
1328  Bus* parent = busList[parentID];
1329  syncGenerator->AddParent(parent, wxPoint2DDouble(nodePosX, nodePosY));
1330  syncGenerator->StartMove(syncGenerator->GetPosition());
1331  syncGenerator->Move(wxPoint2DDouble(posX, posY));
1332  }
1333  syncGenerator->SetWidth(width);
1334  syncGenerator->SetHeight(height);
1335 
1336  int numRot = angle / syncGenerator->GetRotationAngle();
1337  bool clockwise = true;
1338  if(numRot < 0) {
1339  numRot = std::abs(numRot);
1340  clockwise = false;
1341  }
1342  for(int i = 0; i < numRot; i++) syncGenerator->Rotate(clockwise);
1343 
1344  auto electricalProp = syncGeneratorNode->first_node("ElectricalProperties");
1345  if(!electricalProp) return false;
1346 
1347  syncGenerator->SetOnline(GetNodeValueInt(electricalProp, "IsOnline"));
1348  SyncGeneratorElectricalData data = syncGenerator->GetElectricalData();
1349  data.name = electricalProp->first_node("Name")->value();
1350  data.nominalPower = GetNodeValueDouble(electricalProp, "NominalPower");
1351  data.nominalPowerUnit = (ElectricalUnit)GetAttributeValueInt(electricalProp, "NominalPower", "UnitID");
1352  data.nominalVoltage = GetNodeValueDouble(electricalProp, "NominalVoltage");
1353  data.nominalVoltageUnit = (ElectricalUnit)GetAttributeValueInt(electricalProp, "NominalVoltage", "UnitID");
1354  data.activePower = GetNodeValueDouble(electricalProp, "ActivePower");
1355  data.activePowerUnit = (ElectricalUnit)GetAttributeValueInt(electricalProp, "ActivePower", "UnitID");
1356  data.reactivePower = GetNodeValueDouble(electricalProp, "ReactivePower");
1357  data.reactivePowerUnit = (ElectricalUnit)GetAttributeValueInt(electricalProp, "ReactivePower", "UnitID");
1358  data.haveMaxReactive = GetNodeValueInt(electricalProp, "HaveMaxReactive");
1359  data.maxReactive = GetNodeValueDouble(electricalProp, "MaxReactive");
1360  data.maxReactiveUnit = (ElectricalUnit)GetAttributeValueInt(electricalProp, "MaxReactive", "UnitID");
1361  data.haveMinReactive = GetNodeValueInt(electricalProp, "HaveMinReactive");
1362  data.minReactive = GetNodeValueDouble(electricalProp, "MinReactive");
1363  data.minReactiveUnit = (ElectricalUnit)GetAttributeValueInt(electricalProp, "MinReactive", "UnitID");
1364  data.useMachineBase = GetNodeValueInt(electricalProp, "UseMachineBase");
1365 
1366  auto fault = electricalProp->first_node("Fault");
1367  if(!fault) return false;
1368  data.positiveResistance = GetNodeValueDouble(fault, "PositiveResistance");
1369  data.positiveReactance = GetNodeValueDouble(fault, "PositiveReactance");
1370  data.negativeResistance = GetNodeValueDouble(fault, "NegativeResistance");
1371  data.negativeReactance = GetNodeValueDouble(fault, "NegativeReactance");
1372  data.zeroResistance = GetNodeValueDouble(fault, "ZeroResistance");
1373  data.zeroReactance = GetNodeValueDouble(fault, "ZeroReactance");
1374  data.groundResistance = GetNodeValueDouble(fault, "GroundResistance");
1375  data.groundReactance = GetNodeValueDouble(fault, "GroundReactance");
1376  data.groundNeutral = GetNodeValueInt(fault, "GroundNeutral");
1377 
1378  auto stability = electricalProp->first_node("Stability");
1379  if(!stability) return false;
1380  data.plotSyncMachine = GetNodeValueInt(stability, "PlotSyncMachine");
1381  data.inertia = GetNodeValueDouble(stability, "Inertia");
1382  data.damping = GetNodeValueDouble(stability, "Damping");
1383  data.useAVR = GetNodeValueInt(stability, "UseAVR");
1384  data.useSpeedGovernor = GetNodeValueInt(stability, "UseSpeedGovernor");
1385  data.armResistance = GetNodeValueDouble(stability, "ArmResistance");
1386  data.potierReactance = GetNodeValueDouble(stability, "PotierReactance");
1387  data.satFactor = GetNodeValueDouble(stability, "SatFactor");
1388  data.syncXd = GetNodeValueDouble(stability, "SyncXd");
1389  data.syncXq = GetNodeValueDouble(stability, "SyncXq");
1390  data.transXd = GetNodeValueDouble(stability, "TransXd");
1391  data.transXq = GetNodeValueDouble(stability, "TransXq");
1392  data.transTd0 = GetNodeValueDouble(stability, "TransTd0");
1393  data.transTq0 = GetNodeValueDouble(stability, "TransTq0");
1394  data.subXd = GetNodeValueDouble(stability, "SubXd");
1395  data.subXq = GetNodeValueDouble(stability, "SubXq");
1396  data.subTd0 = GetNodeValueDouble(stability, "SubTd0");
1397  data.subTq0 = GetNodeValueDouble(stability, "SubTq0");
1398 
1399  auto avr = stability->first_node("AVR");
1400  if(!avr) return false;
1401  if(!OpenControlElements(doc, avr, data.avr)) return false;
1402 
1403  auto speedGov = stability->first_node("SpeedGovernor");
1404  if(!speedGov) return false;
1405  if(!OpenControlElements(doc, speedGov, data.speedGov)) return false;
1406 
1407  SwitchingData swData;
1408  auto switchingList = electricalProp->first_node("SwitchingList");
1409  if(!switchingList) return false;
1410  auto swNode = switchingList->first_node("Switching");
1411  while(swNode) {
1412  swData.swType.push_back((SwitchingType)GetNodeValueInt(swNode, "Type"));
1413  swData.swTime.push_back(GetNodeValueDouble(swNode, "Time"));
1414  swNode = swNode->next_sibling("Switching");
1415  }
1416  syncGenerator->SetSwitchingData(swData);
1417 
1418  syncGenerator->SetElectricalData(data);
1419 
1420  if(swData.swTime.size() != 0) syncGenerator->SetDynamicEvent(true);
1421 
1422  elementList.push_back(syncGenerator);
1423  syncGeneratorList.push_back(syncGenerator);
1424  syncGeneratorNode = syncGeneratorNode->next_sibling("SyncGenerator");
1425  } //}
1426 
1427  //{ SyncMotor
1428  auto syncMotorListNode = elementsNode->first_node("SyncMotorList");
1429  if(!syncMotorListNode) return false;
1430  auto syncMotorNode = syncMotorListNode->first_node("SyncMotor");
1431  while(syncMotorNode) {
1432  SyncMotor* syncMotor = new SyncMotor();
1433 
1434  auto cadPropNode = syncMotorNode->first_node("CADProperties");
1435  if(!cadPropNode) return false;
1436 
1437  auto position = cadPropNode->first_node("Position");
1438  double posX = GetNodeValueDouble(position, "X");
1439  double posY = GetNodeValueDouble(position, "Y");
1440  auto size = cadPropNode->first_node("Size");
1441  double width = GetNodeValueDouble(size, "Width");
1442  double height = GetNodeValueDouble(size, "Height");
1443  double angle = GetNodeValueDouble(cadPropNode, "Angle");
1444  auto nodePosition = cadPropNode->first_node("NodePosition");
1445  double nodePosX = GetNodeValueDouble(nodePosition, "X");
1446  double nodePosY = GetNodeValueDouble(nodePosition, "Y");
1447  int parentID = GetNodeValueInt(cadPropNode, "ParentID");
1448  if(parentID == -1) {
1449  // If the element has no parent, create a temporary one, remove and delete.
1450  Bus* parent = new Bus(wxPoint2DDouble(nodePosX, nodePosY));
1451  syncMotor->AddParent(parent, wxPoint2DDouble(nodePosX, nodePosY));
1452  syncMotor->StartMove(syncMotor->GetPosition());
1453  syncMotor->Move(wxPoint2DDouble(posX, posY));
1454  syncMotor->RemoveParent(parent);
1455  delete parent;
1456  } else {
1457  Bus* parent = busList[parentID];
1458  syncMotor->AddParent(parent, wxPoint2DDouble(nodePosX, nodePosY));
1459  syncMotor->StartMove(syncMotor->GetPosition());
1460  syncMotor->Move(wxPoint2DDouble(posX, posY));
1461  }
1462  syncMotor->SetWidth(width);
1463  syncMotor->SetHeight(height);
1464 
1465  int numRot = angle / syncMotor->GetRotationAngle();
1466  bool clockwise = true;
1467  if(numRot < 0) {
1468  numRot = std::abs(numRot);
1469  clockwise = false;
1470  }
1471  for(int i = 0; i < numRot; i++) syncMotor->Rotate(clockwise);
1472 
1473  auto electricalProp = syncMotorNode->first_node("ElectricalProperties");
1474  if(!electricalProp) return false;
1475 
1476  syncMotor->SetOnline(GetNodeValueInt(electricalProp, "IsOnline"));
1477  SyncMotorElectricalData data = syncMotor->GetElectricalData();
1478  data.name = electricalProp->first_node("Name")->value();
1479  data.nominalPower = GetNodeValueDouble(electricalProp, "NominalPower");
1480  data.nominalPowerUnit = (ElectricalUnit)GetAttributeValueInt(electricalProp, "NominalPower", "UnitID");
1481  // data.nominalVoltage = GetNodeValueDouble(electricalProp, "NominalVoltage");
1482  // data.nominalVoltageUnit = (ElectricalUnit)GetAttributeValueInt(electricalProp, "NominalVoltage", "UnitID");
1483  data.activePower = GetNodeValueDouble(electricalProp, "ActivePower");
1484  data.activePowerUnit = (ElectricalUnit)GetAttributeValueInt(electricalProp, "ActivePower", "UnitID");
1485  data.reactivePower = GetNodeValueDouble(electricalProp, "ReactivePower");
1486  data.reactivePowerUnit = (ElectricalUnit)GetAttributeValueInt(electricalProp, "ReactivePower", "UnitID");
1487  data.haveMaxReactive = GetNodeValueInt(electricalProp, "HaveMaxReactive");
1488  data.maxReactive = GetNodeValueDouble(electricalProp, "MaxReactive");
1489  data.maxReactiveUnit = (ElectricalUnit)GetAttributeValueInt(electricalProp, "MaxReactive", "UnitID");
1490  data.haveMinReactive = GetNodeValueInt(electricalProp, "HaveMinReactive");
1491  data.minReactive = GetNodeValueDouble(electricalProp, "MinReactive");
1492  data.minReactiveUnit = (ElectricalUnit)GetAttributeValueInt(electricalProp, "MinReactive", "UnitID");
1493  data.useMachineBase = GetNodeValueInt(electricalProp, "UseMachineBase");
1494 
1495  auto fault = electricalProp->first_node("Fault");
1496  if(!fault) return false;
1497  data.positiveResistance = GetNodeValueDouble(fault, "PositiveResistance");
1498  data.positiveReactance = GetNodeValueDouble(fault, "PositiveReactance");
1499  data.negativeResistance = GetNodeValueDouble(fault, "NegativeResistance");
1500  data.negativeReactance = GetNodeValueDouble(fault, "NegativeReactance");
1501  data.zeroResistance = GetNodeValueDouble(fault, "ZeroResistance");
1502  data.zeroReactance = GetNodeValueDouble(fault, "ZeroReactance");
1503  data.groundResistance = GetNodeValueDouble(fault, "GroundResistance");
1504  data.groundReactance = GetNodeValueDouble(fault, "GroundReactance");
1505  data.groundNeutral = GetNodeValueInt(fault, "GroundNeutral");
1506 
1507  /*SwitchingData swData;
1508  auto switchingList = electricalProp->first_node("SwitchingList");
1509  if(!switchingList) return false;
1510  auto swNode = switchingList->first_node("Switching");
1511  while(swNode) {
1512  swData.swType.push_back((SwitchingType)GetNodeValueInt(swNode, "Type"));
1513  swData.swTime.push_back(GetNodeValueDouble(swNode, "Time"));
1514  swNode = swNode->next_sibling("Switching");
1515  }
1516  syncMotor->SetSwitchingData(swData);*/
1517 
1518  syncMotor->SetElectricalData(data);
1519  elementList.push_back(syncMotor);
1520  syncMotorList.push_back(syncMotor);
1521  syncMotorNode = syncMotorNode->next_sibling("SyncMotor");
1522  } //}
1523 
1524  //{ Transformer
1525  auto transformerListNode = elementsNode->first_node("TransformerList");
1526  if(!transformerListNode) return false;
1527  auto transfomerNode = transformerListNode->first_node("Transfomer");
1528  while(transfomerNode) {
1529  Transformer* transformer = new Transformer();
1530 
1531  auto cadPropNode = transfomerNode->first_node("CADProperties");
1532  if(!cadPropNode) return false;
1533 
1534  auto position = cadPropNode->first_node("Position");
1535  double posX = GetNodeValueDouble(position, "X");
1536  double posY = GetNodeValueDouble(position, "Y");
1537  auto size = cadPropNode->first_node("Size");
1538  double width = GetNodeValueDouble(size, "Width");
1539  double height = GetNodeValueDouble(size, "Height");
1540  double angle = GetNodeValueDouble(cadPropNode, "Angle");
1541 
1542  // Get nodes points
1543  std::vector<wxPoint2DDouble> ptsList;
1544  auto nodePosList = cadPropNode->first_node("NodeList");
1545  if(!nodePosList) return false;
1546  auto nodePos = nodePosList->first_node("Node");
1547  while(nodePos) {
1548  double nodePosX = GetNodeValueDouble(nodePos, "X");
1549  double nodePosY = GetNodeValueDouble(nodePos, "Y");
1550  ptsList.push_back(wxPoint2DDouble(nodePosX, nodePosY));
1551  nodePos = nodePos->next_sibling("Node");
1552  }
1553 
1554  // Get parents IDs
1555  auto parentIDList = cadPropNode->first_node("ParentIDList");
1556  if(!parentIDList) return false;
1557  auto parentNode = parentIDList->first_node("ParentID");
1558  long parentID[2] = {-1, -1};
1559  while(parentNode) {
1560  long index = 0;
1561  wxString(parentNode->first_attribute("ID")->value()).ToLong(&index);
1562  wxString(parentNode->value()).ToCLong(&parentID[index]);
1563  parentNode = parentNode->next_sibling("ParentID");
1564  }
1565 
1566  // Set parents (if have)
1567  Bus *parent1, *parent2;
1568  if(parentID[0] == -1) {
1569  parent1 = new Bus(ptsList[0]);
1570  transformer->AddParent(parent1, ptsList[0]);
1571  } else {
1572  parent1 = busList[parentID[0]];
1573  transformer->AddParent(parent1, ptsList[0]);
1574  }
1575  if(parentID[1] == -1) {
1576  parent2 = new Bus(ptsList[ptsList.size() - 1]);
1577  transformer->AddParent(parent2, ptsList[ptsList.size() - 1]);
1578  } else {
1579  parent2 = busList[parentID[1]];
1580  transformer->AddParent(parent2, ptsList[ptsList.size() - 1]);
1581  }
1582 
1583  transformer->StartMove(transformer->GetPosition());
1584  transformer->Move(wxPoint2DDouble(posX, posY));
1585 
1586  if(parentID[0] == -1) {
1587  transformer->RemoveParent(parent1);
1588  delete parent1;
1589  }
1590  if(parentID[1] == -1) {
1591  transformer->RemoveParent(parent2);
1592  delete parent2;
1593  }
1594 
1595  transformer->SetWidth(width);
1596  transformer->SetHeight(height);
1597 
1598  int numRot = angle / transformer->GetRotationAngle();
1599  bool clockwise = true;
1600  if(numRot < 0) {
1601  numRot = std::abs(numRot);
1602  clockwise = false;
1603  }
1604  for(int i = 0; i < numRot; i++) transformer->Rotate(clockwise);
1605 
1606  auto electricalProp = transfomerNode->first_node("ElectricalProperties");
1607  if(!electricalProp) return false;
1608 
1609  transformer->SetOnline(GetNodeValueInt(electricalProp, "IsOnline"));
1610  TransformerElectricalData data = transformer->GetElectricalData();
1611  data.name = electricalProp->first_node("Name")->value();
1612  data.primaryNominalVoltage = GetNodeValueDouble(electricalProp, "PrimaryNominalVoltage");
1613  data.primaryNominalVoltageUnit =
1614  (ElectricalUnit)GetAttributeValueInt(electricalProp, "PrimaryNominalVoltage", "UnitID");
1615  data.secondaryNominalVoltage = GetNodeValueDouble(electricalProp, "SecondaryNominalVoltage");
1616  data.secondaryNominalVoltageUnit =
1617  (ElectricalUnit)GetAttributeValueInt(electricalProp, "SecondaryNominalVoltage", "UnitID");
1618  data.nominalPower = GetNodeValueDouble(electricalProp, "NominalPower");
1619  data.nominalPowerUnit = (ElectricalUnit)GetAttributeValueInt(electricalProp, "NominalPower", "UnitID");
1620  data.resistance = GetNodeValueDouble(electricalProp, "Resistance");
1621  data.resistanceUnit = (ElectricalUnit)GetAttributeValueInt(electricalProp, "Resistance", "UnitID");
1622  data.indReactance = GetNodeValueDouble(electricalProp, "IndReactance");
1623  data.indReactanceUnit = (ElectricalUnit)GetAttributeValueInt(electricalProp, "IndReactance", "UnitID");
1624  data.connection = (TransformerConnection)GetNodeValueInt(electricalProp, "Connection");
1625  data.turnsRatio = GetNodeValueDouble(electricalProp, "TurnsRatio");
1626  data.phaseShift = GetNodeValueDouble(electricalProp, "PhaseShift");
1627  data.useTransformerPower = GetNodeValueInt(electricalProp, "UseTransfomerPower");
1628 
1629  auto fault = electricalProp->first_node("Fault");
1630  data.zeroResistance = GetNodeValueDouble(fault, "ZeroResistance");
1631  data.zeroIndReactance = GetNodeValueDouble(fault, "ZeroIndReactance");
1632  data.primaryGrndResistance = GetNodeValueDouble(fault, "PrimaryGrndResistance");
1633  data.primaryGrndReactance = GetNodeValueDouble(fault, "PrimaryGrndReactance");
1634  data.secondaryGrndResistance = GetNodeValueDouble(fault, "SecondaryGrndResistance");
1635  data.secondaryGrndReactance = GetNodeValueDouble(fault, "SecondaryGrndReactance");
1636 
1637  SwitchingData swData;
1638  auto switchingList = electricalProp->first_node("SwitchingList");
1639  if(!switchingList) return false;
1640  auto swNode = switchingList->first_node("Switching");
1641  while(swNode) {
1642  swData.swType.push_back((SwitchingType)GetNodeValueInt(swNode, "Type"));
1643  swData.swTime.push_back(GetNodeValueDouble(swNode, "Time"));
1644  swNode = swNode->next_sibling("Switching");
1645  }
1646  transformer->SetSwitchingData(swData);
1647 
1648  transformer->SetElectricaData(data);
1649 
1650  if(swData.swTime.size() != 0) transformer->SetDynamicEvent(true);
1651 
1652  elementList.push_back(transformer);
1653  transformerList.push_back(transformer);
1654  transfomerNode = transfomerNode->next_sibling("Transfomer");
1655  } //}
1656 
1657  m_workspace->SetElementList(elementList);
1658 
1659  //{ Text
1660  auto textListNode = elementsNode->first_node("TextList");
1661  if(!textListNode) return false;
1662  auto textNode = textListNode->first_node("Text");
1663  while(textNode) {
1664  auto cadPropNode = textNode->first_node("CADProperties");
1665  if(!cadPropNode) return false;
1666 
1667  auto position = cadPropNode->first_node("Position");
1668  double posX = GetNodeValueDouble(position, "X");
1669  double posY = GetNodeValueDouble(position, "Y");
1670  auto size = cadPropNode->first_node("Size");
1671  double width = GetNodeValueDouble(size, "Width");
1672  double height = GetNodeValueDouble(size, "Height");
1673  double angle = GetNodeValueDouble(cadPropNode, "Angle");
1674 
1675  Text* text = new Text(wxPoint2DDouble(posX, posY));
1676 
1677  text->SetWidth(width);
1678  text->SetHeight(height);
1679 
1680  auto textProperties = textNode->first_node("TextProperties");
1681  if(!textProperties) return false;
1682 
1683  text->SetElementType((ElementType)GetNodeValueDouble(textProperties, "ElementType"));
1684  text->SetDataType((DataType)GetNodeValueDouble(textProperties, "DataType"));
1685  text->SetUnit((ElectricalUnit)GetNodeValueDouble(textProperties, "DataUnit"));
1686  text->SetDirection(GetNodeValueDouble(textProperties, "Direction"));
1687  text->SetDecimalPlaces(GetNodeValueDouble(textProperties, "DecimalPlaces"));
1688 
1689  text->SetElementNumber(GetNodeValueInt(textProperties, "ElementNumber"));
1690  switch(text->GetElementType()) {
1691  case TYPE_NONE:
1692  break;
1693  case TYPE_BUS: {
1694  Bus* bus = busList[text->GetElementNumber()];
1695  text->SetElement(bus);
1696  } break;
1697  case TYPE_CAPACITOR: {
1698  Capacitor* capacitor = capacitorList[text->GetElementNumber()];
1699  text->SetElement(capacitor);
1700  } break;
1701  case TYPE_IND_MOTOR: {
1702  IndMotor* indMotor = indMotorList[text->GetElementNumber()];
1703  text->SetElement(indMotor);
1704  } break;
1705  case TYPE_INDUCTOR: {
1706  Inductor* inductor = inductorList[text->GetElementNumber()];
1707  text->SetElement(inductor);
1708  } break;
1709  case TYPE_LINE: {
1710  Line* line = lineList[text->GetElementNumber()];
1711  text->SetElement(line);
1712  } break;
1713  case TYPE_LOAD: {
1714  Load* load = loadList[text->GetElementNumber()];
1715  text->SetElement(load);
1716  } break;
1717  case TYPE_SYNC_GENERATOR: {
1718  SyncGenerator* syncGenerator = syncGeneratorList[text->GetElementNumber()];
1719  text->SetElement(syncGenerator);
1720  } break;
1721  case TYPE_SYNC_MOTOR: {
1722  SyncMotor* syncMotor = syncMotorList[text->GetElementNumber()];
1723  text->SetElement(syncMotor);
1724  } break;
1725  case TYPE_TRANSFORMER: {
1726  Transformer* transformer = transformerList[text->GetElementNumber()];
1727  text->SetElement(transformer);
1728  } break;
1729  }
1730 
1731  int numRot = angle / text->GetRotationAngle();
1732  bool clockwise = true;
1733  if(numRot < 0) {
1734  numRot = std::abs(numRot);
1735  clockwise = false;
1736  }
1737  for(int i = 0; i < numRot; i++) text->Rotate(clockwise);
1738 
1739  textList.push_back(text);
1740  textNode = textNode->next_sibling("Text");
1741  } //}
1742 
1743  m_workspace->SetTextList(textList);
1744  return true;
1745 }
1746 
1747 void FileHanding::SaveControl(wxFileName path)
1748 {
1749  // Same process present in SaveProject():
1750  std::ofstream writeProjectsFile(path.GetFullPath());
1751  writeProjectsFile.close();
1752 
1753  rapidxml::xml_document<> doc;
1754  rapidxml::file<> xmlFile(path.GetFullPath().mb_str());
1755  doc.parse<0>(xmlFile.data());
1756 
1757  rapidxml::xml_node<>* decl = doc.allocate_node(rapidxml::node_declaration);
1758  rapidxml::xml_attribute<>* ver = doc.allocate_attribute("version", "1.0");
1759  rapidxml::xml_attribute<>* encoding = doc.allocate_attribute("encoding", "utf-8");
1760  decl->append_attribute(ver);
1761  decl->append_attribute(encoding);
1762  doc.append_node(decl);
1763 
1764  rapidxml::xml_node<>* rootNode = doc.allocate_node(rapidxml::node_element, "Control");
1765  doc.append_node(rootNode);
1766 
1767  rapidxml::xml_node<>* projectNameNode = AppendNode(doc, rootNode, "Name");
1768  SetNodeValue(doc, projectNameNode, path.GetName());
1769 
1770  auto elementsNode = AppendNode(doc, rootNode, "ControlElements");
1771  SaveControlElements(doc, elementsNode);
1772  std::ofstream writeXML(path.GetFullPath());
1773  writeXML << doc;
1774  writeXML.close();
1775 }
1776 
1777 bool FileHanding::OpenControl(wxFileName path,
1778  std::vector<ControlElement*>& ctrlElementList,
1779  std::vector<ConnectionLine*>& ctrlConnectionList)
1780 {
1781  rapidxml::xml_document<> doc;
1782  rapidxml::file<> xmlFile(path.GetFullPath().mb_str());
1783 
1784  doc.parse<0>(xmlFile.data());
1785 
1786  auto projectNode = doc.first_node("Control");
1787  if(!projectNode) return false;
1788  // auto nameNode = projectNode->first_node("Name");
1789  // if(!nameNode) return false;
1790  // m_controlEditor->SetName(nameNode->value());
1791 
1792  // Open elements
1793  auto elementsNode = projectNode->first_node("ControlElements");
1794  if(!elementsNode) return false;
1795 
1796  // auto elementsNode = AppendNode(doc, rootNode, "ControlElements");
1797  ControlElementContainer* ctrlElementContainer = new ControlElementContainer();
1798  if(!OpenControlElements(doc, elementsNode, ctrlElementContainer)) return false;
1799  ctrlElementList = ctrlElementContainer->GetControlElementsList();
1800  ctrlConnectionList = ctrlElementContainer->GetConnectionLineList();
1801  return true;
1802 }
1803 
1804 void FileHanding::SaveControlElements(rapidxml::xml_document<>& doc,
1805  rapidxml::xml_node<>* elementsNode,
1806  ControlElementContainer* ctrlContainer)
1807 {
1808  if(!ctrlContainer) {
1809  ctrlContainer = new ControlElementContainer();
1810  ctrlContainer->FillContainer(m_controlEditor);
1811  }
1812 
1813  //{ Constant
1814  auto constsNode = AppendNode(doc, elementsNode, "ConstantList");
1815  auto constList = ctrlContainer->GetConstantList();
1816  for(auto it = constList.begin(), itEnd = constList.end(); it != itEnd; ++it) {
1817  Constant* constant = *it;
1818  auto constNode = AppendNode(doc, constsNode, "Constant");
1819  SetNodeAttribute(doc, constNode, "ID", constant->GetID());
1820  auto cadProp = AppendNode(doc, constNode, "CADProperties");
1821  auto position = AppendNode(doc, cadProp, "Position");
1822  auto posX = AppendNode(doc, position, "X");
1823  SetNodeValue(doc, posX, constant->GetPosition().m_x);
1824  auto posY = AppendNode(doc, position, "Y");
1825  SetNodeValue(doc, posY, constant->GetPosition().m_y);
1826  auto size = AppendNode(doc, cadProp, "Size");
1827  auto width = AppendNode(doc, size, "Width");
1828  SetNodeValue(doc, width, constant->GetWidth());
1829  auto height = AppendNode(doc, size, "Height");
1830  SetNodeValue(doc, height, constant->GetHeight());
1831  auto angle = AppendNode(doc, cadProp, "Angle");
1832  SetNodeValue(doc, angle, constant->GetAngle());
1833 
1834  // Nodes
1835  auto nodeList = AppendNode(doc, constNode, "NodeList");
1836  SaveControlNodes(doc, nodeList, constant->GetNodeList());
1837 
1838  // Control properties
1839  auto value = AppendNode(doc, constNode, "Value");
1840  SetNodeValue(doc, value, constant->GetValue());
1841  } //}
1842 
1843  //{ Exponential
1844  auto expsNode = AppendNode(doc, elementsNode, "ExponentialList");
1845  auto expList = ctrlContainer->GetExponentialList();
1846  for(auto it = expList.begin(), itEnd = expList.end(); it != itEnd; ++it) {
1847  Exponential* exponential = *it;
1848  auto expNode = AppendNode(doc, expsNode, "Exponential");
1849  SetNodeAttribute(doc, expNode, "ID", exponential->GetID());
1850  auto cadProp = AppendNode(doc, expNode, "CADProperties");
1851  auto position = AppendNode(doc, cadProp, "Position");
1852  auto posX = AppendNode(doc, position, "X");
1853  SetNodeValue(doc, posX, exponential->GetPosition().m_x);
1854  auto posY = AppendNode(doc, position, "Y");
1855  SetNodeValue(doc, posY, exponential->GetPosition().m_y);
1856  auto size = AppendNode(doc, cadProp, "Size");
1857  auto width = AppendNode(doc, size, "Width");
1858  SetNodeValue(doc, width, exponential->GetWidth());
1859  auto height = AppendNode(doc, size, "Height");
1860  SetNodeValue(doc, height, exponential->GetHeight());
1861  auto angle = AppendNode(doc, cadProp, "Angle");
1862  SetNodeValue(doc, angle, exponential->GetAngle());
1863 
1864  // Nodes
1865  auto nodeList = AppendNode(doc, expNode, "NodeList");
1866  SaveControlNodes(doc, nodeList, exponential->GetNodeList());
1867 
1868  // Control properties
1869  double a, b;
1870  exponential->GetValues(a, b);
1871  auto value = AppendNode(doc, expNode, "Value");
1872  auto aValue = AppendNode(doc, value, "A");
1873  SetNodeValue(doc, aValue, a);
1874  auto bValue = AppendNode(doc, value, "B");
1875  SetNodeValue(doc, bValue, b);
1876  } //}
1877 
1878  //{ Gain
1879  auto gainsNode = AppendNode(doc, elementsNode, "GainList");
1880  auto gainList = ctrlContainer->GetGainList();
1881  for(auto it = gainList.begin(), itEnd = gainList.end(); it != itEnd; ++it) {
1882  Gain* gain = *it;
1883  auto gainNode = AppendNode(doc, gainsNode, "Gain");
1884  SetNodeAttribute(doc, gainNode, "ID", gain->GetID());
1885  auto cadProp = AppendNode(doc, gainNode, "CADProperties");
1886  auto position = AppendNode(doc, cadProp, "Position");
1887  auto posX = AppendNode(doc, position, "X");
1888  SetNodeValue(doc, posX, gain->GetPosition().m_x);
1889  auto posY = AppendNode(doc, position, "Y");
1890  SetNodeValue(doc, posY, gain->GetPosition().m_y);
1891  auto size = AppendNode(doc, cadProp, "Size");
1892  auto width = AppendNode(doc, size, "Width");
1893  SetNodeValue(doc, width, gain->GetWidth());
1894  auto height = AppendNode(doc, size, "Height");
1895  SetNodeValue(doc, height, gain->GetHeight());
1896  auto angle = AppendNode(doc, cadProp, "Angle");
1897  SetNodeValue(doc, angle, gain->GetAngle());
1898 
1899  // Nodes
1900  auto nodeList = AppendNode(doc, gainNode, "NodeList");
1901  SaveControlNodes(doc, nodeList, gain->GetNodeList());
1902 
1903  // Control properties
1904  auto value = AppendNode(doc, gainNode, "Value");
1905  SetNodeValue(doc, value, gain->GetValue());
1906  } //}
1907 
1908  //{ IO
1909  auto iosNode = AppendNode(doc, elementsNode, "IOList");
1910  auto ioList = ctrlContainer->GetIOControlList();
1911  for(auto it = ioList.begin(), itEnd = ioList.end(); it != itEnd; ++it) {
1912  IOControl* io = *it;
1913  auto ioNode = AppendNode(doc, iosNode, "IO");
1914  SetNodeAttribute(doc, ioNode, "ID", io->GetID());
1915  auto cadProp = AppendNode(doc, ioNode, "CADProperties");
1916  auto position = AppendNode(doc, cadProp, "Position");
1917  auto posX = AppendNode(doc, position, "X");
1918  SetNodeValue(doc, posX, io->GetPosition().m_x);
1919  auto posY = AppendNode(doc, position, "Y");
1920  SetNodeValue(doc, posY, io->GetPosition().m_y);
1921  auto size = AppendNode(doc, cadProp, "Size");
1922  auto width = AppendNode(doc, size, "Width");
1923  SetNodeValue(doc, width, io->GetWidth());
1924  auto height = AppendNode(doc, size, "Height");
1925  SetNodeValue(doc, height, io->GetHeight());
1926  auto angle = AppendNode(doc, cadProp, "Angle");
1927  SetNodeValue(doc, angle, io->GetAngle());
1928 
1929  // Nodes
1930  auto nodeList = AppendNode(doc, ioNode, "NodeList");
1931  SaveControlNodes(doc, nodeList, io->GetNodeList());
1932 
1933  // Control properties
1934  auto value = AppendNode(doc, ioNode, "Value");
1935  SetNodeValue(doc, value, io->GetValue());
1936  auto ioFlags = AppendNode(doc, ioNode, "IOFlags");
1937  SetNodeValue(doc, ioFlags, io->GetIOFlags());
1938  } //}
1939 
1940  //{ Limiter
1941  auto limitersNode = AppendNode(doc, elementsNode, "LimiterList");
1942  auto limiterList = ctrlContainer->GetLimiterList();
1943  for(auto it = limiterList.begin(), itEnd = limiterList.end(); it != itEnd; ++it) {
1944  Limiter* limiter = *it;
1945  auto limiterNode = AppendNode(doc, limitersNode, "Limiter");
1946  SetNodeAttribute(doc, limiterNode, "ID", limiter->GetID());
1947  auto cadProp = AppendNode(doc, limiterNode, "CADProperties");
1948  auto position = AppendNode(doc, cadProp, "Position");
1949  auto posX = AppendNode(doc, position, "X");
1950  SetNodeValue(doc, posX, limiter->GetPosition().m_x);
1951  auto posY = AppendNode(doc, position, "Y");
1952  SetNodeValue(doc, posY, limiter->GetPosition().m_y);
1953  auto size = AppendNode(doc, cadProp, "Size");
1954  auto width = AppendNode(doc, size, "Width");
1955  SetNodeValue(doc, width, limiter->GetWidth());
1956  auto height = AppendNode(doc, size, "Height");
1957  SetNodeValue(doc, height, limiter->GetHeight());
1958  auto angle = AppendNode(doc, cadProp, "Angle");
1959  SetNodeValue(doc, angle, limiter->GetAngle());
1960 
1961  // Nodes
1962  auto nodeList = AppendNode(doc, limiterNode, "NodeList");
1963  SaveControlNodes(doc, nodeList, limiter->GetNodeList());
1964 
1965  // Control properties
1966  auto upLimit = AppendNode(doc, limiterNode, "UpperLimit");
1967  SetNodeValue(doc, upLimit, limiter->GetUpLimit());
1968  auto lowLimit = AppendNode(doc, limiterNode, "LowerLimit");
1969  SetNodeValue(doc, lowLimit, limiter->GetLowLimit());
1970  } //}
1971 
1972  //{ Multiplier
1973  auto multipliersNode = AppendNode(doc, elementsNode, "MultiplierList");
1974  auto multiplierList = ctrlContainer->GetMultiplierList();
1975  for(auto it = multiplierList.begin(), itEnd = multiplierList.end(); it != itEnd; ++it) {
1976  Multiplier* multiplier = *it;
1977  auto multiplierNode = AppendNode(doc, multipliersNode, "Multiplier");
1978  SetNodeAttribute(doc, multiplierNode, "ID", multiplier->GetID());
1979  auto cadProp = AppendNode(doc, multiplierNode, "CADProperties");
1980  auto position = AppendNode(doc, cadProp, "Position");
1981  auto posX = AppendNode(doc, position, "X");
1982  SetNodeValue(doc, posX, multiplier->GetPosition().m_x);
1983  auto posY = AppendNode(doc, position, "Y");
1984  SetNodeValue(doc, posY, multiplier->GetPosition().m_y);
1985  auto size = AppendNode(doc, cadProp, "Size");
1986  auto width = AppendNode(doc, size, "Width");
1987  SetNodeValue(doc, width, multiplier->GetWidth());
1988  auto height = AppendNode(doc, size, "Height");
1989  SetNodeValue(doc, height, multiplier->GetHeight());
1990  auto angle = AppendNode(doc, cadProp, "Angle");
1991  SetNodeValue(doc, angle, multiplier->GetAngle());
1992 
1993  // Nodes
1994  auto nodeList = AppendNode(doc, multiplierNode, "NodeList");
1995  SaveControlNodes(doc, nodeList, multiplier->GetNodeList());
1996  } //}
1997 
1998  //{ Rate limiter
1999  auto rateLimitersNode = AppendNode(doc, elementsNode, "RateLimiterList");
2000  auto rateLimiterList = ctrlContainer->GetRateLimiterList();
2001  for(auto it = rateLimiterList.begin(), itEnd = rateLimiterList.end(); it != itEnd; ++it) {
2002  RateLimiter* rateLimiter = *it;
2003  auto rateLimiterNode = AppendNode(doc, rateLimitersNode, "RateLimiter");
2004  SetNodeAttribute(doc, rateLimiterNode, "ID", rateLimiter->GetID());
2005  auto cadProp = AppendNode(doc, rateLimiterNode, "CADProperties");
2006  auto position = AppendNode(doc, cadProp, "Position");
2007  auto posX = AppendNode(doc, position, "X");
2008  SetNodeValue(doc, posX, rateLimiter->GetPosition().m_x);
2009  auto posY = AppendNode(doc, position, "Y");
2010  SetNodeValue(doc, posY, rateLimiter->GetPosition().m_y);
2011  auto size = AppendNode(doc, cadProp, "Size");
2012  auto width = AppendNode(doc, size, "Width");
2013  SetNodeValue(doc, width, rateLimiter->GetWidth());
2014  auto height = AppendNode(doc, size, "Height");
2015  SetNodeValue(doc, height, rateLimiter->GetHeight());
2016  auto angle = AppendNode(doc, cadProp, "Angle");
2017  SetNodeValue(doc, angle, rateLimiter->GetAngle());
2018 
2019  // Nodes
2020  auto nodeList = AppendNode(doc, rateLimiterNode, "NodeList");
2021  SaveControlNodes(doc, nodeList, rateLimiter->GetNodeList());
2022 
2023  // Control properties
2024  auto upLimit = AppendNode(doc, rateLimiterNode, "UpperLimit");
2025  SetNodeValue(doc, upLimit, rateLimiter->GetUpLimit());
2026  auto lowLimit = AppendNode(doc, rateLimiterNode, "LowerLimit");
2027  SetNodeValue(doc, lowLimit, rateLimiter->GetLowLimit());
2028  } //}
2029 
2030  //{ Sum
2031  auto sumsNode = AppendNode(doc, elementsNode, "SumList");
2032  auto sumList = ctrlContainer->GetSumList();
2033  for(auto it = sumList.begin(), itEnd = sumList.end(); it != itEnd; ++it) {
2034  Sum* sum = *it;
2035  auto sumNode = AppendNode(doc, sumsNode, "Sum");
2036  SetNodeAttribute(doc, sumNode, "ID", sum->GetID());
2037  auto cadProp = AppendNode(doc, sumNode, "CADProperties");
2038  auto position = AppendNode(doc, cadProp, "Position");
2039  auto posX = AppendNode(doc, position, "X");
2040  SetNodeValue(doc, posX, sum->GetPosition().m_x);
2041  auto posY = AppendNode(doc, position, "Y");
2042  SetNodeValue(doc, posY, sum->GetPosition().m_y);
2043  auto size = AppendNode(doc, cadProp, "Size");
2044  auto width = AppendNode(doc, size, "Width");
2045  SetNodeValue(doc, width, sum->GetWidth());
2046  auto height = AppendNode(doc, size, "Height");
2047  SetNodeValue(doc, height, sum->GetHeight());
2048  auto angle = AppendNode(doc, cadProp, "Angle");
2049  SetNodeValue(doc, angle, sum->GetAngle());
2050 
2051  // Nodes
2052  auto nodeList = AppendNode(doc, sumNode, "NodeList");
2053  SaveControlNodes(doc, nodeList, sum->GetNodeList());
2054 
2055  // Control properties
2056  auto signsNode = AppendNode(doc, sumNode, "Signs");
2057  auto signs = sum->GetSignalList();
2058  for(int i = 0; i < (int)signs.size(); ++i) {
2059  auto value = AppendNode(doc, signsNode, "Value");
2060  SetNodeValue(doc, value, static_cast<int>(signs[i]));
2061  }
2062 
2063  } //}
2064 
2065  //{ Transfer function
2066  auto tfsNode = AppendNode(doc, elementsNode, "TransferFunctionList");
2067  auto tfList = ctrlContainer->GetTFList();
2068  for(auto it = tfList.begin(), itEnd = tfList.end(); it != itEnd; ++it) {
2069  TransferFunction* tf = *it;
2070  auto tfNode = AppendNode(doc, tfsNode, "TransferFunction");
2071  SetNodeAttribute(doc, tfNode, "ID", tf->GetID());
2072  auto cadProp = AppendNode(doc, tfNode, "CADProperties");
2073  auto position = AppendNode(doc, cadProp, "Position");
2074  auto posX = AppendNode(doc, position, "X");
2075  SetNodeValue(doc, posX, tf->GetPosition().m_x);
2076  auto posY = AppendNode(doc, position, "Y");
2077  SetNodeValue(doc, posY, tf->GetPosition().m_y);
2078  auto size = AppendNode(doc, cadProp, "Size");
2079  auto width = AppendNode(doc, size, "Width");
2080  SetNodeValue(doc, width, tf->GetWidth());
2081  auto height = AppendNode(doc, size, "Height");
2082  SetNodeValue(doc, height, tf->GetHeight());
2083  auto angle = AppendNode(doc, cadProp, "Angle");
2084  SetNodeValue(doc, angle, tf->GetAngle());
2085 
2086  // Nodes
2087  auto nodeList = AppendNode(doc, tfNode, "NodeList");
2088  SaveControlNodes(doc, nodeList, tf->GetNodeList());
2089 
2090  // Control properties
2091  auto numeratorNode = AppendNode(doc, tfNode, "Numerator");
2092  auto numerator = tf->GetNumerator();
2093  for(int i = 0; i < (int)numerator.size(); ++i) {
2094  auto value = AppendNode(doc, numeratorNode, "Value");
2095  SetNodeValue(doc, value, numerator[i]);
2096  }
2097  auto denominatorNode = AppendNode(doc, tfNode, "Denominator");
2098  auto denominator = tf->GetDenominator();
2099  for(int i = 0; i < (int)denominator.size(); ++i) {
2100  auto value = AppendNode(doc, denominatorNode, "Value");
2101  SetNodeValue(doc, value, denominator[i]);
2102  }
2103  } //}
2104 
2105  //{ Connection line
2106  auto cLinesNode = AppendNode(doc, elementsNode, "ConnectionList");
2107  auto connLineList = ctrlContainer->GetConnectionLineList();
2108  for(auto it = connLineList.begin(), itEnd = connLineList.end(); it != itEnd; ++it) {
2109  ConnectionLine* cLine = *it;
2110  auto cLineNode = AppendNode(doc, cLinesNode, "Connection");
2111  SetNodeAttribute(doc, cLineNode, "ID", cLine->GetID());
2112 
2113  // CAD properties
2114  auto cadProp = AppendNode(doc, cLineNode, "CADProperties");
2115  auto offset = AppendNode(doc, cadProp, "Offset");
2116  SetNodeValue(doc, offset, cLine->GetOffset());
2117 
2118  // Parent list
2119  auto parentsNode = AppendNode(doc, cLineNode, "ParentList");
2120  auto parentList = cLine->GetParentList();
2121  int nodeIndex = 0;
2122  for(auto itP = parentList.begin(), itPEnd = parentList.end(); itP != itPEnd; ++itP) {
2123  Element* parent = *itP;
2124  auto parentNode = AppendNode(doc, parentsNode, "Parent");
2125  auto elementID = AppendNode(doc, parentNode, "ElementID");
2126  SetNodeValue(doc, elementID, parent->GetID());
2127  auto nodeID = AppendNode(doc, parentNode, "NodeID");
2128  SetNodeValue(doc, nodeID, cLine->GetNodeList()[nodeIndex]->GetID());
2129  nodeIndex++;
2130  }
2131 
2132  auto parentLine = AppendNode(doc, cLineNode, "ParentLine");
2133  if(cLine->GetParentLine()) {
2134  ConnectionLine* parent = cLine->GetParentLine();
2135  SetNodeAttribute(doc, parentLine, "ID", parent->GetID());
2136  } else {
2137  SetNodeAttribute(doc, parentLine, "ID", -1);
2138  }
2139  } //}
2140 }
2141 
2142 bool FileHanding::OpenControlElements(rapidxml::xml_document<>& doc,
2143  rapidxml::xml_node<>* elementsNode,
2144  ControlElementContainer* ctrlContainer)
2145 {
2146  std::vector<ControlElement*> elementList;
2147  std::vector<ConnectionLine*> connectionList;
2148 
2149  //{ Constant
2150  auto constListNode = elementsNode->first_node("ConstantList");
2151  if(!constListNode) return false;
2152  auto constNode = constListNode->first_node("Constant");
2153  while(constNode) {
2154  int id = GetAttributeValueInt(constNode, "ID");
2155  Constant* constant = new Constant(id);
2156 
2157  auto cadPropNode = constNode->first_node("CADProperties");
2158  if(!cadPropNode) return false;
2159 
2160  auto position = cadPropNode->first_node("Position");
2161  double posX = GetNodeValueDouble(position, "X");
2162  double posY = GetNodeValueDouble(position, "Y");
2163  auto size = cadPropNode->first_node("Size");
2164  double width = GetNodeValueDouble(size, "Width");
2165  double height = GetNodeValueDouble(size, "Height");
2166  double angle = GetNodeValueDouble(cadPropNode, "Angle");
2167 
2168  double value = GetNodeValueDouble(constNode, "Value");
2169 
2170  constant->SetWidth(width);
2171  constant->SetHeight(height);
2172  constant->SetAngle(angle);
2173  constant->SetPosition(wxPoint2DDouble(posX, posY));
2174  constant->StartMove(constant->GetPosition());
2175 
2176  constant->SetValue(value);
2177 
2178  std::vector<Node*> nodeVector;
2179  if(!OpenControlNodeList(constNode, nodeVector)) return false;
2180 
2181  constant->SetNodeList(nodeVector);
2182  constant->UpdatePoints();
2183  elementList.push_back(constant);
2184 
2185  constNode = constNode->next_sibling("Constant");
2186  } //}
2187 
2188  //{ Exponential
2189  auto expListNode = elementsNode->first_node("ExponentialList");
2190  if(!expListNode) return false;
2191  auto expNode = expListNode->first_node("Exponential");
2192  while(expNode) {
2193  int id = GetAttributeValueInt(expNode, "ID");
2194  Exponential* exponential = new Exponential(id);
2195 
2196  auto cadPropNode = expNode->first_node("CADProperties");
2197  if(!cadPropNode) return false;
2198 
2199  auto position = cadPropNode->first_node("Position");
2200  double posX = GetNodeValueDouble(position, "X");
2201  double posY = GetNodeValueDouble(position, "Y");
2202  auto size = cadPropNode->first_node("Size");
2203  double width = GetNodeValueDouble(size, "Width");
2204  double height = GetNodeValueDouble(size, "Height");
2205  double angle = GetNodeValueDouble(cadPropNode, "Angle");
2206 
2207  auto value = expNode->first_node("Value");
2208  double a = GetNodeValueDouble(value, "A");
2209  double b = GetNodeValueDouble(value, "B");
2210 
2211  exponential->SetWidth(width);
2212  exponential->SetHeight(height);
2213  exponential->SetAngle(angle);
2214  exponential->SetPosition(wxPoint2DDouble(posX, posY));
2215  exponential->StartMove(exponential->GetPosition());
2216 
2217  exponential->SetValues(a, b);
2218 
2219  std::vector<Node*> nodeVector;
2220  if(!OpenControlNodeList(expNode, nodeVector)) return false;
2221 
2222  exponential->SetNodeList(nodeVector);
2223  exponential->UpdatePoints();
2224  elementList.push_back(exponential);
2225 
2226  expNode = expNode->next_sibling("Exponential");
2227  } //}
2228 
2229  //{ Gain
2230  auto gainListNode = elementsNode->first_node("GainList");
2231  if(!gainListNode) return false;
2232  auto gainNode = gainListNode->first_node("Gain");
2233  while(gainNode) {
2234  int id = GetAttributeValueInt(gainNode, "ID");
2235  Gain* gain = new Gain(id);
2236 
2237  auto cadPropNode = gainNode->first_node("CADProperties");
2238  if(!cadPropNode) return false;
2239 
2240  auto position = cadPropNode->first_node("Position");
2241  double posX = GetNodeValueDouble(position, "X");
2242  double posY = GetNodeValueDouble(position, "Y");
2243  auto size = cadPropNode->first_node("Size");
2244  double width = GetNodeValueDouble(size, "Width");
2245  double height = GetNodeValueDouble(size, "Height");
2246  double angle = GetNodeValueDouble(cadPropNode, "Angle");
2247 
2248  double value = GetNodeValueDouble(gainNode, "Value");
2249 
2250  gain->SetWidth(width);
2251  gain->SetHeight(height);
2252  gain->SetAngle(angle);
2253  gain->SetPosition(wxPoint2DDouble(posX, posY));
2254  gain->SetValue(value);
2255  gain->StartMove(gain->GetPosition());
2256 
2257  std::vector<Node*> nodeVector;
2258  if(!OpenControlNodeList(gainNode, nodeVector)) return false;
2259 
2260  gain->SetNodeList(nodeVector);
2261  gain->UpdatePoints();
2262  elementList.push_back(gain);
2263 
2264  gainNode = gainNode->next_sibling("Gain");
2265  }
2266  //}
2267 
2268  //{ IO
2269  auto ioListNode = elementsNode->first_node("IOList");
2270  if(!ioListNode) return false;
2271  auto ioNode = ioListNode->first_node("IO");
2272  while(ioNode) {
2273  int id = GetAttributeValueInt(ioNode, "ID");
2274 
2275  auto cadPropNode = ioNode->first_node("CADProperties");
2276  if(!cadPropNode) return false;
2277 
2278  auto position = cadPropNode->first_node("Position");
2279  double posX = GetNodeValueDouble(position, "X");
2280  double posY = GetNodeValueDouble(position, "Y");
2281  auto size = cadPropNode->first_node("Size");
2282  double width = GetNodeValueDouble(size, "Width");
2283  double height = GetNodeValueDouble(size, "Height");
2284  double angle = GetNodeValueDouble(cadPropNode, "Angle");
2285 
2286  std::vector<Node*> nodeVector;
2287  if(!OpenControlNodeList(ioNode, nodeVector)) return false;
2288 
2289  IOControl::IOFlags value = static_cast<IOControl::IOFlags>(GetNodeValueInt(ioNode, "Value"));
2290  int ioFlags = GetNodeValueInt(ioNode, "IOFlags");
2291 
2292  IOControl* io = new IOControl(ioFlags, id);
2293 
2294  io->SetWidth(width);
2295  io->SetHeight(height);
2296  io->SetAngle(angle);
2297  io->SetPosition(wxPoint2DDouble(posX, posY));
2298  io->SetValue(value);
2299  io->StartMove(io->GetPosition());
2300  io->SetNodeList(nodeVector);
2301  io->UpdatePoints();
2302  elementList.push_back(io);
2303 
2304  ioNode = ioNode->next_sibling("IO");
2305  }
2306  //}
2307 
2308  //{ Limiter
2309  auto limiterListNode = elementsNode->first_node("LimiterList");
2310  if(!limiterListNode) return false;
2311  auto limiterNode = limiterListNode->first_node("Limiter");
2312  while(limiterNode) {
2313  int id = GetAttributeValueInt(limiterNode, "ID");
2314  Limiter* limiter = new Limiter(id);
2315 
2316  auto cadPropNode = limiterNode->first_node("CADProperties");
2317  if(!cadPropNode) return false;
2318 
2319  auto position = cadPropNode->first_node("Position");
2320  double posX = GetNodeValueDouble(position, "X");
2321  double posY = GetNodeValueDouble(position, "Y");
2322  auto size = cadPropNode->first_node("Size");
2323  double width = GetNodeValueDouble(size, "Width");
2324  double height = GetNodeValueDouble(size, "Height");
2325  double angle = GetNodeValueDouble(cadPropNode, "Angle");
2326 
2327  double upLimit = GetNodeValueDouble(limiterNode, "UpperLimit");
2328  double lowLimit = GetNodeValueDouble(limiterNode, "LowerLimit");
2329 
2330  std::vector<Node*> nodeVector;
2331  if(!OpenControlNodeList(limiterNode, nodeVector)) return false;
2332 
2333  limiter->SetWidth(width);
2334  limiter->SetHeight(height);
2335  limiter->SetAngle(angle);
2336  limiter->SetPosition(wxPoint2DDouble(posX, posY));
2337  limiter->SetUpLimit(upLimit);
2338  limiter->SetLowLimit(lowLimit);
2339 
2340  limiter->StartMove(limiter->GetPosition());
2341  limiter->SetNodeList(nodeVector);
2342  limiter->UpdatePoints();
2343  elementList.push_back(limiter);
2344 
2345  limiterNode = limiterNode->next_sibling("Limiter");
2346  }
2347  //}
2348 
2349  //{ Multiplier
2350  auto multiplierListNode = elementsNode->first_node("MultiplierList");
2351  if(!multiplierListNode) return false;
2352  auto multiplierNode = multiplierListNode->first_node("Multiplier");
2353  while(multiplierNode) {
2354  int id = GetAttributeValueInt(multiplierNode, "ID");
2355  Multiplier* multiplier = new Multiplier(id);
2356 
2357  auto cadPropNode = multiplierNode->first_node("CADProperties");
2358  if(!cadPropNode) return false;
2359 
2360  auto position = cadPropNode->first_node("Position");
2361  double posX = GetNodeValueDouble(position, "X");
2362  double posY = GetNodeValueDouble(position, "Y");
2363  auto size = cadPropNode->first_node("Size");
2364  double width = GetNodeValueDouble(size, "Width");
2365  double height = GetNodeValueDouble(size, "Height");
2366  double angle = GetNodeValueDouble(cadPropNode, "Angle");
2367 
2368  std::vector<Node*> nodeVector;
2369  if(!OpenControlNodeList(multiplierNode, nodeVector)) return false;
2370 
2371  multiplier->SetWidth(width);
2372  multiplier->SetHeight(height);
2373  multiplier->SetAngle(angle);
2374  multiplier->SetPosition(wxPoint2DDouble(posX, posY));
2375 
2376  multiplier->StartMove(multiplier->GetPosition());
2377  multiplier->SetNodeList(nodeVector);
2378  multiplier->UpdatePoints();
2379  elementList.push_back(multiplier);
2380 
2381  multiplierNode = multiplierNode->next_sibling("Multiplier");
2382  }
2383  //}
2384 
2385  //{ Rate limiter
2386  auto rateLimiterListNode = elementsNode->first_node("RateLimiterList");
2387  if(!rateLimiterListNode) return false;
2388  auto rateLimiterNode = rateLimiterListNode->first_node("RateLimiter");
2389  while(rateLimiterNode) {
2390  int id = GetAttributeValueInt(rateLimiterNode, "ID");
2391  RateLimiter* limiter = new RateLimiter(id);
2392 
2393  auto cadPropNode = rateLimiterNode->first_node("CADProperties");
2394  if(!cadPropNode) return false;
2395 
2396  auto position = cadPropNode->first_node("Position");
2397  double posX = GetNodeValueDouble(position, "X");
2398  double posY = GetNodeValueDouble(position, "Y");
2399  auto size = cadPropNode->first_node("Size");
2400  double width = GetNodeValueDouble(size, "Width");
2401  double height = GetNodeValueDouble(size, "Height");
2402  double angle = GetNodeValueDouble(cadPropNode, "Angle");
2403 
2404  double upLimit = GetNodeValueDouble(rateLimiterNode, "UpperLimit");
2405  double lowLimit = GetNodeValueDouble(rateLimiterNode, "LowerLimit");
2406 
2407  std::vector<Node*> nodeVector;
2408  if(!OpenControlNodeList(rateLimiterNode, nodeVector)) return false;
2409 
2410  limiter->SetWidth(width);
2411  limiter->SetHeight(height);
2412  limiter->SetAngle(angle);
2413  limiter->SetPosition(wxPoint2DDouble(posX, posY));
2414  limiter->SetUpLimit(upLimit);
2415  limiter->SetLowLimit(lowLimit);
2416 
2417  limiter->StartMove(limiter->GetPosition());
2418  limiter->SetNodeList(nodeVector);
2419  limiter->UpdatePoints();
2420  elementList.push_back(limiter);
2421 
2422  rateLimiterNode = rateLimiterNode->next_sibling("RateLimiter");
2423  }
2424  //}
2425 
2426  //{ Sum
2427  auto sumListNode = elementsNode->first_node("SumList");
2428  if(!sumListNode) return false;
2429  auto sumNode = sumListNode->first_node("Sum");
2430  while(sumNode) {
2431  int id = GetAttributeValueInt(sumNode, "ID");
2432  Sum* sum = new Sum(id);
2433 
2434  auto cadPropNode = sumNode->first_node("CADProperties");
2435  if(!cadPropNode) return false;
2436 
2437  auto position = cadPropNode->first_node("Position");
2438  double posX = GetNodeValueDouble(position, "X");
2439  double posY = GetNodeValueDouble(position, "Y");
2440  auto size = cadPropNode->first_node("Size");
2441  double width = GetNodeValueDouble(size, "Width");
2442  double height = GetNodeValueDouble(size, "Height");
2443  double angle = GetNodeValueDouble(cadPropNode, "Angle");
2444 
2445  std::vector<Sum::Signal> signs;
2446  auto signsNode = sumNode->first_node("Signs");
2447  auto sign = signsNode->first_node("Value");
2448  while(sign) {
2449  long value;
2450  wxString(sign->value()).ToCLong(&value);
2451  signs.push_back(static_cast<Sum::Signal>(value));
2452  sign = sign->next_sibling("Value");
2453  }
2454  sum->SetSignalList(signs);
2455 
2456  std::vector<Node*> nodeVector;
2457  if(!OpenControlNodeList(sumNode, nodeVector)) return false;
2458 
2459  sum->SetWidth(width);
2460  sum->SetHeight(height);
2461  sum->SetAngle(angle);
2462  sum->SetPosition(wxPoint2DDouble(posX, posY));
2463 
2464  sum->StartMove(sum->GetPosition());
2465  sum->SetNodeList(nodeVector);
2466  sum->UpdatePoints();
2467  elementList.push_back(sum);
2468 
2469  sumNode = sumNode->next_sibling("Sum");
2470  }
2471  //}
2472 
2473  //{ Transfer function
2474  auto tfListNode = elementsNode->first_node("TransferFunctionList");
2475  if(!tfListNode) return false;
2476  auto tfNode = tfListNode->first_node("TransferFunction");
2477  while(tfNode) {
2478  int id = GetAttributeValueInt(tfNode, "ID");
2479  TransferFunction* tf = new TransferFunction(id);
2480 
2481  auto cadPropNode = tfNode->first_node("CADProperties");
2482  if(!cadPropNode) return false;
2483 
2484  auto position = cadPropNode->first_node("Position");
2485  double posX = GetNodeValueDouble(position, "X");
2486  double posY = GetNodeValueDouble(position, "Y");
2487  auto size = cadPropNode->first_node("Size");
2488  double width = GetNodeValueDouble(size, "Width");
2489  double height = GetNodeValueDouble(size, "Height");
2490  double angle = GetNodeValueDouble(cadPropNode, "Angle");
2491 
2492  std::vector<double> numerator, denominator;
2493  auto numeratorNode = tfNode->first_node("Numerator");
2494  auto nValue = numeratorNode->first_node("Value");
2495  while(nValue) {
2496  double value = 0.0;
2497  wxString(nValue->value()).ToCDouble(&value);
2498  numerator.push_back(value);
2499  nValue = nValue->next_sibling("Value");
2500  }
2501  auto denominatorNode = tfNode->first_node("Denominator");
2502  auto dValue = denominatorNode->first_node("Value");
2503  while(dValue) {
2504  double value = 0.0;
2505  wxString(dValue->value()).ToCDouble(&value);
2506  denominator.push_back(value);
2507  dValue = dValue->next_sibling("Value");
2508  }
2509 
2510  std::vector<Node*> nodeVector;
2511  if(!OpenControlNodeList(tfNode, nodeVector)) return false;
2512 
2513  tf->SetWidth(width);
2514  tf->SetHeight(height);
2515  tf->SetAngle(angle);
2516  tf->SetPosition(wxPoint2DDouble(posX, posY));
2517 
2518  tf->SetNumerator(numerator);
2519  tf->SetDenominator(denominator);
2520 
2521  tf->StartMove(tf->GetPosition());
2522  tf->SetNodeList(nodeVector);
2523 
2524  tf->UpdateTFText();
2525 
2526  elementList.push_back(tf);
2527 
2528  tfNode = tfNode->next_sibling("TransferFunction");
2529  }
2530  //}
2531 
2532  // Connection line
2533  auto connectionListNode = elementsNode->first_node("ConnectionList");
2534  if(!connectionListNode) return false;
2535  auto connNode = connectionListNode->first_node("Connection");
2536  while(connNode) {
2537  ConnectionLine* cLine = NULL;
2538  int id = GetAttributeValueInt(connNode, "ID");
2539 
2540  auto cadPropNode = connNode->first_node("CADProperties");
2541  if(!cadPropNode) return false;
2542  double offset = GetNodeValueDouble(cadPropNode, "Offset");
2543 
2544  auto parentList = connNode->first_node("ParentList");
2545  if(!parentList) return false;
2546 
2547  auto parentNode = parentList->first_node("Parent");
2548  bool firstNode = true;
2549  while(parentNode) {
2550  int elementID = GetNodeValueInt(parentNode, "ElementID");
2551  int nodeID = GetNodeValueInt(parentNode, "NodeID");
2552 
2553  ControlElement* element = GetControlElementFromID(elementList, elementID);
2554  Node* node = element->GetNodeList()[nodeID];
2555 
2556  if(firstNode) cLine = new ConnectionLine(node, id);
2557  cLine->AddParent(element);
2558  element->AddChild(cLine);
2559  if(!firstNode) cLine->AppendNode(node, element);
2560 
2561  if(firstNode) firstNode = false;
2562  parentNode = parentNode->next_sibling("Parent");
2563  }
2564 
2565  auto parentLine = connNode->first_node("ParentLine");
2566  if(!parentLine) return false;
2567  int parentLineID = GetAttributeValueInt(parentLine, "ID");
2568  if(parentLineID != -1) {
2569  for(auto it = connectionList.begin(), itEnd = connectionList.end(); it != itEnd; ++it) {
2570  ConnectionLine* parent = *it;
2571  if(parent->GetID() == parentLineID) {
2572  cLine->SetParentLine(parent);
2573  parent->AddChild(cLine);
2574  }
2575  }
2576  }
2577 
2578  cLine->SetOffset(offset);
2579  cLine->UpdatePoints();
2580  connectionList.push_back(cLine);
2581  connNode = connNode->next_sibling("Connection");
2582  }
2583  ctrlContainer->FillContainer(elementList, connectionList);
2584  return true;
2585 }
2586 
2587 void FileHanding::SaveControlNodes(rapidxml::xml_document<>& doc,
2588  rapidxml::xml_node<>* nodesN,
2589  std::vector<Node*> nodeList)
2590 {
2591  int id = 0;
2592  for(auto it = nodeList.begin(), itEnd = nodeList.end(); it != itEnd; ++it) {
2593  Node* node = *it;
2594  node->SetID(id);
2595  auto nodeN = AppendNode(doc, nodesN, "Node");
2596  SetNodeAttribute(doc, nodeN, "ID", id);
2597  auto nodePosition = AppendNode(doc, nodeN, "Position");
2598  auto posNodeX = AppendNode(doc, nodePosition, "X");
2599  SetNodeValue(doc, posNodeX, node->GetPosition().m_x);
2600  auto posNodeY = AppendNode(doc, nodePosition, "Y");
2601  SetNodeValue(doc, posNodeY, node->GetPosition().m_y);
2602  auto angle = AppendNode(doc, nodeN, "Angle");
2603  SetNodeValue(doc, angle, node->GetAngle());
2604  auto nodeType = AppendNode(doc, nodeN, "Type");
2605  SetNodeValue(doc, nodeType, node->GetNodeType());
2606  id++;
2607  }
2608 }
2609 
2610 ControlElement* FileHanding::GetControlElementFromID(std::vector<ControlElement*> elementList, int id)
2611 {
2612  for(auto it = elementList.begin(), itEnd = elementList.end(); it != itEnd; ++it) {
2613  ControlElement* element = *it;
2614  if(element->GetID() == id) return element;
2615  }
2616  return NULL;
2617 }
2618 
2619 bool FileHanding::OpenControlNodeList(rapidxml::xml_node<>* elementNode, std::vector<Node*>& nodeVector)
2620 {
2621  auto nodeList = elementNode->first_node("NodeList");
2622  if(!nodeList) return false;
2623  auto nodeN = nodeList->first_node("Node");
2624  while(nodeN) {
2625  auto nodePosition = nodeN->first_node("Position");
2626  double nodePosX = GetNodeValueDouble(nodePosition, "X");
2627  double nodePosY = GetNodeValueDouble(nodePosition, "Y");
2628  double nodeAngle = GetNodeValueDouble(nodeN, "Angle");
2629  Node::NodeType nodeType = (Node::NodeType)GetNodeValueInt(nodeN, "Type");
2630  Node* node = new Node(wxPoint2DDouble(nodePosX, nodePosY), nodeType, 2.0);
2631  node->SetAngle(nodeAngle);
2632  nodeVector.push_back(node);
2633  nodeN = nodeN->next_sibling("Node");
2634  }
2635  return true;
2636 }
2637 
2638 rapidxml::xml_node<>* FileHanding::AppendNode(rapidxml::xml_document<>& doc,
2639  rapidxml::xml_node<>* parentNode,
2640  const char* name,
2641  rapidxml::node_type nodeType)
2642 {
2643  rapidxml::xml_node<>* node = doc.allocate_node(nodeType, name);
2644  parentNode->append_node(node);
2645  return node;
2646 }
2647 
2648 void FileHanding::SetNodeValue(rapidxml::xml_document<>& doc, rapidxml::xml_node<>* node, wxString value)
2649 {
2650  node->value(doc.allocate_string(value.mb_str()));
2651 }
2652 
2653 void FileHanding::SetNodeValue(rapidxml::xml_document<>& doc, rapidxml::xml_node<>* node, int value)
2654 {
2655  node->value(doc.allocate_string(wxString::Format("%d", value).mb_str()));
2656 }
2657 
2658 void FileHanding::SetNodeValue(rapidxml::xml_document<>& doc, rapidxml::xml_node<>* node, double value)
2659 {
2660  node->value(doc.allocate_string(wxString::FromCDouble(value, 13).mb_str()));
2661 }
2662 
2663 void FileHanding::SetNodeAttribute(rapidxml::xml_document<>& doc,
2664  rapidxml::xml_node<>* node,
2665  const char* atrName,
2666  wxString value)
2667 {
2668  node->append_attribute(doc.allocate_attribute(atrName, doc.allocate_string(value.mb_str())));
2669 }
2670 
2671 void FileHanding::SetNodeAttribute(rapidxml::xml_document<>& doc,
2672  rapidxml::xml_node<>* node,
2673  const char* atrName,
2674  int value)
2675 {
2676  node->append_attribute(
2677  doc.allocate_attribute(atrName, doc.allocate_string(wxString::Format("%d", value).mb_str())));
2678 }
2679 
2680 void FileHanding::SetNodeAttribute(rapidxml::xml_document<>& doc,
2681  rapidxml::xml_node<>* node,
2682  const char* atrName,
2683  double value)
2684 {
2685  node->append_attribute(
2686  doc.allocate_attribute(atrName, doc.allocate_string(wxString::FromCDouble(value, 13).mb_str())));
2687 }
2688 
2689 double FileHanding::GetNodeValueDouble(rapidxml::xml_node<>* parent, const char* nodeName)
2690 {
2691  double dValue = 0.0;
2692  if(parent) {
2693  auto node = parent->first_node(nodeName);
2694  if(node) wxString(node->value()).ToCDouble(&dValue);
2695  }
2696  return dValue;
2697 }
2698 
2699 int FileHanding::GetNodeValueInt(rapidxml::xml_node<>* parent, const char* nodeName)
2700 {
2701  long iValue = -1;
2702  if(parent) {
2703  auto node = parent->first_node(nodeName);
2704  if(node) wxString(node->value()).ToCLong(&iValue);
2705  }
2706  return (int)iValue;
2707 }
2708 
2709 int FileHanding::GetAttributeValueInt(rapidxml::xml_node<>* parent, const char* nodeName, const char* atrName)
2710 {
2711  long iValue = -1;
2712  if(parent) {
2713  auto node = parent->first_node(nodeName);
2714  if(node) {
2715  auto atr = node->first_attribute(atrName);
2716  if(atr) wxString(atr->value()).ToCLong(&iValue);
2717  }
2718  }
2719  return (int)iValue;
2720 }
2721 
2722 int FileHanding::GetAttributeValueInt(rapidxml::xml_node<>* node, const char* atrName)
2723 {
2724  long intValue;
2725  auto atr = node->first_attribute(atrName);
2726  if(!atr) return false;
2727  wxString(atr->value()).ToCLong(&intValue);
2728  return (int)intValue;
2729 }
double GetAngle() const
Get the element angle.
Definition: Element.h:212
-
Element that shows power element informations in workspace.
Definition: Text.h:72
+
1 /*
2  * Copyright (C) 2017 Thales Lima Oliveira <thales@ufu.br>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program. If not, see <https://www.gnu.org/licenses/>.
16  */
17 
18 #include "FileHanding.h"
19 
20 FileHanding::~FileHanding() {}
21 FileHanding::FileHanding(Workspace* workspace) { m_workspace = workspace; }
22 FileHanding::FileHanding(ControlEditor* controlEditor) { m_controlEditor = controlEditor; }
23 FileHanding::FileHanding() {}
24 void FileHanding::SaveProject(wxFileName path)
25 {
26  // Erase the file (if exists or not) and write the initial data
27  std::ofstream writeProjectsFile(path.GetFullPath());
28  writeProjectsFile.close();
29 
30  rapidxml::xml_document<> doc;
31  rapidxml::file<> xmlFile(path.GetFullPath().mb_str());
32  doc.parse<0>(xmlFile.data());
33 
34  rapidxml::xml_node<>* decl = doc.allocate_node(rapidxml::node_declaration);
35  rapidxml::xml_attribute<>* ver = doc.allocate_attribute("version", "1.0");
36  rapidxml::xml_attribute<>* encoding = doc.allocate_attribute("encoding", "utf-8");
37  decl->append_attribute(ver);
38  decl->append_attribute(encoding);
39  doc.append_node(decl);
40 
41  rapidxml::xml_node<>* rootNode = doc.allocate_node(rapidxml::node_element, "Project");
42  doc.append_node(rootNode);
43 
44  rapidxml::xml_node<>* projectNameNode = AppendNode(doc, rootNode, "Name");
45  SetNodeValue(doc, projectNameNode, path.GetName());
46 
47  //{ Simulation properties
48  PropertiesData* properties = m_workspace->GetProperties();
49  auto propertiesNode = AppendNode(doc, rootNode, "Properties");
50 
51  SimulationData simulationData = properties->GetSimulationPropertiesData();
52  auto simulationPropNode = AppendNode(doc, propertiesNode, "SimulationProperties");
53 
54  auto generalPropNode = AppendNode(doc, simulationPropNode, "General");
55  auto basePower = AppendNode(doc, generalPropNode, "BasePower");
56  SetNodeValue(doc, basePower, simulationData.basePower);
57  SetNodeAttribute(doc, basePower, "UnitID", simulationData.basePowerUnit);
58  auto contCalc = AppendNode(doc, generalPropNode, "ContinuousCalculation");
59  auto contCalcFault = AppendNode(doc, contCalc, "Fault");
60  SetNodeValue(doc, contCalcFault, simulationData.faultAfterPowerFlow);
61  auto contCalcSCPower = AppendNode(doc, contCalc, "SCPower");
62  SetNodeValue(doc, contCalcSCPower, simulationData.scPowerAfterPowerFlow);
63 
64  auto powerFlowPropNode = AppendNode(doc, simulationPropNode, "PowerFlow");
65  auto solutionMethod = AppendNode(doc, powerFlowPropNode, "SolutionMethod");
66  SetNodeValue(doc, solutionMethod, simulationData.powerFlowMethod);
67  auto accFactor = AppendNode(doc, powerFlowPropNode, "AccFactor");
68  SetNodeValue(doc, accFactor, simulationData.accFator);
69  auto pfTolerance = AppendNode(doc, powerFlowPropNode, "Tolerance");
70  SetNodeValue(doc, pfTolerance, simulationData.powerFlowTolerance);
71  auto pfMaxIter = AppendNode(doc, powerFlowPropNode, "MaxIterations");
72  SetNodeValue(doc, pfMaxIter, simulationData.powerFlowMaxIterations);
73 
74  auto stabilityPropNode = AppendNode(doc, simulationPropNode, "Stability");
75  auto timeStep = AppendNode(doc, stabilityPropNode, "TimeStep");
76  SetNodeValue(doc, timeStep, simulationData.timeStep);
77  auto simTime = AppendNode(doc, stabilityPropNode, "SimulationTime");
78  SetNodeValue(doc, simTime, simulationData.stabilitySimulationTime);
79  auto freq = AppendNode(doc, stabilityPropNode, "Frequency");
80  SetNodeValue(doc, freq, simulationData.stabilityFrequency);
81  auto stabTolerance = AppendNode(doc, stabilityPropNode, "Tolerance");
82  SetNodeValue(doc, stabTolerance, simulationData.stabilityTolerance);
83  auto stabTMaxIter = AppendNode(doc, stabilityPropNode, "MaxIterations");
84  SetNodeValue(doc, stabTMaxIter, simulationData.stabilityMaxIterations);
85  auto controlRatio = AppendNode(doc, stabilityPropNode, "ControlStepRatio");
86  SetNodeValue(doc, controlRatio, simulationData.controlTimeStepRatio);
87  auto plotStep = AppendNode(doc, stabilityPropNode, "PlotStep");
88  SetNodeValue(doc, plotStep, simulationData.plotTime);
89  auto useCOI = AppendNode(doc, stabilityPropNode, "UseCOI");
90  SetNodeValue(doc, useCOI, simulationData.useCOI);
91 
92  auto zipPropNode = AppendNode(doc, simulationPropNode, "ZIPLoad");
93  auto useCompLoads = AppendNode(doc, zipPropNode, "UseCompositeLoad");
94  SetNodeValue(doc, useCompLoads, simulationData.useCompLoads);
95  auto activePowerComp = AppendNode(doc, zipPropNode, "ActivePowerComposition");
96  auto pz = AppendNode(doc, activePowerComp, "ConstantImpedance");
97  SetNodeValue(doc, pz, simulationData.constImpedanceActive);
98  auto pi = AppendNode(doc, activePowerComp, "ConstantCurrent");
99  SetNodeValue(doc, pi, simulationData.constCurrentActive);
100  auto pp = AppendNode(doc, activePowerComp, "ConstantPower");
101  SetNodeValue(doc, pp, simulationData.constPowerActive);
102  auto reactivePowerComp = AppendNode(doc, zipPropNode, "ReactivePowerComposition");
103  auto qz = AppendNode(doc, reactivePowerComp, "ConstantImpedance");
104  SetNodeValue(doc, qz, simulationData.constImpedanceReactive);
105  auto qi = AppendNode(doc, reactivePowerComp, "ConstantCurrent");
106  SetNodeValue(doc, qi, simulationData.constCurrentReactive);
107  auto qp = AppendNode(doc, reactivePowerComp, "ConstantPower");
108  SetNodeValue(doc, qp, simulationData.constPowerReactive);
109  auto undervoltageLim = AppendNode(doc, zipPropNode, "UndervoltageLimit");
110  auto uvi = AppendNode(doc, undervoltageLim, "ConstantCurrent");
111  SetNodeValue(doc, uvi, simulationData.underVoltageConstCurrent);
112  auto uvp = AppendNode(doc, undervoltageLim, "ConstantPower");
113  SetNodeValue(doc, uvp, simulationData.underVoltageConstPower);
114 
115  //}
116 
117  auto elementsNode = AppendNode(doc, rootNode, "Elements");
118 
119  // Save all the data
120  ElectricCalculation allElements;
121  allElements.GetElementsFromList(m_workspace->GetElementList());
122 
123  //{ Buses
124  auto busesNode = AppendNode(doc, elementsNode, "BusList");
125  auto busList = allElements.GetBusList();
126  for(int i = 0; i < (int)busList.size(); i++) {
127  Bus* bus = busList[i];
128  auto busNode = AppendNode(doc, busesNode, "Bus");
129  SetNodeAttribute(doc, busNode, "ID", i);
130  auto cadProp = AppendNode(doc, busNode, "CADProperties");
131  auto position = AppendNode(doc, cadProp, "Position");
132  auto posX = AppendNode(doc, position, "X");
133  SetNodeValue(doc, posX, bus->GetPosition().m_x);
134  auto posY = AppendNode(doc, position, "Y");
135  SetNodeValue(doc, posY, bus->GetPosition().m_y);
136  auto size = AppendNode(doc, cadProp, "Size");
137  auto width = AppendNode(doc, size, "Width");
138  SetNodeValue(doc, width, bus->GetWidth());
139  auto height = AppendNode(doc, size, "Height");
140  SetNodeValue(doc, height, bus->GetHeight());
141  auto angle = AppendNode(doc, cadProp, "Angle");
142  SetNodeValue(doc, angle, bus->GetAngle());
143 
144  BusElectricalData data = bus->GetElectricalData();
145  auto electricalProp = AppendNode(doc, busNode, "ElectricalProperties");
146  auto name = AppendNode(doc, electricalProp, "Name");
147  SetNodeValue(doc, name, data.name);
148  auto nominalVoltage = AppendNode(doc, electricalProp, "NominalVoltage");
149  SetNodeValue(doc, nominalVoltage, data.nominalVoltage);
150  SetNodeAttribute(doc, nominalVoltage, "UnitID", data.nominalVoltageUnit);
151  auto isVoltageControlled = AppendNode(doc, electricalProp, "IsVoltageControlled");
152  SetNodeValue(doc, isVoltageControlled, data.isVoltageControlled);
153  auto controlledVoltage = AppendNode(doc, electricalProp, "ControlledVoltage");
154  SetNodeValue(doc, controlledVoltage, data.controlledVoltage);
155  SetNodeAttribute(doc, controlledVoltage, "Choice", data.controlledVoltageUnitChoice);
156  auto slackBus = AppendNode(doc, electricalProp, "SlackBus");
157  SetNodeValue(doc, slackBus, data.slackBus);
158 
159  auto fault = AppendNode(doc, electricalProp, "Fault");
160  auto hasFault = AppendNode(doc, fault, "HasFault");
161  SetNodeValue(doc, hasFault, data.hasFault);
162  auto faultType = AppendNode(doc, fault, "Type");
163  SetNodeValue(doc, faultType, data.faultType);
164  auto faultLocation = AppendNode(doc, fault, "Location");
165  SetNodeValue(doc, faultLocation, data.faultLocation);
166  auto faultResistance = AppendNode(doc, fault, "Resistance");
167  SetNodeValue(doc, faultResistance, data.faultResistance);
168  auto faultReactance = AppendNode(doc, fault, "Reactance");
169  SetNodeValue(doc, faultReactance, data.faultReactance);
170 
171  auto stability = AppendNode(doc, electricalProp, "Stability");
172  auto plotBus = AppendNode(doc, stability, "Plot");
173  SetNodeValue(doc, plotBus, data.plotBus);
174  auto stabHasFault = AppendNode(doc, stability, "HasFault");
175  SetNodeValue(doc, stabHasFault, data.stabHasFault);
176  auto stabFaultTime = AppendNode(doc, stability, "FaultTime");
177  SetNodeValue(doc, stabFaultTime, data.stabFaultTime);
178  auto stabFaultLength = AppendNode(doc, stability, "FaultLength");
179  SetNodeValue(doc, stabFaultLength, data.stabFaultLength);
180  auto stabFaultResistance = AppendNode(doc, stability, "FaultResistance");
181  SetNodeValue(doc, stabFaultResistance, data.stabFaultResistance);
182  auto stabFaultReactance = AppendNode(doc, stability, "FaultReactance");
183  SetNodeValue(doc, stabFaultReactance, data.stabFaultReactance);
184 
185  data.number = i;
186  bus->SetElectricalData(data);
187  } //}
188 
189  //{ Capacitor
190  auto capacitorsNode = AppendNode(doc, elementsNode, "CapacitorList");
191  auto capacitorList = allElements.GetCapacitorList();
192  for(int i = 0; i < (int)capacitorList.size(); i++) {
193  Capacitor* capacitor = capacitorList[i];
194  auto capacitorNode = AppendNode(doc, capacitorsNode, "Capacitor");
195  SetNodeAttribute(doc, capacitorNode, "ID", i);
196  auto cadProp = AppendNode(doc, capacitorNode, "CADProperties");
197  auto position = AppendNode(doc, cadProp, "Position");
198  auto posX = AppendNode(doc, position, "X");
199  SetNodeValue(doc, posX, capacitor->GetPosition().m_x);
200  auto posY = AppendNode(doc, position, "Y");
201  SetNodeValue(doc, posY, capacitor->GetPosition().m_y);
202  auto size = AppendNode(doc, cadProp, "Size");
203  auto width = AppendNode(doc, size, "Width");
204  SetNodeValue(doc, width, capacitor->GetWidth());
205  auto height = AppendNode(doc, size, "Height");
206  SetNodeValue(doc, height, capacitor->GetHeight());
207  auto angle = AppendNode(doc, cadProp, "Angle");
208  SetNodeValue(doc, angle, capacitor->GetAngle());
209  auto nodePos = AppendNode(doc, cadProp, "NodePosition");
210  auto nodePosX = AppendNode(doc, nodePos, "X");
211  SetNodeValue(doc, nodePosX, capacitor->GetPointList()[0].m_x);
212  auto nodePosY = AppendNode(doc, nodePos, "Y");
213  SetNodeValue(doc, nodePosY, capacitor->GetPointList()[0].m_y);
214  auto parentID = AppendNode(doc, cadProp, "ParentID");
215  Bus* parent = static_cast<Bus*>(capacitor->GetParentList()[0]);
216  if(parent) SetNodeValue(doc, parentID, parent->GetElectricalData().number);
217 
218  CapacitorElectricalData data = capacitor->GetElectricalData();
219  auto electricalProp = AppendNode(doc, capacitorNode, "ElectricalProperties");
220  auto isOnline = AppendNode(doc, electricalProp, "IsOnline");
221  SetNodeValue(doc, isOnline, capacitor->IsOnline());
222  auto name = AppendNode(doc, electricalProp, "Name");
223  SetNodeValue(doc, name, data.name);
224  auto reactivePower = AppendNode(doc, electricalProp, "ReactivePower");
225  SetNodeValue(doc, reactivePower, data.reactivePower);
226  SetNodeAttribute(doc, reactivePower, "UnitID", data.reactivePowerUnit);
227 
228  auto switchingList = AppendNode(doc, electricalProp, "SwitchingList");
229  SwitchingData swData = capacitor->GetSwitchingData();
230  for(int j = 0; j < (int)swData.swType.size(); j++) {
231  auto switching = AppendNode(doc, switchingList, "Switching");
232  SetNodeAttribute(doc, switching, "ID", j);
233  auto swType = AppendNode(doc, switching, "Type");
234  SetNodeValue(doc, swType, swData.swType[j]);
235  auto swTime = AppendNode(doc, switching, "Time");
236  SetNodeValue(doc, swTime, swData.swTime[j]);
237  }
238  } //}
239 
240  //{ IndMotor
241  auto indMotorsNode = AppendNode(doc, elementsNode, "IndMotorList");
242  auto indMotorList = allElements.GetIndMotorList();
243  for(int i = 0; i < (int)indMotorList.size(); i++) {
244  IndMotor* indMotor = indMotorList[i];
245  auto indMotorNode = AppendNode(doc, indMotorsNode, "IndMotor");
246  SetNodeAttribute(doc, indMotorNode, "ID", i);
247  auto cadProp = AppendNode(doc, indMotorNode, "CADProperties");
248  auto position = AppendNode(doc, cadProp, "Position");
249  auto posX = AppendNode(doc, position, "X");
250  SetNodeValue(doc, posX, indMotor->GetPosition().m_x);
251  auto posY = AppendNode(doc, position, "Y");
252  SetNodeValue(doc, posY, indMotor->GetPosition().m_y);
253  auto size = AppendNode(doc, cadProp, "Size");
254  auto width = AppendNode(doc, size, "Width");
255  SetNodeValue(doc, width, indMotor->GetWidth());
256  auto height = AppendNode(doc, size, "Height");
257  SetNodeValue(doc, height, indMotor->GetHeight());
258  auto angle = AppendNode(doc, cadProp, "Angle");
259  SetNodeValue(doc, angle, indMotor->GetAngle());
260  auto nodePos = AppendNode(doc, cadProp, "NodePosition");
261  auto nodePosX = AppendNode(doc, nodePos, "X");
262  SetNodeValue(doc, nodePosX, indMotor->GetPointList()[0].m_x);
263  auto nodePosY = AppendNode(doc, nodePos, "Y");
264  SetNodeValue(doc, nodePosY, indMotor->GetPointList()[0].m_y);
265  auto parentID = AppendNode(doc, cadProp, "ParentID");
266  Bus* parent = static_cast<Bus*>(indMotor->GetParentList()[0]);
267  if(parent) SetNodeValue(doc, parentID, parent->GetElectricalData().number);
268 
269  IndMotorElectricalData data = indMotor->GetElectricalData();
270  auto electricalProp = AppendNode(doc, indMotorNode, "ElectricalProperties");
271  auto isOnline = AppendNode(doc, electricalProp, "IsOnline");
272  SetNodeValue(doc, isOnline, indMotor->IsOnline());
273  auto name = AppendNode(doc, electricalProp, "Name");
274  SetNodeValue(doc, name, data.name);
275  auto activePower = AppendNode(doc, electricalProp, "ActivePower");
276  SetNodeValue(doc, activePower, data.activePower);
277  SetNodeAttribute(doc, activePower, "UnitID", data.activePowerUnit);
278  auto reactivePower = AppendNode(doc, electricalProp, "ReactivePower");
279  SetNodeValue(doc, reactivePower, data.reactivePower);
280  SetNodeAttribute(doc, reactivePower, "UnitID", data.reactivePowerUnit);
281  } //}
282 
283  //{ Inductor
284  auto inductorsNode = AppendNode(doc, elementsNode, "InductorList");
285  auto inductorList = allElements.GetInductorList();
286  for(int i = 0; i < (int)inductorList.size(); i++) {
287  Inductor* inductor = inductorList[i];
288  auto inductorNode = AppendNode(doc, inductorsNode, "Inductor");
289  SetNodeAttribute(doc, inductorNode, "ID", i);
290  auto cadProp = AppendNode(doc, inductorNode, "CADProperties");
291  auto position = AppendNode(doc, cadProp, "Position");
292  auto posX = AppendNode(doc, position, "X");
293  SetNodeValue(doc, posX, inductor->GetPosition().m_x);
294  auto posY = AppendNode(doc, position, "Y");
295  SetNodeValue(doc, posY, inductor->GetPosition().m_y);
296  auto size = AppendNode(doc, cadProp, "Size");
297  auto width = AppendNode(doc, size, "Width");
298  SetNodeValue(doc, width, inductor->GetWidth());
299  auto height = AppendNode(doc, size, "Height");
300  SetNodeValue(doc, height, inductor->GetHeight());
301  auto angle = AppendNode(doc, cadProp, "Angle");
302  SetNodeValue(doc, angle, inductor->GetAngle());
303  auto nodePos = AppendNode(doc, cadProp, "NodePosition");
304  auto nodePosX = AppendNode(doc, nodePos, "X");
305  SetNodeValue(doc, nodePosX, inductor->GetPointList()[0].m_x);
306  auto nodePosY = AppendNode(doc, nodePos, "Y");
307  SetNodeValue(doc, nodePosY, inductor->GetPointList()[0].m_y);
308  auto parentID = AppendNode(doc, cadProp, "ParentID");
309  Bus* parent = static_cast<Bus*>(inductor->GetParentList()[0]);
310  if(parent) SetNodeValue(doc, parentID, parent->GetElectricalData().number);
311 
312  InductorElectricalData data = inductor->GetElectricalData();
313  auto electricalProp = AppendNode(doc, inductorNode, "ElectricalProperties");
314  auto isOnline = AppendNode(doc, electricalProp, "IsOnline");
315  SetNodeValue(doc, isOnline, inductor->IsOnline());
316  auto name = AppendNode(doc, electricalProp, "Name");
317  SetNodeValue(doc, name, data.name);
318  auto reactivePower = AppendNode(doc, electricalProp, "ReactivePower");
319  SetNodeValue(doc, reactivePower, data.reactivePower);
320  SetNodeAttribute(doc, reactivePower, "UnitID", data.reactivePowerUnit);
321 
322  auto switchingList = AppendNode(doc, electricalProp, "SwitchingList");
323  SwitchingData swData = inductor->GetSwitchingData();
324  for(int j = 0; j < (int)swData.swType.size(); j++) {
325  auto switching = AppendNode(doc, switchingList, "Switching");
326  SetNodeAttribute(doc, switching, "ID", j);
327  auto swType = AppendNode(doc, switching, "Type");
328  SetNodeValue(doc, swType, swData.swType[j]);
329  auto swTime = AppendNode(doc, switching, "Time");
330  SetNodeValue(doc, swTime, swData.swTime[j]);
331  }
332  } //}
333 
334  //{ Line
335  auto linesNode = AppendNode(doc, elementsNode, "LineList");
336  auto lineList = allElements.GetLineList();
337  for(int i = 0; i < (int)lineList.size(); i++) {
338  Line* line = lineList[i];
339  auto lineNode = AppendNode(doc, linesNode, "Line");
340  SetNodeAttribute(doc, lineNode, "ID", i);
341  auto cadProp = AppendNode(doc, lineNode, "CADProperties");
342  auto nodeList = AppendNode(doc, cadProp, "NodeList");
343  auto ptList = line->GetPointList();
344  int nodeID = 0;
345  for(int j = 0; j < (int)ptList.size(); j++) {
346  if((j != 1) && (j != (int)ptList.size() - 2)) {
347  auto nodePos = AppendNode(doc, nodeList, "Node");
348  SetNodeAttribute(doc, nodePos, "ID", nodeID);
349  auto nodePosX = AppendNode(doc, nodePos, "X");
350  SetNodeValue(doc, nodePosX, ptList[j].m_x);
351  auto nodePosY = AppendNode(doc, nodePos, "Y");
352  SetNodeValue(doc, nodePosY, ptList[j].m_y);
353  nodeID++;
354  }
355  }
356 
357  auto parentIDList = AppendNode(doc, cadProp, "ParentIDList");
358  for(int j = 0; j < (int)line->GetParentList().size(); j++) {
359  Bus* parent = static_cast<Bus*>(line->GetParentList()[j]);
360  if(parent) {
361  auto parentID = AppendNode(doc, parentIDList, "ParentID");
362  SetNodeAttribute(doc, parentID, "ID", j);
363  SetNodeValue(doc, parentID, parent->GetElectricalData().number);
364  }
365  }
366 
367  LineElectricalData data = line->GetElectricalData();
368  auto electricalProp = AppendNode(doc, lineNode, "ElectricalProperties");
369  auto isOnline = AppendNode(doc, electricalProp, "IsOnline");
370  SetNodeValue(doc, isOnline, line->IsOnline());
371  auto name = AppendNode(doc, electricalProp, "Name");
372  SetNodeValue(doc, name, data.name);
373  auto nominalVoltage = AppendNode(doc, electricalProp, "NominalVoltage");
374  SetNodeValue(doc, nominalVoltage, data.nominalVoltage);
375  SetNodeAttribute(doc, nominalVoltage, "UnitID", data.nominalVoltageUnit);
376  auto nominalPower = AppendNode(doc, electricalProp, "NominalPower");
377  SetNodeValue(doc, nominalPower, data.nominalPower);
378  SetNodeAttribute(doc, nominalPower, "UnitID", data.nominalPowerUnit);
379  auto resistance = AppendNode(doc, electricalProp, "Resistance");
380  SetNodeValue(doc, resistance, data.resistance);
381  SetNodeAttribute(doc, resistance, "UnitID", data.resistanceUnit);
382  auto indReactance = AppendNode(doc, electricalProp, "IndReactance");
383  SetNodeValue(doc, indReactance, data.indReactance);
384  SetNodeAttribute(doc, indReactance, "UnitID", data.indReactanceUnit);
385  auto capSusceptance = AppendNode(doc, electricalProp, "CapSusceptance");
386  SetNodeValue(doc, capSusceptance, data.capSusceptance);
387  SetNodeAttribute(doc, capSusceptance, "UnitID", data.capSusceptanceUnit);
388  auto lineSize = AppendNode(doc, electricalProp, "LineSize");
389  SetNodeValue(doc, lineSize, data.lineSize);
390  auto useLinePower = AppendNode(doc, electricalProp, "UseLinePower");
391  SetNodeValue(doc, useLinePower, data.useLinePower);
392 
393  auto fault = AppendNode(doc, electricalProp, "Fault");
394  auto zeroResistance = AppendNode(doc, fault, "ZeroResistance");
395  SetNodeValue(doc, zeroResistance, data.zeroResistance);
396  auto zeroIndReactance = AppendNode(doc, fault, "ZeroIndReactance");
397  SetNodeValue(doc, zeroIndReactance, data.zeroIndReactance);
398  auto zeroCapSusceptance = AppendNode(doc, fault, "ZeroCapSusceptance");
399  SetNodeValue(doc, zeroCapSusceptance, data.zeroCapSusceptance);
400 
401  auto switchingList = AppendNode(doc, electricalProp, "SwitchingList");
402  SwitchingData swData = line->GetSwitchingData();
403  for(int j = 0; j < (int)swData.swType.size(); j++) {
404  auto switching = AppendNode(doc, switchingList, "Switching");
405  SetNodeAttribute(doc, switching, "ID", j);
406  auto swType = AppendNode(doc, switching, "Type");
407  SetNodeValue(doc, swType, swData.swType[j]);
408  auto swTime = AppendNode(doc, switching, "Time");
409  SetNodeValue(doc, swTime, swData.swTime[j]);
410  }
411  } //}
412 
413  //{ Load
414  auto loadsNode = AppendNode(doc, elementsNode, "LoadList");
415  auto loadList = allElements.GetLoadList();
416  for(int i = 0; i < (int)loadList.size(); i++) {
417  Load* load = loadList[i];
418  auto loadNode = AppendNode(doc, loadsNode, "Load");
419  SetNodeAttribute(doc, loadNode, "ID", i);
420  auto cadProp = AppendNode(doc, loadNode, "CADProperties");
421  auto position = AppendNode(doc, cadProp, "Position");
422  auto posX = AppendNode(doc, position, "X");
423  SetNodeValue(doc, posX, load->GetPosition().m_x);
424  auto posY = AppendNode(doc, position, "Y");
425  SetNodeValue(doc, posY, load->GetPosition().m_y);
426  auto size = AppendNode(doc, cadProp, "Size");
427  auto width = AppendNode(doc, size, "Width");
428  SetNodeValue(doc, width, load->GetWidth());
429  auto height = AppendNode(doc, size, "Height");
430  SetNodeValue(doc, height, load->GetHeight());
431  auto angle = AppendNode(doc, cadProp, "Angle");
432  SetNodeValue(doc, angle, load->GetAngle());
433  auto nodePos = AppendNode(doc, cadProp, "NodePosition");
434  auto nodePosX = AppendNode(doc, nodePos, "X");
435  SetNodeValue(doc, nodePosX, load->GetPointList()[0].m_x);
436  auto nodePosY = AppendNode(doc, nodePos, "Y");
437  SetNodeValue(doc, nodePosY, load->GetPointList()[0].m_y);
438  auto parentID = AppendNode(doc, cadProp, "ParentID");
439  Bus* parent = static_cast<Bus*>(load->GetParentList()[0]);
440  if(parent) SetNodeValue(doc, parentID, parent->GetElectricalData().number);
441 
442  LoadElectricalData data = load->GetElectricalData();
443  auto electricalProp = AppendNode(doc, loadNode, "ElectricalProperties");
444  auto isOnline = AppendNode(doc, electricalProp, "IsOnline");
445  SetNodeValue(doc, isOnline, load->IsOnline());
446  auto name = AppendNode(doc, electricalProp, "Name");
447  SetNodeValue(doc, name, data.name);
448  auto activePower = AppendNode(doc, electricalProp, "ActivePower");
449  SetNodeValue(doc, activePower, data.activePower);
450  SetNodeAttribute(doc, activePower, "UnitID", data.activePowerUnit);
451  auto reactivePower = AppendNode(doc, electricalProp, "ReactivePower");
452  SetNodeValue(doc, reactivePower, data.reactivePower);
453  SetNodeAttribute(doc, reactivePower, "UnitID", data.reactivePowerUnit);
454  auto loadType = AppendNode(doc, electricalProp, "LoadType");
455  SetNodeValue(doc, loadType, data.loadType);
456 
457  auto stability = AppendNode(doc, electricalProp, "Stability");
458  auto plotLoad = AppendNode(doc, stability, "PlotLoad");
459  SetNodeValue(doc, plotLoad, data.plotLoad);
460  auto useCompLoad = AppendNode(doc, stability, "UseCompositeLoad");
461  SetNodeValue(doc, useCompLoad, data.useCompLoad);
462  auto activePowerCompl = AppendNode(doc, stability, "ActivePowerComposition");
463  auto pzl = AppendNode(doc, activePowerCompl, "ConstantImpedance");
464  SetNodeValue(doc, pzl, data.constImpedanceActive);
465  auto pil = AppendNode(doc, activePowerCompl, "ConstantCurrent");
466  SetNodeValue(doc, pil, data.constCurrentActive);
467  auto ppl = AppendNode(doc, activePowerCompl, "ConstantPower");
468  SetNodeValue(doc, ppl, data.constPowerActive);
469  auto reactivePowerCompl = AppendNode(doc, stability, "ReactivePowerComposition");
470  auto qzl = AppendNode(doc, reactivePowerCompl, "ConstantImpedance");
471  SetNodeValue(doc, qzl, data.constImpedanceReactive);
472  auto qil = AppendNode(doc, reactivePowerCompl, "ConstantCurrent");
473  SetNodeValue(doc, qil, data.constCurrentReactive);
474  auto qpl = AppendNode(doc, reactivePowerCompl, "ConstantPower");
475  SetNodeValue(doc, qpl, data.constPowerReactive);
476 
477  auto switchingList = AppendNode(doc, electricalProp, "SwitchingList");
478  SwitchingData swData = load->GetSwitchingData();
479  for(int j = 0; j < (int)swData.swType.size(); j++) {
480  auto switching = AppendNode(doc, switchingList, "Switching");
481  SetNodeAttribute(doc, switching, "ID", j);
482  auto swType = AppendNode(doc, switching, "Type");
483  SetNodeValue(doc, swType, swData.swType[j]);
484  auto swTime = AppendNode(doc, switching, "Time");
485  SetNodeValue(doc, swTime, swData.swTime[j]);
486  }
487  } //}
488 
489  //{ SyncGenerator
490  auto syncGeneratorsNode = AppendNode(doc, elementsNode, "SyncGeneratorList");
491  auto syncGeneratorList = allElements.GetSyncGeneratorList();
492  for(int i = 0; i < (int)syncGeneratorList.size(); i++) {
493  SyncGenerator* syncGenerator = syncGeneratorList[i];
494  auto syncGeneratorNode = AppendNode(doc, syncGeneratorsNode, "SyncGenerator");
495  SetNodeAttribute(doc, syncGeneratorNode, "ID", i);
496  auto cadProp = AppendNode(doc, syncGeneratorNode, "CADProperties");
497  auto position = AppendNode(doc, cadProp, "Position");
498  auto posX = AppendNode(doc, position, "X");
499  SetNodeValue(doc, posX, syncGenerator->GetPosition().m_x);
500  auto posY = AppendNode(doc, position, "Y");
501  SetNodeValue(doc, posY, syncGenerator->GetPosition().m_y);
502  auto size = AppendNode(doc, cadProp, "Size");
503  auto width = AppendNode(doc, size, "Width");
504  SetNodeValue(doc, width, syncGenerator->GetWidth());
505  auto height = AppendNode(doc, size, "Height");
506  SetNodeValue(doc, height, syncGenerator->GetHeight());
507  auto angle = AppendNode(doc, cadProp, "Angle");
508  SetNodeValue(doc, angle, syncGenerator->GetAngle());
509  auto nodePos = AppendNode(doc, cadProp, "NodePosition");
510  auto nodePosX = AppendNode(doc, nodePos, "X");
511  SetNodeValue(doc, nodePosX, syncGenerator->GetPointList()[0].m_x);
512  auto nodePosY = AppendNode(doc, nodePos, "Y");
513  SetNodeValue(doc, nodePosY, syncGenerator->GetPointList()[0].m_y);
514  auto parentID = AppendNode(doc, cadProp, "ParentID");
515  Bus* parent = static_cast<Bus*>(syncGenerator->GetParentList()[0]);
516  if(parent) SetNodeValue(doc, parentID, parent->GetElectricalData().number);
517 
518  SyncGeneratorElectricalData data = syncGenerator->GetElectricalData();
519  auto electricalProp = AppendNode(doc, syncGeneratorNode, "ElectricalProperties");
520  auto isOnline = AppendNode(doc, electricalProp, "IsOnline");
521  SetNodeValue(doc, isOnline, syncGenerator->IsOnline());
522  auto name = AppendNode(doc, electricalProp, "Name");
523  SetNodeValue(doc, name, data.name);
524  auto nominalPower = AppendNode(doc, electricalProp, "NominalPower");
525  SetNodeValue(doc, nominalPower, data.nominalPower);
526  SetNodeAttribute(doc, nominalPower, "UnitID", data.nominalPowerUnit);
527  auto nominalVoltage = AppendNode(doc, electricalProp, "NominalVoltage");
528  SetNodeValue(doc, nominalVoltage, data.nominalVoltage);
529  SetNodeAttribute(doc, nominalVoltage, "UnitID", data.nominalVoltageUnit);
530  auto activePower = AppendNode(doc, electricalProp, "ActivePower");
531  SetNodeValue(doc, activePower, data.activePower);
532  SetNodeAttribute(doc, activePower, "UnitID", data.activePowerUnit);
533  auto reactivePower = AppendNode(doc, electricalProp, "ReactivePower");
534  SetNodeValue(doc, reactivePower, data.reactivePower);
535  SetNodeAttribute(doc, reactivePower, "UnitID", data.reactivePowerUnit);
536  auto haveMaxReactive = AppendNode(doc, electricalProp, "HaveMaxReactive");
537  SetNodeValue(doc, haveMaxReactive, data.haveMaxReactive);
538  auto maxReactive = AppendNode(doc, electricalProp, "MaxReactive");
539  SetNodeValue(doc, maxReactive, data.maxReactive);
540  SetNodeAttribute(doc, maxReactive, "UnitID", data.maxReactiveUnit);
541  auto haveMinReactive = AppendNode(doc, electricalProp, "HaveMinReactive");
542  SetNodeValue(doc, haveMinReactive, data.haveMinReactive);
543  auto minReactive = AppendNode(doc, electricalProp, "MinReactive");
544  SetNodeValue(doc, minReactive, data.minReactive);
545  SetNodeAttribute(doc, minReactive, "UnitID", data.minReactiveUnit);
546  auto useMachineBase = AppendNode(doc, electricalProp, "UseMachineBase");
547  SetNodeValue(doc, useMachineBase, data.useMachineBase);
548 
549  auto fault = AppendNode(doc, electricalProp, "Fault");
550  auto positiveResistance = AppendNode(doc, fault, "PositiveResistance");
551  SetNodeValue(doc, positiveResistance, data.positiveResistance);
552  auto positiveReactance = AppendNode(doc, fault, "PositiveReactance");
553  SetNodeValue(doc, positiveReactance, data.positiveReactance);
554  auto negativeResistance = AppendNode(doc, fault, "NegativeResistance");
555  SetNodeValue(doc, negativeResistance, data.negativeResistance);
556  auto negativeReactance = AppendNode(doc, fault, "NegativeReactance");
557  SetNodeValue(doc, negativeReactance, data.negativeReactance);
558  auto zeroResistance = AppendNode(doc, fault, "ZeroResistance");
559  SetNodeValue(doc, zeroResistance, data.zeroResistance);
560  auto zeroReactance = AppendNode(doc, fault, "ZeroReactance");
561  SetNodeValue(doc, zeroReactance, data.zeroReactance);
562  auto groundResistance = AppendNode(doc, fault, "GroundResistance");
563  SetNodeValue(doc, groundResistance, data.groundResistance);
564  auto groundReactance = AppendNode(doc, fault, "GroundReactance");
565  SetNodeValue(doc, groundReactance, data.groundReactance);
566  auto groundNeutral = AppendNode(doc, fault, "GroundNeutral");
567  SetNodeValue(doc, groundNeutral, data.groundNeutral);
568 
569  auto stability = AppendNode(doc, electricalProp, "Stability");
570  auto plotSyncMachine = AppendNode(doc, stability, "PlotSyncMachine");
571  SetNodeValue(doc, plotSyncMachine, data.plotSyncMachine);
572  auto inertia = AppendNode(doc, stability, "Inertia");
573  SetNodeValue(doc, inertia, data.inertia);
574  auto damping = AppendNode(doc, stability, "Damping");
575  SetNodeValue(doc, damping, data.damping);
576  auto useAVR = AppendNode(doc, stability, "UseAVR");
577  SetNodeValue(doc, useAVR, data.useAVR);
578  auto useSpeedGovernor = AppendNode(doc, stability, "UseSpeedGovernor");
579  SetNodeValue(doc, useSpeedGovernor, data.useSpeedGovernor);
580  auto armResistance = AppendNode(doc, stability, "ArmResistance");
581  SetNodeValue(doc, armResistance, data.armResistance);
582  auto potierReactance = AppendNode(doc, stability, "PotierReactance");
583  SetNodeValue(doc, potierReactance, data.potierReactance);
584  auto satFactor = AppendNode(doc, stability, "SatFactor");
585  SetNodeValue(doc, satFactor, data.satFactor);
586  auto syncXd = AppendNode(doc, stability, "SyncXd");
587  SetNodeValue(doc, syncXd, data.syncXd);
588  auto syncXq = AppendNode(doc, stability, "SyncXq");
589  SetNodeValue(doc, syncXq, data.syncXq);
590  auto transXd = AppendNode(doc, stability, "TransXd");
591  SetNodeValue(doc, transXd, data.transXd);
592  auto transXq = AppendNode(doc, stability, "TransXq");
593  SetNodeValue(doc, transXq, data.transXq);
594  auto transTd0 = AppendNode(doc, stability, "TransTd0");
595  SetNodeValue(doc, transTd0, data.transTd0);
596  auto transTq0 = AppendNode(doc, stability, "TransTq0");
597  SetNodeValue(doc, transTq0, data.transTq0);
598  auto subXd = AppendNode(doc, stability, "SubXd");
599  SetNodeValue(doc, subXd, data.subXd);
600  auto subXq = AppendNode(doc, stability, "SubXq");
601  SetNodeValue(doc, subXq, data.subXq);
602  auto subTd0 = AppendNode(doc, stability, "SubTd0");
603  SetNodeValue(doc, subTd0, data.subTd0);
604  auto subTq0 = AppendNode(doc, stability, "SubTq0");
605  SetNodeValue(doc, subTq0, data.subTq0);
606 
607  auto avr = AppendNode(doc, stability, "AVR");
608  if(data.avr) SaveControlElements(doc, avr, data.avr);
609 
610  auto speedGov = AppendNode(doc, stability, "SpeedGovernor");
611  if(data.speedGov) SaveControlElements(doc, speedGov, data.speedGov);
612 
613  auto switchingList = AppendNode(doc, electricalProp, "SwitchingList");
614  SwitchingData swData = syncGenerator->GetSwitchingData();
615  for(int j = 0; j < (int)swData.swType.size(); j++) {
616  auto switching = AppendNode(doc, switchingList, "Switching");
617  SetNodeAttribute(doc, switching, "ID", j);
618  auto swType = AppendNode(doc, switching, "Type");
619  SetNodeValue(doc, swType, swData.swType[j]);
620  auto swTime = AppendNode(doc, switching, "Time");
621  SetNodeValue(doc, swTime, swData.swTime[j]);
622  }
623  } //}
624 
625  //{ SyncMotor
626  auto syncMotorsNode = AppendNode(doc, elementsNode, "SyncMotorList");
627  auto syncMotorList = allElements.GetSyncMotorList();
628  for(int i = 0; i < (int)syncMotorList.size(); i++) {
629  SyncMotor* syncMotor = syncMotorList[i];
630  auto syncMotorNode = AppendNode(doc, syncMotorsNode, "SyncMotor");
631  SetNodeAttribute(doc, syncMotorNode, "ID", i);
632  auto cadProp = AppendNode(doc, syncMotorNode, "CADProperties");
633  auto position = AppendNode(doc, cadProp, "Position");
634  auto posX = AppendNode(doc, position, "X");
635  SetNodeValue(doc, posX, syncMotor->GetPosition().m_x);
636  auto posY = AppendNode(doc, position, "Y");
637  SetNodeValue(doc, posY, syncMotor->GetPosition().m_y);
638  auto size = AppendNode(doc, cadProp, "Size");
639  auto width = AppendNode(doc, size, "Width");
640  SetNodeValue(doc, width, syncMotor->GetWidth());
641  auto height = AppendNode(doc, size, "Height");
642  SetNodeValue(doc, height, syncMotor->GetHeight());
643  auto angle = AppendNode(doc, cadProp, "Angle");
644  SetNodeValue(doc, angle, syncMotor->GetAngle());
645  auto nodePos = AppendNode(doc, cadProp, "NodePosition");
646  auto nodePosX = AppendNode(doc, nodePos, "X");
647  SetNodeValue(doc, nodePosX, syncMotor->GetPointList()[0].m_x);
648  auto nodePosY = AppendNode(doc, nodePos, "Y");
649  SetNodeValue(doc, nodePosY, syncMotor->GetPointList()[0].m_y);
650  auto parentID = AppendNode(doc, cadProp, "ParentID");
651  Bus* parent = static_cast<Bus*>(syncMotor->GetParentList()[0]);
652  if(parent) SetNodeValue(doc, parentID, parent->GetElectricalData().number);
653 
654  SyncMotorElectricalData data = syncMotor->GetElectricalData();
655  auto electricalProp = AppendNode(doc, syncMotorNode, "ElectricalProperties");
656  auto isOnline = AppendNode(doc, electricalProp, "IsOnline");
657  SetNodeValue(doc, isOnline, syncMotor->IsOnline());
658  auto name = AppendNode(doc, electricalProp, "Name");
659  SetNodeValue(doc, name, data.name);
660  auto nominalPower = AppendNode(doc, electricalProp, "NominalPower");
661  SetNodeValue(doc, nominalPower, data.nominalPower);
662  SetNodeAttribute(doc, nominalPower, "UnitID", data.nominalPowerUnit);
663  // auto nominalVoltage = AppendNode(doc, electricalProp, "NominalVoltage");
664  // SetNodeValue(doc, nominalVoltage, data.nominalVoltage);
665  // SetNodeAttribute(doc, nominalVoltage, "UnitID", data.nominalVoltageUnit);
666  auto activePower = AppendNode(doc, electricalProp, "ActivePower");
667  SetNodeValue(doc, activePower, data.activePower);
668  SetNodeAttribute(doc, activePower, "UnitID", data.activePowerUnit);
669  auto reactivePower = AppendNode(doc, electricalProp, "ReactivePower");
670  SetNodeValue(doc, reactivePower, data.reactivePower);
671  SetNodeAttribute(doc, reactivePower, "UnitID", data.reactivePowerUnit);
672  auto haveMaxReactive = AppendNode(doc, electricalProp, "HaveMaxReactive");
673  SetNodeValue(doc, haveMaxReactive, data.haveMaxReactive);
674  auto maxReactive = AppendNode(doc, electricalProp, "MaxReactive");
675  SetNodeValue(doc, maxReactive, data.maxReactive);
676  SetNodeAttribute(doc, maxReactive, "UnitID", data.maxReactiveUnit);
677  auto haveMinReactive = AppendNode(doc, electricalProp, "HaveMinReactive");
678  SetNodeValue(doc, haveMinReactive, data.haveMinReactive);
679  auto minReactive = AppendNode(doc, electricalProp, "MinReactive");
680  SetNodeValue(doc, minReactive, data.minReactive);
681  SetNodeAttribute(doc, minReactive, "UnitID", data.minReactiveUnit);
682  auto useMachineBase = AppendNode(doc, electricalProp, "UseMachineBase");
683  SetNodeValue(doc, useMachineBase, data.useMachineBase);
684 
685  auto fault = AppendNode(doc, electricalProp, "Fault");
686  auto positiveResistance = AppendNode(doc, fault, "PositiveResistance");
687  SetNodeValue(doc, positiveResistance, data.positiveResistance);
688  auto positiveReactance = AppendNode(doc, fault, "PositiveReactance");
689  SetNodeValue(doc, positiveReactance, data.positiveReactance);
690  auto negativeResistance = AppendNode(doc, fault, "NegativeResistance");
691  SetNodeValue(doc, negativeResistance, data.negativeResistance);
692  auto negativeReactance = AppendNode(doc, fault, "NegativeReactance");
693  SetNodeValue(doc, negativeReactance, data.negativeReactance);
694  auto zeroResistance = AppendNode(doc, fault, "ZeroResistance");
695  SetNodeValue(doc, zeroResistance, data.zeroResistance);
696  auto zeroReactance = AppendNode(doc, fault, "ZeroReactance");
697  SetNodeValue(doc, zeroReactance, data.zeroReactance);
698  auto groundResistance = AppendNode(doc, fault, "GroundResistance");
699  SetNodeValue(doc, groundResistance, data.groundResistance);
700  auto groundReactance = AppendNode(doc, fault, "GroundReactance");
701  SetNodeValue(doc, groundReactance, data.groundReactance);
702  auto groundNeutral = AppendNode(doc, fault, "GroundNeutral");
703  SetNodeValue(doc, groundNeutral, data.groundNeutral);
704 
705  // To future use...
706  /*auto stability = AppendNode(doc, electricalProp, "Stability");
707  auto plotSyncMachine = AppendNode(doc, stability, "PlotSyncMotor");
708  SetNodeValue(doc, plotSyncMachine, data.plotSyncMachine);
709  auto inertia = AppendNode(doc, stability, "Inertia");
710  SetNodeValue(doc, inertia, data.inertia);
711  auto damping = AppendNode(doc, stability, "Damping");
712  SetNodeValue(doc, damping, data.damping);
713  auto useAVR = AppendNode(doc, stability, "UseAVR");
714  SetNodeValue(doc, useAVR, data.useAVR);
715  auto armResistance = AppendNode(doc, stability, "ArmResistance");
716  SetNodeValue(doc, armResistance, data.armResistance);
717  auto potierReactance = AppendNode(doc, stability, "PotierReactance");
718  SetNodeValue(doc, potierReactance, data.potierReactance);
719  auto satFactor = AppendNode(doc, stability, "SatFactor");
720  SetNodeValue(doc, satFactor, data.satFactor);
721  auto syncXd = AppendNode(doc, stability, "SyncXd");
722  SetNodeValue(doc, syncXd, data.syncXd);
723  auto syncXq = AppendNode(doc, stability, "SyncXq");
724  SetNodeValue(doc, syncXq, data.syncXq);
725  auto transXd = AppendNode(doc, stability, "TransXd");
726  SetNodeValue(doc, transXd, data.transXd);
727  auto transXq = AppendNode(doc, stability, "TransXq");
728  SetNodeValue(doc, transXq, data.transXq);
729  auto transTd0 = AppendNode(doc, stability, "TransTd0");
730  SetNodeValue(doc, transTd0, data.transTd0);
731  auto transTq0 = AppendNode(doc, stability, "TransTq0");
732  SetNodeValue(doc, transTq0, data.transTq0);
733  auto subXd = AppendNode(doc, stability, "SubXd");
734  SetNodeValue(doc, subXd, data.subXd);
735  auto subXq = AppendNode(doc, stability, "SubXq");
736  SetNodeValue(doc, subXq, data.subXq);
737  auto subTd0 = AppendNode(doc, stability, "SubTd0");
738  SetNodeValue(doc, subTd0, data.subTd0);
739  auto subTq0 = AppendNode(doc, stability, "SubTq0");
740  SetNodeValue(doc, subTq0, data.subTq0);
741 
742  auto switchingList = AppendNode(doc, electricalProp, "SwitchingList");
743  SwitchingData swData = syncGenerator->GetSwitchingData();
744  for(int j = 0; j < (int)swData.swType.size(); j++) {
745  auto switching = AppendNode(doc, switchingList, "Switching");
746  SetNodeAttribute(doc, switching, "ID", j);
747  auto swType = AppendNode(doc, switching, "Type");
748  SetNodeValue(doc, swType, swData.swType[j]);
749  auto swTime = AppendNode(doc, switching, "Time");
750  SetNodeValue(doc, swTime, swData.swTime[j]);
751  }*/
752  } //}
753 
754  //{ Transfomer
755  auto transformersNode = AppendNode(doc, elementsNode, "TransformerList");
756  auto transformerList = allElements.GetTransformerList();
757  for(int i = 0; i < (int)transformerList.size(); i++) {
758  Transformer* transfomer = transformerList[i];
759  auto transformerNode = AppendNode(doc, transformersNode, "Transfomer");
760  SetNodeAttribute(doc, transformerNode, "ID", i);
761  auto cadProp = AppendNode(doc, transformerNode, "CADProperties");
762  auto position = AppendNode(doc, cadProp, "Position");
763  auto posX = AppendNode(doc, position, "X");
764  SetNodeValue(doc, posX, transfomer->GetPosition().m_x);
765  auto posY = AppendNode(doc, position, "Y");
766  SetNodeValue(doc, posY, transfomer->GetPosition().m_y);
767  auto size = AppendNode(doc, cadProp, "Size");
768  auto width = AppendNode(doc, size, "Width");
769  SetNodeValue(doc, width, transfomer->GetWidth());
770  auto height = AppendNode(doc, size, "Height");
771  SetNodeValue(doc, height, transfomer->GetHeight());
772  auto angle = AppendNode(doc, cadProp, "Angle");
773  SetNodeValue(doc, angle, transfomer->GetAngle());
774  auto nodeList = AppendNode(doc, cadProp, "NodeList");
775  auto nodePos1 = AppendNode(doc, nodeList, "Node");
776  SetNodeAttribute(doc, nodePos1, "ID", 0);
777  auto nodePosX1 = AppendNode(doc, nodePos1, "X");
778  SetNodeValue(doc, nodePosX1, transfomer->GetPointList()[0].m_x);
779  auto nodePosY1 = AppendNode(doc, nodePos1, "Y");
780  SetNodeValue(doc, nodePosY1, transfomer->GetPointList()[0].m_y);
781  auto nodePos2 = AppendNode(doc, nodeList, "Node");
782  SetNodeAttribute(doc, nodePos2, "ID", 1);
783  auto nodePosX2 = AppendNode(doc, nodePos2, "X");
784  SetNodeValue(doc, nodePosX2, transfomer->GetPointList()[transfomer->GetPointList().size() - 1].m_x);
785  auto nodePosY2 = AppendNode(doc, nodePos2, "Y");
786  SetNodeValue(doc, nodePosY2, transfomer->GetPointList()[transfomer->GetPointList().size() - 1].m_y);
787 
788  auto parentIDList = AppendNode(doc, cadProp, "ParentIDList");
789  for(int j = 0; j < (int)transfomer->GetParentList().size(); j++) {
790  Bus* parent = static_cast<Bus*>(transfomer->GetParentList()[j]);
791  if(parent) {
792  auto parentID = AppendNode(doc, parentIDList, "ParentID");
793  SetNodeAttribute(doc, parentID, "ID", j);
794  SetNodeValue(doc, parentID, parent->GetElectricalData().number);
795  }
796  }
797 
798  TransformerElectricalData data = transfomer->GetElectricalData();
799  auto electricalProp = AppendNode(doc, transformerNode, "ElectricalProperties");
800  auto isOnline = AppendNode(doc, electricalProp, "IsOnline");
801  SetNodeValue(doc, isOnline, transfomer->IsOnline());
802  auto name = AppendNode(doc, electricalProp, "Name");
803  SetNodeValue(doc, name, data.name);
804  auto primaryNominalVoltage = AppendNode(doc, electricalProp, "PrimaryNominalVoltage");
805  SetNodeValue(doc, primaryNominalVoltage, data.primaryNominalVoltage);
806  SetNodeAttribute(doc, primaryNominalVoltage, "UnitID", data.primaryNominalVoltageUnit);
807  auto secondaryNominalVoltage = AppendNode(doc, electricalProp, "SecondaryNominalVoltage");
808  SetNodeValue(doc, secondaryNominalVoltage, data.secondaryNominalVoltage);
809  SetNodeAttribute(doc, secondaryNominalVoltage, "UnitID", data.secondaryNominalVoltageUnit);
810  auto nominalPower = AppendNode(doc, electricalProp, "NominalPower");
811  SetNodeValue(doc, nominalPower, data.nominalPower);
812  SetNodeAttribute(doc, nominalPower, "UnitID", data.nominalPowerUnit);
813  auto resistance = AppendNode(doc, electricalProp, "Resistance");
814  SetNodeValue(doc, resistance, data.resistance);
815  SetNodeAttribute(doc, resistance, "UnitID", data.resistanceUnit);
816  auto indReactance = AppendNode(doc, electricalProp, "IndReactance");
817  SetNodeValue(doc, indReactance, data.indReactance);
818  SetNodeAttribute(doc, indReactance, "UnitID", data.indReactanceUnit);
819  auto connection = AppendNode(doc, electricalProp, "Connection");
820  SetNodeValue(doc, connection, data.connection);
821  auto turnsRatio = AppendNode(doc, electricalProp, "TurnsRatio");
822  SetNodeValue(doc, turnsRatio, data.turnsRatio);
823  auto phaseShift = AppendNode(doc, electricalProp, "PhaseShift");
824  SetNodeValue(doc, phaseShift, data.phaseShift);
825  auto useTransformerPower = AppendNode(doc, electricalProp, "UseTransfomerPower");
826  SetNodeValue(doc, useTransformerPower, data.useTransformerPower);
827 
828  auto fault = AppendNode(doc, electricalProp, "Fault");
829  auto zeroResistance = AppendNode(doc, fault, "ZeroResistance");
830  SetNodeValue(doc, zeroResistance, data.zeroResistance);
831  auto zeroIndReactance = AppendNode(doc, fault, "ZeroIndReactance");
832  SetNodeValue(doc, zeroIndReactance, data.zeroIndReactance);
833  auto primaryGrndResistance = AppendNode(doc, fault, "PrimaryGrndResistance");
834  SetNodeValue(doc, primaryGrndResistance, data.primaryGrndResistance);
835  auto primaryGrndReactance = AppendNode(doc, fault, "PrimaryGrndReactance");
836  SetNodeValue(doc, primaryGrndReactance, data.primaryGrndReactance);
837  auto secondaryGrndResistance = AppendNode(doc, fault, "SecondaryGrndResistance");
838  SetNodeValue(doc, secondaryGrndResistance, data.secondaryGrndResistance);
839  auto secondaryGrndReactance = AppendNode(doc, fault, "SecondaryGrndReactance");
840  SetNodeValue(doc, secondaryGrndReactance, data.secondaryGrndReactance);
841 
842  auto switchingList = AppendNode(doc, electricalProp, "SwitchingList");
843  SwitchingData swData = transfomer->GetSwitchingData();
844  for(int j = 0; j < (int)swData.swType.size(); j++) {
845  auto switching = AppendNode(doc, switchingList, "Switching");
846  SetNodeAttribute(doc, switching, "ID", j);
847  auto swType = AppendNode(doc, switching, "Type");
848  SetNodeValue(doc, swType, swData.swType[j]);
849  auto swTime = AppendNode(doc, switching, "Time");
850  SetNodeValue(doc, swTime, swData.swTime[j]);
851  }
852  } //}
853 
854  //{ Text
855  auto textsNode = AppendNode(doc, elementsNode, "TextList");
856  auto textList = m_workspace->GetTextList();
857  for(int i = 0; i < (int)textList.size(); i++) {
858  Text* text = textList[i];
859  auto textNode = AppendNode(doc, textsNode, "Text");
860  SetNodeAttribute(doc, textNode, "ID", i);
861  auto cadProp = AppendNode(doc, textNode, "CADProperties");
862  auto position = AppendNode(doc, cadProp, "Position");
863  auto posX = AppendNode(doc, position, "X");
864  SetNodeValue(doc, posX, text->GetPosition().m_x);
865  auto posY = AppendNode(doc, position, "Y");
866  SetNodeValue(doc, posY, text->GetPosition().m_y);
867  auto size = AppendNode(doc, cadProp, "Size");
868  auto width = AppendNode(doc, size, "Width");
869  SetNodeValue(doc, width, text->GetWidth());
870  auto height = AppendNode(doc, size, "Height");
871  SetNodeValue(doc, height, text->GetHeight());
872  auto angle = AppendNode(doc, cadProp, "Angle");
873  SetNodeValue(doc, angle, text->GetAngle());
874  auto textProperties = AppendNode(doc, textNode, "TextProperties");
875  auto elementType = AppendNode(doc, textProperties, "ElementType");
876  SetNodeValue(doc, elementType, text->GetElementType());
877  auto elementNumber = AppendNode(doc, textProperties, "ElementNumber");
878  SetNodeValue(doc, elementNumber, text->GetElementNumber());
879  auto dataType = AppendNode(doc, textProperties, "DataType");
880  SetNodeValue(doc, dataType, text->GetDataType());
881  auto dataUnit = AppendNode(doc, textProperties, "DataUnit");
882  SetNodeValue(doc, dataUnit, text->GetUnit());
883  auto direction = AppendNode(doc, textProperties, "Direction");
884  SetNodeValue(doc, direction, text->GetDirection());
885  auto decimalPlaces = AppendNode(doc, textProperties, "DecimalPlaces");
886  SetNodeValue(doc, decimalPlaces, text->GetDecimalPlaces());
887  }
888  //}
889 
890  std::ofstream writeXML(path.GetFullPath());
891  writeXML << doc;
892  writeXML.close();
893 }
894 
895 bool FileHanding::OpenProject(wxFileName path)
896 {
897  rapidxml::xml_document<> doc;
898  rapidxml::file<> xmlFile(path.GetFullPath().mb_str());
899 
900  doc.parse<0>(xmlFile.data());
901 
902  auto projectNode = doc.first_node("Project");
903  if(!projectNode) return false;
904  auto nameNode = projectNode->first_node("Name");
905  if(!nameNode) return false;
906  m_workspace->SetName(nameNode->value());
907 
908  PropertiesData* propData = m_workspace->GetProperties();
909  SimulationData simData = propData->GetSimulationPropertiesData();
910 
911  // { Properties data
912  auto propertiesNode = projectNode->first_node("Properties");
913  if(propertiesNode) {
914  auto simPropertiesNode = propertiesNode->first_node("SimulationProperties");
915  if(simPropertiesNode) {
916  // General
917  auto general = simPropertiesNode->first_node("General");
918  simData.basePower = GetNodeValueDouble(general, "BasePower");
919  simData.basePowerUnit = static_cast<ElectricalUnit>(GetAttributeValueInt(general, "BasePower", "UnitID"));
920  auto contCalc = general->first_node("ContinuousCalculation");
921  simData.faultAfterPowerFlow = GetNodeValueInt(contCalc, "Fault");
922  simData.scPowerAfterPowerFlow = GetNodeValueInt(contCalc, "SCPower");
923 
924  // Power flow
925  auto powerFlow = simPropertiesNode->first_node("PowerFlow");
926  simData.powerFlowMethod = static_cast<PowerFlowMethod>(GetNodeValueInt(powerFlow, "SolutionMethod"));
927  simData.accFator = GetNodeValueDouble(powerFlow, "AccFactor");
928  simData.powerFlowTolerance = GetNodeValueDouble(powerFlow, "Tolerance");
929  simData.powerFlowMaxIterations = GetNodeValueInt(powerFlow, "MaxIterations");
930 
931  // Stability
932  auto stability = simPropertiesNode->first_node("Stability");
933  simData.timeStep = GetNodeValueDouble(stability, "TimeStep");
934  simData.stabilitySimulationTime = GetNodeValueDouble(stability, "SimulationTime");
935  simData.stabilityFrequency = GetNodeValueDouble(stability, "Frequency");
936  simData.stabilityTolerance = GetNodeValueDouble(stability, "Tolerance");
937  simData.stabilityMaxIterations = GetNodeValueDouble(stability, "MaxIterations");
938  simData.controlTimeStepRatio = GetNodeValueInt(stability, "ControlStepRatio");
939  simData.plotTime = GetNodeValueDouble(stability, "PlotStep");
940  simData.useCOI = GetNodeValueInt(stability, "UseCOI");
941 
942  // ZIP load
943  auto compLoads = simPropertiesNode->first_node("ZIPLoad");
944  simData.useCompLoads = GetNodeValueInt(compLoads, "UseCompositeLoad");
945  auto activePowerComp = compLoads->first_node("ActivePowerComposition");
946  simData.constImpedanceActive = GetNodeValueDouble(activePowerComp, "ConstantImpedance");
947  simData.constCurrentActive = GetNodeValueDouble(activePowerComp, "ConstantCurrent");
948  simData.constPowerActive = GetNodeValueDouble(activePowerComp, "ConstantPower");
949  auto reactivePowerComp = compLoads->first_node("ReactivePowerComposition");
950  simData.constImpedanceReactive = GetNodeValueDouble(reactivePowerComp, "ConstantImpedance");
951  simData.constCurrentReactive = GetNodeValueDouble(reactivePowerComp, "ConstantCurrent");
952  simData.constPowerReactive = GetNodeValueDouble(reactivePowerComp, "ConstantPower");
953  auto uvLimit = compLoads->first_node("UndervoltageLimit");
954  simData.underVoltageConstCurrent = GetNodeValueDouble(uvLimit, "ConstantCurrent");
955  simData.underVoltageConstPower = GetNodeValueDouble(uvLimit, "ConstantPower");
956  }
957  }
958  // }
959 
960  propData->SetSimulationPropertiesData(simData);
961 
962  // Open elements
963  auto elementsNode = projectNode->first_node("Elements");
964  if(!elementsNode) return false;
965  std::vector<Element*> elementList;
966  // Save lists individually to get parents
967  std::vector<Bus*> busList;
968  std::vector<Capacitor*> capacitorList;
969  std::vector<IndMotor*> indMotorList;
970  std::vector<Inductor*> inductorList;
971  std::vector<Line*> lineList;
972  std::vector<Load*> loadList;
973  std::vector<SyncGenerator*> syncGeneratorList;
974  std::vector<SyncMotor*> syncMotorList;
975  std::vector<Transformer*> transformerList;
976  std::vector<Text*> textList;
977 
978  //{ Bus
979  auto busListNode = elementsNode->first_node("BusList");
980  if(!busListNode) return false;
981  auto busNode = busListNode->first_node("Bus");
982  while(busNode) {
983  auto cadPropNode = busNode->first_node("CADProperties");
984  if(!cadPropNode) return false;
985 
986  auto position = cadPropNode->first_node("Position");
987  double posX = GetNodeValueDouble(position, "X");
988  double posY = GetNodeValueDouble(position, "Y");
989  Bus* bus = new Bus(wxPoint2DDouble(posX, posY));
990 
991  auto size = cadPropNode->first_node("Size");
992  double width = GetNodeValueDouble(size, "Width");
993  double height = GetNodeValueDouble(size, "Height");
994  double angle = GetNodeValueDouble(cadPropNode, "Angle");
995  bus->SetWidth(width);
996  bus->SetHeight(height);
997  bus->SetPosition(bus->GetPosition()); // Update bus rectangle.
998  int numRot = angle / bus->GetRotationAngle();
999  bool clockwise = true;
1000  if(numRot < 0) {
1001  numRot = std::abs(numRot);
1002  clockwise = false;
1003  }
1004  for(int i = 0; i < numRot; i++) bus->Rotate(clockwise);
1005 
1006  BusElectricalData data = bus->GetElectricalData();
1007  auto electricalProp = busNode->first_node("ElectricalProperties");
1008  if(!electricalProp) return false;
1009 
1010  data.name = electricalProp->first_node("Name")->value();
1011  data.nominalVoltage = GetNodeValueDouble(electricalProp, "NominalVoltage");
1012  data.nominalVoltageUnit = (ElectricalUnit)GetAttributeValueInt(electricalProp, "NominalVoltage", "UnitID");
1013  data.isVoltageControlled = GetNodeValueInt(electricalProp, "IsVoltageControlled");
1014  data.controlledVoltage = GetNodeValueDouble(electricalProp, "ControlledVoltage");
1015  data.controlledVoltageUnitChoice = GetAttributeValueInt(electricalProp, "ControlledVoltage", "Choice");
1016  data.slackBus = GetNodeValueInt(electricalProp, "SlackBus");
1017  auto fault = electricalProp->first_node("Fault");
1018  data.hasFault = GetNodeValueInt(fault, "HasFault");
1019  data.faultType = (FaultData)GetNodeValueInt(fault, "Type");
1020  data.faultLocation = (FaultData)GetNodeValueInt(fault, "Location");
1021  data.faultResistance = GetNodeValueDouble(fault, "Resistance");
1022  data.faultReactance = GetNodeValueDouble(fault, "Reactance");
1023  auto stability = electricalProp->first_node("Stability");
1024  data.plotBus = GetNodeValueInt(stability, "Plot");
1025  data.stabHasFault = GetNodeValueInt(stability, "HasFault");
1026  data.stabFaultTime = GetNodeValueDouble(stability, "FaultTime");
1027  data.stabFaultLength = GetNodeValueDouble(stability, "FaultLength");
1028  data.stabFaultResistance = GetNodeValueDouble(stability, "FaultResistance");
1029  data.stabFaultReactance = GetNodeValueDouble(stability, "FaultReactance");
1030 
1031  bus->SetElectricalData(data);
1032 
1033  if(data.stabHasFault) bus->SetDynamicEvent(true);
1034 
1035  elementList.push_back(bus);
1036  busList.push_back(bus);
1037  busNode = busNode->next_sibling("Bus");
1038  } //}
1039 
1040  //{ Capacitor
1041  auto capacitorListNode = elementsNode->first_node("CapacitorList");
1042  if(!capacitorListNode) return false;
1043  auto capacitorNode = capacitorListNode->first_node("Capacitor");
1044  while(capacitorNode) {
1045  Capacitor* capacitor = new Capacitor();
1046 
1047  auto cadPropNode = capacitorNode->first_node("CADProperties");
1048  if(!cadPropNode) return false;
1049 
1050  auto position = cadPropNode->first_node("Position");
1051  double posX = GetNodeValueDouble(position, "X");
1052  double posY = GetNodeValueDouble(position, "Y");
1053  auto size = cadPropNode->first_node("Size");
1054  double width = GetNodeValueDouble(size, "Width");
1055  double height = GetNodeValueDouble(size, "Height");
1056  double angle = GetNodeValueDouble(cadPropNode, "Angle");
1057  auto nodePosition = cadPropNode->first_node("NodePosition");
1058  double nodePosX = GetNodeValueDouble(nodePosition, "X");
1059  double nodePosY = GetNodeValueDouble(nodePosition, "Y");
1060  int parentID = GetNodeValueInt(cadPropNode, "ParentID");
1061  if(parentID == -1) {
1062  // If the element has no parent, create a temporary one, remove and delete.
1063  Bus* parent = new Bus(wxPoint2DDouble(nodePosX, nodePosY));
1064  capacitor->AddParent(parent, wxPoint2DDouble(nodePosX, nodePosY));
1065  capacitor->StartMove(capacitor->GetPosition());
1066  capacitor->Move(wxPoint2DDouble(posX, posY));
1067  capacitor->RemoveParent(parent);
1068  delete parent;
1069  } else {
1070  Bus* parent = busList[parentID];
1071  capacitor->AddParent(parent, wxPoint2DDouble(nodePosX, nodePosY));
1072  capacitor->StartMove(capacitor->GetPosition());
1073  capacitor->Move(wxPoint2DDouble(posX, posY));
1074  }
1075  capacitor->SetWidth(width);
1076  capacitor->SetHeight(height);
1077 
1078  int numRot = angle / capacitor->GetRotationAngle();
1079  bool clockwise = true;
1080  if(numRot < 0) {
1081  numRot = std::abs(numRot);
1082  clockwise = false;
1083  }
1084  for(int i = 0; i < numRot; i++) capacitor->Rotate(clockwise);
1085 
1086  auto electricalProp = capacitorNode->first_node("ElectricalProperties");
1087  if(!electricalProp) return false;
1088 
1089  capacitor->SetOnline(GetNodeValueInt(electricalProp, "IsOnline"));
1090  CapacitorElectricalData data = capacitor->GetElectricalData();
1091  data.name = electricalProp->first_node("Name")->value();
1092  data.reactivePower = GetNodeValueDouble(electricalProp, "ReactivePower");
1093  data.reactivePowerUnit = (ElectricalUnit)GetAttributeValueInt(electricalProp, "ReactivePower", "UnitID");
1094 
1095  SwitchingData swData;
1096  auto switchingList = electricalProp->first_node("SwitchingList");
1097  if(!switchingList) return false;
1098  auto swNode = switchingList->first_node("Switching");
1099  while(swNode) {
1100  swData.swType.push_back((SwitchingType)GetNodeValueInt(swNode, "Type"));
1101  swData.swTime.push_back(GetNodeValueDouble(swNode, "Time"));
1102  swNode = swNode->next_sibling("Switching");
1103  }
1104  capacitor->SetSwitchingData(swData);
1105 
1106  capacitor->SetElectricalData(data);
1107 
1108  if(swData.swTime.size() != 0) capacitor->SetDynamicEvent(true);
1109 
1110  elementList.push_back(capacitor);
1111  capacitorList.push_back(capacitor);
1112  capacitorNode = capacitorNode->next_sibling("Capacitor");
1113  } //}
1114 
1115  //{ IndMotor
1116  auto indMotorListNode = elementsNode->first_node("IndMotorList");
1117  if(!indMotorListNode) return false;
1118  auto indMotorNode = indMotorListNode->first_node("IndMotor");
1119  while(indMotorNode) {
1120  IndMotor* indMotor = new IndMotor();
1121 
1122  auto cadPropNode = indMotorNode->first_node("CADProperties");
1123  if(!cadPropNode) return false;
1124 
1125  auto position = cadPropNode->first_node("Position");
1126  double posX = GetNodeValueDouble(position, "X");
1127  double posY = GetNodeValueDouble(position, "Y");
1128  auto size = cadPropNode->first_node("Size");
1129  double width = GetNodeValueDouble(size, "Width");
1130  double height = GetNodeValueDouble(size, "Height");
1131  double angle = GetNodeValueDouble(cadPropNode, "Angle");
1132  auto nodePosition = cadPropNode->first_node("NodePosition");
1133  double nodePosX = GetNodeValueDouble(nodePosition, "X");
1134  double nodePosY = GetNodeValueDouble(nodePosition, "Y");
1135  int parentID = GetNodeValueInt(cadPropNode, "ParentID");
1136  if(parentID == -1) {
1137  // If the element has no parent, create a temporary one, remove and delete.
1138  Bus* parent = new Bus(wxPoint2DDouble(nodePosX, nodePosY));
1139  indMotor->AddParent(parent, wxPoint2DDouble(nodePosX, nodePosY));
1140  indMotor->StartMove(indMotor->GetPosition());
1141  indMotor->Move(wxPoint2DDouble(posX, posY));
1142  indMotor->RemoveParent(parent);
1143  delete parent;
1144  } else {
1145  Bus* parent = busList[parentID];
1146  indMotor->AddParent(parent, wxPoint2DDouble(nodePosX, nodePosY));
1147  indMotor->StartMove(indMotor->GetPosition());
1148  indMotor->Move(wxPoint2DDouble(posX, posY));
1149  }
1150  indMotor->SetWidth(width);
1151  indMotor->SetHeight(height);
1152 
1153  int numRot = angle / indMotor->GetRotationAngle();
1154  bool clockwise = true;
1155  if(numRot < 0) {
1156  numRot = std::abs(numRot);
1157  clockwise = false;
1158  }
1159  for(int i = 0; i < numRot; i++) indMotor->Rotate(clockwise);
1160 
1161  auto electricalProp = indMotorNode->first_node("ElectricalProperties");
1162  if(!electricalProp) return false;
1163 
1164  indMotor->SetOnline(GetNodeValueInt(electricalProp, "IsOnline"));
1165  IndMotorElectricalData data = indMotor->GetElectricalData();
1166  data.name = electricalProp->first_node("Name")->value();
1167  data.activePower = GetNodeValueDouble(electricalProp, "ActivePower");
1168  data.activePowerUnit = (ElectricalUnit)GetAttributeValueInt(electricalProp, "ActivePower", "UnitID");
1169  data.reactivePower = GetNodeValueDouble(electricalProp, "ReactivePower");
1170  data.reactivePowerUnit = (ElectricalUnit)GetAttributeValueInt(electricalProp, "ReactivePower", "UnitID");
1171 
1172  indMotor->SetElectricalData(data);
1173  elementList.push_back(indMotor);
1174  indMotorList.push_back(indMotor);
1175  indMotorNode = indMotorNode->next_sibling("IndMotor");
1176  } //}
1177 
1178  //{ Inductor
1179  auto inductorListNode = elementsNode->first_node("InductorList");
1180  if(!inductorListNode) return false;
1181  auto inductorNode = inductorListNode->first_node("Inductor");
1182  while(inductorNode) {
1183  Inductor* inductor = new Inductor();
1184 
1185  auto cadPropNode = inductorNode->first_node("CADProperties");
1186  if(!cadPropNode) return false;
1187 
1188  auto position = cadPropNode->first_node("Position");
1189  double posX = GetNodeValueDouble(position, "X");
1190  double posY = GetNodeValueDouble(position, "Y");
1191  auto size = cadPropNode->first_node("Size");
1192  double width = GetNodeValueDouble(size, "Width");
1193  double height = GetNodeValueDouble(size, "Height");
1194  double angle = GetNodeValueDouble(cadPropNode, "Angle");
1195  auto nodePosition = cadPropNode->first_node("NodePosition");
1196  double nodePosX = GetNodeValueDouble(nodePosition, "X");
1197  double nodePosY = GetNodeValueDouble(nodePosition, "Y");
1198  int parentID = GetNodeValueInt(cadPropNode, "ParentID");
1199  if(parentID == -1) {
1200  // If the element has no parent, create a temporary one, remove and delete.
1201  Bus* parent = new Bus(wxPoint2DDouble(nodePosX, nodePosY));
1202  inductor->AddParent(parent, wxPoint2DDouble(nodePosX, nodePosY));
1203  inductor->StartMove(inductor->GetPosition());
1204  inductor->Move(wxPoint2DDouble(posX, posY));
1205  inductor->RemoveParent(parent);
1206  delete parent;
1207  } else {
1208  Bus* parent = busList[parentID];
1209  inductor->AddParent(parent, wxPoint2DDouble(nodePosX, nodePosY));
1210  inductor->StartMove(inductor->GetPosition());
1211  inductor->Move(wxPoint2DDouble(posX, posY));
1212  }
1213  inductor->SetWidth(width);
1214  inductor->SetHeight(height);
1215 
1216  int numRot = angle / inductor->GetRotationAngle();
1217  bool clockwise = true;
1218  if(numRot < 0) {
1219  numRot = std::abs(numRot);
1220  clockwise = false;
1221  }
1222  for(int i = 0; i < numRot; i++) inductor->Rotate(clockwise);
1223 
1224  auto electricalProp = inductorNode->first_node("ElectricalProperties");
1225  if(!electricalProp) return false;
1226 
1227  inductor->SetOnline(GetNodeValueInt(electricalProp, "IsOnline"));
1228  InductorElectricalData data = inductor->GetElectricalData();
1229  data.name = electricalProp->first_node("Name")->value();
1230  data.reactivePower = GetNodeValueDouble(electricalProp, "ReactivePower");
1231  data.reactivePowerUnit = (ElectricalUnit)GetAttributeValueInt(electricalProp, "ReactivePower", "UnitID");
1232 
1233  SwitchingData swData;
1234  auto switchingList = electricalProp->first_node("SwitchingList");
1235  if(!switchingList) return false;
1236  auto swNode = switchingList->first_node("Switching");
1237  while(swNode) {
1238  swData.swType.push_back((SwitchingType)GetNodeValueInt(swNode, "Type"));
1239  swData.swTime.push_back(GetNodeValueDouble(swNode, "Time"));
1240  swNode = swNode->next_sibling("Switching");
1241  }
1242  inductor->SetSwitchingData(swData);
1243 
1244  inductor->SetElectricalData(data);
1245 
1246  if(swData.swTime.size() != 0) inductor->SetDynamicEvent(true);
1247 
1248  elementList.push_back(inductor);
1249  inductorList.push_back(inductor);
1250  inductorNode = inductorNode->next_sibling("Inductor");
1251  } //}
1252 
1253  //{ Line
1254  auto lineListNode = elementsNode->first_node("LineList");
1255  if(!lineListNode) return false;
1256  auto lineNode = lineListNode->first_node("Line");
1257  while(lineNode) {
1258  Line* line = new Line();
1259 
1260  auto cadPropNode = lineNode->first_node("CADProperties");
1261  if(!cadPropNode) return false;
1262 
1263  // Get nodes points
1264  std::vector<wxPoint2DDouble> ptsList;
1265  auto nodePosList = cadPropNode->first_node("NodeList");
1266  if(!nodePosList) return false;
1267  auto nodePos = nodePosList->first_node("Node");
1268  while(nodePos) {
1269  double nodePosX = GetNodeValueDouble(nodePos, "X");
1270  double nodePosY = GetNodeValueDouble(nodePos, "Y");
1271  ptsList.push_back(wxPoint2DDouble(nodePosX, nodePosY));
1272  nodePos = nodePos->next_sibling("Node");
1273  }
1274 
1275  // Get parents IDs
1276  auto parentIDList = cadPropNode->first_node("ParentIDList");
1277  if(!parentIDList) return false;
1278  auto parentNode = parentIDList->first_node("ParentID");
1279  long parentID[2] = {-1, -1};
1280  while(parentNode) {
1281  long index = 0;
1282  wxString(parentNode->first_attribute("ID")->value()).ToLong(&index);
1283  wxString(parentNode->value()).ToCLong(&parentID[index]);
1284  parentNode = parentNode->next_sibling("ParentID");
1285  }
1286 
1287  // Set parents (if have)
1288  Bus *parent1, *parent2;
1289  if(parentID[0] == -1) {
1290  parent1 = new Bus(ptsList[0]);
1291  line->AddParent(parent1, ptsList[0]);
1292  } else {
1293  parent1 = busList[parentID[0]];
1294  line->AddParent(parent1, ptsList[0]);
1295  }
1296  if(parentID[1] == -1) {
1297  parent2 = new Bus(ptsList[ptsList.size() - 1]);
1298  line->AddParent(parent2, ptsList[ptsList.size() - 1]);
1299  } else {
1300  parent2 = busList[parentID[1]];
1301  line->AddParent(parent2, ptsList[ptsList.size() - 1]);
1302  }
1303 
1304  // Add the others nodes (if have)
1305  std::vector<wxPoint2DDouble> midPts;
1306  for(int i = 1; i < (int)ptsList.size() - 1; i++) midPts.push_back(ptsList[i]);
1307  std::vector<wxPoint2DDouble> edgesPts = line->GetPointList();
1308  edgesPts.insert(edgesPts.begin() + 2, midPts.begin(), midPts.end());
1309  line->SetPointList(edgesPts);
1310 
1311  if(parentID[0] == -1) {
1312  line->RemoveParent(parent1);
1313  delete parent1;
1314  }
1315  if(parentID[1] == -1) {
1316  line->RemoveParent(parent2);
1317  delete parent2;
1318  }
1319 
1320  auto electricalProp = lineNode->first_node("ElectricalProperties");
1321  if(!electricalProp) return false;
1322 
1323  line->SetOnline(GetNodeValueInt(electricalProp, "IsOnline"));
1324  LineElectricalData data = line->GetElectricalData();
1325  data.name = electricalProp->first_node("Name")->value();
1326  data.nominalVoltage = GetNodeValueDouble(electricalProp, "NominalVoltage");
1327  data.nominalVoltageUnit = (ElectricalUnit)GetAttributeValueInt(electricalProp, "NominalVoltage", "UnitID");
1328  data.nominalPower = GetNodeValueDouble(electricalProp, "NominalPower");
1329  data.nominalPowerUnit = (ElectricalUnit)GetAttributeValueInt(electricalProp, "NominalPower", "UnitID");
1330  data.resistance = GetNodeValueDouble(electricalProp, "Resistance");
1331  data.resistanceUnit = (ElectricalUnit)GetAttributeValueInt(electricalProp, "Resistance", "UnitID");
1332  data.indReactance = GetNodeValueDouble(electricalProp, "IndReactance");
1333  data.indReactanceUnit = (ElectricalUnit)GetAttributeValueInt(electricalProp, "IndReactance", "UnitID");
1334  data.capSusceptance = GetNodeValueDouble(electricalProp, "CapSusceptance");
1335  data.capSusceptanceUnit = (ElectricalUnit)GetAttributeValueInt(electricalProp, "CapSusceptance", "UnitID");
1336  data.lineSize = GetNodeValueDouble(electricalProp, "LineSize");
1337  data.useLinePower = GetNodeValueInt(electricalProp, "UseLinePower");
1338 
1339  auto fault = electricalProp->first_node("Fault");
1340  data.zeroResistance = GetNodeValueDouble(fault, "ZeroResistance");
1341  data.zeroIndReactance = GetNodeValueDouble(fault, "ZeroIndReactance");
1342  data.zeroCapSusceptance = GetNodeValueDouble(fault, "ZeroCapSusceptance");
1343 
1344  SwitchingData swData;
1345  auto switchingList = electricalProp->first_node("SwitchingList");
1346  if(!switchingList) return false;
1347  auto swNode = switchingList->first_node("Switching");
1348  while(swNode) {
1349  swData.swType.push_back((SwitchingType)GetNodeValueInt(swNode, "Type"));
1350  swData.swTime.push_back(GetNodeValueDouble(swNode, "Time"));
1351  swNode = swNode->next_sibling("Switching");
1352  }
1353  line->SetSwitchingData(swData);
1354 
1355  line->SetElectricalData(data);
1356 
1357  if(swData.swTime.size() != 0) line->SetDynamicEvent(true);
1358 
1359  elementList.push_back(line);
1360  lineList.push_back(line);
1361  lineNode = lineNode->next_sibling("Line");
1362  } //}
1363 
1364  //{ Load
1365  auto loadListNode = elementsNode->first_node("LoadList");
1366  if(!loadListNode) return false;
1367  auto loadNode = loadListNode->first_node("Load");
1368  while(loadNode) {
1369  Load* load = new Load();
1370 
1371  auto cadPropNode = loadNode->first_node("CADProperties");
1372  if(!cadPropNode) return false;
1373 
1374  auto position = cadPropNode->first_node("Position");
1375  double posX = GetNodeValueDouble(position, "X");
1376  double posY = GetNodeValueDouble(position, "Y");
1377  auto size = cadPropNode->first_node("Size");
1378  double width = GetNodeValueDouble(size, "Width");
1379  double height = GetNodeValueDouble(size, "Height");
1380  double angle = GetNodeValueDouble(cadPropNode, "Angle");
1381  auto nodePosition = cadPropNode->first_node("NodePosition");
1382  double nodePosX = GetNodeValueDouble(nodePosition, "X");
1383  double nodePosY = GetNodeValueDouble(nodePosition, "Y");
1384  int parentID = GetNodeValueInt(cadPropNode, "ParentID");
1385  if(parentID == -1) {
1386  // If the element has no parent, create a temporary one, remove and delete.
1387  Bus* parent = new Bus(wxPoint2DDouble(nodePosX, nodePosY));
1388  load->AddParent(parent, wxPoint2DDouble(nodePosX, nodePosY));
1389  load->StartMove(load->GetPosition());
1390  load->Move(wxPoint2DDouble(posX, posY));
1391  load->RemoveParent(parent);
1392  delete parent;
1393  } else {
1394  Bus* parent = busList[parentID];
1395  load->AddParent(parent, wxPoint2DDouble(nodePosX, nodePosY));
1396  load->StartMove(load->GetPosition());
1397  load->Move(wxPoint2DDouble(posX, posY));
1398  }
1399  load->SetWidth(width);
1400  load->SetHeight(height);
1401 
1402  int numRot = angle / load->GetRotationAngle();
1403  bool clockwise = true;
1404  if(numRot < 0) {
1405  numRot = std::abs(numRot);
1406  clockwise = false;
1407  }
1408  for(int i = 0; i < numRot; i++) load->Rotate(clockwise);
1409 
1410  auto electricalProp = loadNode->first_node("ElectricalProperties");
1411  if(!electricalProp) return false;
1412 
1413  load->SetOnline(GetNodeValueInt(electricalProp, "IsOnline"));
1414  LoadElectricalData data = load->GetElectricalData();
1415  data.name = electricalProp->first_node("Name")->value();
1416  data.activePower = GetNodeValueDouble(electricalProp, "ActivePower");
1417  data.activePowerUnit = (ElectricalUnit)GetAttributeValueInt(electricalProp, "ActivePower", "UnitID");
1418  data.reactivePower = GetNodeValueDouble(electricalProp, "ReactivePower");
1419  data.reactivePowerUnit = (ElectricalUnit)GetAttributeValueInt(electricalProp, "ReactivePower", "UnitID");
1420  data.loadType = (LoadType)GetNodeValueInt(electricalProp, "LoadType");
1421  // Stability
1422  auto stability = electricalProp->first_node("Stability");
1423  if(stability) {
1424  data.plotLoad = GetNodeValueInt(stability, "PlotLoad");
1425  data.useCompLoad = GetNodeValueInt(stability, "UseCompositeLoad");
1426  auto activePowerComp = stability->first_node("ActivePowerComposition");
1427  data.constImpedanceActive = GetNodeValueDouble(activePowerComp, "ConstantImpedance");
1428  data.constCurrentActive = GetNodeValueDouble(activePowerComp, "ConstantCurrent");
1429  data.constPowerActive = GetNodeValueDouble(activePowerComp, "ConstantPower");
1430  auto reactivePowerComp = stability->first_node("ReactivePowerComposition");
1431  data.constImpedanceReactive = GetNodeValueDouble(reactivePowerComp, "ConstantImpedance");
1432  data.constCurrentReactive = GetNodeValueDouble(reactivePowerComp, "ConstantCurrent");
1433  data.constPowerReactive = GetNodeValueDouble(reactivePowerComp, "ConstantPower");
1434  }
1435 
1436  SwitchingData swData;
1437  auto switchingList = electricalProp->first_node("SwitchingList");
1438  if(!switchingList) return false;
1439  auto swNode = switchingList->first_node("Switching");
1440  while(swNode) {
1441  swData.swType.push_back((SwitchingType)GetNodeValueInt(swNode, "Type"));
1442  swData.swTime.push_back(GetNodeValueDouble(swNode, "Time"));
1443  swNode = swNode->next_sibling("Switching");
1444  }
1445  load->SetSwitchingData(swData);
1446 
1447  load->SetElectricalData(data);
1448 
1449  if(swData.swTime.size() != 0) load->SetDynamicEvent(true);
1450 
1451  elementList.push_back(load);
1452  loadList.push_back(load);
1453  loadNode = loadNode->next_sibling("Load");
1454  } //}
1455 
1456  //{ SyncGenerator
1457  auto syncGeneratorListNode = elementsNode->first_node("SyncGeneratorList");
1458  if(!syncGeneratorListNode) return false;
1459  auto syncGeneratorNode = syncGeneratorListNode->first_node("SyncGenerator");
1460  while(syncGeneratorNode) {
1461  SyncGenerator* syncGenerator = new SyncGenerator();
1462 
1463  auto cadPropNode = syncGeneratorNode->first_node("CADProperties");
1464  if(!cadPropNode) return false;
1465 
1466  auto position = cadPropNode->first_node("Position");
1467  double posX = GetNodeValueDouble(position, "X");
1468  double posY = GetNodeValueDouble(position, "Y");
1469  auto size = cadPropNode->first_node("Size");
1470  double width = GetNodeValueDouble(size, "Width");
1471  double height = GetNodeValueDouble(size, "Height");
1472  double angle = GetNodeValueDouble(cadPropNode, "Angle");
1473  auto nodePosition = cadPropNode->first_node("NodePosition");
1474  double nodePosX = GetNodeValueDouble(nodePosition, "X");
1475  double nodePosY = GetNodeValueDouble(nodePosition, "Y");
1476  int parentID = GetNodeValueInt(cadPropNode, "ParentID");
1477  if(parentID == -1) {
1478  // If the element has no parent, create a temporary one, remove and delete.
1479  Bus* parent = new Bus(wxPoint2DDouble(nodePosX, nodePosY));
1480  syncGenerator->AddParent(parent, wxPoint2DDouble(nodePosX, nodePosY));
1481  syncGenerator->StartMove(syncGenerator->GetPosition());
1482  syncGenerator->Move(wxPoint2DDouble(posX, posY));
1483  syncGenerator->RemoveParent(parent);
1484  delete parent;
1485  } else {
1486  Bus* parent = busList[parentID];
1487  syncGenerator->AddParent(parent, wxPoint2DDouble(nodePosX, nodePosY));
1488  syncGenerator->StartMove(syncGenerator->GetPosition());
1489  syncGenerator->Move(wxPoint2DDouble(posX, posY));
1490  }
1491  syncGenerator->SetWidth(width);
1492  syncGenerator->SetHeight(height);
1493 
1494  int numRot = angle / syncGenerator->GetRotationAngle();
1495  bool clockwise = true;
1496  if(numRot < 0) {
1497  numRot = std::abs(numRot);
1498  clockwise = false;
1499  }
1500  for(int i = 0; i < numRot; i++) syncGenerator->Rotate(clockwise);
1501 
1502  auto electricalProp = syncGeneratorNode->first_node("ElectricalProperties");
1503  if(!electricalProp) return false;
1504 
1505  syncGenerator->SetOnline(GetNodeValueInt(electricalProp, "IsOnline"));
1506  SyncGeneratorElectricalData data = syncGenerator->GetElectricalData();
1507  data.name = electricalProp->first_node("Name")->value();
1508  data.nominalPower = GetNodeValueDouble(electricalProp, "NominalPower");
1509  data.nominalPowerUnit = (ElectricalUnit)GetAttributeValueInt(electricalProp, "NominalPower", "UnitID");
1510  data.nominalVoltage = GetNodeValueDouble(electricalProp, "NominalVoltage");
1511  data.nominalVoltageUnit = (ElectricalUnit)GetAttributeValueInt(electricalProp, "NominalVoltage", "UnitID");
1512  data.activePower = GetNodeValueDouble(electricalProp, "ActivePower");
1513  data.activePowerUnit = (ElectricalUnit)GetAttributeValueInt(electricalProp, "ActivePower", "UnitID");
1514  data.reactivePower = GetNodeValueDouble(electricalProp, "ReactivePower");
1515  data.reactivePowerUnit = (ElectricalUnit)GetAttributeValueInt(electricalProp, "ReactivePower", "UnitID");
1516  data.haveMaxReactive = GetNodeValueInt(electricalProp, "HaveMaxReactive");
1517  data.maxReactive = GetNodeValueDouble(electricalProp, "MaxReactive");
1518  data.maxReactiveUnit = (ElectricalUnit)GetAttributeValueInt(electricalProp, "MaxReactive", "UnitID");
1519  data.haveMinReactive = GetNodeValueInt(electricalProp, "HaveMinReactive");
1520  data.minReactive = GetNodeValueDouble(electricalProp, "MinReactive");
1521  data.minReactiveUnit = (ElectricalUnit)GetAttributeValueInt(electricalProp, "MinReactive", "UnitID");
1522  data.useMachineBase = GetNodeValueInt(electricalProp, "UseMachineBase");
1523 
1524  auto fault = electricalProp->first_node("Fault");
1525  if(!fault) return false;
1526  data.positiveResistance = GetNodeValueDouble(fault, "PositiveResistance");
1527  data.positiveReactance = GetNodeValueDouble(fault, "PositiveReactance");
1528  data.negativeResistance = GetNodeValueDouble(fault, "NegativeResistance");
1529  data.negativeReactance = GetNodeValueDouble(fault, "NegativeReactance");
1530  data.zeroResistance = GetNodeValueDouble(fault, "ZeroResistance");
1531  data.zeroReactance = GetNodeValueDouble(fault, "ZeroReactance");
1532  data.groundResistance = GetNodeValueDouble(fault, "GroundResistance");
1533  data.groundReactance = GetNodeValueDouble(fault, "GroundReactance");
1534  data.groundNeutral = GetNodeValueInt(fault, "GroundNeutral");
1535 
1536  auto stability = electricalProp->first_node("Stability");
1537  if(!stability) return false;
1538  data.plotSyncMachine = GetNodeValueInt(stability, "PlotSyncMachine");
1539  data.inertia = GetNodeValueDouble(stability, "Inertia");
1540  data.damping = GetNodeValueDouble(stability, "Damping");
1541  data.useAVR = GetNodeValueInt(stability, "UseAVR");
1542  data.useSpeedGovernor = GetNodeValueInt(stability, "UseSpeedGovernor");
1543  data.armResistance = GetNodeValueDouble(stability, "ArmResistance");
1544  data.potierReactance = GetNodeValueDouble(stability, "PotierReactance");
1545  data.satFactor = GetNodeValueDouble(stability, "SatFactor");
1546  data.syncXd = GetNodeValueDouble(stability, "SyncXd");
1547  data.syncXq = GetNodeValueDouble(stability, "SyncXq");
1548  data.transXd = GetNodeValueDouble(stability, "TransXd");
1549  data.transXq = GetNodeValueDouble(stability, "TransXq");
1550  data.transTd0 = GetNodeValueDouble(stability, "TransTd0");
1551  data.transTq0 = GetNodeValueDouble(stability, "TransTq0");
1552  data.subXd = GetNodeValueDouble(stability, "SubXd");
1553  data.subXq = GetNodeValueDouble(stability, "SubXq");
1554  data.subTd0 = GetNodeValueDouble(stability, "SubTd0");
1555  data.subTq0 = GetNodeValueDouble(stability, "SubTq0");
1556 
1557  auto avr = stability->first_node("AVR");
1558  if(!avr) return false;
1559  if(!OpenControlElements(doc, avr, data.avr)) return false;
1560 
1561  auto speedGov = stability->first_node("SpeedGovernor");
1562  if(!speedGov) return false;
1563  if(!OpenControlElements(doc, speedGov, data.speedGov)) return false;
1564 
1565  SwitchingData swData;
1566  auto switchingList = electricalProp->first_node("SwitchingList");
1567  if(!switchingList) return false;
1568  auto swNode = switchingList->first_node("Switching");
1569  while(swNode) {
1570  swData.swType.push_back((SwitchingType)GetNodeValueInt(swNode, "Type"));
1571  swData.swTime.push_back(GetNodeValueDouble(swNode, "Time"));
1572  swNode = swNode->next_sibling("Switching");
1573  }
1574  syncGenerator->SetSwitchingData(swData);
1575 
1576  syncGenerator->SetElectricalData(data);
1577 
1578  if(swData.swTime.size() != 0) syncGenerator->SetDynamicEvent(true);
1579 
1580  elementList.push_back(syncGenerator);
1581  syncGeneratorList.push_back(syncGenerator);
1582  syncGeneratorNode = syncGeneratorNode->next_sibling("SyncGenerator");
1583  } //}
1584 
1585  //{ SyncMotor
1586  auto syncMotorListNode = elementsNode->first_node("SyncMotorList");
1587  if(!syncMotorListNode) return false;
1588  auto syncMotorNode = syncMotorListNode->first_node("SyncMotor");
1589  while(syncMotorNode) {
1590  SyncMotor* syncMotor = new SyncMotor();
1591 
1592  auto cadPropNode = syncMotorNode->first_node("CADProperties");
1593  if(!cadPropNode) return false;
1594 
1595  auto position = cadPropNode->first_node("Position");
1596  double posX = GetNodeValueDouble(position, "X");
1597  double posY = GetNodeValueDouble(position, "Y");
1598  auto size = cadPropNode->first_node("Size");
1599  double width = GetNodeValueDouble(size, "Width");
1600  double height = GetNodeValueDouble(size, "Height");
1601  double angle = GetNodeValueDouble(cadPropNode, "Angle");
1602  auto nodePosition = cadPropNode->first_node("NodePosition");
1603  double nodePosX = GetNodeValueDouble(nodePosition, "X");
1604  double nodePosY = GetNodeValueDouble(nodePosition, "Y");
1605  int parentID = GetNodeValueInt(cadPropNode, "ParentID");
1606  if(parentID == -1) {
1607  // If the element has no parent, create a temporary one, remove and delete.
1608  Bus* parent = new Bus(wxPoint2DDouble(nodePosX, nodePosY));
1609  syncMotor->AddParent(parent, wxPoint2DDouble(nodePosX, nodePosY));
1610  syncMotor->StartMove(syncMotor->GetPosition());
1611  syncMotor->Move(wxPoint2DDouble(posX, posY));
1612  syncMotor->RemoveParent(parent);
1613  delete parent;
1614  } else {
1615  Bus* parent = busList[parentID];
1616  syncMotor->AddParent(parent, wxPoint2DDouble(nodePosX, nodePosY));
1617  syncMotor->StartMove(syncMotor->GetPosition());
1618  syncMotor->Move(wxPoint2DDouble(posX, posY));
1619  }
1620  syncMotor->SetWidth(width);
1621  syncMotor->SetHeight(height);
1622 
1623  int numRot = angle / syncMotor->GetRotationAngle();
1624  bool clockwise = true;
1625  if(numRot < 0) {
1626  numRot = std::abs(numRot);
1627  clockwise = false;
1628  }
1629  for(int i = 0; i < numRot; i++) syncMotor->Rotate(clockwise);
1630 
1631  auto electricalProp = syncMotorNode->first_node("ElectricalProperties");
1632  if(!electricalProp) return false;
1633 
1634  syncMotor->SetOnline(GetNodeValueInt(electricalProp, "IsOnline"));
1635  SyncMotorElectricalData data = syncMotor->GetElectricalData();
1636  data.name = electricalProp->first_node("Name")->value();
1637  data.nominalPower = GetNodeValueDouble(electricalProp, "NominalPower");
1638  data.nominalPowerUnit = (ElectricalUnit)GetAttributeValueInt(electricalProp, "NominalPower", "UnitID");
1639  // data.nominalVoltage = GetNodeValueDouble(electricalProp, "NominalVoltage");
1640  // data.nominalVoltageUnit = (ElectricalUnit)GetAttributeValueInt(electricalProp, "NominalVoltage", "UnitID");
1641  data.activePower = GetNodeValueDouble(electricalProp, "ActivePower");
1642  data.activePowerUnit = (ElectricalUnit)GetAttributeValueInt(electricalProp, "ActivePower", "UnitID");
1643  data.reactivePower = GetNodeValueDouble(electricalProp, "ReactivePower");
1644  data.reactivePowerUnit = (ElectricalUnit)GetAttributeValueInt(electricalProp, "ReactivePower", "UnitID");
1645  data.haveMaxReactive = GetNodeValueInt(electricalProp, "HaveMaxReactive");
1646  data.maxReactive = GetNodeValueDouble(electricalProp, "MaxReactive");
1647  data.maxReactiveUnit = (ElectricalUnit)GetAttributeValueInt(electricalProp, "MaxReactive", "UnitID");
1648  data.haveMinReactive = GetNodeValueInt(electricalProp, "HaveMinReactive");
1649  data.minReactive = GetNodeValueDouble(electricalProp, "MinReactive");
1650  data.minReactiveUnit = (ElectricalUnit)GetAttributeValueInt(electricalProp, "MinReactive", "UnitID");
1651  data.useMachineBase = GetNodeValueInt(electricalProp, "UseMachineBase");
1652 
1653  auto fault = electricalProp->first_node("Fault");
1654  if(!fault) return false;
1655  data.positiveResistance = GetNodeValueDouble(fault, "PositiveResistance");
1656  data.positiveReactance = GetNodeValueDouble(fault, "PositiveReactance");
1657  data.negativeResistance = GetNodeValueDouble(fault, "NegativeResistance");
1658  data.negativeReactance = GetNodeValueDouble(fault, "NegativeReactance");
1659  data.zeroResistance = GetNodeValueDouble(fault, "ZeroResistance");
1660  data.zeroReactance = GetNodeValueDouble(fault, "ZeroReactance");
1661  data.groundResistance = GetNodeValueDouble(fault, "GroundResistance");
1662  data.groundReactance = GetNodeValueDouble(fault, "GroundReactance");
1663  data.groundNeutral = GetNodeValueInt(fault, "GroundNeutral");
1664 
1665  /*SwitchingData swData;
1666  auto switchingList = electricalProp->first_node("SwitchingList");
1667  if(!switchingList) return false;
1668  auto swNode = switchingList->first_node("Switching");
1669  while(swNode) {
1670  swData.swType.push_back((SwitchingType)GetNodeValueInt(swNode, "Type"));
1671  swData.swTime.push_back(GetNodeValueDouble(swNode, "Time"));
1672  swNode = swNode->next_sibling("Switching");
1673  }
1674  syncMotor->SetSwitchingData(swData);*/
1675 
1676  syncMotor->SetElectricalData(data);
1677  elementList.push_back(syncMotor);
1678  syncMotorList.push_back(syncMotor);
1679  syncMotorNode = syncMotorNode->next_sibling("SyncMotor");
1680  } //}
1681 
1682  //{ Transformer
1683  auto transformerListNode = elementsNode->first_node("TransformerList");
1684  if(!transformerListNode) return false;
1685  auto transfomerNode = transformerListNode->first_node("Transfomer");
1686  while(transfomerNode) {
1687  Transformer* transformer = new Transformer();
1688 
1689  auto cadPropNode = transfomerNode->first_node("CADProperties");
1690  if(!cadPropNode) return false;
1691 
1692  auto position = cadPropNode->first_node("Position");
1693  double posX = GetNodeValueDouble(position, "X");
1694  double posY = GetNodeValueDouble(position, "Y");
1695  auto size = cadPropNode->first_node("Size");
1696  double width = GetNodeValueDouble(size, "Width");
1697  double height = GetNodeValueDouble(size, "Height");
1698  double angle = GetNodeValueDouble(cadPropNode, "Angle");
1699 
1700  // Get nodes points
1701  std::vector<wxPoint2DDouble> ptsList;
1702  auto nodePosList = cadPropNode->first_node("NodeList");
1703  if(!nodePosList) return false;
1704  auto nodePos = nodePosList->first_node("Node");
1705  while(nodePos) {
1706  double nodePosX = GetNodeValueDouble(nodePos, "X");
1707  double nodePosY = GetNodeValueDouble(nodePos, "Y");
1708  ptsList.push_back(wxPoint2DDouble(nodePosX, nodePosY));
1709  nodePos = nodePos->next_sibling("Node");
1710  }
1711 
1712  // Get parents IDs
1713  auto parentIDList = cadPropNode->first_node("ParentIDList");
1714  if(!parentIDList) return false;
1715  auto parentNode = parentIDList->first_node("ParentID");
1716  long parentID[2] = {-1, -1};
1717  while(parentNode) {
1718  long index = 0;
1719  wxString(parentNode->first_attribute("ID")->value()).ToLong(&index);
1720  wxString(parentNode->value()).ToCLong(&parentID[index]);
1721  parentNode = parentNode->next_sibling("ParentID");
1722  }
1723 
1724  // Set parents (if have)
1725  Bus *parent1, *parent2;
1726  if(parentID[0] == -1) {
1727  parent1 = new Bus(ptsList[0]);
1728  transformer->AddParent(parent1, ptsList[0]);
1729  } else {
1730  parent1 = busList[parentID[0]];
1731  transformer->AddParent(parent1, ptsList[0]);
1732  }
1733  if(parentID[1] == -1) {
1734  parent2 = new Bus(ptsList[ptsList.size() - 1]);
1735  transformer->AddParent(parent2, ptsList[ptsList.size() - 1]);
1736  } else {
1737  parent2 = busList[parentID[1]];
1738  transformer->AddParent(parent2, ptsList[ptsList.size() - 1]);
1739  }
1740 
1741  transformer->StartMove(transformer->GetPosition());
1742  transformer->Move(wxPoint2DDouble(posX, posY));
1743 
1744  if(parentID[0] == -1) {
1745  transformer->RemoveParent(parent1);
1746  delete parent1;
1747  }
1748  if(parentID[1] == -1) {
1749  transformer->RemoveParent(parent2);
1750  delete parent2;
1751  }
1752 
1753  transformer->SetWidth(width);
1754  transformer->SetHeight(height);
1755 
1756  int numRot = angle / transformer->GetRotationAngle();
1757  bool clockwise = true;
1758  if(numRot < 0) {
1759  numRot = std::abs(numRot);
1760  clockwise = false;
1761  }
1762  for(int i = 0; i < numRot; i++) transformer->Rotate(clockwise);
1763 
1764  auto electricalProp = transfomerNode->first_node("ElectricalProperties");
1765  if(!electricalProp) return false;
1766 
1767  transformer->SetOnline(GetNodeValueInt(electricalProp, "IsOnline"));
1768  TransformerElectricalData data = transformer->GetElectricalData();
1769  data.name = electricalProp->first_node("Name")->value();
1770  data.primaryNominalVoltage = GetNodeValueDouble(electricalProp, "PrimaryNominalVoltage");
1771  data.primaryNominalVoltageUnit =
1772  (ElectricalUnit)GetAttributeValueInt(electricalProp, "PrimaryNominalVoltage", "UnitID");
1773  data.secondaryNominalVoltage = GetNodeValueDouble(electricalProp, "SecondaryNominalVoltage");
1774  data.secondaryNominalVoltageUnit =
1775  (ElectricalUnit)GetAttributeValueInt(electricalProp, "SecondaryNominalVoltage", "UnitID");
1776  data.nominalPower = GetNodeValueDouble(electricalProp, "NominalPower");
1777  data.nominalPowerUnit = (ElectricalUnit)GetAttributeValueInt(electricalProp, "NominalPower", "UnitID");
1778  data.resistance = GetNodeValueDouble(electricalProp, "Resistance");
1779  data.resistanceUnit = (ElectricalUnit)GetAttributeValueInt(electricalProp, "Resistance", "UnitID");
1780  data.indReactance = GetNodeValueDouble(electricalProp, "IndReactance");
1781  data.indReactanceUnit = (ElectricalUnit)GetAttributeValueInt(electricalProp, "IndReactance", "UnitID");
1782  data.connection = (TransformerConnection)GetNodeValueInt(electricalProp, "Connection");
1783  data.turnsRatio = GetNodeValueDouble(electricalProp, "TurnsRatio");
1784  data.phaseShift = GetNodeValueDouble(electricalProp, "PhaseShift");
1785  data.useTransformerPower = GetNodeValueInt(electricalProp, "UseTransfomerPower");
1786 
1787  auto fault = electricalProp->first_node("Fault");
1788  data.zeroResistance = GetNodeValueDouble(fault, "ZeroResistance");
1789  data.zeroIndReactance = GetNodeValueDouble(fault, "ZeroIndReactance");
1790  data.primaryGrndResistance = GetNodeValueDouble(fault, "PrimaryGrndResistance");
1791  data.primaryGrndReactance = GetNodeValueDouble(fault, "PrimaryGrndReactance");
1792  data.secondaryGrndResistance = GetNodeValueDouble(fault, "SecondaryGrndResistance");
1793  data.secondaryGrndReactance = GetNodeValueDouble(fault, "SecondaryGrndReactance");
1794 
1795  SwitchingData swData;
1796  auto switchingList = electricalProp->first_node("SwitchingList");
1797  if(!switchingList) return false;
1798  auto swNode = switchingList->first_node("Switching");
1799  while(swNode) {
1800  swData.swType.push_back((SwitchingType)GetNodeValueInt(swNode, "Type"));
1801  swData.swTime.push_back(GetNodeValueDouble(swNode, "Time"));
1802  swNode = swNode->next_sibling("Switching");
1803  }
1804  transformer->SetSwitchingData(swData);
1805 
1806  transformer->SetElectricaData(data);
1807 
1808  if(swData.swTime.size() != 0) transformer->SetDynamicEvent(true);
1809 
1810  elementList.push_back(transformer);
1811  transformerList.push_back(transformer);
1812  transfomerNode = transfomerNode->next_sibling("Transfomer");
1813  } //}
1814 
1815  m_workspace->SetElementList(elementList);
1816 
1817  //{ Text
1818  auto textListNode = elementsNode->first_node("TextList");
1819  if(!textListNode) return false;
1820  auto textNode = textListNode->first_node("Text");
1821  while(textNode) {
1822  auto cadPropNode = textNode->first_node("CADProperties");
1823  if(!cadPropNode) return false;
1824 
1825  auto position = cadPropNode->first_node("Position");
1826  double posX = GetNodeValueDouble(position, "X");
1827  double posY = GetNodeValueDouble(position, "Y");
1828  auto size = cadPropNode->first_node("Size");
1829  double width = GetNodeValueDouble(size, "Width");
1830  double height = GetNodeValueDouble(size, "Height");
1831  double angle = GetNodeValueDouble(cadPropNode, "Angle");
1832 
1833  Text* text = new Text(wxPoint2DDouble(posX, posY));
1834 
1835  text->SetWidth(width);
1836  text->SetHeight(height);
1837 
1838  auto textProperties = textNode->first_node("TextProperties");
1839  if(!textProperties) return false;
1840 
1841  text->SetElementType((ElementType)GetNodeValueDouble(textProperties, "ElementType"));
1842  text->SetDataType((DataType)GetNodeValueDouble(textProperties, "DataType"));
1843  text->SetUnit((ElectricalUnit)GetNodeValueDouble(textProperties, "DataUnit"));
1844  text->SetDirection(GetNodeValueDouble(textProperties, "Direction"));
1845  text->SetDecimalPlaces(GetNodeValueDouble(textProperties, "DecimalPlaces"));
1846 
1847  text->SetElementNumber(GetNodeValueInt(textProperties, "ElementNumber"));
1848  switch(text->GetElementType()) {
1849  case TYPE_NONE:
1850  break;
1851  case TYPE_BUS: {
1852  Bus* bus = busList[text->GetElementNumber()];
1853  text->SetElement(bus);
1854  } break;
1855  case TYPE_CAPACITOR: {
1856  Capacitor* capacitor = capacitorList[text->GetElementNumber()];
1857  text->SetElement(capacitor);
1858  } break;
1859  case TYPE_IND_MOTOR: {
1860  IndMotor* indMotor = indMotorList[text->GetElementNumber()];
1861  text->SetElement(indMotor);
1862  } break;
1863  case TYPE_INDUCTOR: {
1864  Inductor* inductor = inductorList[text->GetElementNumber()];
1865  text->SetElement(inductor);
1866  } break;
1867  case TYPE_LINE: {
1868  Line* line = lineList[text->GetElementNumber()];
1869  text->SetElement(line);
1870  } break;
1871  case TYPE_LOAD: {
1872  Load* load = loadList[text->GetElementNumber()];
1873  text->SetElement(load);
1874  } break;
1875  case TYPE_SYNC_GENERATOR: {
1876  SyncGenerator* syncGenerator = syncGeneratorList[text->GetElementNumber()];
1877  text->SetElement(syncGenerator);
1878  } break;
1879  case TYPE_SYNC_MOTOR: {
1880  SyncMotor* syncMotor = syncMotorList[text->GetElementNumber()];
1881  text->SetElement(syncMotor);
1882  } break;
1883  case TYPE_TRANSFORMER: {
1884  Transformer* transformer = transformerList[text->GetElementNumber()];
1885  text->SetElement(transformer);
1886  } break;
1887  }
1888 
1889  int numRot = angle / text->GetRotationAngle();
1890  bool clockwise = true;
1891  if(numRot < 0) {
1892  numRot = std::abs(numRot);
1893  clockwise = false;
1894  }
1895  for(int i = 0; i < numRot; i++) text->Rotate(clockwise);
1896 
1897  textList.push_back(text);
1898  textNode = textNode->next_sibling("Text");
1899  } //}
1900 
1901  m_workspace->SetTextList(textList);
1902  return true;
1903 }
1904 
1905 void FileHanding::SaveControl(wxFileName path)
1906 {
1907  // Same process present in SaveProject():
1908  std::ofstream writeProjectsFile(path.GetFullPath());
1909  writeProjectsFile.close();
1910 
1911  rapidxml::xml_document<> doc;
1912  rapidxml::file<> xmlFile(path.GetFullPath().mb_str());
1913  doc.parse<0>(xmlFile.data());
1914 
1915  rapidxml::xml_node<>* decl = doc.allocate_node(rapidxml::node_declaration);
1916  rapidxml::xml_attribute<>* ver = doc.allocate_attribute("version", "1.0");
1917  rapidxml::xml_attribute<>* encoding = doc.allocate_attribute("encoding", "utf-8");
1918  decl->append_attribute(ver);
1919  decl->append_attribute(encoding);
1920  doc.append_node(decl);
1921 
1922  rapidxml::xml_node<>* rootNode = doc.allocate_node(rapidxml::node_element, "Control");
1923  doc.append_node(rootNode);
1924 
1925  rapidxml::xml_node<>* projectNameNode = AppendNode(doc, rootNode, "Name");
1926  SetNodeValue(doc, projectNameNode, path.GetName());
1927 
1928  auto elementsNode = AppendNode(doc, rootNode, "ControlElements");
1929  SaveControlElements(doc, elementsNode);
1930  std::ofstream writeXML(path.GetFullPath());
1931  writeXML << doc;
1932  writeXML.close();
1933 }
1934 
1935 bool FileHanding::OpenControl(wxFileName path,
1936  std::vector<ControlElement*>& ctrlElementList,
1937  std::vector<ConnectionLine*>& ctrlConnectionList)
1938 {
1939  rapidxml::xml_document<> doc;
1940  rapidxml::file<> xmlFile(path.GetFullPath().mb_str());
1941 
1942  doc.parse<0>(xmlFile.data());
1943 
1944  auto projectNode = doc.first_node("Control");
1945  if(!projectNode) return false;
1946  // auto nameNode = projectNode->first_node("Name");
1947  // if(!nameNode) return false;
1948  // m_controlEditor->SetName(nameNode->value());
1949 
1950  // Open elements
1951  auto elementsNode = projectNode->first_node("ControlElements");
1952  if(!elementsNode) return false;
1953 
1954  // auto elementsNode = AppendNode(doc, rootNode, "ControlElements");
1955  ControlElementContainer* ctrlElementContainer = new ControlElementContainer();
1956  if(!OpenControlElements(doc, elementsNode, ctrlElementContainer)) return false;
1957  ctrlElementList = ctrlElementContainer->GetControlElementsList();
1958  ctrlConnectionList = ctrlElementContainer->GetConnectionLineList();
1959  return true;
1960 }
1961 
1962 void FileHanding::SaveControlElements(rapidxml::xml_document<>& doc,
1963  rapidxml::xml_node<>* elementsNode,
1964  ControlElementContainer* ctrlContainer)
1965 {
1966  if(!ctrlContainer) {
1967  ctrlContainer = new ControlElementContainer();
1968  ctrlContainer->FillContainer(m_controlEditor);
1969  }
1970 
1971  //{ Constant
1972  auto constsNode = AppendNode(doc, elementsNode, "ConstantList");
1973  auto constList = ctrlContainer->GetConstantList();
1974  for(auto it = constList.begin(), itEnd = constList.end(); it != itEnd; ++it) {
1975  Constant* constant = *it;
1976  auto constNode = AppendNode(doc, constsNode, "Constant");
1977  SetNodeAttribute(doc, constNode, "ID", constant->GetID());
1978  auto cadProp = AppendNode(doc, constNode, "CADProperties");
1979  auto position = AppendNode(doc, cadProp, "Position");
1980  auto posX = AppendNode(doc, position, "X");
1981  SetNodeValue(doc, posX, constant->GetPosition().m_x);
1982  auto posY = AppendNode(doc, position, "Y");
1983  SetNodeValue(doc, posY, constant->GetPosition().m_y);
1984  auto size = AppendNode(doc, cadProp, "Size");
1985  auto width = AppendNode(doc, size, "Width");
1986  SetNodeValue(doc, width, constant->GetWidth());
1987  auto height = AppendNode(doc, size, "Height");
1988  SetNodeValue(doc, height, constant->GetHeight());
1989  auto angle = AppendNode(doc, cadProp, "Angle");
1990  SetNodeValue(doc, angle, constant->GetAngle());
1991 
1992  // Nodes
1993  auto nodeList = AppendNode(doc, constNode, "NodeList");
1994  SaveControlNodes(doc, nodeList, constant->GetNodeList());
1995 
1996  // Control properties
1997  auto value = AppendNode(doc, constNode, "Value");
1998  SetNodeValue(doc, value, constant->GetValue());
1999  } //}
2000 
2001  //{ Exponential
2002  auto expsNode = AppendNode(doc, elementsNode, "ExponentialList");
2003  auto expList = ctrlContainer->GetExponentialList();
2004  for(auto it = expList.begin(), itEnd = expList.end(); it != itEnd; ++it) {
2005  Exponential* exponential = *it;
2006  auto expNode = AppendNode(doc, expsNode, "Exponential");
2007  SetNodeAttribute(doc, expNode, "ID", exponential->GetID());
2008  auto cadProp = AppendNode(doc, expNode, "CADProperties");
2009  auto position = AppendNode(doc, cadProp, "Position");
2010  auto posX = AppendNode(doc, position, "X");
2011  SetNodeValue(doc, posX, exponential->GetPosition().m_x);
2012  auto posY = AppendNode(doc, position, "Y");
2013  SetNodeValue(doc, posY, exponential->GetPosition().m_y);
2014  auto size = AppendNode(doc, cadProp, "Size");
2015  auto width = AppendNode(doc, size, "Width");
2016  SetNodeValue(doc, width, exponential->GetWidth());
2017  auto height = AppendNode(doc, size, "Height");
2018  SetNodeValue(doc, height, exponential->GetHeight());
2019  auto angle = AppendNode(doc, cadProp, "Angle");
2020  SetNodeValue(doc, angle, exponential->GetAngle());
2021 
2022  // Nodes
2023  auto nodeList = AppendNode(doc, expNode, "NodeList");
2024  SaveControlNodes(doc, nodeList, exponential->GetNodeList());
2025 
2026  // Control properties
2027  double a, b;
2028  exponential->GetValues(a, b);
2029  auto value = AppendNode(doc, expNode, "Value");
2030  auto aValue = AppendNode(doc, value, "A");
2031  SetNodeValue(doc, aValue, a);
2032  auto bValue = AppendNode(doc, value, "B");
2033  SetNodeValue(doc, bValue, b);
2034  } //}
2035 
2036  //{ Gain
2037  auto gainsNode = AppendNode(doc, elementsNode, "GainList");
2038  auto gainList = ctrlContainer->GetGainList();
2039  for(auto it = gainList.begin(), itEnd = gainList.end(); it != itEnd; ++it) {
2040  Gain* gain = *it;
2041  auto gainNode = AppendNode(doc, gainsNode, "Gain");
2042  SetNodeAttribute(doc, gainNode, "ID", gain->GetID());
2043  auto cadProp = AppendNode(doc, gainNode, "CADProperties");
2044  auto position = AppendNode(doc, cadProp, "Position");
2045  auto posX = AppendNode(doc, position, "X");
2046  SetNodeValue(doc, posX, gain->GetPosition().m_x);
2047  auto posY = AppendNode(doc, position, "Y");
2048  SetNodeValue(doc, posY, gain->GetPosition().m_y);
2049  auto size = AppendNode(doc, cadProp, "Size");
2050  auto width = AppendNode(doc, size, "Width");
2051  SetNodeValue(doc, width, gain->GetWidth());
2052  auto height = AppendNode(doc, size, "Height");
2053  SetNodeValue(doc, height, gain->GetHeight());
2054  auto angle = AppendNode(doc, cadProp, "Angle");
2055  SetNodeValue(doc, angle, gain->GetAngle());
2056 
2057  // Nodes
2058  auto nodeList = AppendNode(doc, gainNode, "NodeList");
2059  SaveControlNodes(doc, nodeList, gain->GetNodeList());
2060 
2061  // Control properties
2062  auto value = AppendNode(doc, gainNode, "Value");
2063  SetNodeValue(doc, value, gain->GetValue());
2064  } //}
2065 
2066  //{ IO
2067  auto iosNode = AppendNode(doc, elementsNode, "IOList");
2068  auto ioList = ctrlContainer->GetIOControlList();
2069  for(auto it = ioList.begin(), itEnd = ioList.end(); it != itEnd; ++it) {
2070  IOControl* io = *it;
2071  auto ioNode = AppendNode(doc, iosNode, "IO");
2072  SetNodeAttribute(doc, ioNode, "ID", io->GetID());
2073  auto cadProp = AppendNode(doc, ioNode, "CADProperties");
2074  auto position = AppendNode(doc, cadProp, "Position");
2075  auto posX = AppendNode(doc, position, "X");
2076  SetNodeValue(doc, posX, io->GetPosition().m_x);
2077  auto posY = AppendNode(doc, position, "Y");
2078  SetNodeValue(doc, posY, io->GetPosition().m_y);
2079  auto size = AppendNode(doc, cadProp, "Size");
2080  auto width = AppendNode(doc, size, "Width");
2081  SetNodeValue(doc, width, io->GetWidth());
2082  auto height = AppendNode(doc, size, "Height");
2083  SetNodeValue(doc, height, io->GetHeight());
2084  auto angle = AppendNode(doc, cadProp, "Angle");
2085  SetNodeValue(doc, angle, io->GetAngle());
2086 
2087  // Nodes
2088  auto nodeList = AppendNode(doc, ioNode, "NodeList");
2089  SaveControlNodes(doc, nodeList, io->GetNodeList());
2090 
2091  // Control properties
2092  auto value = AppendNode(doc, ioNode, "Value");
2093  SetNodeValue(doc, value, io->GetValue());
2094  auto ioFlags = AppendNode(doc, ioNode, "IOFlags");
2095  SetNodeValue(doc, ioFlags, io->GetIOFlags());
2096  } //}
2097 
2098  //{ Limiter
2099  auto limitersNode = AppendNode(doc, elementsNode, "LimiterList");
2100  auto limiterList = ctrlContainer->GetLimiterList();
2101  for(auto it = limiterList.begin(), itEnd = limiterList.end(); it != itEnd; ++it) {
2102  Limiter* limiter = *it;
2103  auto limiterNode = AppendNode(doc, limitersNode, "Limiter");
2104  SetNodeAttribute(doc, limiterNode, "ID", limiter->GetID());
2105  auto cadProp = AppendNode(doc, limiterNode, "CADProperties");
2106  auto position = AppendNode(doc, cadProp, "Position");
2107  auto posX = AppendNode(doc, position, "X");
2108  SetNodeValue(doc, posX, limiter->GetPosition().m_x);
2109  auto posY = AppendNode(doc, position, "Y");
2110  SetNodeValue(doc, posY, limiter->GetPosition().m_y);
2111  auto size = AppendNode(doc, cadProp, "Size");
2112  auto width = AppendNode(doc, size, "Width");
2113  SetNodeValue(doc, width, limiter->GetWidth());
2114  auto height = AppendNode(doc, size, "Height");
2115  SetNodeValue(doc, height, limiter->GetHeight());
2116  auto angle = AppendNode(doc, cadProp, "Angle");
2117  SetNodeValue(doc, angle, limiter->GetAngle());
2118 
2119  // Nodes
2120  auto nodeList = AppendNode(doc, limiterNode, "NodeList");
2121  SaveControlNodes(doc, nodeList, limiter->GetNodeList());
2122 
2123  // Control properties
2124  auto upLimit = AppendNode(doc, limiterNode, "UpperLimit");
2125  SetNodeValue(doc, upLimit, limiter->GetUpLimit());
2126  auto lowLimit = AppendNode(doc, limiterNode, "LowerLimit");
2127  SetNodeValue(doc, lowLimit, limiter->GetLowLimit());
2128  } //}
2129 
2130  //{ Multiplier
2131  auto multipliersNode = AppendNode(doc, elementsNode, "MultiplierList");
2132  auto multiplierList = ctrlContainer->GetMultiplierList();
2133  for(auto it = multiplierList.begin(), itEnd = multiplierList.end(); it != itEnd; ++it) {
2134  Multiplier* multiplier = *it;
2135  auto multiplierNode = AppendNode(doc, multipliersNode, "Multiplier");
2136  SetNodeAttribute(doc, multiplierNode, "ID", multiplier->GetID());
2137  auto cadProp = AppendNode(doc, multiplierNode, "CADProperties");
2138  auto position = AppendNode(doc, cadProp, "Position");
2139  auto posX = AppendNode(doc, position, "X");
2140  SetNodeValue(doc, posX, multiplier->GetPosition().m_x);
2141  auto posY = AppendNode(doc, position, "Y");
2142  SetNodeValue(doc, posY, multiplier->GetPosition().m_y);
2143  auto size = AppendNode(doc, cadProp, "Size");
2144  auto width = AppendNode(doc, size, "Width");
2145  SetNodeValue(doc, width, multiplier->GetWidth());
2146  auto height = AppendNode(doc, size, "Height");
2147  SetNodeValue(doc, height, multiplier->GetHeight());
2148  auto angle = AppendNode(doc, cadProp, "Angle");
2149  SetNodeValue(doc, angle, multiplier->GetAngle());
2150 
2151  // Nodes
2152  auto nodeList = AppendNode(doc, multiplierNode, "NodeList");
2153  SaveControlNodes(doc, nodeList, multiplier->GetNodeList());
2154  } //}
2155 
2156  //{ Divider
2157  auto dividersNode = AppendNode(doc, elementsNode, "DividerList");
2158  auto dividersList = ctrlContainer->GetDividerList();
2159  for(auto it = dividersList.begin(), itEnd = dividersList.end(); it != itEnd; ++it) {
2160  Divider* divider = *it;
2161  auto dividerNode = AppendNode(doc, dividersNode, "Divider");
2162  SetNodeAttribute(doc, dividerNode, "ID", divider->GetID());
2163  auto cadProp = AppendNode(doc, dividerNode, "CADProperties");
2164  auto position = AppendNode(doc, cadProp, "Position");
2165  auto posX = AppendNode(doc, position, "X");
2166  SetNodeValue(doc, posX, divider->GetPosition().m_x);
2167  auto posY = AppendNode(doc, position, "Y");
2168  SetNodeValue(doc, posY, divider->GetPosition().m_y);
2169  auto size = AppendNode(doc, cadProp, "Size");
2170  auto width = AppendNode(doc, size, "Width");
2171  SetNodeValue(doc, width, divider->GetWidth());
2172  auto height = AppendNode(doc, size, "Height");
2173  SetNodeValue(doc, height, divider->GetHeight());
2174  auto angle = AppendNode(doc, cadProp, "Angle");
2175  SetNodeValue(doc, angle, divider->GetAngle());
2176 
2177  // Nodes
2178  auto nodeList = AppendNode(doc, dividerNode, "NodeList");
2179  SaveControlNodes(doc, nodeList, divider->GetNodeList());
2180  } //}
2181 
2182  //{ Rate limiter
2183  auto rateLimitersNode = AppendNode(doc, elementsNode, "RateLimiterList");
2184  auto rateLimiterList = ctrlContainer->GetRateLimiterList();
2185  for(auto it = rateLimiterList.begin(), itEnd = rateLimiterList.end(); it != itEnd; ++it) {
2186  RateLimiter* rateLimiter = *it;
2187  auto rateLimiterNode = AppendNode(doc, rateLimitersNode, "RateLimiter");
2188  SetNodeAttribute(doc, rateLimiterNode, "ID", rateLimiter->GetID());
2189  auto cadProp = AppendNode(doc, rateLimiterNode, "CADProperties");
2190  auto position = AppendNode(doc, cadProp, "Position");
2191  auto posX = AppendNode(doc, position, "X");
2192  SetNodeValue(doc, posX, rateLimiter->GetPosition().m_x);
2193  auto posY = AppendNode(doc, position, "Y");
2194  SetNodeValue(doc, posY, rateLimiter->GetPosition().m_y);
2195  auto size = AppendNode(doc, cadProp, "Size");
2196  auto width = AppendNode(doc, size, "Width");
2197  SetNodeValue(doc, width, rateLimiter->GetWidth());
2198  auto height = AppendNode(doc, size, "Height");
2199  SetNodeValue(doc, height, rateLimiter->GetHeight());
2200  auto angle = AppendNode(doc, cadProp, "Angle");
2201  SetNodeValue(doc, angle, rateLimiter->GetAngle());
2202 
2203  // Nodes
2204  auto nodeList = AppendNode(doc, rateLimiterNode, "NodeList");
2205  SaveControlNodes(doc, nodeList, rateLimiter->GetNodeList());
2206 
2207  // Control properties
2208  auto upLimit = AppendNode(doc, rateLimiterNode, "UpperLimit");
2209  SetNodeValue(doc, upLimit, rateLimiter->GetUpLimit());
2210  auto lowLimit = AppendNode(doc, rateLimiterNode, "LowerLimit");
2211  SetNodeValue(doc, lowLimit, rateLimiter->GetLowLimit());
2212  } //}
2213 
2214  //{ Sum
2215  auto sumsNode = AppendNode(doc, elementsNode, "SumList");
2216  auto sumList = ctrlContainer->GetSumList();
2217  for(auto it = sumList.begin(), itEnd = sumList.end(); it != itEnd; ++it) {
2218  Sum* sum = *it;
2219  auto sumNode = AppendNode(doc, sumsNode, "Sum");
2220  SetNodeAttribute(doc, sumNode, "ID", sum->GetID());
2221  auto cadProp = AppendNode(doc, sumNode, "CADProperties");
2222  auto position = AppendNode(doc, cadProp, "Position");
2223  auto posX = AppendNode(doc, position, "X");
2224  SetNodeValue(doc, posX, sum->GetPosition().m_x);
2225  auto posY = AppendNode(doc, position, "Y");
2226  SetNodeValue(doc, posY, sum->GetPosition().m_y);
2227  auto size = AppendNode(doc, cadProp, "Size");
2228  auto width = AppendNode(doc, size, "Width");
2229  SetNodeValue(doc, width, sum->GetWidth());
2230  auto height = AppendNode(doc, size, "Height");
2231  SetNodeValue(doc, height, sum->GetHeight());
2232  auto angle = AppendNode(doc, cadProp, "Angle");
2233  SetNodeValue(doc, angle, sum->GetAngle());
2234 
2235  // Nodes
2236  auto nodeList = AppendNode(doc, sumNode, "NodeList");
2237  SaveControlNodes(doc, nodeList, sum->GetNodeList());
2238 
2239  // Control properties
2240  auto signsNode = AppendNode(doc, sumNode, "Signs");
2241  auto signs = sum->GetSignalList();
2242  for(int i = 0; i < (int)signs.size(); ++i) {
2243  auto value = AppendNode(doc, signsNode, "Value");
2244  SetNodeValue(doc, value, static_cast<int>(signs[i]));
2245  }
2246 
2247  } //}
2248 
2249  //{ Transfer function
2250  auto tfsNode = AppendNode(doc, elementsNode, "TransferFunctionList");
2251  auto tfList = ctrlContainer->GetTFList();
2252  for(auto it = tfList.begin(), itEnd = tfList.end(); it != itEnd; ++it) {
2253  TransferFunction* tf = *it;
2254  auto tfNode = AppendNode(doc, tfsNode, "TransferFunction");
2255  SetNodeAttribute(doc, tfNode, "ID", tf->GetID());
2256  auto cadProp = AppendNode(doc, tfNode, "CADProperties");
2257  auto position = AppendNode(doc, cadProp, "Position");
2258  auto posX = AppendNode(doc, position, "X");
2259  SetNodeValue(doc, posX, tf->GetPosition().m_x);
2260  auto posY = AppendNode(doc, position, "Y");
2261  SetNodeValue(doc, posY, tf->GetPosition().m_y);
2262  auto size = AppendNode(doc, cadProp, "Size");
2263  auto width = AppendNode(doc, size, "Width");
2264  SetNodeValue(doc, width, tf->GetWidth());
2265  auto height = AppendNode(doc, size, "Height");
2266  SetNodeValue(doc, height, tf->GetHeight());
2267  auto angle = AppendNode(doc, cadProp, "Angle");
2268  SetNodeValue(doc, angle, tf->GetAngle());
2269 
2270  // Nodes
2271  auto nodeList = AppendNode(doc, tfNode, "NodeList");
2272  SaveControlNodes(doc, nodeList, tf->GetNodeList());
2273 
2274  // Control properties
2275  auto numeratorNode = AppendNode(doc, tfNode, "Numerator");
2276  auto numerator = tf->GetNumerator();
2277  for(int i = 0; i < (int)numerator.size(); ++i) {
2278  auto value = AppendNode(doc, numeratorNode, "Value");
2279  SetNodeValue(doc, value, numerator[i]);
2280  }
2281  auto denominatorNode = AppendNode(doc, tfNode, "Denominator");
2282  auto denominator = tf->GetDenominator();
2283  for(int i = 0; i < (int)denominator.size(); ++i) {
2284  auto value = AppendNode(doc, denominatorNode, "Value");
2285  SetNodeValue(doc, value, denominator[i]);
2286  }
2287  } //}
2288 
2289  //{ Connection line
2290  auto cLinesNode = AppendNode(doc, elementsNode, "ConnectionList");
2291  auto connLineList = ctrlContainer->GetConnectionLineList();
2292  for(auto it = connLineList.begin(), itEnd = connLineList.end(); it != itEnd; ++it) {
2293  ConnectionLine* cLine = *it;
2294  auto cLineNode = AppendNode(doc, cLinesNode, "Connection");
2295  SetNodeAttribute(doc, cLineNode, "ID", cLine->GetID());
2296 
2297  // CAD properties
2298  auto cadProp = AppendNode(doc, cLineNode, "CADProperties");
2299  auto offset = AppendNode(doc, cadProp, "Offset");
2300  SetNodeValue(doc, offset, cLine->GetOffset());
2301 
2302  // Parent list
2303  auto parentsNode = AppendNode(doc, cLineNode, "ParentList");
2304  auto parentList = cLine->GetParentList();
2305  int nodeIndex = 0;
2306  for(auto itP = parentList.begin(), itPEnd = parentList.end(); itP != itPEnd; ++itP) {
2307  Element* parent = *itP;
2308  auto parentNode = AppendNode(doc, parentsNode, "Parent");
2309  auto elementID = AppendNode(doc, parentNode, "ElementID");
2310  SetNodeValue(doc, elementID, parent->GetID());
2311  auto nodeID = AppendNode(doc, parentNode, "NodeID");
2312  SetNodeValue(doc, nodeID, cLine->GetNodeList()[nodeIndex]->GetID());
2313  nodeIndex++;
2314  }
2315 
2316  auto parentLine = AppendNode(doc, cLineNode, "ParentLine");
2317  if(cLine->GetParentLine()) {
2318  ConnectionLine* parent = cLine->GetParentLine();
2319  SetNodeAttribute(doc, parentLine, "ID", parent->GetID());
2320  } else {
2321  SetNodeAttribute(doc, parentLine, "ID", -1);
2322  }
2323  } //}
2324 }
2325 
2326 bool FileHanding::OpenControlElements(rapidxml::xml_document<>& doc,
2327  rapidxml::xml_node<>* elementsNode,
2328  ControlElementContainer* ctrlContainer)
2329 {
2330  std::vector<ControlElement*> elementList;
2331  std::vector<ConnectionLine*> connectionList;
2332 
2333  //{ Constant
2334  auto constListNode = elementsNode->first_node("ConstantList");
2335  if(constListNode) {
2336  auto constNode = constListNode->first_node("Constant");
2337  while(constNode) {
2338  int id = GetAttributeValueInt(constNode, "ID");
2339  Constant* constant = new Constant(id);
2340 
2341  auto cadPropNode = constNode->first_node("CADProperties");
2342  if(!cadPropNode) return false;
2343 
2344  auto position = cadPropNode->first_node("Position");
2345  double posX = GetNodeValueDouble(position, "X");
2346  double posY = GetNodeValueDouble(position, "Y");
2347  auto size = cadPropNode->first_node("Size");
2348  double width = GetNodeValueDouble(size, "Width");
2349  double height = GetNodeValueDouble(size, "Height");
2350  double angle = GetNodeValueDouble(cadPropNode, "Angle");
2351 
2352  double value = GetNodeValueDouble(constNode, "Value");
2353 
2354  constant->SetWidth(width);
2355  constant->SetHeight(height);
2356  constant->SetAngle(angle);
2357  constant->SetPosition(wxPoint2DDouble(posX, posY));
2358  constant->StartMove(constant->GetPosition());
2359 
2360  constant->SetValue(value);
2361 
2362  std::vector<Node*> nodeVector;
2363  if(!OpenControlNodeList(constNode, nodeVector)) return false;
2364 
2365  constant->SetNodeList(nodeVector);
2366  constant->UpdatePoints();
2367  elementList.push_back(constant);
2368 
2369  constNode = constNode->next_sibling("Constant");
2370  }
2371  }
2372  //}
2373 
2374  //{ Exponential
2375  auto expListNode = elementsNode->first_node("ExponentialList");
2376  if(expListNode) {
2377  auto expNode = expListNode->first_node("Exponential");
2378  while(expNode) {
2379  int id = GetAttributeValueInt(expNode, "ID");
2380  Exponential* exponential = new Exponential(id);
2381 
2382  auto cadPropNode = expNode->first_node("CADProperties");
2383  if(!cadPropNode) return false;
2384 
2385  auto position = cadPropNode->first_node("Position");
2386  double posX = GetNodeValueDouble(position, "X");
2387  double posY = GetNodeValueDouble(position, "Y");
2388  auto size = cadPropNode->first_node("Size");
2389  double width = GetNodeValueDouble(size, "Width");
2390  double height = GetNodeValueDouble(size, "Height");
2391  double angle = GetNodeValueDouble(cadPropNode, "Angle");
2392 
2393  auto value = expNode->first_node("Value");
2394  double a = GetNodeValueDouble(value, "A");
2395  double b = GetNodeValueDouble(value, "B");
2396 
2397  exponential->SetWidth(width);
2398  exponential->SetHeight(height);
2399  exponential->SetAngle(angle);
2400  exponential->SetPosition(wxPoint2DDouble(posX, posY));
2401  exponential->StartMove(exponential->GetPosition());
2402 
2403  exponential->SetValues(a, b);
2404 
2405  std::vector<Node*> nodeVector;
2406  if(!OpenControlNodeList(expNode, nodeVector)) return false;
2407 
2408  exponential->SetNodeList(nodeVector);
2409  exponential->UpdatePoints();
2410  elementList.push_back(exponential);
2411 
2412  expNode = expNode->next_sibling("Exponential");
2413  }
2414  }
2415  //}
2416 
2417  //{ Gain
2418  auto gainListNode = elementsNode->first_node("GainList");
2419  if(gainListNode) {
2420  auto gainNode = gainListNode->first_node("Gain");
2421  while(gainNode) {
2422  int id = GetAttributeValueInt(gainNode, "ID");
2423  Gain* gain = new Gain(id);
2424 
2425  auto cadPropNode = gainNode->first_node("CADProperties");
2426  if(!cadPropNode) return false;
2427 
2428  auto position = cadPropNode->first_node("Position");
2429  double posX = GetNodeValueDouble(position, "X");
2430  double posY = GetNodeValueDouble(position, "Y");
2431  auto size = cadPropNode->first_node("Size");
2432  double width = GetNodeValueDouble(size, "Width");
2433  double height = GetNodeValueDouble(size, "Height");
2434  double angle = GetNodeValueDouble(cadPropNode, "Angle");
2435 
2436  double value = GetNodeValueDouble(gainNode, "Value");
2437 
2438  gain->SetWidth(width);
2439  gain->SetHeight(height);
2440  gain->SetAngle(angle);
2441  gain->SetPosition(wxPoint2DDouble(posX, posY));
2442  gain->SetValue(value);
2443  gain->StartMove(gain->GetPosition());
2444 
2445  std::vector<Node*> nodeVector;
2446  if(!OpenControlNodeList(gainNode, nodeVector)) return false;
2447 
2448  gain->SetNodeList(nodeVector);
2449  gain->UpdatePoints();
2450  elementList.push_back(gain);
2451 
2452  gainNode = gainNode->next_sibling("Gain");
2453  }
2454  }
2455  //}
2456 
2457  //{ IO
2458  auto ioListNode = elementsNode->first_node("IOList");
2459  if(ioListNode) {
2460  auto ioNode = ioListNode->first_node("IO");
2461  while(ioNode) {
2462  int id = GetAttributeValueInt(ioNode, "ID");
2463 
2464  auto cadPropNode = ioNode->first_node("CADProperties");
2465  if(!cadPropNode) return false;
2466 
2467  auto position = cadPropNode->first_node("Position");
2468  double posX = GetNodeValueDouble(position, "X");
2469  double posY = GetNodeValueDouble(position, "Y");
2470  auto size = cadPropNode->first_node("Size");
2471  double width = GetNodeValueDouble(size, "Width");
2472  double height = GetNodeValueDouble(size, "Height");
2473  double angle = GetNodeValueDouble(cadPropNode, "Angle");
2474 
2475  std::vector<Node*> nodeVector;
2476  if(!OpenControlNodeList(ioNode, nodeVector)) return false;
2477 
2478  IOControl::IOFlags value = static_cast<IOControl::IOFlags>(GetNodeValueInt(ioNode, "Value"));
2479  int ioFlags = GetNodeValueInt(ioNode, "IOFlags");
2480 
2481  IOControl* io = new IOControl(ioFlags, id);
2482 
2483  io->SetWidth(width);
2484  io->SetHeight(height);
2485  io->SetAngle(angle);
2486  io->SetPosition(wxPoint2DDouble(posX, posY));
2487  io->SetValue(value);
2488  io->StartMove(io->GetPosition());
2489  io->SetNodeList(nodeVector);
2490  io->UpdatePoints();
2491  elementList.push_back(io);
2492 
2493  ioNode = ioNode->next_sibling("IO");
2494  }
2495  }
2496  //}
2497 
2498  //{ Limiter
2499  auto limiterListNode = elementsNode->first_node("LimiterList");
2500  if(limiterListNode) {
2501  auto limiterNode = limiterListNode->first_node("Limiter");
2502  while(limiterNode) {
2503  int id = GetAttributeValueInt(limiterNode, "ID");
2504  Limiter* limiter = new Limiter(id);
2505 
2506  auto cadPropNode = limiterNode->first_node("CADProperties");
2507  if(!cadPropNode) return false;
2508 
2509  auto position = cadPropNode->first_node("Position");
2510  double posX = GetNodeValueDouble(position, "X");
2511  double posY = GetNodeValueDouble(position, "Y");
2512  auto size = cadPropNode->first_node("Size");
2513  double width = GetNodeValueDouble(size, "Width");
2514  double height = GetNodeValueDouble(size, "Height");
2515  double angle = GetNodeValueDouble(cadPropNode, "Angle");
2516 
2517  double upLimit = GetNodeValueDouble(limiterNode, "UpperLimit");
2518  double lowLimit = GetNodeValueDouble(limiterNode, "LowerLimit");
2519 
2520  std::vector<Node*> nodeVector;
2521  if(!OpenControlNodeList(limiterNode, nodeVector)) return false;
2522 
2523  limiter->SetWidth(width);
2524  limiter->SetHeight(height);
2525  limiter->SetAngle(angle);
2526  limiter->SetPosition(wxPoint2DDouble(posX, posY));
2527  limiter->SetUpLimit(upLimit);
2528  limiter->SetLowLimit(lowLimit);
2529 
2530  limiter->StartMove(limiter->GetPosition());
2531  limiter->SetNodeList(nodeVector);
2532  limiter->UpdatePoints();
2533  elementList.push_back(limiter);
2534 
2535  limiterNode = limiterNode->next_sibling("Limiter");
2536  }
2537  }
2538  //}
2539 
2540  //{ Multiplier
2541  auto multiplierListNode = elementsNode->first_node("MultiplierList");
2542  if(multiplierListNode) {
2543  auto multiplierNode = multiplierListNode->first_node("Multiplier");
2544  while(multiplierNode) {
2545  int id = GetAttributeValueInt(multiplierNode, "ID");
2546  Multiplier* multiplier = new Multiplier(id);
2547 
2548  auto cadPropNode = multiplierNode->first_node("CADProperties");
2549  if(!cadPropNode) return false;
2550 
2551  auto position = cadPropNode->first_node("Position");
2552  double posX = GetNodeValueDouble(position, "X");
2553  double posY = GetNodeValueDouble(position, "Y");
2554  auto size = cadPropNode->first_node("Size");
2555  double width = GetNodeValueDouble(size, "Width");
2556  double height = GetNodeValueDouble(size, "Height");
2557  double angle = GetNodeValueDouble(cadPropNode, "Angle");
2558 
2559  std::vector<Node*> nodeVector;
2560  if(!OpenControlNodeList(multiplierNode, nodeVector)) return false;
2561 
2562  multiplier->SetWidth(width);
2563  multiplier->SetHeight(height);
2564  multiplier->SetAngle(angle);
2565  multiplier->SetPosition(wxPoint2DDouble(posX, posY));
2566 
2567  multiplier->StartMove(multiplier->GetPosition());
2568  multiplier->SetNodeList(nodeVector);
2569  multiplier->UpdatePoints();
2570  elementList.push_back(multiplier);
2571 
2572  multiplierNode = multiplierNode->next_sibling("Multiplier");
2573  }
2574  }
2575  //}
2576 
2577  //{ Divider
2578  auto dividerListNode = elementsNode->first_node("DividerList");
2579  if(dividerListNode) {
2580  auto dividerNode = dividerListNode->first_node("Divider");
2581  while(dividerNode) {
2582  int id = GetAttributeValueInt(dividerNode, "ID");
2583  Divider* divider = new Divider(id);
2584 
2585  auto cadPropNode = dividerNode->first_node("CADProperties");
2586  if(!cadPropNode) return false;
2587 
2588  auto position = cadPropNode->first_node("Position");
2589  double posX = GetNodeValueDouble(position, "X");
2590  double posY = GetNodeValueDouble(position, "Y");
2591  auto size = cadPropNode->first_node("Size");
2592  double width = GetNodeValueDouble(size, "Width");
2593  double height = GetNodeValueDouble(size, "Height");
2594  double angle = GetNodeValueDouble(cadPropNode, "Angle");
2595 
2596  std::vector<Node*> nodeVector;
2597  if(!OpenControlNodeList(dividerNode, nodeVector)) return false;
2598 
2599  divider->SetWidth(width);
2600  divider->SetHeight(height);
2601  divider->SetAngle(angle);
2602  divider->SetPosition(wxPoint2DDouble(posX, posY));
2603 
2604  divider->StartMove(divider->GetPosition());
2605  divider->SetNodeList(nodeVector);
2606  divider->UpdatePoints();
2607  elementList.push_back(divider);
2608 
2609  dividerNode = dividerNode->next_sibling("Divider");
2610  }
2611  }
2612  //}
2613 
2614  //{ Rate limiter
2615  auto rateLimiterListNode = elementsNode->first_node("RateLimiterList");
2616  if(rateLimiterListNode) {
2617  auto rateLimiterNode = rateLimiterListNode->first_node("RateLimiter");
2618  while(rateLimiterNode) {
2619  int id = GetAttributeValueInt(rateLimiterNode, "ID");
2620  RateLimiter* limiter = new RateLimiter(id);
2621 
2622  auto cadPropNode = rateLimiterNode->first_node("CADProperties");
2623  if(!cadPropNode) return false;
2624 
2625  auto position = cadPropNode->first_node("Position");
2626  double posX = GetNodeValueDouble(position, "X");
2627  double posY = GetNodeValueDouble(position, "Y");
2628  auto size = cadPropNode->first_node("Size");
2629  double width = GetNodeValueDouble(size, "Width");
2630  double height = GetNodeValueDouble(size, "Height");
2631  double angle = GetNodeValueDouble(cadPropNode, "Angle");
2632 
2633  double upLimit = GetNodeValueDouble(rateLimiterNode, "UpperLimit");
2634  double lowLimit = GetNodeValueDouble(rateLimiterNode, "LowerLimit");
2635 
2636  std::vector<Node*> nodeVector;
2637  if(!OpenControlNodeList(rateLimiterNode, nodeVector)) return false;
2638 
2639  limiter->SetWidth(width);
2640  limiter->SetHeight(height);
2641  limiter->SetAngle(angle);
2642  limiter->SetPosition(wxPoint2DDouble(posX, posY));
2643  limiter->SetUpLimit(upLimit);
2644  limiter->SetLowLimit(lowLimit);
2645 
2646  limiter->StartMove(limiter->GetPosition());
2647  limiter->SetNodeList(nodeVector);
2648  limiter->UpdatePoints();
2649  elementList.push_back(limiter);
2650 
2651  rateLimiterNode = rateLimiterNode->next_sibling("RateLimiter");
2652  }
2653  }
2654  //}
2655 
2656  //{ Sum
2657  auto sumListNode = elementsNode->first_node("SumList");
2658  if(sumListNode) {
2659  auto sumNode = sumListNode->first_node("Sum");
2660  while(sumNode) {
2661  int id = GetAttributeValueInt(sumNode, "ID");
2662  Sum* sum = new Sum(id);
2663 
2664  auto cadPropNode = sumNode->first_node("CADProperties");
2665  if(!cadPropNode) return false;
2666 
2667  auto position = cadPropNode->first_node("Position");
2668  double posX = GetNodeValueDouble(position, "X");
2669  double posY = GetNodeValueDouble(position, "Y");
2670  auto size = cadPropNode->first_node("Size");
2671  double width = GetNodeValueDouble(size, "Width");
2672  double height = GetNodeValueDouble(size, "Height");
2673  double angle = GetNodeValueDouble(cadPropNode, "Angle");
2674 
2675  std::vector<Sum::Signal> signs;
2676  auto signsNode = sumNode->first_node("Signs");
2677  auto sign = signsNode->first_node("Value");
2678  while(sign) {
2679  long value;
2680  wxString(sign->value()).ToCLong(&value);
2681  signs.push_back(static_cast<Sum::Signal>(value));
2682  sign = sign->next_sibling("Value");
2683  }
2684  sum->SetSignalList(signs);
2685 
2686  std::vector<Node*> nodeVector;
2687  if(!OpenControlNodeList(sumNode, nodeVector)) return false;
2688 
2689  sum->SetWidth(width);
2690  sum->SetHeight(height);
2691  sum->SetAngle(angle);
2692  sum->SetPosition(wxPoint2DDouble(posX, posY));
2693 
2694  sum->StartMove(sum->GetPosition());
2695  sum->SetNodeList(nodeVector);
2696  sum->UpdatePoints();
2697  elementList.push_back(sum);
2698 
2699  sumNode = sumNode->next_sibling("Sum");
2700  }
2701  }
2702  //}
2703 
2704  //{ Transfer function
2705  auto tfListNode = elementsNode->first_node("TransferFunctionList");
2706  if(tfListNode) {
2707  auto tfNode = tfListNode->first_node("TransferFunction");
2708  while(tfNode) {
2709  int id = GetAttributeValueInt(tfNode, "ID");
2710  TransferFunction* tf = new TransferFunction(id);
2711 
2712  auto cadPropNode = tfNode->first_node("CADProperties");
2713  if(!cadPropNode) return false;
2714 
2715  auto position = cadPropNode->first_node("Position");
2716  double posX = GetNodeValueDouble(position, "X");
2717  double posY = GetNodeValueDouble(position, "Y");
2718  auto size = cadPropNode->first_node("Size");
2719  double width = GetNodeValueDouble(size, "Width");
2720  double height = GetNodeValueDouble(size, "Height");
2721  double angle = GetNodeValueDouble(cadPropNode, "Angle");
2722 
2723  std::vector<double> numerator, denominator;
2724  auto numeratorNode = tfNode->first_node("Numerator");
2725  auto nValue = numeratorNode->first_node("Value");
2726  while(nValue) {
2727  double value = 0.0;
2728  wxString(nValue->value()).ToCDouble(&value);
2729  numerator.push_back(value);
2730  nValue = nValue->next_sibling("Value");
2731  }
2732  auto denominatorNode = tfNode->first_node("Denominator");
2733  auto dValue = denominatorNode->first_node("Value");
2734  while(dValue) {
2735  double value = 0.0;
2736  wxString(dValue->value()).ToCDouble(&value);
2737  denominator.push_back(value);
2738  dValue = dValue->next_sibling("Value");
2739  }
2740 
2741  std::vector<Node*> nodeVector;
2742  if(!OpenControlNodeList(tfNode, nodeVector)) return false;
2743 
2744  tf->SetWidth(width);
2745  tf->SetHeight(height);
2746  tf->SetAngle(angle);
2747  tf->SetPosition(wxPoint2DDouble(posX, posY));
2748 
2749  tf->SetNumerator(numerator);
2750  tf->SetDenominator(denominator);
2751 
2752  tf->StartMove(tf->GetPosition());
2753  tf->SetNodeList(nodeVector);
2754 
2755  tf->UpdateTFText();
2756 
2757  elementList.push_back(tf);
2758 
2759  tfNode = tfNode->next_sibling("TransferFunction");
2760  }
2761  }
2762  //}
2763 
2764  // Connection line
2765  auto connectionListNode = elementsNode->first_node("ConnectionList");
2766  if(connectionListNode) {
2767  auto connNode = connectionListNode->first_node("Connection");
2768  while(connNode) {
2769  ConnectionLine* cLine = NULL;
2770  int id = GetAttributeValueInt(connNode, "ID");
2771 
2772  auto cadPropNode = connNode->first_node("CADProperties");
2773  if(!cadPropNode) return false;
2774  double offset = GetNodeValueDouble(cadPropNode, "Offset");
2775 
2776  auto parentList = connNode->first_node("ParentList");
2777  if(!parentList) return false;
2778 
2779  auto parentNode = parentList->first_node("Parent");
2780  bool firstNode = true;
2781  while(parentNode) {
2782  int elementID = GetNodeValueInt(parentNode, "ElementID");
2783  int nodeID = GetNodeValueInt(parentNode, "NodeID");
2784 
2785  ControlElement* element = GetControlElementFromID(elementList, elementID);
2786  Node* node = element->GetNodeList()[nodeID];
2787 
2788  if(firstNode) cLine = new ConnectionLine(node, id);
2789  cLine->AddParent(element);
2790  element->AddChild(cLine);
2791  if(!firstNode) cLine->AppendNode(node, element);
2792 
2793  if(firstNode) firstNode = false;
2794  parentNode = parentNode->next_sibling("Parent");
2795  }
2796 
2797  auto parentLine = connNode->first_node("ParentLine");
2798  if(!parentLine) return false;
2799  int parentLineID = GetAttributeValueInt(parentLine, "ID");
2800  if(parentLineID != -1) {
2801  for(auto it = connectionList.begin(), itEnd = connectionList.end(); it != itEnd; ++it) {
2802  ConnectionLine* parent = *it;
2803  if(parent->GetID() == parentLineID) {
2804  cLine->SetParentLine(parent);
2805  parent->AddChild(cLine);
2806  }
2807  }
2808  }
2809 
2810  cLine->SetOffset(offset);
2811  cLine->UpdatePoints();
2812  connectionList.push_back(cLine);
2813  connNode = connNode->next_sibling("Connection");
2814  }
2815  }
2816  ctrlContainer->FillContainer(elementList, connectionList);
2817  return true;
2818 }
2819 
2820 void FileHanding::SaveControlNodes(rapidxml::xml_document<>& doc,
2821  rapidxml::xml_node<>* nodesN,
2822  std::vector<Node*> nodeList)
2823 {
2824  int id = 0;
2825  for(auto it = nodeList.begin(), itEnd = nodeList.end(); it != itEnd; ++it) {
2826  Node* node = *it;
2827  node->SetID(id);
2828  auto nodeN = AppendNode(doc, nodesN, "Node");
2829  SetNodeAttribute(doc, nodeN, "ID", id);
2830  auto nodePosition = AppendNode(doc, nodeN, "Position");
2831  auto posNodeX = AppendNode(doc, nodePosition, "X");
2832  SetNodeValue(doc, posNodeX, node->GetPosition().m_x);
2833  auto posNodeY = AppendNode(doc, nodePosition, "Y");
2834  SetNodeValue(doc, posNodeY, node->GetPosition().m_y);
2835  auto angle = AppendNode(doc, nodeN, "Angle");
2836  SetNodeValue(doc, angle, node->GetAngle());
2837  auto nodeType = AppendNode(doc, nodeN, "Type");
2838  SetNodeValue(doc, nodeType, node->GetNodeType());
2839  id++;
2840  }
2841 }
2842 
2843 ControlElement* FileHanding::GetControlElementFromID(std::vector<ControlElement*> elementList, int id)
2844 {
2845  for(auto it = elementList.begin(), itEnd = elementList.end(); it != itEnd; ++it) {
2846  ControlElement* element = *it;
2847  if(element->GetID() == id) return element;
2848  }
2849  return NULL;
2850 }
2851 
2852 bool FileHanding::OpenControlNodeList(rapidxml::xml_node<>* elementNode, std::vector<Node*>& nodeVector)
2853 {
2854  auto nodeList = elementNode->first_node("NodeList");
2855  if(!nodeList) return false;
2856  auto nodeN = nodeList->first_node("Node");
2857  while(nodeN) {
2858  auto nodePosition = nodeN->first_node("Position");
2859  double nodePosX = GetNodeValueDouble(nodePosition, "X");
2860  double nodePosY = GetNodeValueDouble(nodePosition, "Y");
2861  double nodeAngle = GetNodeValueDouble(nodeN, "Angle");
2862  Node::NodeType nodeType = (Node::NodeType)GetNodeValueInt(nodeN, "Type");
2863  Node* node = new Node(wxPoint2DDouble(nodePosX, nodePosY), nodeType, 2.0);
2864  node->SetAngle(nodeAngle);
2865  nodeVector.push_back(node);
2866  nodeN = nodeN->next_sibling("Node");
2867  }
2868  return true;
2869 }
2870 
2871 rapidxml::xml_node<>* FileHanding::AppendNode(rapidxml::xml_document<>& doc,
2872  rapidxml::xml_node<>* parentNode,
2873  const char* name,
2874  rapidxml::node_type nodeType)
2875 {
2876  rapidxml::xml_node<>* node = doc.allocate_node(nodeType, name);
2877  parentNode->append_node(node);
2878  return node;
2879 }
2880 
2881 void FileHanding::SetNodeValue(rapidxml::xml_document<>& doc, rapidxml::xml_node<>* node, wxString value)
2882 {
2883  node->value(doc.allocate_string(value.mb_str()));
2884 }
2885 
2886 void FileHanding::SetNodeValue(rapidxml::xml_document<>& doc, rapidxml::xml_node<>* node, int value)
2887 {
2888  node->value(doc.allocate_string(wxString::Format("%d", value).mb_str()));
2889 }
2890 
2891 void FileHanding::SetNodeValue(rapidxml::xml_document<>& doc, rapidxml::xml_node<>* node, double value)
2892 {
2893  node->value(doc.allocate_string(wxString::FromCDouble(value, 13).mb_str()));
2894 }
2895 
2896 void FileHanding::SetNodeAttribute(rapidxml::xml_document<>& doc,
2897  rapidxml::xml_node<>* node,
2898  const char* atrName,
2899  wxString value)
2900 {
2901  node->append_attribute(doc.allocate_attribute(atrName, doc.allocate_string(value.mb_str())));
2902 }
2903 
2904 void FileHanding::SetNodeAttribute(rapidxml::xml_document<>& doc,
2905  rapidxml::xml_node<>* node,
2906  const char* atrName,
2907  int value)
2908 {
2909  node->append_attribute(
2910  doc.allocate_attribute(atrName, doc.allocate_string(wxString::Format("%d", value).mb_str())));
2911 }
2912 
2913 void FileHanding::SetNodeAttribute(rapidxml::xml_document<>& doc,
2914  rapidxml::xml_node<>* node,
2915  const char* atrName,
2916  double value)
2917 {
2918  node->append_attribute(
2919  doc.allocate_attribute(atrName, doc.allocate_string(wxString::FromCDouble(value, 13).mb_str())));
2920 }
2921 
2922 double FileHanding::GetNodeValueDouble(rapidxml::xml_node<>* parent, const char* nodeName)
2923 {
2924  double dValue = 0.0;
2925  if(parent) {
2926  auto node = parent->first_node(nodeName);
2927  if(node) wxString(node->value()).ToCDouble(&dValue);
2928  }
2929  return dValue;
2930 }
2931 
2932 int FileHanding::GetNodeValueInt(rapidxml::xml_node<>* parent, const char* nodeName)
2933 {
2934  long iValue = -1;
2935  if(parent) {
2936  auto node = parent->first_node(nodeName);
2937  if(node) wxString(node->value()).ToCLong(&iValue);
2938  }
2939  return (int)iValue;
2940 }
2941 
2942 int FileHanding::GetAttributeValueInt(rapidxml::xml_node<>* parent, const char* nodeName, const char* atrName)
2943 {
2944  long iValue = -1;
2945  if(parent) {
2946  auto node = parent->first_node(nodeName);
2947  if(node) {
2948  auto atr = node->first_attribute(atrName);
2949  if(atr) wxString(atr->value()).ToCLong(&iValue);
2950  }
2951  }
2952  return (int)iValue;
2953 }
2954 
2955 int FileHanding::GetAttributeValueInt(rapidxml::xml_node<>* node, const char* atrName)
2956 {
2957  long intValue;
2958  auto atr = node->first_attribute(atrName);
2959  if(!atr) return false;
2960  wxString(atr->value()).ToCLong(&intValue);
2961  return (int)intValue;
2962 }
double GetAngle() const
Get the element angle.
Definition: Element.h:212
+
Element that shows power element informations in workspace.
Definition: Text.h:75
+
General and simulation data manager.
Multiplies two inputs.
Definition: Multiplier.h:32
std::vector< double > swTime
Definition: PowerElement.h:95
virtual void StartMove(wxPoint2DDouble position)
Update the element attributes related to the movement.
Definition: Machines.cpp:146
@@ -98,7 +99,7 @@ $(document).ready(function(){initNavTree('_file_handing_8cpp_source.html','');})
virtual void RemoveParent(Element *parent)
Remove a parent.
Definition: Branch.cpp:105
Base class of all elements of the program. This class is responsible for manage graphical and his dat...
Definition: Element.h:113
const std::vector< Transformer * > GetTransformerList() const
Get the transformers of the system (use GetElementsFromList first).
-
virtual void Rotate(bool clockwise=true)
Rotate the element.
Definition: Text.cpp:162
+
virtual void Rotate(bool clockwise=true)
Rotate the element.
Definition: Text.cpp:114
Sum the all inputs (can choose the input signal).
Definition: Sum.h:33
virtual std::vector< Element * > GetParentList() const
Get the parent list.
Definition: Element.h:506
void SetWidth(double width)
Set element width.
Definition: Element.h:151
@@ -132,6 +133,8 @@ $(document).ready(function(){initNavTree('_file_handing_8cpp_source.html','');})
bool IsOnline() const
Checks if the element is online or offline.
Definition: Element.h:227
Switching data of power elements.
Definition: PowerElement.h:93
virtual void Move(wxPoint2DDouble position)
Move the element other position.
Definition: Shunt.cpp:32
+ +
Control element that divides two inputs.
Definition: Divider.h:32
Generates an output following an exponential function.
Definition: Exponential.h:32
void SetAngle(double angle)
Set element angle.
Definition: Element.h:156
double GetWidth() const
Get the element width.
Definition: Element.h:207
@@ -142,11 +145,11 @@ $(document).ready(function(){initNavTree('_file_handing_8cpp_source.html','');})
virtual void AddChild(Element *child)
Add a child to the child list.
Definition: Element.cpp:353
Power line element.
Definition: Line.h:59
-
Loas shunt power element.
Definition: Load.h:42
+
Loas shunt power element.
Definition: Load.h:73
double GetHeight() const
Get the element height.
Definition: Element.h:197
virtual std::vector< wxPoint2DDouble > GetPointList() const
Get the list of points that connect the element to bus.
Definition: Element.h:232
Limits the rising and/or falling rate.
Definition: RateLimiter.h:32
-
Class that can contain all control elements. Can identify (using RTTI) the elements from a generic li...
+
Class that can contain all control elements. Can identify (using RTTI) the elements from a generic li...
const std::vector< Load * > GetLoadList() const
Get the loads of the system (use GetElementsFromList first).
@@ -160,7 +163,7 @@ $(document).ready(function(){initNavTree('_file_handing_8cpp_source.html','');})
SwitchingType
Type of switching.
Definition: PowerElement.h:69
Calculates the time response by a frequency domain transfer function.
Induction motor power element.
Definition: IndMotor.h:40
- +
virtual bool AddParent(Element *parent, wxPoint2DDouble position)
Add a parent to the element. This method must be used on power elements that connect to a bus...
Definition: Transformer.cpp:39
const std::vector< SyncMotor * > GetSyncMotorList() const
Get the synchronous motors of the system (use GetElementsFromList first).
virtual int GetID() const
Get the element ID.
Definition: Element.h:272
diff --git a/docs/doxygen/html/_file_handing_8h_source.html b/docs/doxygen/html/_file_handing_8h_source.html index 08ec41e..c4be33b 100644 --- a/docs/doxygen/html/_file_handing_8h_source.html +++ b/docs/doxygen/html/_file_handing_8h_source.html @@ -92,10 +92,10 @@ $(document).ready(function(){initNavTree('_file_handing_8h_source.html','');});
Save and opens the projects created on disk.
Definition: FileHanding.h:43
-
Class that can contain all control elements. Can identify (using RTTI) the elements from a generic li...
+
Class that can contain all control elements. Can identify (using RTTI) the elements from a generic li...
- +
This class manages the graphical and power elements. It is responsible for handling the user&#39;s intera...
Definition: Workspace.h:81
diff --git a/docs/doxygen/html/_formulas.tex b/docs/doxygen/html/_formulas.tex deleted file mode 100644 index 7aacf93..0000000 --- a/docs/doxygen/html/_formulas.tex +++ /dev/null @@ -1,8 +0,0 @@ -\documentclass{article} -\usepackage{epsfig} -\pagestyle{empty} -\begin{document} -$ output = A\cdot e^{B\cdot input} $ -\pagebreak - -\end{document} diff --git a/docs/doxygen/html/_gain_8cpp_source.html b/docs/doxygen/html/_gain_8cpp_source.html index e1bc08a..0820a21 100644 --- a/docs/doxygen/html/_gain_8cpp_source.html +++ b/docs/doxygen/html/_gain_8cpp_source.html @@ -88,20 +88,21 @@ $(document).ready(function(){initNavTree('_gain_8cpp_source.html','');});
Gain.cpp
-
1 /*
2  * Copyright (C) 2017 Thales Lima Oliveira <thales@ufu.br>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program. If not, see <https://www.gnu.org/licenses/>.
16  */
17 
18 #include "Gain.h"
19 #include "GainForm.h"
20 
21 Gain::Gain(int id) : ControlElement(id)
22 {
23  m_triPts.resize(3);
24  SetValue(m_value);
25  Node* nodeIn = new Node(m_position + wxPoint2DDouble(-m_width / 2, 0), Node::NODE_IN, m_borderSize);
26  nodeIn->StartMove(m_position);
27  Node* nodeOut = new Node(m_position + wxPoint2DDouble(m_width / 2, 0), Node::NODE_OUT, m_borderSize);
28  nodeOut->SetAngle(180.0);
29  nodeOut->StartMove(m_position);
30  m_nodeList.push_back(nodeIn);
31  m_nodeList.push_back(nodeOut);
32 }
33 
34 Gain::~Gain() {}
35 void Gain::Draw(wxPoint2DDouble translation, double scale) const
36 {
37  if(m_selected) {
38  glColor4dv(m_selectionColour.GetRGBA());
39  double borderSize = (m_borderSize * 2.0 + 1.0) / scale;
40  std::vector<wxPoint2DDouble> m_triSelectedPts;
41  if(m_angle == 0.0) {
42  m_triSelectedPts.push_back(m_triPts[0] - wxPoint2DDouble(borderSize / 2, borderSize / 1.5));
43  m_triSelectedPts.push_back(m_triPts[1] - wxPoint2DDouble(borderSize / 2, -borderSize / 1.5));
44  m_triSelectedPts.push_back(m_triPts[2] - wxPoint2DDouble(-borderSize, 0));
45  } else if(m_angle == 90.0) {
46  m_triSelectedPts.push_back(m_triPts[0] - wxPoint2DDouble(borderSize / 1.5, borderSize / 2));
47  m_triSelectedPts.push_back(m_triPts[1] - wxPoint2DDouble(-borderSize / 1.5, borderSize / 2));
48  m_triSelectedPts.push_back(m_triPts[2] - wxPoint2DDouble(0, -borderSize));
49  } else if(m_angle == 180.0) {
50  m_triSelectedPts.push_back(m_triPts[0] - wxPoint2DDouble(borderSize, 0));
51  m_triSelectedPts.push_back(m_triPts[1] - wxPoint2DDouble(-borderSize / 2, borderSize / 1.5));
52  m_triSelectedPts.push_back(m_triPts[2] - wxPoint2DDouble(-borderSize / 2, -borderSize / 1.5));
53  } else if(m_angle == 270.0) {
54  m_triSelectedPts.push_back(m_triPts[0] - wxPoint2DDouble(0, borderSize));
55  m_triSelectedPts.push_back(m_triPts[1] - wxPoint2DDouble(-borderSize / 1.5, -borderSize / 2));
56  m_triSelectedPts.push_back(m_triPts[2] - wxPoint2DDouble(borderSize / 1.5, -borderSize / 2));
57  }
58  DrawTriangle(m_triSelectedPts);
59  }
60  glLineWidth(1.0);
61  glColor4d(1.0, 1.0, 1.0, 1.0);
62  DrawTriangle(m_triPts);
63  glColor4d(0.0, 0.0, 0.0, 1.0);
64  DrawTriangle(m_triPts, GL_LINE_LOOP);
65 
66  // Plot number.
67  glEnable(GL_TEXTURE_2D);
68  glColor4d(0.0, 0.0, 0.0, 1.0);
69  m_glStringValue->bind();
70  if(m_angle == 0.0)
71  m_glStringValue->render(m_position.m_x - m_width / 2 + m_glStringValue->getWidth() / 2 + 2 + m_borderSize,
72  m_position.m_y);
73  else if(m_angle == 90.0)
74  m_glStringValue->render(m_position.m_x,
75  m_position.m_y - m_height / 2 + m_glStringValue->getheight() / 2 + 2 + m_borderSize);
76  else if(m_angle == 180.0)
77  m_glStringValue->render(m_position.m_x + m_width / 2 - m_glStringValue->getWidth() / 2 - 2 - m_borderSize,
78  m_position.m_y);
79  else if(m_angle == 270.0)
80  m_glStringValue->render(m_position.m_x,
81  m_position.m_y + m_height / 2 - m_glStringValue->getheight() / 2 - 2 - m_borderSize);
82  glDisable(GL_TEXTURE_2D);
83 
84  glColor4d(0.0, 0.0, 0.0, 1.0);
85  DrawNodes();
86 }
87 
88 bool Gain::ShowForm(wxWindow* parent, Element* element)
89 {
90  GainForm* form = new GainForm(parent, this);
91  if(form->ShowModal() == wxID_OK) {
92  form->Destroy();
93  return true;
94  }
95  form->Destroy();
96  return false;
97 }
98 
99 void Gain::Rotate(bool clockwise)
100 {
101  if(clockwise)
102  m_angle += 90.0;
103  else
104  m_angle -= 90.0;
105  if(m_angle >= 360.0)
106  m_angle = 0.0;
107  else if(m_angle < 0)
108  m_angle = 270.0;
109 
110  UpdatePoints();
111 
112  for(auto it = m_nodeList.begin(), itEnd = m_nodeList.end(); it != itEnd; ++it) {
113  Node* node = *it;
114  node->Rotate(clockwise);
115  }
116 }
117 
118 void Gain::SetValue(double value)
119 {
120  m_value = value;
121  wxString text = "";
122  if(std::abs(m_value) > 1e3 || std::abs(m_value) < 1e-3)
123  text = wxString::Format("%g", m_value);
124  else
125  text = StringFromDouble(m_value);
126 
127  wxFont font(m_fontSize, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL);
128  wxScreenDC dc;
129 
130  if(m_glStringValue) {
131  delete m_glStringValue;
132  m_glStringValue = NULL;
133  }
134  m_glStringValue = new wxGLString(text);
135  m_glStringValue->setFont(font);
136  m_glStringValue->consolidate(&dc);
137 
138  m_width = m_glStringValue->getWidth() + 18 + 2 * m_borderSize;
139  m_height = m_glStringValue->getheight() + 18 + 2 * m_borderSize;
140 
141  if(m_width > m_height)
142  m_height = m_width;
143  else
144  m_width = m_height;
145 
146  SetPosition(m_position); // Update rectangle.
147 
148  UpdatePoints();
149 }
150 
151 void Gain::UpdatePoints()
152 {
153  if(m_nodeList.size() != 0) {
154  if(m_angle == 0.0) {
155  m_triPts[0] = m_rect.GetLeftTop() + wxPoint2DDouble(m_borderSize, m_borderSize);
156  m_triPts[1] = m_rect.GetLeftBottom() + wxPoint2DDouble(m_borderSize, -m_borderSize);
157  m_triPts[2] = m_position + wxPoint2DDouble(m_width / 2 - m_borderSize, 0);
158  m_nodeList[0]->SetPosition(m_position + wxPoint2DDouble(-m_width / 2, 0));
159  m_nodeList[1]->SetPosition(m_position + wxPoint2DDouble(m_width / 2 - 2, 0));
160  } else if(m_angle == 90.0) {
161  m_triPts[0] = m_rect.GetLeftTop() + wxPoint2DDouble(m_borderSize, m_borderSize);
162  m_triPts[1] = m_rect.GetRightTop() + wxPoint2DDouble(-m_borderSize, m_borderSize);
163  m_triPts[2] = m_position + wxPoint2DDouble(0, m_height / 2 - m_borderSize);
164  m_nodeList[0]->SetPosition(m_position + wxPoint2DDouble(0, -m_height / 2));
165  m_nodeList[1]->SetPosition(m_position + wxPoint2DDouble(0, m_height / 2 - 2));
166  } else if(m_angle == 180.0) {
167  m_triPts[0] = m_position + wxPoint2DDouble(-m_width / 2 + m_borderSize, 0);
168  m_triPts[1] = m_rect.GetRightTop() + wxPoint2DDouble(-m_borderSize, m_borderSize);
169  m_triPts[2] = m_rect.GetRightBottom() + wxPoint2DDouble(-m_borderSize, -m_borderSize);
170  m_nodeList[0]->SetPosition(m_position + wxPoint2DDouble(m_width / 2, 0));
171  m_nodeList[1]->SetPosition(m_position + wxPoint2DDouble(-m_width / 2 + 2, 0));
172  } else if(m_angle == 270.0) {
173  m_triPts[0] = m_position + wxPoint2DDouble(0, -m_height / 2 + m_borderSize);
174  m_triPts[1] = m_rect.GetRightBottom() + wxPoint2DDouble(-m_borderSize, -m_borderSize);
175  m_triPts[2] = m_rect.GetLeftBottom() + wxPoint2DDouble(m_borderSize, -m_borderSize);
176  m_nodeList[0]->SetPosition(m_position + wxPoint2DDouble(0, m_height / 2));
177  m_nodeList[1]->SetPosition(m_position + wxPoint2DDouble(0, -m_height / 2 + 2));
178  }
179  }
180 }
181 
182 void Gain::Move(wxPoint2DDouble position)
183 {
184  SetPosition(m_movePos + position - m_moveStartPt);
185  UpdatePoints();
186 }
187 
188 bool Gain::Solve(double input, double timeStep)
189 {
190  m_output = input * m_value;
191  return true;
192 }
193 
195 {
196  Gain* copy = new Gain(m_elementID);
197  *copy = *this;
198  m_glStringValue = NULL;
199  SetValue(m_value);
200  return copy;
201 }
virtual void Move(wxPoint2DDouble position)
Move the element other position.
Definition: Gain.cpp:182
+
1 /*
2  * Copyright (C) 2017 Thales Lima Oliveira <thales@ufu.br>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program. If not, see <https://www.gnu.org/licenses/>.
16  */
17 
18 #include "Gain.h"
19 #include "GainForm.h"
20 
21 Gain::Gain(int id) : ControlElement(id)
22 {
23  m_triPts.resize(3);
24  SetValue(m_value);
25  Node* nodeIn = new Node(m_position + wxPoint2DDouble(-m_width / 2, 0), Node::NODE_IN, m_borderSize);
26  nodeIn->StartMove(m_position);
27  Node* nodeOut = new Node(m_position + wxPoint2DDouble(m_width / 2, 0), Node::NODE_OUT, m_borderSize);
28  nodeOut->SetAngle(180.0);
29  nodeOut->StartMove(m_position);
30  m_nodeList.push_back(nodeIn);
31  m_nodeList.push_back(nodeOut);
32 }
33 
34 Gain::~Gain()
35 {
36  if(m_glText) delete m_glText;
37 }
38 void Gain::Draw(wxPoint2DDouble translation, double scale) const
39 {
40  if(m_selected) {
41  glColor4dv(m_selectionColour.GetRGBA());
42  double borderSize = (m_borderSize * 2.0 + 1.0) / scale;
43  std::vector<wxPoint2DDouble> m_triSelectedPts;
44  if(m_angle == 0.0) {
45  m_triSelectedPts.push_back(m_triPts[0] - wxPoint2DDouble(borderSize / 2, borderSize / 1.5));
46  m_triSelectedPts.push_back(m_triPts[1] - wxPoint2DDouble(borderSize / 2, -borderSize / 1.5));
47  m_triSelectedPts.push_back(m_triPts[2] - wxPoint2DDouble(-borderSize, 0));
48  } else if(m_angle == 90.0) {
49  m_triSelectedPts.push_back(m_triPts[0] - wxPoint2DDouble(borderSize / 1.5, borderSize / 2));
50  m_triSelectedPts.push_back(m_triPts[1] - wxPoint2DDouble(-borderSize / 1.5, borderSize / 2));
51  m_triSelectedPts.push_back(m_triPts[2] - wxPoint2DDouble(0, -borderSize));
52  } else if(m_angle == 180.0) {
53  m_triSelectedPts.push_back(m_triPts[0] - wxPoint2DDouble(borderSize, 0));
54  m_triSelectedPts.push_back(m_triPts[1] - wxPoint2DDouble(-borderSize / 2, borderSize / 1.5));
55  m_triSelectedPts.push_back(m_triPts[2] - wxPoint2DDouble(-borderSize / 2, -borderSize / 1.5));
56  } else if(m_angle == 270.0) {
57  m_triSelectedPts.push_back(m_triPts[0] - wxPoint2DDouble(0, borderSize));
58  m_triSelectedPts.push_back(m_triPts[1] - wxPoint2DDouble(-borderSize / 1.5, -borderSize / 2));
59  m_triSelectedPts.push_back(m_triPts[2] - wxPoint2DDouble(borderSize / 1.5, -borderSize / 2));
60  }
61  DrawTriangle(m_triSelectedPts);
62  }
63  glLineWidth(1.0);
64  glColor4d(1.0, 1.0, 1.0, 1.0);
65  DrawTriangle(m_triPts);
66  glColor4d(0.0, 0.0, 0.0, 1.0);
67  DrawTriangle(m_triPts, GL_LINE_LOOP);
68 
69  // Plot number.
70  glColor4d(0.0, 0.0, 0.0, 1.0);
71  if(m_angle == 0.0)
72  m_glText->Draw(m_position + wxPoint2DDouble(-m_width / 2 + m_glText->GetWidth() / 2 + 2 + m_borderSize, 0.0));
73  else if(m_angle == 90.0)
74  m_glText->Draw(m_position + wxPoint2DDouble(0.0, -m_height / 2 + m_glText->GetHeight() / 2 + 2 + m_borderSize));
75  else if(m_angle == 180.0)
76  m_glText->Draw(m_position + wxPoint2DDouble(m_width / 2 - m_glText->GetWidth() / 2 - 2 - m_borderSize, 0.0));
77  else if(m_angle == 270.0)
78  m_glText->Draw(m_position + wxPoint2DDouble(0.0, m_height / 2 - m_glText->GetHeight() / 2 - 2 - m_borderSize));
79 
80  glColor4d(0.0, 0.0, 0.0, 1.0);
81  DrawNodes();
82 }
83 
84 bool Gain::ShowForm(wxWindow* parent, Element* element)
85 {
86  GainForm* form = new GainForm(parent, this);
87  if(form->ShowModal() == wxID_OK) {
88  form->Destroy();
89  return true;
90  }
91  form->Destroy();
92  return false;
93 }
94 
95 void Gain::Rotate(bool clockwise)
96 {
97  if(clockwise)
98  m_angle += 90.0;
99  else
100  m_angle -= 90.0;
101  if(m_angle >= 360.0)
102  m_angle = 0.0;
103  else if(m_angle < 0)
104  m_angle = 270.0;
105 
106  UpdatePoints();
107 
108  for(auto it = m_nodeList.begin(), itEnd = m_nodeList.end(); it != itEnd; ++it) {
109  Node* node = *it;
110  node->Rotate(clockwise);
111  }
112 }
113 
114 void Gain::SetValue(double value)
115 {
116  m_value = value;
117  wxString text = "";
118  if(std::abs(m_value) > 1e3 || std::abs(m_value) < 1e-3)
119  text = wxString::Format("%g", m_value);
120  else
121  text = StringFromDouble(m_value);
122 
123  if(m_glText)
124  m_glText->SetText(text);
125  else
126  m_glText = new OpenGLText(text);
127 
128  m_width = m_glText->GetWidth() + 18 + 2 * m_borderSize;
129  m_height = m_glText->GetHeight() + 18 + 2 * m_borderSize;
130 
131  if(m_width > m_height)
132  m_height = m_width;
133  else
134  m_width = m_height;
135 
136  SetPosition(m_position); // Update rectangle.
137 
138  UpdatePoints();
139 }
140 
141 void Gain::UpdatePoints()
142 {
143  if(m_nodeList.size() != 0) {
144  if(m_angle == 0.0) {
145  m_triPts[0] = m_rect.GetLeftTop() + wxPoint2DDouble(m_borderSize, m_borderSize);
146  m_triPts[1] = m_rect.GetLeftBottom() + wxPoint2DDouble(m_borderSize, -m_borderSize);
147  m_triPts[2] = m_position + wxPoint2DDouble(m_width / 2 - m_borderSize, 0);
148  m_nodeList[0]->SetPosition(m_position + wxPoint2DDouble(-m_width / 2, 0));
149  m_nodeList[1]->SetPosition(m_position + wxPoint2DDouble(m_width / 2 - 2, 0));
150  } else if(m_angle == 90.0) {
151  m_triPts[0] = m_rect.GetLeftTop() + wxPoint2DDouble(m_borderSize, m_borderSize);
152  m_triPts[1] = m_rect.GetRightTop() + wxPoint2DDouble(-m_borderSize, m_borderSize);
153  m_triPts[2] = m_position + wxPoint2DDouble(0, m_height / 2 - m_borderSize);
154  m_nodeList[0]->SetPosition(m_position + wxPoint2DDouble(0, -m_height / 2));
155  m_nodeList[1]->SetPosition(m_position + wxPoint2DDouble(0, m_height / 2 - 2));
156  } else if(m_angle == 180.0) {
157  m_triPts[0] = m_position + wxPoint2DDouble(-m_width / 2 + m_borderSize, 0);
158  m_triPts[1] = m_rect.GetRightTop() + wxPoint2DDouble(-m_borderSize, m_borderSize);
159  m_triPts[2] = m_rect.GetRightBottom() + wxPoint2DDouble(-m_borderSize, -m_borderSize);
160  m_nodeList[0]->SetPosition(m_position + wxPoint2DDouble(m_width / 2, 0));
161  m_nodeList[1]->SetPosition(m_position + wxPoint2DDouble(-m_width / 2 + 2, 0));
162  } else if(m_angle == 270.0) {
163  m_triPts[0] = m_position + wxPoint2DDouble(0, -m_height / 2 + m_borderSize);
164  m_triPts[1] = m_rect.GetRightBottom() + wxPoint2DDouble(-m_borderSize, -m_borderSize);
165  m_triPts[2] = m_rect.GetLeftBottom() + wxPoint2DDouble(m_borderSize, -m_borderSize);
166  m_nodeList[0]->SetPosition(m_position + wxPoint2DDouble(0, m_height / 2));
167  m_nodeList[1]->SetPosition(m_position + wxPoint2DDouble(0, -m_height / 2 + 2));
168  }
169  }
170 }
171 
172 void Gain::Move(wxPoint2DDouble position)
173 {
174  SetPosition(m_movePos + position - m_moveStartPt);
175  UpdatePoints();
176 }
177 
178 bool Gain::Solve(double input, double timeStep)
179 {
180  m_output = input * m_value;
181  return true;
182 }
183 
185 {
186  Gain* copy = new Gain(m_elementID);
187  *copy = *this;
188  copy->m_glText = m_glText->GetCopy();
189  return copy;
190 }
191 
193 {
194  SetValue(m_value);
195  if(!m_glText->IsTextureOK()) return false;
196  return true;
197 }
virtual void Move(wxPoint2DDouble position)
Move the element other position.
Definition: Gain.cpp:172
Base class of all elements of the program. This class is responsible for manage graphical and his dat...
Definition: Element.h:113
Provide an output multiplying the input by a constant.
Definition: Gain.h:35
Node of a control element. This class manages the user interaction with the connection and control el...
-
virtual Element * GetCopy()
Get a the element copy.
Definition: Gain.cpp:194
-
virtual bool ShowForm(wxWindow *parent, Element *element)
Show element data form.
Definition: Gain.cpp:88
+
virtual Element * GetCopy()
Get a the element copy.
Definition: Gain.cpp:184
+
virtual bool UpdateText()
Update the OpenGL text in the element (if present).
Definition: Gain.cpp:192
+
virtual bool ShowForm(wxWindow *parent, Element *element)
Show element data form.
Definition: Gain.cpp:84
-
virtual void Rotate(bool clockwise=true)
Rotate the element.
Definition: Gain.cpp:99
+
virtual void Rotate(bool clockwise=true)
Rotate the element.
Definition: Gain.cpp:95
Form to edit the gain control data.
Definition: GainForm.h:31
-
virtual bool Solve(double input, double timeStep)
Multiply the input by a constant.
Definition: Gain.cpp:188
-
virtual void Draw(wxPoint2DDouble translation, double scale) const
Draw the element.
Definition: Gain.cpp:35
+
Class to draw text on OpenGL using wxWidgets.
Definition: OpenGLText.h:31
+
virtual bool Solve(double input, double timeStep)
Multiply the input by a constant.
Definition: Gain.cpp:178
+
virtual void Draw(wxPoint2DDouble translation, double scale) const
Draw the element.
Definition: Gain.cpp:38
-
diff --git a/docs/doxygen/html/_gain_8h.html b/docs/doxygen/html/_gain_8h.html index f732cac..c191167 100644 --- a/docs/doxygen/html/_gain_8h.html +++ b/docs/doxygen/html/_gain_8h.html @@ -92,7 +92,7 @@ $(document).ready(function(){initNavTree('_gain_8h.html','');});
#include "ControlElement.h"
#include <wx/dcscreen.h>
-#include "wxGLString.h"
+#include "OpenGLText.h"

Go to the source code of this file.

diff --git a/docs/doxygen/html/_gain_8h_source.html b/docs/doxygen/html/_gain_8h_source.html index 99cf636..1add68f 100644 --- a/docs/doxygen/html/_gain_8h_source.html +++ b/docs/doxygen/html/_gain_8h_source.html @@ -88,20 +88,22 @@ $(document).ready(function(){initNavTree('_gain_8h_source.html','');});
Gain.h
-Go to the documentation of this file.
1 /*
2  * Copyright (C) 2017 Thales Lima Oliveira <thales@ufu.br>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program. If not, see <https://www.gnu.org/licenses/>.
16  */
17 
18 #ifndef GAIN_H
19 #define GAIN_H
20 
21 #include "ControlElement.h"
22 
23 #include <wx/dcscreen.h>
24 #include "wxGLString.h"
25 
26 class GainForm;
27 
35 class Gain : public ControlElement
36 {
37  public:
38  Gain(int id);
39  ~Gain();
40 
41  virtual void Draw(wxPoint2DDouble translation, double scale) const;
42  virtual bool Contains(wxPoint2DDouble position) const { return m_rect.Contains(position); }
43  virtual bool Intersects(wxRect2DDouble rect) const { return m_rect.Intersects(rect); }
44  virtual bool ShowForm(wxWindow* parent, Element* element);
45  virtual void Rotate(bool clockwise = true);
46  virtual void Move(wxPoint2DDouble position);
47  virtual void UpdateText() { SetValue(m_value); }
48  virtual void SetValue(double value);
49  virtual double GetValue() const { return m_value; }
50  virtual void UpdatePoints();
59  virtual bool Solve(double input, double timeStep);
60 
61  virtual Element* GetCopy();
62 
63  protected:
64  double m_value = 1.0;
65 
66  wxGLString* m_glStringValue = NULL;
67  int m_fontSize = 10;
68 
69  std::vector<wxPoint2DDouble> m_triPts;
70 };
71 
72 #endif // GAIN_H
virtual void Move(wxPoint2DDouble position)
Move the element other position.
Definition: Gain.cpp:182
+Go to the documentation of this file.
1 /*
2  * Copyright (C) 2017 Thales Lima Oliveira <thales@ufu.br>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program. If not, see <https://www.gnu.org/licenses/>.
16  */
17 
18 #ifndef GAIN_H
19 #define GAIN_H
20 
21 #include "ControlElement.h"
22 
23 #include <wx/dcscreen.h>
24 #include "OpenGLText.h"
25 
26 class GainForm;
27 
35 class Gain : public ControlElement
36 {
37  public:
38  Gain(int id);
39  ~Gain();
40 
41  virtual void Draw(wxPoint2DDouble translation, double scale) const;
42  virtual bool Contains(wxPoint2DDouble position) const { return m_rect.Contains(position); }
43  virtual bool Intersects(wxRect2DDouble rect) const { return m_rect.Intersects(rect); }
44  virtual bool ShowForm(wxWindow* parent, Element* element);
45  virtual void Rotate(bool clockwise = true);
46  virtual void Move(wxPoint2DDouble position);
47  virtual bool UpdateText();
48  virtual void SetValue(double value);
49  virtual double GetValue() const { return m_value; }
50  virtual void UpdatePoints();
59  virtual bool Solve(double input, double timeStep);
60 
61  virtual Element* GetCopy();
62 
63  protected:
64  double m_value = 1.0;
65 
66  OpenGLText* m_glText = NULL;
67 
68  std::vector<wxPoint2DDouble> m_triPts;
69 };
70 
71 #endif // GAIN_H
virtual void Move(wxPoint2DDouble position)
Move the element other position.
Definition: Gain.cpp:172
Base class of all elements of the program. This class is responsible for manage graphical and his dat...
Definition: Element.h:113
Provide an output multiplying the input by a constant.
Definition: Gain.h:35
-
virtual Element * GetCopy()
Get a the element copy.
Definition: Gain.cpp:194
+
virtual Element * GetCopy()
Get a the element copy.
Definition: Gain.cpp:184
virtual bool Intersects(wxRect2DDouble rect) const
Check if the element&#39;s rect intersects other rect.
Definition: Gain.h:43
-
virtual bool ShowForm(wxWindow *parent, Element *element)
Show element data form.
Definition: Gain.cpp:88
-
virtual void Rotate(bool clockwise=true)
Rotate the element.
Definition: Gain.cpp:99
+
virtual bool UpdateText()
Update the OpenGL text in the element (if present).
Definition: Gain.cpp:192
+ +
virtual bool ShowForm(wxWindow *parent, Element *element)
Show element data form.
Definition: Gain.cpp:84
+
virtual void Rotate(bool clockwise=true)
Rotate the element.
Definition: Gain.cpp:95
Form to edit the gain control data.
Definition: GainForm.h:31
+
Class to draw text on OpenGL using wxWidgets.
Definition: OpenGLText.h:31
Base class of a control element. Provide general methods to other control classes.
-
virtual bool Solve(double input, double timeStep)
Multiply the input by a constant.
Definition: Gain.cpp:188
+
virtual bool Solve(double input, double timeStep)
Multiply the input by a constant.
Definition: Gain.cpp:178
virtual bool Contains(wxPoint2DDouble position) const
Checks if the element contains a position.
Definition: Gain.h:42
-
virtual void Draw(wxPoint2DDouble translation, double scale) const
Draw the element.
Definition: Gain.cpp:35
+
virtual void Draw(wxPoint2DDouble translation, double scale) const
Draw the element.
Definition: Gain.cpp:38
-
diff --git a/docs/doxygen/html/_gain_form_8cpp_source.html b/docs/doxygen/html/_gain_form_8cpp_source.html index aa3d409..06542d9 100644 --- a/docs/doxygen/html/_gain_form_8cpp_source.html +++ b/docs/doxygen/html/_gain_form_8cpp_source.html @@ -90,7 +90,7 @@ $(document).ready(function(){initNavTree('_gain_form_8cpp_source.html','');});
1 /*
2  * Copyright (C) 2017 Thales Lima Oliveira <thales@ufu.br>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program. If not, see <https://www.gnu.org/licenses/>.
16  */
17 
18 #include "GainForm.h"
19 #include "Gain.h"
20 
21 GainForm::GainForm(wxWindow* parent, Gain* gain) : GainFormBase(parent)
22 {
23  SetSize(GetBestSize());
24 
25  m_parent = parent;
26  m_gain = gain;
27 
28  m_textCtrlValue->SetValue(m_gain->StringFromDouble(m_gain->GetValue()));
29 }
30 
31 GainForm::~GainForm() {}
32 void GainForm::OnOKButtonClick(wxCommandEvent& event)
33 {
34  if(ValidateData()) EndModal(wxID_OK);
35 }
36 
37 bool GainForm::ValidateData()
38 {
39  double value;
40  if(!m_gain->DoubleFromString(this, m_textCtrlValue->GetValue(), value,
41  _("Value entered incorrectly in the field \"Gain value\".")))
42  return false;
43 
44  m_gain->SetValue(value);
45  return true;
46 }
Provide an output multiplying the input by a constant.
Definition: Gain.h:35
- +
diff --git a/docs/doxygen/html/_gain_form_8h_source.html b/docs/doxygen/html/_gain_form_8h_source.html index a6399b8..72383b1 100644 --- a/docs/doxygen/html/_gain_form_8h_source.html +++ b/docs/doxygen/html/_gain_form_8h_source.html @@ -89,7 +89,7 @@ $(document).ready(function(){initNavTree('_gain_form_8h_source.html','');});
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2017 Thales Lima Oliveira <thales@ufu.br>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program. If not, see <https://www.gnu.org/licenses/>.
16  */
17 
18 #ifndef GAINFORM_H
19 #define GAINFORM_H
20 #include "ElementForm.h"
21 
22 class Gain;
23 
31 class GainForm : public GainFormBase
32 {
33  public:
34  GainForm(wxWindow* parent, Gain* gain);
35  virtual ~GainForm();
36 
37  virtual bool ValidateData();
38 
39  protected:
40  virtual void OnCancelButtonClick(wxCommandEvent& event) { EndModal(wxID_CANCEL); }
41  virtual void OnOKButtonClick(wxCommandEvent& event);
42 
43  wxWindow* m_parent;
44  Gain* m_gain;
45 };
46 #endif // GAINFORM_H
Provide an output multiplying the input by a constant.
Definition: Gain.h:35
- +
Form to edit the gain control data.
Definition: GainForm.h:31
diff --git a/docs/doxygen/html/_general_properties_form_8cpp_source.html b/docs/doxygen/html/_general_properties_form_8cpp_source.html index 614eac2..f4c2ba0 100644 --- a/docs/doxygen/html/_general_properties_form_8cpp_source.html +++ b/docs/doxygen/html/_general_properties_form_8cpp_source.html @@ -88,7 +88,7 @@ $(document).ready(function(){initNavTree('_general_properties_form_8cpp_source.h
GeneralPropertiesForm.cpp
-
1 /*
2  * Copyright (C) 2017 Thales Lima Oliveira <thales@ufu.br>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program. If not, see <https://www.gnu.org/licenses/>.
16  */
17 
18 #include "GeneralPropertiesForm.h"
19 #include "PropertiesData.h"
20 
21 GeneralPropertiesForm::GeneralPropertiesForm(wxWindow* parent, PropertiesData* properties)
23 {
24  m_properties = properties;
25  auto data = m_properties->GetGeneralPropertiesData();
26 
27  // Clear the choices and rebuild to set the correct translations.
28  m_choiceLanguage->Clear();
29  m_choiceLanguage->Insert(_("English"), 0);
30  m_choiceLanguage->Insert(_("Portuguese"), 1);
31  m_choiceTheme->Clear();
32  m_choiceTheme->Insert(_("Light"), 0);
33  m_choiceTheme->Insert(_("Dark"), 1);
34 
35  switch(data.language) {
36  case wxLANGUAGE_ENGLISH: {
37  m_choiceLanguage->SetSelection(0);
38  } break;
39  case wxLANGUAGE_PORTUGUESE_BRAZILIAN: {
40  m_choiceLanguage->SetSelection(1);
41  } break;
42  default: {
43  m_choiceLanguage->SetSelection(wxNOT_FOUND);
44  } break;
45  }
46  switch(data.theme) {
47  case THEME_LIGHT: {
48  m_choiceTheme->SetSelection(0);
49  } break;
50  case THEME_DARK: {
51  m_choiceTheme->SetSelection(1);
52  } break;
53  }
54 }
55 
56 GeneralPropertiesForm::~GeneralPropertiesForm() {}
57 void GeneralPropertiesForm::OnButtonOKClick(wxCommandEvent& event)
58 {
59  if(ValidateData()) EndModal(wxID_OK);
60 }
61 
62 bool GeneralPropertiesForm::ValidateData()
63 {
64  auto data = m_properties->GetGeneralPropertiesData();
65  auto checkData = m_properties->GetGeneralPropertiesData();
66  bool hasChanges = false;
67 
68  wxTextFile file("config.ini");
69  if(!file.Create()) {
70  if(!file.Open()) {
71  // Fail to access the file.
72  wxMessageDialog msgDialog(this,
73  _("It was not possible to access the init file.\nThe settings won't be applied."),
74  _("Error"), wxOK | wxCENTRE | wxICON_ERROR);
75  msgDialog.ShowModal();
76  }
77  file.Clear();
78  }
79 
80  wxString line = "lang=";
81  switch(m_choiceLanguage->GetSelection()) {
82  case 0: {
83  line += "en";
84  data.language = wxLANGUAGE_ENGLISH;
85  } break;
86  case 1: {
87  line += "pt-br";
88  data.language = wxLANGUAGE_PORTUGUESE_BRAZILIAN;
89  } break;
90  }
91  file.AddLine(line);
92  if(data.language != checkData.language) hasChanges = true;
93 
94  line = "theme=";
95  switch(m_choiceTheme->GetSelection()) {
96  case 0: {
97  line += "light";
98  data.theme = THEME_LIGHT;
99  } break;
100  case 1: {
101  line += "dark";
102  data.theme = THEME_DARK;
103  } break;
104  }
105  file.AddLine(line);
106  if(data.theme != checkData.theme) hasChanges = true;
107 
108  file.Write();
109  file.Close();
110 
111  if(hasChanges) {
112  wxMessageDialog msgDialog(this, _("The application must be restarted to settings changes be applied."),
113  _("Info"), wxOK | wxCENTRE | wxICON_INFORMATION);
114  msgDialog.ShowModal();
115  }
116  m_properties->SetGeneralPropertiesData(data);
117  return true;
118 }
General and simulation data manager.
+
1 /*
2  * Copyright (C) 2017 Thales Lima Oliveira <thales@ufu.br>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program. If not, see <https://www.gnu.org/licenses/>.
16  */
17 
18 #include "GeneralPropertiesForm.h"
19 #include "PropertiesData.h"
20 
21 GeneralPropertiesForm::GeneralPropertiesForm(wxWindow* parent, PropertiesData* properties)
23 {
24  m_properties = properties;
25  auto data = m_properties->GetGeneralPropertiesData();
26 
27  // Clear the choices and rebuild to set the correct translations.
28  m_choiceLanguage->Clear();
29  m_choiceLanguage->Insert(_("English"), 0);
30  m_choiceLanguage->Insert(_("Portuguese"), 1);
31  m_choiceTheme->Clear();
32  m_choiceTheme->Insert(_("Light"), 0);
33  m_choiceTheme->Insert(_("Dark"), 1);
34 
35  switch(data.language) {
36  case wxLANGUAGE_ENGLISH: {
37  m_choiceLanguage->SetSelection(0);
38  } break;
39  case wxLANGUAGE_PORTUGUESE_BRAZILIAN: {
40  m_choiceLanguage->SetSelection(1);
41  } break;
42  default: {
43  m_choiceLanguage->SetSelection(wxNOT_FOUND);
44  } break;
45  }
46  switch(data.theme) {
47  case THEME_LIGHT: {
48  m_choiceTheme->SetSelection(0);
49  } break;
50  case THEME_DARK: {
51  m_choiceTheme->SetSelection(1);
52  } break;
53  }
54 }
55 
56 GeneralPropertiesForm::~GeneralPropertiesForm() {}
57 void GeneralPropertiesForm::OnButtonOKClick(wxCommandEvent& event)
58 {
59  if(ValidateData()) EndModal(wxID_OK);
60 }
61 
62 bool GeneralPropertiesForm::ValidateData()
63 {
64  auto data = m_properties->GetGeneralPropertiesData();
65  auto checkData = m_properties->GetGeneralPropertiesData();
66  bool hasChanges = false;
67 
68  wxTextFile file("config.ini");
69  if(!file.Create()) {
70  if(!file.Open()) {
71  // Fail to access the file.
72  wxMessageDialog msgDialog(this,
73  _("It was not possible to access the init file.\nThe settings won't be applied."),
74  _("Error"), wxOK | wxCENTRE | wxICON_ERROR);
75  msgDialog.ShowModal();
76  }
77  file.Clear();
78  }
79 
80  wxString line = "lang=";
81  switch(m_choiceLanguage->GetSelection()) {
82  case 0: {
83  line += "en";
84  data.language = wxLANGUAGE_ENGLISH;
85  } break;
86  case 1: {
87  line += "pt-br";
88  data.language = wxLANGUAGE_PORTUGUESE_BRAZILIAN;
89  } break;
90  }
91  file.AddLine(line);
92  if(data.language != checkData.language) hasChanges = true;
93 
94  line = "theme=";
95  switch(m_choiceTheme->GetSelection()) {
96  case 0: {
97  line += "light";
98  data.theme = THEME_LIGHT;
99  } break;
100  case 1: {
101  line += "dark";
102  data.theme = THEME_DARK;
103  } break;
104  }
105  file.AddLine(line);
106  if(data.theme != checkData.theme) hasChanges = true;
107 
108  file.Write();
109  file.Close();
110 
111  if(hasChanges) {
112  wxMessageDialog msgDialog(this, _("The application must be restarted to settings changes be applied."),
113  _("Info"), wxOK | wxCENTRE | wxICON_INFORMATION);
114  msgDialog.ShowModal();
115  }
116  m_properties->SetGeneralPropertiesData(data);
117  return true;
118 }
General and simulation data manager.
diff --git a/docs/doxygen/html/_general_properties_form_8h_source.html b/docs/doxygen/html/_general_properties_form_8h_source.html index fa7496f..231dc0d 100644 --- a/docs/doxygen/html/_general_properties_form_8h_source.html +++ b/docs/doxygen/html/_general_properties_form_8h_source.html @@ -88,7 +88,7 @@ $(document).ready(function(){initNavTree('_general_properties_form_8h_source.htm
GeneralPropertiesForm.h
-Go to the documentation of this file.
1 /*
2  * Copyright (C) 2017 Thales Lima Oliveira <thales@ufu.br>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program. If not, see <https://www.gnu.org/licenses/>.
16  */
17 
18 #ifndef GENERALPROPERTIESFORM_H
19 #define GENERALPROPERTIESFORM_H
20 
21 #include "PropertiesForm.h"
22 
23 #include <wx/textfile.h>
24 #include <wx/msgdlg.h>
25 
26 class PropertiesData;
27 
36 {
37  public:
38  GeneralPropertiesForm(wxWindow* parent, PropertiesData* properties);
39  virtual ~GeneralPropertiesForm();
40 
41  protected:
42  virtual void OnButtonCancelClick(wxCommandEvent& event) { EndModal(wxID_CANCEL); }
43  virtual void OnButtonOKClick(wxCommandEvent& event);
44  virtual bool ValidateData();
45 
46  PropertiesData* m_properties = NULL;
47 };
48 #endif // GENERALPROPERTIESFORM_H
General and simulation data manager.
+Go to the documentation of this file.
1 /*
2  * Copyright (C) 2017 Thales Lima Oliveira <thales@ufu.br>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program. If not, see <https://www.gnu.org/licenses/>.
16  */
17 
18 #ifndef GENERALPROPERTIESFORM_H
19 #define GENERALPROPERTIESFORM_H
20 
21 #include "PropertiesForm.h"
22 
23 #include <wx/textfile.h>
24 #include <wx/msgdlg.h>
25 
26 class PropertiesData;
27 
36 {
37  public:
38  GeneralPropertiesForm(wxWindow* parent, PropertiesData* properties);
39  virtual ~GeneralPropertiesForm();
40 
41  protected:
42  virtual void OnButtonCancelClick(wxCommandEvent& event) { EndModal(wxID_CANCEL); }
43  virtual void OnButtonOKClick(wxCommandEvent& event);
44  virtual bool ValidateData();
45 
46  PropertiesData* m_properties = NULL;
47 };
48 #endif // GENERALPROPERTIESFORM_H
General and simulation data manager.
Form to edit the software&#39;s general data.
diff --git a/docs/doxygen/html/_generator_stab_form_8cpp_source.html b/docs/doxygen/html/_generator_stab_form_8cpp_source.html index 6b06c32..a1d3009 100644 --- a/docs/doxygen/html/_generator_stab_form_8cpp_source.html +++ b/docs/doxygen/html/_generator_stab_form_8cpp_source.html @@ -88,17 +88,17 @@ $(document).ready(function(){initNavTree('_generator_stab_form_8cpp_source.html'
GeneratorStabForm.cpp
-
1 /*
2  * Copyright (C) 2017 Thales Lima Oliveira <thales@ufu.br>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program. If not, see <https://www.gnu.org/licenses/>.
16  */
17 
18 #include "GeneratorStabForm.h"
19 #include "SwitchingForm.h"
20 #include "SyncGenerator.h"
21 #include "ControlEditor.h"
23 
24 GeneratorStabForm::GeneratorStabForm(wxWindow* parent, SyncGenerator* syncGenerator) : GeneratorStabFormBase(parent)
25 {
26  SetSize(GetBestSize());
27  m_syncGenerator = syncGenerator;
28  m_parent = parent;
29 
30  SyncGeneratorElectricalData data = syncGenerator->GetElectricalData();
31 
32  m_checkBoxPlotSyncMachine->SetValue(data.plotSyncMachine);
33 
34  m_textCtrlInertia->SetValue(SyncGenerator::StringFromDouble(data.inertia));
35  m_textCtrlDamping->SetValue(SyncGenerator::StringFromDouble(data.damping));
36 
37  m_checkBoxUseAVR->SetValue(data.useAVR);
38  m_buttonEditAVR->Enable(data.useAVR);
39 
40  m_checkBoxUseSG->SetValue(data.useSpeedGovernor);
41  m_buttonEditSG->Enable(data.useSpeedGovernor);
42 
43  m_textCtrlRa->SetValue(SyncGenerator::StringFromDouble(data.armResistance));
44  m_textCtrlXp->SetValue(SyncGenerator::StringFromDouble(data.potierReactance));
45  m_textCtrlSat->SetValue(SyncGenerator::StringFromDouble(data.satFactor));
46 
47  m_textCtrlSyncXd->SetValue(SyncGenerator::StringFromDouble(data.syncXd));
48  m_textCtrlSyncXq->SetValue(SyncGenerator::StringFromDouble(data.syncXq));
49 
50  m_textCtrlTranXd->SetValue(SyncGenerator::StringFromDouble(data.transXd));
51  m_textCtrlTranXq->SetValue(SyncGenerator::StringFromDouble(data.transXq));
52  m_textCtrlTranTd0->SetValue(SyncGenerator::StringFromDouble(data.transTd0));
53  m_textCtrlTranTq0->SetValue(SyncGenerator::StringFromDouble(data.transTq0));
54 
55  m_textCtrlSubXd->SetValue(SyncGenerator::StringFromDouble(data.subXd));
56  m_textCtrlSubXq->SetValue(SyncGenerator::StringFromDouble(data.subXq));
57  m_textCtrlSubTd0->SetValue(SyncGenerator::StringFromDouble(data.subTd0));
58  m_textCtrlSubTq0->SetValue(SyncGenerator::StringFromDouble(data.subTq0));
59 }
60 
61 GeneratorStabForm::~GeneratorStabForm() {}
62 void GeneratorStabForm::OnCancelButtonClick(wxCommandEvent& event) { EndModal(wxID_CANCEL); }
63 void GeneratorStabForm::OnEditAVRButtonClick(wxCommandEvent& event)
64 {
65  SyncGeneratorElectricalData data = m_syncGenerator->GetElectricalData();
66  if(!data.avr) {
67  data.avr = new ControlElementContainer();
68  m_syncGenerator->SetElectricalData(data);
69  }
70  ControlEditor* cEditor = new ControlEditor(m_parent, IOControl::IN_TERMINAL_VOLTAGE | IOControl::OUT_FIELD_VOLTAGE);
71  cEditor->SetElementsList(data.avr->GetControlElementsList());
72  cEditor->SetConnectionsList(data.avr->GetConnectionLineList());
73  cEditor->SetControlContainer(data.avr);
74  cEditor->Show();
75 }
76 
77 void GeneratorStabForm::OnOKButtonClick(wxCommandEvent& event)
78 {
79  if(ValidateData()) EndModal(wxID_OK);
80 }
81 
82 void GeneratorStabForm::OnSpeedGovernorButtonClick(wxCommandEvent& event)
83 {
84  SyncGeneratorElectricalData data = m_syncGenerator->GetElectricalData();
85  if(!data.speedGov) {
86  data.speedGov = new ControlElementContainer();
87  m_syncGenerator->SetElectricalData(data);
88  }
89  ControlEditor* cEditor = new ControlEditor(m_parent, IOControl::IN_VELOCITY | IOControl::OUT_MEC_POWER);
90  cEditor->SetElementsList(data.speedGov->GetControlElementsList());
91  cEditor->SetConnectionsList(data.speedGov->GetConnectionLineList());
92  cEditor->SetControlContainer(data.speedGov);
93  cEditor->Show();
94 }
95 
96 void GeneratorStabForm::OnSwitchingButtonClick(wxCommandEvent& event)
97 {
98  if(ValidateData()) {
99  SwitchingForm swForm(m_parent, m_syncGenerator);
100  swForm.SetTitle(_("Synchronous generator: Switching"));
101  swForm.ShowModal();
102  EndModal(wxID_OK);
103  }
104 }
105 
106 bool GeneratorStabForm::ValidateData()
107 {
108  SyncGeneratorElectricalData data = m_syncGenerator->GetElectricalData();
109 
110  data.plotSyncMachine = m_checkBoxPlotSyncMachine->GetValue();
111 
112  if(!m_syncGenerator->DoubleFromString(m_parent, m_textCtrlInertia->GetValue(), data.inertia,
113  _("Value entered incorrectly in the field \"Inertia\".")))
114  return false;
115 
116  if(!m_syncGenerator->DoubleFromString(m_parent, m_textCtrlDamping->GetValue(), data.damping,
117  _("Value entered incorrectly in the field \"Damping factor\".")))
118  return false;
119 
120  data.useAVR = m_checkBoxUseAVR->GetValue();
121  data.useSpeedGovernor = m_checkBoxUseSG->GetValue();
122 
123  if(!m_syncGenerator->DoubleFromString(m_parent, m_textCtrlRa->GetValue(), data.armResistance,
124  _("Value entered incorrectly in the field \"Armature resistance\".")))
125  return false;
126 
127  if(!m_syncGenerator->DoubleFromString(m_parent, m_textCtrlXp->GetValue(), data.potierReactance,
128  _("Value entered incorrectly in the field \"Potier reactance\".")))
129  return false;
130 
131  if(!m_syncGenerator->DoubleFromString(m_parent, m_textCtrlSat->GetValue(), data.satFactor,
132  _("Value entered incorrectly in the field \"Saturation factor\".")))
133  return false;
134 
135  if(!m_syncGenerator->DoubleFromString(
136  m_parent, m_textCtrlSyncXd->GetValue(), data.syncXd,
137  _("Value entered incorrectly in the field \"Synchronous direct-axis reactance\".")))
138  return false;
139 
140  if(!m_syncGenerator->DoubleFromString(
141  m_parent, m_textCtrlSyncXq->GetValue(), data.syncXq,
142  _("Value entered incorrectly in the field \"Synchronous quadrature-axis reactance\".")))
143  return false;
144 
145  if(!m_syncGenerator->DoubleFromString(
146  m_parent, m_textCtrlTranXd->GetValue(), data.transXd,
147  _("Value entered incorrectly in the field \"Transitory direct-axis reactance\".")))
148  return false;
149 
150  if(!m_syncGenerator->DoubleFromString(
151  m_parent, m_textCtrlTranXq->GetValue(), data.transXq,
152  _("Value entered incorrectly in the field \"Transitory quadrature-axis reactance\".")))
153  return false;
154 
155  if(!m_syncGenerator->DoubleFromString(
156  m_parent, m_textCtrlTranTd0->GetValue(), data.transTd0,
157  _("Value entered incorrectly in the field \"Transitory direct-axis time constant\".")))
158  return false;
159 
160  if(!m_syncGenerator->DoubleFromString(
161  m_parent, m_textCtrlTranTq0->GetValue(), data.transTq0,
162  _("Value entered incorrectly in the field \"Transitory quadrature-axis time constant\".")))
163  return false;
164 
165  if(!m_syncGenerator->DoubleFromString(
166  m_parent, m_textCtrlSubXd->GetValue(), data.subXd,
167  _("Value entered incorrectly in the field \"Subtransitory direct-axis reactance\".")))
168  return false;
169 
170  if(!m_syncGenerator->DoubleFromString(
171  m_parent, m_textCtrlSubXq->GetValue(), data.subXq,
172  _("Value entered incorrectly in the field \"Subtransitory quadrature-axis reactance\".")))
173  return false;
174 
175  if(!m_syncGenerator->DoubleFromString(
176  m_parent, m_textCtrlSubTd0->GetValue(), data.subTd0,
177  _("Value entered incorrectly in the field \"Subtransitory direct-axis time constant\".")))
178  return false;
179 
180  if(!m_syncGenerator->DoubleFromString(
181  m_parent, m_textCtrlSubTq0->GetValue(), data.subTq0,
182  _("Value entered incorrectly in the field \"Subtransitory quadrature-axis time constant\".")))
183  return false;
184 
185  m_syncGenerator->SetElectricalData(data);
186 
187  return true;
188 }
189 void GeneratorStabForm::UseAVRClick(wxCommandEvent& event) { m_buttonEditAVR->Enable(m_checkBoxUseAVR->GetValue()); }
190 void GeneratorStabForm::UseSGClick(wxCommandEvent& event) { m_buttonEditSG->Enable(m_checkBoxUseSG->GetValue()); }
+
1 /*
2  * Copyright (C) 2017 Thales Lima Oliveira <thales@ufu.br>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program. If not, see <https://www.gnu.org/licenses/>.
16  */
17 
18 #include "GeneratorStabForm.h"
19 #include "ControlEditor.h"
21 #include "SwitchingForm.h"
22 #include "SyncGenerator.h"
23 
24 GeneratorStabForm::GeneratorStabForm(wxWindow* parent, SyncGenerator* syncGenerator)
25  : GeneratorStabFormBase(parent)
26 {
27  SetSize(GetBestSize());
28  m_syncGenerator = syncGenerator;
29  m_parent = parent;
30 
31  SyncGeneratorElectricalData data = syncGenerator->GetElectricalData();
32 
33  m_checkBoxPlotSyncMachine->SetValue(data.plotSyncMachine);
34 
35  m_textCtrlInertia->SetValue(SyncGenerator::StringFromDouble(data.inertia));
36  m_textCtrlDamping->SetValue(SyncGenerator::StringFromDouble(data.damping));
37 
38  m_checkBoxUseAVR->SetValue(data.useAVR);
39  m_buttonEditAVR->Enable(data.useAVR);
40 
41  m_checkBoxUseSG->SetValue(data.useSpeedGovernor);
42  m_buttonEditSG->Enable(data.useSpeedGovernor);
43 
44  m_textCtrlRa->SetValue(SyncGenerator::StringFromDouble(data.armResistance));
45  m_textCtrlXp->SetValue(SyncGenerator::StringFromDouble(data.potierReactance));
46  m_textCtrlSat->SetValue(SyncGenerator::StringFromDouble(data.satFactor));
47 
48  m_textCtrlSyncXd->SetValue(SyncGenerator::StringFromDouble(data.syncXd));
49  m_textCtrlSyncXq->SetValue(SyncGenerator::StringFromDouble(data.syncXq));
50 
51  m_textCtrlTranXd->SetValue(SyncGenerator::StringFromDouble(data.transXd));
52  m_textCtrlTranXq->SetValue(SyncGenerator::StringFromDouble(data.transXq));
53  m_textCtrlTranTd0->SetValue(SyncGenerator::StringFromDouble(data.transTd0));
54  m_textCtrlTranTq0->SetValue(SyncGenerator::StringFromDouble(data.transTq0));
55 
56  m_textCtrlSubXd->SetValue(SyncGenerator::StringFromDouble(data.subXd));
57  m_textCtrlSubXq->SetValue(SyncGenerator::StringFromDouble(data.subXq));
58  m_textCtrlSubTd0->SetValue(SyncGenerator::StringFromDouble(data.subTd0));
59  m_textCtrlSubTq0->SetValue(SyncGenerator::StringFromDouble(data.subTq0));
60 }
61 
62 GeneratorStabForm::~GeneratorStabForm()
63 {
64 }
65 void GeneratorStabForm::OnCancelButtonClick(wxCommandEvent& event)
66 {
67  EndModal(wxID_CANCEL);
68 }
69 void GeneratorStabForm::OnEditAVRButtonClick(wxCommandEvent& event)
70 {
71  if(ValidateData()) {
72  SyncGeneratorElectricalData data = m_syncGenerator->GetElectricalData();
73  if(!data.avr) {
74  data.avr = new ControlElementContainer();
75  m_syncGenerator->SetElectricalData(data);
76  }
77  ControlEditor* cEditor = new ControlEditor(m_parent, IOControl::IN_TERMINAL_VOLTAGE | IOControl::IN_ACTIVE_POWER |
78  IOControl::IN_REACTIVE_POWER | IOControl::IN_INITIAL_TERMINAL_VOLTAGE | IOControl::IN_VELOCITY |
79  IOControl::IN_INITIAL_VELOCITY | IOControl::IN_DELTA_VELOCITY | IOControl::IN_DELTA_ACTIVE_POWER |
80  IOControl::OUT_FIELD_VOLTAGE);
81  cEditor->SetElementsList(data.avr->GetControlElementsList());
82  cEditor->SetConnectionsList(data.avr->GetConnectionLineList());
83  cEditor->SetControlContainer(data.avr);
84  cEditor->Show();
85  cEditor->SetJustOpened(true);
86  #ifdef __WXGTK__
87  EndModal(wxID_OK);
88  #endif
89  }
90 }
91 
92 void GeneratorStabForm::OnOKButtonClick(wxCommandEvent& event)
93 {
94  if(ValidateData())
95  EndModal(wxID_OK);
96 }
97 
98 void GeneratorStabForm::OnSpeedGovernorButtonClick(wxCommandEvent& event)
99 {
100  if(ValidateData()) {
101  SyncGeneratorElectricalData data = m_syncGenerator->GetElectricalData();
102  if(!data.speedGov) {
103  data.speedGov = new ControlElementContainer();
104  m_syncGenerator->SetElectricalData(data);
105  }
106  ControlEditor* cEditor =
107  new ControlEditor(NULL, IOControl::IN_VELOCITY | IOControl::IN_ACTIVE_POWER | IOControl::IN_REACTIVE_POWER |
108  IOControl::IN_INITIAL_VELOCITY | IOControl::IN_INITIAL_MEC_POWER | IOControl::OUT_MEC_POWER);
109  cEditor->SetElementsList(data.speedGov->GetControlElementsList());
110  cEditor->SetConnectionsList(data.speedGov->GetConnectionLineList());
111  cEditor->SetControlContainer(data.speedGov);
112  cEditor->Show();
113  cEditor->SetJustOpened(true);
114  #ifdef __WXGTK__
115  EndModal(wxID_OK);
116  #endif
117  }
118 }
119 
120 void GeneratorStabForm::OnSwitchingButtonClick(wxCommandEvent& event)
121 {
122  if(ValidateData()) {
123  SwitchingForm swForm(m_parent, m_syncGenerator);
124  swForm.SetTitle(_("Synchronous generator: Switching"));
125  swForm.ShowModal();
126  EndModal(wxID_OK);
127  }
128 }
129 
130 bool GeneratorStabForm::ValidateData()
131 {
132  SyncGeneratorElectricalData data = m_syncGenerator->GetElectricalData();
133 
134  data.plotSyncMachine = m_checkBoxPlotSyncMachine->GetValue();
135 
136  if(!m_syncGenerator->DoubleFromString(m_parent, m_textCtrlInertia->GetValue(), data.inertia,
137  _("Value entered incorrectly in the field \"Inertia\".")))
138  return false;
139 
140  if(!m_syncGenerator->DoubleFromString(m_parent, m_textCtrlDamping->GetValue(), data.damping,
141  _("Value entered incorrectly in the field \"Damping factor\".")))
142  return false;
143 
144  data.useAVR = m_checkBoxUseAVR->GetValue();
145  data.useSpeedGovernor = m_checkBoxUseSG->GetValue();
146 
147  if(!m_syncGenerator->DoubleFromString(m_parent, m_textCtrlRa->GetValue(), data.armResistance,
148  _("Value entered incorrectly in the field \"Armature resistance\".")))
149  return false;
150 
151  if(!m_syncGenerator->DoubleFromString(m_parent, m_textCtrlXp->GetValue(), data.potierReactance,
152  _("Value entered incorrectly in the field \"Potier reactance\".")))
153  return false;
154 
155  if(!m_syncGenerator->DoubleFromString(m_parent, m_textCtrlSat->GetValue(), data.satFactor,
156  _("Value entered incorrectly in the field \"Saturation factor\".")))
157  return false;
158 
159  if(!m_syncGenerator->DoubleFromString(m_parent, m_textCtrlSyncXd->GetValue(), data.syncXd,
160  _("Value entered incorrectly in the field \"Synchronous direct-axis reactance\".")))
161  return false;
162 
163  if(!m_syncGenerator->DoubleFromString(m_parent, m_textCtrlSyncXq->GetValue(), data.syncXq,
164  _("Value entered incorrectly in the field \"Synchronous quadrature-axis reactance\".")))
165  return false;
166 
167  if(!m_syncGenerator->DoubleFromString(m_parent, m_textCtrlTranXd->GetValue(), data.transXd,
168  _("Value entered incorrectly in the field \"Transitory direct-axis reactance\".")))
169  return false;
170 
171  if(!m_syncGenerator->DoubleFromString(m_parent, m_textCtrlTranXq->GetValue(), data.transXq,
172  _("Value entered incorrectly in the field \"Transitory quadrature-axis reactance\".")))
173  return false;
174 
175  if(!m_syncGenerator->DoubleFromString(m_parent, m_textCtrlTranTd0->GetValue(), data.transTd0,
176  _("Value entered incorrectly in the field \"Transitory direct-axis time constant\".")))
177  return false;
178 
179  if(!m_syncGenerator->DoubleFromString(m_parent, m_textCtrlTranTq0->GetValue(), data.transTq0,
180  _("Value entered incorrectly in the field \"Transitory quadrature-axis time constant\".")))
181  return false;
182 
183  if(!m_syncGenerator->DoubleFromString(m_parent, m_textCtrlSubXd->GetValue(), data.subXd,
184  _("Value entered incorrectly in the field \"Subtransitory direct-axis reactance\".")))
185  return false;
186 
187  if(!m_syncGenerator->DoubleFromString(m_parent, m_textCtrlSubXq->GetValue(), data.subXq,
188  _("Value entered incorrectly in the field \"Subtransitory quadrature-axis reactance\".")))
189  return false;
190 
191  if(!m_syncGenerator->DoubleFromString(m_parent, m_textCtrlSubTd0->GetValue(), data.subTd0,
192  _("Value entered incorrectly in the field \"Subtransitory direct-axis time constant\".")))
193  return false;
194 
195  if(!m_syncGenerator->DoubleFromString(m_parent, m_textCtrlSubTq0->GetValue(), data.subTq0,
196  _("Value entered incorrectly in the field \"Subtransitory quadrature-axis time constant\".")))
197  return false;
198 
199  m_syncGenerator->SetElectricalData(data);
200 
201  return true;
202 }
203 void GeneratorStabForm::UseAVRClick(wxCommandEvent& event)
204 {
205  m_buttonEditAVR->Enable(m_checkBoxUseAVR->GetValue());
206 }
207 void GeneratorStabForm::UseSGClick(wxCommandEvent& event)
208 {
209  m_buttonEditSG->Enable(m_checkBoxUseSG->GetValue());
210 }
Form to edit the switching data of power elements for electromechanical transient studies...
Definition: SwitchingForm.h:32
Synchronous generator power element.
-
Class that can contain all control elements. Can identify (using RTTI) the elements from a generic li...
+
Class that can contain all control elements. Can identify (using RTTI) the elements from a generic li...
- +
static wxString StringFromDouble(double value, int minDecimal=1)
Convert a double value to string.
Definition: Element.cpp:320
diff --git a/docs/doxygen/html/_generator_stab_form_8h_source.html b/docs/doxygen/html/_generator_stab_form_8h_source.html index 62ee696..668fd46 100644 --- a/docs/doxygen/html/_generator_stab_form_8h_source.html +++ b/docs/doxygen/html/_generator_stab_form_8h_source.html @@ -91,9 +91,9 @@ $(document).ready(function(){initNavTree('_generator_stab_form_8h_source.html',' Go to the documentation of this file.
1 /*
2  * Copyright (C) 2017 Thales Lima Oliveira <thales@ufu.br>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program. If not, see <https://www.gnu.org/licenses/>.
16  */
17 
18 #ifndef GENERATORSTABFORM_H
19 #define GENERATORSTABFORM_H
20 
21 #include "ElementForm.h"
22 
23 class SwitchingForm;
24 class SyncGenerator;
25 class ControlEditor;
27 
36 {
37  public:
38  GeneratorStabForm(wxWindow* parent, SyncGenerator* syncGenerator);
39  virtual ~GeneratorStabForm();
40 
41  protected:
42  virtual void UseAVRClick(wxCommandEvent& event);
43  virtual void UseSGClick(wxCommandEvent& event);
44  virtual void OnCancelButtonClick(wxCommandEvent& event);
45  virtual void OnEditAVRButtonClick(wxCommandEvent& event);
46  virtual void OnOKButtonClick(wxCommandEvent& event);
47  virtual void OnSpeedGovernorButtonClick(wxCommandEvent& event);
48  virtual void OnSwitchingButtonClick(wxCommandEvent& event);
49 
50  virtual bool ValidateData();
51 
52  SyncGenerator* m_syncGenerator = NULL;
53  wxWindow* m_parent = NULL;
54 };
55 #endif // GENERATORSTABFORM_H
Form to edit the switching data of power elements for electromechanical transient studies...
Definition: SwitchingForm.h:32
Synchronous generator power element.
Form to edit the synchronous generator data for electromechanical studies.
-
Class that can contain all control elements. Can identify (using RTTI) the elements from a generic li...
+
Class that can contain all control elements. Can identify (using RTTI) the elements from a generic li...
- +
diff --git a/docs/doxygen/html/_i_o_control_8cpp_source.html b/docs/doxygen/html/_i_o_control_8cpp_source.html index 22c79bf..c4f6ddf 100644 --- a/docs/doxygen/html/_i_o_control_8cpp_source.html +++ b/docs/doxygen/html/_i_o_control_8cpp_source.html @@ -88,20 +88,21 @@ $(document).ready(function(){initNavTree('_i_o_control_8cpp_source.html','');});
IOControl.cpp
-
1 /*
2  * Copyright (C) 2017 Thales Lima Oliveira <thales@ufu.br>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program. If not, see <https://www.gnu.org/licenses/>.
16  */
17 
18 #include "IOControl.h"
19 #include "IOControlForm.h"
20 
21 IOControl::IOControl(int ioFlags, int id) : ControlElement(id)
22 {
23  m_ioFlags = ioFlags;
24 
25  Node* node = new Node(m_position, Node::NODE_IN, m_borderSize);
26  m_nodeList.push_back(node);
27 
28  if(ioFlags & IN_TERMINAL_VOLTAGE)
29  SetValue(IN_TERMINAL_VOLTAGE);
30  else if(ioFlags & IN_VELOCITY)
31  SetValue(IN_VELOCITY);
32  node->StartMove(m_position);
33 }
34 
35 IOControl::~IOControl() {}
36 void IOControl::Draw(wxPoint2DDouble translation, double scale) const
37 {
38  std::vector<wxPoint2DDouble> pts;
39  if(m_angle == 0.0) {
40  pts.push_back(m_rect.GetLeftTop() + wxPoint2DDouble(m_borderSize, m_borderSize));
41  pts.push_back(m_rect.GetRightTop() + wxPoint2DDouble(-m_borderSize - 10, m_borderSize));
42  pts.push_back(m_position + wxPoint2DDouble(m_width / 2 - m_borderSize, 0));
43  pts.push_back(m_rect.GetRightBottom() + wxPoint2DDouble(-m_borderSize - 10, -m_borderSize));
44  pts.push_back(m_rect.GetLeftBottom() + wxPoint2DDouble(m_borderSize, -m_borderSize));
45  } else if(m_angle == 90.0) {
46  pts.push_back(m_rect.GetLeftTop() + wxPoint2DDouble(m_borderSize, m_borderSize));
47  pts.push_back(m_rect.GetRightTop() + wxPoint2DDouble(-m_borderSize, m_borderSize));
48  pts.push_back(m_rect.GetRightBottom() + wxPoint2DDouble(-m_borderSize, -m_borderSize - 10));
49  pts.push_back(m_position + wxPoint2DDouble(0, m_height / 2 - m_borderSize));
50  pts.push_back(m_rect.GetLeftBottom() + wxPoint2DDouble(m_borderSize, -m_borderSize - 10));
51  } else if(m_angle == 180.0) {
52  pts.push_back(m_rect.GetLeftTop() + wxPoint2DDouble(m_borderSize + 10, m_borderSize));
53  pts.push_back(m_rect.GetRightTop() + wxPoint2DDouble(-m_borderSize, m_borderSize));
54  pts.push_back(m_rect.GetRightBottom() + wxPoint2DDouble(-m_borderSize, -m_borderSize));
55  pts.push_back(m_rect.GetLeftBottom() + wxPoint2DDouble(m_borderSize + 10, -m_borderSize));
56  pts.push_back(m_position + wxPoint2DDouble(-m_width / 2 + m_borderSize, 0));
57  } else if(m_angle == 270.0) {
58  pts.push_back(m_position + wxPoint2DDouble(0, -m_height / 2 + m_borderSize));
59  pts.push_back(m_rect.GetRightTop() + wxPoint2DDouble(-m_borderSize, m_borderSize + 10));
60  pts.push_back(m_rect.GetRightBottom() + wxPoint2DDouble(-m_borderSize, -m_borderSize));
61  pts.push_back(m_rect.GetLeftBottom() + wxPoint2DDouble(m_borderSize, -m_borderSize));
62  pts.push_back(m_rect.GetLeftTop() + wxPoint2DDouble(m_borderSize, m_borderSize + 10));
63  }
64 
65  if(m_selected) {
66  glColor4dv(m_selectionColour.GetRGBA());
67  double borderSize = (m_borderSize * 2.0 + 1.0) / scale;
68  std::vector<wxPoint2DDouble> selPts = pts;
69  if(m_angle == 0.0) {
70  selPts[0] += wxPoint2DDouble(-borderSize / 2, -borderSize / 2);
71  selPts[1] += wxPoint2DDouble(borderSize / 2, -borderSize / 2);
72  selPts[2] += wxPoint2DDouble(1.5 * borderSize / 2, 0);
73  selPts[3] += wxPoint2DDouble(borderSize / 2, borderSize / 2);
74  selPts[4] += wxPoint2DDouble(-borderSize / 2, borderSize / 2);
75  } else if(m_angle == 90.0) {
76  selPts[0] += wxPoint2DDouble(-borderSize / 2, -borderSize / 2);
77  selPts[1] += wxPoint2DDouble(borderSize / 2, -borderSize / 2);
78  selPts[2] += wxPoint2DDouble(borderSize / 2, borderSize / 2);
79  selPts[3] += wxPoint2DDouble(0, 1.5 * borderSize / 2);
80  selPts[4] += wxPoint2DDouble(-borderSize / 2, borderSize / 2);
81  } else if(m_angle == 180.0) {
82  selPts[0] += wxPoint2DDouble(-borderSize / 2, -borderSize / 2);
83  selPts[1] += wxPoint2DDouble(borderSize / 2, -borderSize / 2);
84  selPts[2] += wxPoint2DDouble(borderSize / 2, borderSize / 2);
85  selPts[3] += wxPoint2DDouble(-borderSize / 2, borderSize / 2);
86  selPts[4] += wxPoint2DDouble(-1.5 * borderSize / 2, 0);
87  } else if(m_angle == 270.0) {
88  selPts[0] += wxPoint2DDouble(0, -1.5 * borderSize / 2);
89  selPts[1] += wxPoint2DDouble(borderSize / 2, -borderSize / 2);
90  selPts[2] += wxPoint2DDouble(borderSize / 2, borderSize / 2);
91  selPts[3] += wxPoint2DDouble(-borderSize / 2, borderSize / 2);
92  selPts[4] += wxPoint2DDouble(-borderSize / 2, -borderSize / 2);
93  }
94  DrawLine(selPts, GL_POLYGON);
95  }
96  glLineWidth(1.0);
97  glColor4d(1.0, 1.0, 1.0, 1.0);
98  DrawLine(pts, GL_POLYGON);
99  glColor4d(0.0, 0.0, 0.0, 1.0);
100  DrawLine(pts, GL_LINE_LOOP);
101 
102  // Plot number.
103  glEnable(GL_TEXTURE_2D);
104  glColor4d(0.0, 0.0, 0.0, 1.0);
105  m_glStringValue->bind();
106  if(m_angle == 0.0) {
107  m_glStringValue->render(m_position.m_x - 5, m_position.m_y);
108  } else if(m_angle == 90.0) {
109  m_glStringValue->render(m_position.m_x, m_position.m_y - 5);
110  } else if(m_angle == 180.0) {
111  m_glStringValue->render(m_position.m_x + 5, m_position.m_y);
112  } else if(m_angle == 270.0) {
113  m_glStringValue->render(m_position.m_x, m_position.m_y + 5);
114  }
115 
116  glDisable(GL_TEXTURE_2D);
117 
118  glColor4d(0.0, 0.0, 0.0, 1.0);
119  DrawNodes();
120 }
121 
122 bool IOControl::ShowForm(wxWindow* parent, Element* element)
123 {
124  IOControlForm* form = new IOControlForm(parent, this);
125  if(form->ShowModal() == wxID_OK) {
126  form->Destroy();
127  return true;
128  }
129  form->Destroy();
130  return false;
131 }
132 
133 void IOControl::Rotate(bool clockwise)
134 {
135  if(clockwise)
136  m_angle += 90.0;
137  else
138  m_angle -= 90.0;
139  if(m_angle >= 360.0)
140  m_angle = 0.0;
141  else if(m_angle < 0)
142  m_angle = 270.0;
143 
144  UpdatePoints();
145 
146  for(auto it = m_nodeList.begin(), itEnd = m_nodeList.end(); it != itEnd; ++it) {
147  Node* node = *it;
148  node->Rotate(clockwise);
149  }
150 }
151 
152 wxString IOControl::GenerateText()
153 {
154  wxString omega = wxString::FromUTF8("\xCF\x89");
155 
156  switch(m_value) {
157  case IN_TERMINAL_VOLTAGE: {
158  m_ioNodeType = Node::NODE_OUT;
159  return _("Vt");
160  } break;
161  case IN_VELOCITY: {
162  m_ioNodeType = Node::NODE_OUT;
163  return omega;
164  } break;
165  case IN_ACTIVE_POWER: {
166  m_ioNodeType = Node::NODE_OUT;
167  return _("Pe");
168  } break;
169  case IN_REACTIVE_POWER: {
170  m_ioNodeType = Node::NODE_OUT;
171  return _("Qe");
172  } break;
173  case OUT_FIELD_VOLTAGE: {
174  m_ioNodeType = Node::NODE_IN;
175  return _("Vf");
176  } break;
177  case OUT_MEC_POWER: {
178  m_ioNodeType = Node::NODE_IN;
179  return _("Pm");
180  } break;
181  }
182  return "";
183 }
184 
185 void IOControl::SetValue(IOFlags value)
186 {
187  m_value = value;
188  wxString text = GenerateText();
189 
190  wxFont font(m_fontSize, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL);
191  wxScreenDC dc;
192 
193  if(m_glStringValue) {
194  delete m_glStringValue;
195  m_glStringValue = NULL;
196  }
197  m_glStringValue = new wxGLString(text);
198  m_glStringValue->setFont(font);
199  m_glStringValue->consolidate(&dc);
200 
201  m_width = m_glStringValue->getWidth() + 10 + 2 * m_borderSize;
202  m_height = m_glStringValue->getheight() + 10 + 2 * m_borderSize;
203 
204  SetPosition(m_position); // Update rectangle.
205 
206  UpdatePoints();
207 }
208 
209 void IOControl::UpdatePoints()
210 {
211  if(m_nodeList.size() != 0) {
212  Node* node = m_nodeList[0];
213  if(node->GetNodeType() != m_ioNodeType) {
214  // Rotate 180 degrees
215  node->Rotate();
216  node->Rotate();
217  }
218  node->SetNodeType(m_ioNodeType);
219  if(m_angle == 0.0) {
220  if(m_ioNodeType == Node::NODE_IN)
221  node->SetPosition(m_position + wxPoint2DDouble(-m_width / 2, 0));
222  else
223  node->SetPosition(m_position + wxPoint2DDouble(m_width / 2 - 2, 0));
224  } else if(m_angle == 90.0) {
225  if(m_ioNodeType == Node::NODE_IN)
226  node->SetPosition(m_position + wxPoint2DDouble(0, -m_height / 2));
227  else
228  node->SetPosition(m_position + wxPoint2DDouble(0, m_height / 2 - 2));
229  } else if(m_angle == 180.0) {
230  if(m_ioNodeType == Node::NODE_IN)
231  node->SetPosition(m_position + wxPoint2DDouble(m_width / 2, 0));
232  else
233  node->SetPosition(m_position + wxPoint2DDouble(2 - m_width / 2, 0));
234  } else if(m_angle == 270.0) {
235  if(m_ioNodeType == Node::NODE_IN)
236  node->SetPosition(m_position + wxPoint2DDouble(0, m_height / 2));
237  else
238  node->SetPosition(m_position + wxPoint2DDouble(0, 2 - m_height / 2));
239  }
240  }
241 }
242 
244 {
245  IOControl* copy = new IOControl(m_ioFlags, m_elementID);
246  *copy = *this;
247  m_glStringValue = NULL;
248  SetValue(m_value);
249  return copy;
250 }
Base class of all elements of the program. This class is responsible for manage graphical and his dat...
Definition: Element.h:113
+
1 /*
2  * Copyright (C) 2017 Thales Lima Oliveira <thales@ufu.br>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program. If not, see <https://www.gnu.org/licenses/>.
16  */
17 
18 #include "IOControl.h"
19 #include "IOControlForm.h"
20 
21 IOControl::IOControl(int ioFlags, int id) : ControlElement(id)
22 {
23  m_ioFlags = ioFlags;
24 
25  Node* node = new Node(m_position, Node::NODE_IN, m_borderSize);
26  m_nodeList.push_back(node);
27 
28  if(ioFlags & IN_TERMINAL_VOLTAGE)
29  SetValue(IN_TERMINAL_VOLTAGE);
30  else if(ioFlags & IN_VELOCITY)
31  SetValue(IN_VELOCITY);
32  node->StartMove(m_position);
33 }
34 
35 IOControl::~IOControl()
36 {
37  if(m_glText) delete m_glText;
38 }
39 
40 void IOControl::Draw(wxPoint2DDouble translation, double scale) const
41 {
42  std::vector<wxPoint2DDouble> pts;
43  if(m_angle == 0.0) {
44  pts.push_back(m_rect.GetLeftTop() + wxPoint2DDouble(m_borderSize, m_borderSize));
45  pts.push_back(m_rect.GetRightTop() + wxPoint2DDouble(-m_borderSize - 10, m_borderSize));
46  pts.push_back(m_position + wxPoint2DDouble(m_width / 2 - m_borderSize, 0));
47  pts.push_back(m_rect.GetRightBottom() + wxPoint2DDouble(-m_borderSize - 10, -m_borderSize));
48  pts.push_back(m_rect.GetLeftBottom() + wxPoint2DDouble(m_borderSize, -m_borderSize));
49  } else if(m_angle == 90.0) {
50  pts.push_back(m_rect.GetLeftTop() + wxPoint2DDouble(m_borderSize, m_borderSize));
51  pts.push_back(m_rect.GetRightTop() + wxPoint2DDouble(-m_borderSize, m_borderSize));
52  pts.push_back(m_rect.GetRightBottom() + wxPoint2DDouble(-m_borderSize, -m_borderSize - 10));
53  pts.push_back(m_position + wxPoint2DDouble(0, m_height / 2 - m_borderSize));
54  pts.push_back(m_rect.GetLeftBottom() + wxPoint2DDouble(m_borderSize, -m_borderSize - 10));
55  } else if(m_angle == 180.0) {
56  pts.push_back(m_rect.GetLeftTop() + wxPoint2DDouble(m_borderSize + 10, m_borderSize));
57  pts.push_back(m_rect.GetRightTop() + wxPoint2DDouble(-m_borderSize, m_borderSize));
58  pts.push_back(m_rect.GetRightBottom() + wxPoint2DDouble(-m_borderSize, -m_borderSize));
59  pts.push_back(m_rect.GetLeftBottom() + wxPoint2DDouble(m_borderSize + 10, -m_borderSize));
60  pts.push_back(m_position + wxPoint2DDouble(-m_width / 2 + m_borderSize, 0));
61  } else if(m_angle == 270.0) {
62  pts.push_back(m_position + wxPoint2DDouble(0, -m_height / 2 + m_borderSize));
63  pts.push_back(m_rect.GetRightTop() + wxPoint2DDouble(-m_borderSize, m_borderSize + 10));
64  pts.push_back(m_rect.GetRightBottom() + wxPoint2DDouble(-m_borderSize, -m_borderSize));
65  pts.push_back(m_rect.GetLeftBottom() + wxPoint2DDouble(m_borderSize, -m_borderSize));
66  pts.push_back(m_rect.GetLeftTop() + wxPoint2DDouble(m_borderSize, m_borderSize + 10));
67  }
68 
69  if(m_selected) {
70  glColor4dv(m_selectionColour.GetRGBA());
71  double borderSize = (m_borderSize * 2.0 + 1.0) / scale;
72  std::vector<wxPoint2DDouble> selPts = pts;
73  if(m_angle == 0.0) {
74  selPts[0] += wxPoint2DDouble(-borderSize / 2, -borderSize / 2);
75  selPts[1] += wxPoint2DDouble(borderSize / 2, -borderSize / 2);
76  selPts[2] += wxPoint2DDouble(1.5 * borderSize / 2, 0);
77  selPts[3] += wxPoint2DDouble(borderSize / 2, borderSize / 2);
78  selPts[4] += wxPoint2DDouble(-borderSize / 2, borderSize / 2);
79  } else if(m_angle == 90.0) {
80  selPts[0] += wxPoint2DDouble(-borderSize / 2, -borderSize / 2);
81  selPts[1] += wxPoint2DDouble(borderSize / 2, -borderSize / 2);
82  selPts[2] += wxPoint2DDouble(borderSize / 2, borderSize / 2);
83  selPts[3] += wxPoint2DDouble(0, 1.5 * borderSize / 2);
84  selPts[4] += wxPoint2DDouble(-borderSize / 2, borderSize / 2);
85  } else if(m_angle == 180.0) {
86  selPts[0] += wxPoint2DDouble(-borderSize / 2, -borderSize / 2);
87  selPts[1] += wxPoint2DDouble(borderSize / 2, -borderSize / 2);
88  selPts[2] += wxPoint2DDouble(borderSize / 2, borderSize / 2);
89  selPts[3] += wxPoint2DDouble(-borderSize / 2, borderSize / 2);
90  selPts[4] += wxPoint2DDouble(-1.5 * borderSize / 2, 0);
91  } else if(m_angle == 270.0) {
92  selPts[0] += wxPoint2DDouble(0, -1.5 * borderSize / 2);
93  selPts[1] += wxPoint2DDouble(borderSize / 2, -borderSize / 2);
94  selPts[2] += wxPoint2DDouble(borderSize / 2, borderSize / 2);
95  selPts[3] += wxPoint2DDouble(-borderSize / 2, borderSize / 2);
96  selPts[4] += wxPoint2DDouble(-borderSize / 2, -borderSize / 2);
97  }
98  DrawLine(selPts, GL_POLYGON);
99  }
100  glLineWidth(1.0);
101  glColor4d(1.0, 1.0, 1.0, 1.0);
102  DrawLine(pts, GL_POLYGON);
103  glColor4d(0.0, 0.0, 0.0, 1.0);
104  DrawLine(pts, GL_LINE_LOOP);
105 
106  // Plot number.
107  glColor4d(0.0, 0.0, 0.0, 1.0);
108  if(m_angle == 0.0) {
109  m_glText->Draw(m_position + wxPoint2DDouble(-5.0, 0.0));
110  } else if(m_angle == 90.0) {
111  m_glText->Draw(m_position + wxPoint2DDouble(0.0, -5.0));
112  } else if(m_angle == 180.0) {
113  m_glText->Draw(m_position + wxPoint2DDouble(5.0, 0.0));
114  } else if(m_angle == 270.0) {
115  m_glText->Draw(m_position + wxPoint2DDouble(0.0, 5.0));
116  }
117 
118  glColor4d(0.0, 0.0, 0.0, 1.0);
119  DrawNodes();
120 }
121 
122 bool IOControl::ShowForm(wxWindow* parent, Element* element)
123 {
124  IOControlForm* form = new IOControlForm(parent, this);
125  if(form->ShowModal() == wxID_OK) {
126  form->Destroy();
127  return true;
128  }
129  form->Destroy();
130  return false;
131 }
132 
133 void IOControl::Rotate(bool clockwise)
134 {
135  if(clockwise)
136  m_angle += 90.0;
137  else
138  m_angle -= 90.0;
139  if(m_angle >= 360.0)
140  m_angle = 0.0;
141  else if(m_angle < 0)
142  m_angle = 270.0;
143 
144  UpdatePoints();
145 
146  for(auto it = m_nodeList.begin(), itEnd = m_nodeList.end(); it != itEnd; ++it) {
147  Node* node = *it;
148  node->Rotate(clockwise);
149  }
150 }
151 
152 wxString IOControl::GenerateText()
153 {
154  wxString omega = wxString::FromUTF8("\xCF\x89");
155  wxString subZero = wxString::FromUTF8("\xE2\x82\x92");
156  wxString capDelta = wxString::FromUTF8("\xCE\x94");
157 
158  switch(m_value) {
159  case IN_TERMINAL_VOLTAGE: {
160  m_ioNodeType = Node::NODE_OUT;
161  return _("Vt");
162  } break;
163  case IN_VELOCITY: {
164  m_ioNodeType = Node::NODE_OUT;
165  return omega;
166  } break;
167  case IN_ACTIVE_POWER: {
168  m_ioNodeType = Node::NODE_OUT;
169  return _("P");
170  } break;
171  case IN_REACTIVE_POWER: {
172  m_ioNodeType = Node::NODE_OUT;
173  return _("Q");
174  } break;
175  case OUT_FIELD_VOLTAGE: {
176  m_ioNodeType = Node::NODE_IN;
177  return _("Vf");
178  } break;
179  case OUT_MEC_POWER: {
180  m_ioNodeType = Node::NODE_IN;
181  return _("Pm");
182  } break;
183  case IN_INITIAL_TERMINAL_VOLTAGE: {
184  m_ioNodeType = Node::NODE_OUT;
185  return _("Vt") + subZero;
186  } break;
187  case IN_INITIAL_MEC_POWER: {
188  m_ioNodeType = Node::NODE_OUT;
189  return _("Pm") + subZero;
190  } break;
191  case IN_INITIAL_VELOCITY: {
192  m_ioNodeType = Node::NODE_OUT;
193  return omega + subZero;
194  } break;
195  case IN_DELTA_VELOCITY: {
196  m_ioNodeType = Node::NODE_OUT;
197  return capDelta + omega;
198  } break;
199  case IN_DELTA_ACTIVE_POWER: {
200  m_ioNodeType = Node::NODE_OUT;
201  return capDelta + _("P");
202  } break;
203  }
204  return "";
205 }
206 
207 void IOControl::SetValue(IOFlags value)
208 {
209  m_value = value;
210  wxString text = GenerateText();
211 
212  if(m_glText)
213  m_glText->SetText(text);
214  else
215  m_glText = new OpenGLText(text);
216 
217  m_width = m_glText->GetWidth() + 10 + 2 * m_borderSize;
218  m_height = m_glText->GetHeight() + 10 + 2 * m_borderSize;
219 
220  SetPosition(m_position); // Update rectangle.
221 
222  UpdatePoints();
223 }
224 
225 void IOControl::UpdatePoints()
226 {
227  if(m_nodeList.size() != 0) {
228  Node* node = m_nodeList[0];
229  if(node->GetNodeType() != m_ioNodeType) {
230  // Rotate 180 degrees
231  node->Rotate();
232  node->Rotate();
233  }
234  node->SetNodeType(m_ioNodeType);
235  if(m_angle == 0.0) {
236  if(m_ioNodeType == Node::NODE_IN)
237  node->SetPosition(m_position + wxPoint2DDouble(-m_width / 2, 0));
238  else
239  node->SetPosition(m_position + wxPoint2DDouble(m_width / 2 - 2, 0));
240  } else if(m_angle == 90.0) {
241  if(m_ioNodeType == Node::NODE_IN)
242  node->SetPosition(m_position + wxPoint2DDouble(0, -m_height / 2));
243  else
244  node->SetPosition(m_position + wxPoint2DDouble(0, m_height / 2 - 2));
245  } else if(m_angle == 180.0) {
246  if(m_ioNodeType == Node::NODE_IN)
247  node->SetPosition(m_position + wxPoint2DDouble(m_width / 2, 0));
248  else
249  node->SetPosition(m_position + wxPoint2DDouble(2 - m_width / 2, 0));
250  } else if(m_angle == 270.0) {
251  if(m_ioNodeType == Node::NODE_IN)
252  node->SetPosition(m_position + wxPoint2DDouble(0, m_height / 2));
253  else
254  node->SetPosition(m_position + wxPoint2DDouble(0, 2 - m_height / 2));
255  }
256  }
257 }
258 
260 {
261  IOControl* copy = new IOControl(m_ioFlags, m_elementID);
262  *copy = *this;
263  copy->m_glText = m_glText->GetCopy();
264  return copy;
265 }
266 
268 {
269  SetValue(m_value);
270  if(!m_glText->IsTextureOK()) return false;
271  return true;
272 }
Base class of all elements of the program. This class is responsible for manage graphical and his dat...
Definition: Element.h:113
virtual void DrawLine(std::vector< wxPoint2DDouble > points, GLenum mode=GL_LINE_STRIP) const
Draw line.
Definition: Element.cpp:89
Node of a control element. This class manages the user interaction with the connection and control el...
virtual void Rotate(bool clockwise=true)
Rotate the element.
Definition: IOControl.cpp:133
+
virtual bool UpdateText()
Update the OpenGL text in the element (if present).
Definition: IOControl.cpp:267
Provides the communication with the power element.
Definition: IOControl.h:35
-
virtual Element * GetCopy()
Get a the element copy.
Definition: IOControl.cpp:243
+
virtual Element * GetCopy()
Get a the element copy.
Definition: IOControl.cpp:259
void SetPosition(const wxPoint2DDouble position)
Set the element position and update the rectangle.
Definition: Element.cpp:25
virtual bool ShowForm(wxWindow *parent, Element *element)
Show element data form.
Definition: IOControl.cpp:122
-
virtual void Draw(wxPoint2DDouble translation, double scale) const
Draw the element.
Definition: IOControl.cpp:36
+
Class to draw text on OpenGL using wxWidgets.
Definition: OpenGLText.h:31
+
virtual void Draw(wxPoint2DDouble translation, double scale) const
Draw the element.
Definition: IOControl.cpp:40
Form to edit the input/output control data.
Definition: IOControlForm.h:31
-
const GLdouble * GetRGBA() const
Get colour in RGBA.
Definition: Element.h:101
diff --git a/docs/doxygen/html/_i_o_control_8h.html b/docs/doxygen/html/_i_o_control_8h.html index e4a200a..119082e 100644 --- a/docs/doxygen/html/_i_o_control_8h.html +++ b/docs/doxygen/html/_i_o_control_8h.html @@ -92,7 +92,7 @@ $(document).ready(function(){initNavTree('_i_o_control_8h.html','');});
#include "ControlElement.h"
#include <wx/dcscreen.h>
-#include "wxGLString.h"
+#include "OpenGLText.h"

Go to the source code of this file.

diff --git a/docs/doxygen/html/_i_o_control_8h_source.html b/docs/doxygen/html/_i_o_control_8h_source.html index 4950e4d..7090270 100644 --- a/docs/doxygen/html/_i_o_control_8h_source.html +++ b/docs/doxygen/html/_i_o_control_8h_source.html @@ -88,18 +88,20 @@ $(document).ready(function(){initNavTree('_i_o_control_8h_source.html','');});
IOControl.h
-Go to the documentation of this file.
1 /*
2  * Copyright (C) 2017 Thales Lima Oliveira <thales@ufu.br>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program. If not, see <https://www.gnu.org/licenses/>.
16  */
17 
18 #ifndef IOCONTROL_H
19 #define IOCONTROL_H
20 
21 #include "ControlElement.h"
22 
23 #include <wx/dcscreen.h>
24 #include "wxGLString.h"
25 
26 class IOControlForm;
27 
35 class IOControl : public ControlElement
36 {
37  public:
38  enum IOFlags {
39  IN_TERMINAL_VOLTAGE = 1 << 0,
40  IN_VELOCITY = 1 << 1,
41  IN_ACTIVE_POWER = 1 << 2,
42  IN_REACTIVE_POWER = 1 << 3,
43  OUT_FIELD_VOLTAGE = 1 << 4,
44  OUT_MEC_POWER = 1 << 5
45  };
46 
47  IOControl(int ioFlags, int id);
48  ~IOControl();
49 
50  virtual void Draw(wxPoint2DDouble translation, double scale) const;
51  virtual bool Contains(wxPoint2DDouble position) const { return m_rect.Contains(position); }
52  virtual bool Intersects(wxRect2DDouble rect) const { return m_rect.Intersects(rect); }
53  virtual bool ShowForm(wxWindow* parent, Element* element);
54  virtual void Rotate(bool clockwise = true);
55  virtual void UpdateText() { SetValue(m_value); }
56  virtual wxString GenerateText();
57  virtual void UpdatePoints();
58 
59  virtual IOFlags GetValue() const { return m_value; }
60  virtual void SetValue(IOFlags value);
61  virtual int GetIOFlags() const { return m_ioFlags; }
62  virtual Node::NodeType GetType() { return m_ioNodeType; }
63  virtual Element* GetCopy();
64 
65  protected:
66  IOFlags m_value;
67  int m_ioFlags;
68 
69  Node::NodeType m_ioNodeType = Node::NODE_IN;
70 
71  wxGLString* m_glStringValue = NULL;
72  int m_fontSize = 10;
73 };
74 
75 #endif // IOCONTROL_H
Base class of all elements of the program. This class is responsible for manage graphical and his dat...
Definition: Element.h:113
-
virtual bool Contains(wxPoint2DDouble position) const
Checks if the element contains a position.
Definition: IOControl.h:51
+Go to the documentation of this file.
1 /*
2  * Copyright (C) 2017 Thales Lima Oliveira <thales@ufu.br>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program. If not, see <https://www.gnu.org/licenses/>.
16  */
17 
18 #ifndef IOCONTROL_H
19 #define IOCONTROL_H
20 
21 #include "ControlElement.h"
22 
23 #include <wx/dcscreen.h>
24 #include "OpenGLText.h"
25 
26 class IOControlForm;
27 
35 class IOControl : public ControlElement
36 {
37  public:
38  enum IOFlags {
39  IN_TERMINAL_VOLTAGE = 1 << 0,
40  IN_VELOCITY = 1 << 1,
41  IN_ACTIVE_POWER = 1 << 2,
42  IN_REACTIVE_POWER = 1 << 3,
43  OUT_FIELD_VOLTAGE = 1 << 4,
44  OUT_MEC_POWER = 1 << 5,
45  IN_INITIAL_TERMINAL_VOLTAGE = 1 << 6,
46  IN_INITIAL_MEC_POWER = 1 << 7,
47  IN_INITIAL_VELOCITY = 1 << 8,
48  IN_DELTA_VELOCITY = 1 << 9,
49  IN_DELTA_ACTIVE_POWER = 1 << 10,
50  };
51 
52  IOControl(int ioFlags, int id);
53  ~IOControl();
54 
55  virtual void Draw(wxPoint2DDouble translation, double scale) const;
56  virtual bool Contains(wxPoint2DDouble position) const { return m_rect.Contains(position); }
57  virtual bool Intersects(wxRect2DDouble rect) const { return m_rect.Intersects(rect); }
58  virtual bool ShowForm(wxWindow* parent, Element* element);
59  virtual void Rotate(bool clockwise = true);
60  virtual bool UpdateText();
61  virtual wxString GenerateText();
62  virtual void UpdatePoints();
63 
64  virtual IOFlags GetValue() const { return m_value; }
65  virtual void SetValue(IOFlags value);
66  virtual int GetIOFlags() const { return m_ioFlags; }
67  virtual Node::NodeType GetType() { return m_ioNodeType; }
68  virtual Element* GetCopy();
69 
70  protected:
71  IOFlags m_value;
72  int m_ioFlags;
73 
74  Node::NodeType m_ioNodeType = Node::NODE_IN;
75 
76  OpenGLText* m_glText = NULL;
77 };
78 
79 #endif // IOCONTROL_H
Base class of all elements of the program. This class is responsible for manage graphical and his dat...
Definition: Element.h:113
+
virtual bool Contains(wxPoint2DDouble position) const
Checks if the element contains a position.
Definition: IOControl.h:56
virtual void Rotate(bool clockwise=true)
Rotate the element.
Definition: IOControl.cpp:133
+
virtual bool UpdateText()
Update the OpenGL text in the element (if present).
Definition: IOControl.cpp:267
Provides the communication with the power element.
Definition: IOControl.h:35
-
virtual bool Intersects(wxRect2DDouble rect) const
Check if the element&#39;s rect intersects other rect.
Definition: IOControl.h:52
-
virtual Element * GetCopy()
Get a the element copy.
Definition: IOControl.cpp:243
+
virtual bool Intersects(wxRect2DDouble rect) const
Check if the element&#39;s rect intersects other rect.
Definition: IOControl.h:57
+ +
virtual Element * GetCopy()
Get a the element copy.
Definition: IOControl.cpp:259
virtual bool ShowForm(wxWindow *parent, Element *element)
Show element data form.
Definition: IOControl.cpp:122
-
virtual void Draw(wxPoint2DDouble translation, double scale) const
Draw the element.
Definition: IOControl.cpp:36
+
Class to draw text on OpenGL using wxWidgets.
Definition: OpenGLText.h:31
+
virtual void Draw(wxPoint2DDouble translation, double scale) const
Draw the element.
Definition: IOControl.cpp:40
Base class of a control element. Provide general methods to other control classes.
Form to edit the input/output control data.
Definition: IOControlForm.h:31
-
diff --git a/docs/doxygen/html/_i_o_control_form_8cpp_source.html b/docs/doxygen/html/_i_o_control_form_8cpp_source.html index 7f17159..82b4948 100644 --- a/docs/doxygen/html/_i_o_control_form_8cpp_source.html +++ b/docs/doxygen/html/_i_o_control_form_8cpp_source.html @@ -88,7 +88,7 @@ $(document).ready(function(){initNavTree('_i_o_control_form_8cpp_source.html',''
IOControlForm.cpp
-
1 /*
2  * Copyright (C) 2017 Thales Lima Oliveira <thales@ufu.br>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program. If not, see <https://www.gnu.org/licenses/>.
16  */
17 
18 #include "IOControlForm.h"
19 
20 IOControlForm::IOControlForm(wxWindow* parent, IOControl* ioControl) : IOControlFormBase(parent)
21 {
22  SetSize(GetBestSize());
23 
24  m_parent = parent;
25  m_ioControl = ioControl;
26 
27  int ioFlags = m_ioControl->GetIOFlags();
28  int inChoiceNumber = -1;
29  int outChoiceNumber = -1;
30 
31  if(ioFlags & IOControl::IN_TERMINAL_VOLTAGE) {
32  m_choiceInput->Append(_("Terminal voltage"));
33  m_inputFlags.push_back(IOControl::IN_TERMINAL_VOLTAGE);
34  if(m_ioControl->GetValue() == IOControl::IN_TERMINAL_VOLTAGE) inChoiceNumber = (int)m_inputFlags.size() - 1;
35  }
36  if(ioFlags & IOControl::IN_VELOCITY) {
37  m_choiceInput->Append(_("Velocity"));
38  m_inputFlags.push_back(IOControl::IN_VELOCITY);
39  if(m_ioControl->GetValue() == IOControl::IN_VELOCITY) inChoiceNumber = (int)m_inputFlags.size() - 1;
40  }
41  if(ioFlags & IOControl::IN_ACTIVE_POWER) {
42  m_choiceInput->Append(_("Active power"));
43  m_inputFlags.push_back(IOControl::IN_ACTIVE_POWER);
44  if(m_ioControl->GetValue() == IOControl::IN_ACTIVE_POWER) inChoiceNumber = (int)m_inputFlags.size() - 1;
45  }
46  if(ioFlags & IOControl::IN_REACTIVE_POWER) {
47  m_choiceInput->Append(_("Reactive power"));
48  m_inputFlags.push_back(IOControl::IN_REACTIVE_POWER);
49  if(m_ioControl->GetValue() == IOControl::IN_REACTIVE_POWER) inChoiceNumber = (int)m_inputFlags.size() - 1;
50  }
51  if(ioFlags & IOControl::OUT_FIELD_VOLTAGE) {
52  m_choiceOutput->Append(_("Field voltage"));
53  m_outputFlags.push_back(IOControl::OUT_FIELD_VOLTAGE);
54  if(m_ioControl->GetValue() == IOControl::OUT_FIELD_VOLTAGE) outChoiceNumber = (int)m_outputFlags.size() - 1;
55  }
56  if(ioFlags & IOControl::OUT_MEC_POWER) {
57  m_choiceOutput->Append(_("Mechanical power"));
58  m_outputFlags.push_back(IOControl::OUT_MEC_POWER);
59  if(m_ioControl->GetValue() == IOControl::OUT_MEC_POWER) outChoiceNumber = (int)m_outputFlags.size() - 1;
60  }
61 
62  if(inChoiceNumber != -1) {
63  m_choiceInput->SetSelection(inChoiceNumber);
64  m_checkBoxInput->SetValue(true);
65  m_checkBoxOutput->SetValue(false);
66  m_choiceOutput->Enable(false);
67  } else {
68  m_choiceOutput->SetSelection(outChoiceNumber);
69  m_checkBoxInput->SetValue(false);
70  m_checkBoxOutput->SetValue(true);
71  m_choiceInput->Enable(false);
72  }
73 }
74 
75 IOControlForm::~IOControlForm() {}
76 void IOControlForm::OnOKButtonClick(wxCommandEvent& event)
77 {
78  if(ValidateData()) EndModal(wxID_OK);
79 }
80 
81 bool IOControlForm::ValidateData()
82 {
83  if(m_checkBoxInput->GetValue() && m_choiceInput->GetSelection() != -1) {
84  m_ioControl->SetValue(m_inputFlags[m_choiceInput->GetSelection()]);
85  return true;
86  } else if(m_checkBoxOutput->GetValue() && m_choiceOutput->GetSelection() != -1) {
87  m_ioControl->SetValue(m_outputFlags[m_choiceOutput->GetSelection()]);
88  return true;
89  }
90 
91  return false;
92 }
93 
94 void IOControlForm::OnInputChecked(wxCommandEvent& event)
95 {
96  m_checkBoxInput->SetValue(true);
97  m_checkBoxOutput->SetValue(false);
98  m_choiceOutput->Enable(false);
99  m_choiceInput->Enable(true);
100 }
101 
102 void IOControlForm::OnOutputChecked(wxCommandEvent& event)
103 {
104  m_checkBoxOutput->SetValue(true);
105  m_checkBoxInput->SetValue(false);
106  m_choiceOutput->Enable(true);
107  m_choiceInput->Enable(false);
108 }
+
1 /*
2  * Copyright (C) 2017 Thales Lima Oliveira <thales@ufu.br>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program. If not, see <https://www.gnu.org/licenses/>.
16  */
17 
18 #include "IOControlForm.h"
19 
20 IOControlForm::IOControlForm(wxWindow* parent, IOControl* ioControl) : IOControlFormBase(parent)
21 {
22  SetSize(GetBestSize());
23 
24  m_parent = parent;
25  m_ioControl = ioControl;
26 
27  int ioFlags = m_ioControl->GetIOFlags();
28  int inChoiceNumber = -1;
29  int outChoiceNumber = -1;
30 
31  if(ioFlags & IOControl::IN_TERMINAL_VOLTAGE) {
32  m_choiceInput->Append(_("Terminal voltage"));
33  m_inputFlags.push_back(IOControl::IN_TERMINAL_VOLTAGE);
34  if(m_ioControl->GetValue() == IOControl::IN_TERMINAL_VOLTAGE) inChoiceNumber = (int)m_inputFlags.size() - 1;
35  }
36  if(ioFlags & IOControl::IN_VELOCITY) {
37  m_choiceInput->Append(_("Velocity"));
38  m_inputFlags.push_back(IOControl::IN_VELOCITY);
39  if(m_ioControl->GetValue() == IOControl::IN_VELOCITY) inChoiceNumber = (int)m_inputFlags.size() - 1;
40  }
41  if(ioFlags & IOControl::IN_ACTIVE_POWER) {
42  m_choiceInput->Append(_("Active power"));
43  m_inputFlags.push_back(IOControl::IN_ACTIVE_POWER);
44  if(m_ioControl->GetValue() == IOControl::IN_ACTIVE_POWER) inChoiceNumber = (int)m_inputFlags.size() - 1;
45  }
46  if(ioFlags & IOControl::IN_REACTIVE_POWER) {
47  m_choiceInput->Append(_("Reactive power"));
48  m_inputFlags.push_back(IOControl::IN_REACTIVE_POWER);
49  if(m_ioControl->GetValue() == IOControl::IN_REACTIVE_POWER) inChoiceNumber = (int)m_inputFlags.size() - 1;
50  }
51  if(ioFlags & IOControl::OUT_FIELD_VOLTAGE) {
52  m_choiceOutput->Append(_("Field voltage"));
53  m_outputFlags.push_back(IOControl::OUT_FIELD_VOLTAGE);
54  if(m_ioControl->GetValue() == IOControl::OUT_FIELD_VOLTAGE) outChoiceNumber = (int)m_outputFlags.size() - 1;
55  }
56  if(ioFlags & IOControl::OUT_MEC_POWER) {
57  m_choiceOutput->Append(_("Mechanical power"));
58  m_outputFlags.push_back(IOControl::OUT_MEC_POWER);
59  if(m_ioControl->GetValue() == IOControl::OUT_MEC_POWER) outChoiceNumber = (int)m_outputFlags.size() - 1;
60  }
61 
62  if(ioFlags & IOControl::IN_INITIAL_MEC_POWER) {
63  m_choiceInput->Append(_("Initial mechanical power"));
64  m_inputFlags.push_back(IOControl::IN_INITIAL_MEC_POWER);
65  if(m_ioControl->GetValue() == IOControl::IN_INITIAL_MEC_POWER) inChoiceNumber = (int)m_inputFlags.size() - 1;
66  }
67 
68  if(ioFlags & IOControl::IN_INITIAL_TERMINAL_VOLTAGE) {
69  m_choiceInput->Append(_("Initial terminal voltage"));
70  m_inputFlags.push_back(IOControl::IN_INITIAL_TERMINAL_VOLTAGE);
71  if(m_ioControl->GetValue() == IOControl::IN_INITIAL_TERMINAL_VOLTAGE)
72  inChoiceNumber = (int)m_inputFlags.size() - 1;
73  }
74 
75  if(ioFlags & IOControl::IN_INITIAL_VELOCITY) {
76  m_choiceInput->Append(_("Initial velocity"));
77  m_inputFlags.push_back(IOControl::IN_INITIAL_VELOCITY);
78  if(m_ioControl->GetValue() == IOControl::IN_INITIAL_VELOCITY) inChoiceNumber = (int)m_inputFlags.size() - 1;
79  }
80 
81  if(ioFlags & IOControl::IN_DELTA_VELOCITY) {
82  m_choiceInput->Append(_("Velocity variation"));
83  m_inputFlags.push_back(IOControl::IN_DELTA_VELOCITY);
84  if(m_ioControl->GetValue() == IOControl::IN_DELTA_VELOCITY) inChoiceNumber = (int)m_inputFlags.size() - 1;
85  }
86 
87  if(ioFlags & IOControl::IN_DELTA_ACTIVE_POWER) {
88  m_choiceInput->Append(_("Active power variation"));
89  m_inputFlags.push_back(IOControl::IN_DELTA_ACTIVE_POWER);
90  if(m_ioControl->GetValue() == IOControl::IN_DELTA_ACTIVE_POWER) inChoiceNumber = (int)m_inputFlags.size() - 1;
91  }
92 
93  if(inChoiceNumber != -1) {
94  m_choiceInput->SetSelection(inChoiceNumber);
95  m_checkBoxInput->SetValue(true);
96  m_checkBoxOutput->SetValue(false);
97  m_choiceOutput->Enable(false);
98  } else {
99  m_choiceOutput->SetSelection(outChoiceNumber);
100  m_checkBoxInput->SetValue(false);
101  m_checkBoxOutput->SetValue(true);
102  m_choiceInput->Enable(false);
103  }
104 }
105 
106 IOControlForm::~IOControlForm() {}
107 void IOControlForm::OnOKButtonClick(wxCommandEvent& event)
108 {
109  if(ValidateData()) EndModal(wxID_OK);
110 }
111 
112 bool IOControlForm::ValidateData()
113 {
114  if(m_checkBoxInput->GetValue() && m_choiceInput->GetSelection() != -1) {
115  m_ioControl->SetValue(m_inputFlags[m_choiceInput->GetSelection()]);
116  return true;
117  } else if(m_checkBoxOutput->GetValue() && m_choiceOutput->GetSelection() != -1) {
118  m_ioControl->SetValue(m_outputFlags[m_choiceOutput->GetSelection()]);
119  return true;
120  }
121 
122  return false;
123 }
124 
125 void IOControlForm::OnInputChecked(wxCommandEvent& event)
126 {
127  m_checkBoxInput->SetValue(true);
128  m_checkBoxOutput->SetValue(false);
129  m_choiceOutput->Enable(false);
130  m_choiceInput->Enable(true);
131 }
132 
133 void IOControlForm::OnOutputChecked(wxCommandEvent& event)
134 {
135  m_checkBoxOutput->SetValue(true);
136  m_checkBoxInput->SetValue(false);
137  m_choiceOutput->Enable(true);
138  m_choiceInput->Enable(false);
139 }
Provides the communication with the power element.
Definition: IOControl.h:35
diff --git a/docs/doxygen/html/_i_o_control_form_8h_source.html b/docs/doxygen/html/_i_o_control_form_8h_source.html index f24ff47..55acd09 100644 --- a/docs/doxygen/html/_i_o_control_form_8h_source.html +++ b/docs/doxygen/html/_i_o_control_form_8h_source.html @@ -88,7 +88,7 @@ $(document).ready(function(){initNavTree('_i_o_control_form_8h_source.html','');
IOControlForm.h
-Go to the documentation of this file.
1 /*
2  * Copyright (C) 2017 Thales Lima Oliveira <thales@ufu.br>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program. If not, see <https://www.gnu.org/licenses/>.
16  */
17 
18 #ifndef IOCONTROLFORM_H
19 #define IOCONTROLFORM_H
20 
21 #include "ElementForm.h"
22 #include "IOControl.h"
23 
32 {
33  public:
34  IOControlForm(wxWindow* parent, IOControl* ioControl);
35  virtual ~IOControlForm();
36 
37  virtual bool ValidateData();
38 
39  protected:
40  virtual void OnInputChecked(wxCommandEvent& event);
41  virtual void OnOutputChecked(wxCommandEvent& event);
42  virtual void OnCancelButtonClick(wxCommandEvent& event) { EndModal(wxID_CANCEL); };
43  virtual void OnOKButtonClick(wxCommandEvent& event);
44 
45  wxWindow* m_parent;
46  IOControl* m_ioControl;
47 
48  std::vector<IOControl::IOFlags> m_inputFlags;
49  std::vector<IOControl::IOFlags> m_outputFlags;
50 };
51 #endif // IOCONTROLFORM_H
+Go to the documentation of this file.
1 /*
2  * Copyright (C) 2017 Thales Lima Oliveira <thales@ufu.br>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program. If not, see <https://www.gnu.org/licenses/>.
16  */
17 
18 #ifndef IOCONTROLFORM_H
19 #define IOCONTROLFORM_H
20 
21 #include "ElementForm.h"
22 #include "IOControl.h"
23 
32 {
33  public:
34  IOControlForm(wxWindow* parent, IOControl* ioControl);
35  virtual ~IOControlForm();
36 
37  virtual bool ValidateData();
38 
39  protected:
40  virtual void OnInputChecked(wxCommandEvent& event);
41  virtual void OnOutputChecked(wxCommandEvent& event);
42  virtual void OnCancelButtonClick(wxCommandEvent& event) { EndModal(wxID_CANCEL); };
43  virtual void OnOKButtonClick(wxCommandEvent& event);
44 
45  wxWindow* m_parent;
46  IOControl* m_ioControl;
47 
48  std::vector<IOControl::IOFlags> m_inputFlags;
49  std::vector<IOControl::IOFlags> m_outputFlags;
50 };
51 #endif // IOCONTROLFORM_H
Provides the communication with the power element.
Definition: IOControl.h:35
Form to edit the input/output control data.
Definition: IOControlForm.h:31
diff --git a/docs/doxygen/html/_ind_motor_form_8cpp_source.html b/docs/doxygen/html/_ind_motor_form_8cpp_source.html index 4113377..a547072 100644 --- a/docs/doxygen/html/_ind_motor_form_8cpp_source.html +++ b/docs/doxygen/html/_ind_motor_form_8cpp_source.html @@ -92,7 +92,7 @@ $(document).ready(function(){initNavTree('_ind_motor_form_8cpp_source.html',''); - + diff --git a/docs/doxygen/html/_ind_motor_form_8h_source.html b/docs/doxygen/html/_ind_motor_form_8h_source.html index be88cab..b1f254f 100644 --- a/docs/doxygen/html/_ind_motor_form_8h_source.html +++ b/docs/doxygen/html/_ind_motor_form_8h_source.html @@ -88,7 +88,7 @@ $(document).ready(function(){initNavTree('_ind_motor_form_8h_source.html','');})
IndMotorForm.h
-Go to the documentation of this file.
1 /*
2  * Copyright (C) 2017 Thales Lima Oliveira <thales@ufu.br>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program. If not, see <https://www.gnu.org/licenses/>.
16  */
17 
18 #ifndef INDMOTORFORM_H
19 #define INDMOTORFORM_H
20 #include "ElementForm.h"
21 
22 class IndMotor;
23 
32 {
33  public:
34  IndMotorForm(wxWindow* parent, IndMotor* indMotor);
35  virtual ~IndMotorForm();
36  virtual bool ValidateData();
37 
38  protected:
39  virtual void OnCancelButtonClick(wxCommandEvent& event) { EndModal(wxID_CANCEL); };
40  virtual void OnOKButtonClick(wxCommandEvent& event);
41  virtual void OnStabilityButtonClick(wxCommandEvent& event);
42 
43  wxWindow* m_parent = NULL;
44  IndMotor* m_indMotor = NULL;
45 };
46 #endif // INDMOTORFORM_H
+Go to the documentation of this file.
1 /*
2  * Copyright (C) 2017 Thales Lima Oliveira <thales@ufu.br>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program. If not, see <https://www.gnu.org/licenses/>.
16  */
17 
18 #ifndef INDMOTORFORM_H
19 #define INDMOTORFORM_H
20 #include "ElementForm.h"
21 
22 class IndMotor;
23 
32 {
33  public:
34  IndMotorForm(wxWindow* parent, IndMotor* indMotor);
35  virtual ~IndMotorForm();
36  virtual bool ValidateData();
37 
38  protected:
39  virtual void OnCancelButtonClick(wxCommandEvent& event) { EndModal(wxID_CANCEL); };
40  virtual void OnOKButtonClick(wxCommandEvent& event);
41  virtual void OnStabilityButtonClick(wxCommandEvent& event);
42 
43  wxWindow* m_parent = NULL;
44  IndMotor* m_indMotor = NULL;
45 };
46 #endif // INDMOTORFORM_H
Induction motor power element.
Definition: IndMotor.h:40
Form to edit the induction motor power data.
Definition: IndMotorForm.h:31
diff --git a/docs/doxygen/html/_limiter_form_8cpp_source.html b/docs/doxygen/html/_limiter_form_8cpp_source.html index df9af8c..22cb91e 100644 --- a/docs/doxygen/html/_limiter_form_8cpp_source.html +++ b/docs/doxygen/html/_limiter_form_8cpp_source.html @@ -89,7 +89,7 @@ $(document).ready(function(){initNavTree('_limiter_form_8cpp_source.html','');})
1 /*
2  * Copyright (C) 2017 Thales Lima Oliveira <thales@ufu.br>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program. If not, see <https://www.gnu.org/licenses/>.
16  */
17 
18 #include "LimiterForm.h"
19 #include "Limiter.h"
20 
21 LimiterForm::LimiterForm(wxWindow* parent, Limiter* limiter) : LimiterFormBase(parent)
22 {
23  SetSize(GetBestSize());
24 
25  m_limiter = limiter;
26  m_parent = parent;
27 
28  m_textCtrlUpLimit->SetValue(m_limiter->StringFromDouble(m_limiter->GetUpLimit()));
29  m_textCtrlLowLimit->SetValue(m_limiter->StringFromDouble(m_limiter->GetLowLimit()));
30 }
31 
32 LimiterForm::~LimiterForm() {}
33 void LimiterForm::OnOKButtonClick(wxCommandEvent& event)
34 {
35  if(ValidateData()) EndModal(wxID_OK);
36 }
37 
38 bool LimiterForm::ValidateData()
39 {
40  double upLimit;
41  double lowLimit;
42 
43  if(!m_limiter->DoubleFromString(this, m_textCtrlUpLimit->GetValue(), upLimit,
44  _("Value entered incorrectly in the field \"Upper limit\".")))
45  return false;
46  if(!m_limiter->DoubleFromString(this, m_textCtrlLowLimit->GetValue(), lowLimit,
47  _("Value entered incorrectly in the field \"Lower limit\".")))
48  return false;
49 
50  m_limiter->SetUpLimit(upLimit);
51  m_limiter->SetLowLimit(lowLimit);
52  return true;
53 }
Limits the input value by superior and inferior values.
Definition: Limiter.h:32
- +
diff --git a/docs/doxygen/html/_limiter_form_8h_source.html b/docs/doxygen/html/_limiter_form_8h_source.html index e5f60e9..09384a4 100644 --- a/docs/doxygen/html/_limiter_form_8h_source.html +++ b/docs/doxygen/html/_limiter_form_8h_source.html @@ -89,7 +89,7 @@ $(document).ready(function(){initNavTree('_limiter_form_8h_source.html','');});
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2017 Thales Lima Oliveira <thales@ufu.br>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program. If not, see <https://www.gnu.org/licenses/>.
16  */
17 
18 #ifndef LIMITERFORM_H
19 #define LIMITERFORM_H
20 #include "ElementForm.h"
21 
22 class Limiter;
23 
32 {
33  public:
34  LimiterForm(wxWindow* parent, Limiter* limiter);
35  virtual ~LimiterForm();
36  virtual bool ValidateData();
37 
38  protected:
39  virtual void OnCancelButtonClick(wxCommandEvent& event) { EndModal(wxID_CANCEL); }
40  virtual void OnOKButtonClick(wxCommandEvent& event);
41 
42  wxWindow* m_parent = NULL;
43  Limiter* m_limiter = NULL;
44 };
45 #endif // LIMITERFORM_H
Limits the input value by superior and inferior values.
Definition: Limiter.h:32
- +
Form to edit the limit control data.
Definition: LimiterForm.h:31
diff --git a/docs/doxygen/html/_line_8cpp_source.html b/docs/doxygen/html/_line_8cpp_source.html index aace7c2..be4f201 100644 --- a/docs/doxygen/html/_line_8cpp_source.html +++ b/docs/doxygen/html/_line_8cpp_source.html @@ -88,7 +88,7 @@ $(document).ready(function(){initNavTree('_line_8cpp_source.html','');});
Line.cpp
-
1 /*
2  * Copyright (C) 2017 Thales Lima Oliveira <thales@ufu.br>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program. If not, see <https://www.gnu.org/licenses/>.
16  */
17 
18 #include "Line.h"
19 
20 Line::Line() : Branch()
21 {
22  for(int i = 0; i < 2; i++) {
23  for(int j = 0; j < 3; j++) {
24  m_electricalData.faultCurrent[i][j] = std::complex<double>(0.0, 0.0);
25  }
26  }
27 }
28 
29 Line::Line(wxString name) : Branch()
30 {
31  for(int i = 0; i < 2; i++) {
32  for(int j = 0; j < 3; j++) {
33  m_electricalData.faultCurrent[i][j] = std::complex<double>(0.0, 0.0);
34  }
35  }
36  m_electricalData.name = name;
37 }
38 Line::~Line() {}
39 bool Line::Contains(wxPoint2DDouble position) const
40 {
41  if(PointToLineDistance(position) < 5.0) {
42  return true;
43  }
44  return false;
45 }
46 
47 void Line::Draw(wxPoint2DDouble translation, double scale) const
48 {
49  OpenGLColour elementColour;
50  if(m_online) {
51  if(m_dynEvent)
52  elementColour = m_dynamicEventColour;
53  else
54  elementColour = m_onlineElementColour;
55 
56  } else
57  elementColour = m_offlineElementColour;
58 
59  std::vector<wxPoint2DDouble> pointList = m_pointList;
60  if(!m_inserted && pointList.size() > 0) {
61  wxPoint2DDouble secondPoint = m_position;
62  if(pointList.size() > 2) {
63  secondPoint = pointList[2];
64  }
65  pointList[1] = GetSwitchPoint(m_parentList[0], pointList[0], secondPoint);
66  pointList.push_back(m_position);
67  }
68 
69  // Line selected (Layer 1).
70  if(m_selected) {
71  glLineWidth(1.5 + m_borderSize * 2.0);
72  glColor4dv(m_selectionColour.GetRGBA());
73  DrawLine(pointList);
74 
75  // Draw nodes selection.
76  if(pointList.size() > 0) {
77  DrawCircle(pointList[0], 5.0 + m_borderSize / scale, 10, GL_POLYGON);
78  if(m_inserted) {
79  DrawCircle(pointList[pointList.size() - 1], 5.0 + m_borderSize / scale, 10, GL_POLYGON);
80  }
81  }
82  }
83 
84  // Draw line (Layer 2)
85  glLineWidth(1.5);
86  glColor4dv(elementColour.GetRGBA());
87  DrawLine(pointList);
88 
89  if(m_inserted) {
90  DrawSwitches();
91  DrawPowerFlowPts();
92  }
93 
94  // Draw nodes.
95  if(pointList.size() > 0) {
96  glColor4dv(elementColour.GetRGBA());
97  DrawCircle(pointList[0], 5.0, 10, GL_POLYGON);
98  if(m_inserted) {
99  DrawCircle(pointList[pointList.size() - 1], 5.0, 10, GL_POLYGON);
100  }
101  }
102 
103  // Draw pickboxes (Layer 3).
104  if(m_showPickbox) {
105  glPushMatrix();
106  glLoadIdentity();
107 
108  for(int i = 2; i < (int)m_pointList.size() - 2; i++) {
109  DrawPickbox(WorldToScreen(m_pointList[i], translation, scale));
110  }
111 
112  glPopMatrix();
113  }
114 }
115 
116 void Line::Move(wxPoint2DDouble position)
117 {
118  if(!m_parentList[0]) {
119  m_pointList[0] = m_movePts[0] + position - m_moveStartPt;
120  UpdateSwitchesPosition();
121  UpdatePowerFlowArrowsPosition();
122  }
123  if(!m_parentList[1]) {
124  m_pointList[m_pointList.size() - 1] = m_movePts[m_pointList.size() - 1] + position - m_moveStartPt;
125  UpdateSwitchesPosition();
126  UpdatePowerFlowArrowsPosition();
127  }
128 
129  if(!m_parentList[0] && !m_parentList[1]) {
130  for(int i = 2; i < (int)m_pointList.size() - 2; i++) {
131  m_pointList[i] = m_movePts[i] + position - m_moveStartPt;
132  }
133  }
134 }
135 
136 bool Line::AddParent(Element* parent, wxPoint2DDouble position)
137 {
138  if(parent) {
139  // First bus.
140  if(m_parentList.size() == 0) {
141  m_position = position;
142  m_parentList.push_back(parent);
143  parent->AddChild(this);
144  wxPoint2DDouble parentPt =
145  parent->RotateAtPosition(position, -parent->GetAngle()); // Rotate click to horizontal position.
146  parentPt.m_y = parent->GetPosition().m_y; // Centralize on bus.
147  parentPt = parent->RotateAtPosition(parentPt, parent->GetAngle()); // Rotate back.
148  m_pointList.push_back(parentPt); // First point
149  m_pointList.push_back(GetSwitchPoint(parent, parentPt, m_position));
150 
151  wxRect2DDouble genRect(0, 0, 0, 0);
152  m_switchRect.push_back(genRect);
153  UpdateSwitches();
154 
155  Bus* parentBus = static_cast<Bus*>(parent);
156  m_electricalData.nominalVoltage = parentBus->GetElectricalData().nominalVoltage;
157  m_electricalData.nominalVoltageUnit = parentBus->GetElectricalData().nominalVoltageUnit;
158 
159  return false;
160  }
161  // Second bus.
162  else if(parent != m_parentList[0]) {
163  Bus* parentBus = static_cast<Bus*>(parent);
164  if(m_electricalData.nominalVoltage != parentBus->GetElectricalData().nominalVoltage ||
165  m_electricalData.nominalVoltageUnit != parentBus->GetElectricalData().nominalVoltageUnit) {
166  wxMessageDialog msgDialog(NULL, _("Unable to connect two buses with different nominal voltages.\n"
167  "Use a transformer or edit the bus properties."),
168  _("Error"), wxOK | wxCENTRE | wxICON_ERROR);
169  msgDialog.ShowModal();
170  return false;
171  }
172 
173  m_parentList.push_back(parent);
174  parent->AddChild(this);
175  wxPoint2DDouble parentPt =
176  parent->RotateAtPosition(position, -parent->GetAngle()); // Rotate click to horizontal position.
177  parentPt.m_y = parent->GetPosition().m_y; // Centralize on bus.
178  parentPt = parent->RotateAtPosition(parentPt, parent->GetAngle()); // Rotate back.
179 
180  // Set first switch point.
181  wxPoint2DDouble secondPoint = parentPt;
182  if(m_pointList.size() > 2) {
183  secondPoint = m_pointList[2];
184  }
185  m_pointList[1] = GetSwitchPoint(m_parentList[0], m_pointList[0], secondPoint);
186 
187  // Set the second switch point.
188  m_pointList.push_back(GetSwitchPoint(parent, parentPt, m_pointList[m_pointList.size() - 1]));
189 
190  m_pointList.push_back(parentPt); // Last point.
191 
192  wxRect2DDouble genRect(0, 0, 0, 0);
193  m_switchRect.push_back(genRect);
194  UpdateSwitches();
195 
196  m_inserted = true;
197  UpdatePowerFlowArrowsPosition();
198  return true;
199  }
200  }
201  return false;
202 }
203 bool Line::Intersects(wxRect2DDouble rect) const
204 {
205  for(auto it = m_pointList.begin(); it != m_pointList.end(); ++it) {
206  if(rect.Contains(*it)) return true;
207  }
208  return false;
209 }
210 void Line::MovePickbox(wxPoint2DDouble position)
211 {
212  if(m_activePickboxID == ID_PB_NONE) return;
213 
214  for(int i = 2; i < (int)m_pointList.size() - 2; i++) {
215  if(m_activePickboxID == i) {
216  m_pointList[i] = m_movePts[i] + position - m_moveStartPt;
217  UpdateSwitchesPosition();
218  UpdatePowerFlowArrowsPosition();
219  }
220  }
221 }
222 bool Line::PickboxContains(wxPoint2DDouble position)
223 {
224  for(int i = 2; i < (int)m_pointList.size() - 2; i++) {
225  wxRect2DDouble rect(m_pointList[i].m_x - 5.0, m_pointList[i].m_y - 5.0, 10.0, 10.0);
226  if(rect.Contains(position)) {
227  m_activePickboxID = i;
228  return true;
229  }
230  }
231  return false;
232 }
233 
234 void Line::AddPoint(wxPoint2DDouble point)
235 {
236  if(m_parentList.size() != 0) {
237  m_pointList.push_back(point);
238  }
239 }
240 
241 void Line::StartMove(wxPoint2DDouble position)
242 {
243  m_moveStartPt = position;
244  m_movePts = m_pointList;
245 }
246 
247 void Line::MoveNode(Element* parent, wxPoint2DDouble position)
248 {
249  if(parent) {
250  // First bus.
251  if(parent == m_parentList[0]) {
252  m_pointList[0] = m_movePts[0] + position - m_moveStartPt;
253  }
254  // Second bus.
255  else if(parent == m_parentList[1]) {
256  m_pointList[m_pointList.size() - 1] = m_movePts[m_pointList.size() - 1] + position - m_moveStartPt;
257  }
258 
259  // If the line is selected, move all the points, except the switches and buses points.
260  if(m_selected) {
261  for(int i = 2; i < (int)m_pointList.size() - 1; i++) {
262  m_pointList[i] = m_movePts[i] + position - m_moveStartPt;
263  }
264  }
265  } else {
266  // If parent is setted to NULL for the firts time, remove the parent child
267  if(m_activeNodeID == 1) {
268  m_pointList[0] = m_movePts[0] + position - m_moveStartPt;
269  if(m_parentList[0]) {
270  m_parentList[0]->RemoveChild(this);
271  m_parentList[0] = NULL;
272  m_online = false;
273  }
274  } else if(m_activeNodeID == 2) {
275  m_pointList[m_pointList.size() - 1] = m_movePts[m_pointList.size() - 1] + position - m_moveStartPt;
276  if(m_parentList[1]) {
277  m_parentList[1]->RemoveChild(this);
278  m_parentList[1] = NULL;
279  m_online = false;
280  }
281  }
282  }
283 
284  // Recalculate switches positions
285  UpdateSwitchesPosition();
286  UpdatePowerFlowArrowsPosition();
287 }
288 
289 bool Line::GetContextMenu(wxMenu& menu)
290 {
291  wxFileName exeFileName(wxStandardPaths::Get().GetExecutablePath());
292  wxString exePath = exeFileName.GetPath();
293 
294  menu.Append(ID_EDIT_ELEMENT, _("Edit line"));
295  if(m_activePickboxID == ID_PB_NONE) {
296  wxMenuItem* addNodeItem = new wxMenuItem(&menu, ID_LINE_ADD_NODE, _("Insert node"));
297  addNodeItem->SetBitmap(wxImage(exePath + "\\..\\data\\images\\menu\\addNode16.png"));
298  menu.Append(addNodeItem);
299  } else {
300  wxMenuItem* addNodeItem = new wxMenuItem(&menu, ID_LINE_REMOVE_NODE, _("Remove node"));
301  addNodeItem->SetBitmap(wxImage(exePath + "\\..\\data\\images\\menu\\removeNode16.png"));
302  menu.Append(addNodeItem);
303  }
304  wxMenuItem* deleteItem = new wxMenuItem(&menu, ID_DELETE, _("Delete"));
305  deleteItem->SetBitmap(wxImage(exePath + "\\..\\data\\images\\menu\\delete16.png"));
306  menu.Append(deleteItem);
307  return true;
308 }
309 
310 void Line::RemoveNode(wxPoint2DDouble point)
311 {
312  if(PickboxContains(point)) {
313  for(int i = 2; i < (int)m_pointList.size() - 2; i++) {
314  if(m_activePickboxID == i) {
315  m_pointList.erase(m_pointList.begin() + i);
316  break;
317  }
318  }
319  }
320  UpdateSwitchesPosition();
321  UpdatePowerFlowArrowsPosition();
322 }
323 
324 void Line::AddNode(wxPoint2DDouble point)
325 {
326  int segmentNumber = 0;
327  PointToLineDistance(point, &segmentNumber);
328  if(segmentNumber > 0 && segmentNumber < (int)m_pointList.size() - 2) {
329  m_pointList.insert(m_pointList.begin() + segmentNumber + 1, point);
330  }
331  UpdateSwitchesPosition();
332  UpdatePowerFlowArrowsPosition();
333 }
334 
335 void Line::CalculateBoundaries(wxPoint2DDouble& leftUp, wxPoint2DDouble& rightBottom) const
336 {
337  if(m_pointList.size() > 0) {
338  // Check points list boundaries.
339  leftUp = m_pointList[0];
340  rightBottom = m_pointList[0];
341  for(int i = 1; i < (int)m_pointList.size(); i++) {
342  if(m_pointList[i].m_x < leftUp.m_x) leftUp.m_x = m_pointList[i].m_x;
343  if(m_pointList[i].m_y < leftUp.m_y) leftUp.m_y = m_pointList[i].m_y;
344  if(m_pointList[i].m_x > rightBottom.m_x) rightBottom.m_x = m_pointList[i].m_x;
345  if(m_pointList[i].m_y > rightBottom.m_y) rightBottom.m_y = m_pointList[i].m_y;
346  }
347  }
348 }
349 
350 bool Line::ShowForm(wxWindow* parent, Element* element)
351 {
352  LineForm* lineForm = new LineForm(parent, this);
353  if(lineForm->ShowModal() == wxID_OK) {
354  lineForm->Destroy();
355  return true;
356  }
357  lineForm->Destroy();
358  return false;
359 }
360 
361 void Line::SetNominalVoltage(std::vector<double> nominalVoltage, std::vector<ElectricalUnit> nominalVoltageUnit)
362 {
363  if(nominalVoltage.size() > 0) {
364  m_electricalData.nominalVoltage = nominalVoltage[0];
365  m_electricalData.nominalVoltageUnit = nominalVoltageUnit[0];
366  }
367 }
368 
370 {
371  if(m_activeNodeID == 1 && parent == m_parentList[0]) return false;
372  if(m_activeNodeID == 2 && parent == m_parentList[1]) return false;
373 
374  if(parent && m_activeNodeID != 0) {
375  wxRect2DDouble nodeRect(0, 0, 0, 0);
376  if(m_activeNodeID == 1) {
377  nodeRect = wxRect2DDouble(m_pointList[0].m_x - 5.0 - m_borderSize, m_pointList[0].m_y - 5.0 - m_borderSize,
378  10 + 2.0 * m_borderSize, 10 + 2.0 * m_borderSize);
379  }
380  if(m_activeNodeID == 2) {
381  nodeRect = wxRect2DDouble(m_pointList[m_pointList.size() - 1].m_x - 5.0 - m_borderSize,
382  m_pointList[m_pointList.size() - 1].m_y - 5.0 - m_borderSize,
383  10 + 2.0 * m_borderSize, 10 + 2.0 * m_borderSize);
384  }
385 
386  if(parent->Intersects(nodeRect)) {
387  // If the line has no parents set the new rated voltage, otherwise check if it's not connecting
388  // two different voltages buses
389  Bus* parentBus = static_cast<Bus*>(parent);
390  if(!m_parentList[0] && !m_parentList[1]) {
391  m_electricalData.nominalVoltage = parentBus->GetElectricalData().nominalVoltage;
392  m_electricalData.nominalVoltageUnit = parentBus->GetElectricalData().nominalVoltageUnit;
393  } else if(m_electricalData.nominalVoltage != parentBus->GetElectricalData().nominalVoltage ||
394  m_electricalData.nominalVoltageUnit != parentBus->GetElectricalData().nominalVoltageUnit) {
395  wxMessageDialog msgDialog(NULL, _("Unable to connect two buses with different nominal voltages.\n"
396  "Use a transformer or edit the bus properties."),
397  _("Error"), wxOK | wxCENTRE | wxICON_ERROR);
398  msgDialog.ShowModal();
399  m_activeNodeID = 0;
400  return false;
401  }
402 
403  if(m_activeNodeID == 1) {
404  // Check if the user is trying to connect the same bus.
405  if(m_parentList[1] == parent) {
406  m_activeNodeID = 0;
407  return false;
408  }
409 
410  m_parentList[0] = parent;
411 
412  // Centralize the node on bus.
413  wxPoint2DDouble parentPt = parent->RotateAtPosition(
414  m_pointList[0], -parent->GetAngle()); // Rotate click to horizontal position.
415  parentPt.m_y = parent->GetPosition().m_y; // Centralize on bus.
416  parentPt = parent->RotateAtPosition(parentPt, parent->GetAngle());
417  m_pointList[0] = parentPt;
418 
419  UpdateSwitchesPosition();
420  UpdatePowerFlowArrowsPosition();
421  return true;
422  }
423  if(m_activeNodeID == 2) {
424  if(m_parentList[0] == parent) {
425  m_activeNodeID = 0;
426  return false;
427  }
428 
429  m_parentList[1] = parent;
430 
431  wxPoint2DDouble parentPt =
432  parent->RotateAtPosition(m_pointList[m_pointList.size() - 1], -parent->GetAngle());
433  parentPt.m_y = parent->GetPosition().m_y;
434  parentPt = parent->RotateAtPosition(parentPt, parent->GetAngle());
435  m_pointList[m_pointList.size() - 1] = parentPt;
436 
437  UpdateSwitchesPosition();
438  UpdatePowerFlowArrowsPosition();
439  return true;
440  }
441  } else {
442  if(m_activeNodeID == 1) m_parentList[0] = NULL;
443  if(m_activeNodeID == 2) m_parentList[1] = NULL;
444  }
445  }
446  return false;
447 }
448 
450 {
451  m_pfDirection = pfDirection;
452  UpdatePowerFlowArrowsPosition();
453 }
454 
455 void Line::UpdatePowerFlowArrowsPosition()
456 {
457  std::vector<wxPoint2DDouble> edges;
458  switch(m_pfDirection) {
459  case PF_NONE: {
460  m_powerFlowArrow.clear();
461  } break;
462  case PF_BUS1_TO_BUS2: {
463  for(int i = 1; i < (int)m_pointList.size() - 1; i++) {
464  edges.push_back(m_pointList[i]);
465  }
466  } break;
467  case PF_BUS2_TO_BUS1: {
468  for(int i = (int)m_pointList.size() - 2; i > 0; i--) {
469  edges.push_back(m_pointList[i]);
470  }
471  } break;
472  default:
473  break;
474  }
475  CalculatePowerFlowPts(edges);
476 }
477 
478 void Line::RotateNode(Element* parent, bool clockwise)
479 {
480  double rotAngle = m_rotationAngle;
481  if(!clockwise) rotAngle = -m_rotationAngle;
482 
483  if(parent == m_parentList[0]) {
484  m_pointList[0] = parent->RotateAtPosition(m_pointList[0], rotAngle);
485  } else if(parent == m_parentList[1]) {
486  m_pointList[m_pointList.size() - 1] = parent->RotateAtPosition(m_pointList[m_pointList.size() - 1], rotAngle);
487  }
488  UpdateSwitchesPosition();
489  UpdatePowerFlowArrowsPosition();
490 }
491 
492 void Line::SetPointList(std::vector<wxPoint2DDouble> pointList)
493 {
494  m_pointList = pointList;
495  UpdateSwitchesPosition();
496  UpdatePowerFlowArrowsPosition();
497 }
498 
500 {
501  Line* copy = new Line();
502  *copy = *this;
503  return copy;
504 }
505 
506 wxString Line::GetTipText() const
507 {
508  wxString tipText = m_electricalData.name;
509 
510  if(m_online) {
511  tipText += "\n";
512  int busNumber[2];
513  busNumber[0] = static_cast<Bus*>(m_parentList[0])->GetElectricalData().number + 1;
514  busNumber[1] = static_cast<Bus*>(m_parentList[1])->GetElectricalData().number + 1;
515 
516  tipText += _("\nP") + wxString::Format("(%d-%d) = ", busNumber[0], busNumber[1]) +
517  wxString::FromDouble(m_electricalData.powerFlow[0].real(), 5) + _(" p.u.");
518  tipText += _("\nQ") + wxString::Format("(%d-%d) = ", busNumber[0], busNumber[1]) +
519  wxString::FromDouble(m_electricalData.powerFlow[0].imag(), 5) + _(" p.u.");
520  tipText += _("\nP") + wxString::Format("(%d-%d) = ", busNumber[1], busNumber[0]) +
521  wxString::FromDouble(m_electricalData.powerFlow[1].real(), 5) + _(" p.u.");
522  tipText += _("\nQ") + wxString::Format("(%d-%d) = ", busNumber[1], busNumber[0]) +
523  wxString::FromDouble(m_electricalData.powerFlow[1].imag(), 5) + _(" p.u.");
524  }
525 
526  return tipText;
527 }
528 
529 LineElectricalData Line::GetPUElectricalData(double systemBasePower)
530 {
531  LineElectricalData data = m_electricalData;
532  double lineBasePower = GetValueFromUnit(data.nominalPower, data.nominalPowerUnit);
533  double baseVoltage = GetValueFromUnit(data.nominalVoltage, data.nominalVoltageUnit);
534  double systemBaseImpedance = (baseVoltage * baseVoltage) / systemBasePower;
535  double lineBaseImpedance = (baseVoltage * baseVoltage) / lineBasePower;
536 
537  // Resistance
538  double r = data.resistance;
539  if(data.resistanceUnit == UNIT_OHM_km) r *= data.lineSize;
540  if(data.resistanceUnit == UNIT_PU) {
541  if(data.useLinePower) data.resistance = (r * lineBaseImpedance) / systemBaseImpedance;
542  } else {
543  data.resistance = r / systemBaseImpedance;
544  }
545  data.resistanceUnit = UNIT_PU;
546 
547  // Inductive reactance
548  double x = data.indReactance;
549  if(data.indReactanceUnit == UNIT_OHM_km) x *= data.lineSize;
550  if(data.indReactanceUnit == UNIT_PU) {
551  if(data.useLinePower) data.indReactance = (x * lineBaseImpedance) / systemBaseImpedance;
552  } else {
553  data.indReactance = x / systemBaseImpedance;
554  }
555  data.indReactanceUnit = UNIT_PU;
556 
557  // Capacitive susceptance
558  double b = data.capSusceptance;
559  if(data.capSusceptanceUnit == UNIT_OHM_km) b *= data.lineSize;
560  if(data.capSusceptanceUnit == UNIT_PU) {
561  if(data.useLinePower) data.capSusceptance = (b * lineBaseImpedance) / systemBaseImpedance;
562  } else {
563  data.capSusceptance = b / systemBaseImpedance;
564  }
565  data.capSusceptanceUnit = UNIT_PU;
566 
567  // Fault
568 
569  // Zero seq. resistance
570  double r0 = data.zeroResistance;
571  if(data.useLinePower) data.zeroResistance = (r0 * lineBaseImpedance) / systemBaseImpedance;
572 
573  // Zero seq. ind. reactance
574  double x0 = data.zeroIndReactance;
575  if(data.useLinePower) data.zeroIndReactance = (x0 * lineBaseImpedance) / systemBaseImpedance;
576 
577  // Zero seq. cap. susceptance
578  double b0 = data.zeroCapSusceptance;
579  if(data.useLinePower) data.zeroCapSusceptance = (b0 * lineBaseImpedance) / systemBaseImpedance;
580 
581  if(!m_online) {
582  data.powerFlow[0] = std::complex<double>(0, 0);
583  data.powerFlow[1] = std::complex<double>(0, 0);
584  data.faultCurrent[0][0] = std::complex<double>(0, 0);
585  data.faultCurrent[0][1] = std::complex<double>(0, 0);
586  data.faultCurrent[0][2] = std::complex<double>(0, 0);
587  data.faultCurrent[1][0] = std::complex<double>(0, 0);
588  data.faultCurrent[1][1] = std::complex<double>(0, 0);
589  data.faultCurrent[1][2] = std::complex<double>(0, 0);
590  }
591 
592  return data;
593 }
double GetAngle() const
Get the element angle.
Definition: Element.h:212
+
1 /*
2  * Copyright (C) 2017 Thales Lima Oliveira <thales@ufu.br>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program. If not, see <https://www.gnu.org/licenses/>.
16  */
17 
18 #include "Line.h"
19 
20 Line::Line() : Branch()
21 {
22  for(int i = 0; i < 2; i++) {
23  for(int j = 0; j < 3; j++) {
24  m_electricalData.faultCurrent[i][j] = std::complex<double>(0.0, 0.0);
25  }
26  }
27 }
28 
29 Line::Line(wxString name) : Branch()
30 {
31  for(int i = 0; i < 2; i++) {
32  for(int j = 0; j < 3; j++) {
33  m_electricalData.faultCurrent[i][j] = std::complex<double>(0.0, 0.0);
34  }
35  }
36  m_electricalData.name = name;
37 }
38 Line::~Line() {}
39 bool Line::Contains(wxPoint2DDouble position) const
40 {
41  if(PointToLineDistance(position) < 5.0) {
42  return true;
43  }
44  return false;
45 }
46 
47 void Line::Draw(wxPoint2DDouble translation, double scale) const
48 {
49  OpenGLColour elementColour;
50  if(m_online) {
51  if(m_dynEvent)
52  elementColour = m_dynamicEventColour;
53  else
54  elementColour = m_onlineElementColour;
55 
56  } else
57  elementColour = m_offlineElementColour;
58 
59  std::vector<wxPoint2DDouble> pointList = m_pointList;
60  if(!m_inserted && pointList.size() > 0) {
61  wxPoint2DDouble secondPoint = m_position;
62  if(pointList.size() > 2) {
63  secondPoint = pointList[2];
64  }
65  pointList[1] = GetSwitchPoint(m_parentList[0], pointList[0], secondPoint);
66  pointList.push_back(m_position);
67  }
68 
69  // Line selected (Layer 1).
70  if(m_selected) {
71  glLineWidth(1.5 + m_borderSize * 2.0);
72  glColor4dv(m_selectionColour.GetRGBA());
73  DrawLine(pointList);
74 
75  // Draw nodes selection.
76  if(pointList.size() > 0) {
77  DrawCircle(pointList[0], 5.0 + m_borderSize / scale, 10, GL_POLYGON);
78  if(m_inserted) {
79  DrawCircle(pointList[pointList.size() - 1], 5.0 + m_borderSize / scale, 10, GL_POLYGON);
80  }
81  }
82  }
83 
84  // Draw line (Layer 2)
85  glLineWidth(1.5);
86  glColor4dv(elementColour.GetRGBA());
87  DrawLine(pointList);
88 
89  if(m_inserted) {
90  DrawSwitches();
91  DrawPowerFlowPts();
92  }
93 
94  // Draw nodes.
95  if(pointList.size() > 0) {
96  glColor4dv(elementColour.GetRGBA());
97  DrawCircle(pointList[0], 5.0, 10, GL_POLYGON);
98  if(m_inserted) {
99  DrawCircle(pointList[pointList.size() - 1], 5.0, 10, GL_POLYGON);
100  }
101  }
102 
103  // Draw pickboxes (Layer 3).
104  if(m_showPickbox) {
105  glPushMatrix();
106  glLoadIdentity();
107 
108  for(int i = 2; i < (int)m_pointList.size() - 2; i++) {
109  DrawPickbox(WorldToScreen(m_pointList[i], translation, scale));
110  }
111 
112  glPopMatrix();
113  }
114 }
115 
116 void Line::Move(wxPoint2DDouble position)
117 {
118  if(!m_parentList[0]) {
119  m_pointList[0] = m_movePts[0] + position - m_moveStartPt;
120  UpdateSwitchesPosition();
121  UpdatePowerFlowArrowsPosition();
122  }
123  if(!m_parentList[1]) {
124  m_pointList[m_pointList.size() - 1] = m_movePts[m_pointList.size() - 1] + position - m_moveStartPt;
125  UpdateSwitchesPosition();
126  UpdatePowerFlowArrowsPosition();
127  }
128 
129  if(!m_parentList[0] && !m_parentList[1]) {
130  for(int i = 2; i < (int)m_pointList.size() - 2; i++) {
131  m_pointList[i] = m_movePts[i] + position - m_moveStartPt;
132  }
133  }
134 }
135 
136 bool Line::AddParent(Element* parent, wxPoint2DDouble position)
137 {
138  if(parent) {
139  // First bus.
140  if(m_parentList.size() == 0) {
141  m_position = position;
142  m_parentList.push_back(parent);
143  parent->AddChild(this);
144  wxPoint2DDouble parentPt =
145  parent->RotateAtPosition(position, -parent->GetAngle()); // Rotate click to horizontal position.
146  parentPt.m_y = parent->GetPosition().m_y; // Centralize on bus.
147  parentPt = parent->RotateAtPosition(parentPt, parent->GetAngle()); // Rotate back.
148  m_pointList.push_back(parentPt); // First point
149  m_pointList.push_back(GetSwitchPoint(parent, parentPt, m_position));
150 
151  wxRect2DDouble genRect(0, 0, 0, 0);
152  m_switchRect.push_back(genRect);
153  UpdateSwitches();
154 
155  Bus* parentBus = static_cast<Bus*>(parent);
156  m_electricalData.nominalVoltage = parentBus->GetElectricalData().nominalVoltage;
157  m_electricalData.nominalVoltageUnit = parentBus->GetElectricalData().nominalVoltageUnit;
158 
159  return false;
160  }
161  // Second bus.
162  else if(parent != m_parentList[0]) {
163  Bus* parentBus = static_cast<Bus*>(parent);
164  if(m_electricalData.nominalVoltage != parentBus->GetElectricalData().nominalVoltage ||
165  m_electricalData.nominalVoltageUnit != parentBus->GetElectricalData().nominalVoltageUnit) {
166  wxMessageDialog msgDialog(NULL, _("Unable to connect two buses with different nominal voltages.\n"
167  "Use a transformer or edit the bus properties."),
168  _("Error"), wxOK | wxCENTRE | wxICON_ERROR);
169  msgDialog.ShowModal();
170  return false;
171  }
172 
173  m_parentList.push_back(parent);
174  parent->AddChild(this);
175  wxPoint2DDouble parentPt =
176  parent->RotateAtPosition(position, -parent->GetAngle()); // Rotate click to horizontal position.
177  parentPt.m_y = parent->GetPosition().m_y; // Centralize on bus.
178  parentPt = parent->RotateAtPosition(parentPt, parent->GetAngle()); // Rotate back.
179 
180  // Set first switch point.
181  wxPoint2DDouble secondPoint = parentPt;
182  if(m_pointList.size() > 2) {
183  secondPoint = m_pointList[2];
184  }
185  m_pointList[1] = GetSwitchPoint(m_parentList[0], m_pointList[0], secondPoint);
186 
187  // Set the second switch point.
188  m_pointList.push_back(GetSwitchPoint(parent, parentPt, m_pointList[m_pointList.size() - 1]));
189 
190  m_pointList.push_back(parentPt); // Last point.
191 
192  wxRect2DDouble genRect(0, 0, 0, 0);
193  m_switchRect.push_back(genRect);
194  UpdateSwitches();
195 
196  m_inserted = true;
197  UpdatePowerFlowArrowsPosition();
198  return true;
199  }
200  }
201  return false;
202 }
203 bool Line::Intersects(wxRect2DDouble rect) const
204 {
205  for(auto it = m_pointList.begin(); it != m_pointList.end(); ++it) {
206  if(rect.Contains(*it)) return true;
207  }
208  return false;
209 }
210 void Line::MovePickbox(wxPoint2DDouble position)
211 {
212  if(m_activePickboxID == ID_PB_NONE) return;
213 
214  for(int i = 2; i < (int)m_pointList.size() - 2; i++) {
215  if(m_activePickboxID == i) {
216  m_pointList[i] = m_movePts[i] + position - m_moveStartPt;
217  UpdateSwitchesPosition();
218  UpdatePowerFlowArrowsPosition();
219  }
220  }
221 }
222 bool Line::PickboxContains(wxPoint2DDouble position)
223 {
224  for(int i = 2; i < (int)m_pointList.size() - 2; i++) {
225  wxRect2DDouble rect(m_pointList[i].m_x - 5.0, m_pointList[i].m_y - 5.0, 10.0, 10.0);
226  if(rect.Contains(position)) {
227  m_activePickboxID = i;
228  return true;
229  }
230  }
231  return false;
232 }
233 
234 void Line::AddPoint(wxPoint2DDouble point)
235 {
236  if(m_parentList.size() != 0) {
237  m_pointList.push_back(point);
238  }
239 }
240 
241 void Line::StartMove(wxPoint2DDouble position)
242 {
243  m_moveStartPt = position;
244  m_movePts = m_pointList;
245 }
246 
247 void Line::MoveNode(Element* parent, wxPoint2DDouble position)
248 {
249  if(parent) {
250  // First bus.
251  if(parent == m_parentList[0]) {
252  m_pointList[0] = m_movePts[0] + position - m_moveStartPt;
253  }
254  // Second bus.
255  else if(parent == m_parentList[1]) {
256  m_pointList[m_pointList.size() - 1] = m_movePts[m_pointList.size() - 1] + position - m_moveStartPt;
257  }
258 
259  // If the line is selected, move all the points, except the switches and buses points.
260  if(m_selected) {
261  for(int i = 2; i < (int)m_pointList.size() - 1; i++) {
262  m_pointList[i] = m_movePts[i] + position - m_moveStartPt;
263  }
264  }
265  } else {
266  // If parent is setted to NULL for the firts time, remove the parent child
267  if(m_activeNodeID == 1) {
268  m_pointList[0] = m_movePts[0] + position - m_moveStartPt;
269  if(m_parentList[0]) {
270  m_parentList[0]->RemoveChild(this);
271  m_parentList[0] = NULL;
272  m_online = false;
273  }
274  } else if(m_activeNodeID == 2) {
275  m_pointList[m_pointList.size() - 1] = m_movePts[m_pointList.size() - 1] + position - m_moveStartPt;
276  if(m_parentList[1]) {
277  m_parentList[1]->RemoveChild(this);
278  m_parentList[1] = NULL;
279  m_online = false;
280  }
281  }
282  }
283 
284  // Recalculate switches positions
285  UpdateSwitchesPosition();
286  UpdatePowerFlowArrowsPosition();
287 }
288 
289 bool Line::GetContextMenu(wxMenu& menu)
290 {
291  wxFileName exeFileName(wxStandardPaths::Get().GetExecutablePath());
292  wxString exePath = exeFileName.GetPath();
293 
294  menu.Append(ID_EDIT_ELEMENT, _("Edit line"));
295  if(m_activePickboxID == ID_PB_NONE) {
296  wxMenuItem* addNodeItem = new wxMenuItem(&menu, ID_LINE_ADD_NODE, _("Insert node"));
297  addNodeItem->SetBitmap(wxImage(exePath + wxFileName::DirName("\\..\\data\\images\\menu\\addNode16.png", wxPATH_WIN).GetPath()));
298  menu.Append(addNodeItem);
299  } else {
300  wxMenuItem* addNodeItem = new wxMenuItem(&menu, ID_LINE_REMOVE_NODE, _("Remove node"));
301  addNodeItem->SetBitmap(wxImage(exePath + wxFileName::DirName("\\..\\data\\images\\menu\\removeNode16.png", wxPATH_WIN).GetPath()));
302  menu.Append(addNodeItem);
303  }
304  wxMenuItem* deleteItem = new wxMenuItem(&menu, ID_DELETE, _("Delete"));
305  deleteItem->SetBitmap(wxImage(exePath + wxFileName::DirName("\\..\\data\\images\\menu\\delete16.png", wxPATH_WIN).GetPath()));
306  menu.Append(deleteItem);
307  return true;
308 }
309 
310 void Line::RemoveNode(wxPoint2DDouble point)
311 {
312  if(PickboxContains(point)) {
313  for(int i = 2; i < (int)m_pointList.size() - 2; i++) {
314  if(m_activePickboxID == i) {
315  m_pointList.erase(m_pointList.begin() + i);
316  break;
317  }
318  }
319  }
320  UpdateSwitchesPosition();
321  UpdatePowerFlowArrowsPosition();
322 }
323 
324 void Line::AddNode(wxPoint2DDouble point)
325 {
326  int segmentNumber = 0;
327  PointToLineDistance(point, &segmentNumber);
328  if(segmentNumber > 0 && segmentNumber < (int)m_pointList.size() - 2) {
329  m_pointList.insert(m_pointList.begin() + segmentNumber + 1, point);
330  }
331  UpdateSwitchesPosition();
332  UpdatePowerFlowArrowsPosition();
333 }
334 
335 void Line::CalculateBoundaries(wxPoint2DDouble& leftUp, wxPoint2DDouble& rightBottom) const
336 {
337  if(m_pointList.size() > 0) {
338  // Check points list boundaries.
339  leftUp = m_pointList[0];
340  rightBottom = m_pointList[0];
341  for(int i = 1; i < (int)m_pointList.size(); i++) {
342  if(m_pointList[i].m_x < leftUp.m_x) leftUp.m_x = m_pointList[i].m_x;
343  if(m_pointList[i].m_y < leftUp.m_y) leftUp.m_y = m_pointList[i].m_y;
344  if(m_pointList[i].m_x > rightBottom.m_x) rightBottom.m_x = m_pointList[i].m_x;
345  if(m_pointList[i].m_y > rightBottom.m_y) rightBottom.m_y = m_pointList[i].m_y;
346  }
347  }
348 }
349 
350 bool Line::ShowForm(wxWindow* parent, Element* element)
351 {
352  LineForm* lineForm = new LineForm(parent, this);
353  if(lineForm->ShowModal() == wxID_OK) {
354  lineForm->Destroy();
355  return true;
356  }
357  lineForm->Destroy();
358  return false;
359 }
360 
361 void Line::SetNominalVoltage(std::vector<double> nominalVoltage, std::vector<ElectricalUnit> nominalVoltageUnit)
362 {
363  if(nominalVoltage.size() > 0) {
364  m_electricalData.nominalVoltage = nominalVoltage[0];
365  m_electricalData.nominalVoltageUnit = nominalVoltageUnit[0];
366  }
367 }
368 
370 {
371  if(m_activeNodeID == 1 && parent == m_parentList[0]) return false;
372  if(m_activeNodeID == 2 && parent == m_parentList[1]) return false;
373 
374  if(parent && m_activeNodeID != 0) {
375  wxRect2DDouble nodeRect(0, 0, 0, 0);
376  if(m_activeNodeID == 1) {
377  nodeRect = wxRect2DDouble(m_pointList[0].m_x - 5.0 - m_borderSize, m_pointList[0].m_y - 5.0 - m_borderSize,
378  10 + 2.0 * m_borderSize, 10 + 2.0 * m_borderSize);
379  }
380  if(m_activeNodeID == 2) {
381  nodeRect = wxRect2DDouble(m_pointList[m_pointList.size() - 1].m_x - 5.0 - m_borderSize,
382  m_pointList[m_pointList.size() - 1].m_y - 5.0 - m_borderSize,
383  10 + 2.0 * m_borderSize, 10 + 2.0 * m_borderSize);
384  }
385 
386  if(parent->Intersects(nodeRect)) {
387  // If the line has no parents set the new rated voltage, otherwise check if it's not connecting
388  // two different voltages buses
389  Bus* parentBus = static_cast<Bus*>(parent);
390  if(!m_parentList[0] && !m_parentList[1]) {
391  m_electricalData.nominalVoltage = parentBus->GetElectricalData().nominalVoltage;
392  m_electricalData.nominalVoltageUnit = parentBus->GetElectricalData().nominalVoltageUnit;
393  } else if(m_electricalData.nominalVoltage != parentBus->GetElectricalData().nominalVoltage ||
394  m_electricalData.nominalVoltageUnit != parentBus->GetElectricalData().nominalVoltageUnit) {
395  wxMessageDialog msgDialog(NULL, _("Unable to connect two buses with different nominal voltages.\n"
396  "Use a transformer or edit the bus properties."),
397  _("Error"), wxOK | wxCENTRE | wxICON_ERROR);
398  msgDialog.ShowModal();
399  m_activeNodeID = 0;
400  return false;
401  }
402 
403  if(m_activeNodeID == 1) {
404  // Check if the user is trying to connect the same bus.
405  if(m_parentList[1] == parent) {
406  m_activeNodeID = 0;
407  return false;
408  }
409 
410  m_parentList[0] = parent;
411 
412  // Centralize the node on bus.
413  wxPoint2DDouble parentPt = parent->RotateAtPosition(
414  m_pointList[0], -parent->GetAngle()); // Rotate click to horizontal position.
415  parentPt.m_y = parent->GetPosition().m_y; // Centralize on bus.
416  parentPt = parent->RotateAtPosition(parentPt, parent->GetAngle());
417  m_pointList[0] = parentPt;
418 
419  UpdateSwitchesPosition();
420  UpdatePowerFlowArrowsPosition();
421  return true;
422  }
423  if(m_activeNodeID == 2) {
424  if(m_parentList[0] == parent) {
425  m_activeNodeID = 0;
426  return false;
427  }
428 
429  m_parentList[1] = parent;
430 
431  wxPoint2DDouble parentPt =
432  parent->RotateAtPosition(m_pointList[m_pointList.size() - 1], -parent->GetAngle());
433  parentPt.m_y = parent->GetPosition().m_y;
434  parentPt = parent->RotateAtPosition(parentPt, parent->GetAngle());
435  m_pointList[m_pointList.size() - 1] = parentPt;
436 
437  UpdateSwitchesPosition();
438  UpdatePowerFlowArrowsPosition();
439  return true;
440  }
441  } else {
442  if(m_activeNodeID == 1) m_parentList[0] = NULL;
443  if(m_activeNodeID == 2) m_parentList[1] = NULL;
444  }
445  }
446  return false;
447 }
448 
450 {
451  m_pfDirection = pfDirection;
452  UpdatePowerFlowArrowsPosition();
453 }
454 
455 void Line::UpdatePowerFlowArrowsPosition()
456 {
457  std::vector<wxPoint2DDouble> edges;
458  switch(m_pfDirection) {
459  case PF_NONE: {
460  m_powerFlowArrow.clear();
461  } break;
462  case PF_BUS1_TO_BUS2: {
463  for(int i = 1; i < (int)m_pointList.size() - 1; i++) {
464  edges.push_back(m_pointList[i]);
465  }
466  } break;
467  case PF_BUS2_TO_BUS1: {
468  for(int i = (int)m_pointList.size() - 2; i > 0; i--) {
469  edges.push_back(m_pointList[i]);
470  }
471  } break;
472  default:
473  break;
474  }
475  CalculatePowerFlowPts(edges);
476 }
477 
478 void Line::RotateNode(Element* parent, bool clockwise)
479 {
480  double rotAngle = m_rotationAngle;
481  if(!clockwise) rotAngle = -m_rotationAngle;
482 
483  if(parent == m_parentList[0]) {
484  m_pointList[0] = parent->RotateAtPosition(m_pointList[0], rotAngle);
485  } else if(parent == m_parentList[1]) {
486  m_pointList[m_pointList.size() - 1] = parent->RotateAtPosition(m_pointList[m_pointList.size() - 1], rotAngle);
487  }
488  UpdateSwitchesPosition();
489  UpdatePowerFlowArrowsPosition();
490 }
491 
492 void Line::SetPointList(std::vector<wxPoint2DDouble> pointList)
493 {
494  m_pointList = pointList;
495  UpdateSwitchesPosition();
496  UpdatePowerFlowArrowsPosition();
497 }
498 
500 {
501  Line* copy = new Line();
502  *copy = *this;
503  return copy;
504 }
505 
506 wxString Line::GetTipText() const
507 {
508  wxString tipText = m_electricalData.name;
509 
510  if(m_online) {
511  tipText += "\n";
512  int busNumber[2];
513  busNumber[0] = static_cast<Bus*>(m_parentList[0])->GetElectricalData().number + 1;
514  busNumber[1] = static_cast<Bus*>(m_parentList[1])->GetElectricalData().number + 1;
515 
516  tipText += _("\nP") + wxString::Format("(%d-%d) = ", busNumber[0], busNumber[1]) +
517  wxString::FromDouble(m_electricalData.powerFlow[0].real(), 5) + _(" p.u.");
518  tipText += _("\nQ") + wxString::Format("(%d-%d) = ", busNumber[0], busNumber[1]) +
519  wxString::FromDouble(m_electricalData.powerFlow[0].imag(), 5) + _(" p.u.");
520  tipText += _("\nP") + wxString::Format("(%d-%d) = ", busNumber[1], busNumber[0]) +
521  wxString::FromDouble(m_electricalData.powerFlow[1].real(), 5) + _(" p.u.");
522  tipText += _("\nQ") + wxString::Format("(%d-%d) = ", busNumber[1], busNumber[0]) +
523  wxString::FromDouble(m_electricalData.powerFlow[1].imag(), 5) + _(" p.u.");
524  }
525 
526  return tipText;
527 }
528 
529 LineElectricalData Line::GetPUElectricalData(double systemBasePower)
530 {
531  LineElectricalData data = m_electricalData;
532  double lineBasePower = GetValueFromUnit(data.nominalPower, data.nominalPowerUnit);
533  double baseVoltage = GetValueFromUnit(data.nominalVoltage, data.nominalVoltageUnit);
534  double systemBaseImpedance = (baseVoltage * baseVoltage) / systemBasePower;
535  double lineBaseImpedance = (baseVoltage * baseVoltage) / lineBasePower;
536 
537  // Resistance
538  double r = data.resistance;
539  if(data.resistanceUnit == UNIT_OHM_km) r *= data.lineSize;
540  if(data.resistanceUnit == UNIT_PU) {
541  if(data.useLinePower) data.resistance = (r * lineBaseImpedance) / systemBaseImpedance;
542  } else {
543  data.resistance = r / systemBaseImpedance;
544  }
545  data.resistanceUnit = UNIT_PU;
546 
547  // Inductive reactance
548  double x = data.indReactance;
549  if(data.indReactanceUnit == UNIT_OHM_km) x *= data.lineSize;
550  if(data.indReactanceUnit == UNIT_PU) {
551  if(data.useLinePower) data.indReactance = (x * lineBaseImpedance) / systemBaseImpedance;
552  } else {
553  data.indReactance = x / systemBaseImpedance;
554  }
555  data.indReactanceUnit = UNIT_PU;
556 
557  // Capacitive susceptance
558  double b = data.capSusceptance;
559  if(data.capSusceptanceUnit == UNIT_OHM_km) b *= data.lineSize;
560  if(data.capSusceptanceUnit == UNIT_PU) {
561  if(data.useLinePower) data.capSusceptance = (b * lineBaseImpedance) / systemBaseImpedance;
562  } else {
563  data.capSusceptance = b / systemBaseImpedance;
564  }
565  data.capSusceptanceUnit = UNIT_PU;
566 
567  // Fault
568 
569  // Zero seq. resistance
570  double r0 = data.zeroResistance;
571  if(data.useLinePower) data.zeroResistance = (r0 * lineBaseImpedance) / systemBaseImpedance;
572 
573  // Zero seq. ind. reactance
574  double x0 = data.zeroIndReactance;
575  if(data.useLinePower) data.zeroIndReactance = (x0 * lineBaseImpedance) / systemBaseImpedance;
576 
577  // Zero seq. cap. susceptance
578  double b0 = data.zeroCapSusceptance;
579  if(data.useLinePower) data.zeroCapSusceptance = (b0 * lineBaseImpedance) / systemBaseImpedance;
580 
581  if(!m_online) {
582  data.powerFlow[0] = std::complex<double>(0, 0);
583  data.powerFlow[1] = std::complex<double>(0, 0);
584  data.faultCurrent[0][0] = std::complex<double>(0, 0);
585  data.faultCurrent[0][1] = std::complex<double>(0, 0);
586  data.faultCurrent[0][2] = std::complex<double>(0, 0);
587  data.faultCurrent[1][0] = std::complex<double>(0, 0);
588  data.faultCurrent[1][1] = std::complex<double>(0, 0);
589  data.faultCurrent[1][2] = std::complex<double>(0, 0);
590  }
591 
592  return data;
593 }
double GetAngle() const
Get the element angle.
Definition: Element.h:212
Base class of all elements of the program. This class is responsible for manage graphical and his dat...
Definition: Element.h:113
virtual void MovePickbox(wxPoint2DDouble position)
Move the pickbox.
Definition: Line.cpp:210
diff --git a/docs/doxygen/html/_load_8cpp_source.html b/docs/doxygen/html/_load_8cpp_source.html index 0dd68df..1f66473 100644 --- a/docs/doxygen/html/_load_8cpp_source.html +++ b/docs/doxygen/html/_load_8cpp_source.html @@ -88,22 +88,24 @@ $(document).ready(function(){initNavTree('_load_8cpp_source.html','');});
Load.cpp
-
1 /*
2  * Copyright (C) 2017 Thales Lima Oliveira <thales@ufu.br>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program. If not, see <https://www.gnu.org/licenses/>.
16  */
17 
18 #include "Load.h"
19 
20 Load::Load() : Shunt() {}
21 Load::Load(wxString name) : Shunt() { m_electricalData.name = name; }
22 Load::~Load() {}
23 bool Load::AddParent(Element* parent, wxPoint2DDouble position)
24 {
25  if(parent) {
26  m_parentList.push_back(parent);
27  parent->AddChild(this);
28  wxPoint2DDouble parentPt =
29  parent->RotateAtPosition(position, -parent->GetAngle()); // Rotate click to horizontal position.
30  parentPt.m_y = parent->GetPosition().m_y; // Centralize on bus.
31  parentPt = parent->RotateAtPosition(parentPt, parent->GetAngle()); // Rotate back.
32 
33  m_position = parentPt + wxPoint2DDouble(0.0, 100.0); // Shifts the position to the down of the bus.
34  m_width = m_height = 20.0;
35  m_rect = wxRect2DDouble(m_position.m_x - 10.0, m_position.m_y - 10.0, m_width, m_height);
36 
37  m_pointList.push_back(parentPt);
38  m_pointList.push_back(GetSwitchPoint(parent, parentPt, m_position));
39  m_pointList.push_back(m_position + wxPoint2DDouble(0.0, -20.0));
40  m_pointList.push_back(m_position + wxPoint2DDouble(0.0, -10.0));
41 
42  m_triangPts.push_back(wxPoint2DDouble(-m_width / 2.0, -m_height / 2.0));
43  m_triangPts.push_back(wxPoint2DDouble(m_width / 2.0, -m_height / 2.0));
44  m_triangPts.push_back(wxPoint2DDouble(0.0, m_height / 2.0));
45 
46  m_inserted = true;
47 
48  wxRect2DDouble genRect(0, 0, 0, 0);
49  m_switchRect.push_back(genRect); // Push a general rectangle.
50  UpdateSwitches();
51  m_pfDirection = PF_TO_ELEMENT;
52  UpdatePowerFlowArrowsPosition();
53 
54  return true;
55  }
56  return false;
57 }
58 
59 void Load::Draw(wxPoint2DDouble translation, double scale) const
60 {
61  OpenGLColour elementColour;
62  if(m_online) {
63  if(m_dynEvent)
64  elementColour = m_dynamicEventColour;
65  else
66  elementColour = m_onlineElementColour;
67  } else
68  elementColour = m_offlineElementColour;
69 
70  if(m_inserted) {
71  // Draw Selection (layer 1).
72  if(m_selected) {
73  glLineWidth(1.5 + m_borderSize * 2.0);
74  glColor4dv(m_selectionColour.GetRGBA());
75  std::vector<wxPoint2DDouble> selTriangPts;
76  selTriangPts.push_back(m_triangPts[0] + m_position +
77  wxPoint2DDouble(-m_borderSize / scale, -m_borderSize / scale));
78  selTriangPts.push_back(m_triangPts[1] + m_position +
79  wxPoint2DDouble(m_borderSize / scale, -m_borderSize / scale));
80  selTriangPts.push_back(m_triangPts[2] + m_position + wxPoint2DDouble(0.0, m_borderSize / scale));
81 
82  glPushMatrix();
83  glTranslated(m_position.m_x, m_position.m_y, 0.0);
84  glRotated(m_angle, 0.0, 0.0, 1.0);
85  glTranslated(-m_position.m_x, -m_position.m_y, 0.0);
86  DrawTriangle(selTriangPts);
87  glPopMatrix();
88 
89  DrawLine(m_pointList);
90 
91  // Draw node selection.
92  DrawCircle(m_pointList[0], 5.0 + m_borderSize / scale, 10, GL_POLYGON);
93  }
94 
95  // Draw Load (layer 2).
96  glLineWidth(1.5);
97 
98  // Draw node.
99  glColor4dv(elementColour.GetRGBA());
100  DrawCircle(m_pointList[0], 5.0, 10, GL_POLYGON);
101 
102  DrawLine(m_pointList);
103 
104  DrawSwitches();
105  DrawPowerFlowPts();
106 
107  std::vector<wxPoint2DDouble> triangPts;
108  for(int i = 0; i < 3; i++) {
109  triangPts.push_back(m_triangPts[i] + m_position);
110  }
111  glPushMatrix();
112  glTranslated(m_position.m_x, m_position.m_y, 0.0);
113  glRotated(m_angle, 0.0, 0.0, 1.0);
114  glTranslated(-m_position.m_x, -m_position.m_y, 0.0);
115  glColor4dv(elementColour.GetRGBA());
116  DrawTriangle(triangPts);
117  glPopMatrix();
118  }
119 }
120 
121 void Load::Rotate(bool clockwise)
122 {
123  double rotAngle = m_rotationAngle;
124  if(!clockwise) rotAngle = -m_rotationAngle;
125 
126  m_angle += rotAngle;
127  if(m_angle >= 360 || m_angle <= -360) m_angle = 0.0;
128  m_pointList[2] = RotateAtPosition(m_pointList[2], rotAngle);
129  m_pointList[3] = RotateAtPosition(m_pointList[3], rotAngle);
130  UpdateSwitchesPosition();
131  UpdatePowerFlowArrowsPosition();
132 }
133 
134 bool Load::GetContextMenu(wxMenu& menu)
135 {
136  menu.Append(ID_EDIT_ELEMENT, _("Edit Load"));
137  GeneralMenuItens(menu);
138  return true;
139 }
140 
141 bool Load::ShowForm(wxWindow* parent, Element* element)
142 {
143  LoadForm* loadForm = new LoadForm(parent, this);
144  if(loadForm->ShowModal() == wxID_OK) {
145  loadForm->Destroy();
146  return true;
147  }
148  loadForm->Destroy();
149  return false;
150 }
151 
152 LoadElectricalData Load::GetPUElectricalData(double systemPowerBase)
153 {
154  LoadElectricalData data = m_electricalData;
155  switch(data.activePowerUnit) {
156  case UNIT_W: {
157  data.activePower = data.activePower / systemPowerBase;
158  data.activePowerUnit = UNIT_PU;
159  } break;
160  case UNIT_kW: {
161  data.activePower = (data.activePower * 1e3) / systemPowerBase;
162  data.activePowerUnit = UNIT_PU;
163  } break;
164  case UNIT_MW: {
165  data.activePower = (data.activePower * 1e6) / systemPowerBase;
166  data.activePowerUnit = UNIT_PU;
167  } break;
168  default:
169  break;
170  }
171  switch(data.reactivePowerUnit) {
172  case UNIT_VAr: {
173  data.reactivePower = data.reactivePower / systemPowerBase;
174  data.reactivePowerUnit = UNIT_PU;
175  } break;
176  case UNIT_kVAr: {
177  data.reactivePower = (data.reactivePower * 1e3) / systemPowerBase;
178  data.reactivePowerUnit = UNIT_PU;
179  } break;
180  case UNIT_MVAr: {
181  data.reactivePower = (data.reactivePower * 1e6) / systemPowerBase;
182  data.reactivePowerUnit = UNIT_PU;
183  } break;
184  default:
185  break;
186  }
187 
188  return data;
189 }
190 
192 {
193  Load* copy = new Load();
194  *copy = *this;
195  return copy;
196 }
197 
198 wxString Load::GetTipText() const
199 {
200  wxString tipText = m_electricalData.name;
201 
202  // TODO: Avoid power calculation.
203  double activePower = m_electricalData.activePower;
204  double reactivePower = m_electricalData.reactivePower;
205  if(!m_online) {
206  activePower = 0.0;
207  reactivePower = 0.0;
208  }
209  if(m_online && m_electricalData.loadType == CONST_IMPEDANCE) {
210  std::complex<double> v = static_cast<Bus*>(m_parentList[0])->GetElectricalData().voltage;
211  reactivePower *= std::pow(std::abs(v), 2);
212  activePower *= std::pow(std::abs(v), 2);
213  }
214  tipText += "\n";
215  tipText += _("\nP = ") + wxString::FromDouble(activePower, 5);
216  switch(m_electricalData.activePowerUnit) {
217  case UNIT_PU: {
218  tipText += _(" p.u.");
219  } break;
220  case UNIT_W: {
221  tipText += _(" W");
222  } break;
223  case UNIT_kW: {
224  tipText += _(" kW");
225  } break;
226  case UNIT_MW: {
227  tipText += _(" MW");
228  } break;
229  default:
230  break;
231  }
232  tipText += _("\nQ = ") + wxString::FromDouble(reactivePower, 5);
233  switch(m_electricalData.reactivePowerUnit) {
234  case UNIT_PU: {
235  tipText += _(" p.u.");
236  } break;
237  case UNIT_VAr: {
238  tipText += _(" VAr");
239  } break;
240  case UNIT_kVAr: {
241  tipText += _(" kVAr");
242  } break;
243  case UNIT_MVAr: {
244  tipText += _(" MVAr");
245  } break;
246  default:
247  break;
248  }
249 
250  return tipText;
251 }
double GetAngle() const
Get the element angle.
Definition: Element.h:212
+
1 /*
2  * Copyright (C) 2017 Thales Lima Oliveira <thales@ufu.br>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program. If not, see <https://www.gnu.org/licenses/>.
16  */
17 
18 #include "Load.h"
19 
20 Load::Load() : Shunt() {}
21 Load::Load(wxString name) : Shunt() { m_electricalData.name = name; }
22 Load::~Load() {}
23 bool Load::AddParent(Element* parent, wxPoint2DDouble position)
24 {
25  if(parent) {
26  m_parentList.push_back(parent);
27  parent->AddChild(this);
28  wxPoint2DDouble parentPt =
29  parent->RotateAtPosition(position, -parent->GetAngle()); // Rotate click to horizontal position.
30  parentPt.m_y = parent->GetPosition().m_y; // Centralize on bus.
31  parentPt = parent->RotateAtPosition(parentPt, parent->GetAngle()); // Rotate back.
32 
33  m_position = parentPt + wxPoint2DDouble(0.0, 100.0); // Shifts the position to the down of the bus.
34  m_width = m_height = 20.0;
35  m_rect = wxRect2DDouble(m_position.m_x - 10.0, m_position.m_y - 10.0, m_width, m_height);
36 
37  m_pointList.push_back(parentPt);
38  m_pointList.push_back(GetSwitchPoint(parent, parentPt, m_position));
39  m_pointList.push_back(m_position + wxPoint2DDouble(0.0, -20.0));
40  m_pointList.push_back(m_position + wxPoint2DDouble(0.0, -10.0));
41 
42  m_triangPts.push_back(wxPoint2DDouble(-m_width / 2.0, -m_height / 2.0));
43  m_triangPts.push_back(wxPoint2DDouble(m_width / 2.0, -m_height / 2.0));
44  m_triangPts.push_back(wxPoint2DDouble(0.0, m_height / 2.0));
45 
46  m_inserted = true;
47 
48  wxRect2DDouble genRect(0, 0, 0, 0);
49  m_switchRect.push_back(genRect); // Push a general rectangle.
50  UpdateSwitches();
51  m_pfDirection = PF_TO_ELEMENT;
52  UpdatePowerFlowArrowsPosition();
53 
54  return true;
55  }
56  return false;
57 }
58 
59 void Load::Draw(wxPoint2DDouble translation, double scale) const
60 {
61  OpenGLColour elementColour;
62  if(m_online) {
63  if(m_dynEvent)
64  elementColour = m_dynamicEventColour;
65  else
66  elementColour = m_onlineElementColour;
67  } else
68  elementColour = m_offlineElementColour;
69 
70  if(m_inserted) {
71  // Draw Selection (layer 1).
72  if(m_selected) {
73  glLineWidth(1.5 + m_borderSize * 2.0);
74  glColor4dv(m_selectionColour.GetRGBA());
75  std::vector<wxPoint2DDouble> selTriangPts;
76  selTriangPts.push_back(m_triangPts[0] + m_position +
77  wxPoint2DDouble(-m_borderSize / scale, -m_borderSize / scale));
78  selTriangPts.push_back(m_triangPts[1] + m_position +
79  wxPoint2DDouble(m_borderSize / scale, -m_borderSize / scale));
80  selTriangPts.push_back(m_triangPts[2] + m_position + wxPoint2DDouble(0.0, m_borderSize / scale));
81 
82  glPushMatrix();
83  glTranslated(m_position.m_x, m_position.m_y, 0.0);
84  glRotated(m_angle, 0.0, 0.0, 1.0);
85  glTranslated(-m_position.m_x, -m_position.m_y, 0.0);
86  DrawTriangle(selTriangPts);
87  glPopMatrix();
88 
89  DrawLine(m_pointList);
90 
91  // Draw node selection.
92  DrawCircle(m_pointList[0], 5.0 + m_borderSize / scale, 10, GL_POLYGON);
93  }
94 
95  // Draw Load (layer 2).
96  glLineWidth(1.5);
97 
98  // Draw node.
99  glColor4dv(elementColour.GetRGBA());
100  DrawCircle(m_pointList[0], 5.0, 10, GL_POLYGON);
101 
102  DrawLine(m_pointList);
103 
104  DrawSwitches();
105  DrawPowerFlowPts();
106 
107  std::vector<wxPoint2DDouble> triangPts;
108  for(int i = 0; i < 3; i++) {
109  triangPts.push_back(m_triangPts[i] + m_position);
110  }
111  glPushMatrix();
112  glTranslated(m_position.m_x, m_position.m_y, 0.0);
113  glRotated(m_angle, 0.0, 0.0, 1.0);
114  glTranslated(-m_position.m_x, -m_position.m_y, 0.0);
115  glColor4dv(elementColour.GetRGBA());
116  DrawTriangle(triangPts);
117  glPopMatrix();
118  }
119 }
120 
121 void Load::Rotate(bool clockwise)
122 {
123  double rotAngle = m_rotationAngle;
124  if(!clockwise) rotAngle = -m_rotationAngle;
125 
126  m_angle += rotAngle;
127  if(m_angle >= 360 || m_angle <= -360) m_angle = 0.0;
128  m_pointList[2] = RotateAtPosition(m_pointList[2], rotAngle);
129  m_pointList[3] = RotateAtPosition(m_pointList[3], rotAngle);
130  UpdateSwitchesPosition();
131  UpdatePowerFlowArrowsPosition();
132 }
133 
134 bool Load::GetContextMenu(wxMenu& menu)
135 {
136  menu.Append(ID_EDIT_ELEMENT, _("Edit Load"));
137  GeneralMenuItens(menu);
138  return true;
139 }
140 
141 bool Load::ShowForm(wxWindow* parent, Element* element)
142 {
143  LoadForm* loadForm = new LoadForm(parent, this);
144  if(loadForm->ShowModal() == wxID_OK) {
145  loadForm->Destroy();
146  return true;
147  }
148  loadForm->Destroy();
149  return false;
150 }
151 
152 LoadElectricalData Load::GetPUElectricalData(double systemPowerBase)
153 {
154  LoadElectricalData data = m_electricalData;
155  switch(data.activePowerUnit) {
156  case UNIT_W: {
157  data.activePower = data.activePower / systemPowerBase;
158  data.activePowerUnit = UNIT_PU;
159  } break;
160  case UNIT_kW: {
161  data.activePower = (data.activePower * 1e3) / systemPowerBase;
162  data.activePowerUnit = UNIT_PU;
163  } break;
164  case UNIT_MW: {
165  data.activePower = (data.activePower * 1e6) / systemPowerBase;
166  data.activePowerUnit = UNIT_PU;
167  } break;
168  default:
169  break;
170  }
171  switch(data.reactivePowerUnit) {
172  case UNIT_VAr: {
173  data.reactivePower = data.reactivePower / systemPowerBase;
174  data.reactivePowerUnit = UNIT_PU;
175  } break;
176  case UNIT_kVAr: {
177  data.reactivePower = (data.reactivePower * 1e3) / systemPowerBase;
178  data.reactivePowerUnit = UNIT_PU;
179  } break;
180  case UNIT_MVAr: {
181  data.reactivePower = (data.reactivePower * 1e6) / systemPowerBase;
182  data.reactivePowerUnit = UNIT_PU;
183  } break;
184  default:
185  break;
186  }
187 
188  return data;
189 }
190 
192 {
193  Load* copy = new Load();
194  *copy = *this;
195  return copy;
196 }
197 
198 wxString Load::GetTipText() const
199 {
200  wxString tipText = m_electricalData.name;
201 
202  // TODO: Avoid power calculation.
203  double activePower = m_electricalData.activePower;
204  double reactivePower = m_electricalData.reactivePower;
205  if(!m_online) {
206  activePower = 0.0;
207  reactivePower = 0.0;
208  }
209  if(m_online && m_electricalData.loadType == CONST_IMPEDANCE) {
210  std::complex<double> v = static_cast<Bus*>(m_parentList[0])->GetElectricalData().voltage;
211  reactivePower *= std::pow(std::abs(v), 2);
212  activePower *= std::pow(std::abs(v), 2);
213  }
214  tipText += "\n";
215  tipText += _("\nP = ") + wxString::FromDouble(activePower, 5);
216  switch(m_electricalData.activePowerUnit) {
217  case UNIT_PU: {
218  tipText += _(" p.u.");
219  } break;
220  case UNIT_W: {
221  tipText += _(" W");
222  } break;
223  case UNIT_kW: {
224  tipText += _(" kW");
225  } break;
226  case UNIT_MW: {
227  tipText += _(" MW");
228  } break;
229  default:
230  break;
231  }
232  tipText += _("\nQ = ") + wxString::FromDouble(reactivePower, 5);
233  switch(m_electricalData.reactivePowerUnit) {
234  case UNIT_PU: {
235  tipText += _(" p.u.");
236  } break;
237  case UNIT_VAr: {
238  tipText += _(" VAr");
239  } break;
240  case UNIT_kVAr: {
241  tipText += _(" kVAr");
242  } break;
243  case UNIT_MVAr: {
244  tipText += _(" MVAr");
245  } break;
246  default:
247  break;
248  }
249 
250  return tipText;
251 }
252 
254 {
255  if(!m_electricalData.plotLoad) return false;
256  plotData.SetName(m_electricalData.name);
257  plotData.SetCurveType(ElementPlotData::CT_LOAD);
258 
259  std::vector<double> absVoltage, activePower, reactivePower, current;
260  for(unsigned int i = 0; i < m_electricalData.voltageVector.size(); ++i) {
261  absVoltage.push_back(std::abs(m_electricalData.voltageVector[i]));
262  activePower.push_back(std::real(m_electricalData.electricalPowerVector[i]));
263  reactivePower.push_back(std::imag(m_electricalData.electricalPowerVector[i]));
264  current.push_back(std::abs(std::complex<double>(activePower[i], -reactivePower[i]) /
265  std::conj(m_electricalData.voltageVector[i])));
266  }
267 
268  plotData.AddData(absVoltage, _("Voltage"));
269  plotData.AddData(activePower, _("Active power"));
270  plotData.AddData(reactivePower, _("Reactive power"));
271  plotData.AddData(current, _("Current"));
272 
273  return true;
274 }
double GetAngle() const
Get the element angle.
Definition: Element.h:212
Base class of all elements of the program. This class is responsible for manage graphical and his dat...
Definition: Element.h:113
virtual void Rotate(bool clockwise=true)
Rotate the element.
Definition: Load.cpp:121
virtual wxPoint2DDouble RotateAtPosition(wxPoint2DDouble pointToRotate, double angle, bool degrees=true) const
Rotate a point as element position being the origin.
Definition: Element.cpp:107
+
virtual bool GetPlotData(ElementPlotData &plotData)
Fill the plot data.
Definition: Load.cpp:253
Node for power elements. All others power elements are connected through this.
Definition: Bus.h:69
virtual Element * GetCopy()
Get a the element copy.
Definition: Load.cpp:191
+
virtual bool GetContextMenu(wxMenu &menu)
Get the element contex menu.
Definition: Load.cpp:134
virtual void AddChild(Element *child)
Add a child to the child list.
Definition: Element.cpp:353
-
Loas shunt power element.
Definition: Load.h:42
+
Loas shunt power element.
Definition: Load.h:73
virtual void Draw(wxPoint2DDouble translation, double scale) const
Draw the element.
Definition: Load.cpp:59
diff --git a/docs/doxygen/html/_load_8h_source.html b/docs/doxygen/html/_load_8h_source.html index 468482b..3bb0e1c 100644 --- a/docs/doxygen/html/_load_8h_source.html +++ b/docs/doxygen/html/_load_8h_source.html @@ -88,13 +88,14 @@ $(document).ready(function(){initNavTree('_load_8h_source.html','');});
Load.h
-Go to the documentation of this file.
1 /*
2  * Copyright (C) 2017 Thales Lima Oliveira <thales@ufu.br>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program. If not, see <https://www.gnu.org/licenses/>.
16  */
17 
18 #ifndef LOAD_H
19 #define LOAD_H
20 
21 #include "LoadForm.h"
22 #include "Shunt.h"
23 
24 enum LoadType { CONST_POWER = 0, CONST_IMPEDANCE };
25 
27  wxString name;
28  double activePower = 100.0;
29  ElectricalUnit activePowerUnit = UNIT_MW;
30  double reactivePower = 0.0;
31  ElectricalUnit reactivePowerUnit = UNIT_MVAr;
32  LoadType loadType = CONST_POWER;
33 };
34 
42 class Load : public Shunt
43 {
44  public:
45  Load();
46  Load(wxString name);
47  ~Load();
48 
49  virtual Element* GetCopy();
50  virtual bool AddParent(Element* parent, wxPoint2DDouble position);
51  virtual void Draw(wxPoint2DDouble translation, double scale) const;
52  virtual void Rotate(bool clockwise = true);
53  virtual bool GetContextMenu(wxMenu& menu);
54  virtual wxString GetTipText() const;
55  virtual bool ShowForm(wxWindow* parent, Element* element);
56  LoadElectricalData GetElectricalData() { return m_electricalData; }
57  LoadElectricalData GetPUElectricalData(double systemPowerBase);
58  void SetElectricalData(LoadElectricalData electricalData) { m_electricalData = electricalData; }
59  protected:
60  std::vector<wxPoint2DDouble> m_triangPts;
61  LoadElectricalData m_electricalData;
62 };
63 
64 #endif // LOAD_H
Base class of all elements of the program. This class is responsible for manage graphical and his dat...
Definition: Element.h:113
+Go to the documentation of this file.
1 /*
2  * Copyright (C) 2017 Thales Lima Oliveira <thales@ufu.br>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program. If not, see <https://www.gnu.org/licenses/>.
16  */
17 
18 #ifndef LOAD_H
19 #define LOAD_H
20 
21 #include "LoadForm.h"
22 #include "Shunt.h"
23 
24 enum LoadType { CONST_POWER = 0, CONST_IMPEDANCE };
25 
27  wxString name;
28  double activePower = 100.0;
29  ElectricalUnit activePowerUnit = UNIT_MW;
30  double reactivePower = 0.0;
31  ElectricalUnit reactivePowerUnit = UNIT_MVAr;
32  LoadType loadType = CONST_POWER;
33 
34  // Stability
35  bool plotLoad = false;
36  // ZIP load
37  bool useCompLoad = false;
38  // The power injected on the "i" bus flollow the quadratic equation:
39  // -p(i) = pz0 * (v(i) / v0) ^ 2 + pi0 * (v(i) / v0) + pp0
40  double v0 = 1.0; // Initial load voltage from load flow in p.u.
41  double pz0 = 1.0; // Initial active power modelled as constant impedance from load flow in p.u.
42  double pi0 = 0.0; // Initial active power modelled as constant current from load flow in p.u.
43  double pp0 = 0.0; // Initial active power modelled as constant power from load flow in p.u.
44  double qz0 = 1.0; // Initial reactive power modelled as constant impedance from load flow in p.u.
45  double qi0 = 0.0; // Initial reactive power modelled as constant current from load flow in p.u.
46  double qp0 = 0.0; // Initial reactive power modelled as constant power from load flow in p.u.
47  double constImpedanceActive = 100.0; // Constant impedance portion of active power (%).
48  double constCurrentActive = 0.0; // Constant current portion of active power (%).
49  double constPowerActive = 0.0; // Constant power portion of active power (%).
50  double constImpedanceReactive = 100.0; // Constant impedance portion of reactive power (%).
51  double constCurrentReactive = 0.0; // Constant current portion of reactive power (%).
52  double constPowerReactive = 0.0; // Constant power portion of reactive power (%).
53  std::complex<double> y0; // Steady-state equivalent admittance calculated from power flow.
54  // Undervoltage (in p.u.) which the constant current portion will be modelled as constant impedance.
55  double constCurrentUV = 0.7;
56  // Undervoltage (in p.u.) which the constant power portion will be modelled as constant impedance.
57  double constPowerUV = 0.7;
58 
59  // Load state variables
60  std::complex<double> voltage;
61  std::vector<std::complex<double> > voltageVector;
62  std::complex<double> electricalPower;
63  std::vector<std::complex<double> > electricalPowerVector;
64 };
65 
73 class Load : public Shunt
74 {
75  public:
76  Load();
77  Load(wxString name);
78  ~Load();
79 
80  virtual Element* GetCopy();
81  virtual bool AddParent(Element* parent, wxPoint2DDouble position);
82  virtual void Draw(wxPoint2DDouble translation, double scale) const;
83  virtual void Rotate(bool clockwise = true);
84  virtual bool GetContextMenu(wxMenu& menu);
85  virtual wxString GetTipText() const;
86  virtual bool ShowForm(wxWindow* parent, Element* element);
87  LoadElectricalData GetElectricalData() { return m_electricalData; }
88  LoadElectricalData GetPUElectricalData(double systemPowerBase);
89  void SetElectricalData(LoadElectricalData electricalData) { m_electricalData = electricalData; }
90  virtual bool GetPlotData(ElementPlotData& plotData);
91 
92  protected:
93  std::vector<wxPoint2DDouble> m_triangPts;
94  LoadElectricalData m_electricalData;
95 };
96 
97 #endif // LOAD_H
Base class of all elements of the program. This class is responsible for manage graphical and his dat...
Definition: Element.h:113
ElectricalUnit
Electrical units.
Definition: PowerElement.h:28
+ -
Loas shunt power element.
Definition: Load.h:42
+
Loas shunt power element.
Definition: Load.h:73
Abstract class for shunt power elements.
Definition: Shunt.h:31
diff --git a/docs/doxygen/html/_load_form_8cpp_source.html b/docs/doxygen/html/_load_form_8cpp_source.html index ff86191..cd1c453 100644 --- a/docs/doxygen/html/_load_form_8cpp_source.html +++ b/docs/doxygen/html/_load_form_8cpp_source.html @@ -88,7 +88,8 @@ $(document).ready(function(){initNavTree('_load_form_8cpp_source.html','');});
LoadForm.cpp
-
1 /*
2  * Copyright (C) 2017 Thales Lima Oliveira <thales@ufu.br>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program. If not, see <https://www.gnu.org/licenses/>.
16  */
17 
18 #include "LoadForm.h"
19 #include "SwitchingForm.h"
20 #include "Load.h"
21 
22 LoadForm::LoadForm(wxWindow* parent, Load* load) : LoadFormBase(parent)
23 {
24  SetSize(GetBestSize());
25  LoadElectricalData data = load->GetElectricalData();
26 
27  m_textCtrlName->SetValue(data.name);
28 
29  m_textCtrlActivePower->SetValue(Load::StringFromDouble(data.activePower));
30  switch(data.activePowerUnit) {
31  case UNIT_PU: {
32  m_choiceActivePower->SetSelection(0);
33  } break;
34  case UNIT_W: {
35  m_choiceActivePower->SetSelection(1);
36  } break;
37  case UNIT_kW: {
38  m_choiceActivePower->SetSelection(2);
39  } break;
40  case UNIT_MW: {
41  m_choiceActivePower->SetSelection(3);
42  } break;
43  default:
44  break;
45  }
46 
47  m_textCtrlReactivePower->SetValue(Load::StringFromDouble(data.reactivePower));
48  switch(data.reactivePowerUnit) {
49  case UNIT_PU: {
50  m_choiceReactivePower->SetSelection(0);
51  } break;
52  case UNIT_VAr: {
53  m_choiceReactivePower->SetSelection(1);
54  } break;
55  case UNIT_kVAr: {
56  m_choiceReactivePower->SetSelection(2);
57  } break;
58  case UNIT_MVAr: {
59  m_choiceReactivePower->SetSelection(3);
60  } break;
61  default:
62  break;
63  }
64 
65  switch(data.loadType) {
66  case CONST_POWER: {
67  m_choiceType->SetSelection(0);
68  } break;
69  case CONST_IMPEDANCE: {
70  m_choiceType->SetSelection(1);
71  } break;
72  }
73 
74  m_parent = parent;
75  m_load = load;
76 }
77 
78 LoadForm::~LoadForm() {}
79 void LoadForm::OnOnButtonClick(wxCommandEvent& event)
80 {
81  if(ValidateData()) EndModal(wxID_OK);
82 }
83 
84 void LoadForm::OnStabilityButtonClick(wxCommandEvent& event)
85 {
86  if(ValidateData()) {
87  SwitchingForm swForm(m_parent, m_load);
88  swForm.SetTitle(_("Load: Switching"));
89  swForm.ShowModal();
90  EndModal(wxID_OK);
91  }
92 }
93 
94 bool LoadForm::ValidateData()
95 {
96  LoadElectricalData data;
97 
98  data.name = m_textCtrlName->GetValue();
99 
100  if(!m_load->DoubleFromString(m_parent, m_textCtrlActivePower->GetValue(), data.activePower,
101  _("Value entered incorrectly in the field \"Active power\".")))
102  return false;
103  switch(m_choiceActivePower->GetSelection()) {
104  case 0: {
105  data.activePowerUnit = UNIT_PU;
106  } break;
107  case 1: {
108  data.activePowerUnit = UNIT_W;
109  } break;
110  case 2: {
111  data.activePowerUnit = UNIT_kW;
112  } break;
113  case 3: {
114  data.activePowerUnit = UNIT_MW;
115  } break;
116  }
117 
118  if(!m_load->DoubleFromString(m_parent, m_textCtrlReactivePower->GetValue(), data.reactivePower,
119  _("Value entered incorrectly in the field \"Reactive power\".")))
120  return false;
121  switch(m_choiceReactivePower->GetSelection()) {
122  case 0: {
123  data.reactivePowerUnit = UNIT_PU;
124  } break;
125  case 1: {
126  data.reactivePowerUnit = UNIT_VAr;
127  } break;
128  case 2: {
129  data.reactivePowerUnit = UNIT_kVAr;
130  } break;
131  case 3: {
132  data.reactivePowerUnit = UNIT_MVAr;
133  } break;
134  }
135 
136  switch(m_choiceType->GetSelection()) {
137  case 0: {
138  data.loadType = CONST_POWER;
139  } break;
140  case 1: {
141  data.loadType = CONST_IMPEDANCE;
142  } break;
143  }
144 
145  m_load->SetElectricalData(data);
146  return true;
147 }
Form to edit the switching data of power elements for electromechanical transient studies...
Definition: SwitchingForm.h:32
+
1 /*
2  * Copyright (C) 2017 Thales Lima Oliveira <thales@ufu.br>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program. If not, see <https://www.gnu.org/licenses/>.
16  */
17 
18 #include "LoadForm.h"
19 #include "SwitchingForm.h"
20 #include "Load.h"
21 
22 LoadForm::LoadForm(wxWindow* parent, Load* load) : LoadFormBase(parent)
23 {
24  SetSize(GetBestSize());
25  LoadElectricalData data = load->GetElectricalData();
26 
27  m_textCtrlName->SetValue(data.name);
28 
29  m_textCtrlActivePower->SetValue(Load::StringFromDouble(data.activePower));
30  switch(data.activePowerUnit) {
31  case UNIT_PU: {
32  m_choiceActivePower->SetSelection(0);
33  } break;
34  case UNIT_W: {
35  m_choiceActivePower->SetSelection(1);
36  } break;
37  case UNIT_kW: {
38  m_choiceActivePower->SetSelection(2);
39  } break;
40  case UNIT_MW: {
41  m_choiceActivePower->SetSelection(3);
42  } break;
43  default:
44  break;
45  }
46 
47  m_textCtrlReactivePower->SetValue(Load::StringFromDouble(data.reactivePower));
48  switch(data.reactivePowerUnit) {
49  case UNIT_PU: {
50  m_choiceReactivePower->SetSelection(0);
51  } break;
52  case UNIT_VAr: {
53  m_choiceReactivePower->SetSelection(1);
54  } break;
55  case UNIT_kVAr: {
56  m_choiceReactivePower->SetSelection(2);
57  } break;
58  case UNIT_MVAr: {
59  m_choiceReactivePower->SetSelection(3);
60  } break;
61  default:
62  break;
63  }
64 
65  switch(data.loadType) {
66  case CONST_POWER: {
67  m_choiceType->SetSelection(0);
68  } break;
69  case CONST_IMPEDANCE: {
70  m_choiceType->SetSelection(1);
71  } break;
72  }
73 
74  m_checkBoxPlotData->SetValue(data.plotLoad);
75 
76  m_checkBoxUseCompLoad->SetValue(data.useCompLoad);
77 
78  m_textCtrlActivePowerImp->SetValue(Element::StringFromDouble(data.constImpedanceActive));
79  m_textCtrlActivePowerCur->SetValue(Element::StringFromDouble(data.constCurrentActive));
80  m_textCtrlActivePowerPow->SetValue(Element::StringFromDouble(data.constPowerActive));
81  m_textCtrlReactivePowerImp->SetValue(Element::StringFromDouble(data.constImpedanceReactive));
82  m_textCtrlReactivePowerCur->SetValue(Element::StringFromDouble(data.constCurrentReactive));
83  m_textCtrlReactivePowerPow->SetValue(Element::StringFromDouble(data.constPowerReactive));
84 
85  m_parent = parent;
86  m_load = load;
87 
88  UpdateZIPLoadFieldStatus();
89 }
90 
91 LoadForm::~LoadForm() {}
92 void LoadForm::OnOnButtonClick(wxCommandEvent& event)
93 {
94  if(ValidateData()) EndModal(wxID_OK);
95 }
96 
97 void LoadForm::OnStabilityButtonClick(wxCommandEvent& event)
98 {
99  if(ValidateData()) {
100  SwitchingForm swForm(m_parent, m_load);
101  swForm.SetTitle(_("Load: Switching"));
102  swForm.ShowModal();
103  EndModal(wxID_OK);
104  }
105 }
106 
107 bool LoadForm::ValidateData()
108 {
109  LoadElectricalData data;
110 
111  data.name = m_textCtrlName->GetValue();
112 
113  if(!m_load->DoubleFromString(m_parent, m_textCtrlActivePower->GetValue(), data.activePower,
114  _("Value entered incorrectly in the field \"Active power\".")))
115  return false;
116  switch(m_choiceActivePower->GetSelection()) {
117  case 0: {
118  data.activePowerUnit = UNIT_PU;
119  } break;
120  case 1: {
121  data.activePowerUnit = UNIT_W;
122  } break;
123  case 2: {
124  data.activePowerUnit = UNIT_kW;
125  } break;
126  case 3: {
127  data.activePowerUnit = UNIT_MW;
128  } break;
129  }
130 
131  if(!m_load->DoubleFromString(m_parent, m_textCtrlReactivePower->GetValue(), data.reactivePower,
132  _("Value entered incorrectly in the field \"Reactive power\".")))
133  return false;
134  switch(m_choiceReactivePower->GetSelection()) {
135  case 0: {
136  data.reactivePowerUnit = UNIT_PU;
137  } break;
138  case 1: {
139  data.reactivePowerUnit = UNIT_VAr;
140  } break;
141  case 2: {
142  data.reactivePowerUnit = UNIT_kVAr;
143  } break;
144  case 3: {
145  data.reactivePowerUnit = UNIT_MVAr;
146  } break;
147  }
148 
149  switch(m_choiceType->GetSelection()) {
150  case 0: {
151  data.loadType = CONST_POWER;
152  } break;
153  case 1: {
154  data.loadType = CONST_IMPEDANCE;
155  } break;
156  }
157 
158  data.plotLoad = m_checkBoxPlotData->GetValue();
159 
160  data.useCompLoad = m_checkBoxUseCompLoad->GetValue();
161 
163  this, m_textCtrlActivePowerImp->GetValue(), data.constImpedanceActive,
164  _("Value entered incorrectly in the field \"Constant impedance portion of active power\".")))
165  return false;
167  this, m_textCtrlActivePowerCur->GetValue(), data.constCurrentActive,
168  _("Value entered incorrectly in the field \"Constant current portion of active power\".")))
169  return false;
171  this, m_textCtrlActivePowerPow->GetValue(), data.constPowerActive,
172  _("Value entered incorrectly in the field \"Constant power portion of active power\".")))
173  return false;
175  this, m_textCtrlReactivePowerImp->GetValue(), data.constImpedanceReactive,
176  _("Value entered incorrectly in the field \"Constant impedance portion of reactive power\".")))
177  return false;
179  this, m_textCtrlReactivePowerCur->GetValue(), data.constCurrentReactive,
180  _("Value entered incorrectly in the field \"Constant current portion of reactive power\".")))
181  return false;
183  this, m_textCtrlReactivePowerPow->GetValue(), data.constPowerReactive,
184  _("Value entered incorrectly in the field \"Constant power portion of reactive power\".")))
185  return false;
186 
187  double sum = data.constImpedanceActive + data.constCurrentActive + data.constPowerActive;
188  if(sum > 100.01 || sum < 99.99) {
189  wxMessageDialog msgDialog(this, _("The sum of active power load composition must be 100%."), _("Error"),
190  wxOK | wxCENTRE | wxICON_ERROR);
191  msgDialog.ShowModal();
192  return false;
193  }
194  sum = data.constImpedanceReactive + data.constCurrentReactive + data.constPowerReactive;
195  if(sum > 100.01 || sum < 99.99) {
196  wxMessageDialog msgDialog(this, _("The sum of reactive power load composition must be 100%."), _("Error"),
197  wxOK | wxCENTRE | wxICON_ERROR);
198  msgDialog.ShowModal();
199  return false;
200  }
201 
202  m_load->SetElectricalData(data);
203  return true;
204 }
205 
206 void LoadForm::UpdateZIPLoadFieldStatus()
207 {
208  m_textCtrlActivePowerImp->Enable(m_checkBoxUseCompLoad->GetValue());
209  m_textCtrlActivePowerCur->Enable(m_checkBoxUseCompLoad->GetValue());
210  m_textCtrlActivePowerPow->Enable(m_checkBoxUseCompLoad->GetValue());
211  m_textCtrlReactivePowerImp->Enable(m_checkBoxUseCompLoad->GetValue());
212  m_textCtrlReactivePowerCur->Enable(m_checkBoxUseCompLoad->GetValue());
213  m_textCtrlReactivePowerPow->Enable(m_checkBoxUseCompLoad->GetValue());
214 }
static bool DoubleFromString(wxWindow *parent, wxString strValue, double &value, wxString errorMsg)
Get a double value from a string. Show a error message if the conversion fail.
Definition: Element.cpp:292
+
Form to edit the switching data of power elements for electromechanical transient studies...
Definition: SwitchingForm.h:32
@@ -96,7 +97,7 @@ $(document).ready(function(){initNavTree('_load_form_8cpp_source.html','');}); -
Loas shunt power element.
Definition: Load.h:42
+
Loas shunt power element.
Definition: Load.h:73
diff --git a/docs/doxygen/html/_load_form_8h_source.html b/docs/doxygen/html/_load_form_8h_source.html index 47a70cd..6b0a831 100644 --- a/docs/doxygen/html/_load_form_8h_source.html +++ b/docs/doxygen/html/_load_form_8h_source.html @@ -88,8 +88,8 @@ $(document).ready(function(){initNavTree('_load_form_8h_source.html','');});
LoadForm.h
-Go to the documentation of this file.
1 /*
2  * Copyright (C) 2017 Thales Lima Oliveira <thales@ufu.br>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program. If not, see <https://www.gnu.org/licenses/>.
16  */
17 
18 #ifndef LOADFORM_H
19 #define LOADFORM_H
20 #include "ElementForm.h"
21 
22 class Load;
23 class SwitchingForm;
24 
32 class LoadForm : public LoadFormBase
33 {
34  public:
35  LoadForm(wxWindow* parent, Load* load);
36  virtual ~LoadForm();
37 
38  virtual bool ValidateData();
39 
40  protected:
41  virtual void OnCancelButtonClick(wxCommandEvent& event) { EndModal(wxID_CANCEL); };
42  virtual void OnOnButtonClick(wxCommandEvent& event);
43  virtual void OnStabilityButtonClick(wxCommandEvent& event);
44 
45  wxWindow* m_parent = NULL;
46  Load* m_load = NULL;
47 };
48 #endif // LOADFORM_H
Form to edit the switching data of power elements for electromechanical transient studies...
Definition: SwitchingForm.h:32
-
Loas shunt power element.
Definition: Load.h:42
+Go to the documentation of this file.
1 /*
2  * Copyright (C) 2017 Thales Lima Oliveira <thales@ufu.br>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program. If not, see <https://www.gnu.org/licenses/>.
16  */
17 
18 #ifndef LOADFORM_H
19 #define LOADFORM_H
20 #include "ElementForm.h"
21 
22 class Load;
23 class SwitchingForm;
24 
32 class LoadForm : public LoadFormBase
33 {
34  public:
35  LoadForm(wxWindow* parent, Load* load);
36  virtual ~LoadForm();
37 
38  virtual bool ValidateData();
39 
40  protected:
41  virtual void OnCheckBoxCompLoadClick(wxCommandEvent& event) { UpdateZIPLoadFieldStatus(); }
42  virtual void OnCancelButtonClick(wxCommandEvent& event) { EndModal(wxID_CANCEL); };
43  virtual void OnOnButtonClick(wxCommandEvent& event);
44  virtual void OnStabilityButtonClick(wxCommandEvent& event);
45  virtual void UpdateZIPLoadFieldStatus();
46 
47  wxWindow* m_parent = NULL;
48  Load* m_load = NULL;
49 };
50 #endif // LOADFORM_H
Form to edit the switching data of power elements for electromechanical transient studies...
Definition: SwitchingForm.h:32
+
Loas shunt power element.
Definition: Load.h:73
Form to edit the load power data.
Definition: LoadForm.h:32
diff --git a/docs/doxygen/html/_machines_8h_source.html b/docs/doxygen/html/_machines_8h_source.html index 1310bfd..d2264c3 100644 --- a/docs/doxygen/html/_machines_8h_source.html +++ b/docs/doxygen/html/_machines_8h_source.html @@ -99,7 +99,7 @@ $(document).ready(function(){initNavTree('_machines_8h_source.html','');});
virtual bool AddParent(Element *parent, wxPoint2DDouble position)
Add a parent to the element. This method must be used on power elements that connect to a bus...
Definition: Machines.cpp:25
virtual bool SetNodeParent(Element *parent)
Set a perent to the node. If all conditions are met, a new parent are added to the element and the po...
Definition: Machines.cpp:189
virtual void UpdateNodes()
Update the nodes according to the parents. If a parent is removed, use this method.
Definition: Machines.cpp:216
-
Class that can contain all control elements. Can identify (using RTTI) the elements from a generic li...
+
Class that can contain all control elements. Can identify (using RTTI) the elements from a generic li...
virtual void Rotate(bool clockwise=true)
Rotate the element.
Definition: Machines.cpp:232
virtual void Draw(wxPoint2DDouble translation, double scale) const
Draw the element.
Definition: Machines.cpp:54
diff --git a/docs/doxygen/html/_main_frame_8cpp_source.html b/docs/doxygen/html/_main_frame_8cpp_source.html index 849dbb5..7afa9cb 100644 --- a/docs/doxygen/html/_main_frame_8cpp_source.html +++ b/docs/doxygen/html/_main_frame_8cpp_source.html @@ -88,13 +88,13 @@ $(document).ready(function(){initNavTree('_main_frame_8cpp_source.html','');});
MainFrame.cpp
-
1 /*
2  * Copyright (C) 2017 Thales Lima Oliveira <thales@ufu.br>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program. If not, see <https://www.gnu.org/licenses/>.
16  */
17 
18 #include "MainFrame.h"
19 #include "ArtMetro.h"
20 #include "Workspace.h"
21 #include "Bus.h"
22 #include "Line.h"
23 #include "Transformer.h"
24 #include "SyncGenerator.h"
25 #include "IndMotor.h"
26 #include "SyncMotor.h"
27 #include "Load.h"
28 #include "Inductor.h"
29 #include "Capacitor.h"
30 #include "FileHanding.h"
31 #include "GeneralPropertiesForm.h"
33 #include "PropertiesData.h"
34 #include "ChartView.h"
35 #include "DataReport.h"
36 #include "AboutForm.h"
37 
39 MainFrame::MainFrame(wxWindow* parent, wxLocale* locale, PropertiesData* initProperties, wxString openPath)
40  : MainFrameBase(parent)
41 {
42  m_locale = locale;
43  m_generalProperties = initProperties;
44 
45  Init();
46 
47  if(openPath != "") {
48  EnableCurrentProjectRibbon();
49  Workspace* newWorkspace = new Workspace(this, _("Open project"), this->GetStatusBar());
50 
51  FileHanding fileHandling(newWorkspace);
52  if(fileHandling.OpenProject(openPath)) {
53  newWorkspace->SetSavedPath(openPath);
54 
55  m_workspaceList.push_back(newWorkspace);
56 
57  m_ribbonButtonBarContinuous->ToggleButton(ID_RIBBON_DISABLESOL, true);
58  m_ribbonButtonBarContinuous->ToggleButton(ID_RIBBON_ENABLESOL, false);
59 
60  m_auiNotebook->AddPage(newWorkspace, newWorkspace->GetName(), true);
61  m_auiNotebook->Layout();
62  newWorkspace->Redraw();
63  newWorkspace->SetJustOpened(true);
64  m_projectNumber++;
65  }
66  }
67 }
68 
70 {
71  // if(m_artMetro) delete m_artMetro;
72  if(m_addElementsMenu) {
73  m_addElementsMenu->Disconnect(wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MainFrame::OnAddElementsClick),
74  NULL, this);
75  delete m_addElementsMenu;
76  }
77  if(m_locale) delete m_locale;
78  if(m_generalProperties) delete m_generalProperties;
79 }
80 
81 void MainFrame::Init()
82 {
83  this->SetSize(800, 600);
84 
85  CreateAddElementsMenu();
86 
87  EnableCurrentProjectRibbon(false);
88 
89  m_artMetro = new wxRibbonMetroArtProvider();
90  m_ribbonBar->SetArtProvider(m_artMetro);
91  m_ribbonBar->Realize();
92 
93  this->Layout();
94 }
95 
96 void MainFrame::EnableCurrentProjectRibbon(bool enable)
97 {
98  m_ribbonButtonBarCircuit->EnableButton(ID_RIBBON_ADDELEMENT, enable);
99  m_ribbonButtonBarReports->EnableButton(ID_RIBBON_CHARTS, enable);
100  m_ribbonButtonBarCProject->EnableButton(ID_RIBBON_CLOSE, enable);
101  m_ribbonButtonBarClipboard->EnableButton(ID_RIBBON_COPY, enable);
102  m_ribbonButtonBarReports->EnableButton(ID_RIBBON_DATAREPORT, enable);
103  m_ribbonButtonBarCircuit->EnableButton(ID_RIBBON_DELETE, enable);
104  m_ribbonButtonBarContinuous->EnableButton(ID_RIBBON_DISABLESOL, enable);
105  m_ribbonButtonBarCircuit->EnableButton(ID_RIBBON_DRAG, enable);
106  m_ribbonButtonBarContinuous->EnableButton(ID_RIBBON_ENABLESOL, enable);
107  m_ribbonButtonBarSimulations->EnableButton(ID_RIBBON_FAULT, enable);
108  m_ribbonButtonBarCircuit->EnableButton(ID_RIBBON_FIT, enable);
109  m_ribbonButtonBarCircuit->EnableButton(ID_RIBBON_MOVE, enable);
110  m_ribbonButtonBarClipboard->EnableButton(ID_RIBBON_PASTE, enable);
111  m_ribbonButtonBarSimulations->EnableButton(ID_RIBBON_POWERFLOW, enable);
112  m_ribbonButtonBarClipboard->EnableButton(ID_RIBBON_REDO, enable);
113  m_ribbonButtonBarContinuous->EnableButton(ID_RIBBON_RESETVOLT, enable);
114  m_ribbonButtonBarSimulations->EnableButton(ID_RIBBON_RUNSTAB, enable);
115  m_ribbonButtonBarCProject->EnableButton(ID_RIBBON_SAVE, enable);
116  m_ribbonButtonBarCProject->EnableButton(ID_RIBBON_SAVEAS, enable);
117  m_ribbonButtonBarSimulations->EnableButton(ID_RIBBON_SCPOWER, enable);
118  m_ribbonButtonBarCircuit->EnableButton(ID_RIBBON_PROJSETTINGS, enable);
119  m_ribbonButtonBarReports->EnableButton(ID_RIBBON_SNAPSHOT, enable);
120  m_ribbonButtonBarSimulations->EnableButton(ID_RIBBON_SIMULSETTINGS, enable);
121  m_ribbonButtonBarClipboard->EnableButton(ID_RIBBON_UNDO, enable);
122  m_ribbonButtonBarCircuit->EnableButton(ID_RIBBON_ROTATEC, enable);
123  m_ribbonButtonBarCircuit->EnableButton(ID_RIBBON_ROTATECC, enable);
124 }
125 
126 void MainFrame::CreateAddElementsMenu()
127 {
128  m_addElementsMenu = new wxMenu();
129 
130  wxMenuItem* busElement =
131  new wxMenuItem(m_addElementsMenu, ID_ADDMENU_BUS, _("&Bus\tB"), _("Adds a bus at the circuit"));
132  // busElement->SetBitmap(wxArtProvider::GetBitmap(wxART_WARNING));
133  wxMenuItem* lineElement =
134  new wxMenuItem(m_addElementsMenu, ID_ADDMENU_LINE, _("&Line\tL"), _("Adds a power line at the circuit"));
135  wxMenuItem* transformerElement = new wxMenuItem(m_addElementsMenu, ID_ADDMENU_TRANSFORMER, _("&Transformer\tT"),
136  _("Adds a transformer at the circuit"));
137  wxMenuItem* generatorElement = new wxMenuItem(m_addElementsMenu, ID_ADDMENU_GENERATOR, _("&Generator\tG"),
138  _("Adds a generator at the circuit"));
139  wxMenuItem* indMotorElement = new wxMenuItem(m_addElementsMenu, ID_ADDMENU_INDMOTOR, _("&Induction motor\tI"),
140  _("Adds an induction motor at the circuit"));
141  wxMenuItem* syncCompElement =
142  new wxMenuItem(m_addElementsMenu, ID_ADDMENU_SYNCCOMP, _("&Synchronous compensator \tK"),
143  _("Adds an induction motor at the circuit"));
144  wxMenuItem* loadElement =
145  new wxMenuItem(m_addElementsMenu, ID_ADDMENU_LOAD, _("&Load\tShift-L"), _("Adds a load at the circuit"));
146  wxMenuItem* capacitorElement = new wxMenuItem(m_addElementsMenu, ID_ADDMENU_CAPACITOR, _("&Capacitor\tShift-C"),
147  _("Adds a shunt capacitor at the circuit"));
148  wxMenuItem* inductorElement = new wxMenuItem(m_addElementsMenu, ID_ADDMENU_INDUCTOR, _("&Inductor\tShift-I"),
149  _("Adds a shunt inductor at the circuit"));
150 
151  m_addElementsMenu->Append(busElement);
152  m_addElementsMenu->Append(lineElement);
153  m_addElementsMenu->Append(transformerElement);
154  m_addElementsMenu->Append(generatorElement);
155  m_addElementsMenu->Append(indMotorElement);
156  m_addElementsMenu->Append(syncCompElement);
157  m_addElementsMenu->Append(loadElement);
158  m_addElementsMenu->Append(capacitorElement);
159  m_addElementsMenu->Append(inductorElement);
160 
161  m_addElementsMenu->Bind(wxEVT_COMMAND_MENU_SELECTED, &MainFrame::OnAddElementsClick, this);
162 }
163 
164 void MainFrame::OnNewClick(wxRibbonButtonBarEvent& event)
165 {
166  EnableCurrentProjectRibbon();
167 
168  Workspace* newWorkspace =
169  new Workspace(this, wxString::Format(_("New project %d"), m_projectNumber), this->GetStatusBar());
170  m_workspaceList.push_back(newWorkspace);
171 
172  m_ribbonButtonBarContinuous->ToggleButton(ID_RIBBON_DISABLESOL, true);
173  m_ribbonButtonBarContinuous->ToggleButton(ID_RIBBON_ENABLESOL, false);
174 
175  m_auiNotebook->AddPage(newWorkspace, newWorkspace->GetName(), true);
176  newWorkspace->Redraw();
177  m_projectNumber++;
178 }
179 
180 void MainFrame::OnAboutClick(wxRibbonButtonBarEvent& event)
181 {
182  AboutForm about(this);
183  about.ShowModal();
184 }
185 
186 void MainFrame::OnAddElementDropdown(wxRibbonButtonBarEvent& event) { event.PopupMenu(m_addElementsMenu); }
187 void MainFrame::OnChartsClick(wxRibbonButtonBarEvent& event)
188 {
189  if(Workspace* workspace = dynamic_cast<Workspace*>(m_auiNotebook->GetCurrentPage())) {
190  std::vector<ElementPlotData> plotDataList;
191  auto elementList = workspace->GetElementList();
192  for(auto it = elementList.begin(), itEnd = elementList.end(); it != itEnd; ++it) {
193  if(PowerElement* powerElement = dynamic_cast<PowerElement*>(*it)) {
194  ElementPlotData plotData;
195  if(powerElement->GetPlotData(plotData)) plotDataList.push_back(plotData);
196  }
197  }
198  ChartView* cView = new ChartView(workspace, plotDataList, workspace->GetStabilityTimeVector());
199  cView->Show();
200  }
201 }
202 
203 void MainFrame::OnCloseClick(wxRibbonButtonBarEvent& event) {}
204 void MainFrame::OnCopyClick(wxRibbonButtonBarEvent& event) {}
205 void MainFrame::OnDataReportClick(wxRibbonButtonBarEvent& event)
206 {
207  if(Workspace* workspace = dynamic_cast<Workspace*>(m_auiNotebook->GetCurrentPage())) {
208  DataReport* dataReport = new DataReport(workspace, workspace);
209  dataReport->Show();
210  }
211 }
212 void MainFrame::OnDeleteClick(wxRibbonButtonBarEvent& event)
213 {
214  Workspace* workspace = static_cast<Workspace*>(m_auiNotebook->GetCurrentPage());
215  if(workspace) {
216  workspace->DeleteSelectedElements();
217  }
218 }
219 void MainFrame::OnDisableSolutionClick(wxRibbonButtonBarEvent& event)
220 {
221  if(Workspace* workspace = dynamic_cast<Workspace*>(m_auiNotebook->GetCurrentPage())) {
222  workspace->SetContinuousCalculationActive(false);
223  }
224  m_ribbonButtonBarContinuous->ToggleButton(ID_RIBBON_DISABLESOL, true);
225  m_ribbonButtonBarContinuous->ToggleButton(ID_RIBBON_ENABLESOL, false);
226 }
227 
228 void MainFrame::OnDragClick(wxRibbonButtonBarEvent& event) {}
229 void MainFrame::OnEnableSolutionClick(wxRibbonButtonBarEvent& event)
230 {
231  if(Workspace* workspace = dynamic_cast<Workspace*>(m_auiNotebook->GetCurrentPage())) {
232  workspace->SetContinuousCalculationActive(true);
233  workspace->RunStaticStudies();
234  }
235  m_ribbonButtonBarContinuous->ToggleButton(ID_RIBBON_ENABLESOL, true);
236  m_ribbonButtonBarContinuous->ToggleButton(ID_RIBBON_DISABLESOL, false);
237 }
238 
239 void MainFrame::OnExpImpClick(wxRibbonButtonBarEvent& event) {}
240 void MainFrame::OnFaultClick(wxRibbonButtonBarEvent& event)
241 {
242  if(Workspace* workspace = dynamic_cast<Workspace*>(m_auiNotebook->GetCurrentPage())) {
243  workspace->RunFault();
244  }
245 }
246 
247 void MainFrame::OnFitClick(wxRibbonButtonBarEvent& event)
248 {
249  Workspace* workspace = static_cast<Workspace*>(m_auiNotebook->GetCurrentPage());
250  if(workspace) {
251  workspace->Fit();
252  }
253 }
254 
255 void MainFrame::OnMoveClick(wxRibbonButtonBarEvent& event)
256 {
257  Workspace* workspace = static_cast<Workspace*>(m_auiNotebook->GetCurrentPage());
258  if(workspace) {
259  auto elementList = workspace->GetAllElements();
260  // Calculate the average position of selected elements.
261  wxPoint2DDouble averagePos(0, 0);
262  int numSelElements = 0;
263  for(auto it = elementList.begin(), itEnd = elementList.end(); it != itEnd; ++it) {
264  Element* element = *it;
265  if(element->IsSelected()) {
266  averagePos += element->GetPosition();
267  numSelElements++;
268  }
269  }
270  averagePos = wxPoint2DDouble(averagePos.m_x / double(numSelElements), averagePos.m_y / double(numSelElements));
271  // Set the move position to the average of selected elements.
272  for(auto it = elementList.begin(), itEnd = elementList.end(); it != itEnd; ++it) {
273  Element* element = *it;
274  if(element->IsSelected()) {
275  element->StartMove(averagePos);
276  }
277  }
278  workspace->SetWorkspaceMode(Workspace::MODE_MOVE_ELEMENT);
279  }
280 }
281 
282 void MainFrame::OnOpenClick(wxRibbonButtonBarEvent& event)
283 {
284  wxFileDialog openFileDialog(this, _("Open PSP file"), "", "", "PSP files (*.psp)|*.psp",
285  wxFD_OPEN | wxFD_FILE_MUST_EXIST);
286  if(openFileDialog.ShowModal() == wxID_CANCEL) return;
287 
288  wxFileName fileName(openFileDialog.GetPath());
289 
290  EnableCurrentProjectRibbon();
291  Workspace* newWorkspace = new Workspace(this, _("Open project"), this->GetStatusBar());
292 
293  FileHanding fileHandling(newWorkspace);
294  if(fileHandling.OpenProject(fileName)) {
295  newWorkspace->SetSavedPath(fileName);
296 
297  m_workspaceList.push_back(newWorkspace);
298 
299  m_ribbonButtonBarContinuous->ToggleButton(ID_RIBBON_DISABLESOL, true);
300  m_ribbonButtonBarContinuous->ToggleButton(ID_RIBBON_ENABLESOL, false);
301 
302  m_auiNotebook->AddPage(newWorkspace, newWorkspace->GetName(), true);
303  m_auiNotebook->Layout();
304  newWorkspace->Redraw();
305  newWorkspace->SetJustOpened(true);
306  m_projectNumber++;
307  } else {
308  wxMessageDialog msgDialog(this, _("It was not possible to open the selected file."), _("Error"),
309  wxOK | wxCENTRE | wxICON_ERROR);
310  msgDialog.ShowModal();
311  delete newWorkspace;
312  }
313 }
314 
315 void MainFrame::OnPSPGuideClick(wxRibbonButtonBarEvent& event) {}
316 void MainFrame::OnPasteClick(wxRibbonButtonBarEvent& event) {}
317 void MainFrame::OnPowerFlowClick(wxRibbonButtonBarEvent& event)
318 {
319  Workspace* workspace = static_cast<Workspace*>(m_auiNotebook->GetCurrentPage());
320  if(workspace) {
321  workspace->RunPowerFlow();
322  }
323 }
324 
325 void MainFrame::OnRedoClick(wxRibbonButtonBarEvent& event) {}
326 void MainFrame::OnResetVoltagesClick(wxRibbonButtonBarEvent& event) {}
327 void MainFrame::OnRunStabilityClick(wxRibbonButtonBarEvent& event)
328 {
329  Workspace* workspace = static_cast<Workspace*>(m_auiNotebook->GetCurrentPage());
330  if(workspace) {
331  workspace->RunStability();
332  }
333 }
334 
335 void MainFrame::OnSCPowerClick(wxRibbonButtonBarEvent& event)
336 {
337  Workspace* workspace = static_cast<Workspace*>(m_auiNotebook->GetCurrentPage());
338  if(workspace) {
339  workspace->RunSCPower();
340  }
341 }
342 
343 void MainFrame::OnSaveAsClick(wxRibbonButtonBarEvent& event)
344 {
345  Workspace* workspace = static_cast<Workspace*>(m_auiNotebook->GetCurrentPage());
346  if(workspace) {
347  FileHanding fileHandling(workspace);
348 
349  wxFileDialog saveFileDialog(this, _("Save PSP file"), "", "", "PSP files (*.psp)|*.psp",
350  wxFD_SAVE | wxFD_OVERWRITE_PROMPT);
351  if(saveFileDialog.ShowModal() == wxID_CANCEL) return;
352 
353  fileHandling.SaveProject(saveFileDialog.GetPath());
354  wxFileName fileName(saveFileDialog.GetPath());
355  workspace->SetName(fileName.GetName());
356  m_auiNotebook->SetPageText(m_auiNotebook->GetPageIndex(workspace), workspace->GetName());
357  workspace->SetSavedPath(fileName);
358  }
359 }
360 
361 void MainFrame::OnSaveClick(wxRibbonButtonBarEvent& event)
362 {
363  Workspace* workspace = static_cast<Workspace*>(m_auiNotebook->GetCurrentPage());
364  if(workspace) {
365  FileHanding fileHandling(workspace);
366 
367  if(workspace->GetSavedPath().IsOk()) {
368  fileHandling.SaveProject(workspace->GetSavedPath());
369  } else {
370  wxFileDialog saveFileDialog(this, _("Save PSP file"), "", "", "PSP files (*.psp)|*.psp",
371  wxFD_SAVE | wxFD_OVERWRITE_PROMPT);
372  if(saveFileDialog.ShowModal() == wxID_CANCEL) return;
373 
374  fileHandling.SaveProject(saveFileDialog.GetPath());
375  wxFileName fileName(saveFileDialog.GetPath());
376  workspace->SetName(fileName.GetName());
377  m_auiNotebook->SetPageText(m_auiNotebook->GetPageIndex(workspace), workspace->GetName());
378  workspace->SetSavedPath(fileName);
379  }
380  }
381 }
382 
383 void MainFrame::OnSnapshotClick(wxRibbonButtonBarEvent& event) {}
384 void MainFrame::OnUndoClick(wxRibbonButtonBarEvent& event) {}
385 void MainFrame::OnAddElementsClick(wxCommandEvent& event)
386 {
387  Workspace* workspace = static_cast<Workspace*>(m_auiNotebook->GetCurrentPage());
388 
389  if(workspace) {
390  if(workspace->GetWorkspaceMode() != Workspace::MODE_INSERT) {
391  auto elementList = workspace->GetElementList();
392  wxString statusBarText = "";
393  bool newElement = false;
394 
395  switch(event.GetId()) {
396  case ID_ADDMENU_BUS: {
397  Bus* newBus = new Bus(wxPoint2DDouble(0, 0),
398  wxString::Format(_("Bus %d"), workspace->GetElementNumber(ID_BUS)));
399  workspace->IncrementElementNumber(ID_BUS);
400  elementList.push_back(newBus);
401  statusBarText = _("Insert Bus: Click to insert, ESC to cancel.");
402  newElement = true;
403  } break;
404  case ID_ADDMENU_LINE: {
405  Line* newLine = new Line(wxString::Format(_("Line %d"), workspace->GetElementNumber(ID_LINE)));
406  elementList.push_back(newLine);
407  workspace->IncrementElementNumber(ID_LINE);
408  statusBarText = _("Insert Line: Click on two buses, ESC to cancel.");
409  newElement = true;
410  } break;
411  case ID_ADDMENU_TRANSFORMER: {
412  Transformer* newTransformer = new Transformer(
413  wxString::Format(_("Transformer %d"), workspace->GetElementNumber(ID_TRANSFORMER)));
414  workspace->IncrementElementNumber(ID_TRANSFORMER);
415  elementList.push_back(newTransformer);
416  statusBarText = _("Insert Transformer: Click on two buses, ESC to cancel.");
417  newElement = true;
418  } break;
419  case ID_ADDMENU_GENERATOR: {
420  SyncGenerator* newGenerator = new SyncGenerator(
421  wxString::Format(_("Generator %d"), workspace->GetElementNumber(ID_SYNCGENERATOR)));
422  workspace->IncrementElementNumber(ID_SYNCGENERATOR);
423  elementList.push_back(newGenerator);
424  statusBarText = _("Insert Generator: Click on a buses, ESC to cancel.");
425  newElement = true;
426  } break;
427  case ID_ADDMENU_LOAD: {
428  Load* newLoad = new Load(wxString::Format(_("Load %d"), workspace->GetElementNumber(ID_LOAD)));
429  workspace->IncrementElementNumber(ID_LOAD);
430  elementList.push_back(newLoad);
431  statusBarText = _("Insert Load: Click on a buses, ESC to cancel.");
432  newElement = true;
433  } break;
434  case ID_ADDMENU_CAPACITOR: {
435  Capacitor* newCapacitor =
436  new Capacitor(wxString::Format(_("Capacitor %d"), workspace->GetElementNumber(ID_CAPACITOR)));
437  workspace->IncrementElementNumber(ID_CAPACITOR);
438  elementList.push_back(newCapacitor);
439  statusBarText = _("Insert Capacitor: Click on a buses, ESC to cancel.");
440  newElement = true;
441  } break;
442  case ID_ADDMENU_INDUCTOR: {
443  Inductor* newInductor =
444  new Inductor(wxString::Format(_("Inductor %d"), workspace->GetElementNumber(ID_INDUCTOR)));
445  workspace->IncrementElementNumber(ID_INDUCTOR);
446  elementList.push_back(newInductor);
447  statusBarText = _("Insert Inductor: Click on a buses, ESC to cancel.");
448  newElement = true;
449  } break;
450  case ID_ADDMENU_INDMOTOR: {
451  IndMotor* newIndMotor = new IndMotor(
452  wxString::Format(_("Induction motor %d"), workspace->GetElementNumber(ID_INDMOTOR)));
453  workspace->IncrementElementNumber(ID_INDMOTOR);
454  elementList.push_back(newIndMotor);
455  statusBarText = _("Insert Induction Motor: Click on a buses, ESC to cancel.");
456  newElement = true;
457  } break;
458  case ID_ADDMENU_SYNCCOMP: {
459  SyncMotor* newSyncCondenser = new SyncMotor(
460  wxString::Format(_("Synchronous condenser %d"), workspace->GetElementNumber(ID_SYNCMOTOR)));
461  workspace->IncrementElementNumber(ID_SYNCMOTOR);
462  elementList.push_back(newSyncCondenser);
463  statusBarText = _("Insert Synchronous Condenser: Click on a buses, ESC to cancel.");
464  newElement = true;
465  } break;
466  }
467  if(newElement) {
468  workspace->SetElementList(elementList);
469  workspace->SetWorkspaceMode(Workspace::MODE_INSERT);
470  workspace->SetStatusBarText(statusBarText);
471  workspace->Redraw();
472  }
473  }
474  }
475 }
476 void MainFrame::NotebookPageClosed(wxAuiNotebookEvent& event)
477 {
478  if(m_auiNotebook->GetPageCount() == 0) EnableCurrentProjectRibbon(false);
479 }
480 
481 void MainFrame::NotebookPageClosing(wxAuiNotebookEvent& event)
482 {
483  auto it = m_workspaceList.begin();
484  while(it != m_workspaceList.end()) {
485  if(*it == m_auiNotebook->GetCurrentPage()) {
486  m_workspaceList.erase(it);
487  break;
488  }
489  it++;
490  }
491  event.Skip();
492 }
493 
494 void MainFrame::OnRotClockClick(wxRibbonButtonBarEvent& event)
495 {
496  Workspace* workspace = static_cast<Workspace*>(m_auiNotebook->GetCurrentPage());
497  if(workspace) {
498  workspace->RotateSelectedElements();
499  }
500 }
501 
502 void MainFrame::OnRotCounterClockClick(wxRibbonButtonBarEvent& event)
503 {
504  Workspace* workspace = static_cast<Workspace*>(m_auiNotebook->GetCurrentPage());
505  if(workspace) {
506  workspace->RotateSelectedElements(false);
507  }
508 }
509 
510 void MainFrame::OnGeneralSettingsClick(wxRibbonButtonBarEvent& event)
511 {
512  GeneralPropertiesForm genPropForm(this, m_generalProperties);
513  genPropForm.SetInitialSize();
514  genPropForm.ShowModal();
515 }
516 
517 void MainFrame::OnSimulationSettingsClick(wxRibbonButtonBarEvent& event)
518 {
519  Workspace* workspace = static_cast<Workspace*>(m_auiNotebook->GetCurrentPage());
520  if(workspace) {
521  SimulationsSettingsForm simulSettingsForm(this, workspace->GetProperties());
522  simulSettingsForm.SetInitialSize();
523  simulSettingsForm.ShowModal();
524  }
525 }
General and simulation data manager.
+
1 /*
2  * Copyright (C) 2017 Thales Lima Oliveira <thales@ufu.br>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program. If not, see <https://www.gnu.org/licenses/>.
16  */
17 
18 #include "MainFrame.h"
19 #include "ArtMetro.h"
20 #include "Workspace.h"
21 #include "Bus.h"
22 #include "Line.h"
23 #include "Transformer.h"
24 #include "SyncGenerator.h"
25 #include "IndMotor.h"
26 #include "SyncMotor.h"
27 #include "Load.h"
28 #include "Inductor.h"
29 #include "Capacitor.h"
30 #include "FileHanding.h"
31 #include "GeneralPropertiesForm.h"
33 #include "PropertiesData.h"
34 #include "ChartView.h"
35 #include "DataReport.h"
36 #include "AboutForm.h"
37 
39 MainFrame::MainFrame(wxWindow* parent, wxLocale* locale, PropertiesData* initProperties, wxString openPath)
40  : MainFrameBase(parent)
41 {
42  m_locale = locale;
43  m_generalProperties = initProperties;
44 
45  Init();
46 
47  if(openPath != "") {
48  EnableCurrentProjectRibbon();
49  Workspace* newWorkspace = new Workspace(this, _("Open project"), this->GetStatusBar(), m_sharedGLContext);
50  if(!m_sharedGLContext) m_sharedGLContext = newWorkspace->GetOpenGLContext();
51 
52  FileHanding fileHandling(newWorkspace);
53  if(fileHandling.OpenProject(openPath)) {
54  newWorkspace->SetSavedPath(openPath);
55 
56  m_workspaceList.push_back(newWorkspace);
57 
58  m_ribbonButtonBarContinuous->ToggleButton(ID_RIBBON_DISABLESOL, true);
59  m_ribbonButtonBarContinuous->ToggleButton(ID_RIBBON_ENABLESOL, false);
60 
61  m_auiNotebook->AddPage(newWorkspace, newWorkspace->GetName(), true);
62  m_auiNotebook->Layout();
63  newWorkspace->Redraw();
64  newWorkspace->SetJustOpened(true);
65  m_projectNumber++;
66  }
67  }
68 }
69 
71 {
72  // if(m_artMetro) delete m_artMetro;
73  if(m_addElementsMenu) {
74  m_addElementsMenu->Disconnect(wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MainFrame::OnAddElementsClick),
75  NULL, this);
76  delete m_addElementsMenu;
77  }
78  if(m_locale) delete m_locale;
79  if(m_generalProperties) delete m_generalProperties;
80 }
81 
82 void MainFrame::Init()
83 {
84  this->SetSize(800, 600);
85 
86  CreateAddElementsMenu();
87 
88  EnableCurrentProjectRibbon(false);
89 
90  m_artMetro = new wxRibbonMetroArtProvider();
91  m_ribbonBar->SetArtProvider(m_artMetro);
92  m_ribbonBar->Realize();
93 
94  this->Layout();
95 }
96 
97 void MainFrame::EnableCurrentProjectRibbon(bool enable)
98 {
99  m_ribbonButtonBarCircuit->EnableButton(ID_RIBBON_ADDELEMENT, enable);
100  m_ribbonButtonBarReports->EnableButton(ID_RIBBON_CHARTS, enable);
101  m_ribbonButtonBarCProject->EnableButton(ID_RIBBON_CLOSE, enable);
102  m_ribbonButtonBarClipboard->EnableButton(ID_RIBBON_COPY, enable);
103  m_ribbonButtonBarReports->EnableButton(ID_RIBBON_DATAREPORT, enable);
104  m_ribbonButtonBarCircuit->EnableButton(ID_RIBBON_DELETE, enable);
105  m_ribbonButtonBarContinuous->EnableButton(ID_RIBBON_DISABLESOL, enable);
106  m_ribbonButtonBarCircuit->EnableButton(ID_RIBBON_DRAG, enable);
107  m_ribbonButtonBarContinuous->EnableButton(ID_RIBBON_ENABLESOL, enable);
108  m_ribbonButtonBarSimulations->EnableButton(ID_RIBBON_FAULT, enable);
109  m_ribbonButtonBarCircuit->EnableButton(ID_RIBBON_FIT, enable);
110  m_ribbonButtonBarCircuit->EnableButton(ID_RIBBON_MOVE, enable);
111  m_ribbonButtonBarClipboard->EnableButton(ID_RIBBON_PASTE, enable);
112  m_ribbonButtonBarSimulations->EnableButton(ID_RIBBON_POWERFLOW, enable);
113  m_ribbonButtonBarClipboard->EnableButton(ID_RIBBON_REDO, enable);
114  m_ribbonButtonBarContinuous->EnableButton(ID_RIBBON_RESETVOLT, enable);
115  m_ribbonButtonBarSimulations->EnableButton(ID_RIBBON_RUNSTAB, enable);
116  m_ribbonButtonBarCProject->EnableButton(ID_RIBBON_SAVE, enable);
117  m_ribbonButtonBarCProject->EnableButton(ID_RIBBON_SAVEAS, enable);
118  m_ribbonButtonBarSimulations->EnableButton(ID_RIBBON_SCPOWER, enable);
119  m_ribbonButtonBarCircuit->EnableButton(ID_RIBBON_PROJSETTINGS, enable);
120  m_ribbonButtonBarReports->EnableButton(ID_RIBBON_SNAPSHOT, enable);
121  m_ribbonButtonBarSimulations->EnableButton(ID_RIBBON_SIMULSETTINGS, enable);
122  m_ribbonButtonBarClipboard->EnableButton(ID_RIBBON_UNDO, enable);
123  m_ribbonButtonBarCircuit->EnableButton(ID_RIBBON_ROTATEC, enable);
124  m_ribbonButtonBarCircuit->EnableButton(ID_RIBBON_ROTATECC, enable);
125 }
126 
127 void MainFrame::CreateAddElementsMenu()
128 {
129  m_addElementsMenu = new wxMenu();
130 
131  wxMenuItem* busElement =
132  new wxMenuItem(m_addElementsMenu, ID_ADDMENU_BUS, _("&Bus\tB"), _("Adds a bus at the circuit"));
133  // busElement->SetBitmap(wxArtProvider::GetBitmap(wxART_WARNING));
134  wxMenuItem* lineElement =
135  new wxMenuItem(m_addElementsMenu, ID_ADDMENU_LINE, _("&Line\tL"), _("Adds a power line at the circuit"));
136  wxMenuItem* transformerElement = new wxMenuItem(m_addElementsMenu, ID_ADDMENU_TRANSFORMER, _("&Transformer\tT"),
137  _("Adds a transformer at the circuit"));
138  wxMenuItem* generatorElement = new wxMenuItem(m_addElementsMenu, ID_ADDMENU_GENERATOR, _("&Generator\tG"),
139  _("Adds a generator at the circuit"));
140  wxMenuItem* indMotorElement = new wxMenuItem(m_addElementsMenu, ID_ADDMENU_INDMOTOR, _("&Induction motor\tI"),
141  _("Adds an induction motor at the circuit"));
142  wxMenuItem* syncCompElement =
143  new wxMenuItem(m_addElementsMenu, ID_ADDMENU_SYNCCOMP, _("&Synchronous compensator \tK"),
144  _("Adds an induction motor at the circuit"));
145  wxMenuItem* loadElement =
146  new wxMenuItem(m_addElementsMenu, ID_ADDMENU_LOAD, _("&Load\tShift-L"), _("Adds a load at the circuit"));
147  wxMenuItem* capacitorElement = new wxMenuItem(m_addElementsMenu, ID_ADDMENU_CAPACITOR, _("&Capacitor\tShift-C"),
148  _("Adds a shunt capacitor at the circuit"));
149  wxMenuItem* inductorElement = new wxMenuItem(m_addElementsMenu, ID_ADDMENU_INDUCTOR, _("&Inductor\tShift-I"),
150  _("Adds a shunt inductor at the circuit"));
151 
152  m_addElementsMenu->Append(busElement);
153  m_addElementsMenu->Append(lineElement);
154  m_addElementsMenu->Append(transformerElement);
155  m_addElementsMenu->Append(generatorElement);
156  m_addElementsMenu->Append(indMotorElement);
157  m_addElementsMenu->Append(syncCompElement);
158  m_addElementsMenu->Append(loadElement);
159  m_addElementsMenu->Append(capacitorElement);
160  m_addElementsMenu->Append(inductorElement);
161 
162  m_addElementsMenu->Bind(wxEVT_COMMAND_MENU_SELECTED, &MainFrame::OnAddElementsClick, this);
163 }
164 
165 void MainFrame::OnNewClick(wxRibbonButtonBarEvent& event)
166 {
167  EnableCurrentProjectRibbon();
168 
169  Workspace* newWorkspace =
170  new Workspace(this, wxString::Format(_("New project %d"), m_projectNumber), this->GetStatusBar(), m_sharedGLContext);
171  if(!m_sharedGLContext) m_sharedGLContext = newWorkspace->GetOpenGLContext();
172  m_workspaceList.push_back(newWorkspace);
173 
174  m_ribbonButtonBarContinuous->ToggleButton(ID_RIBBON_DISABLESOL, true);
175  m_ribbonButtonBarContinuous->ToggleButton(ID_RIBBON_ENABLESOL, false);
176 
177  m_auiNotebook->AddPage(newWorkspace, newWorkspace->GetName(), true);
178  newWorkspace->Redraw();
179  m_projectNumber++;
180 }
181 
182 void MainFrame::OnAboutClick(wxRibbonButtonBarEvent& event)
183 {
184  AboutForm about(this);
185  about.ShowModal();
186 }
187 
188 void MainFrame::OnAddElementDropdown(wxRibbonButtonBarEvent& event) { event.PopupMenu(m_addElementsMenu); }
189 void MainFrame::OnChartsClick(wxRibbonButtonBarEvent& event)
190 {
191  if(Workspace* workspace = dynamic_cast<Workspace*>(m_auiNotebook->GetCurrentPage())) {
192  std::vector<ElementPlotData> plotDataList;
193  auto elementList = workspace->GetElementList();
194  for(auto it = elementList.begin(), itEnd = elementList.end(); it != itEnd; ++it) {
195  if(PowerElement* powerElement = dynamic_cast<PowerElement*>(*it)) {
196  ElementPlotData plotData;
197  if(powerElement->GetPlotData(plotData)) plotDataList.push_back(plotData);
198  }
199  }
200  ChartView* cView = new ChartView(workspace, plotDataList, workspace->GetStabilityTimeVector());
201  cView->Show();
202  }
203 }
204 
205 void MainFrame::OnCloseClick(wxRibbonButtonBarEvent& event) {}
206 void MainFrame::OnCopyClick(wxRibbonButtonBarEvent& event) {}
207 void MainFrame::OnDataReportClick(wxRibbonButtonBarEvent& event)
208 {
209  if(Workspace* workspace = dynamic_cast<Workspace*>(m_auiNotebook->GetCurrentPage())) {
210  DataReport* dataReport = new DataReport(workspace, workspace);
211  dataReport->Show();
212  }
213 }
214 void MainFrame::OnDeleteClick(wxRibbonButtonBarEvent& event)
215 {
216  Workspace* workspace = static_cast<Workspace*>(m_auiNotebook->GetCurrentPage());
217  if(workspace) {
218  workspace->DeleteSelectedElements();
219  }
220 }
221 void MainFrame::OnDisableSolutionClick(wxRibbonButtonBarEvent& event)
222 {
223  if(Workspace* workspace = dynamic_cast<Workspace*>(m_auiNotebook->GetCurrentPage())) {
224  workspace->SetContinuousCalculationActive(false);
225  }
226  m_ribbonButtonBarContinuous->ToggleButton(ID_RIBBON_DISABLESOL, true);
227  m_ribbonButtonBarContinuous->ToggleButton(ID_RIBBON_ENABLESOL, false);
228 }
229 
230 void MainFrame::OnDragClick(wxRibbonButtonBarEvent& event) {}
231 void MainFrame::OnEnableSolutionClick(wxRibbonButtonBarEvent& event)
232 {
233  if(Workspace* workspace = dynamic_cast<Workspace*>(m_auiNotebook->GetCurrentPage())) {
234  workspace->SetContinuousCalculationActive(true);
235  workspace->RunStaticStudies();
236  }
237  m_ribbonButtonBarContinuous->ToggleButton(ID_RIBBON_ENABLESOL, true);
238  m_ribbonButtonBarContinuous->ToggleButton(ID_RIBBON_DISABLESOL, false);
239 }
240 
241 void MainFrame::OnExpImpClick(wxRibbonButtonBarEvent& event) {}
242 void MainFrame::OnFaultClick(wxRibbonButtonBarEvent& event)
243 {
244  if(Workspace* workspace = dynamic_cast<Workspace*>(m_auiNotebook->GetCurrentPage())) {
245  workspace->RunFault();
246  }
247 }
248 
249 void MainFrame::OnFitClick(wxRibbonButtonBarEvent& event)
250 {
251  Workspace* workspace = static_cast<Workspace*>(m_auiNotebook->GetCurrentPage());
252  if(workspace) {
253  workspace->Fit();
254  }
255 }
256 
257 void MainFrame::OnMoveClick(wxRibbonButtonBarEvent& event)
258 {
259  Workspace* workspace = static_cast<Workspace*>(m_auiNotebook->GetCurrentPage());
260  if(workspace) {
261  auto elementList = workspace->GetAllElements();
262  // Calculate the average position of selected elements.
263  wxPoint2DDouble averagePos(0, 0);
264  int numSelElements = 0;
265  for(auto it = elementList.begin(), itEnd = elementList.end(); it != itEnd; ++it) {
266  Element* element = *it;
267  if(element->IsSelected()) {
268  averagePos += element->GetPosition();
269  numSelElements++;
270  }
271  }
272  averagePos = wxPoint2DDouble(averagePos.m_x / double(numSelElements), averagePos.m_y / double(numSelElements));
273  // Set the move position to the average of selected elements.
274  for(auto it = elementList.begin(), itEnd = elementList.end(); it != itEnd; ++it) {
275  Element* element = *it;
276  if(element->IsSelected()) {
277  element->StartMove(averagePos);
278  }
279  }
280  workspace->SetWorkspaceMode(Workspace::MODE_MOVE_ELEMENT);
281  }
282 }
283 
284 void MainFrame::OnOpenClick(wxRibbonButtonBarEvent& event)
285 {
286  wxFileDialog openFileDialog(this, _("Open PSP file"), "", "", "PSP files (*.psp)|*.psp",
287  wxFD_OPEN | wxFD_FILE_MUST_EXIST);
288  if(openFileDialog.ShowModal() == wxID_CANCEL) return;
289 
290  wxFileName fileName(openFileDialog.GetPath());
291 
292  EnableCurrentProjectRibbon();
293  Workspace* newWorkspace = new Workspace(this, _("Open project"), this->GetStatusBar(), m_sharedGLContext);
294  if(!m_sharedGLContext) m_sharedGLContext = newWorkspace->GetOpenGLContext();
295 
296  FileHanding fileHandling(newWorkspace);
297  if(fileHandling.OpenProject(fileName)) {
298  newWorkspace->SetSavedPath(fileName);
299 
300  m_workspaceList.push_back(newWorkspace);
301 
302  m_ribbonButtonBarContinuous->ToggleButton(ID_RIBBON_DISABLESOL, true);
303  m_ribbonButtonBarContinuous->ToggleButton(ID_RIBBON_ENABLESOL, false);
304 
305  m_auiNotebook->AddPage(newWorkspace, newWorkspace->GetName(), true);
306  m_auiNotebook->Layout();
307  newWorkspace->Redraw();
308  newWorkspace->SetJustOpened(true);
309  m_projectNumber++;
310  } else {
311  wxMessageDialog msgDialog(this, _("It was not possible to open the selected file."), _("Error"),
312  wxOK | wxCENTRE | wxICON_ERROR);
313  msgDialog.ShowModal();
314  delete newWorkspace;
315  }
316 }
317 
318 void MainFrame::OnPSPGuideClick(wxRibbonButtonBarEvent& event) {}
319 void MainFrame::OnPasteClick(wxRibbonButtonBarEvent& event) {}
320 void MainFrame::OnPowerFlowClick(wxRibbonButtonBarEvent& event)
321 {
322  Workspace* workspace = static_cast<Workspace*>(m_auiNotebook->GetCurrentPage());
323  if(workspace) {
324  workspace->RunPowerFlow();
325  }
326 }
327 
328 void MainFrame::OnRedoClick(wxRibbonButtonBarEvent& event) {}
329 void MainFrame::OnResetVoltagesClick(wxRibbonButtonBarEvent& event) {}
330 void MainFrame::OnRunStabilityClick(wxRibbonButtonBarEvent& event)
331 {
332  Workspace* workspace = static_cast<Workspace*>(m_auiNotebook->GetCurrentPage());
333  if(workspace) {
334  workspace->RunStability();
335  }
336 }
337 
338 void MainFrame::OnSCPowerClick(wxRibbonButtonBarEvent& event)
339 {
340  Workspace* workspace = static_cast<Workspace*>(m_auiNotebook->GetCurrentPage());
341  if(workspace) {
342  workspace->RunSCPower();
343  }
344 }
345 
346 void MainFrame::OnSaveAsClick(wxRibbonButtonBarEvent& event)
347 {
348  Workspace* workspace = static_cast<Workspace*>(m_auiNotebook->GetCurrentPage());
349  if(workspace) {
350  FileHanding fileHandling(workspace);
351 
352  wxFileDialog saveFileDialog(this, _("Save PSP file"), "", "", "PSP files (*.psp)|*.psp",
353  wxFD_SAVE | wxFD_OVERWRITE_PROMPT);
354  if(saveFileDialog.ShowModal() == wxID_CANCEL) return;
355 
356  fileHandling.SaveProject(saveFileDialog.GetPath());
357  wxFileName fileName(saveFileDialog.GetPath());
358  workspace->SetName(fileName.GetName());
359  m_auiNotebook->SetPageText(m_auiNotebook->GetPageIndex(workspace), workspace->GetName());
360  workspace->SetSavedPath(fileName);
361  }
362 }
363 
364 void MainFrame::OnSaveClick(wxRibbonButtonBarEvent& event)
365 {
366  Workspace* workspace = static_cast<Workspace*>(m_auiNotebook->GetCurrentPage());
367  if(workspace) {
368  FileHanding fileHandling(workspace);
369 
370  if(workspace->GetSavedPath().IsOk()) {
371  fileHandling.SaveProject(workspace->GetSavedPath());
372  } else {
373  wxFileDialog saveFileDialog(this, _("Save PSP file"), "", "", "PSP files (*.psp)|*.psp",
374  wxFD_SAVE | wxFD_OVERWRITE_PROMPT);
375  if(saveFileDialog.ShowModal() == wxID_CANCEL) return;
376 
377  fileHandling.SaveProject(saveFileDialog.GetPath());
378  wxFileName fileName(saveFileDialog.GetPath());
379  workspace->SetName(fileName.GetName());
380  m_auiNotebook->SetPageText(m_auiNotebook->GetPageIndex(workspace), workspace->GetName());
381  workspace->SetSavedPath(fileName);
382  }
383  }
384 }
385 
386 void MainFrame::OnSnapshotClick(wxRibbonButtonBarEvent& event) {}
387 void MainFrame::OnUndoClick(wxRibbonButtonBarEvent& event) {}
388 void MainFrame::OnAddElementsClick(wxCommandEvent& event)
389 {
390  Workspace* workspace = static_cast<Workspace*>(m_auiNotebook->GetCurrentPage());
391 
392  if(workspace) {
393  if(workspace->GetWorkspaceMode() != Workspace::MODE_INSERT) {
394  auto elementList = workspace->GetElementList();
395  wxString statusBarText = "";
396  bool newElement = false;
397 
398  switch(event.GetId()) {
399  case ID_ADDMENU_BUS: {
400  Bus* newBus = new Bus(wxPoint2DDouble(0, 0),
401  wxString::Format(_("Bus %d"), workspace->GetElementNumber(ID_BUS)));
402  workspace->IncrementElementNumber(ID_BUS);
403  elementList.push_back(newBus);
404  statusBarText = _("Insert Bus: Click to insert, ESC to cancel.");
405  newElement = true;
406  } break;
407  case ID_ADDMENU_LINE: {
408  Line* newLine = new Line(wxString::Format(_("Line %d"), workspace->GetElementNumber(ID_LINE)));
409  elementList.push_back(newLine);
410  workspace->IncrementElementNumber(ID_LINE);
411  statusBarText = _("Insert Line: Click on two buses, ESC to cancel.");
412  newElement = true;
413  } break;
414  case ID_ADDMENU_TRANSFORMER: {
415  Transformer* newTransformer = new Transformer(
416  wxString::Format(_("Transformer %d"), workspace->GetElementNumber(ID_TRANSFORMER)));
417  workspace->IncrementElementNumber(ID_TRANSFORMER);
418  elementList.push_back(newTransformer);
419  statusBarText = _("Insert Transformer: Click on two buses, ESC to cancel.");
420  newElement = true;
421  } break;
422  case ID_ADDMENU_GENERATOR: {
423  SyncGenerator* newGenerator = new SyncGenerator(
424  wxString::Format(_("Generator %d"), workspace->GetElementNumber(ID_SYNCGENERATOR)));
425  workspace->IncrementElementNumber(ID_SYNCGENERATOR);
426  elementList.push_back(newGenerator);
427  statusBarText = _("Insert Generator: Click on a buses, ESC to cancel.");
428  newElement = true;
429  } break;
430  case ID_ADDMENU_LOAD: {
431  Load* newLoad = new Load(wxString::Format(_("Load %d"), workspace->GetElementNumber(ID_LOAD)));
432  workspace->IncrementElementNumber(ID_LOAD);
433  elementList.push_back(newLoad);
434  statusBarText = _("Insert Load: Click on a buses, ESC to cancel.");
435  newElement = true;
436  } break;
437  case ID_ADDMENU_CAPACITOR: {
438  Capacitor* newCapacitor =
439  new Capacitor(wxString::Format(_("Capacitor %d"), workspace->GetElementNumber(ID_CAPACITOR)));
440  workspace->IncrementElementNumber(ID_CAPACITOR);
441  elementList.push_back(newCapacitor);
442  statusBarText = _("Insert Capacitor: Click on a buses, ESC to cancel.");
443  newElement = true;
444  } break;
445  case ID_ADDMENU_INDUCTOR: {
446  Inductor* newInductor =
447  new Inductor(wxString::Format(_("Inductor %d"), workspace->GetElementNumber(ID_INDUCTOR)));
448  workspace->IncrementElementNumber(ID_INDUCTOR);
449  elementList.push_back(newInductor);
450  statusBarText = _("Insert Inductor: Click on a buses, ESC to cancel.");
451  newElement = true;
452  } break;
453  case ID_ADDMENU_INDMOTOR: {
454  IndMotor* newIndMotor = new IndMotor(
455  wxString::Format(_("Induction motor %d"), workspace->GetElementNumber(ID_INDMOTOR)));
456  workspace->IncrementElementNumber(ID_INDMOTOR);
457  elementList.push_back(newIndMotor);
458  statusBarText = _("Insert Induction Motor: Click on a buses, ESC to cancel.");
459  newElement = true;
460  } break;
461  case ID_ADDMENU_SYNCCOMP: {
462  SyncMotor* newSyncCondenser = new SyncMotor(
463  wxString::Format(_("Synchronous condenser %d"), workspace->GetElementNumber(ID_SYNCMOTOR)));
464  workspace->IncrementElementNumber(ID_SYNCMOTOR);
465  elementList.push_back(newSyncCondenser);
466  statusBarText = _("Insert Synchronous Condenser: Click on a buses, ESC to cancel.");
467  newElement = true;
468  } break;
469  }
470  if(newElement) {
471  workspace->SetElementList(elementList);
472  workspace->SetWorkspaceMode(Workspace::MODE_INSERT);
473  workspace->SetStatusBarText(statusBarText);
474  workspace->Redraw();
475  }
476  }
477  }
478 }
479 void MainFrame::NotebookPageClosed(wxAuiNotebookEvent& event)
480 {
481  if(m_auiNotebook->GetPageCount() == 0) EnableCurrentProjectRibbon(false);
482 }
483 
484 void MainFrame::NotebookPageClosing(wxAuiNotebookEvent& event)
485 {
486  auto it = m_workspaceList.begin();
487  while(it != m_workspaceList.end()) {
488  if(*it == m_auiNotebook->GetCurrentPage()) {
489  if((*it)->GetOpenGLContext() == m_sharedGLContext) m_sharedGLContext = NULL;
490  m_workspaceList.erase(it);
491  break;
492  }
493  it++;
494  }
495  if(!m_sharedGLContext && m_workspaceList.size() != 0) {
496  m_sharedGLContext = m_workspaceList[0]->GetOpenGLContext();
497  }
498  event.Skip();
499 }
500 
501 void MainFrame::OnRotClockClick(wxRibbonButtonBarEvent& event)
502 {
503  Workspace* workspace = static_cast<Workspace*>(m_auiNotebook->GetCurrentPage());
504  if(workspace) {
505  workspace->RotateSelectedElements();
506  }
507 }
508 
509 void MainFrame::OnRotCounterClockClick(wxRibbonButtonBarEvent& event)
510 {
511  Workspace* workspace = static_cast<Workspace*>(m_auiNotebook->GetCurrentPage());
512  if(workspace) {
513  workspace->RotateSelectedElements(false);
514  }
515 }
516 
517 void MainFrame::OnGeneralSettingsClick(wxRibbonButtonBarEvent& event)
518 {
519  GeneralPropertiesForm genPropForm(this, m_generalProperties);
520  genPropForm.SetInitialSize();
521  genPropForm.ShowModal();
522 }
523 
524 void MainFrame::OnSimulationSettingsClick(wxRibbonButtonBarEvent& event)
525 {
526  Workspace* workspace = static_cast<Workspace*>(m_auiNotebook->GetCurrentPage());
527  if(workspace) {
528  SimulationsSettingsForm simulSettingsForm(this, workspace->GetProperties());
529  simulSettingsForm.SetInitialSize();
530  simulSettingsForm.ShowModal();
531  }
532 }
General and simulation data manager.
Base class of all elements of the program. This class is responsible for manage graphical and his dat...
Definition: Element.h:113
-
~MainFrame()
Default destructor.
Definition: MainFrame.cpp:69
+
~MainFrame()
Default destructor.
Definition: MainFrame.cpp:70
@@ -114,7 +114,7 @@ $(document).ready(function(){initNavTree('_main_frame_8cpp_source.html','');});
Power line element.
Definition: Line.h:59
-
Loas shunt power element.
Definition: Load.h:42
+
Loas shunt power element.
Definition: Load.h:73
This class is responsible to manage the charts generated in the transient electromechanical studies...
Definition: ChartView.h:40
Synchronous motor (synchronous compensator) power element.
Definition: SyncMotor.h:134
diff --git a/docs/doxygen/html/_main_frame_8h.html b/docs/doxygen/html/_main_frame_8h.html index 0239390..cf5d664 100644 --- a/docs/doxygen/html/_main_frame_8h.html +++ b/docs/doxygen/html/_main_frame_8h.html @@ -94,6 +94,7 @@ $(document).ready(function(){initNavTree('_main_frame_8h.html','');});
#include <wx/menu.h>
#include <wx/msgdlg.h>
#include <wx/filedlg.h>
+#include <wx/glcanvas.h>
#include "MainFrameBase.h"

Go to the source code of this file.

diff --git a/docs/doxygen/html/_main_frame_8h_source.html b/docs/doxygen/html/_main_frame_8h_source.html index 3ac55b9..0eca7c8 100644 --- a/docs/doxygen/html/_main_frame_8h_source.html +++ b/docs/doxygen/html/_main_frame_8h_source.html @@ -88,13 +88,13 @@ $(document).ready(function(){initNavTree('_main_frame_8h_source.html','');});
MainFrame.h
-Go to the documentation of this file.
1 /*
2  * Copyright (C) 2017 Thales Lima Oliveira <thales@ufu.br>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program. If not, see <https://www.gnu.org/licenses/>.
16  */
17 
18 #ifndef MAINFRAME_H
19 #define MAINFRAME_H
20 
21 #include <wx/menu.h>
22 #include <wx/msgdlg.h>
23 #include <wx/filedlg.h>
24 
25 #include "MainFrameBase.h"
26 
27 class MainFrameBase;
29 class Workspace;
30 class FileHanding;
33 class PropertiesData;
34 class ChartView;
35 class DataReport;
36 class AboutForm;
37 
38 enum {
39  ID_ADDMENU_BUS = 20000,
40  ID_ADDMENU_LINE,
41  ID_ADDMENU_TRANSFORMER,
42  ID_ADDMENU_GENERATOR,
43  ID_ADDMENU_LOAD,
44  ID_ADDMENU_CAPACITOR,
45  ID_ADDMENU_INDUCTOR,
46  ID_ADDMENU_INDMOTOR,
47  ID_ADDMENU_SYNCCOMP
48 };
49 
57 class MainFrame : public MainFrameBase
58 {
59  public:
64  MainFrame();
71  MainFrame(wxWindow* parent, wxLocale* locale, PropertiesData* initProperties, wxString openPath = "");
72 
76  ~MainFrame();
77 
78  protected:
79  virtual void OnGeneralSettingsClick(wxRibbonButtonBarEvent& event);
80  virtual void OnSimulationSettingsClick(wxRibbonButtonBarEvent& event);
81  virtual void OnRotClockClick(wxRibbonButtonBarEvent& event);
82  virtual void OnRotCounterClockClick(wxRibbonButtonBarEvent& event);
83  virtual void NotebookPageClosed(wxAuiNotebookEvent& event);
84  virtual void NotebookPageClosing(wxAuiNotebookEvent& event);
85  virtual void OnAboutClick(wxRibbonButtonBarEvent& event);
86  virtual void OnAddElementDropdown(wxRibbonButtonBarEvent& event);
87  virtual void OnChartsClick(wxRibbonButtonBarEvent& event);
88  virtual void OnCloseClick(wxRibbonButtonBarEvent& event);
89  virtual void OnCopyClick(wxRibbonButtonBarEvent& event);
90  virtual void OnDataReportClick(wxRibbonButtonBarEvent& event);
91  virtual void OnDeleteClick(wxRibbonButtonBarEvent& event);
92  virtual void OnDisableSolutionClick(wxRibbonButtonBarEvent& event);
93  virtual void OnDragClick(wxRibbonButtonBarEvent& event);
94  virtual void OnEnableSolutionClick(wxRibbonButtonBarEvent& event);
95  virtual void OnExitClick(wxRibbonButtonBarEvent& event) { this->Close(); };
96  virtual void OnExpImpClick(wxRibbonButtonBarEvent& event);
97  virtual void OnFaultClick(wxRibbonButtonBarEvent& event);
98  virtual void OnFitClick(wxRibbonButtonBarEvent& event);
99  virtual void OnMoveClick(wxRibbonButtonBarEvent& event);
100  virtual void OnOpenClick(wxRibbonButtonBarEvent& event);
101  virtual void OnPSPGuideClick(wxRibbonButtonBarEvent& event);
102  virtual void OnPasteClick(wxRibbonButtonBarEvent& event);
103  virtual void OnPowerFlowClick(wxRibbonButtonBarEvent& event);
104  virtual void OnRedoClick(wxRibbonButtonBarEvent& event);
105  virtual void OnResetVoltagesClick(wxRibbonButtonBarEvent& event);
106  virtual void OnRunStabilityClick(wxRibbonButtonBarEvent& event);
107  virtual void OnSCPowerClick(wxRibbonButtonBarEvent& event);
108  virtual void OnSaveAsClick(wxRibbonButtonBarEvent& event);
109  virtual void OnSaveClick(wxRibbonButtonBarEvent& event);
110  virtual void OnSnapshotClick(wxRibbonButtonBarEvent& event);
111  virtual void OnUndoClick(wxRibbonButtonBarEvent& event);
112  virtual void OnNewClick(wxRibbonButtonBarEvent& event);
113 
114  std::vector<Workspace*> m_workspaceList;
115  int m_projectNumber = 1;
116 
117  wxRibbonMetroArtProvider* m_artMetro = NULL;
118  wxMenu* m_addElementsMenu = NULL;
119  wxLocale* m_locale = NULL;
120  PropertiesData* m_generalProperties = NULL;
121 
122  void Init();
123  void EnableCurrentProjectRibbon(bool enable = true);
124  void CreateAddElementsMenu();
125 
126  void OnAddElementsClick(wxCommandEvent& event);
127 };
128 
129 #endif // MAINFRAME_H
General and simulation data manager.
+Go to the documentation of this file.
1 /*
2  * Copyright (C) 2017 Thales Lima Oliveira <thales@ufu.br>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program. If not, see <https://www.gnu.org/licenses/>.
16  */
17 
18 #ifndef MAINFRAME_H
19 #define MAINFRAME_H
20 
21 #include <wx/menu.h>
22 #include <wx/msgdlg.h>
23 #include <wx/filedlg.h>
24 #include <wx/glcanvas.h>
25 
26 #include "MainFrameBase.h"
27 
28 class MainFrameBase;
30 class Workspace;
31 class FileHanding;
34 class PropertiesData;
35 class ChartView;
36 class DataReport;
37 class AboutForm;
38 
39 enum {
40  ID_ADDMENU_BUS = 20000,
41  ID_ADDMENU_LINE,
42  ID_ADDMENU_TRANSFORMER,
43  ID_ADDMENU_GENERATOR,
44  ID_ADDMENU_LOAD,
45  ID_ADDMENU_CAPACITOR,
46  ID_ADDMENU_INDUCTOR,
47  ID_ADDMENU_INDMOTOR,
48  ID_ADDMENU_SYNCCOMP
49 };
50 
58 class MainFrame : public MainFrameBase
59 {
60  public:
65  MainFrame();
72  MainFrame(wxWindow* parent, wxLocale* locale, PropertiesData* initProperties, wxString openPath = "");
73 
77  ~MainFrame();
78 
79  protected:
80  virtual void OnGeneralSettingsClick(wxRibbonButtonBarEvent& event);
81  virtual void OnSimulationSettingsClick(wxRibbonButtonBarEvent& event);
82  virtual void OnRotClockClick(wxRibbonButtonBarEvent& event);
83  virtual void OnRotCounterClockClick(wxRibbonButtonBarEvent& event);
84  virtual void NotebookPageClosed(wxAuiNotebookEvent& event);
85  virtual void NotebookPageClosing(wxAuiNotebookEvent& event);
86  virtual void OnAboutClick(wxRibbonButtonBarEvent& event);
87  virtual void OnAddElementDropdown(wxRibbonButtonBarEvent& event);
88  virtual void OnChartsClick(wxRibbonButtonBarEvent& event);
89  virtual void OnCloseClick(wxRibbonButtonBarEvent& event);
90  virtual void OnCopyClick(wxRibbonButtonBarEvent& event);
91  virtual void OnDataReportClick(wxRibbonButtonBarEvent& event);
92  virtual void OnDeleteClick(wxRibbonButtonBarEvent& event);
93  virtual void OnDisableSolutionClick(wxRibbonButtonBarEvent& event);
94  virtual void OnDragClick(wxRibbonButtonBarEvent& event);
95  virtual void OnEnableSolutionClick(wxRibbonButtonBarEvent& event);
96  virtual void OnExitClick(wxRibbonButtonBarEvent& event) { this->Close(); };
97  virtual void OnExpImpClick(wxRibbonButtonBarEvent& event);
98  virtual void OnFaultClick(wxRibbonButtonBarEvent& event);
99  virtual void OnFitClick(wxRibbonButtonBarEvent& event);
100  virtual void OnMoveClick(wxRibbonButtonBarEvent& event);
101  virtual void OnOpenClick(wxRibbonButtonBarEvent& event);
102  virtual void OnPSPGuideClick(wxRibbonButtonBarEvent& event);
103  virtual void OnPasteClick(wxRibbonButtonBarEvent& event);
104  virtual void OnPowerFlowClick(wxRibbonButtonBarEvent& event);
105  virtual void OnRedoClick(wxRibbonButtonBarEvent& event);
106  virtual void OnResetVoltagesClick(wxRibbonButtonBarEvent& event);
107  virtual void OnRunStabilityClick(wxRibbonButtonBarEvent& event);
108  virtual void OnSCPowerClick(wxRibbonButtonBarEvent& event);
109  virtual void OnSaveAsClick(wxRibbonButtonBarEvent& event);
110  virtual void OnSaveClick(wxRibbonButtonBarEvent& event);
111  virtual void OnSnapshotClick(wxRibbonButtonBarEvent& event);
112  virtual void OnUndoClick(wxRibbonButtonBarEvent& event);
113  virtual void OnNewClick(wxRibbonButtonBarEvent& event);
114 
115  std::vector<Workspace*> m_workspaceList;
116  int m_projectNumber = 1;
117 
118  wxRibbonMetroArtProvider* m_artMetro = NULL;
119  wxMenu* m_addElementsMenu = NULL;
120  wxLocale* m_locale = NULL;
121  PropertiesData* m_generalProperties = NULL;
122  wxGLContext* m_sharedGLContext = NULL;
123 
124  void Init();
125  void EnableCurrentProjectRibbon(bool enable = true);
126  void CreateAddElementsMenu();
127 
128  void OnAddElementsClick(wxCommandEvent& event);
129 };
130 
131 #endif // MAINFRAME_H
General and simulation data manager.
-
~MainFrame()
Default destructor.
Definition: MainFrame.cpp:69
+
~MainFrame()
Default destructor.
Definition: MainFrame.cpp:70
MainFrame()
Default constructor.
Definition: MainFrame.cpp:38
Save and opens the projects created on disk.
Definition: FileHanding.h:43
Form to edit the software&#39;s general data.
-
Main frame of the program. This class manage the ribbon menu and the notebook behavior.
Definition: MainFrame.h:57
+
Main frame of the program. This class manage the ribbon menu and the notebook behavior.
Definition: MainFrame.h:58
This class is responsible to manage the charts generated in the transient electromechanical studies...
Definition: ChartView.h:40
Form to edit the simulation data.
diff --git a/docs/doxygen/html/_math_operation_8cpp_source.html b/docs/doxygen/html/_math_operation_8cpp_source.html new file mode 100644 index 0000000..8d2f113 --- /dev/null +++ b/docs/doxygen/html/_math_operation_8cpp_source.html @@ -0,0 +1,109 @@ + + + + + + + + + +Project/MathOperation.cpp Source File + + + + + + + + + + + + + + + +
+
+
+ + + + + +
+
+ + + + + + + + +
+ +
+
+
+ +
+ +
+
+ + +
+ +
+ +
+
+
MathOperation.cpp
+
+
+
1 /*
2  * Copyright (C) 2017 Thales Lima Oliveira <thales@ufu.br>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program. If not, see <https://www.gnu.org/licenses/>.
16  */
17 
18 #include "MathOperation.h"
19 #include "ConnectionLine.h"
20 
21 MathOperation::MathOperation(int id) : ControlElement(id)
22 {
23  m_width = m_height = 36.0;
24  Node* nodeIn1 = new Node(m_position + wxPoint2DDouble(-18, -9), Node::NODE_IN, m_borderSize);
25  nodeIn1->StartMove(m_position);
26  Node* nodeIn2 = new Node(m_position + wxPoint2DDouble(-18, 9), Node::NODE_IN, m_borderSize);
27  nodeIn2->StartMove(m_position);
28  Node* nodeOut = new Node(m_position + wxPoint2DDouble(18, 0), Node::NODE_OUT, m_borderSize);
29  nodeOut->SetAngle(180.0);
30  nodeOut->StartMove(m_position);
31  m_nodeList.push_back(nodeIn1);
32  m_nodeList.push_back(nodeIn2);
33  m_nodeList.push_back(nodeOut);
34 }
35 
36 MathOperation::~MathOperation() {}
37 void MathOperation::Draw(wxPoint2DDouble translation, double scale) const
38 {
39  glLineWidth(1.0);
40  if(m_selected) {
41  glColor4dv(m_selectionColour.GetRGBA());
42  double borderSize = (m_borderSize * 2.0 + 1.0) / scale;
43  DrawRectangle(m_position, m_width + borderSize, m_height + borderSize);
44  }
45  glColor4d(1.0, 1.0, 1.0, 1.0);
46  DrawRectangle(m_position, m_width, m_height);
47  glColor4d(0.0, 0.0, 0.0, 1.0);
48  DrawRectangle(m_position, m_width, m_height, GL_LINE_LOOP);
49 
50  // Draw personalized element symbol.
51  DrawSymbol();
52 
53  glColor4d(0.0, 0.0, 0.0, 1.0);
54  DrawNodes();
55 }
56 
57 void MathOperation::Rotate(bool clockwise)
58 {
59  if(clockwise)
60  m_angle += 90.0;
61  else
62  m_angle -= 90.0;
63  if(m_angle >= 360.0)
64  m_angle = 0.0;
65  else if(m_angle < 0)
66  m_angle = 270.0;
67 
68  UpdatePoints();
69 
70  for(auto it = m_nodeList.begin(), itEnd = m_nodeList.end(); it != itEnd; ++it) {
71  Node* node = *it;
72  node->Rotate(clockwise);
73  }
74 }
75 
76 void MathOperation::UpdatePoints()
77 {
78  if(m_angle == 0.0) {
79  m_nodeList[0]->SetPosition(m_position + wxPoint2DDouble(-18, -9));
80  m_nodeList[1]->SetPosition(m_position + wxPoint2DDouble(-18, 9));
81  m_nodeList[2]->SetPosition(m_position + wxPoint2DDouble(18, 0));
82  } else if(m_angle == 90.0) {
83  m_nodeList[0]->SetPosition(m_position + wxPoint2DDouble(9, -18));
84  m_nodeList[1]->SetPosition(m_position + wxPoint2DDouble(-9, -18));
85  m_nodeList[2]->SetPosition(m_position + wxPoint2DDouble(0, 18));
86  } else if(m_angle == 180.0) {
87  m_nodeList[0]->SetPosition(m_position + wxPoint2DDouble(18, 9));
88  m_nodeList[1]->SetPosition(m_position + wxPoint2DDouble(18, -9));
89  m_nodeList[2]->SetPosition(m_position + wxPoint2DDouble(-18, 0));
90  } else if(m_angle == 270.0) {
91  m_nodeList[0]->SetPosition(m_position + wxPoint2DDouble(-9, 18));
92  m_nodeList[1]->SetPosition(m_position + wxPoint2DDouble(9, 18));
93  m_nodeList[2]->SetPosition(m_position + wxPoint2DDouble(0, -18));
94  }
95 }
Node of a control element. This class manages the user interaction with the connection and control el...
+ + +
virtual void Rotate(bool clockwise=true)
Rotate the element.
+
virtual void Draw(wxPoint2DDouble translation, double scale) const
Draw the element.
+ +
+
+ + + + diff --git a/docs/doxygen/html/_math_operation_8h.html b/docs/doxygen/html/_math_operation_8h.html new file mode 100644 index 0000000..3ebeefc --- /dev/null +++ b/docs/doxygen/html/_math_operation_8h.html @@ -0,0 +1,115 @@ + + + + + + + + + +Project/MathOperation.h File Reference + + + + + + + + + + + + + + + +
+
+ + + + + + +
+
+ + + + + + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+ +
+ +
+ +
+
MathOperation.h File Reference
+
+
+
#include "ControlElement.h"
+
+

Go to the source code of this file.

+ + + + + +

+Classes

class  MathOperation
 Abstract class that define the general behavior of math operation control block. More...
 
+
+
+ + + + diff --git a/docs/doxygen/html/_math_operation_8h_source.html b/docs/doxygen/html/_math_operation_8h_source.html new file mode 100644 index 0000000..28b3981 --- /dev/null +++ b/docs/doxygen/html/_math_operation_8h_source.html @@ -0,0 +1,113 @@ + + + + + + + + + +Project/MathOperation.h Source File + + + + + + + + + + + + + + + +
+
+ + + + + + +
+
+ + + + + + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+ +
+ +
+
+
MathOperation.h
+
+
+Go to the documentation of this file.
1 /*
2  * Copyright (C) 2017 Thales Lima Oliveira <thales@ufu.br>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program. If not, see <https://www.gnu.org/licenses/>.
16  */
17 
18 #ifndef MATHOPERATION_H
19 #define MATHOPERATION_H
20 
21 #include "ControlElement.h"
22 
23 class ConnectionLine;
24 
33 {
34  public:
35  MathOperation(int id);
36  ~MathOperation();
37 
38  virtual void Draw(wxPoint2DDouble translation, double scale) const;
39  virtual void DrawSymbol() const {}
40  virtual bool Contains(wxPoint2DDouble position) const { return m_rect.Contains(position); }
41  virtual bool Intersects(wxRect2DDouble rect) const { return m_rect.Intersects(rect); }
42  virtual bool ShowForm(wxWindow* parent, Element* element) { return false; }
43  virtual void Rotate(bool clockwise = true);
44 
45  virtual void UpdatePoints();
46 };
47 
48 #endif // MATHOPERATION_H
Base class of all elements of the program. This class is responsible for manage graphical and his dat...
Definition: Element.h:113
+
virtual bool Intersects(wxRect2DDouble rect) const
Check if the element&#39;s rect intersects other rect.
Definition: MathOperation.h:41
+
virtual bool Contains(wxPoint2DDouble position) const
Checks if the element contains a position.
Definition: MathOperation.h:40
+
virtual void Rotate(bool clockwise=true)
Rotate the element.
+
Abstract class that define the general behavior of math operation control block.
Definition: MathOperation.h:32
+
virtual void Draw(wxPoint2DDouble translation, double scale) const
Draw the element.
+
Connection between two control elements or other connection line and an element.
+
Base class of a control element. Provide general methods to other control classes.
+ +
virtual bool ShowForm(wxWindow *parent, Element *element)
Show element data form.
Definition: MathOperation.h:42
+
+
+ + + + diff --git a/docs/doxygen/html/_multiplier_8cpp_source.html b/docs/doxygen/html/_multiplier_8cpp_source.html index ca5ebdd..cb88e21 100644 --- a/docs/doxygen/html/_multiplier_8cpp_source.html +++ b/docs/doxygen/html/_multiplier_8cpp_source.html @@ -88,16 +88,15 @@ $(document).ready(function(){initNavTree('_multiplier_8cpp_source.html','');});
Multiplier.cpp
-
1 /*
2  * Copyright (C) 2017 Thales Lima Oliveira <thales@ufu.br>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program. If not, see <https://www.gnu.org/licenses/>.
16  */
17 
18 #include "Multiplier.h"
19 #include "ConnectionLine.h"
20 
21 Multiplier::Multiplier(int id) : ControlElement(id)
22 {
23  m_width = m_height = 36.0;
24  Node* nodeIn1 = new Node(m_position + wxPoint2DDouble(-18, -9), Node::NODE_IN, m_borderSize);
25  nodeIn1->StartMove(m_position);
26  Node* nodeIn2 = new Node(m_position + wxPoint2DDouble(-18, 9), Node::NODE_IN, m_borderSize);
27  nodeIn2->StartMove(m_position);
28  Node* nodeOut = new Node(m_position + wxPoint2DDouble(18, 0), Node::NODE_OUT, m_borderSize);
29  nodeOut->SetAngle(180.0);
30  nodeOut->StartMove(m_position);
31  m_nodeList.push_back(nodeIn1);
32  m_nodeList.push_back(nodeIn2);
33  m_nodeList.push_back(nodeOut);
34 }
35 
36 Multiplier::~Multiplier() {}
37 void Multiplier::Draw(wxPoint2DDouble translation, double scale) const
38 {
39  glLineWidth(1.0);
40  if(m_selected) {
41  glColor4dv(m_selectionColour.GetRGBA());
42  double borderSize = (m_borderSize * 2.0 + 1.0) / scale;
43  DrawRectangle(m_position, m_width + borderSize, m_height + borderSize);
44  }
45  glColor4d(1.0, 1.0, 1.0, 1.0);
46  DrawRectangle(m_position, m_width, m_height);
47  glColor4d(0.0, 0.0, 0.0, 1.0);
48  DrawRectangle(m_position, m_width, m_height, GL_LINE_LOOP);
49 
50  // Plot x.
51  glLineWidth(2.0);
52  std::vector<wxPoint2DDouble> xSymbol;
53  xSymbol.push_back(m_position + wxPoint2DDouble(-5, -5));
54  xSymbol.push_back(m_position + wxPoint2DDouble(5, 5));
55  xSymbol.push_back(m_position + wxPoint2DDouble(-5, 5));
56  xSymbol.push_back(m_position + wxPoint2DDouble(5, -5));
57  glColor4d(0.0, 0.3, 1.0, 1.0);
58  DrawLine(xSymbol, GL_LINES);
59 
60  glColor4d(0.0, 0.0, 0.0, 1.0);
61  DrawNodes();
62 }
63 
64 void Multiplier::Rotate(bool clockwise)
65 {
66  if(clockwise)
67  m_angle += 90.0;
68  else
69  m_angle -= 90.0;
70  if(m_angle >= 360.0)
71  m_angle = 0.0;
72  else if(m_angle < 0)
73  m_angle = 270.0;
74 
75  UpdatePoints();
76 
77  for(auto it = m_nodeList.begin(), itEnd = m_nodeList.end(); it != itEnd; ++it) {
78  Node* node = *it;
79  node->Rotate(clockwise);
80  }
81 }
82 
83 void Multiplier::UpdatePoints()
84 {
85  if(m_angle == 0.0) {
86  m_nodeList[0]->SetPosition(m_position + wxPoint2DDouble(-18, -9));
87  m_nodeList[1]->SetPosition(m_position + wxPoint2DDouble(-18, 9));
88  m_nodeList[2]->SetPosition(m_position + wxPoint2DDouble(18, 0));
89  } else if(m_angle == 90.0) {
90  m_nodeList[0]->SetPosition(m_position + wxPoint2DDouble(9, -18));
91  m_nodeList[1]->SetPosition(m_position + wxPoint2DDouble(-9, -18));
92  m_nodeList[2]->SetPosition(m_position + wxPoint2DDouble(0, 18));
93  } else if(m_angle == 180.0) {
94  m_nodeList[0]->SetPosition(m_position + wxPoint2DDouble(18, 9));
95  m_nodeList[1]->SetPosition(m_position + wxPoint2DDouble(18, -9));
96  m_nodeList[2]->SetPosition(m_position + wxPoint2DDouble(-18, 0));
97  } else if(m_angle == 270.0) {
98  m_nodeList[0]->SetPosition(m_position + wxPoint2DDouble(-9, 18));
99  m_nodeList[1]->SetPosition(m_position + wxPoint2DDouble(9, 18));
100  m_nodeList[2]->SetPosition(m_position + wxPoint2DDouble(0, -18));
101  }
102 }
103 
104 bool Multiplier::Solve(double input, double timeStep)
105 {
106  std::vector<double> inputVector;
107  for(auto itN = m_nodeList.begin(), itNEnd = m_nodeList.end(); itN != itNEnd; ++itN) {
108  Node* node = *itN;
109  if(node->GetNodeType() != Node::NODE_OUT) {
110  if(!node->IsConnected()) {
111  inputVector.push_back(1.0);
112  } else {
113  for(auto itC = m_childList.begin(), itCEnd = m_childList.end(); itC != itCEnd; ++itC) {
114  ConnectionLine* cLine = static_cast<ConnectionLine*>(*itC);
115  auto nodeList = cLine->GetNodeList();
116  for(auto itCN = nodeList.begin(), itCNEnd = nodeList.end(); itCN != itCNEnd; ++itCN) {
117  Node* childNode = *itCN;
118  if(childNode == node) {
119  inputVector.push_back(cLine->GetValue());
120  break;
121  }
122  }
123  }
124  }
125  }
126  }
127 
128  m_output = 1.0;
129  for(unsigned int i = 0; i < inputVector.size(); ++i) {
130  m_output *= inputVector[i];
131  }
132 
133  return true;
134 }
135 
137 {
138  Multiplier* copy = new Multiplier(m_elementID);
139  *copy = *this;
140  return copy;
141 }
Multiplies two inputs.
Definition: Multiplier.h:32
+
1 /*
2  * Copyright (C) 2017 Thales Lima Oliveira <thales@ufu.br>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program. If not, see <https://www.gnu.org/licenses/>.
16  */
17 
18 #include "Multiplier.h"
19 #include "ConnectionLine.h"
20 
21 Multiplier::Multiplier(int id) : MathOperation(id) {}
22 Multiplier::~Multiplier() {}
23 void Multiplier::DrawSymbol() const
24 {
25  // Plot x.
26  glLineWidth(2.0);
27  std::vector<wxPoint2DDouble> xSymbol;
28  xSymbol.push_back(m_position + wxPoint2DDouble(-5, -5));
29  xSymbol.push_back(m_position + wxPoint2DDouble(5, 5));
30  xSymbol.push_back(m_position + wxPoint2DDouble(-5, 5));
31  xSymbol.push_back(m_position + wxPoint2DDouble(5, -5));
32  glColor4d(0.0, 0.3, 1.0, 1.0);
33  DrawLine(xSymbol, GL_LINES);
34 }
35 
36 bool Multiplier::Solve(double input, double timeStep)
37 {
38  std::vector<double> inputVector;
39  for(auto itN = m_nodeList.begin(), itNEnd = m_nodeList.end(); itN != itNEnd; ++itN) {
40  Node* node = *itN;
41  if(node->GetNodeType() != Node::NODE_OUT) {
42  if(!node->IsConnected()) {
43  inputVector.push_back(1.0);
44  } else {
45  for(auto itC = m_childList.begin(), itCEnd = m_childList.end(); itC != itCEnd; ++itC) {
46  ConnectionLine* cLine = static_cast<ConnectionLine*>(*itC);
47  auto nodeList = cLine->GetNodeList();
48  for(auto itCN = nodeList.begin(), itCNEnd = nodeList.end(); itCN != itCNEnd; ++itCN) {
49  Node* childNode = *itCN;
50  if(childNode == node) {
51  inputVector.push_back(cLine->GetValue());
52  break;
53  }
54  }
55  }
56  }
57  }
58  }
59 
60  m_output = 1.0;
61  for(unsigned int i = 0; i < inputVector.size(); ++i) {
62  m_output *= inputVector[i];
63  }
64 
65  return true;
66 }
67 
69 {
70  Multiplier* copy = new Multiplier(m_elementID);
71  *copy = *this;
72  return copy;
73 }
Multiplies two inputs.
Definition: Multiplier.h:32
Base class of all elements of the program. This class is responsible for manage graphical and his dat...
Definition: Element.h:113
-
virtual void Rotate(bool clockwise=true)
Rotate the element.
Definition: Multiplier.cpp:64
+
virtual void DrawLine(std::vector< wxPoint2DDouble > points, GLenum mode=GL_LINE_STRIP) const
Draw line.
Definition: Element.cpp:89
Node of a control element. This class manages the user interaction with the connection and control el...
-
virtual void Draw(wxPoint2DDouble translation, double scale) const
Draw the element.
Definition: Multiplier.cpp:37
+
Abstract class that define the general behavior of math operation control block.
Definition: MathOperation.h:32
Connection between two control elements or other connection line and an element.
- -
virtual Element * GetCopy()
Get a the element copy.
Definition: Multiplier.cpp:136
+
virtual Element * GetCopy()
Get a the element copy.
Definition: Multiplier.cpp:68
diff --git a/docs/doxygen/html/_multiplier_8h.html b/docs/doxygen/html/_multiplier_8h.html index cddba01..1d34e78 100644 --- a/docs/doxygen/html/_multiplier_8h.html +++ b/docs/doxygen/html/_multiplier_8h.html @@ -90,7 +90,7 @@ $(document).ready(function(){initNavTree('_multiplier_8h.html','');});
Multiplier.h File Reference
-
#include "ControlElement.h"
+
#include "MathOperation.h"

Go to the source code of this file.

diff --git a/docs/doxygen/html/_multiplier_8h_source.html b/docs/doxygen/html/_multiplier_8h_source.html index befa79b..c2ad57d 100644 --- a/docs/doxygen/html/_multiplier_8h_source.html +++ b/docs/doxygen/html/_multiplier_8h_source.html @@ -88,17 +88,12 @@ $(document).ready(function(){initNavTree('_multiplier_8h_source.html','');});
Multiplier.h
-Go to the documentation of this file.
1 /*
2  * Copyright (C) 2017 Thales Lima Oliveira <thales@ufu.br>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program. If not, see <https://www.gnu.org/licenses/>.
16  */
17 
18 #ifndef MULTIPLIER_H
19 #define MULTIPLIER_H
20 
21 #include "ControlElement.h"
22 
23 class ConnectionLine;
24 
32 class Multiplier : public ControlElement
33 {
34  public:
35  Multiplier(int id);
36  ~Multiplier();
37 
38  virtual void Draw(wxPoint2DDouble translation, double scale) const;
39  virtual bool Contains(wxPoint2DDouble position) const { return m_rect.Contains(position); }
40  virtual bool Intersects(wxRect2DDouble rect) const { return m_rect.Intersects(rect); }
41  virtual bool ShowForm(wxWindow* parent, Element* element) { return false; }
42  virtual void Rotate(bool clockwise = true);
43 
44  virtual void UpdatePoints();
45 
46  virtual bool Solve(double input, double timeStep);
47 
48  virtual Element* GetCopy();
49 };
50 
51 #endif // MULTIPLIER_H
Multiplies two inputs.
Definition: Multiplier.h:32
+Go to the documentation of this file.
1 /*
2  * Copyright (C) 2017 Thales Lima Oliveira <thales@ufu.br>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program. If not, see <https://www.gnu.org/licenses/>.
16  */
17 
18 #ifndef MULTIPLIER_H
19 #define MULTIPLIER_H
20 
21 #include "MathOperation.h"
22 
23 class ConnectionLine;
24 
32 class Multiplier : public MathOperation
33 {
34  public:
35  Multiplier(int id);
36  ~Multiplier();
37 
38  virtual void DrawSymbol() const;
39  virtual bool Solve(double input, double timeStep);
40  virtual Element* GetCopy();
41 };
42 
43 #endif // MULTIPLIER_H
Multiplies two inputs.
Definition: Multiplier.h:32
Base class of all elements of the program. This class is responsible for manage graphical and his dat...
Definition: Element.h:113
-
virtual void Rotate(bool clockwise=true)
Rotate the element.
Definition: Multiplier.cpp:64
-
virtual bool ShowForm(wxWindow *parent, Element *element)
Show element data form.
Definition: Multiplier.h:41
-
virtual bool Contains(wxPoint2DDouble position) const
Checks if the element contains a position.
Definition: Multiplier.h:39
-
virtual void Draw(wxPoint2DDouble translation, double scale) const
Draw the element.
Definition: Multiplier.cpp:37
+ +
Abstract class that define the general behavior of math operation control block.
Definition: MathOperation.h:32
Connection between two control elements or other connection line and an element.
-
Base class of a control element. Provide general methods to other control classes.
-
virtual bool Intersects(wxRect2DDouble rect) const
Check if the element&#39;s rect intersects other rect.
Definition: Multiplier.h:40
- -
virtual Element * GetCopy()
Get a the element copy.
Definition: Multiplier.cpp:136
+
virtual Element * GetCopy()
Get a the element copy.
Definition: Multiplier.cpp:68
diff --git a/docs/doxygen/html/_open_g_l_text_8cpp_source.html b/docs/doxygen/html/_open_g_l_text_8cpp_source.html new file mode 100644 index 0000000..0d57066 --- /dev/null +++ b/docs/doxygen/html/_open_g_l_text_8cpp_source.html @@ -0,0 +1,105 @@ + + + + + + + + + +Project/OpenGLText.cpp Source File + + + + + + + + + + + + + + + +
+
+
+ + + + + +
+
+ + + + + + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+ +
+ +
+
+
OpenGLText.cpp
+
+
+
1 /*
2  * Copyright (C) 2017 Thales Lima Oliveira <thales@ufu.br>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program. If not, see <https://www.gnu.org/licenses/>.
16  */
17 
18 #include "OpenGLText.h"
19 #include <wx/log.h>
20 
21 OpenGLText::OpenGLText() { Init(); }
22 OpenGLText::OpenGLText(wxString text)
23 {
24  Init();
25  SetText(text);
26 }
27 
28 OpenGLText::~OpenGLText()
29 {
30  if(m_textureID) {
31  glDeleteTextures(1, &m_textureID[0]);
32  }
33 }
34 
35 void OpenGLText::Init()
36 {
37  m_textCoord = new wxPoint2DDouble[2];
38  m_textCoord[0] = wxPoint2DDouble(0, 1);
39  m_textCoord[1] = wxPoint2DDouble(1, 0);
40 }
41 
42 void OpenGLText::Draw(wxPoint2DDouble position) const
43 {
44  if(m_textureID) {
45  glPushMatrix();
46 
47  glTranslated(position.m_x - m_bitmapSize.GetWidth() / 2, position.m_y - m_bitmapSize.GetHeight() / 2, 0);
48 
49  glEnable(GL_TEXTURE_2D);
50  glBindTexture(GL_TEXTURE_2D, m_textureID[0]);
51 
52  glBegin(GL_QUADS);
53 
54  glTexCoord2f(m_textCoord[0].m_x, m_textCoord[0].m_y);
55  glVertex2f(0, 0);
56 
57  glTexCoord2f(m_textCoord[1].m_x, m_textCoord[0].m_y);
58  glVertex2f(m_bitmapSize.GetWidth(), 0);
59 
60  glTexCoord2f(m_textCoord[1].m_x, m_textCoord[1].m_y);
61  glVertex2f(m_bitmapSize.GetWidth(), m_bitmapSize.GetHeight());
62 
63  glTexCoord2f(m_textCoord[0].m_x, m_textCoord[1].m_y);
64  glVertex2f(0, m_bitmapSize.GetHeight());
65  glEnd();
66 
67  glDisable(GL_TEXTURE_2D);
68 
69  glPopMatrix();
70  }
71 }
72 
73 void OpenGLText::SetText(wxString text)
74 {
75  m_text = text;
76  TextToBitmap();
77  LoadTextTexture();
78 }
79 
80 int OpenGLText::RoundToPowerOfTwo(int value, int min)
81 {
82  //[Ref] https://stackoverflow.com/questions/466204/rounding-up-to-next-power-of-2
83  double baseOfTwo = std::log(static_cast<double>(value)) / std::log(2.0);
84  int powerOfTwo = static_cast<int>(std::pow(2.0, static_cast<int>(std::ceil(baseOfTwo))));
85  return std::max(min, powerOfTwo);
86 }
87 
88 void OpenGLText::TextToBitmap()
89 {
90  wxFont font = wxFont(m_fontSize, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL);
91 
92  wxMemoryDC memDC;
93  memDC.SetFont(font);
94  m_bitmapSize = memDC.GetTextExtent(m_text);
95 
96  int p2w = RoundToPowerOfTwo(m_bitmapSize.GetWidth());
97  int p2h = RoundToPowerOfTwo(m_bitmapSize.GetHeight());
98 
99  m_bitmap = wxBitmap(p2w, p2h);
100 
101  memDC.SelectObject(m_bitmap);
102  memDC.SetBackground(*wxWHITE_BRUSH);
103  memDC.Clear();
104  memDC.DrawText(m_text, 0, 0);
105 
106  m_textCoord[1].m_x = static_cast<double>(m_bitmapSize.GetWidth()) / static_cast<double>(p2w);
107  m_textCoord[1].m_y = 1.0 - static_cast<double>(m_bitmapSize.GetHeight()) / static_cast<double>(p2h);
108 }
109 
110 void OpenGLText::LoadTextTexture()
111 {
112  if(m_textureID) glDeleteTextures(1, &m_textureID[0]);
113  m_textureID = new GLuint[1];
114  glGenTextures(1, &m_textureID[0]);
115 
116  glBindTexture(GL_TEXTURE_2D, *m_textureID);
117 
118  wxImage img = m_bitmap.ConvertToImage();
119 
120  glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
121 
122  const int w = img.GetWidth(), h = img.GetHeight();
123  int bytesPerPixel = 4;
124  GLubyte* bitmapData = img.GetData();
125  int imageSize = w * h * bytesPerPixel;
126  GLubyte* imageData = new GLubyte[imageSize];
127  int revVal = h - 1;
128 
129  for(int y = 0; y < h; y++) {
130  for(int x = 0; x < w; x++) {
131  imageData[(x + y * w) * bytesPerPixel + 0] = 255;
132  imageData[(x + y * w) * bytesPerPixel + 1] = 255;
133  imageData[(x + y * w) * bytesPerPixel + 2] = 255;
134 
135  // alpha
136  imageData[(x + y * w) * bytesPerPixel + 3] = 255 - bitmapData[(x + (revVal - y) * w) * 3];
137  }
138  }
139 
140  glTexImage2D(GL_TEXTURE_2D, 0, bytesPerPixel, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, imageData);
141  delete imageData;
142 
143  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
144  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
145 
146  glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
147  glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
148 }
149 
150 OpenGLText* OpenGLText::GetCopy()
151 {
152  OpenGLText* copy = new OpenGLText();
153  *copy = *this;
154  copy->m_textureID = NULL;
155  copy->m_bitmapSize = wxSize(0, 0);
156  copy->m_bitmap = wxNullBitmap;
157  copy->SetText(copy->m_text);
158  return copy;
159 }
160 
161 bool OpenGLText::IsTextureOK()
162 {
163  if(m_textureID) {
164  if(glIsTexture(m_textureID[0]) == GL_TRUE) return true;
165  }
166  return false;
167 }
+
Class to draw text on OpenGL using wxWidgets.
Definition: OpenGLText.h:31
+
+
+ + + + diff --git a/docs/doxygen/html/_open_g_l_text_8h.html b/docs/doxygen/html/_open_g_l_text_8h.html new file mode 100644 index 0000000..bfb5807 --- /dev/null +++ b/docs/doxygen/html/_open_g_l_text_8h.html @@ -0,0 +1,116 @@ + + + + + + + + + +Project/OpenGLText.h File Reference + + + + + + + + + + + + + + + +
+
+ + + + + + +
+
+ + + + + + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+ +
+ +
+ +
+
OpenGLText.h File Reference
+
+
+
#include <GL/gl.h>
+#include <wx/dcmemory.h>
+
+

Go to the source code of this file.

+ + + + + +

+Classes

class  OpenGLText
 Class to draw text on OpenGL using wxWidgets. More...
 
+
+
+ + + + diff --git a/docs/doxygen/html/_open_g_l_text_8h_source.html b/docs/doxygen/html/_open_g_l_text_8h_source.html new file mode 100644 index 0000000..5a066e2 --- /dev/null +++ b/docs/doxygen/html/_open_g_l_text_8h_source.html @@ -0,0 +1,104 @@ + + + + + + + + + +Project/OpenGLText.h Source File + + + + + + + + + + + + + + + +
+
+ + + + + + +
+
+ + + + + + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+ +
+ +
+
+
OpenGLText.h
+
+
+Go to the documentation of this file.
1 /*
2  * Copyright (C) 2017 Thales Lima Oliveira <thales@ufu.br>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program. If not, see <https://www.gnu.org/licenses/>.
16  */
17 
18 #ifndef OPENGLTEXT_H
19 #define OPENGLTEXT_H
20 
21 #include <GL/gl.h>
22 #include <wx/dcmemory.h>
23 
32 {
33  public:
34  OpenGLText();
35  OpenGLText(wxString text);
36  virtual ~OpenGLText();
37 
38  virtual void Draw(wxPoint2DDouble position) const;
39  virtual OpenGLText* GetCopy();
40 
41  virtual void SetText(wxString text);
42  virtual wxString GetText() const { return m_text; }
43  virtual int GetWidth() const { return m_bitmapSize.GetWidth(); }
44  virtual int GetHeight() const { return m_bitmapSize.GetHeight(); }
45  virtual bool IsTextureOK();
46  protected:
47  void Init();
48  int RoundToPowerOfTwo(int value, int min = 32);
49  void TextToBitmap();
50  void LoadTextTexture();
51 
52  wxString m_text = _("Text");
53  int m_fontSize = 10;
54 
55  wxBitmap m_bitmap = wxNullBitmap;
56  wxSize m_bitmapSize = wxSize(0, 0);
57  wxPoint2DDouble* m_textCoord = NULL;
58  GLuint* m_textureID = NULL;
59 };
60 
61 #endif // OPENGLTEXT_H
Class to draw text on OpenGL using wxWidgets.
Definition: OpenGLText.h:31
+
+
+ + + + diff --git a/docs/doxygen/html/_power_flow_8cpp_source.html b/docs/doxygen/html/_power_flow_8cpp_source.html index d0931d7..7c25975 100644 --- a/docs/doxygen/html/_power_flow_8cpp_source.html +++ b/docs/doxygen/html/_power_flow_8cpp_source.html @@ -95,7 +95,7 @@ $(document).ready(function(){initNavTree('_power_flow_8cpp_source.html','');});
Definition: Bus.h:24
Node for power elements. All others power elements are connected through this.
Definition: Bus.h:69
bool IsOnline() const
Checks if the element is online or offline.
Definition: Element.h:227
-
Loas shunt power element.
Definition: Load.h:42
+
Loas shunt power element.
Definition: Load.h:73
Definition: Load.h:26
Synchronous motor (synchronous compensator) power element.
Definition: SyncMotor.h:134
diff --git a/docs/doxygen/html/_properties_data_8h_source.html b/docs/doxygen/html/_properties_data_8h_source.html index 10b41d3..29c37b7 100644 --- a/docs/doxygen/html/_properties_data_8h_source.html +++ b/docs/doxygen/html/_properties_data_8h_source.html @@ -88,13 +88,13 @@ $(document).ready(function(){initNavTree('_properties_data_8h_source.html','');}
PropertiesData.h
-Go to the documentation of this file.
1 /*
2  * Copyright (C) 2017 Thales Lima Oliveira <thales@ufu.br>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program. If not, see <https://www.gnu.org/licenses/>.
16  */
17 
18 #ifndef PROPERTIESDATA_H
19 #define PROPERTIESDATA_H
20 
21 #include "wx/language.h"
22 #include "Element.h"
23 #include "PowerElement.h"
24 
25 enum PowerFlowMethod { GAUSS_SEIDEL = 0, NEWTON_RAPHSON };
26 enum GUITheme { THEME_LIGHT = 0, THEME_DARK };
27 
29  // General simulation data
30  double basePower = 100.0;
31  ElectricalUnit basePowerUnit = UNIT_MVA;
32  bool faultAfterPowerFlow = true;
33  bool scPowerAfterPowerFlow = true;
34 
35  // Power flow
36  PowerFlowMethod powerFlowMethod = GAUSS_SEIDEL;
37  double accFator = 1.0;
38  double powerFlowTolerance = 1e-7;
39  int powerFlowMaxIterations = 5000;
40 
41  // Stability
42  double stabilityFrequency = 60.0;
43  double timeStep = 1e-2;
44  double stabilitySimulationTime = 10.0;
45  double stabilityTolerance = 1e-8;
46  int stabilityMaxIterations = 100;
47  int controlTimeStepRatio = 10;
48  double plotTime = 1e-2;
49  bool useCOI = true;
50 };
51 
52 struct GeneralData {
53  wxLanguage language = wxLANGUAGE_ENGLISH;
54  GUITheme theme = THEME_LIGHT;
55 };
56 
65 {
66  public:
68  ~PropertiesData();
69 
70  SimulationData GetSimulationPropertiesData() const { return m_simulData; }
71  void SetSimulationPropertiesData(SimulationData simulationData) { m_simulData = simulationData; }
72  GeneralData GetGeneralPropertiesData() const { return m_genData; }
73  void SetGeneralPropertiesData(GeneralData generalData) { m_genData = generalData; }
74  protected:
75  SimulationData m_simulData;
76  GeneralData m_genData;
77 };
78 
79 #endif // PROPERTIESDATA_H
General and simulation data manager.
+Go to the documentation of this file.
1 /*
2  * Copyright (C) 2017 Thales Lima Oliveira <thales@ufu.br>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program. If not, see <https://www.gnu.org/licenses/>.
16  */
17 
18 #ifndef PROPERTIESDATA_H
19 #define PROPERTIESDATA_H
20 
21 #include "wx/language.h"
22 #include "Element.h"
23 #include "PowerElement.h"
24 
25 enum PowerFlowMethod { GAUSS_SEIDEL = 0, NEWTON_RAPHSON };
26 enum GUITheme { THEME_LIGHT = 0, THEME_DARK };
27 
29  // General simulation data
30  double basePower = 100.0;
31  ElectricalUnit basePowerUnit = UNIT_MVA;
32  bool faultAfterPowerFlow = false;
33  bool scPowerAfterPowerFlow = false;
34 
35  // Power flow
36  PowerFlowMethod powerFlowMethod = GAUSS_SEIDEL;
37  double accFator = 1.0;
38  double powerFlowTolerance = 1e-7;
39  int powerFlowMaxIterations = 5000;
40 
41  // Stability
42  double stabilityFrequency = 60.0;
43  double timeStep = 1e-2;
44  double stabilitySimulationTime = 10.0;
45  double stabilityTolerance = 1e-8;
46  int stabilityMaxIterations = 100;
47  int controlTimeStepRatio = 10;
48  double plotTime = 1e-2;
49  bool useCOI = true;
50 
51  // ZIP load
52  bool useCompLoads = false;
53  double constImpedanceActive = 100.0;
54  double constCurrentActive = 0.0;
55  double constPowerActive = 0.0;
56  double constImpedanceReactive = 100.0;
57  double constCurrentReactive = 0.0;
58  double constPowerReactive = 0.0;
59  double underVoltageConstCurrent = 70.0;
60  double underVoltageConstPower = 70.0;
61 };
62 
63 struct GeneralData {
64  wxLanguage language = wxLANGUAGE_ENGLISH;
65  GUITheme theme = THEME_LIGHT;
66 };
67 
76 {
77  public:
79  ~PropertiesData();
80 
81  SimulationData GetSimulationPropertiesData() const { return m_simulData; }
82  void SetSimulationPropertiesData(SimulationData simulationData) { m_simulData = simulationData; }
83  GeneralData GetGeneralPropertiesData() const { return m_genData; }
84  void SetGeneralPropertiesData(GeneralData generalData) { m_genData = generalData; }
85  protected:
86  SimulationData m_simulData;
87  GeneralData m_genData;
88 };
89 
90 #endif // PROPERTIESDATA_H
General and simulation data manager.
ElectricalUnit
Electrical units.
Definition: PowerElement.h:28
- +
diff --git a/docs/doxygen/html/_properties_form_8cpp_source.html b/docs/doxygen/html/_properties_form_8cpp_source.html index 82cfe31..2214af0 100644 --- a/docs/doxygen/html/_properties_form_8cpp_source.html +++ b/docs/doxygen/html/_properties_form_8cpp_source.html @@ -88,7 +88,7 @@ $(document).ready(function(){initNavTree('_properties_form_8cpp_source.html','')
PropertiesForm.cpp
-
1 // This file was auto-generated by codelite's wxCrafter Plugin
3 // wxCrafter project file: PropertiesForm.wxcp
4 // Do not modify this file by hand!
6 
7 #include "PropertiesForm.h"
8 
9 
10 // Declare the bitmap loading function
11 extern void wxCDAD0InitBitmapResources();
12 
13 static bool bBitmapLoaded = false;
14 
15 
16 GeneralPropertiesFormBase::GeneralPropertiesFormBase(wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style)
17  : wxDialog(parent, id, title, pos, size, style)
18 {
19  if ( !bBitmapLoaded ) {
20  // We need to initialise the default bitmap handler
21  wxXmlResource::Get()->AddHandler(new wxBitmapXmlHandler);
22  wxCDAD0InitBitmapResources();
23  bBitmapLoaded = true;
24  }
25 
26  wxBoxSizer* boxSizer_lvl1_1 = new wxBoxSizer(wxVERTICAL);
27  this->SetSizer(boxSizer_lvl1_1);
28 
29  m_notebook = new wxNotebook(this, wxID_ANY, wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), wxBK_DEFAULT);
30  m_notebook->SetName(wxT("m_notebook"));
31 
32  boxSizer_lvl1_1->Add(m_notebook, 1, wxALL|wxEXPAND, WXC_FROM_DIP(5));
33 
34  m_panelGeneral = new wxPanel(m_notebook, wxID_ANY, wxDefaultPosition, wxDLG_UNIT(m_notebook, wxSize(-1,-1)), wxTAB_TRAVERSAL);
35  m_notebook->AddPage(m_panelGeneral, _("General"), false);
36 
37  wxBoxSizer* boxSizerLvl2_1 = new wxBoxSizer(wxVERTICAL);
38  m_panelGeneral->SetSizer(boxSizerLvl2_1);
39 
40  wxBoxSizer* boxSizerLvl3_1 = new wxBoxSizer(wxVERTICAL);
41 
42  boxSizerLvl2_1->Add(boxSizerLvl3_1, 0, wxEXPAND, WXC_FROM_DIP(5));
43 
44  m_staticTextLanguage = new wxStaticText(m_panelGeneral, wxID_ANY, _("Language"), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
45 
46  boxSizerLvl3_1->Add(m_staticTextLanguage, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
47 
48  wxArrayString m_choiceLanguageArr;
49  m_choiceLanguageArr.Add(wxT("English"));
50  m_choiceLanguageArr.Add(wxT("Portuguese"));
51  m_choiceLanguage = new wxChoice(m_panelGeneral, wxID_ANY, wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), m_choiceLanguageArr, 0);
52  m_choiceLanguage->SetSelection(0);
53 
54  boxSizerLvl3_1->Add(m_choiceLanguage, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxEXPAND, WXC_FROM_DIP(5));
55 
56  wxBoxSizer* boxSizerLvl3_2 = new wxBoxSizer(wxVERTICAL);
57 
58  boxSizerLvl2_1->Add(boxSizerLvl3_2, 0, wxEXPAND, WXC_FROM_DIP(5));
59 
60  m_staticTextTheme = new wxStaticText(m_panelGeneral, wxID_ANY, _("Theme"), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
61 
62  boxSizerLvl3_2->Add(m_staticTextTheme, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
63 
64  wxArrayString m_choiceThemeArr;
65  m_choiceThemeArr.Add(wxT("Light"));
66  m_choiceThemeArr.Add(wxT("Dark"));
67  m_choiceTheme = new wxChoice(m_panelGeneral, wxID_ANY, wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), m_choiceThemeArr, 0);
68  m_choiceTheme->SetSelection(0);
69 
70  boxSizerLvl3_2->Add(m_choiceTheme, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxEXPAND, WXC_FROM_DIP(5));
71 
72  wxBoxSizer* boxSizer_bottonButtons = new wxBoxSizer(wxHORIZONTAL);
73 
74  boxSizer_lvl1_1->Add(boxSizer_bottonButtons, 0, wxALL|wxEXPAND, WXC_FROM_DIP(5));
75 
76  boxSizer_bottonButtons->Add(0, 0, 1, wxALL, WXC_FROM_DIP(5));
77 
78  m_buttonOK = new wxButton(this, wxID_ANY, _("OK"), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
79 
80  boxSizer_bottonButtons->Add(m_buttonOK, 0, wxALL|wxALIGN_RIGHT, WXC_FROM_DIP(5));
81 
82  m_buttonCancel = new wxButton(this, wxID_ANY, _("Cancel"), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
83 
84  boxSizer_bottonButtons->Add(m_buttonCancel, 0, wxALL|wxALIGN_RIGHT, WXC_FROM_DIP(5));
85 
86 
87  #if wxVERSION_NUMBER >= 2900
88  if(!wxPersistenceManager::Get().Find(m_notebook)){
89  wxPersistenceManager::Get().RegisterAndRestore(m_notebook);
90  } else {
91  wxPersistenceManager::Get().Restore(m_notebook);
92  }
93  #endif
94 
95  SetName(wxT("GeneralPropertiesFormBase"));
96  SetSize(-1,-1);
97  if (GetSizer()) {
98  GetSizer()->Fit(this);
99  }
100  if(GetParent()) {
101  CentreOnParent(wxBOTH);
102  } else {
103  CentreOnScreen(wxBOTH);
104  }
105 #if wxVERSION_NUMBER >= 2900
106  if(!wxPersistenceManager::Get().Find(this)) {
107  wxPersistenceManager::Get().RegisterAndRestore(this);
108  } else {
109  wxPersistenceManager::Get().Restore(this);
110  }
111 #endif
112  // Connect events
113  m_buttonOK->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(GeneralPropertiesFormBase::OnButtonOKClick), NULL, this);
114  m_buttonCancel->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(GeneralPropertiesFormBase::OnButtonCancelClick), NULL, this);
115 
116 }
117 
118 GeneralPropertiesFormBase::~GeneralPropertiesFormBase()
119 {
120  m_buttonOK->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(GeneralPropertiesFormBase::OnButtonOKClick), NULL, this);
121  m_buttonCancel->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(GeneralPropertiesFormBase::OnButtonCancelClick), NULL, this);
122 
123 }
124 
125 SimulationsSettingsFormBase::SimulationsSettingsFormBase(wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style)
126  : wxDialog(parent, id, title, pos, size, style)
127 {
128  if ( !bBitmapLoaded ) {
129  // We need to initialise the default bitmap handler
130  wxXmlResource::Get()->AddHandler(new wxBitmapXmlHandler);
131  wxCDAD0InitBitmapResources();
132  bBitmapLoaded = true;
133  }
134 
135  wxBoxSizer* boxSizer_lvl1_1 = new wxBoxSizer(wxVERTICAL);
136  this->SetSizer(boxSizer_lvl1_1);
137 
138  m_notebook = new wxNotebook(this, wxID_ANY, wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), wxBK_DEFAULT);
139  m_notebook->SetName(wxT("m_notebook"));
140 
141  boxSizer_lvl1_1->Add(m_notebook, 1, wxALL|wxEXPAND, WXC_FROM_DIP(5));
142 
143  m_panelGeneral = new wxPanel(m_notebook, wxID_ANY, wxDefaultPosition, wxDLG_UNIT(m_notebook, wxSize(-1,-1)), wxTAB_TRAVERSAL);
144  m_notebook->AddPage(m_panelGeneral, _("General"), false);
145 
146  wxBoxSizer* boxSizerLvl2_1 = new wxBoxSizer(wxVERTICAL);
147  m_panelGeneral->SetSizer(boxSizerLvl2_1);
148 
149  wxBoxSizer* boxSizerLvl3_1 = new wxBoxSizer(wxVERTICAL);
150 
151  boxSizerLvl2_1->Add(boxSizerLvl3_1, 0, wxEXPAND, WXC_FROM_DIP(5));
152 
153  m_staticTextBasePower = new wxStaticText(m_panelGeneral, wxID_ANY, _("Base power"), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
154 
155  boxSizerLvl3_1->Add(m_staticTextBasePower, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
156 
157  wxBoxSizer* boxSizerLvl4_1 = new wxBoxSizer(wxHORIZONTAL);
158 
159  boxSizerLvl3_1->Add(boxSizerLvl4_1, 0, wxEXPAND, WXC_FROM_DIP(5));
160 
161  m_textCtrlbasePower = new wxTextCtrl(m_panelGeneral, wxID_ANY, wxT("100,0"), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
162  #if wxVERSION_NUMBER >= 3000
163  m_textCtrlbasePower->SetHint(wxT(""));
164  #endif
165 
166  boxSizerLvl4_1->Add(m_textCtrlbasePower, 1, wxLEFT|wxRIGHT|wxBOTTOM|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
167 
168  wxArrayString m_choiceBasePowerArr;
169  m_choiceBasePowerArr.Add(wxT("VA"));
170  m_choiceBasePowerArr.Add(wxT("kVA"));
171  m_choiceBasePowerArr.Add(wxT("MVA"));
172  m_choiceBasePower = new wxChoice(m_panelGeneral, wxID_ANY, wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), m_choiceBasePowerArr, 0);
173  m_choiceBasePower->SetSelection(2);
174 
175  boxSizerLvl4_1->Add(m_choiceBasePower, 0, wxLEFT|wxRIGHT|wxBOTTOM, WXC_FROM_DIP(5));
176 
177  wxStaticBoxSizer* staticBoxSizerLvl3_2 = new wxStaticBoxSizer( new wxStaticBox(m_panelGeneral, wxID_ANY, _("Continuous calculation")), wxVERTICAL);
178 
179  boxSizerLvl2_1->Add(staticBoxSizerLvl3_2, 0, wxALL|wxEXPAND, WXC_FROM_DIP(5));
180 
181  m_checkBoxFaultAfterPF = new wxCheckBox(m_panelGeneral, wxID_ANY, _("Calculate fault after power flow"), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
182  m_checkBoxFaultAfterPF->SetValue(true);
183 
184  staticBoxSizerLvl3_2->Add(m_checkBoxFaultAfterPF, 0, wxALL, WXC_FROM_DIP(5));
185 
186  m_checkBoxSCPowerAfterPF = new wxCheckBox(m_panelGeneral, wxID_ANY, _("Calculate short-circuit power after power flow"), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
187  m_checkBoxSCPowerAfterPF->SetValue(true);
188 
189  staticBoxSizerLvl3_2->Add(m_checkBoxSCPowerAfterPF, 0, wxALL, WXC_FROM_DIP(5));
190 
191  m_panelPF = new wxPanel(m_notebook, wxID_ANY, wxDefaultPosition, wxDLG_UNIT(m_notebook, wxSize(-1,-1)), wxTAB_TRAVERSAL);
192  m_notebook->AddPage(m_panelPF, _("Power flow"), false);
193 
194  wxBoxSizer* boxSizerLvl2_2 = new wxBoxSizer(wxVERTICAL);
195  m_panelPF->SetSizer(boxSizerLvl2_2);
196 
197  wxBoxSizer* boxSizerLvl3_3 = new wxBoxSizer(wxVERTICAL);
198 
199  boxSizerLvl2_2->Add(boxSizerLvl3_3, 0, wxEXPAND, WXC_FROM_DIP(5));
200 
201  m_staticTextPFMethod = new wxStaticText(m_panelPF, wxID_ANY, _("Solution method"), wxDefaultPosition, wxDLG_UNIT(m_panelPF, wxSize(-1,-1)), 0);
202 
203  boxSizerLvl3_3->Add(m_staticTextPFMethod, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
204 
205  wxArrayString m_choicePFMethodArr;
206  m_choicePFMethodArr.Add(wxT("Gauss-Seidel"));
207  m_choicePFMethodArr.Add(wxT("Newton-Raphson"));
208  m_choicePFMethod = new wxChoice(m_panelPF, wxID_ANY, wxDefaultPosition, wxDLG_UNIT(m_panelPF, wxSize(-1,-1)), m_choicePFMethodArr, 0);
209  m_choicePFMethod->SetSelection(0);
210 
211  boxSizerLvl3_3->Add(m_choicePFMethod, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxEXPAND, WXC_FROM_DIP(5));
212 
213  wxGridSizer* gridSizerLvl_3_4 = new wxGridSizer(0, 2, 0, 0);
214 
215  boxSizerLvl2_2->Add(gridSizerLvl_3_4, 0, wxEXPAND, WXC_FROM_DIP(5));
216 
217  wxBoxSizer* boxSizerLvl4_2 = new wxBoxSizer(wxVERTICAL);
218 
219  gridSizerLvl_3_4->Add(boxSizerLvl4_2, 0, wxEXPAND, WXC_FROM_DIP(5));
220 
221  m_staticTextAccFactor = new wxStaticText(m_panelPF, wxID_ANY, _("Acceleration factor"), wxDefaultPosition, wxDLG_UNIT(m_panelPF, wxSize(-1,-1)), 0);
222 
223  boxSizerLvl4_2->Add(m_staticTextAccFactor, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
224 
225  m_textCtrlAccFactor = new wxTextCtrl(m_panelPF, wxID_ANY, wxT("1,0"), wxDefaultPosition, wxDLG_UNIT(m_panelPF, wxSize(-1,-1)), 0);
226  #if wxVERSION_NUMBER >= 3000
227  m_textCtrlAccFactor->SetHint(wxT(""));
228  #endif
229 
230  boxSizerLvl4_2->Add(m_textCtrlAccFactor, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxEXPAND|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
231 
232  wxBoxSizer* boxSizerLvl4_3 = new wxBoxSizer(wxVERTICAL);
233 
234  gridSizerLvl_3_4->Add(boxSizerLvl4_3, 0, wxEXPAND, WXC_FROM_DIP(5));
235 
236  m_staticTextPFTolerance = new wxStaticText(m_panelPF, wxID_ANY, _("Tolerance"), wxDefaultPosition, wxDLG_UNIT(m_panelPF, wxSize(-1,-1)), 0);
237 
238  boxSizerLvl4_3->Add(m_staticTextPFTolerance, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
239 
240  m_textCtrlPFTolerance = new wxTextCtrl(m_panelPF, wxID_ANY, wxT("1e-7"), wxDefaultPosition, wxDLG_UNIT(m_panelPF, wxSize(-1,-1)), 0);
241  #if wxVERSION_NUMBER >= 3000
242  m_textCtrlPFTolerance->SetHint(wxT(""));
243  #endif
244 
245  boxSizerLvl4_3->Add(m_textCtrlPFTolerance, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxEXPAND|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
246 
247  wxBoxSizer* boxSizerLvl4_4 = new wxBoxSizer(wxVERTICAL);
248 
249  gridSizerLvl_3_4->Add(boxSizerLvl4_4, 0, wxEXPAND, WXC_FROM_DIP(5));
250 
251  m_staticTextPFMaxIterations = new wxStaticText(m_panelPF, wxID_ANY, _("Max. iterations"), wxDefaultPosition, wxDLG_UNIT(m_panelPF, wxSize(-1,-1)), 0);
252 
253  boxSizerLvl4_4->Add(m_staticTextPFMaxIterations, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
254 
255  m_textCtrlPFMaxIterations = new wxTextCtrl(m_panelPF, wxID_ANY, wxT("5000"), wxDefaultPosition, wxDLG_UNIT(m_panelPF, wxSize(-1,-1)), 0);
256  #if wxVERSION_NUMBER >= 3000
257  m_textCtrlPFMaxIterations->SetHint(wxT(""));
258  #endif
259 
260  boxSizerLvl4_4->Add(m_textCtrlPFMaxIterations, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxEXPAND|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
261 
262  m_panelStability = new wxPanel(m_notebook, wxID_ANY, wxDefaultPosition, wxDLG_UNIT(m_notebook, wxSize(-1,-1)), wxTAB_TRAVERSAL);
263  m_notebook->AddPage(m_panelStability, _("Stability"), false);
264 
265  wxBoxSizer* boxSizerLvl2_232 = new wxBoxSizer(wxVERTICAL);
266  m_panelStability->SetSizer(boxSizerLvl2_232);
267 
268  wxGridSizer* gridSizerLvl_2_3 = new wxGridSizer(0, 2, 0, 0);
269 
270  boxSizerLvl2_232->Add(gridSizerLvl_2_3, 0, wxEXPAND, WXC_FROM_DIP(5));
271 
272  wxBoxSizer* boxSizerLvl3_6 = new wxBoxSizer(wxVERTICAL);
273 
274  gridSizerLvl_2_3->Add(boxSizerLvl3_6, 0, wxEXPAND, WXC_FROM_DIP(5));
275 
276  m_staticTextTimeStep = new wxStaticText(m_panelStability, wxID_ANY, _("Time step"), wxDefaultPosition, wxDLG_UNIT(m_panelStability, wxSize(-1,-1)), 0);
277 
278  boxSizerLvl3_6->Add(m_staticTextTimeStep, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
279 
280  wxBoxSizer* boxSizerLvl4_6 = new wxBoxSizer(wxHORIZONTAL);
281 
282  boxSizerLvl3_6->Add(boxSizerLvl4_6, 0, wxEXPAND, WXC_FROM_DIP(5));
283 
284  m_textCtrlTimeStep = new wxTextCtrl(m_panelStability, wxID_ANY, wxT("0,01"), wxDefaultPosition, wxDLG_UNIT(m_panelStability, wxSize(-1,-1)), 0);
285  #if wxVERSION_NUMBER >= 3000
286  m_textCtrlTimeStep->SetHint(wxT(""));
287  #endif
288 
289  boxSizerLvl4_6->Add(m_textCtrlTimeStep, 1, wxLEFT|wxRIGHT|wxBOTTOM|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
290 
291  m_staticTextSec_1 = new wxStaticText(m_panelStability, wxID_ANY, _("s"), wxDefaultPosition, wxDLG_UNIT(m_panelStability, wxSize(-1,-1)), 0);
292 
293  boxSizerLvl4_6->Add(m_staticTextSec_1, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
294 
295  wxBoxSizer* boxSizerLvl3_7 = new wxBoxSizer(wxVERTICAL);
296 
297  gridSizerLvl_2_3->Add(boxSizerLvl3_7, 0, wxEXPAND, WXC_FROM_DIP(5));
298 
299  m_staticTextTSimTime = new wxStaticText(m_panelStability, wxID_ANY, _("Simulation time"), wxDefaultPosition, wxDLG_UNIT(m_panelStability, wxSize(-1,-1)), 0);
300 
301  boxSizerLvl3_7->Add(m_staticTextTSimTime, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
302 
303  wxBoxSizer* boxSizerLvl4_7 = new wxBoxSizer(wxHORIZONTAL);
304 
305  boxSizerLvl3_7->Add(boxSizerLvl4_7, 0, wxEXPAND, WXC_FROM_DIP(5));
306 
307  m_textCtrlSimTime = new wxTextCtrl(m_panelStability, wxID_ANY, wxT("10"), wxDefaultPosition, wxDLG_UNIT(m_panelStability, wxSize(-1,-1)), 0);
308  #if wxVERSION_NUMBER >= 3000
309  m_textCtrlSimTime->SetHint(wxT(""));
310  #endif
311 
312  boxSizerLvl4_7->Add(m_textCtrlSimTime, 1, wxLEFT|wxRIGHT|wxBOTTOM|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
313 
314  m_staticTextSec_2 = new wxStaticText(m_panelStability, wxID_ANY, _("s"), wxDefaultPosition, wxDLG_UNIT(m_panelStability, wxSize(-1,-1)), 0);
315 
316  boxSizerLvl4_7->Add(m_staticTextSec_2, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
317 
318  wxBoxSizer* boxSizerLvl3_5 = new wxBoxSizer(wxVERTICAL);
319 
320  gridSizerLvl_2_3->Add(boxSizerLvl3_5, 0, wxEXPAND, WXC_FROM_DIP(5));
321 
322  m_staticTextFreq = new wxStaticText(m_panelStability, wxID_ANY, _("System frequency"), wxDefaultPosition, wxDLG_UNIT(m_panelStability, wxSize(-1,-1)), 0);
323 
324  boxSizerLvl3_5->Add(m_staticTextFreq, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
325 
326  wxBoxSizer* boxSizerLvl4_5 = new wxBoxSizer(wxHORIZONTAL);
327 
328  boxSizerLvl3_5->Add(boxSizerLvl4_5, 0, wxEXPAND, WXC_FROM_DIP(5));
329 
330  m_textCtrlFreq = new wxTextCtrl(m_panelStability, wxID_ANY, wxT("60,0"), wxDefaultPosition, wxDLG_UNIT(m_panelStability, wxSize(-1,-1)), 0);
331  #if wxVERSION_NUMBER >= 3000
332  m_textCtrlFreq->SetHint(wxT(""));
333  #endif
334 
335  boxSizerLvl4_5->Add(m_textCtrlFreq, 1, wxLEFT|wxRIGHT|wxBOTTOM|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
336 
337  m_staticTextFreqUnit = new wxStaticText(m_panelStability, wxID_ANY, _("Hz"), wxDefaultPosition, wxDLG_UNIT(m_panelStability, wxSize(-1,-1)), 0);
338 
339  boxSizerLvl4_5->Add(m_staticTextFreqUnit, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
340 
341  wxBoxSizer* boxSizerLvl3_8 = new wxBoxSizer(wxVERTICAL);
342 
343  gridSizerLvl_2_3->Add(boxSizerLvl3_8, 0, wxEXPAND, WXC_FROM_DIP(5));
344 
345  m_staticTextTStabTolerance = new wxStaticText(m_panelStability, wxID_ANY, _("Tolerance"), wxDefaultPosition, wxDLG_UNIT(m_panelStability, wxSize(-1,-1)), 0);
346 
347  boxSizerLvl3_8->Add(m_staticTextTStabTolerance, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
348 
349  m_textCtrlStabTolerance = new wxTextCtrl(m_panelStability, wxID_ANY, wxT("1e-8"), wxDefaultPosition, wxDLG_UNIT(m_panelStability, wxSize(-1,-1)), 0);
350  #if wxVERSION_NUMBER >= 3000
351  m_textCtrlStabTolerance->SetHint(wxT(""));
352  #endif
353 
354  boxSizerLvl3_8->Add(m_textCtrlStabTolerance, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxEXPAND|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
355 
356  wxBoxSizer* boxSizerLvl3_9 = new wxBoxSizer(wxVERTICAL);
357 
358  gridSizerLvl_2_3->Add(boxSizerLvl3_9, 0, wxEXPAND, WXC_FROM_DIP(5));
359 
360  m_staticTextTStabMaxIterations = new wxStaticText(m_panelStability, wxID_ANY, _("Max. Iterations"), wxDefaultPosition, wxDLG_UNIT(m_panelStability, wxSize(-1,-1)), 0);
361 
362  boxSizerLvl3_9->Add(m_staticTextTStabMaxIterations, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
363 
364  m_textCtrlStabMaxIterations = new wxTextCtrl(m_panelStability, wxID_ANY, wxT("100"), wxDefaultPosition, wxDLG_UNIT(m_panelStability, wxSize(-1,-1)), 0);
365  #if wxVERSION_NUMBER >= 3000
366  m_textCtrlStabMaxIterations->SetHint(wxT(""));
367  #endif
368 
369  boxSizerLvl3_9->Add(m_textCtrlStabMaxIterations, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxEXPAND|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
370 
371  wxBoxSizer* boxSizerLvl3_10 = new wxBoxSizer(wxVERTICAL);
372 
373  gridSizerLvl_2_3->Add(boxSizerLvl3_10, 0, wxEXPAND, WXC_FROM_DIP(5));
374 
375  m_staticTextCtrlStepRation = new wxStaticText(m_panelStability, wxID_ANY, _("Controls step ratio"), wxDefaultPosition, wxDLG_UNIT(m_panelStability, wxSize(-1,-1)), 0);
376 
377  boxSizerLvl3_10->Add(m_staticTextCtrlStepRation, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
378 
379  m_textCtrlCtrlStepRatio = new wxTextCtrl(m_panelStability, wxID_ANY, wxT("10"), wxDefaultPosition, wxDLG_UNIT(m_panelStability, wxSize(-1,-1)), 0);
380  #if wxVERSION_NUMBER >= 3000
381  m_textCtrlCtrlStepRatio->SetHint(wxT(""));
382  #endif
383 
384  boxSizerLvl3_10->Add(m_textCtrlCtrlStepRatio, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxEXPAND|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
385 
386  wxBoxSizer* boxSizerLvl3_11 = new wxBoxSizer(wxVERTICAL);
387 
388  gridSizerLvl_2_3->Add(boxSizerLvl3_11, 0, wxEXPAND, WXC_FROM_DIP(5));
389 
390  m_staticTextPrintTime = new wxStaticText(m_panelStability, wxID_ANY, _("Plot time"), wxDefaultPosition, wxDLG_UNIT(m_panelStability, wxSize(-1,-1)), 0);
391 
392  boxSizerLvl3_11->Add(m_staticTextPrintTime, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
393 
394  wxBoxSizer* boxSizerLvl4_8 = new wxBoxSizer(wxHORIZONTAL);
395 
396  boxSizerLvl3_11->Add(boxSizerLvl4_8, 0, wxEXPAND, WXC_FROM_DIP(5));
397 
398  m_textCtrlPrintTime = new wxTextCtrl(m_panelStability, wxID_ANY, wxT("0,01"), wxDefaultPosition, wxDLG_UNIT(m_panelStability, wxSize(-1,-1)), 0);
399  #if wxVERSION_NUMBER >= 3000
400  m_textCtrlPrintTime->SetHint(wxT(""));
401  #endif
402 
403  boxSizerLvl4_8->Add(m_textCtrlPrintTime, 1, wxLEFT|wxRIGHT|wxBOTTOM|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
404 
405  m_staticTextSec_4 = new wxStaticText(m_panelStability, wxID_ANY, _("s"), wxDefaultPosition, wxDLG_UNIT(m_panelStability, wxSize(-1,-1)), 0);
406 
407  boxSizerLvl4_8->Add(m_staticTextSec_4, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
408 
409  m_checkBoxUseCOI = new wxCheckBox(m_panelStability, wxID_ANY, _("Use center of inertia as reference"), wxDefaultPosition, wxDLG_UNIT(m_panelStability, wxSize(-1,-1)), 0);
410  m_checkBoxUseCOI->SetValue(true);
411 
412  boxSizerLvl2_232->Add(m_checkBoxUseCOI, 0, wxALL, WXC_FROM_DIP(5));
413 
414  wxBoxSizer* boxSizer_bottonButtons = new wxBoxSizer(wxHORIZONTAL);
415 
416  boxSizer_lvl1_1->Add(boxSizer_bottonButtons, 0, wxALL|wxEXPAND, WXC_FROM_DIP(5));
417 
418  boxSizer_bottonButtons->Add(0, 0, 1, wxALL, WXC_FROM_DIP(5));
419 
420  m_buttonOK = new wxButton(this, wxID_ANY, _("OK"), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
421 
422  boxSizer_bottonButtons->Add(m_buttonOK, 0, wxALL|wxALIGN_RIGHT, WXC_FROM_DIP(5));
423 
424  m_buttonCancel = new wxButton(this, wxID_ANY, _("Cancel"), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
425 
426  boxSizer_bottonButtons->Add(m_buttonCancel, 0, wxALL|wxALIGN_RIGHT, WXC_FROM_DIP(5));
427 
428 
429  #if wxVERSION_NUMBER >= 2900
430  if(!wxPersistenceManager::Get().Find(m_notebook)){
431  wxPersistenceManager::Get().RegisterAndRestore(m_notebook);
432  } else {
433  wxPersistenceManager::Get().Restore(m_notebook);
434  }
435  #endif
436 
437  SetName(wxT("SimulationsSettingsFormBase"));
438  SetSize(-1,-1);
439  if (GetSizer()) {
440  GetSizer()->Fit(this);
441  }
442  if(GetParent()) {
443  CentreOnParent(wxBOTH);
444  } else {
445  CentreOnScreen(wxBOTH);
446  }
447 #if wxVERSION_NUMBER >= 2900
448  if(!wxPersistenceManager::Get().Find(this)) {
449  wxPersistenceManager::Get().RegisterAndRestore(this);
450  } else {
451  wxPersistenceManager::Get().Restore(this);
452  }
453 #endif
454  // Connect events
455  m_choicePFMethod->Connect(wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler(SimulationsSettingsFormBase::OnPFMethodChoiceSelected), NULL, this);
456  m_buttonOK->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(SimulationsSettingsFormBase::OnButtonOKClick), NULL, this);
457  m_buttonCancel->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(SimulationsSettingsFormBase::OnButtonCancelClick), NULL, this);
458 
459 }
460 
461 SimulationsSettingsFormBase::~SimulationsSettingsFormBase()
462 {
463  m_choicePFMethod->Disconnect(wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler(SimulationsSettingsFormBase::OnPFMethodChoiceSelected), NULL, this);
464  m_buttonOK->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(SimulationsSettingsFormBase::OnButtonOKClick), NULL, this);
465  m_buttonCancel->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(SimulationsSettingsFormBase::OnButtonCancelClick), NULL, this);
466 
467 }
468 
469 AboutFormBase::AboutFormBase(wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style)
470  : wxDialog(parent, id, title, pos, size, style)
471 {
472  if ( !bBitmapLoaded ) {
473  // We need to initialise the default bitmap handler
474  wxXmlResource::Get()->AddHandler(new wxBitmapXmlHandler);
475  wxCDAD0InitBitmapResources();
476  bBitmapLoaded = true;
477  }
478 
479  wxBoxSizer* boxSizerMain = new wxBoxSizer(wxVERTICAL);
480  this->SetSizer(boxSizerMain);
481 
482  m_notebook = new wxNotebook(this, wxID_ANY, wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), wxBK_DEFAULT);
483  m_notebook->SetName(wxT("m_notebook"));
484 
485  boxSizerMain->Add(m_notebook, 1, wxALL|wxEXPAND, WXC_FROM_DIP(5));
486 
487  m_panelLogo = new wxPanel(m_notebook, wxID_ANY, wxDefaultPosition, wxDLG_UNIT(m_notebook, wxSize(-1,-1)), wxTAB_TRAVERSAL);
488  m_notebook->AddPage(m_panelLogo, _("About"), false);
489 
490  wxBoxSizer* boxSizerLvl1_1 = new wxBoxSizer(wxVERTICAL);
491  m_panelLogo->SetSizer(boxSizerLvl1_1);
492 
493  m_staticBitmapLogo = new wxStaticBitmap(m_panelLogo, wxID_ANY, wxXmlResource::Get()->LoadBitmap(wxT("About2017")), wxDefaultPosition, wxDLG_UNIT(m_panelLogo, wxSize(-1,-1)), 0 );
494 
495  boxSizerLvl1_1->Add(m_staticBitmapLogo, 0, wxALL|wxALIGN_CENTER_HORIZONTAL, WXC_FROM_DIP(5));
496 
497  m_panelCredits = new wxPanel(m_notebook, wxID_ANY, wxDefaultPosition, wxDLG_UNIT(m_notebook, wxSize(-1,-1)), wxTAB_TRAVERSAL);
498  m_notebook->AddPage(m_panelCredits, _("Credits"), false);
499 
500  wxBoxSizer* boxSizerLvl1_2 = new wxBoxSizer(wxVERTICAL);
501  m_panelCredits->SetSizer(boxSizerLvl1_2);
502 
503  m_gridCredits = new wxGrid(m_panelCredits, wxID_ANY, wxDefaultPosition, wxDLG_UNIT(m_panelCredits, wxSize(-1,-1)), wxWANTS_CHARS);
504  m_gridCredits->CreateGrid(0, 0);
505  m_gridCredits->SetRowLabelAlignment(wxALIGN_RIGHT, wxALIGN_CENTRE);
506  m_gridCredits->SetColLabelAlignment(wxALIGN_CENTRE, wxALIGN_CENTRE);
507  #if wxVERSION_NUMBER >= 2904
508  m_gridCredits->UseNativeColHeader(true);
509  #endif
510  m_gridCredits->EnableEditing(false);
511 
512  boxSizerLvl1_2->Add(m_gridCredits, 1, wxEXPAND, WXC_FROM_DIP(5));
513 
514  m_panelLicense = new wxPanel(m_notebook, wxID_ANY, wxDefaultPosition, wxDLG_UNIT(m_notebook, wxSize(-1,-1)), wxTAB_TRAVERSAL);
515  m_notebook->AddPage(m_panelLicense, _("License"), false);
516 
517  wxBoxSizer* boxSizerLvl1_3 = new wxBoxSizer(wxVERTICAL);
518  m_panelLicense->SetSizer(boxSizerLvl1_3);
519 
520  m_richTextCtrlLicense = new wxRichTextCtrl(m_panelLicense, wxID_ANY, wxT(""), wxDefaultPosition, wxDLG_UNIT(m_panelLicense, wxSize(-1,-1)), wxTE_MULTILINE|wxTE_PROCESS_TAB|wxTE_PROCESS_ENTER|wxWANTS_CHARS);
521 
522  boxSizerLvl1_3->Add(m_richTextCtrlLicense, 1, wxALL|wxEXPAND, WXC_FROM_DIP(5));
523 
524  wxFlexGridSizer* flexGridSizer247 = new wxFlexGridSizer(2, 2, 0, 0);
525  flexGridSizer247->SetFlexibleDirection( wxBOTH );
526  flexGridSizer247->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
527  flexGridSizer247->AddGrowableCol(1);
528 
529  boxSizerMain->Add(flexGridSizer247, 0, wxALL|wxEXPAND, WXC_FROM_DIP(5));
530 
531  m_staticTextVersionLabel = new wxStaticText(this, wxID_ANY, _("Version:"), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
532 
533  flexGridSizer247->Add(m_staticTextVersionLabel, 0, wxALL, WXC_FROM_DIP(5));
534 
535  m_staticTextVersion = new wxStaticText(this, wxID_ANY, _("Alpha 2017w38b"), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
536 
537  flexGridSizer247->Add(m_staticTextVersion, 0, wxALL, WXC_FROM_DIP(5));
538 
539  m_staticTextHome = new wxStaticText(this, wxID_ANY, _("Home page:"), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
540 
541  flexGridSizer247->Add(m_staticTextHome, 0, wxALL, WXC_FROM_DIP(5));
542 
543  m_hyperLinkPSP = new wxHyperlinkCtrl(this, wxID_ANY, _("https://thales1330.github.io/PSP/"), wxT("https://thales1330.github.io/PSP/"), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), wxHL_DEFAULT_STYLE);
544  m_hyperLinkPSP->SetNormalColour(wxColour(wxT("#0000FF")));
545  m_hyperLinkPSP->SetHoverColour(wxColour(wxT("#0000FF")));
546  m_hyperLinkPSP->SetVisitedColour(wxColour(wxT("#FF0000")));
547 
548  flexGridSizer247->Add(m_hyperLinkPSP, 0, wxALL, WXC_FROM_DIP(5));
549 
550  m_buttonOK = new wxButton(this, wxID_ANY, _("OK"), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
551 
552  boxSizerMain->Add(m_buttonOK, 0, wxALL|wxALIGN_CENTER_HORIZONTAL, WXC_FROM_DIP(5));
553 
554 
555  #if wxVERSION_NUMBER >= 2900
556  if(!wxPersistenceManager::Get().Find(m_notebook)){
557  wxPersistenceManager::Get().RegisterAndRestore(m_notebook);
558  } else {
559  wxPersistenceManager::Get().Restore(m_notebook);
560  }
561  #endif
562 
563  SetName(wxT("AboutFormBase"));
564  SetSize(-1,-1);
565  if (GetSizer()) {
566  GetSizer()->Fit(this);
567  }
568  if(GetParent()) {
569  CentreOnParent(wxBOTH);
570  } else {
571  CentreOnScreen(wxBOTH);
572  }
573 #if wxVERSION_NUMBER >= 2900
574  if(!wxPersistenceManager::Get().Find(this)) {
575  wxPersistenceManager::Get().RegisterAndRestore(this);
576  } else {
577  wxPersistenceManager::Get().Restore(this);
578  }
579 #endif
580  // Connect events
581  m_buttonOK->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(AboutFormBase::OnOKButtonClick), NULL, this);
582 
583 }
584 
585 AboutFormBase::~AboutFormBase()
586 {
587  m_buttonOK->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(AboutFormBase::OnOKButtonClick), NULL, this);
588 
589 }
+
1 // This file was auto-generated by codelite's wxCrafter Plugin
3 // wxCrafter project file: PropertiesForm.wxcp
4 // Do not modify this file by hand!
6 
7 #include "PropertiesForm.h"
8 
9 
10 // Declare the bitmap loading function
11 extern void wxCDAD0InitBitmapResources();
12 
13 static bool bBitmapLoaded = false;
14 
15 
16 GeneralPropertiesFormBase::GeneralPropertiesFormBase(wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style)
17  : wxDialog(parent, id, title, pos, size, style)
18 {
19  if ( !bBitmapLoaded ) {
20  // We need to initialise the default bitmap handler
21  wxXmlResource::Get()->AddHandler(new wxBitmapXmlHandler);
22  wxCDAD0InitBitmapResources();
23  bBitmapLoaded = true;
24  }
25 
26  wxBoxSizer* boxSizer_lvl1_1 = new wxBoxSizer(wxVERTICAL);
27  this->SetSizer(boxSizer_lvl1_1);
28 
29  m_notebook = new wxNotebook(this, wxID_ANY, wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), wxBK_DEFAULT);
30  m_notebook->SetName(wxT("m_notebook"));
31 
32  boxSizer_lvl1_1->Add(m_notebook, 1, wxALL|wxEXPAND, WXC_FROM_DIP(5));
33 
34  m_panelGeneral = new wxPanel(m_notebook, wxID_ANY, wxDefaultPosition, wxDLG_UNIT(m_notebook, wxSize(-1,-1)), wxTAB_TRAVERSAL);
35  m_notebook->AddPage(m_panelGeneral, _("General"), false);
36 
37  wxBoxSizer* boxSizerLvl2_1 = new wxBoxSizer(wxVERTICAL);
38  m_panelGeneral->SetSizer(boxSizerLvl2_1);
39 
40  wxBoxSizer* boxSizerLvl3_1 = new wxBoxSizer(wxVERTICAL);
41 
42  boxSizerLvl2_1->Add(boxSizerLvl3_1, 0, wxEXPAND, WXC_FROM_DIP(5));
43 
44  m_staticTextLanguage = new wxStaticText(m_panelGeneral, wxID_ANY, _("Language"), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
45 
46  boxSizerLvl3_1->Add(m_staticTextLanguage, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
47 
48  wxArrayString m_choiceLanguageArr;
49  m_choiceLanguageArr.Add(wxT("English"));
50  m_choiceLanguageArr.Add(wxT("Portuguese"));
51  m_choiceLanguage = new wxChoice(m_panelGeneral, wxID_ANY, wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), m_choiceLanguageArr, 0);
52  m_choiceLanguage->SetSelection(0);
53 
54  boxSizerLvl3_1->Add(m_choiceLanguage, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxEXPAND, WXC_FROM_DIP(5));
55 
56  wxBoxSizer* boxSizerLvl3_2 = new wxBoxSizer(wxVERTICAL);
57 
58  boxSizerLvl2_1->Add(boxSizerLvl3_2, 0, wxEXPAND, WXC_FROM_DIP(5));
59 
60  m_staticTextTheme = new wxStaticText(m_panelGeneral, wxID_ANY, _("Theme"), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
61 
62  boxSizerLvl3_2->Add(m_staticTextTheme, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
63 
64  wxArrayString m_choiceThemeArr;
65  m_choiceThemeArr.Add(wxT("Light"));
66  m_choiceThemeArr.Add(wxT("Dark"));
67  m_choiceTheme = new wxChoice(m_panelGeneral, wxID_ANY, wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), m_choiceThemeArr, 0);
68  m_choiceTheme->SetSelection(0);
69 
70  boxSizerLvl3_2->Add(m_choiceTheme, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxEXPAND, WXC_FROM_DIP(5));
71 
72  wxBoxSizer* boxSizer_bottonButtons = new wxBoxSizer(wxHORIZONTAL);
73 
74  boxSizer_lvl1_1->Add(boxSizer_bottonButtons, 0, wxALL|wxEXPAND, WXC_FROM_DIP(5));
75 
76  boxSizer_bottonButtons->Add(0, 0, 1, wxALL, WXC_FROM_DIP(5));
77 
78  m_buttonOK = new wxButton(this, wxID_ANY, _("OK"), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
79 
80  boxSizer_bottonButtons->Add(m_buttonOK, 0, wxALL|wxALIGN_RIGHT, WXC_FROM_DIP(5));
81 
82  m_buttonCancel = new wxButton(this, wxID_ANY, _("Cancel"), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
83 
84  boxSizer_bottonButtons->Add(m_buttonCancel, 0, wxALL|wxALIGN_RIGHT, WXC_FROM_DIP(5));
85 
86 
87  #if wxVERSION_NUMBER >= 2900
88  if(!wxPersistenceManager::Get().Find(m_notebook)){
89  wxPersistenceManager::Get().RegisterAndRestore(m_notebook);
90  } else {
91  wxPersistenceManager::Get().Restore(m_notebook);
92  }
93  #endif
94 
95  SetName(wxT("GeneralPropertiesFormBase"));
96  SetSize(-1,-1);
97  if (GetSizer()) {
98  GetSizer()->Fit(this);
99  }
100  if(GetParent()) {
101  CentreOnParent(wxBOTH);
102  } else {
103  CentreOnScreen(wxBOTH);
104  }
105 #if wxVERSION_NUMBER >= 2900
106  if(!wxPersistenceManager::Get().Find(this)) {
107  wxPersistenceManager::Get().RegisterAndRestore(this);
108  } else {
109  wxPersistenceManager::Get().Restore(this);
110  }
111 #endif
112  // Connect events
113  m_buttonOK->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(GeneralPropertiesFormBase::OnButtonOKClick), NULL, this);
114  m_buttonCancel->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(GeneralPropertiesFormBase::OnButtonCancelClick), NULL, this);
115 
116 }
117 
118 GeneralPropertiesFormBase::~GeneralPropertiesFormBase()
119 {
120  m_buttonOK->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(GeneralPropertiesFormBase::OnButtonOKClick), NULL, this);
121  m_buttonCancel->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(GeneralPropertiesFormBase::OnButtonCancelClick), NULL, this);
122 
123 }
124 
125 SimulationsSettingsFormBase::SimulationsSettingsFormBase(wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style)
126  : wxDialog(parent, id, title, pos, size, style)
127 {
128  if ( !bBitmapLoaded ) {
129  // We need to initialise the default bitmap handler
130  wxXmlResource::Get()->AddHandler(new wxBitmapXmlHandler);
131  wxCDAD0InitBitmapResources();
132  bBitmapLoaded = true;
133  }
134 
135  wxBoxSizer* boxSizer_lvl1_1 = new wxBoxSizer(wxVERTICAL);
136  this->SetSizer(boxSizer_lvl1_1);
137 
138  m_notebook = new wxNotebook(this, wxID_ANY, wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), wxBK_DEFAULT);
139  m_notebook->SetName(wxT("m_notebook"));
140 
141  boxSizer_lvl1_1->Add(m_notebook, 1, wxALL|wxEXPAND, WXC_FROM_DIP(5));
142 
143  m_panelGeneral = new wxPanel(m_notebook, wxID_ANY, wxDefaultPosition, wxDLG_UNIT(m_notebook, wxSize(-1,-1)), wxTAB_TRAVERSAL);
144  m_notebook->AddPage(m_panelGeneral, _("General"), false);
145 
146  wxBoxSizer* boxSizerLvl2_1 = new wxBoxSizer(wxVERTICAL);
147  m_panelGeneral->SetSizer(boxSizerLvl2_1);
148 
149  wxBoxSizer* boxSizerLvl3_1 = new wxBoxSizer(wxVERTICAL);
150 
151  boxSizerLvl2_1->Add(boxSizerLvl3_1, 0, wxEXPAND, WXC_FROM_DIP(5));
152 
153  m_staticTextBasePower = new wxStaticText(m_panelGeneral, wxID_ANY, _("Base power"), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
154 
155  boxSizerLvl3_1->Add(m_staticTextBasePower, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
156 
157  wxBoxSizer* boxSizerLvl4_1 = new wxBoxSizer(wxHORIZONTAL);
158 
159  boxSizerLvl3_1->Add(boxSizerLvl4_1, 0, wxEXPAND, WXC_FROM_DIP(5));
160 
161  m_textCtrlbasePower = new wxTextCtrl(m_panelGeneral, wxID_ANY, wxT("100,0"), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
162  #if wxVERSION_NUMBER >= 3000
163  m_textCtrlbasePower->SetHint(wxT(""));
164  #endif
165 
166  boxSizerLvl4_1->Add(m_textCtrlbasePower, 1, wxLEFT|wxRIGHT|wxBOTTOM|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
167 
168  wxArrayString m_choiceBasePowerArr;
169  m_choiceBasePowerArr.Add(wxT("VA"));
170  m_choiceBasePowerArr.Add(wxT("kVA"));
171  m_choiceBasePowerArr.Add(wxT("MVA"));
172  m_choiceBasePower = new wxChoice(m_panelGeneral, wxID_ANY, wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), m_choiceBasePowerArr, 0);
173  m_choiceBasePower->SetSelection(2);
174 
175  boxSizerLvl4_1->Add(m_choiceBasePower, 0, wxLEFT|wxRIGHT|wxBOTTOM, WXC_FROM_DIP(5));
176 
177  wxStaticBoxSizer* staticBoxSizerLvl3_2 = new wxStaticBoxSizer( new wxStaticBox(m_panelGeneral, wxID_ANY, _("Continuous calculation")), wxVERTICAL);
178 
179  boxSizerLvl2_1->Add(staticBoxSizerLvl3_2, 0, wxALL|wxEXPAND, WXC_FROM_DIP(5));
180 
181  m_checkBoxFaultAfterPF = new wxCheckBox(m_panelGeneral, wxID_ANY, _("Calculate fault after power flow"), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
182  m_checkBoxFaultAfterPF->SetValue(true);
183 
184  staticBoxSizerLvl3_2->Add(m_checkBoxFaultAfterPF, 0, wxALL, WXC_FROM_DIP(5));
185 
186  m_checkBoxSCPowerAfterPF = new wxCheckBox(m_panelGeneral, wxID_ANY, _("Calculate short-circuit power after power flow"), wxDefaultPosition, wxDLG_UNIT(m_panelGeneral, wxSize(-1,-1)), 0);
187  m_checkBoxSCPowerAfterPF->SetValue(true);
188 
189  staticBoxSizerLvl3_2->Add(m_checkBoxSCPowerAfterPF, 0, wxALL, WXC_FROM_DIP(5));
190 
191  m_panelPF = new wxPanel(m_notebook, wxID_ANY, wxDefaultPosition, wxDLG_UNIT(m_notebook, wxSize(-1,-1)), wxTAB_TRAVERSAL);
192  m_notebook->AddPage(m_panelPF, _("Power flow"), false);
193 
194  wxBoxSizer* boxSizerLvl2_2 = new wxBoxSizer(wxVERTICAL);
195  m_panelPF->SetSizer(boxSizerLvl2_2);
196 
197  wxBoxSizer* boxSizerLvl3_3 = new wxBoxSizer(wxVERTICAL);
198 
199  boxSizerLvl2_2->Add(boxSizerLvl3_3, 0, wxEXPAND, WXC_FROM_DIP(5));
200 
201  m_staticTextPFMethod = new wxStaticText(m_panelPF, wxID_ANY, _("Solution method"), wxDefaultPosition, wxDLG_UNIT(m_panelPF, wxSize(-1,-1)), 0);
202 
203  boxSizerLvl3_3->Add(m_staticTextPFMethod, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
204 
205  wxArrayString m_choicePFMethodArr;
206  m_choicePFMethodArr.Add(wxT("Gauss-Seidel"));
207  m_choicePFMethodArr.Add(wxT("Newton-Raphson"));
208  m_choicePFMethod = new wxChoice(m_panelPF, wxID_ANY, wxDefaultPosition, wxDLG_UNIT(m_panelPF, wxSize(-1,-1)), m_choicePFMethodArr, 0);
209  m_choicePFMethod->SetSelection(0);
210 
211  boxSizerLvl3_3->Add(m_choicePFMethod, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxEXPAND, WXC_FROM_DIP(5));
212 
213  wxGridSizer* gridSizerLvl_3_4 = new wxGridSizer(0, 2, 0, 0);
214 
215  boxSizerLvl2_2->Add(gridSizerLvl_3_4, 0, wxEXPAND, WXC_FROM_DIP(5));
216 
217  wxBoxSizer* boxSizerLvl4_2 = new wxBoxSizer(wxVERTICAL);
218 
219  gridSizerLvl_3_4->Add(boxSizerLvl4_2, 0, wxEXPAND, WXC_FROM_DIP(5));
220 
221  m_staticTextAccFactor = new wxStaticText(m_panelPF, wxID_ANY, _("Acceleration factor"), wxDefaultPosition, wxDLG_UNIT(m_panelPF, wxSize(-1,-1)), 0);
222 
223  boxSizerLvl4_2->Add(m_staticTextAccFactor, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
224 
225  m_textCtrlAccFactor = new wxTextCtrl(m_panelPF, wxID_ANY, wxT("1,0"), wxDefaultPosition, wxDLG_UNIT(m_panelPF, wxSize(-1,-1)), 0);
226  #if wxVERSION_NUMBER >= 3000
227  m_textCtrlAccFactor->SetHint(wxT(""));
228  #endif
229 
230  boxSizerLvl4_2->Add(m_textCtrlAccFactor, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxEXPAND|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
231 
232  wxBoxSizer* boxSizerLvl4_3 = new wxBoxSizer(wxVERTICAL);
233 
234  gridSizerLvl_3_4->Add(boxSizerLvl4_3, 0, wxEXPAND, WXC_FROM_DIP(5));
235 
236  m_staticTextPFTolerance = new wxStaticText(m_panelPF, wxID_ANY, _("Tolerance"), wxDefaultPosition, wxDLG_UNIT(m_panelPF, wxSize(-1,-1)), 0);
237 
238  boxSizerLvl4_3->Add(m_staticTextPFTolerance, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
239 
240  m_textCtrlPFTolerance = new wxTextCtrl(m_panelPF, wxID_ANY, wxT("1e-7"), wxDefaultPosition, wxDLG_UNIT(m_panelPF, wxSize(-1,-1)), 0);
241  #if wxVERSION_NUMBER >= 3000
242  m_textCtrlPFTolerance->SetHint(wxT(""));
243  #endif
244 
245  boxSizerLvl4_3->Add(m_textCtrlPFTolerance, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxEXPAND|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
246 
247  wxBoxSizer* boxSizerLvl4_4 = new wxBoxSizer(wxVERTICAL);
248 
249  gridSizerLvl_3_4->Add(boxSizerLvl4_4, 0, wxEXPAND, WXC_FROM_DIP(5));
250 
251  m_staticTextPFMaxIterations = new wxStaticText(m_panelPF, wxID_ANY, _("Max. iterations"), wxDefaultPosition, wxDLG_UNIT(m_panelPF, wxSize(-1,-1)), 0);
252 
253  boxSizerLvl4_4->Add(m_staticTextPFMaxIterations, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
254 
255  m_textCtrlPFMaxIterations = new wxTextCtrl(m_panelPF, wxID_ANY, wxT("5000"), wxDefaultPosition, wxDLG_UNIT(m_panelPF, wxSize(-1,-1)), 0);
256  #if wxVERSION_NUMBER >= 3000
257  m_textCtrlPFMaxIterations->SetHint(wxT(""));
258  #endif
259 
260  boxSizerLvl4_4->Add(m_textCtrlPFMaxIterations, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxEXPAND|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
261 
262  m_panelStability = new wxPanel(m_notebook, wxID_ANY, wxDefaultPosition, wxDLG_UNIT(m_notebook, wxSize(-1,-1)), wxTAB_TRAVERSAL);
263  m_notebook->AddPage(m_panelStability, _("Stability"), false);
264 
265  wxBoxSizer* boxSizerLvl2_3 = new wxBoxSizer(wxVERTICAL);
266  m_panelStability->SetSizer(boxSizerLvl2_3);
267 
268  wxGridSizer* gridSizerLvl_2_3 = new wxGridSizer(0, 2, 0, 0);
269 
270  boxSizerLvl2_3->Add(gridSizerLvl_2_3, 0, wxEXPAND, WXC_FROM_DIP(5));
271 
272  wxBoxSizer* boxSizerLvl3_6 = new wxBoxSizer(wxVERTICAL);
273 
274  gridSizerLvl_2_3->Add(boxSizerLvl3_6, 0, wxEXPAND, WXC_FROM_DIP(5));
275 
276  m_staticTextTimeStep = new wxStaticText(m_panelStability, wxID_ANY, _("Time step"), wxDefaultPosition, wxDLG_UNIT(m_panelStability, wxSize(-1,-1)), 0);
277 
278  boxSizerLvl3_6->Add(m_staticTextTimeStep, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
279 
280  wxBoxSizer* boxSizerLvl4_6 = new wxBoxSizer(wxHORIZONTAL);
281 
282  boxSizerLvl3_6->Add(boxSizerLvl4_6, 0, wxEXPAND, WXC_FROM_DIP(5));
283 
284  m_textCtrlTimeStep = new wxTextCtrl(m_panelStability, wxID_ANY, wxT("0,01"), wxDefaultPosition, wxDLG_UNIT(m_panelStability, wxSize(-1,-1)), 0);
285  #if wxVERSION_NUMBER >= 3000
286  m_textCtrlTimeStep->SetHint(wxT(""));
287  #endif
288 
289  boxSizerLvl4_6->Add(m_textCtrlTimeStep, 1, wxLEFT|wxRIGHT|wxBOTTOM|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
290 
291  m_staticTextSec_1 = new wxStaticText(m_panelStability, wxID_ANY, _("s"), wxDefaultPosition, wxDLG_UNIT(m_panelStability, wxSize(-1,-1)), 0);
292 
293  boxSizerLvl4_6->Add(m_staticTextSec_1, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
294 
295  wxBoxSizer* boxSizerLvl3_7 = new wxBoxSizer(wxVERTICAL);
296 
297  gridSizerLvl_2_3->Add(boxSizerLvl3_7, 0, wxEXPAND, WXC_FROM_DIP(5));
298 
299  m_staticTextTSimTime = new wxStaticText(m_panelStability, wxID_ANY, _("Simulation time"), wxDefaultPosition, wxDLG_UNIT(m_panelStability, wxSize(-1,-1)), 0);
300 
301  boxSizerLvl3_7->Add(m_staticTextTSimTime, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
302 
303  wxBoxSizer* boxSizerLvl4_7 = new wxBoxSizer(wxHORIZONTAL);
304 
305  boxSizerLvl3_7->Add(boxSizerLvl4_7, 0, wxEXPAND, WXC_FROM_DIP(5));
306 
307  m_textCtrlSimTime = new wxTextCtrl(m_panelStability, wxID_ANY, wxT("10"), wxDefaultPosition, wxDLG_UNIT(m_panelStability, wxSize(-1,-1)), 0);
308  #if wxVERSION_NUMBER >= 3000
309  m_textCtrlSimTime->SetHint(wxT(""));
310  #endif
311 
312  boxSizerLvl4_7->Add(m_textCtrlSimTime, 1, wxLEFT|wxRIGHT|wxBOTTOM|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
313 
314  m_staticTextSec_2 = new wxStaticText(m_panelStability, wxID_ANY, _("s"), wxDefaultPosition, wxDLG_UNIT(m_panelStability, wxSize(-1,-1)), 0);
315 
316  boxSizerLvl4_7->Add(m_staticTextSec_2, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
317 
318  wxBoxSizer* boxSizerLvl3_5 = new wxBoxSizer(wxVERTICAL);
319 
320  gridSizerLvl_2_3->Add(boxSizerLvl3_5, 0, wxEXPAND, WXC_FROM_DIP(5));
321 
322  m_staticTextFreq = new wxStaticText(m_panelStability, wxID_ANY, _("System frequency"), wxDefaultPosition, wxDLG_UNIT(m_panelStability, wxSize(-1,-1)), 0);
323 
324  boxSizerLvl3_5->Add(m_staticTextFreq, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
325 
326  wxBoxSizer* boxSizerLvl4_5 = new wxBoxSizer(wxHORIZONTAL);
327 
328  boxSizerLvl3_5->Add(boxSizerLvl4_5, 0, wxEXPAND, WXC_FROM_DIP(5));
329 
330  m_textCtrlFreq = new wxTextCtrl(m_panelStability, wxID_ANY, wxT("60,0"), wxDefaultPosition, wxDLG_UNIT(m_panelStability, wxSize(-1,-1)), 0);
331  #if wxVERSION_NUMBER >= 3000
332  m_textCtrlFreq->SetHint(wxT(""));
333  #endif
334 
335  boxSizerLvl4_5->Add(m_textCtrlFreq, 1, wxLEFT|wxRIGHT|wxBOTTOM|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
336 
337  m_staticTextFreqUnit = new wxStaticText(m_panelStability, wxID_ANY, _("Hz"), wxDefaultPosition, wxDLG_UNIT(m_panelStability, wxSize(-1,-1)), 0);
338 
339  boxSizerLvl4_5->Add(m_staticTextFreqUnit, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
340 
341  wxBoxSizer* boxSizerLvl3_8 = new wxBoxSizer(wxVERTICAL);
342 
343  gridSizerLvl_2_3->Add(boxSizerLvl3_8, 0, wxEXPAND, WXC_FROM_DIP(5));
344 
345  m_staticTextTStabTolerance = new wxStaticText(m_panelStability, wxID_ANY, _("Tolerance"), wxDefaultPosition, wxDLG_UNIT(m_panelStability, wxSize(-1,-1)), 0);
346 
347  boxSizerLvl3_8->Add(m_staticTextTStabTolerance, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
348 
349  m_textCtrlStabTolerance = new wxTextCtrl(m_panelStability, wxID_ANY, wxT("1e-8"), wxDefaultPosition, wxDLG_UNIT(m_panelStability, wxSize(-1,-1)), 0);
350  #if wxVERSION_NUMBER >= 3000
351  m_textCtrlStabTolerance->SetHint(wxT(""));
352  #endif
353 
354  boxSizerLvl3_8->Add(m_textCtrlStabTolerance, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxEXPAND|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
355 
356  wxBoxSizer* boxSizerLvl3_9 = new wxBoxSizer(wxVERTICAL);
357 
358  gridSizerLvl_2_3->Add(boxSizerLvl3_9, 0, wxEXPAND, WXC_FROM_DIP(5));
359 
360  m_staticTextTStabMaxIterations = new wxStaticText(m_panelStability, wxID_ANY, _("Max. Iterations"), wxDefaultPosition, wxDLG_UNIT(m_panelStability, wxSize(-1,-1)), 0);
361 
362  boxSizerLvl3_9->Add(m_staticTextTStabMaxIterations, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
363 
364  m_textCtrlStabMaxIterations = new wxTextCtrl(m_panelStability, wxID_ANY, wxT("100"), wxDefaultPosition, wxDLG_UNIT(m_panelStability, wxSize(-1,-1)), 0);
365  #if wxVERSION_NUMBER >= 3000
366  m_textCtrlStabMaxIterations->SetHint(wxT(""));
367  #endif
368 
369  boxSizerLvl3_9->Add(m_textCtrlStabMaxIterations, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxEXPAND|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
370 
371  wxBoxSizer* boxSizerLvl3_10 = new wxBoxSizer(wxVERTICAL);
372 
373  gridSizerLvl_2_3->Add(boxSizerLvl3_10, 0, wxEXPAND, WXC_FROM_DIP(5));
374 
375  m_staticTextCtrlStepRation = new wxStaticText(m_panelStability, wxID_ANY, _("Controls step ratio"), wxDefaultPosition, wxDLG_UNIT(m_panelStability, wxSize(-1,-1)), 0);
376 
377  boxSizerLvl3_10->Add(m_staticTextCtrlStepRation, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
378 
379  m_textCtrlCtrlStepRatio = new wxTextCtrl(m_panelStability, wxID_ANY, wxT("10"), wxDefaultPosition, wxDLG_UNIT(m_panelStability, wxSize(-1,-1)), 0);
380  #if wxVERSION_NUMBER >= 3000
381  m_textCtrlCtrlStepRatio->SetHint(wxT(""));
382  #endif
383 
384  boxSizerLvl3_10->Add(m_textCtrlCtrlStepRatio, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxEXPAND|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
385 
386  wxBoxSizer* boxSizerLvl3_11 = new wxBoxSizer(wxVERTICAL);
387 
388  gridSizerLvl_2_3->Add(boxSizerLvl3_11, 0, wxEXPAND, WXC_FROM_DIP(5));
389 
390  m_staticTextPrintTime = new wxStaticText(m_panelStability, wxID_ANY, _("Plot time"), wxDefaultPosition, wxDLG_UNIT(m_panelStability, wxSize(-1,-1)), 0);
391 
392  boxSizerLvl3_11->Add(m_staticTextPrintTime, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
393 
394  wxBoxSizer* boxSizerLvl4_8 = new wxBoxSizer(wxHORIZONTAL);
395 
396  boxSizerLvl3_11->Add(boxSizerLvl4_8, 0, wxEXPAND, WXC_FROM_DIP(5));
397 
398  m_textCtrlPrintTime = new wxTextCtrl(m_panelStability, wxID_ANY, wxT("0,01"), wxDefaultPosition, wxDLG_UNIT(m_panelStability, wxSize(-1,-1)), 0);
399  #if wxVERSION_NUMBER >= 3000
400  m_textCtrlPrintTime->SetHint(wxT(""));
401  #endif
402 
403  boxSizerLvl4_8->Add(m_textCtrlPrintTime, 1, wxLEFT|wxRIGHT|wxBOTTOM|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
404 
405  m_staticTextSec_4 = new wxStaticText(m_panelStability, wxID_ANY, _("s"), wxDefaultPosition, wxDLG_UNIT(m_panelStability, wxSize(-1,-1)), 0);
406 
407  boxSizerLvl4_8->Add(m_staticTextSec_4, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
408 
409  m_checkBoxUseCOI = new wxCheckBox(m_panelStability, wxID_ANY, _("Use center of inertia as reference"), wxDefaultPosition, wxDLG_UNIT(m_panelStability, wxSize(-1,-1)), 0);
410  m_checkBoxUseCOI->SetValue(true);
411 
412  boxSizerLvl2_3->Add(m_checkBoxUseCOI, 0, wxALL, WXC_FROM_DIP(5));
413 
414  m_panelLoadComp = new wxPanel(m_notebook, wxID_ANY, wxDefaultPosition, wxDLG_UNIT(m_notebook, wxSize(-1,-1)), wxTAB_TRAVERSAL);
415  m_notebook->AddPage(m_panelLoadComp, _("ZIP Load"), false);
416 
417  wxBoxSizer* boxSizerLvl2_4 = new wxBoxSizer(wxVERTICAL);
418  m_panelLoadComp->SetSizer(boxSizerLvl2_4);
419 
420  m_checkBoxUseCompLoads = new wxCheckBox(m_panelLoadComp, wxID_ANY, _("Use general composition to all system loads"), wxDefaultPosition, wxDLG_UNIT(m_panelLoadComp, wxSize(-1,-1)), 0);
421  m_checkBoxUseCompLoads->SetValue(false);
422 
423  boxSizerLvl2_4->Add(m_checkBoxUseCompLoads, 0, wxALL, WXC_FROM_DIP(5));
424 
425  wxGridSizer* gridSizerLvl2_4 = new wxGridSizer(0, 2, 0, 0);
426 
427  boxSizerLvl2_4->Add(gridSizerLvl2_4, 1, wxEXPAND, WXC_FROM_DIP(5));
428 
429  wxStaticBoxSizer* staticBoxSizerLvl3_4 = new wxStaticBoxSizer( new wxStaticBox(m_panelLoadComp, wxID_ANY, _("Active power")), wxVERTICAL);
430 
431  gridSizerLvl2_4->Add(staticBoxSizerLvl3_4, 0, wxALL|wxEXPAND, WXC_FROM_DIP(5));
432 
433  wxBoxSizer* boxSizerLvl4_12 = new wxBoxSizer(wxVERTICAL);
434 
435  staticBoxSizerLvl3_4->Add(boxSizerLvl4_12, 0, wxEXPAND, WXC_FROM_DIP(5));
436 
437  m_staticTextActivePowerImp = new wxStaticText(m_panelLoadComp, wxID_ANY, _("Constant impedance"), wxDefaultPosition, wxDLG_UNIT(m_panelLoadComp, wxSize(-1,-1)), 0);
438 
439  boxSizerLvl4_12->Add(m_staticTextActivePowerImp, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
440 
441  wxBoxSizer* boxSizerLvl5_9 = new wxBoxSizer(wxHORIZONTAL);
442 
443  boxSizerLvl4_12->Add(boxSizerLvl5_9, 0, wxEXPAND, WXC_FROM_DIP(5));
444 
445  m_textCtrlActivePowerImp = new wxTextCtrl(m_panelLoadComp, wxID_ANY, wxT("100"), wxDefaultPosition, wxDLG_UNIT(m_panelLoadComp, wxSize(-1,-1)), 0);
446  #if wxVERSION_NUMBER >= 3000
447  m_textCtrlActivePowerImp->SetHint(wxT(""));
448  #endif
449 
450  boxSizerLvl5_9->Add(m_textCtrlActivePowerImp, 1, wxLEFT|wxRIGHT|wxBOTTOM|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
451 
452  m_staticTextPerc_1 = new wxStaticText(m_panelLoadComp, wxID_ANY, _("%"), wxDefaultPosition, wxDLG_UNIT(m_panelLoadComp, wxSize(-1,-1)), 0);
453 
454  boxSizerLvl5_9->Add(m_staticTextPerc_1, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
455 
456  wxBoxSizer* boxSizerLvl4_13 = new wxBoxSizer(wxVERTICAL);
457 
458  staticBoxSizerLvl3_4->Add(boxSizerLvl4_13, 0, wxEXPAND, WXC_FROM_DIP(5));
459 
460  m_staticTextActivePowerCur = new wxStaticText(m_panelLoadComp, wxID_ANY, _("Constant current"), wxDefaultPosition, wxDLG_UNIT(m_panelLoadComp, wxSize(-1,-1)), 0);
461 
462  boxSizerLvl4_13->Add(m_staticTextActivePowerCur, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
463 
464  wxBoxSizer* boxSizerLvl5_10 = new wxBoxSizer(wxHORIZONTAL);
465 
466  boxSizerLvl4_13->Add(boxSizerLvl5_10, 0, wxEXPAND, WXC_FROM_DIP(5));
467 
468  m_textCtrlActivePowerCur = new wxTextCtrl(m_panelLoadComp, wxID_ANY, wxT("0"), wxDefaultPosition, wxDLG_UNIT(m_panelLoadComp, wxSize(-1,-1)), 0);
469  #if wxVERSION_NUMBER >= 3000
470  m_textCtrlActivePowerCur->SetHint(wxT(""));
471  #endif
472 
473  boxSizerLvl5_10->Add(m_textCtrlActivePowerCur, 1, wxLEFT|wxRIGHT|wxBOTTOM|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
474 
475  m_staticTextPerc_2 = new wxStaticText(m_panelLoadComp, wxID_ANY, _("%"), wxDefaultPosition, wxDLG_UNIT(m_panelLoadComp, wxSize(-1,-1)), 0);
476 
477  boxSizerLvl5_10->Add(m_staticTextPerc_2, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
478 
479  wxBoxSizer* boxSizerLvl4_14 = new wxBoxSizer(wxVERTICAL);
480 
481  staticBoxSizerLvl3_4->Add(boxSizerLvl4_14, 0, wxEXPAND, WXC_FROM_DIP(5));
482 
483  m_staticTextActivePowerPow = new wxStaticText(m_panelLoadComp, wxID_ANY, _("Constant power"), wxDefaultPosition, wxDLG_UNIT(m_panelLoadComp, wxSize(-1,-1)), 0);
484 
485  boxSizerLvl4_14->Add(m_staticTextActivePowerPow, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
486 
487  wxBoxSizer* boxSizerLvl5_11 = new wxBoxSizer(wxHORIZONTAL);
488 
489  boxSizerLvl4_14->Add(boxSizerLvl5_11, 0, wxEXPAND, WXC_FROM_DIP(5));
490 
491  m_textCtrlActivePowerPow = new wxTextCtrl(m_panelLoadComp, wxID_ANY, wxT("0"), wxDefaultPosition, wxDLG_UNIT(m_panelLoadComp, wxSize(-1,-1)), 0);
492  #if wxVERSION_NUMBER >= 3000
493  m_textCtrlActivePowerPow->SetHint(wxT(""));
494  #endif
495 
496  boxSizerLvl5_11->Add(m_textCtrlActivePowerPow, 1, wxLEFT|wxRIGHT|wxBOTTOM|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
497 
498  m_staticTextPerc_3 = new wxStaticText(m_panelLoadComp, wxID_ANY, _("%"), wxDefaultPosition, wxDLG_UNIT(m_panelLoadComp, wxSize(-1,-1)), 0);
499 
500  boxSizerLvl5_11->Add(m_staticTextPerc_3, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
501 
502  wxStaticBoxSizer* staticBoxSizerLvl3_5 = new wxStaticBoxSizer( new wxStaticBox(m_panelLoadComp, wxID_ANY, _("Reactive power")), wxVERTICAL);
503 
504  gridSizerLvl2_4->Add(staticBoxSizerLvl3_5, 0, wxALL|wxEXPAND, WXC_FROM_DIP(5));
505 
506  wxBoxSizer* boxSizerLvl4_15 = new wxBoxSizer(wxVERTICAL);
507 
508  staticBoxSizerLvl3_5->Add(boxSizerLvl4_15, 0, wxEXPAND, WXC_FROM_DIP(5));
509 
510  m_staticTextReactivePowerImp = new wxStaticText(m_panelLoadComp, wxID_ANY, _("Constant impedance"), wxDefaultPosition, wxDLG_UNIT(m_panelLoadComp, wxSize(-1,-1)), 0);
511 
512  boxSizerLvl4_15->Add(m_staticTextReactivePowerImp, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
513 
514  wxBoxSizer* boxSizerLvl5_12 = new wxBoxSizer(wxHORIZONTAL);
515 
516  boxSizerLvl4_15->Add(boxSizerLvl5_12, 0, wxEXPAND, WXC_FROM_DIP(5));
517 
518  m_textCtrlReactivePowerImp = new wxTextCtrl(m_panelLoadComp, wxID_ANY, wxT("100"), wxDefaultPosition, wxDLG_UNIT(m_panelLoadComp, wxSize(-1,-1)), 0);
519  #if wxVERSION_NUMBER >= 3000
520  m_textCtrlReactivePowerImp->SetHint(wxT(""));
521  #endif
522 
523  boxSizerLvl5_12->Add(m_textCtrlReactivePowerImp, 1, wxLEFT|wxRIGHT|wxBOTTOM|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
524 
525  m_staticTextPerc_4 = new wxStaticText(m_panelLoadComp, wxID_ANY, _("%"), wxDefaultPosition, wxDLG_UNIT(m_panelLoadComp, wxSize(-1,-1)), 0);
526 
527  boxSizerLvl5_12->Add(m_staticTextPerc_4, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
528 
529  wxBoxSizer* boxSizerLvl4_16 = new wxBoxSizer(wxVERTICAL);
530 
531  staticBoxSizerLvl3_5->Add(boxSizerLvl4_16, 0, wxEXPAND, WXC_FROM_DIP(5));
532 
533  m_staticTextReactivePowerCur = new wxStaticText(m_panelLoadComp, wxID_ANY, _("Constant current"), wxDefaultPosition, wxDLG_UNIT(m_panelLoadComp, wxSize(-1,-1)), 0);
534 
535  boxSizerLvl4_16->Add(m_staticTextReactivePowerCur, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
536 
537  wxBoxSizer* boxSizerLvl5_13 = new wxBoxSizer(wxHORIZONTAL);
538 
539  boxSizerLvl4_16->Add(boxSizerLvl5_13, 0, wxEXPAND, WXC_FROM_DIP(5));
540 
541  m_textCtrlReactivePowerCur = new wxTextCtrl(m_panelLoadComp, wxID_ANY, wxT("0"), wxDefaultPosition, wxDLG_UNIT(m_panelLoadComp, wxSize(-1,-1)), 0);
542  #if wxVERSION_NUMBER >= 3000
543  m_textCtrlReactivePowerCur->SetHint(wxT(""));
544  #endif
545 
546  boxSizerLvl5_13->Add(m_textCtrlReactivePowerCur, 1, wxLEFT|wxRIGHT|wxBOTTOM|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
547 
548  m_staticTextPerc_5 = new wxStaticText(m_panelLoadComp, wxID_ANY, _("%"), wxDefaultPosition, wxDLG_UNIT(m_panelLoadComp, wxSize(-1,-1)), 0);
549 
550  boxSizerLvl5_13->Add(m_staticTextPerc_5, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
551 
552  wxBoxSizer* boxSizerLvl4_17 = new wxBoxSizer(wxVERTICAL);
553 
554  staticBoxSizerLvl3_5->Add(boxSizerLvl4_17, 0, wxEXPAND, WXC_FROM_DIP(5));
555 
556  m_staticTextReactivePowerPow = new wxStaticText(m_panelLoadComp, wxID_ANY, _("Constant power"), wxDefaultPosition, wxDLG_UNIT(m_panelLoadComp, wxSize(-1,-1)), 0);
557 
558  boxSizerLvl4_17->Add(m_staticTextReactivePowerPow, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
559 
560  wxBoxSizer* boxSizerLvl5_14 = new wxBoxSizer(wxHORIZONTAL);
561 
562  boxSizerLvl4_17->Add(boxSizerLvl5_14, 0, wxEXPAND, WXC_FROM_DIP(5));
563 
564  m_textCtrlReactivePowerPow = new wxTextCtrl(m_panelLoadComp, wxID_ANY, wxT("0"), wxDefaultPosition, wxDLG_UNIT(m_panelLoadComp, wxSize(-1,-1)), 0);
565  #if wxVERSION_NUMBER >= 3000
566  m_textCtrlReactivePowerPow->SetHint(wxT(""));
567  #endif
568 
569  boxSizerLvl5_14->Add(m_textCtrlReactivePowerPow, 1, wxLEFT|wxRIGHT|wxBOTTOM|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
570 
571  m_staticTextPerc_6 = new wxStaticText(m_panelLoadComp, wxID_ANY, _("%"), wxDefaultPosition, wxDLG_UNIT(m_panelLoadComp, wxSize(-1,-1)), 0);
572 
573  boxSizerLvl5_14->Add(m_staticTextPerc_6, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
574 
575  m_staticTextUV = new wxStaticText(m_panelLoadComp, wxID_ANY, _("Undervoltage limit which the loads will be modelled by\nconstant impedance:"), wxDefaultPosition, wxDLG_UNIT(m_panelLoadComp, wxSize(-1,-1)), 0);
576 
577  boxSizerLvl2_4->Add(m_staticTextUV, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
578 
579  wxBoxSizer* boxSizerLvl2_5 = new wxBoxSizer(wxHORIZONTAL);
580 
581  boxSizerLvl2_4->Add(boxSizerLvl2_5, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxEXPAND, WXC_FROM_DIP(5));
582 
583  wxBoxSizer* boxSizerLvl4_18 = new wxBoxSizer(wxVERTICAL);
584 
585  boxSizerLvl2_5->Add(boxSizerLvl4_18, 1, 0, WXC_FROM_DIP(5));
586 
587  m_staticTextUVCur = new wxStaticText(m_panelLoadComp, wxID_ANY, _("Constant current"), wxDefaultPosition, wxDLG_UNIT(m_panelLoadComp, wxSize(-1,-1)), 0);
588 
589  boxSizerLvl4_18->Add(m_staticTextUVCur, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
590 
591  wxBoxSizer* boxSizerLvl5_15 = new wxBoxSizer(wxHORIZONTAL);
592 
593  boxSizerLvl4_18->Add(boxSizerLvl5_15, 0, wxEXPAND, WXC_FROM_DIP(5));
594 
595  m_textCtrlUVCur = new wxTextCtrl(m_panelLoadComp, wxID_ANY, wxT("70"), wxDefaultPosition, wxDLG_UNIT(m_panelLoadComp, wxSize(-1,-1)), 0);
596  #if wxVERSION_NUMBER >= 3000
597  m_textCtrlUVCur->SetHint(wxT(""));
598  #endif
599 
600  boxSizerLvl5_15->Add(m_textCtrlUVCur, 1, wxLEFT|wxRIGHT|wxBOTTOM|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
601 
602  m_staticTextPerc_7 = new wxStaticText(m_panelLoadComp, wxID_ANY, _("%"), wxDefaultPosition, wxDLG_UNIT(m_panelLoadComp, wxSize(-1,-1)), 0);
603 
604  boxSizerLvl5_15->Add(m_staticTextPerc_7, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
605 
606  wxBoxSizer* boxSizerLvl4_19 = new wxBoxSizer(wxVERTICAL);
607 
608  boxSizerLvl2_5->Add(boxSizerLvl4_19, 1, 0, WXC_FROM_DIP(5));
609 
610  m_staticTextUVPow = new wxStaticText(m_panelLoadComp, wxID_ANY, _("Constant power"), wxDefaultPosition, wxDLG_UNIT(m_panelLoadComp, wxSize(-1,-1)), 0);
611 
612  boxSizerLvl4_19->Add(m_staticTextUVPow, 0, wxLEFT|wxRIGHT|wxTOP|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
613 
614  wxBoxSizer* boxSizerLvl5_16 = new wxBoxSizer(wxHORIZONTAL);
615 
616  boxSizerLvl4_19->Add(boxSizerLvl5_16, 0, wxEXPAND, WXC_FROM_DIP(5));
617 
618  m_textCtrlUVPow = new wxTextCtrl(m_panelLoadComp, wxID_ANY, wxT("70"), wxDefaultPosition, wxDLG_UNIT(m_panelLoadComp, wxSize(-1,-1)), 0);
619  #if wxVERSION_NUMBER >= 3000
620  m_textCtrlUVPow->SetHint(wxT(""));
621  #endif
622 
623  boxSizerLvl5_16->Add(m_textCtrlUVPow, 1, wxLEFT|wxRIGHT|wxBOTTOM|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
624 
625  m_staticTextPerc_8 = new wxStaticText(m_panelLoadComp, wxID_ANY, _("%"), wxDefaultPosition, wxDLG_UNIT(m_panelLoadComp, wxSize(-1,-1)), 0);
626 
627  boxSizerLvl5_16->Add(m_staticTextPerc_8, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxALIGN_CENTER_VERTICAL, WXC_FROM_DIP(5));
628 
629  wxBoxSizer* boxSizer_bottonButtons = new wxBoxSizer(wxHORIZONTAL);
630 
631  boxSizer_lvl1_1->Add(boxSizer_bottonButtons, 0, wxALL|wxEXPAND, WXC_FROM_DIP(5));
632 
633  boxSizer_bottonButtons->Add(0, 0, 1, wxALL, WXC_FROM_DIP(5));
634 
635  m_buttonOK = new wxButton(this, wxID_ANY, _("OK"), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
636 
637  boxSizer_bottonButtons->Add(m_buttonOK, 0, wxALL|wxALIGN_RIGHT, WXC_FROM_DIP(5));
638 
639  m_buttonCancel = new wxButton(this, wxID_ANY, _("Cancel"), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
640 
641  boxSizer_bottonButtons->Add(m_buttonCancel, 0, wxALL|wxALIGN_RIGHT, WXC_FROM_DIP(5));
642 
643 
644  #if wxVERSION_NUMBER >= 2900
645  if(!wxPersistenceManager::Get().Find(m_notebook)){
646  wxPersistenceManager::Get().RegisterAndRestore(m_notebook);
647  } else {
648  wxPersistenceManager::Get().Restore(m_notebook);
649  }
650  #endif
651 
652  SetName(wxT("SimulationsSettingsFormBase"));
653  SetSize(-1,-1);
654  if (GetSizer()) {
655  GetSizer()->Fit(this);
656  }
657  if(GetParent()) {
658  CentreOnParent(wxBOTH);
659  } else {
660  CentreOnScreen(wxBOTH);
661  }
662 #if wxVERSION_NUMBER >= 2900
663  if(!wxPersistenceManager::Get().Find(this)) {
664  wxPersistenceManager::Get().RegisterAndRestore(this);
665  } else {
666  wxPersistenceManager::Get().Restore(this);
667  }
668 #endif
669  // Connect events
670  m_choicePFMethod->Connect(wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler(SimulationsSettingsFormBase::OnPFMethodChoiceSelected), NULL, this);
671  m_checkBoxUseCompLoads->Connect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler(SimulationsSettingsFormBase::OnCheckboxUseCompLoadClick), NULL, this);
672  m_buttonOK->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(SimulationsSettingsFormBase::OnButtonOKClick), NULL, this);
673  m_buttonCancel->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(SimulationsSettingsFormBase::OnButtonCancelClick), NULL, this);
674 
675 }
676 
677 SimulationsSettingsFormBase::~SimulationsSettingsFormBase()
678 {
679  m_choicePFMethod->Disconnect(wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler(SimulationsSettingsFormBase::OnPFMethodChoiceSelected), NULL, this);
680  m_checkBoxUseCompLoads->Disconnect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler(SimulationsSettingsFormBase::OnCheckboxUseCompLoadClick), NULL, this);
681  m_buttonOK->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(SimulationsSettingsFormBase::OnButtonOKClick), NULL, this);
682  m_buttonCancel->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(SimulationsSettingsFormBase::OnButtonCancelClick), NULL, this);
683 
684 }
685 
686 AboutFormBase::AboutFormBase(wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style)
687  : wxDialog(parent, id, title, pos, size, style)
688 {
689  if ( !bBitmapLoaded ) {
690  // We need to initialise the default bitmap handler
691  wxXmlResource::Get()->AddHandler(new wxBitmapXmlHandler);
692  wxCDAD0InitBitmapResources();
693  bBitmapLoaded = true;
694  }
695 
696  wxBoxSizer* boxSizerMain = new wxBoxSizer(wxVERTICAL);
697  this->SetSizer(boxSizerMain);
698 
699  m_notebook = new wxNotebook(this, wxID_ANY, wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), wxBK_DEFAULT);
700  m_notebook->SetName(wxT("m_notebook"));
701 
702  boxSizerMain->Add(m_notebook, 1, wxALL|wxEXPAND, WXC_FROM_DIP(5));
703 
704  m_panelLogo = new wxPanel(m_notebook, wxID_ANY, wxDefaultPosition, wxDLG_UNIT(m_notebook, wxSize(-1,-1)), wxTAB_TRAVERSAL);
705  m_notebook->AddPage(m_panelLogo, _("About"), false);
706 
707  wxBoxSizer* boxSizerLvl1_1 = new wxBoxSizer(wxVERTICAL);
708  m_panelLogo->SetSizer(boxSizerLvl1_1);
709 
710  m_staticBitmapLogo = new wxStaticBitmap(m_panelLogo, wxID_ANY, wxXmlResource::Get()->LoadBitmap(wxT("About2017")), wxDefaultPosition, wxDLG_UNIT(m_panelLogo, wxSize(-1,-1)), 0 );
711 
712  boxSizerLvl1_1->Add(m_staticBitmapLogo, 0, wxALL|wxALIGN_CENTER_HORIZONTAL, WXC_FROM_DIP(5));
713 
714  m_panelCredits = new wxPanel(m_notebook, wxID_ANY, wxDefaultPosition, wxDLG_UNIT(m_notebook, wxSize(-1,-1)), wxTAB_TRAVERSAL);
715  m_notebook->AddPage(m_panelCredits, _("Credits"), false);
716 
717  wxBoxSizer* boxSizerLvl1_2 = new wxBoxSizer(wxVERTICAL);
718  m_panelCredits->SetSizer(boxSizerLvl1_2);
719 
720  m_gridCredits = new wxGrid(m_panelCredits, wxID_ANY, wxDefaultPosition, wxDLG_UNIT(m_panelCredits, wxSize(-1,-1)), wxWANTS_CHARS);
721  m_gridCredits->CreateGrid(0, 0);
722  m_gridCredits->SetRowLabelAlignment(wxALIGN_RIGHT, wxALIGN_CENTRE);
723  m_gridCredits->SetColLabelAlignment(wxALIGN_CENTRE, wxALIGN_CENTRE);
724  #if wxVERSION_NUMBER >= 2904
725  m_gridCredits->UseNativeColHeader(true);
726  #endif
727  m_gridCredits->EnableEditing(false);
728 
729  boxSizerLvl1_2->Add(m_gridCredits, 1, wxEXPAND, WXC_FROM_DIP(5));
730 
731  m_panelLicense = new wxPanel(m_notebook, wxID_ANY, wxDefaultPosition, wxDLG_UNIT(m_notebook, wxSize(-1,-1)), wxTAB_TRAVERSAL);
732  m_notebook->AddPage(m_panelLicense, _("License"), false);
733 
734  wxBoxSizer* boxSizerLvl1_3 = new wxBoxSizer(wxVERTICAL);
735  m_panelLicense->SetSizer(boxSizerLvl1_3);
736 
737  m_richTextCtrlLicense = new wxRichTextCtrl(m_panelLicense, wxID_ANY, wxT(""), wxDefaultPosition, wxDLG_UNIT(m_panelLicense, wxSize(-1,-1)), wxTE_MULTILINE|wxTE_PROCESS_TAB|wxTE_PROCESS_ENTER|wxWANTS_CHARS);
738 
739  boxSizerLvl1_3->Add(m_richTextCtrlLicense, 1, wxALL|wxEXPAND, WXC_FROM_DIP(5));
740 
741  wxFlexGridSizer* flexGridSizer247 = new wxFlexGridSizer(2, 2, 0, 0);
742  flexGridSizer247->SetFlexibleDirection( wxBOTH );
743  flexGridSizer247->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
744  flexGridSizer247->AddGrowableCol(1);
745 
746  boxSizerMain->Add(flexGridSizer247, 0, wxALL|wxEXPAND, WXC_FROM_DIP(5));
747 
748  m_staticTextVersionLabel = new wxStaticText(this, wxID_ANY, _("Version:"), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
749 
750  flexGridSizer247->Add(m_staticTextVersionLabel, 0, wxALL, WXC_FROM_DIP(5));
751 
752  m_staticTextVersion = new wxStaticText(this, wxID_ANY, _("Alpha 2017w45a"), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
753 
754  flexGridSizer247->Add(m_staticTextVersion, 0, wxALL, WXC_FROM_DIP(5));
755 
756  m_staticTextHome = new wxStaticText(this, wxID_ANY, _("Home page:"), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
757 
758  flexGridSizer247->Add(m_staticTextHome, 0, wxALL, WXC_FROM_DIP(5));
759 
760  m_hyperLinkPSP = new wxHyperlinkCtrl(this, wxID_ANY, _("https://thales1330.github.io/PSP/"), wxT("https://thales1330.github.io/PSP/"), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), wxHL_DEFAULT_STYLE);
761  m_hyperLinkPSP->SetNormalColour(wxColour(wxT("#0000FF")));
762  m_hyperLinkPSP->SetHoverColour(wxColour(wxT("#0000FF")));
763  m_hyperLinkPSP->SetVisitedColour(wxColour(wxT("#FF0000")));
764 
765  flexGridSizer247->Add(m_hyperLinkPSP, 0, wxALL, WXC_FROM_DIP(5));
766 
767  m_buttonOK = new wxButton(this, wxID_ANY, _("OK"), wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), 0);
768 
769  boxSizerMain->Add(m_buttonOK, 0, wxALL|wxALIGN_CENTER_HORIZONTAL, WXC_FROM_DIP(5));
770 
771 
772  #if wxVERSION_NUMBER >= 2900
773  if(!wxPersistenceManager::Get().Find(m_notebook)){
774  wxPersistenceManager::Get().RegisterAndRestore(m_notebook);
775  } else {
776  wxPersistenceManager::Get().Restore(m_notebook);
777  }
778  #endif
779 
780  SetName(wxT("AboutFormBase"));
781  SetSize(-1,-1);
782  if (GetSizer()) {
783  GetSizer()->Fit(this);
784  }
785  if(GetParent()) {
786  CentreOnParent(wxBOTH);
787  } else {
788  CentreOnScreen(wxBOTH);
789  }
790 #if wxVERSION_NUMBER >= 2900
791  if(!wxPersistenceManager::Get().Find(this)) {
792  wxPersistenceManager::Get().RegisterAndRestore(this);
793  } else {
794  wxPersistenceManager::Get().Restore(this);
795  }
796 #endif
797  // Connect events
798  m_buttonOK->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(AboutFormBase::OnOKButtonClick), NULL, this);
799 
800 }
801 
802 AboutFormBase::~AboutFormBase()
803 {
804  m_buttonOK->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(AboutFormBase::OnOKButtonClick), NULL, this);
805 
806 }
-
1 // This file was auto-generated by codelite's wxCrafter Plugin
3 // wxCrafter project file: PropertiesForm.wxcp
4 // Do not modify this file by hand!
6 
7 #ifndef _PSP_PROJECT_PROPERTIESFORM_BASE_CLASSES_H
8 #define _PSP_PROJECT_PROPERTIESFORM_BASE_CLASSES_H
9 
10 #include <wx/settings.h>
11 #include <wx/xrc/xmlres.h>
12 #include <wx/xrc/xh_bmp.h>
13 #include <wx/dialog.h>
14 #include <wx/iconbndl.h>
15 #include <wx/artprov.h>
16 #include <wx/sizer.h>
17 #include <wx/notebook.h>
18 #include <wx/panel.h>
19 #include <wx/imaglist.h>
20 #include <wx/stattext.h>
21 #include <wx/choice.h>
22 #include <wx/arrstr.h>
23 #include <wx/button.h>
24 #include <wx/textctrl.h>
25 #include <wx/statbox.h>
26 #include <wx/checkbox.h>
27 #include <wx/statbmp.h>
28 #include <wx/grid.h>
29 #include <wx/richtext/richtextctrl.h>
30 #include <wx/hyperlink.h>
31 #if wxVERSION_NUMBER >= 2900
32 #include <wx/persist.h>
33 #include <wx/persist/toplevel.h>
34 #include <wx/persist/bookctrl.h>
35 #include <wx/persist/treebook.h>
36 #endif
37 
38 #ifdef WXC_FROM_DIP
39 #undef WXC_FROM_DIP
40 #endif
41 #if wxVERSION_NUMBER >= 3100
42 #define WXC_FROM_DIP(x) wxWindow::FromDIP(x, NULL)
43 #else
44 #define WXC_FROM_DIP(x) x
45 #endif
46 
47 
48 class GeneralPropertiesFormBase : public wxDialog
49 {
50 protected:
51  wxNotebook* m_notebook;
52  wxPanel* m_panelGeneral;
53  wxStaticText* m_staticTextLanguage;
54  wxChoice* m_choiceLanguage;
55  wxStaticText* m_staticTextTheme;
56  wxChoice* m_choiceTheme;
57  wxButton* m_buttonOK;
58  wxButton* m_buttonCancel;
59 
60 protected:
61  virtual void OnButtonOKClick(wxCommandEvent& event) { event.Skip(); }
62  virtual void OnButtonCancelClick(wxCommandEvent& event) { event.Skip(); }
63 
64 public:
65  wxStaticText* GetStaticTextLanguage() { return m_staticTextLanguage; }
66  wxChoice* GetChoiceLanguage() { return m_choiceLanguage; }
67  wxStaticText* GetStaticTextTheme() { return m_staticTextTheme; }
68  wxChoice* GetChoiceTheme() { return m_choiceTheme; }
69  wxPanel* GetPanelGeneral() { return m_panelGeneral; }
70  wxNotebook* GetNotebook() { return m_notebook; }
71  wxButton* GetButtonOK() { return m_buttonOK; }
72  wxButton* GetButtonCancel() { return m_buttonCancel; }
73  GeneralPropertiesFormBase(wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("General settings"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize(-1,-1), long style = wxDEFAULT_DIALOG_STYLE);
74  virtual ~GeneralPropertiesFormBase();
75 };
76 
77 
78 class SimulationsSettingsFormBase : public wxDialog
79 {
80 protected:
81  wxNotebook* m_notebook;
82  wxPanel* m_panelGeneral;
83  wxStaticText* m_staticTextBasePower;
84  wxTextCtrl* m_textCtrlbasePower;
85  wxChoice* m_choiceBasePower;
86  wxCheckBox* m_checkBoxFaultAfterPF;
87  wxCheckBox* m_checkBoxSCPowerAfterPF;
88  wxPanel* m_panelPF;
89  wxStaticText* m_staticTextPFMethod;
90  wxChoice* m_choicePFMethod;
91  wxStaticText* m_staticTextAccFactor;
92  wxTextCtrl* m_textCtrlAccFactor;
93  wxStaticText* m_staticTextPFTolerance;
94  wxTextCtrl* m_textCtrlPFTolerance;
95  wxStaticText* m_staticTextPFMaxIterations;
96  wxTextCtrl* m_textCtrlPFMaxIterations;
97  wxPanel* m_panelStability;
98  wxStaticText* m_staticTextTimeStep;
99  wxTextCtrl* m_textCtrlTimeStep;
100  wxStaticText* m_staticTextSec_1;
101  wxStaticText* m_staticTextTSimTime;
102  wxTextCtrl* m_textCtrlSimTime;
103  wxStaticText* m_staticTextSec_2;
104  wxStaticText* m_staticTextFreq;
105  wxTextCtrl* m_textCtrlFreq;
106  wxStaticText* m_staticTextFreqUnit;
107  wxStaticText* m_staticTextTStabTolerance;
108  wxTextCtrl* m_textCtrlStabTolerance;
109  wxStaticText* m_staticTextTStabMaxIterations;
110  wxTextCtrl* m_textCtrlStabMaxIterations;
111  wxStaticText* m_staticTextCtrlStepRation;
112  wxTextCtrl* m_textCtrlCtrlStepRatio;
113  wxStaticText* m_staticTextPrintTime;
114  wxTextCtrl* m_textCtrlPrintTime;
115  wxStaticText* m_staticTextSec_4;
116  wxCheckBox* m_checkBoxUseCOI;
117  wxButton* m_buttonOK;
118  wxButton* m_buttonCancel;
119 
120 protected:
121  virtual void OnPFMethodChoiceSelected(wxCommandEvent& event) { event.Skip(); }
122  virtual void OnButtonOKClick(wxCommandEvent& event) { event.Skip(); }
123  virtual void OnButtonCancelClick(wxCommandEvent& event) { event.Skip(); }
124 
125 public:
126  wxStaticText* GetStaticTextBasePower() { return m_staticTextBasePower; }
127  wxTextCtrl* GetTextCtrlbasePower() { return m_textCtrlbasePower; }
128  wxChoice* GetChoiceBasePower() { return m_choiceBasePower; }
129  wxCheckBox* GetCheckBoxFaultAfterPF() { return m_checkBoxFaultAfterPF; }
130  wxCheckBox* GetCheckBoxSCPowerAfterPF() { return m_checkBoxSCPowerAfterPF; }
131  wxPanel* GetPanelGeneral() { return m_panelGeneral; }
132  wxStaticText* GetStaticTextPFMethod() { return m_staticTextPFMethod; }
133  wxChoice* GetChoicePFMethod() { return m_choicePFMethod; }
134  wxStaticText* GetStaticTextAccFactor() { return m_staticTextAccFactor; }
135  wxTextCtrl* GetTextCtrlAccFactor() { return m_textCtrlAccFactor; }
136  wxStaticText* GetStaticTextPFTolerance() { return m_staticTextPFTolerance; }
137  wxTextCtrl* GetTextCtrlPFTolerance() { return m_textCtrlPFTolerance; }
138  wxStaticText* GetStaticTextPFMaxIterations() { return m_staticTextPFMaxIterations; }
139  wxTextCtrl* GetTextCtrlPFMaxIterations() { return m_textCtrlPFMaxIterations; }
140  wxPanel* GetPanelPF() { return m_panelPF; }
141  wxStaticText* GetStaticTextTimeStep() { return m_staticTextTimeStep; }
142  wxTextCtrl* GetTextCtrlTimeStep() { return m_textCtrlTimeStep; }
143  wxStaticText* GetStaticTextSec_1() { return m_staticTextSec_1; }
144  wxStaticText* GetStaticTextTSimTime() { return m_staticTextTSimTime; }
145  wxTextCtrl* GetTextCtrlSimTime() { return m_textCtrlSimTime; }
146  wxStaticText* GetStaticTextSec_2() { return m_staticTextSec_2; }
147  wxStaticText* GetStaticTextFreq() { return m_staticTextFreq; }
148  wxTextCtrl* GetTextCtrlFreq() { return m_textCtrlFreq; }
149  wxStaticText* GetStaticTextFreqUnit() { return m_staticTextFreqUnit; }
150  wxStaticText* GetStaticTextTStabTolerance() { return m_staticTextTStabTolerance; }
151  wxTextCtrl* GetTextCtrlStabTolerance() { return m_textCtrlStabTolerance; }
152  wxStaticText* GetStaticTextTStabMaxIterations() { return m_staticTextTStabMaxIterations; }
153  wxTextCtrl* GetTextCtrlStabMaxIterations() { return m_textCtrlStabMaxIterations; }
154  wxStaticText* GetStaticTextCtrlStepRation() { return m_staticTextCtrlStepRation; }
155  wxTextCtrl* GetTextCtrlCtrlStepRatio() { return m_textCtrlCtrlStepRatio; }
156  wxStaticText* GetStaticTextPrintTime() { return m_staticTextPrintTime; }
157  wxTextCtrl* GetTextCtrlPrintTime() { return m_textCtrlPrintTime; }
158  wxStaticText* GetStaticTextSec_4() { return m_staticTextSec_4; }
159  wxCheckBox* GetCheckBoxUseCOI() { return m_checkBoxUseCOI; }
160  wxPanel* GetPanelStability() { return m_panelStability; }
161  wxNotebook* GetNotebook() { return m_notebook; }
162  wxButton* GetButtonOK() { return m_buttonOK; }
163  wxButton* GetButtonCancel() { return m_buttonCancel; }
164  SimulationsSettingsFormBase(wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Simulation settings"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize(-1,-1), long style = wxDEFAULT_DIALOG_STYLE);
165  virtual ~SimulationsSettingsFormBase();
166 };
167 
168 
169 class AboutFormBase : public wxDialog
170 {
171 protected:
172  wxNotebook* m_notebook;
173  wxPanel* m_panelLogo;
174  wxStaticBitmap* m_staticBitmapLogo;
175  wxPanel* m_panelCredits;
176  wxGrid* m_gridCredits;
177  wxPanel* m_panelLicense;
178  wxRichTextCtrl* m_richTextCtrlLicense;
179  wxStaticText* m_staticTextVersionLabel;
180  wxStaticText* m_staticTextVersion;
181  wxStaticText* m_staticTextHome;
182  wxHyperlinkCtrl* m_hyperLinkPSP;
183  wxButton* m_buttonOK;
184 
185 protected:
186  virtual void OnOKButtonClick(wxCommandEvent& event) { event.Skip(); }
187 
188 public:
189  wxStaticBitmap* GetStaticBitmapLogo() { return m_staticBitmapLogo; }
190  wxPanel* GetPanelLogo() { return m_panelLogo; }
191  wxGrid* GetGridCredits() { return m_gridCredits; }
192  wxPanel* GetPanelCredits() { return m_panelCredits; }
193  wxRichTextCtrl* GetRichTextCtrlLicense() { return m_richTextCtrlLicense; }
194  wxPanel* GetPanelLicense() { return m_panelLicense; }
195  wxNotebook* GetNotebook() { return m_notebook; }
196  wxStaticText* GetStaticTextVersionLabel() { return m_staticTextVersionLabel; }
197  wxStaticText* GetStaticTextVersion() { return m_staticTextVersion; }
198  wxStaticText* GetStaticTextHome() { return m_staticTextHome; }
199  wxHyperlinkCtrl* GetHyperLinkPSP() { return m_hyperLinkPSP; }
200  wxButton* GetButtonOK() { return m_buttonOK; }
201  AboutFormBase(wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("About PSP-UFU"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize(-1,-1), long style = wxDEFAULT_DIALOG_STYLE);
202  virtual ~AboutFormBase();
203 };
204 
205 #endif
- +
1 // This file was auto-generated by codelite's wxCrafter Plugin
3 // wxCrafter project file: PropertiesForm.wxcp
4 // Do not modify this file by hand!
6 
7 #ifndef _PSP_PROJECT_PROPERTIESFORM_BASE_CLASSES_H
8 #define _PSP_PROJECT_PROPERTIESFORM_BASE_CLASSES_H
9 
10 #include <wx/settings.h>
11 #include <wx/xrc/xmlres.h>
12 #include <wx/xrc/xh_bmp.h>
13 #include <wx/dialog.h>
14 #include <wx/iconbndl.h>
15 #include <wx/artprov.h>
16 #include <wx/sizer.h>
17 #include <wx/notebook.h>
18 #include <wx/panel.h>
19 #include <wx/imaglist.h>
20 #include <wx/stattext.h>
21 #include <wx/choice.h>
22 #include <wx/arrstr.h>
23 #include <wx/button.h>
24 #include <wx/textctrl.h>
25 #include <wx/statbox.h>
26 #include <wx/checkbox.h>
27 #include <wx/statbmp.h>
28 #include <wx/grid.h>
29 #include <wx/richtext/richtextctrl.h>
30 #include <wx/hyperlink.h>
31 #if wxVERSION_NUMBER >= 2900
32 #include <wx/persist.h>
33 #include <wx/persist/toplevel.h>
34 #include <wx/persist/bookctrl.h>
35 #include <wx/persist/treebook.h>
36 #endif
37 
38 #ifdef WXC_FROM_DIP
39 #undef WXC_FROM_DIP
40 #endif
41 #if wxVERSION_NUMBER >= 3100
42 #define WXC_FROM_DIP(x) wxWindow::FromDIP(x, NULL)
43 #else
44 #define WXC_FROM_DIP(x) x
45 #endif
46 
47 
48 class GeneralPropertiesFormBase : public wxDialog
49 {
50 protected:
51  wxNotebook* m_notebook;
52  wxPanel* m_panelGeneral;
53  wxStaticText* m_staticTextLanguage;
54  wxChoice* m_choiceLanguage;
55  wxStaticText* m_staticTextTheme;
56  wxChoice* m_choiceTheme;
57  wxButton* m_buttonOK;
58  wxButton* m_buttonCancel;
59 
60 protected:
61  virtual void OnButtonOKClick(wxCommandEvent& event) { event.Skip(); }
62  virtual void OnButtonCancelClick(wxCommandEvent& event) { event.Skip(); }
63 
64 public:
65  wxStaticText* GetStaticTextLanguage() { return m_staticTextLanguage; }
66  wxChoice* GetChoiceLanguage() { return m_choiceLanguage; }
67  wxStaticText* GetStaticTextTheme() { return m_staticTextTheme; }
68  wxChoice* GetChoiceTheme() { return m_choiceTheme; }
69  wxPanel* GetPanelGeneral() { return m_panelGeneral; }
70  wxNotebook* GetNotebook() { return m_notebook; }
71  wxButton* GetButtonOK() { return m_buttonOK; }
72  wxButton* GetButtonCancel() { return m_buttonCancel; }
73  GeneralPropertiesFormBase(wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("General settings"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize(-1,-1), long style = wxDEFAULT_DIALOG_STYLE);
74  virtual ~GeneralPropertiesFormBase();
75 };
76 
77 
78 class SimulationsSettingsFormBase : public wxDialog
79 {
80 protected:
81  wxNotebook* m_notebook;
82  wxPanel* m_panelGeneral;
83  wxStaticText* m_staticTextBasePower;
84  wxTextCtrl* m_textCtrlbasePower;
85  wxChoice* m_choiceBasePower;
86  wxCheckBox* m_checkBoxFaultAfterPF;
87  wxCheckBox* m_checkBoxSCPowerAfterPF;
88  wxPanel* m_panelPF;
89  wxStaticText* m_staticTextPFMethod;
90  wxChoice* m_choicePFMethod;
91  wxStaticText* m_staticTextAccFactor;
92  wxTextCtrl* m_textCtrlAccFactor;
93  wxStaticText* m_staticTextPFTolerance;
94  wxTextCtrl* m_textCtrlPFTolerance;
95  wxStaticText* m_staticTextPFMaxIterations;
96  wxTextCtrl* m_textCtrlPFMaxIterations;
97  wxPanel* m_panelStability;
98  wxStaticText* m_staticTextTimeStep;
99  wxTextCtrl* m_textCtrlTimeStep;
100  wxStaticText* m_staticTextSec_1;
101  wxStaticText* m_staticTextTSimTime;
102  wxTextCtrl* m_textCtrlSimTime;
103  wxStaticText* m_staticTextSec_2;
104  wxStaticText* m_staticTextFreq;
105  wxTextCtrl* m_textCtrlFreq;
106  wxStaticText* m_staticTextFreqUnit;
107  wxStaticText* m_staticTextTStabTolerance;
108  wxTextCtrl* m_textCtrlStabTolerance;
109  wxStaticText* m_staticTextTStabMaxIterations;
110  wxTextCtrl* m_textCtrlStabMaxIterations;
111  wxStaticText* m_staticTextCtrlStepRation;
112  wxTextCtrl* m_textCtrlCtrlStepRatio;
113  wxStaticText* m_staticTextPrintTime;
114  wxTextCtrl* m_textCtrlPrintTime;
115  wxStaticText* m_staticTextSec_4;
116  wxCheckBox* m_checkBoxUseCOI;
117  wxPanel* m_panelLoadComp;
118  wxCheckBox* m_checkBoxUseCompLoads;
119  wxStaticText* m_staticTextActivePowerImp;
120  wxTextCtrl* m_textCtrlActivePowerImp;
121  wxStaticText* m_staticTextPerc_1;
122  wxStaticText* m_staticTextActivePowerCur;
123  wxTextCtrl* m_textCtrlActivePowerCur;
124  wxStaticText* m_staticTextPerc_2;
125  wxStaticText* m_staticTextActivePowerPow;
126  wxTextCtrl* m_textCtrlActivePowerPow;
127  wxStaticText* m_staticTextPerc_3;
128  wxStaticText* m_staticTextReactivePowerImp;
129  wxTextCtrl* m_textCtrlReactivePowerImp;
130  wxStaticText* m_staticTextPerc_4;
131  wxStaticText* m_staticTextReactivePowerCur;
132  wxTextCtrl* m_textCtrlReactivePowerCur;
133  wxStaticText* m_staticTextPerc_5;
134  wxStaticText* m_staticTextReactivePowerPow;
135  wxTextCtrl* m_textCtrlReactivePowerPow;
136  wxStaticText* m_staticTextPerc_6;
137  wxStaticText* m_staticTextUV;
138  wxStaticText* m_staticTextUVCur;
139  wxTextCtrl* m_textCtrlUVCur;
140  wxStaticText* m_staticTextPerc_7;
141  wxStaticText* m_staticTextUVPow;
142  wxTextCtrl* m_textCtrlUVPow;
143  wxStaticText* m_staticTextPerc_8;
144  wxButton* m_buttonOK;
145  wxButton* m_buttonCancel;
146 
147 protected:
148  virtual void OnPFMethodChoiceSelected(wxCommandEvent& event) { event.Skip(); }
149  virtual void OnCheckboxUseCompLoadClick(wxCommandEvent& event) { event.Skip(); }
150  virtual void OnButtonOKClick(wxCommandEvent& event) { event.Skip(); }
151  virtual void OnButtonCancelClick(wxCommandEvent& event) { event.Skip(); }
152 
153 public:
154  wxStaticText* GetStaticTextBasePower() { return m_staticTextBasePower; }
155  wxTextCtrl* GetTextCtrlbasePower() { return m_textCtrlbasePower; }
156  wxChoice* GetChoiceBasePower() { return m_choiceBasePower; }
157  wxCheckBox* GetCheckBoxFaultAfterPF() { return m_checkBoxFaultAfterPF; }
158  wxCheckBox* GetCheckBoxSCPowerAfterPF() { return m_checkBoxSCPowerAfterPF; }
159  wxPanel* GetPanelGeneral() { return m_panelGeneral; }
160  wxStaticText* GetStaticTextPFMethod() { return m_staticTextPFMethod; }
161  wxChoice* GetChoicePFMethod() { return m_choicePFMethod; }
162  wxStaticText* GetStaticTextAccFactor() { return m_staticTextAccFactor; }
163  wxTextCtrl* GetTextCtrlAccFactor() { return m_textCtrlAccFactor; }
164  wxStaticText* GetStaticTextPFTolerance() { return m_staticTextPFTolerance; }
165  wxTextCtrl* GetTextCtrlPFTolerance() { return m_textCtrlPFTolerance; }
166  wxStaticText* GetStaticTextPFMaxIterations() { return m_staticTextPFMaxIterations; }
167  wxTextCtrl* GetTextCtrlPFMaxIterations() { return m_textCtrlPFMaxIterations; }
168  wxPanel* GetPanelPF() { return m_panelPF; }
169  wxStaticText* GetStaticTextTimeStep() { return m_staticTextTimeStep; }
170  wxTextCtrl* GetTextCtrlTimeStep() { return m_textCtrlTimeStep; }
171  wxStaticText* GetStaticTextSec_1() { return m_staticTextSec_1; }
172  wxStaticText* GetStaticTextTSimTime() { return m_staticTextTSimTime; }
173  wxTextCtrl* GetTextCtrlSimTime() { return m_textCtrlSimTime; }
174  wxStaticText* GetStaticTextSec_2() { return m_staticTextSec_2; }
175  wxStaticText* GetStaticTextFreq() { return m_staticTextFreq; }
176  wxTextCtrl* GetTextCtrlFreq() { return m_textCtrlFreq; }
177  wxStaticText* GetStaticTextFreqUnit() { return m_staticTextFreqUnit; }
178  wxStaticText* GetStaticTextTStabTolerance() { return m_staticTextTStabTolerance; }
179  wxTextCtrl* GetTextCtrlStabTolerance() { return m_textCtrlStabTolerance; }
180  wxStaticText* GetStaticTextTStabMaxIterations() { return m_staticTextTStabMaxIterations; }
181  wxTextCtrl* GetTextCtrlStabMaxIterations() { return m_textCtrlStabMaxIterations; }
182  wxStaticText* GetStaticTextCtrlStepRation() { return m_staticTextCtrlStepRation; }
183  wxTextCtrl* GetTextCtrlCtrlStepRatio() { return m_textCtrlCtrlStepRatio; }
184  wxStaticText* GetStaticTextPrintTime() { return m_staticTextPrintTime; }
185  wxTextCtrl* GetTextCtrlPrintTime() { return m_textCtrlPrintTime; }
186  wxStaticText* GetStaticTextSec_4() { return m_staticTextSec_4; }
187  wxCheckBox* GetCheckBoxUseCOI() { return m_checkBoxUseCOI; }
188  wxPanel* GetPanelStability() { return m_panelStability; }
189  wxCheckBox* GetCheckBoxUseCompLoads() { return m_checkBoxUseCompLoads; }
190  wxStaticText* GetStaticTextActivePowerImp() { return m_staticTextActivePowerImp; }
191  wxTextCtrl* GetTextCtrlActivePowerImp() { return m_textCtrlActivePowerImp; }
192  wxStaticText* GetStaticTextPerc_1() { return m_staticTextPerc_1; }
193  wxStaticText* GetStaticTextActivePowerCur() { return m_staticTextActivePowerCur; }
194  wxTextCtrl* GetTextCtrlActivePowerCur() { return m_textCtrlActivePowerCur; }
195  wxStaticText* GetStaticTextPerc_2() { return m_staticTextPerc_2; }
196  wxStaticText* GetStaticTextActivePowerPow() { return m_staticTextActivePowerPow; }
197  wxTextCtrl* GetTextCtrlActivePowerPow() { return m_textCtrlActivePowerPow; }
198  wxStaticText* GetStaticTextPerc_3() { return m_staticTextPerc_3; }
199  wxStaticText* GetStaticTextReactivePowerImp() { return m_staticTextReactivePowerImp; }
200  wxTextCtrl* GetTextCtrlReactivePowerImp() { return m_textCtrlReactivePowerImp; }
201  wxStaticText* GetStaticTextPerc_4() { return m_staticTextPerc_4; }
202  wxStaticText* GetStaticTextReactivePowerCur() { return m_staticTextReactivePowerCur; }
203  wxTextCtrl* GetTextCtrlReactivePowerCur() { return m_textCtrlReactivePowerCur; }
204  wxStaticText* GetStaticTextPerc_5() { return m_staticTextPerc_5; }
205  wxStaticText* GetStaticTextReactivePowerPow() { return m_staticTextReactivePowerPow; }
206  wxTextCtrl* GetTextCtrlReactivePowerPow() { return m_textCtrlReactivePowerPow; }
207  wxStaticText* GetStaticTextPerc_6() { return m_staticTextPerc_6; }
208  wxStaticText* GetStaticTextUV() { return m_staticTextUV; }
209  wxStaticText* GetStaticTextUVCur() { return m_staticTextUVCur; }
210  wxTextCtrl* GetTextCtrlUVCur() { return m_textCtrlUVCur; }
211  wxStaticText* GetStaticTextPerc_7() { return m_staticTextPerc_7; }
212  wxStaticText* GetStaticTextUVPow() { return m_staticTextUVPow; }
213  wxTextCtrl* GetTextCtrlUVPow() { return m_textCtrlUVPow; }
214  wxStaticText* GetStaticTextPerc_8() { return m_staticTextPerc_8; }
215  wxPanel* GetPanelLoadComp() { return m_panelLoadComp; }
216  wxNotebook* GetNotebook() { return m_notebook; }
217  wxButton* GetButtonOK() { return m_buttonOK; }
218  wxButton* GetButtonCancel() { return m_buttonCancel; }
219  SimulationsSettingsFormBase(wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Simulation settings"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize(-1,-1), long style = wxDEFAULT_DIALOG_STYLE);
220  virtual ~SimulationsSettingsFormBase();
221 };
222 
223 
224 class AboutFormBase : public wxDialog
225 {
226 protected:
227  wxNotebook* m_notebook;
228  wxPanel* m_panelLogo;
229  wxStaticBitmap* m_staticBitmapLogo;
230  wxPanel* m_panelCredits;
231  wxGrid* m_gridCredits;
232  wxPanel* m_panelLicense;
233  wxRichTextCtrl* m_richTextCtrlLicense;
234  wxStaticText* m_staticTextVersionLabel;
235  wxStaticText* m_staticTextVersion;
236  wxStaticText* m_staticTextHome;
237  wxHyperlinkCtrl* m_hyperLinkPSP;
238  wxButton* m_buttonOK;
239 
240 protected:
241  virtual void OnOKButtonClick(wxCommandEvent& event) { event.Skip(); }
242 
243 public:
244  wxStaticBitmap* GetStaticBitmapLogo() { return m_staticBitmapLogo; }
245  wxPanel* GetPanelLogo() { return m_panelLogo; }
246  wxGrid* GetGridCredits() { return m_gridCredits; }
247  wxPanel* GetPanelCredits() { return m_panelCredits; }
248  wxRichTextCtrl* GetRichTextCtrlLicense() { return m_richTextCtrlLicense; }
249  wxPanel* GetPanelLicense() { return m_panelLicense; }
250  wxNotebook* GetNotebook() { return m_notebook; }
251  wxStaticText* GetStaticTextVersionLabel() { return m_staticTextVersionLabel; }
252  wxStaticText* GetStaticTextVersion() { return m_staticTextVersion; }
253  wxStaticText* GetStaticTextHome() { return m_staticTextHome; }
254  wxHyperlinkCtrl* GetHyperLinkPSP() { return m_hyperLinkPSP; }
255  wxButton* GetButtonOK() { return m_buttonOK; }
256  AboutFormBase(wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("About PSP-UFU"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize(-1,-1), long style = wxDEFAULT_DIALOG_STYLE);
257  virtual ~AboutFormBase();
258 };
259 
260 #endif
+
diff --git a/docs/doxygen/html/_properties_form_bitmaps_8cpp_source.html b/docs/doxygen/html/_properties_form_bitmaps_8cpp_source.html index aeb0d0b..e43af91 100644 --- a/docs/doxygen/html/_properties_form_bitmaps_8cpp_source.html +++ b/docs/doxygen/html/_properties_form_bitmaps_8cpp_source.html @@ -88,7 +88,7 @@ $(document).ready(function(){initNavTree('_properties_form_bitmaps_8cpp_source.h
PropertiesFormBitmaps.cpp
-
1 //
2 // This file was automatically generated by wxrc, do not edit by hand.
3 //
4 
5 #include <wx/wxprec.h>
6 
7 #ifdef __BORLANDC__
8  #pragma hdrstop
9 #endif
10 
11 #include <wx/filesys.h>
12 #include <wx/fs_mem.h>
13 #include <wx/xrc/xmlres.h>
14 #include <wx/xrc/xh_all.h>
15 
16 #if wxCHECK_VERSION(2,8,5) && wxABI_VERSION >= 20805
17  #define XRC_ADD_FILE(name, data, size, mime) \
18  wxMemoryFSHandler::AddFileWithMimeType(name, data, size, mime)
19 #else
20  #define XRC_ADD_FILE(name, data, size, mime) \
21  wxMemoryFSHandler::AddFile(name, data, size)
22 #endif
23 
24 static size_t xml_res_size_0 = 52890;
25 static unsigned char xml_res_file_0[] = {
26 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,2,88,0,0,1,138,8,2,0,
27 0,0,95,26,168,50,0,0,0,1,115,82,71,66,0,174,206,28,233,0,0,0,4,103,65,77,
28 65,0,0,177,143,11,252,97,5,0,0,0,9,112,72,89,115,0,0,14,195,0,0,14,195,
29 1,199,111,168,100,0,0,0,25,116,69,88,116,83,111,102,116,119,97,114,101,
30 0,112,97,105,110,116,46,110,101,116,32,52,46,48,46,49,55,51,110,159,99,
31 0,0,206,10,73,68,65,84,120,94,236,157,7,152,27,197,253,247,99,12,24,3,54,
32 152,222,59,9,157,80,67,239,161,5,18,146,208,33,148,208,75,32,188,127,106,
33 32,128,68,53,216,96,211,139,193,52,3,38,128,43,24,247,118,189,247,234,235,
34 189,247,94,244,126,78,51,90,214,187,146,78,39,223,233,86,210,124,159,121,
35 238,180,179,51,187,59,237,247,153,223,214,223,56,148,148,148,148,148,148,
36 194,88,10,132,193,167,238,30,25,148,148,148,44,165,30,215,216,84,195,51,
37 184,164,64,24,124,250,37,209,177,36,118,40,180,119,202,24,37,37,37,43,168,
38 190,81,142,205,159,226,100,140,210,24,105,112,80,134,81,145,255,32,108,
39 110,149,161,191,95,198,40,5,70,140,177,5,81,67,161,173,67,198,40,5,181,
40 58,58,135,198,81,75,171,163,183,87,198,40,5,169,234,27,228,216,92,28,35,
41 99,148,198,66,237,29,142,172,34,71,90,129,163,162,118,116,88,232,63,8,151,
42 39,56,126,137,31,10,12,96,165,64,74,129,48,196,180,169,108,104,28,173,76,
43 116,212,54,200,24,165,32,149,2,97,96,84,215,40,205,96,122,129,99,96,64,
44 70,110,137,252,7,225,66,103,123,19,154,154,101,140,82,96,164,64,24,98,202,
45 43,25,106,77,76,103,117,157,140,81,10,82,41,16,6,70,10,132,74,10,132,161,
46 38,5,194,144,145,2,97,96,164,64,168,164,64,24,106,82,32,12,25,41,16,6,70,
47 10,132,74,10,132,161,38,5,194,144,145,2,97,96,164,64,168,164,64,24,106,
48 82,32,12,25,41,16,6,70,10,132,74,10,132,161,38,5,194,144,145,2,97,96,164,
49 64,168,164,64,24,106,82,32,12,25,41,16,6,70,10,132,74,10,132,161,38,5,194,
50 144,145,2,97,96,164,64,168,164,64,24,106,82,32,12,25,41,16,6,70,10,132,
51 74,10,132,161,38,5,194,144,145,2,97,96,164,64,168,164,64,24,106,82,32,12,
52 25,41,16,6,70,10,132,74,10,132,161,38,5,194,144,145,2,97,96,164,64,168,
53 164,64,24,106,82,32,12,25,41,16,6,70,10,132,142,158,158,158,198,198,198,
54 134,134,134,254,112,253,254,147,2,97,136,73,129,48,100,164,64,24,24,133,
55 59,8,123,123,123,55,109,218,180,110,221,186,181,107,215,242,99,96,84,234,
56 32,216,164,64,24,98,82,32,12,25,41,16,6,70,225,14,194,214,214,214,168,168,
57 40,40,40,212,210,210,34,87,184,4,26,113,25,73,86,235,20,176,108,106,106,
58 98,177,175,175,79,166,240,44,210,136,140,5,5,5,249,249,249,252,96,251,237,
59 237,237,86,115,61,21,8,67,76,10,132,33,35,107,130,16,147,216,217,217,89,
60 87,87,87,85,85,149,155,155,203,95,12,93,87,87,151,92,237,89,56,30,36,171,
61 175,175,175,174,174,38,99,101,101,37,25,209,184,123,32,10,132,155,129,176,
62 177,177,81,174,112,170,163,163,35,51,51,51,50,50,146,52,144,140,102,43,
63 47,47,79,76,76,140,136,136,136,143,143,167,45,7,61,124,204,152,198,166,
64 153,201,40,82,242,187,162,162,162,180,180,52,38,38,134,24,226,201,43,147,
65 90,64,10,132,33,38,5,194,144,145,213,64,200,36,30,83,134,61,196,142,101,
66 101,101,49,197,103,17,247,128,69,68,60,22,85,38,221,92,160,14,94,70,71,
67 71,147,12,163,74,22,50,146,29,219,72,12,38,17,58,118,119,119,203,212,1,
68 87,184,131,144,169,77,122,122,58,237,135,104,21,25,235,68,96,81,81,81,114,
69 114,50,179,30,183,205,195,132,40,47,47,15,200,209,156,250,169,16,241,180,
70 49,192,99,179,248,127,102,82,146,128,29,145,145,62,65,2,43,120,135,10,132,
71 33,38,5,194,144,145,69,64,136,29,195,12,50,125,207,206,206,46,44,44,196,
72 226,153,79,137,225,237,53,53,53,37,37,37,193,54,126,104,150,141,31,181,
73 181,181,105,105,105,184,16,13,13,13,36,19,241,154,216,84,115,115,51,25,
74 217,56,86,215,151,147,109,163,46,117,179,204,80,251,181,59,165,53,64,77,
75 77,13,205,166,111,75,79,162,115,224,38,166,164,164,136,115,170,109,109,
76 109,52,39,156,27,214,217,7,192,204,143,216,75,106,106,234,184,52,188,94,
77 10,132,33,38,5,194,144,145,69,64,136,49,132,82,229,229,229,204,227,61,157,
78 6,19,194,238,145,24,103,0,97,63,49,110,57,57,57,248,12,141,141,141,222,
79 77,34,155,5,135,80,54,35,35,35,240,174,161,2,161,81,80,16,239,16,143,80,
80 46,251,32,218,56,54,54,150,140,113,113,113,56,248,222,59,138,94,244,170,
81 200,200,72,124,199,241,245,11,21,8,67,76,10,132,33,35,43,128,16,39,1,251,
82 230,246,252,150,39,97,208,240,11,75,75,75,161,32,4,245,125,174,207,46,192,
83 109,102,102,102,128,77,162,2,225,102,98,74,130,151,54,34,10,10,225,23,174,
84 93,187,182,172,172,76,46,251,172,174,174,174,132,132,132,146,146,18,223,
85 59,217,168,75,129,48,196,164,64,24,50,26,119,16,226,222,97,160,26,26,26,
86 228,178,207,98,150,31,19,19,51,82,167,2,225,56,226,23,226,30,232,47,57,
87 141,181,20,8,127,85,107,107,107,82,82,146,56,201,57,82,37,38,38,22,23,23,
88 243,215,15,167,158,30,195,126,43,42,42,228,114,192,165,64,24,98,82,32,12,
89 25,141,47,8,113,203,112,206,96,161,92,246,89,76,235,139,138,138,242,243,
90 243,225,25,78,130,140,245,89,226,206,154,188,188,60,239,103,83,71,81,10,
91 132,82,180,92,92,92,156,225,174,81,31,85,95,95,207,164,137,45,192,51,154,
92 95,198,142,68,226,70,172,192,159,25,23,82,32,12,49,41,16,134,140,198,23,
93 132,109,109,109,57,57,57,126,156,165,236,235,235,203,206,206,38,59,22,213,
94 191,243,156,100,129,163,126,156,156,243,79,10,132,82,117,117,117,25,25,
95 25,114,97,36,162,201,161,96,123,123,59,191,241,237,162,163,163,249,43,86,
96 249,46,54,2,68,75,75,75,199,229,4,169,2,97,136,73,129,48,100,52,142,32,
97 236,234,234,130,97,24,70,185,60,18,149,148,148,100,101,101,225,207,97,217,
98 210,210,210,252,115,48,112,10,113,40,3,99,18,21,8,135,68,131,49,127,241,
99 244,4,140,119,137,167,236,181,214,42,44,44,244,227,84,0,18,119,156,246,
100 244,244,200,229,0,74,129,48,196,164,64,24,50,26,71,16,138,123,0,253,56,
101 57,137,33,141,137,137,209,78,168,86,87,87,179,40,126,143,72,24,67,14,32,
102 48,87,10,3,10,194,161,9,66,127,159,33,104,171,22,71,118,45,142,108,35,52,
103 52,74,63,186,163,187,163,186,169,90,31,26,90,26,6,6,61,31,230,96,191,163,
104 215,159,90,235,237,237,205,203,203,243,3,66,240,15,255,189,166,166,70,46,
105 59,121,6,83,253,59,153,192,49,248,116,118,20,232,246,25,159,197,241,174,
106 182,206,182,162,234,34,125,168,109,170,21,240,230,80,87,199,212,255,18,
107 81,71,104,109,147,205,65,187,52,119,54,235,67,123,119,251,184,120,171,163,
108 35,142,220,213,211,66,67,189,125,189,45,157,45,134,54,146,235,134,64,216,
109 191,40,178,123,105,116,79,117,157,28,44,140,175,238,222,238,238,158,205,
110 130,88,165,52,238,162,117,12,146,43,134,64,136,97,28,178,138,75,162,101,
111 7,102,24,214,183,212,27,12,99,103,183,207,103,161,24,11,189,221,190,24,
112 251,132,132,132,250,250,122,185,48,18,53,55,55,199,199,199,203,5,167,117,
113 141,142,142,246,143,103,165,165,165,197,197,197,114,193,71,1,136,1,247,
114 230,215,208,255,25,17,90,85,215,53,14,46,139,237,89,20,217,147,81,48,168,
115 213,141,121,200,248,110,216,189,129,176,160,166,32,58,63,90,31,242,202,
116 243,104,87,113,58,120,205,186,24,241,122,151,204,204,60,168,64,124,94,85,
117 222,130,228,5,250,16,147,23,163,177,211,141,186,154,29,5,171,29,85,201,
118 142,238,145,185,54,52,82,70,70,134,31,244,26,58,200,188,60,26,94,46,59,
119 207,142,102,101,101,113,252,114,217,103,209,36,226,65,84,185,236,69,244,
120 227,210,228,161,98,118,182,250,104,223,169,121,67,77,166,20,167,244,15,
121 80,226,126,220,89,241,170,85,148,158,158,14,200,73,95,211,92,99,72,191,
122 33,119,67,79,239,56,120,171,163,163,254,94,71,101,186,163,42,197,225,187,
123 189,176,182,202,107,203,23,165,44,50,180,145,88,213,222,222,158,144,144,
124 182,102,93,252,218,245,241,121,249,133,162,87,55,181,54,69,230,70,174,203,
125 90,167,15,125,3,161,50,57,232,108,115,180,143,199,5,149,209,16,6,45,187,
126 34,59,161,40,65,31,90,58,134,110,217,99,90,156,153,153,43,198,230,154,245,
127 41,229,229,229,88,9,210,71,229,70,25,154,158,1,238,211,60,181,171,221,81,
128 149,238,40,140,28,170,49,175,162,219,196,197,197,249,119,146,12,199,192,
129 112,86,12,143,208,191,83,172,108,10,163,36,23,134,21,53,208,214,228,168,
130 72,118,52,253,234,153,232,181,62,123,189,190,255,111,204,217,88,223,60,
131 68,122,106,181,176,176,108,221,134,132,53,235,18,98,227,179,154,92,246,
132 60,34,55,66,159,158,80,89,231,235,217,62,111,32,76,42,77,50,180,95,74,65,
133 10,237,215,209,209,17,165,123,207,25,118,185,170,170,202,79,16,102,47,24,
134 10,121,63,59,106,243,135,234,197,55,65,50,255,64,72,13,130,112,253,69,65,
135 250,46,51,41,63,110,123,161,188,48,201,167,41,24,32,44,88,239,44,230,79,
136 142,154,92,71,203,240,89,60,129,176,165,165,101,253,250,245,178,222,157,
137 42,44,44,36,125,8,130,176,56,66,118,140,186,2,223,59,134,101,229,5,132,
138 177,177,177,178,45,215,174,165,113,133,1,98,192,255,148,246,147,33,189,
139 183,161,228,69,61,173,142,186,44,71,109,134,37,66,105,172,35,233,19,71,
140 252,7,142,156,101,142,26,211,90,115,104,200,119,12,140,236,108,202,88,11,
141 231,126,99,238,70,67,211,224,228,177,138,193,168,77,82,17,45,139,169,241,
142 19,132,12,222,234,194,161,254,159,189,208,145,187,116,88,16,178,35,232,
143 165,57,76,35,18,232,170,173,173,149,11,78,21,20,20,248,241,104,25,18,135,
144 225,147,95,209,211,229,40,207,116,228,254,52,84,192,250,114,25,185,185,
145 12,149,182,56,101,113,117,195,80,61,131,27,189,25,140,136,136,16,103,7,
146 151,164,45,49,100,41,174,242,213,61,253,13,62,141,39,197,108,138,49,108,
147 55,54,55,182,177,169,49,59,59,91,30,130,75,73,73,73,0,38,46,39,206,144,
148 126,73,226,146,236,220,108,86,25,68,69,23,21,21,85,20,102,73,16,138,144,
149 179,184,189,178,160,164,152,53,195,40,45,45,13,199,206,167,41,213,230,130,
150 157,201,201,201,250,151,6,209,102,169,169,169,122,52,250,174,146,146,146,
151 148,148,20,121,76,158,85,86,144,211,151,185,88,87,204,69,125,101,185,37,
152 67,175,245,150,202,201,201,193,43,133,199,204,233,132,214,38,173,53,212,
153 228,242,164,229,177,113,177,209,209,209,178,198,93,162,230,153,205,101,
154 23,102,27,210,175,72,91,81,90,94,90,29,156,170,171,170,24,40,88,247,107,
155 141,229,46,233,171,43,170,173,169,146,171,131,80,217,69,52,208,162,121,
156 241,11,231,68,45,126,123,227,146,153,235,150,190,182,230,167,149,185,181,
157 75,210,43,94,95,24,249,236,119,27,31,253,122,227,3,95,69,60,244,85,196,
158 75,63,165,206,75,170,250,38,177,112,250,154,21,175,174,254,233,245,181,
159 63,189,177,110,233,123,17,75,230,198,44,42,40,175,168,26,97,29,52,231,71,
160 245,127,122,150,195,62,193,97,255,77,176,133,9,189,111,29,222,153,248,85,
161 103,123,27,195,115,11,213,213,213,197,168,31,21,117,116,118,172,207,89,
162 111,24,110,149,13,149,236,5,107,32,135,165,75,152,202,252,130,124,204,160,
163 33,125,82,254,208,253,234,158,212,81,158,231,200,91,161,245,255,193,156,
164 197,181,133,57,114,157,7,97,15,225,174,31,38,17,118,98,67,12,19,122,40,
165 136,141,149,11,35,17,64,138,140,140,148,199,228,65,45,181,149,142,234,28,
166 71,206,82,173,128,61,229,67,167,214,204,50,84,26,83,201,130,178,2,226,177,
167 153,178,126,93,42,45,29,178,117,144,210,144,37,179,48,83,12,132,97,245,
168 155,161,87,235,120,208,250,12,99,123,47,77,88,154,191,41,159,214,221,176,
169 97,131,60,4,167,152,83,224,149,103,150,102,26,210,111,200,218,208,220,210,
170 220,102,18,133,97,230,219,88,85,164,213,133,163,96,163,163,190,176,167,
171 185,186,161,174,150,85,222,85,92,92,76,93,248,7,194,248,248,120,189,255,
172 39,64,232,223,93,191,128,144,170,96,50,37,15,203,131,26,107,171,6,133,71,
173 56,84,204,13,20,115,160,179,173,163,93,86,5,106,111,111,231,144,244,202,
174 175,204,55,212,100,98,65,34,35,141,173,201,26,119,137,177,87,94,94,158,
175 177,41,195,144,126,117,230,234,146,178,18,86,5,163,170,74,139,122,115,87,
176 254,218,55,74,18,250,234,139,171,42,202,228,234,32,81,105,89,89,108,118,
177 209,188,168,92,251,207,233,55,204,139,57,253,163,13,199,188,19,113,208,
178 155,81,187,189,22,179,227,203,177,219,189,20,183,141,61,110,130,45,254,
179 55,30,194,86,246,184,109,94,136,155,252,82,236,148,87,98,247,124,61,250,
180 176,217,145,39,189,21,125,201,135,177,247,125,151,244,250,242,204,5,241,
181 249,89,5,94,219,183,172,172,106,253,71,237,51,14,52,1,38,8,194,224,75,219,
182 53,205,191,189,56,105,149,115,162,56,10,202,205,205,77,28,37,197,39,198,
183 255,156,252,179,97,184,69,165,68,49,145,221,184,113,163,28,150,46,97,247,
184 171,107,170,215,101,174,51,164,79,45,76,245,98,55,122,155,171,29,117,155,
185 112,12,68,255,31,204,89,210,90,85,34,215,121,16,13,206,1,248,97,18,17,54,
186 4,43,36,23,156,106,104,104,240,207,35,100,162,16,21,21,133,199,38,15,203,
187 164,138,138,138,166,170,18,71,85,150,211,23,148,3,188,49,107,189,68,206,
188 230,50,84,218,194,228,133,81,105,81,196,155,39,28,248,226,212,128,25,132,
189 105,155,210,156,131,97,120,253,134,186,243,164,164,18,227,169,209,164,77,
190 73,204,32,168,38,188,81,121,8,206,83,163,148,144,244,126,157,26,93,56,212,
191 222,53,133,142,190,30,223,207,128,193,81,122,182,31,231,1,200,66,70,136,
192 34,151,93,32,132,61,114,217,103,81,94,154,132,130,203,101,47,162,6,74,98,
193 112,4,29,133,107,135,174,134,250,80,76,79,167,70,153,216,14,249,139,46,
194 81,243,248,214,28,73,77,147,251,83,163,67,173,24,140,162,51,20,69,12,213,
195 216,166,53,142,150,218,161,107,233,114,133,165,53,48,56,216,211,63,208,
196 222,211,159,90,221,241,242,198,202,51,62,201,218,233,213,196,237,95,78,
197 156,244,98,194,68,187,145,115,254,5,192,185,245,11,9,108,112,135,151,19,
198 119,153,158,120,229,215,121,115,147,235,42,90,122,58,123,7,122,251,229,
199 97,12,105,160,111,48,109,158,99,198,238,6,192,4,67,152,224,120,117,71,71,
200 236,91,3,61,29,140,214,209,18,51,96,70,250,168,168,179,171,115,67,206,6,
201 195,112,171,168,175,192,25,202,202,202,146,35,211,169,152,152,24,102,216,
202 126,158,26,101,109,127,239,16,48,48,143,48,99,184,83,163,16,72,156,137,
203 149,203,35,17,6,80,92,97,209,132,167,225,223,19,20,88,102,14,67,46,184,
204 147,232,158,67,165,107,174,117,228,46,25,178,255,217,11,7,91,27,68,188,
205 65,134,74,131,115,85,245,67,215,224,0,144,254,20,244,250,245,235,49,140,
206 196,47,73,117,115,106,212,185,165,225,229,207,53,66,122,21,147,172,213,
207 235,18,196,113,228,228,228,211,63,136,47,173,43,141,200,139,208,135,236,
208 178,108,204,183,220,156,89,189,29,142,154,188,161,147,197,35,148,232,115,
209 236,84,46,251,44,14,50,35,35,67,127,179,12,53,152,151,151,231,223,229,70,
210 142,65,60,143,56,140,0,118,253,38,71,219,8,94,122,84,221,92,29,83,16,163,
211 15,5,213,5,236,145,85,244,245,245,17,169,171,215,37,173,90,159,90,81,81,
212 35,142,188,190,165,126,77,230,26,125,72,40,72,8,230,107,132,125,142,234,
213 44,71,67,57,243,20,25,99,97,13,12,58,74,91,122,86,21,182,188,19,87,115,
214 243,143,5,135,191,157,182,213,40,97,207,199,0,26,79,250,40,243,223,191,
215 148,124,153,90,31,83,222,222,218,214,226,136,123,199,241,250,46,38,198,
216 88,62,188,180,141,227,203,63,58,74,35,100,205,90,82,94,174,17,182,182,182,
217 38,38,166,9,171,136,132,97,65,233,197,233,6,195,88,217,232,243,35,91,93,
218 29,206,187,198,134,57,101,197,94,152,34,251,119,179,12,94,90,102,102,166,
219 92,112,90,182,232,232,104,255,64,40,62,91,33,23,134,21,104,168,203,115,
220 20,71,58,218,221,223,114,104,168,100,64,40,174,17,82,88,160,179,206,121,
221 153,48,54,54,190,177,81,102,223,162,107,132,242,191,59,53,181,55,149,55,
222 148,235,131,184,105,71,104,113,100,247,146,136,102,66,83,179,244,204,56,
223 62,122,137,62,12,127,121,223,7,247,200,44,118,84,82,82,226,223,227,19,76,
224 118,244,87,134,219,156,239,98,16,140,25,145,192,112,81,81,17,19,49,185,
225 60,170,226,56,57,36,131,228,58,135,99,89,92,239,162,200,222,69,81,253,218,
226 115,132,84,72,103,119,167,62,116,245,12,77,145,228,234,224,211,224,208,
227 236,193,242,194,7,139,42,109,187,255,167,226,163,223,203,152,54,61,41,192,
228 252,51,135,137,47,36,28,61,115,125,194,7,215,58,94,222,206,200,24,235,135,
229 23,182,114,172,253,175,163,99,179,187,54,44,40,198,90,126,69,126,114,65,
230 178,62,52,182,72,108,212,212,246,173,220,80,188,130,16,89,77,74,98,112,
231 127,12,86,145,224,237,161,50,183,242,97,44,87,58,63,191,42,23,70,34,108,
232 96,84,84,148,230,87,224,197,70,70,70,250,119,181,8,231,82,255,112,154,79,
233 194,241,245,128,9,3,125,42,26,42,58,152,22,56,85,223,216,255,75,76,11,244,
234 201,220,212,173,153,138,134,246,134,250,246,122,125,232,246,249,161,35,
235 111,32,244,174,113,124,160,30,19,95,80,80,224,211,105,73,147,160,32,78,
236 161,198,21,184,232,223,3,245,85,85,85,129,127,231,186,144,122,160,126,28,
237 133,65,234,236,29,168,110,235,253,34,181,254,228,143,50,39,189,152,48,238,
238 252,211,194,110,182,149,159,219,254,212,111,223,202,200,24,139,7,16,248,
239 246,97,67,247,84,123,57,123,100,37,97,127,12,146,43,228,3,245,131,132,192,
240 63,80,223,220,220,28,27,27,235,135,123,64,22,64,168,1,108,211,166,77,27,
241 55,110,20,191,71,164,246,246,246,248,120,252,51,127,92,201,145,74,189,89,
242 70,138,74,199,7,247,227,236,40,8,20,119,184,240,187,171,171,139,174,227,
243 135,87,71,198,172,172,172,234,113,250,108,189,2,225,120,169,177,171,127,
244 126,70,195,205,63,22,236,243,70,138,1,66,227,27,38,216,226,254,96,155,187,
245 210,126,170,145,49,214,15,47,110,227,88,112,243,208,3,30,67,115,140,160,
246 215,248,190,107,52,221,249,202,108,61,152,125,84,69,69,5,206,28,230,20,
247 40,98,18,253,248,120,5,59,45,44,44,44,41,41,145,203,99,44,5,66,41,234,29,
248 167,208,191,79,64,136,153,11,173,158,146,146,226,31,204,154,154,154,162,
249 163,163,245,167,43,3,41,5,194,192,171,127,96,240,127,153,13,184,128,83,
250 94,77,50,64,200,10,225,20,219,231,57,246,3,7,131,238,49,137,25,187,59,82,
251 62,115,116,251,243,1,25,107,106,124,65,216,218,218,42,120,38,151,125,22,
252 206,64,82,82,18,252,171,114,126,126,220,191,45,144,209,191,187,117,252,
253 144,2,225,175,234,238,238,78,76,76,244,239,51,76,120,132,184,116,204,125,
254 252,152,61,181,57,223,50,26,152,51,0,110,165,64,24,72,53,116,246,45,201,
255 109,58,103,110,182,117,78,129,234,195,182,182,168,243,109,239,87,217,119,
256 53,50,198,226,225,197,173,29,31,28,239,40,222,224,203,213,175,32,210,248,
257 130,176,127,232,46,146,161,39,14,71,122,201,6,51,136,51,135,67,185,126,
258 253,122,63,46,21,177,187,178,178,161,167,155,252,32,168,127,82,32,220,76,
259 80,48,35,35,3,255,76,46,251,172,210,210,210,181,107,215,230,231,231,203,
260 101,159,197,156,139,238,226,199,30,71,81,10,132,129,81,125,103,223,59,113,
261 53,231,125,150,179,221,75,137,6,252,88,36,108,111,219,248,180,237,190,38,
262 251,20,35,102,44,30,94,155,230,88,243,140,163,213,159,59,59,44,174,241,
263 5,33,194,51,219,180,105,83,110,110,238,72,153,84,81,81,1,5,35,35,35,13,
264 207,20,14,43,118,148,231,212,24,221,57,232,86,10,132,70,137,179,148,35,
265 242,11,113,255,201,130,83,24,23,23,55,162,147,171,80,48,38,38,166,161,97,
266 232,169,23,25,53,30,82,32,12,128,178,235,58,207,254,52,219,178,8,20,225,
267 101,219,109,93,246,73,70,204,88,60,188,58,213,145,245,157,163,63,104,159,
268 237,241,170,113,7,33,26,112,126,50,30,249,126,237,6,203,182,113,227,70,
269 140,97,113,113,241,72,79,141,146,5,244,6,248,182,65,5,66,55,130,130,201,
270 201,201,180,71,119,183,183,215,141,211,45,58,157,175,216,142,143,143,23,
271 143,18,246,244,244,20,21,21,17,211,216,216,232,165,237,193,94,87,87,151,
272 184,158,236,199,101,228,81,151,2,225,216,105,96,208,81,220,212,253,226,
273 134,202,41,175,88,241,90,160,8,19,108,241,251,218,126,250,194,126,249,160,
274 129,49,22,15,47,77,114,124,125,153,163,62,71,214,117,40,202,10,32,68,88,
275 179,236,236,108,88,88,93,93,237,221,81,195,178,149,151,151,227,18,212,215,
276 215,99,33,17,84,99,177,172,172,204,251,5,63,118,129,49,36,49,134,81,24,
277 79,242,178,145,146,146,18,156,147,177,118,21,20,8,221,171,163,163,3,16,
278 38,37,37,9,170,49,193,17,68,164,61,160,35,139,120,129,57,57,57,249,206,
279 111,48,233,123,6,9,232,43,52,39,40,229,7,76,213,136,200,22,200,75,163,226,
280 245,199,198,198,150,150,150,250,113,107,242,88,72,129,112,140,212,221,55,
281 240,118,108,205,209,239,165,79,180,39,24,216,99,169,240,91,219,15,235,236,
282 39,246,219,39,26,73,99,229,240,234,20,71,204,155,142,174,113,187,178,30,
283 24,89,4,132,8,59,86,87,87,7,14,19,19,19,177,126,88,54,152,39,86,97,199,
284 248,93,91,91,155,153,153,137,221,195,25,208,191,24,4,158,145,0,147,136,
285 107,152,145,145,65,70,141,136,88,78,97,18,217,96,122,122,58,38,23,211,74,
286 122,86,97,72,177,144,226,213,155,17,17,17,254,61,219,230,187,20,8,61,138,
287 150,160,157,196,236,38,210,169,168,168,40,241,3,17,73,219,184,245,23,201,
288 136,160,96,74,74,138,76,173,19,8,100,114,68,207,32,141,204,48,222,82,32,
289 28,117,209,180,185,245,93,23,124,158,51,233,69,75,35,112,130,45,238,247,
290 182,121,5,246,125,131,233,6,209,23,38,56,62,56,206,81,17,239,8,153,207,
291 72,121,150,117,64,40,4,165,196,189,160,210,156,233,4,228,112,12,112,33,
292 220,90,54,34,155,155,155,221,102,132,115,185,185,185,176,83,159,145,29,
293 225,105,12,189,80,199,41,126,203,21,99,35,5,66,159,68,11,209,192,204,122,
294 218,218,218,152,194,140,136,97,76,127,152,4,225,56,178,5,242,202,88,43,
295 73,129,112,116,213,217,55,240,99,118,227,145,239,166,27,168,99,181,48,209,
296 22,251,87,219,107,165,246,61,141,164,177,114,120,117,7,199,194,91,29,205,
297 35,252,88,107,208,202,106,32,212,11,63,1,203,134,48,107,222,207,151,26,
298 68,98,60,63,50,98,81,61,157,21,195,198,230,229,229,73,12,174,93,139,67,
299 41,87,140,141,20,8,149,20,8,71,83,13,157,125,119,45,41,154,106,201,167,
300 3,245,97,43,91,236,99,246,135,106,237,59,27,73,99,229,240,206,225,67,159,
301 23,232,13,163,110,106,101,16,142,181,240,32,179,178,178,54,110,220,8,17,
302 199,250,129,66,5,66,37,247,32,100,70,102,144,92,161,228,65,3,131,131,229,
303 45,61,151,205,203,181,230,3,130,250,176,163,109,195,76,251,141,221,246,
304 109,140,164,177,108,120,113,27,199,156,83,29,53,233,244,75,89,221,225,161,
305 112,6,33,194,236,128,192,0,24,31,5,194,112,87,127,127,255,138,152,166,159,
306 55,150,16,154,154,37,9,219,187,218,51,202,51,244,161,168,182,200,219,119,
307 63,194,94,93,125,3,159,37,215,29,246,86,154,1,57,22,12,123,216,86,124,104,
308 255,107,48,81,112,230,94,142,245,118,71,215,120,62,107,59,94,10,115,16,
309 6,76,10,132,97,173,190,190,190,204,204,204,181,235,228,199,32,227,226,226,
310 196,41,136,154,102,247,223,35,20,185,148,204,154,21,83,109,253,211,161,
311 132,35,108,255,139,180,31,23,76,239,209,126,235,96,71,209,154,161,79,10,
312 132,165,20,8,3,35,5,194,176,86,71,71,71,116,116,180,160,160,80,126,254,
313 208,199,32,43,235,43,13,32,92,159,179,190,179,171,147,85,66,94,30,175,12,
314 55,181,116,247,63,183,174,220,250,167,67,9,191,183,205,75,182,255,206,72,
315 26,203,134,151,39,59,126,188,209,250,223,81,218,66,13,14,14,118,116,119,
316 180,116,181,232,131,246,189,185,250,134,129,69,145,61,132,37,209,161,127,
317 139,236,56,74,129,48,172,85,95,95,47,1,232,18,92,76,77,77,141,76,142,52,
318 128,112,89,202,178,228,180,100,86,9,101,103,103,143,232,62,177,80,85,99,
319 87,223,29,139,139,44,254,140,4,97,107,91,204,141,182,23,242,236,251,27,
320 97,99,217,240,230,126,142,196,15,29,61,35,123,59,87,48,170,215,243,135,
321 121,187,187,187,179,178,242,214,172,139,31,10,27,210,2,240,92,121,216,74,
322 129,48,172,101,246,8,115,115,115,135,222,13,81,87,110,24,153,235,178,215,
323 181,182,183,178,74,136,100,250,239,242,135,167,58,123,7,174,154,159,191,
324 205,11,86,167,224,68,91,204,253,182,39,26,236,83,141,176,177,108,248,252,
325 60,71,93,118,176,124,77,112,11,229,5,132,133,133,133,235,214,173,147,35,
326 115,237,218,248,248,248,177,190,121,50,108,165,64,24,214,234,235,235,203,
327 202,202,210,6,91,98,98,162,143,215,8,55,109,218,196,252,84,46,132,165,138,
328 154,186,255,248,101,238,4,19,117,172,22,166,218,214,253,219,246,255,58,
329 236,65,242,137,249,215,118,118,44,185,203,209,49,182,175,17,25,95,49,232,
330 202,203,203,139,93,42,40,44,88,153,190,210,48,220,178,10,179,160,96,76,
331 76,140,24,152,66,81,81,81,250,55,182,40,141,162,20,8,195,93,189,189,189,
332 203,163,107,151,111,44,35,180,180,202,231,253,155,219,154,179,202,178,244,
333 161,168,186,72,187,110,129,194,28,132,245,29,125,23,127,153,59,209,242,
334 215,5,247,179,45,253,198,126,113,175,125,107,35,111,172,24,38,56,230,156,
335 226,200,255,41,228,239,139,169,172,172,204,201,201,169,169,169,169,117,
336 170,178,170,114,117,230,106,3,8,115,75,114,171,171,171,147,147,147,37,3,
337 157,138,28,249,151,28,148,124,148,2,161,210,80,15,88,24,53,72,208,158,35,
338 28,28,28,28,24,28,208,7,195,197,137,112,6,97,103,239,192,159,191,201,183,
339 254,221,49,211,108,171,151,218,207,26,8,138,27,68,95,156,232,248,242,34,
340 71,83,113,56,60,38,88,234,148,92,240,122,106,148,81,166,63,53,154,148,148,
341 164,46,204,143,145,20,8,149,100,15,32,248,254,102,153,176,5,97,115,87,255,
342 237,139,138,44,254,18,237,173,108,177,167,217,62,141,177,31,109,228,141,
343 37,67,153,125,143,232,239,158,29,232,179,226,219,7,199,66,6,16,246,245,
344 245,37,22,38,226,20,234,67,93,243,208,201,97,86,149,149,213,172,94,151,
345 68,88,179,49,112,159,107,15,67,41,16,42,41,16,250,42,220,149,167,86,149,
346 77,122,201,234,119,199,92,106,155,93,104,223,39,40,222,163,29,105,63,238,
347 84,219,103,123,189,150,48,47,173,94,214,114,168,203,0,194,193,193,193,238,
348 158,238,142,174,14,125,208,61,62,225,88,28,217,75,88,18,163,30,88,26,67,
349 41,16,42,41,16,250,164,222,254,193,183,98,170,39,90,251,30,209,73,182,168,
350 171,108,175,183,216,119,48,240,198,130,161,195,190,221,44,219,13,83,108,
351 235,196,13,71,187,189,158,188,166,168,53,28,158,14,48,128,208,187,124,121,
352 160,126,96,96,0,223,81,72,124,195,200,15,137,141,132,237,243,193,10,132,
353 74,10,132,195,171,111,96,240,189,248,154,237,173,253,125,121,160,242,130,
354 237,142,206,96,248,196,124,166,253,224,219,109,207,110,103,139,212,31,255,
355 9,31,100,102,215,201,79,220,133,176,70,29,132,218,183,81,81,113,113,177,
356 31,215,17,161,96,121,121,57,217,139,138,138,44,242,145,212,0,75,129,80,
357 73,129,112,120,101,212,118,30,48,43,85,111,181,173,22,182,181,69,125,102,
358 191,162,203,190,173,1,57,86,11,253,246,173,190,178,95,122,184,237,199,9,
359 182,56,67,17,112,13,207,255,60,167,187,127,52,236,144,133,53,234,32,44,
360 41,41,129,133,221,221,221,93,93,93,89,89,89,13,13,13,114,133,207,34,99,
361 118,118,118,91,91,91,101,101,229,88,127,2,215,63,225,173,82,64,33,126,203,
362 216,17,106,232,44,180,243,139,81,230,247,18,88,26,132,29,29,29,5,46,209,
363 117,104,45,185,98,36,98,130,195,44,137,153,78,120,222,220,225,139,20,8,
364 189,171,181,167,255,226,175,114,13,86,219,58,1,162,28,100,91,188,220,126,
365 154,245,47,10,214,219,119,122,213,126,235,14,182,13,134,34,104,1,22,62,
366 186,162,180,167,63,148,207,144,142,58,8,177,111,108,176,165,165,133,33,
367 153,146,146,130,197,171,169,169,137,142,142,142,140,140,196,238,53,54,54,
368 38,37,37,49,96,89,149,150,150,6,50,49,167,17,17,17,171,87,175,214,44,106,
369 103,103,39,238,32,132,128,130,21,21,21,102,78,140,187,0,60,197,73,112,42,
370 35,35,195,191,251,134,202,202,202,98,99,99,19,19,19,235,235,141,23,164,
371 45,13,66,90,5,151,159,214,69,52,36,19,31,63,206,128,179,5,58,10,173,75,
372 85,250,125,2,125,188,196,1,211,120,148,29,21,22,22,250,215,252,76,244,196,
373 22,16,163,69,198,234,164,64,232,69,237,189,3,247,44,41,50,216,107,75,133,
374 83,108,159,71,217,143,181,248,99,18,28,222,106,251,41,23,218,222,51,59,
375 130,134,176,211,171,73,223,103,53,14,132,46,10,71,29,132,88,6,8,199,144,
376 4,102,201,201,201,140,113,224,199,223,230,230,230,244,244,116,160,200,95,
377 232,8,0,202,203,203,161,29,49,237,237,237,169,169,169,24,70,177,133,254,
378 254,126,232,136,133,204,204,204,36,210,154,32,172,173,149,111,157,165,188,
379 24,31,108,99,181,83,226,99,233,148,23,94,136,178,19,195,15,86,145,69,239,
380 62,82,33,44,98,81,153,31,24,202,104,117,16,2,63,113,196,20,30,183,157,223,
381 113,113,113,76,103,192,27,69,162,237,227,227,227,137,167,165,233,4,20,62,
382 38,38,134,181,148,83,108,1,137,194,211,240,164,9,186,75,193,244,90,102,
383 115,52,167,104,102,255,138,192,70,200,142,214,172,89,227,150,94,10,132,
384 158,68,215,251,40,177,118,135,151,173,123,105,240,34,219,187,229,246,61,
385 172,239,11,206,181,95,177,167,109,249,176,20,20,225,168,247,210,43,91,67,
386 246,74,213,168,131,144,173,225,226,96,27,97,67,94,94,30,147,126,44,6,118,
387 3,99,8,237,192,30,145,216,64,64,200,152,197,128,96,84,49,155,107,215,174,
388 213,64,136,136,199,65,36,49,46,163,53,65,136,51,231,124,207,113,42,176,
389 199,37,192,236,243,59,59,59,27,79,151,34,243,23,194,177,72,74,76,37,94,
390 35,200,32,1,201,228,38,156,167,70,153,10,80,15,36,144,81,46,89,29,132,235,
391 215,175,223,232,212,134,13,27,4,225,105,84,168,70,177,27,26,26,168,145,
392 214,214,86,166,0,76,100,48,247,84,4,29,130,233,0,205,172,191,228,75,27,
393 211,87,168,23,11,54,176,119,9,16,82,70,250,49,109,15,254,137,161,248,20,
394 83,76,118,40,44,164,39,1,156,163,151,83,106,170,133,181,44,234,11,203,111,
395 102,124,204,21,228,242,230,42,175,118,148,86,14,133,46,159,31,229,10,19,
396 16,102,213,118,254,238,157,116,131,153,182,72,216,218,22,115,189,253,197,
397 58,107,127,98,30,66,23,217,247,254,167,237,191,91,217,98,13,199,239,61,
398 92,54,47,183,165,59,52,239,96,116,114,208,87,16,118,247,200,177,89,246,
399 171,61,55,10,176,97,223,49,11,216,1,44,33,246,16,30,8,164,193,3,126,48,
400 240,177,129,2,132,152,11,76,10,38,2,72,104,14,3,107,177,39,100,39,198,143,
401 75,140,1,16,120,3,219,206,249,124,11,8,224,248,193,54,128,160,224,120,195,
402 212,0,9,40,69,110,110,46,228,99,66,64,49,41,8,102,202,224,224,146,11,75,
403 104,246,122,131,198,35,20,119,70,137,115,217,148,60,33,33,129,114,82,120,
404 156,98,90,23,200,81,120,168,64,15,16,83,6,226,197,70,168,29,0,73,221,233,
405 209,24,44,2,123,98,90,71,73,113,7,105,102,74,65,97,41,81,84,84,20,117,66,
406 121,169,22,166,8,204,12,232,1,84,5,105,68,231,232,232,248,213,191,163,54,
407 216,130,127,103,86,221,42,28,64,216,221,55,112,225,23,57,6,3,109,145,176,
408 189,109,227,75,246,219,45,254,30,109,40,248,189,253,130,223,219,230,77,
409 28,33,5,69,120,124,101,89,127,176,205,92,125,209,136,64,232,139,160,2,198,
410 29,134,33,120,134,197,3,126,88,9,246,130,101,0,111,24,82,113,145,5,11,128,
411 1,33,158,148,88,9,18,139,45,96,99,201,66,36,105,152,94,139,72,75,9,243,
412 37,142,150,67,229,248,41,17,38,8,22,80,112,1,66,129,0,98,4,35,49,131,148,
413 69,92,23,211,152,71,205,240,151,188,102,16,182,180,58,178,139,29,153,133,
414 142,202,186,161,243,64,91,46,255,65,216,220,38,131,230,151,136,35,166,120,
415 72,52,30,5,163,252,76,10,152,233,0,66,48,64,187,98,145,89,69,26,106,132,
416 90,64,144,67,3,33,120,0,18,84,141,161,228,65,33,131,71,72,1,5,248,105,254,
417 216,216,88,234,68,80,144,25,0,63,168,10,90,154,254,13,245,41,50,145,114,
418 43,14,7,147,68,106,82,244,131,81,81,200,131,144,190,50,43,166,122,107,75,
419 62,53,56,197,182,126,174,253,202,30,107,127,98,190,221,190,221,147,182,
420 7,57,84,195,193,251,30,14,156,149,154,86,19,130,239,82,97,216,34,185,48,
421 26,194,178,9,35,137,132,149,19,49,252,213,36,34,157,201,55,91,43,98,144,
422 22,41,151,45,38,64,8,234,176,57,152,119,126,99,220,240,16,64,29,134,8,79,
423 23,16,10,4,0,66,184,128,193,4,16,224,3,231,129,92,90,161,176,153,208,148,
424 196,218,12,64,19,73,112,4,9,163,85,1,254,131,208,44,138,77,73,48,235,224,
425 29,67,79,225,241,129,68,12,139,130,127,160,130,120,225,14,83,102,208,200,
426 90,106,71,248,127,240,3,40,34,34,41,63,105,196,150,131,69,148,14,239,86,
427 248,118,176,60,51,51,83,76,2,232,1,241,241,241,148,136,154,161,225,169,
428 1,138,76,98,166,117,98,42,68,145,245,32,164,222,208,40,246,242,144,7,97,
429 86,109,231,33,179,173,248,188,196,126,182,159,62,177,255,185,223,62,209,
430 0,30,235,132,1,251,86,169,246,195,110,176,189,184,181,45,198,112,240,35,
431 10,19,108,241,15,254,92,210,19,114,79,83,140,58,8,195,65,88,57,32,39,4,
432 11,49,101,205,205,205,252,102,222,207,44,159,223,136,72,140,18,118,146,
433 25,127,69,69,5,54,10,39,129,120,185,9,231,109,131,100,97,213,40,186,4,158,
434 52,154,32,132,91,56,64,136,178,97,229,41,167,136,1,114,16,142,223,252,37,
435 18,137,130,241,87,172,229,7,145,196,240,151,69,178,35,129,198,224,18,165,
436 142,140,140,100,238,3,246,152,206,192,123,252,66,126,196,197,197,225,41,
437 226,23,26,64,8,237,72,207,20,9,143,16,100,138,141,80,9,160,145,100,98,113,
438 84,20,218,32,236,233,31,124,120,89,137,5,95,40,122,166,109,78,156,253,40,
439 43,223,26,211,109,223,246,77,251,13,7,219,22,25,142,220,191,176,253,203,
440 137,63,102,53,202,86,9,21,41,16,134,131,70,19,132,74,8,222,195,117,33,65,
441 119,17,195,95,22,133,136,212,254,138,85,98,237,80,126,167,134,18,233,22,
442 183,92,161,13,194,212,234,142,41,175,88,235,78,209,9,182,184,83,108,159,
443 91,249,19,243,224,185,201,62,229,33,251,163,219,218,162,12,7,191,37,225,
444 192,89,169,117,29,86,188,106,229,183,20,8,195,65,10,132,97,161,16,6,97,
445 67,103,223,153,159,102,27,204,241,248,134,237,108,17,183,216,158,47,179,
446 239,97,96,143,117,66,159,125,226,82,251,89,167,218,62,51,28,249,150,7,252,
447 242,39,86,149,133,210,35,246,10,132,225,32,5,194,176,80,8,131,208,190,190,
448 194,82,247,200,76,178,69,61,107,187,199,202,239,209,238,179,111,253,156,
449 237,174,93,109,171,124,124,76,112,164,225,128,55,83,179,66,232,29,164,91,
450 8,194,126,231,109,240,237,186,79,213,247,246,246,102,103,103,111,216,176,
451 65,92,39,99,237,250,245,235,51,51,51,251,156,175,37,75,78,78,142,136,136,
452 16,119,81,144,184,173,173,173,160,160,128,44,34,175,210,24,73,129,48,44,
453 20,170,32,172,104,237,57,254,131,12,131,33,30,199,176,179,109,141,221,118,
454 7,164,49,176,199,34,97,208,62,33,199,126,224,101,182,89,254,61,32,225,123,
455 120,110,109,121,200,60,74,177,37,32,4,96,133,133,133,113,113,113,218,29,
456 0,168,166,166,166,184,184,184,177,177,49,49,49,177,179,179,147,4,93,93,
457 93,169,169,169,21,21,21,37,37,37,112,177,163,163,35,61,61,157,72,32,154,
458 155,155,155,148,148,164,191,97,2,64,18,47,238,183,144,81,206,72,254,18,
459 35,126,4,94,148,212,176,107,98,40,130,136,228,104,41,41,152,31,186,228,
460 227,188,17,68,44,178,138,69,113,167,136,51,211,184,105,139,64,88,95,95,
461 175,191,201,7,177,200,212,134,150,22,165,205,203,203,203,200,200,16,38,
462 152,72,86,177,72,60,245,66,147,231,228,228,136,186,80,26,107,133,42,8,191,
463 74,171,223,206,50,159,27,60,220,246,195,15,246,243,7,172,122,107,76,183,
464 125,219,79,108,127,62,218,54,127,140,28,65,125,216,253,245,228,252,134,
465 16,113,10,183,4,132,152,251,242,242,114,12,93,107,107,171,140,114,190,66,
466 83,60,41,40,104,135,169,196,108,2,66,208,136,255,7,63,200,69,22,86,145,
467 11,223,81,216,76,145,23,4,194,75,214,138,231,13,68,36,155,34,146,52,152,
468 211,170,170,170,192,179,16,127,23,168,235,203,200,145,80,58,142,19,204,
469 99,237,249,139,9,202,114,190,68,134,2,66,119,220,92,106,134,226,112,192,
470 196,147,120,124,89,232,39,8,105,60,138,29,25,25,73,163,202,40,231,3,3,81,
471 81,81,52,39,5,19,51,29,154,135,54,142,143,143,103,85,90,90,26,181,192,100,
472 71,52,91,126,126,62,44,244,187,135,89,68,148,133,18,81,27,114,217,25,67,
473 205,208,161,69,119,228,7,21,34,186,59,173,14,141,196,162,126,149,51,223,
474 216,42,36,65,56,48,56,120,150,101,174,14,238,101,251,37,210,126,92,191,
475 85,223,32,218,108,223,241,118,219,179,59,110,193,99,130,35,13,247,44,249,
476 245,125,96,65,173,45,1,161,24,245,88,66,61,36,216,26,46,4,246,1,199,64,
477 88,134,218,218,218,132,132,4,225,84,16,143,191,72,26,225,45,8,255,65,131,
478 4,20,1,141,36,192,150,110,220,184,81,68,146,18,115,138,201,197,22,1,24,
479 97,121,2,38,14,27,179,47,206,244,202,40,103,25,41,53,199,3,224,41,29,30,
480 17,71,46,158,169,192,57,102,21,139,20,28,94,82,28,76,19,9,32,162,204,60,
481 30,242,19,132,20,131,26,103,22,0,213,101,148,243,217,17,34,105,120,218,
482 143,150,22,147,20,26,9,46,138,199,42,169,41,22,105,39,18,144,152,150,163,
483 252,164,23,217,153,86,80,23,172,210,79,106,168,35,226,73,3,51,200,43,34,
484 45,34,42,129,246,214,159,184,160,105,57,120,218,94,188,76,142,38,7,255,
485 180,180,152,25,80,100,18,51,27,162,44,84,5,201,136,39,65,0,88,24,146,32,
486 92,146,219,100,48,190,227,18,182,182,197,156,105,155,99,217,27,68,123,237,
487 91,167,217,15,251,163,237,157,0,56,130,250,128,83,152,89,27,10,207,215,
488 51,198,145,92,24,185,220,130,80,120,132,120,117,218,216,103,132,18,47,224,
489 135,197,128,16,164,33,1,6,86,188,163,3,219,66,50,108,14,44,193,146,176,
490 217,149,43,87,178,72,228,248,130,144,99,64,88,51,61,8,41,2,252,195,48,98,
491 226,196,105,97,142,159,178,20,21,21,81,46,14,18,192,99,216,57,96,12,32,
492 71,206,42,34,69,94,81,99,192,21,145,94,20,28,197,198,198,226,60,128,18,
493 168,49,234,44,240,223,35,164,186,57,116,104,39,163,92,175,88,35,158,82,
494 137,119,1,240,155,34,209,72,172,74,73,73,161,0,44,82,108,138,135,93,166,
495 19,64,5,173,72,32,132,74,33,35,205,79,75,139,72,242,86,87,87,211,45,248,
496 17,24,231,201,71,81,3,180,37,199,79,185,52,16,82,22,14,158,162,137,57,29,
497 109,198,111,34,41,56,63,136,209,202,37,124,98,58,16,200,164,117,69,36,41,
498 73,64,21,81,129,218,252,128,178,3,78,106,146,58,244,187,6,66,15,132,245,
499 157,125,199,190,111,137,171,131,55,218,94,40,183,239,110,192,143,69,66,
500 155,125,251,231,237,119,237,109,91,102,56,230,0,132,137,47,36,60,179,166,
501 188,55,248,63,75,193,176,69,114,97,228,210,131,80,216,116,236,6,246,1,108,
502 224,72,0,3,172,40,118,64,24,73,204,2,182,2,123,66,74,178,176,200,218,184,
503 184,56,44,128,200,75,74,44,140,240,52,0,3,145,136,93,96,136,48,35,88,143,
504 156,156,28,108,133,72,28,72,121,7,33,135,132,121,23,30,48,197,164,248,84,
505 2,135,138,81,114,11,66,42,129,2,146,61,61,61,29,3,40,226,173,8,66,33,26,
506 216,45,8,203,202,202,168,5,126,96,127,169,32,202,67,97,40,51,173,72,25,
507 200,226,9,132,84,16,185,72,64,207,19,109,105,89,16,34,142,92,204,104,52,
508 16,10,176,17,73,89,104,87,90,148,82,176,72,183,224,47,61,152,57,14,224,
509 228,183,40,81,116,116,52,37,213,152,71,135,136,143,143,167,86,233,61,98,
510 38,129,168,40,81,75,212,36,227,65,68,142,84,161,7,194,143,18,107,183,27,
511 239,15,208,79,180,197,222,107,123,178,195,190,157,1,63,86,8,226,49,193,
512 191,219,166,111,107,139,54,28,118,192,194,113,239,103,148,183,140,231,133,
513 159,81,145,147,131,254,131,80,216,67,113,90,139,97,136,173,64,24,141,245,
514 235,215,51,156,69,36,191,5,255,24,227,107,215,174,101,17,70,10,115,135,
515 233,39,1,134,69,108,77,152,208,200,200,72,76,7,219,196,98,104,190,199,198,
516 141,27,177,45,24,79,17,169,101,9,140,12,32,196,184,113,36,88,57,72,6,209,
517 43,43,43,41,178,152,241,115,180,136,31,216,67,144,193,95,10,130,229,231,
518 152,157,89,135,64,136,241,36,23,70,143,181,20,71,196,3,66,34,131,0,132,
519 226,76,32,13,64,203,81,41,192,128,234,160,117,89,69,163,82,6,168,0,18,0,
520 27,29,139,181,164,161,192,162,82,144,72,47,106,129,223,34,146,223,36,166,
521 46,196,213,99,17,105,29,209,210,94,64,72,209,56,114,230,65,76,127,40,59,
522 49,52,57,179,54,74,68,171,211,69,88,164,199,139,83,7,136,196,130,121,164,
523 39,129,152,10,0,48,202,78,36,189,92,115,40,71,170,16,3,97,107,119,255,37,
524 227,253,233,221,157,109,107,94,183,223,108,205,55,136,114,84,11,236,231,
525 30,97,251,222,112,204,1,14,19,108,241,159,167,212,5,218,55,25,109,13,97,
526 112,52,110,101,96,56,99,247,183,208,130,99,97,48,146,126,219,129,177,147,
527 0,33,101,196,136,81,70,126,99,217,112,120,32,25,191,19,18,18,64,29,197,
528 199,226,49,197,231,55,127,197,5,35,76,19,96,211,159,24,3,1,96,130,120,224,
529 66,97,41,50,22,85,176,131,148,196,243,3,147,171,153,205,81,209,22,129,144,
530 242,96,241,57,68,74,5,168,177,251,148,13,71,30,107,78,129,113,110,112,128,
531 248,75,36,86,24,96,176,74,160,142,50,80,114,225,242,203,109,57,65,40,222,
532 70,70,57,97,30,211,40,129,79,166,63,73,73,73,2,132,64,148,186,147,25,44,
533 32,3,8,233,1,96,143,66,209,3,24,60,180,31,253,3,170,9,216,115,228,212,21,
534 85,193,4,2,40,130,58,210,83,57,90,37,144,128,69,26,94,204,21,72,76,164,
535 0,33,187,160,99,41,16,10,101,214,118,238,49,35,217,96,118,3,25,118,181,
536 173,90,96,63,175,219,190,173,129,64,86,8,141,246,169,247,217,158,216,197,
537 182,218,112,204,227,18,78,250,40,51,216,79,142,58,57,56,10,32,68,152,62,
538 49,168,253,22,150,4,174,88,208,37,224,168,48,92,148,14,115,7,210,248,129,
539 89,131,11,28,42,70,146,72,196,34,171,48,101,192,66,172,34,35,107,1,36,214,
540 73,243,136,132,47,36,78,43,146,134,69,12,41,107,197,118,176,129,192,69,
541 176,86,164,31,21,109,17,8,41,45,226,7,199,36,108,52,139,28,183,40,18,127,
542 249,45,22,137,23,139,34,189,182,86,252,22,2,132,144,149,18,106,217,69,188,
543 115,27,114,155,67,251,219,178,158,52,186,162,109,152,242,208,180,116,2,
544 209,150,204,98,64,35,222,27,176,167,57,65,56,163,136,162,145,18,23,16,4,
545 34,26,24,192,179,138,223,164,212,186,53,32,100,222,64,46,102,18,84,41,139,
546 52,57,127,217,5,41,163,163,163,169,100,18,147,87,164,247,93,33,6,194,15,
547 18,106,241,54,12,54,55,48,97,130,45,238,183,182,31,226,236,71,89,240,49,
548 9,14,41,213,126,248,169,182,207,198,250,49,65,223,195,4,123,124,92,197,
549 175,207,146,7,163,70,17,132,33,47,12,32,252,195,214,201,101,191,132,181,
550 199,145,208,28,196,192,104,139,64,168,73,144,64,46,248,43,44,53,83,3,185,
551 16,36,162,225,193,18,127,169,1,88,5,164,1,185,152,224,208,156,176,16,4,
552 34,98,72,0,195,248,13,204,88,69,94,210,224,249,49,217,17,155,66,194,35,
553 172,116,126,167,144,109,210,159,196,57,1,182,195,84,136,72,42,153,72,232,
554 40,51,248,172,80,2,33,179,170,83,62,206,52,24,220,128,133,243,108,31,36,
555 216,143,176,224,123,180,155,237,59,126,96,255,219,33,182,133,134,3,30,247,
556 112,231,226,34,43,205,93,71,44,5,194,0,11,139,135,221,195,144,202,229,128,
557 104,116,64,56,42,26,242,245,130,118,196,192,45,61,210,252,19,32,204,211,
558 61,79,50,138,10,37,16,70,149,182,77,28,143,119,170,225,11,222,102,127,174,
559 194,146,55,136,86,218,119,187,202,246,250,100,91,132,225,152,173,16,14,
560 127,59,45,168,111,153,81,32,12,7,89,8,132,74,104,140,166,2,33,3,194,129,
561 65,199,109,11,11,13,166,54,0,97,146,45,242,30,219,83,120,93,6,2,89,36,212,
562 216,167,37,217,127,151,104,63,34,192,97,189,253,196,231,237,119,121,255,
563 156,239,148,87,146,22,229,6,113,223,11,0,8,153,70,27,6,62,179,97,225,18,
564 17,207,15,33,34,197,34,233,69,50,165,209,146,2,97,88,40,100,64,184,169,
565 177,123,191,55,3,253,1,222,93,109,171,94,183,255,163,213,190,189,1,63,225,
566 28,6,236,91,69,218,143,187,214,246,10,83,4,67,117,153,195,191,127,41,237,
567 238,11,86,219,61,214,32,236,238,238,102,251,157,186,123,0,219,156,143,76,
568 228,58,223,188,209,213,213,197,239,252,252,252,196,196,68,146,53,59,63,
569 111,27,116,151,144,172,47,5,194,176,80,200,128,240,139,212,250,29,2,251,
570 233,65,40,248,163,253,188,94,171,190,71,123,92,194,160,125,194,91,246,107,
571 247,178,45,219,202,183,183,213,252,254,195,140,250,206,128,94,242,25,69,
572 57,57,56,86,32,236,112,222,88,30,31,31,175,191,55,164,164,164,164,162,162,
573 130,24,241,52,90,79,79,79,107,107,43,105,160,32,241,13,13,13,85,206,123,
574 245,101,106,165,209,208,88,129,16,231,189,182,182,150,14,164,191,197,81,
575 68,150,149,149,213,212,212,224,224,51,21,162,93,73,67,147,211,222,213,213,
576 213,172,85,13,60,22,10,13,16,246,15,14,254,223,138,210,9,118,163,157,29,
577 187,112,128,109,201,247,182,11,44,120,107,204,120,133,126,251,86,9,246,
578 35,47,181,189,229,35,2,69,216,230,133,132,224,125,221,154,147,131,99,8,
579 66,140,33,206,159,30,132,197,197,197,245,245,245,88,72,113,75,57,38,177,
580 188,188,156,72,236,39,241,233,233,233,252,149,73,131,68,152,247,184,205,
581 63,193,1,221,41,93,84,84,84,102,102,38,107,169,225,232,232,104,210,0,123,
582 74,23,27,27,11,236,101,210,128,104,172,64,136,243,46,30,36,79,78,78,214,
583 30,15,192,211,207,201,201,161,156,52,60,127,197,195,34,176,48,43,43,139,
584 148,162,177,183,240,214,91,75,9,246,20,22,22,210,162,218,253,47,116,110,
585 202,72,36,18,159,28,3,255,69,69,69,52,63,221,157,191,116,136,177,184,0,
586 16,26,32,108,238,10,220,115,244,19,108,113,151,219,102,37,217,127,103,32,
587 65,56,135,74,251,110,143,219,254,181,191,109,169,161,174,124,9,175,70,84,
588 202,86,12,54,57,57,56,86,32,100,212,99,28,176,132,122,16,50,84,147,146,
589 146,196,83,88,237,206,87,210,96,46,132,71,65,122,108,72,112,121,11,28,45,
590 62,238,198,141,27,245,32,196,232,229,231,231,83,22,202,69,217,197,179,227,
591 24,127,113,107,61,70,18,52,200,164,1,209,88,129,16,170,81,84,154,144,249,
592 139,118,70,187,211,249,90,88,12,61,245,2,6,104,126,220,124,98,104,114,24,
593 73,74,236,181,198,140,96,23,109,204,84,128,70,205,203,203,3,243,162,239,
594 138,57,29,142,111,66,66,2,253,128,226,147,134,170,200,200,200,160,30,40,
595 62,53,163,247,161,71,75,161,1,194,178,150,158,3,103,5,226,2,33,20,60,219,
596 246,113,153,125,207,65,19,12,194,51,224,19,167,218,15,63,209,246,229,214,
597 182,24,67,93,249,24,206,250,52,91,182,98,176,105,76,65,136,204,32,196,86,
598 136,7,165,48,11,128,1,179,137,231,64,140,92,29,108,130,229,152,184,248,
599 248,120,61,8,197,37,79,108,32,150,31,139,71,1,177,147,226,29,35,88,66,126,
600 232,47,154,6,64,99,5,66,204,46,38,30,28,26,62,213,132,104,114,252,66,106,
601 7,36,128,64,230,62,84,19,189,129,134,15,222,198,118,43,10,5,249,112,121,
602 41,160,126,18,71,195,227,4,211,197,1,36,94,32,109,79,135,160,151,16,73,
603 231,208,15,137,209,82,104,128,112,99,73,219,86,99,127,94,116,71,219,134,
604 91,108,207,55,218,167,24,96,16,158,1,4,22,217,247,121,217,126,219,206,182,
605 181,134,138,26,81,216,250,133,132,186,142,160,188,76,232,228,96,32,64,40,
606 248,199,95,126,131,7,204,99,106,106,42,107,49,17,194,169,144,25,130,74,
607 20,167,186,186,26,139,135,157,215,131,48,42,42,10,248,97,27,147,147,147,
608 249,11,23,73,134,25,12,176,35,168,105,12,111,150,161,240,120,60,76,106,
609 48,247,50,202,73,65,156,33,218,152,10,194,238,99,157,225,63,200,236,113,
610 189,165,44,148,68,25,233,226,244,0,186,178,140,114,70,194,69,237,114,55,
611 127,89,75,159,16,83,63,126,139,248,209,85,104,128,240,169,213,101,6,243,
612 58,234,97,7,219,134,55,108,55,182,91,242,61,218,227,18,230,219,47,58,222,
613 246,245,168,188,170,102,126,134,229,222,144,233,139,198,26,132,204,149,
614 107,107,107,113,3,196,164,25,22,98,7,176,27,216,4,49,39,198,144,194,197,
615 177,48,11,1,16,197,137,137,137,1,123,191,252,242,11,204,211,236,60,191,
616 197,107,70,40,38,213,43,78,147,194,11,10,62,46,37,29,43,16,82,66,124,62,
617 90,55,58,58,26,212,81,54,196,15,42,133,210,50,187,97,145,42,160,129,105,
618 236,80,5,33,162,115,211,204,120,198,148,87,196,136,9,32,157,155,223,68,
619 82,124,230,10,244,9,45,193,88,40,4,64,72,237,156,248,225,216,190,80,102,
620 138,109,221,199,246,191,244,219,39,26,96,16,134,1,71,176,220,190,199,237,
621 182,255,78,178,69,25,106,201,239,112,239,210,160,252,84,175,147,131,99,
622 8,66,36,198,190,32,34,60,16,49,44,58,87,14,105,76,141,195,88,11,139,135,
623 240,249,48,65,20,4,52,82,52,102,252,105,105,105,120,68,248,69,216,192,28,
624 231,39,153,48,140,56,9,50,91,96,53,86,32,196,191,201,203,203,203,206,206,
625 198,169,167,240,0,15,191,24,55,136,137,0,70,153,72,10,79,201,97,33,130,
626 19,250,86,15,13,81,34,104,71,217,233,220,154,255,135,168,25,166,63,76,17,
627 248,77,37,136,27,133,198,186,248,33,0,194,138,214,158,109,95,28,195,23,
628 202,108,103,139,124,192,246,248,66,251,185,139,236,231,140,105,88,108,63,
629 59,215,126,160,149,239,68,109,181,239,240,133,253,114,28,193,209,253,150,
630 239,233,159,100,181,247,6,223,48,15,0,8,53,1,12,249,43,228,132,149,195,
631 219,161,128,101,206,143,82,17,195,236,95,179,75,194,9,166,158,197,60,32,
632 240,26,195,83,163,20,27,163,143,137,135,1,120,129,20,152,66,18,131,192,
633 0,53,66,60,63,80,232,81,16,81,64,60,221,164,164,36,80,71,195,211,210,21,
634 206,79,86,65,71,154,92,92,12,96,30,180,110,221,58,145,102,76,47,14,135,
635 0,8,127,202,107,26,211,55,171,77,180,197,78,177,173,159,106,91,55,214,225,
636 47,182,153,101,246,61,44,11,194,108,251,65,151,217,102,239,96,219,96,168,
637 159,45,15,71,190,155,94,218,28,124,39,126,2,9,194,144,23,70,143,217,63,
638 214,79,46,91,70,99,8,66,189,160,2,146,11,97,35,166,2,224,13,210,211,252,
639 76,2,10,11,11,137,132,250,218,172,135,4,29,29,29,164,17,51,6,17,57,22,10,
640 1,16,206,136,170,10,192,157,50,99,26,118,180,109,248,151,237,209,78,251,
641 36,3,123,44,18,154,237,59,206,183,95,180,175,237,167,209,117,4,181,176,
642 223,155,41,169,213,91,250,62,222,192,75,129,48,28,20,32,16,42,1,63,113,
643 66,96,92,20,2,32,188,109,97,97,32,31,165,31,245,112,128,109,201,103,246,
644 63,117,89,149,130,17,246,227,175,180,189,225,247,211,17,190,132,169,175,
645 38,173,45,26,253,71,131,198,90,10,132,225,32,5,194,144,214,224,160,163,
646 187,147,80,93,148,223,209,80,59,244,187,55,40,223,87,48,48,56,120,250,156,
647 44,131,97,13,162,112,166,237,147,44,251,193,253,246,173,12,248,177,66,192,
648 67,181,219,238,216,205,182,114,140,28,65,45,224,208,255,144,245,235,135,
649 184,131,69,10,132,225,32,5,194,144,86,127,183,35,239,103,71,246,130,95,
650 67,121,188,92,21,84,170,237,232,61,242,221,116,131,97,13,138,48,201,22,
651 121,141,237,149,106,251,174,6,252,88,33,244,218,183,142,181,31,125,190,
652 237,131,173,2,245,33,223,153,81,85,253,193,246,197,250,198,198,198,252,
653 252,124,185,160,20,162,82,32,12,105,225,17,214,102,111,6,194,222,160,124,
654 76,37,189,166,243,128,128,188,83,102,116,195,65,182,197,31,217,175,178,
655 230,103,43,138,236,251,252,203,246,216,94,182,95,12,199,60,166,225,238,
656 37,69,221,253,65,2,194,129,1,71,75,157,163,177,170,179,44,187,62,43,194,
657 209,88,201,111,199,64,216,221,232,16,38,82,32,12,117,117,181,57,242,151,
658 75,10,214,14,221,173,19,140,90,93,216,178,219,235,201,6,171,106,241,112,
659 160,109,113,148,253,56,11,158,14,29,180,79,136,179,31,117,220,208,99,242,
660 99,120,69,208,109,184,232,139,156,142,32,122,130,162,174,204,145,187,212,
661 145,189,104,48,123,161,35,103,137,163,34,85,129,48,84,165,64,24,6,42,79,
662 24,162,32,56,236,147,111,63,15,58,125,159,213,184,99,96,191,190,180,37,
663 97,123,219,198,43,109,51,11,236,251,26,8,52,238,1,4,22,218,247,125,204,
664 254,144,47,31,17,28,139,112,196,187,233,173,61,193,195,146,190,94,199,166,
665 85,114,18,153,179,216,209,82,46,227,149,66,78,10,132,97,32,198,115,206,
666 66,71,93,206,208,153,210,224,212,87,105,245,219,189,20,28,32,156,98,91,
667 255,150,237,186,86,251,14,6,8,141,123,232,179,79,156,99,251,203,81,182,
668 249,163,242,190,52,255,194,190,111,164,180,116,7,149,83,213,84,37,65,88,
669 176,82,185,131,33,44,5,194,176,80,123,73,110,111,107,240,221,176,167,233,
670 147,164,186,109,198,242,105,250,81,9,91,217,226,246,181,253,180,220,126,
671 154,213,78,135,226,8,150,218,247,188,198,183,175,201,143,105,216,233,213,
672 164,230,224,2,97,127,159,163,40,106,8,132,173,234,163,240,161,44,5,194,
673 176,80,176,63,71,248,110,92,205,4,147,85,181,84,192,205,250,171,237,245,
674 108,251,65,6,8,141,123,168,179,239,252,169,253,202,99,108,223,26,14,120,
675 92,194,214,47,36,52,118,5,215,55,40,6,29,13,69,253,155,214,15,253,80,10,
676 93,41,16,134,133,130,26,132,88,160,25,81,85,6,147,106,169,176,173,45,234,
677 69,251,63,235,237,59,25,32,52,238,33,211,126,240,31,109,239,108,103,139,
678 48,28,240,56,134,242,214,32,187,111,185,171,165,177,172,64,61,62,17,226,
679 82,32,12,11,5,53,8,7,6,7,95,88,95,97,176,167,214,9,251,219,150,254,104,
680 63,191,207,74,223,172,24,180,255,166,201,62,229,125,251,223,118,182,173,
681 25,235,199,228,71,26,50,107,3,250,193,213,45,23,3,71,61,71,24,242,82,32,
682 12,11,5,53,8,251,6,6,159,92,53,230,95,34,244,35,108,101,139,189,204,54,
683 59,210,126,220,128,149,222,160,61,104,159,176,194,254,135,75,108,111,111,
684 99,139,54,28,176,21,66,100,233,232,127,119,122,76,165,64,24,14,82,32,12,
685 11,5,53,8,123,251,7,31,94,86,98,176,167,227,30,192,204,227,246,127,213,
686 218,167,25,56,52,190,161,217,190,227,195,182,255,219,213,182,202,106,142,
687 160,22,150,229,253,250,145,234,160,144,2,97,56,72,129,48,44,164,64,56,186,
688 97,47,219,47,175,217,254,209,99,223,198,192,161,113,12,157,246,73,49,246,
689 99,206,177,125,100,89,4,138,176,44,95,129,80,201,114,82,32,12,11,5,251,
690 169,209,167,86,91,229,212,232,86,182,216,63,218,222,137,176,31,63,104,66,
691 209,56,134,18,251,94,119,218,158,158,102,91,109,56,90,11,134,232,50,117,
692 106,84,201,114,82,32,12,11,169,155,101,70,37,224,108,93,105,155,89,101,
693 223,205,58,159,213,229,72,214,217,79,252,173,237,135,113,124,76,126,68,
694 33,75,221,44,163,100,61,41,16,134,133,130,26,132,131,14,199,204,232,106,
695 131,61,13,124,216,211,182,252,37,219,237,189,246,173,13,40,26,199,144,103,
696 223,255,1,219,227,219,218,162,12,135,106,229,80,17,108,143,79,40,16,134,
697 131,20,8,195,66,65,13,66,244,94,124,205,248,126,149,247,40,219,119,107,
698 236,39,91,135,130,237,246,201,51,109,55,253,206,246,125,192,190,160,52,
699 42,97,155,224,123,160,94,129,48,44,164,64,24,22,10,118,16,142,227,43,214,
700 182,182,197,252,197,54,163,218,190,139,69,78,135,14,216,183,42,181,239,
701 249,87,219,235,193,229,8,138,176,243,244,96,123,197,154,2,97,120,72,129,
702 48,44,20,236,32,156,55,78,47,221,158,106,91,247,148,253,129,38,251,20,3,
703 141,198,43,212,216,167,205,182,95,119,144,109,177,225,56,131,37,236,247,
704 102,176,189,116,91,129,48,60,164,64,24,22,10,118,16,142,203,103,152,142,
705 180,253,111,133,253,15,221,150,121,70,34,201,254,187,115,109,31,142,251,
706 139,179,183,36,28,25,92,159,97,114,74,129,48,28,164,64,24,22,10,118,16,
707 174,41,10,232,135,121,39,218,98,78,183,125,146,109,63,200,34,207,72,52,
708 216,167,190,100,187,125,7,219,6,139,191,121,124,216,240,199,47,115,131,
709 233,195,188,78,41,16,134,131,20,8,195,66,193,14,194,204,218,206,3,103,165,
710 26,172,234,24,133,93,109,171,158,178,61,80,109,223,197,64,163,113,9,61,
711 246,109,150,216,207,254,163,237,29,107,190,47,109,164,225,254,159,138,123,
712 250,131,236,51,14,10,132,225,32,5,194,176,80,176,131,176,190,163,239,168,
713 247,210,13,86,117,44,194,52,219,234,249,182,139,44,114,58,180,217,190,227,
714 61,182,167,118,9,134,199,228,125,12,111,68,87,245,7,219,215,161,21,8,195,
715 65,10,132,97,161,96,7,225,192,224,224,153,159,100,25,172,234,232,6,92,174,
716 147,108,95,198,219,143,50,208,104,92,66,187,125,242,90,251,73,28,143,225,
717 32,131,58,76,180,199,255,152,21,124,95,135,86,32,12,7,41,16,134,133,130,
718 29,132,232,174,37,69,99,247,40,33,20,252,183,237,255,85,218,119,51,0,105,
719 92,66,190,125,255,91,109,207,77,177,173,55,28,100,176,135,157,166,39,173,
720 47,110,149,205,25,60,82,32,12,7,41,16,134,133,66,0,132,51,163,170,182,26,
721 27,16,78,182,69,124,104,255,107,151,125,146,1,72,129,15,3,246,9,223,216,
722 47,222,215,246,83,176,188,47,109,68,97,191,55,83,83,171,131,236,253,106,
723 72,129,48,28,164,64,24,22,10,1,16,254,146,223,60,113,12,158,169,63,206,
724 246,245,26,251,73,227,254,176,60,8,204,178,31,116,175,237,169,160,126,58,
725 194,123,56,242,221,244,178,150,32,123,191,26,82,32,12,7,41,16,134,133,66,
726 0,132,181,237,189,147,94,28,77,16,78,180,197,220,105,127,122,147,125,191,
727 113,167,96,155,125,123,187,253,206,67,109,11,130,253,233,8,239,225,204,
728 79,179,58,251,130,236,217,9,164,64,24,14,82,32,12,11,133,0,8,7,29,142,83,
729 62,206,52,216,86,191,195,84,219,186,153,246,155,58,236,219,25,152,20,224,
730 208,111,159,88,102,223,227,10,219,27,91,219,98,12,71,24,122,225,129,159,
731 138,101,91,6,149,20,8,195,65,10,132,97,161,16,0,33,122,126,221,40,124,140,
732 9,175,235,120,219,215,223,218,47,238,179,79,52,96,41,192,161,198,62,237,
733 85,251,173,123,218,150,27,142,48,84,195,130,236,224,187,101,20,41,16,134,
734 131,20,8,195,66,161,1,194,152,178,246,137,91,118,191,204,68,91,236,245,
735 182,151,242,236,251,27,152,20,248,176,202,126,202,169,182,207,38,5,225,
736 139,179,253,11,219,188,144,208,212,25,100,47,87,19,82,32,12,7,41,16,134,
737 133,66,3,132,101,45,61,7,207,246,255,253,50,83,108,235,239,183,61,209,106,
738 223,222,192,164,0,7,28,193,255,218,238,217,49,228,158,142,240,30,206,253,
739 44,91,182,98,176,73,129,48,28,164,64,24,22,10,13,16,182,116,247,95,241,
740 117,158,193,194,250,18,38,216,226,142,182,205,255,214,254,199,126,251,86,
741 6,44,5,50,116,216,183,251,198,126,241,217,182,143,130,235,35,130,163,18,
742 102,199,84,203,86,12,54,41,16,134,131,20,8,195,66,161,1,194,129,193,193,
743 199,86,150,250,241,88,253,201,182,207,51,237,135,12,140,43,5,91,236,59,
744 220,97,123,102,170,109,157,225,216,194,33,108,243,66,66,78,93,240,61,65,
745 40,164,64,24,14,82,32,12,11,133,6,8,209,188,180,250,17,125,143,105,7,219,
746 134,123,109,79,182,141,235,233,80,28,193,133,246,115,15,179,253,104,56,
747 182,240,9,39,125,148,89,223,25,100,31,166,215,164,64,24,14,82,32,12,11,
748 133,12,8,203,90,122,124,255,12,197,158,182,229,159,218,175,28,223,103,36,
749 50,236,135,220,100,179,135,219,21,65,125,152,96,139,127,106,85,89,208,125,
750 116,66,147,2,97,56,72,129,48,44,20,50,32,196,154,254,115,113,145,193,212,
751 186,13,39,216,190,74,183,31,54,142,23,5,251,236,19,63,180,253,117,111,219,
752 178,173,108,113,134,99,11,171,48,245,213,164,37,185,65,220,247,20,8,195,
753 65,10,132,97,161,144,1,33,138,43,111,223,218,235,187,214,38,217,162,254,
754 102,123,173,196,190,151,129,76,129,12,61,246,109,222,180,223,112,178,237,
755 139,227,109,95,7,32,28,109,155,111,217,151,116,255,238,157,244,202,214,
756 94,217,120,65,40,5,194,112,144,2,97,88,40,148,64,56,48,56,120,238,220,108,
757 131,181,213,194,62,182,159,63,177,255,185,213,190,131,129,76,1,14,128,176,
758 202,190,107,0,66,165,125,183,165,246,51,255,98,155,177,147,109,173,161,
759 42,44,18,30,90,86,18,172,103,69,157,82,32,12,7,41,16,134,133,66,9,132,104,
760 78,82,173,249,181,156,19,108,113,7,216,150,172,177,159,60,190,207,72,4,
761 38,12,218,39,116,219,183,205,180,31,124,181,237,213,41,182,117,150,125,
762 30,99,43,123,124,82,85,135,108,182,224,148,2,97,56,72,129,48,44,20,98,32,
763 204,169,239,218,247,141,20,189,193,157,108,139,184,198,246,74,174,253,0,
764 3,48,66,50,224,8,126,99,191,24,4,82,106,125,37,88,48,156,61,55,123,32,168,
765 253,65,5,194,240,144,2,97,88,40,196,64,216,214,51,240,167,121,191,62,89,
766 63,201,22,249,154,237,31,45,227,125,58,52,0,161,218,190,235,115,182,187,
767 143,177,125,187,131,109,131,86,124,203,6,188,246,111,211,27,130,156,131,
768 10,132,97,33,5,194,176,80,136,129,16,125,146,84,55,249,165,196,173,156,
769 167,67,23,219,207,25,223,135,229,199,58,116,219,183,41,182,239,253,178,
770 253,246,125,109,63,7,209,91,105,78,248,48,179,162,53,248,62,64,104,144,
771 2,97,56,72,129,48,44,20,122,32,108,233,238,63,125,78,214,149,182,55,210,
772 237,135,142,251,7,5,199,46,180,218,183,255,217,126,198,189,182,39,247,177,
773 253,28,92,95,43,220,230,133,132,151,54,84,246,5,251,137,81,5,194,240,144,
774 2,97,88,40,244,64,232,24,232,203,90,240,76,131,125,170,129,28,161,20,22,
775 217,207,57,211,54,103,154,109,245,132,32,124,18,113,247,25,201,121,245,
776 93,178,177,130,89,10,132,225,32,5,194,176,80,168,129,176,165,204,241,227,
777 205,142,23,183,54,144,35,4,66,191,125,171,114,251,30,95,219,47,57,217,246,
778 69,48,242,79,11,15,45,43,145,141,21,228,82,32,12,7,41,16,134,133,66,7,132,
779 131,131,142,252,159,29,159,156,230,120,33,212,46,10,14,216,39,36,218,127,
780 247,136,237,145,223,219,230,109,99,139,54,112,37,184,194,126,111,166,150,
781 183,4,253,213,65,33,5,194,112,144,2,97,88,40,68,64,56,208,239,136,127,207,
782 49,99,119,3,66,66,32,100,219,15,186,205,246,220,46,182,85,19,67,226,11,
783 77,47,110,168,232,103,202,18,18,82,32,12,7,41,16,134,133,66,1,132,189,29,
784 142,152,89,142,55,247,115,204,216,77,31,250,95,219,173,206,190,179,31,97,
785 124,95,198,77,24,180,79,224,48,54,218,127,127,135,253,153,160,120,28,194,
786 199,112,200,236,180,156,144,184,58,40,164,64,24,14,82,32,12,11,133,2,8,
787 123,218,28,21,241,142,242,88,67,232,43,141,121,230,203,31,79,181,125,54,
788 162,112,133,237,13,156,48,3,153,2,25,64,224,12,219,77,167,219,62,217,49,
789 132,16,72,216,250,133,132,23,214,87,132,192,205,162,154,20,8,195,65,225,
790 5,194,193,205,37,99,71,174,45,204,30,120,133,218,205,50,155,43,171,182,
791 115,167,87,147,12,22,217,83,152,96,139,159,102,91,179,220,126,218,184,60,
792 122,216,103,159,88,111,223,105,186,237,150,125,108,63,7,251,133,64,183,
793 225,208,183,82,155,186,250,101,195,132,132,20,8,195,65,225,5,194,250,250,
794 250,194,194,194,162,162,162,226,226,226,234,234,234,190,62,127,62,22,218,
795 214,214,198,22,74,74,74,248,33,163,44,175,208,6,97,111,255,224,83,171,202,
796 188,127,146,66,132,173,108,177,167,217,62,141,179,31,101,224,83,0,66,183,
797 125,219,141,246,223,63,105,127,240,64,219,98,195,81,133,76,152,250,106,
798 210,242,77,205,178,85,66,69,10,132,225,160,240,2,97,65,65,1,8,4,96,173,
799 173,173,176,161,161,161,65,174,24,137,64,96,101,101,101,123,123,187,127,
800 28,29,23,133,54,8,209,166,198,238,195,223,78,51,216,101,115,56,215,246,
801 193,38,251,126,1,126,0,191,199,190,205,247,182,11,254,104,123,103,15,219,
802 242,16,254,54,33,174,246,19,43,203,152,148,200,38,9,21,41,16,134,131,194,
803 14,132,101,101,101,157,157,157,29,29,29,176,1,34,242,35,45,45,45,57,57,
804 25,79,177,185,185,153,30,79,26,254,162,170,170,170,210,210,82,86,197,199,
805 199,147,69,108,97,112,112,144,4,141,141,141,61,61,61,65,116,118,52,228,
806 65,72,75,188,23,95,179,141,103,167,112,91,91,244,223,108,175,5,242,125,
807 164,3,246,173,26,236,59,45,179,159,126,142,237,195,109,108,209,193,245,
808 94,24,63,194,193,179,211,50,106,229,48,9,37,5,17,8,153,154,167,167,167,
809 71,56,21,29,29,93,94,94,238,135,141,34,11,70,114,227,198,141,169,169,169,
810 65,52,215,223,66,133,29,8,83,82,82,4,231,232,49,45,45,45,32,13,191,16,7,
811 49,41,41,137,230,103,45,116,228,47,41,129,31,44,100,85,102,102,38,126,164,
812 216,194,192,192,0,224,204,205,205,21,104,9,22,22,134,60,8,81,79,255,224,
813 181,255,219,164,55,205,90,216,214,22,245,168,237,225,38,251,20,3,171,198,
814 40,244,219,183,74,181,31,246,138,253,182,83,108,159,135,198,227,16,190,
815 132,87,54,86,134,208,45,50,191,42,136,64,216,219,219,203,72,103,114,143,
816 93,234,234,234,74,76,76,228,119,127,127,63,241,136,72,204,23,108,35,134,
817 191,136,24,254,138,181,114,19,14,7,254,64,66,66,2,19,253,186,186,186,238,
818 238,110,25,27,234,10,59,16,194,54,122,3,93,1,182,85,84,84,180,183,183,199,
819 198,198,174,93,187,54,38,38,6,16,230,229,229,209,51,152,10,209,9,232,37,
820 76,169,152,25,173,88,177,130,238,37,55,225,112,208,195,216,2,195,131,236,
821 10,132,150,210,166,134,238,163,222,77,55,24,104,188,177,89,246,235,219,
822 237,147,13,184,26,163,80,96,223,247,118,219,179,251,219,150,134,228,189,
823 48,158,194,85,223,230,119,244,14,200,102,8,45,5,23,8,115,114,114,176,75,
824 76,238,43,43,43,147,147,147,177,102,216,180,184,184,56,236,27,147,126,86,
825 17,201,42,24,201,252,158,152,140,140,140,248,248,248,245,235,215,147,82,
826 108,132,52,133,133,133,108,1,151,32,88,236,219,150,43,236,64,8,219,152,
827 236,0,179,162,162,34,26,155,126,80,91,91,203,36,8,63,175,180,180,148,30,
828 47,64,200,42,34,133,215,136,255,71,70,177,5,122,6,171,152,40,213,215,215,
829 211,159,44,222,81,134,38,128,76,254,250,251,178,114,179,26,26,27,196,239,
830 16,238,220,148,108,110,114,221,212,87,19,53,3,189,187,109,197,151,246,203,
831 2,240,169,222,102,251,142,209,246,99,110,183,253,119,59,91,100,200,159,
832 5,53,132,19,62,204,168,12,254,175,76,120,82,112,129,16,147,133,77,3,135,
833 112,78,156,223,98,234,207,95,216,134,74,156,194,44,192,197,214,214,86,113,
834 210,11,103,32,50,50,18,131,38,54,130,97,196,24,178,5,204,32,14,165,136,
835 12,121,133,23,8,65,87,86,86,22,83,36,4,246,232,55,120,129,52,57,14,19,205,
836 15,17,153,13,225,44,210,99,232,37,192,146,1,64,74,254,146,76,108,1,138,
837 144,17,52,146,222,250,189,164,174,169,46,58,63,154,240,115,210,207,17,185,
838 17,252,72,45,73,165,128,114,117,40,170,171,111,224,153,53,229,194,64,139,
839 47,52,245,217,39,26,160,53,186,161,206,190,243,219,246,107,47,179,205,222,
840 217,182,70,99,67,248,132,221,94,79,94,190,169,57,36,79,138,10,5,227,169,
841 81,126,51,221,7,138,117,117,117,197,197,197,204,227,249,141,201,194,142,
842 65,62,140,24,94,32,246,13,16,178,10,69,71,71,107,32,196,190,177,17,96,73,
843 70,220,0,17,25,242,10,47,16,14,121,72,46,241,91,139,129,13,252,16,34,146,
844 69,225,54,241,67,91,59,148,223,41,126,139,72,185,108,97,149,215,149,47,
845 72,94,160,15,107,115,214,6,197,145,111,137,96,225,229,243,242,142,182,205,
846 79,183,31,58,48,150,55,136,182,217,183,127,215,118,205,225,182,31,240,2,
847 13,120,8,159,240,212,170,178,80,122,124,94,19,195,164,177,165,145,169,100,
848 86,97,86,102,126,38,63,8,29,157,150,158,251,234,65,8,195,18,18,18,152,220,
849 51,245,7,120,217,217,217,0,15,16,86,87,87,99,220,88,5,8,153,247,51,167,
850 111,110,110,94,183,110,157,6,66,50,226,11,82,124,178,224,74,138,200,144,
851 87,120,129,48,220,20,158,32,68,85,89,235,54,189,116,168,129,91,163,21,58,
852 237,147,50,237,135,188,97,191,225,32,219,162,112,59,11,170,15,19,236,241,
853 87,124,157,215,211,31,154,151,6,187,123,186,215,100,175,49,12,159,134,22,
854 127,30,184,10,152,152,160,67,175,40,167,226,226,226,240,101,241,11,1,33,
855 14,31,192,43,47,47,135,139,141,141,141,128,144,69,86,129,204,228,228,228,
856 196,196,196,146,146,18,13,132,136,100,108,33,47,47,47,28,108,133,144,2,
857 97,40,43,28,65,56,216,239,72,154,227,152,117,128,129,94,163,18,250,237,
858 19,151,218,207,186,218,246,234,126,182,159,12,84,8,195,112,214,167,217,
859 69,77,33,123,87,97,48,130,80,201,111,41,16,134,178,194,14,132,253,189,142,
860 152,217,142,233,59,25,0,182,133,97,208,62,1,47,112,149,253,148,51,108,159,
861 108,111,219,24,212,159,9,28,173,176,231,140,148,136,210,182,208,189,50,
862 168,64,24,94,82,32,12,101,133,23,8,187,155,29,27,95,118,188,186,163,1,99,
863 91,24,54,217,247,253,200,126,213,5,182,247,182,182,197,24,96,16,182,97,
864 191,55,83,23,231,134,248,211,56,10,132,97,165,144,5,97,95,95,95,81,81,81,
865 74,74,74,123,123,187,140,114,222,243,153,151,151,39,238,152,98,177,161,
866 161,33,41,41,73,188,127,129,244,249,249,249,172,202,205,205,5,21,36,200,
867 204,204,12,246,27,136,187,123,187,43,26,42,8,169,121,169,155,202,55,241,
868 163,182,165,86,220,7,20,106,106,171,118,124,127,173,227,165,109,13,24,243,
869 59,12,218,127,147,110,63,244,1,219,227,191,181,253,176,173,45,202,64,130,
870 112,14,248,130,75,243,154,66,247,25,28,41,5,194,176,82,104,130,16,91,95,
871 93,93,157,157,157,93,89,89,9,14,53,211,47,30,150,104,107,107,139,138,138,
872 2,144,201,201,201,245,245,245,208,142,223,144,15,70,246,246,246,14,12,12,
873 144,94,60,80,81,82,82,82,92,92,172,191,101,148,85,218,214,132,180,69,67,
874 252,22,202,185,159,209,217,32,219,201,223,148,223,216,216,40,151,67,79,
875 237,213,142,255,93,61,42,223,172,135,127,237,246,201,185,246,3,238,183,
876 63,190,147,109,109,8,191,26,212,191,48,249,165,196,25,81,85,33,243,209,
877 93,47,98,18,25,145,31,177,44,99,217,207,105,63,47,77,93,202,15,66,83,155,
878 229,252,96,131,149,96,17,123,165,63,235,51,100,71,156,105,248,75,60,18,
879 49,226,55,226,183,72,25,206,10,89,16,150,150,150,214,213,213,129,55,252,
880 60,188,61,17,95,88,88,8,26,233,40,192,175,162,162,2,40,146,0,218,129,189,
881 230,230,102,214,194,72,241,104,4,140,132,28,172,213,40,200,15,60,72,210,
882 192,75,18,139,72,84,85,85,213,227,84,77,77,141,30,153,126,11,24,179,23,
883 14,155,191,252,150,177,254,138,45,192,114,28,95,28,220,214,214,86,25,27,
884 58,26,116,148,69,57,62,63,207,192,51,255,66,141,125,218,215,246,75,174,
885 181,189,50,213,182,206,0,0,21,8,59,188,156,248,210,134,202,208,123,173,
886 182,39,245,245,15,189,126,140,185,50,243,200,158,222,30,126,91,141,25,216,
887 43,236,152,102,223,80,75,75,139,176,81,226,245,200,88,36,102,255,20,129,
888 35,199,106,97,85,80,83,83,19,150,13,163,135,48,11,44,138,188,225,172,208,
889 4,33,205,143,245,23,175,128,161,79,104,29,5,52,226,38,210,51,162,163,163,
890 33,98,110,110,46,157,6,40,166,167,167,131,49,224,199,15,214,210,227,215,
891 172,89,147,149,149,69,140,120,215,26,121,217,8,224,164,27,145,50,33,33,
892 65,99,94,90,90,26,14,37,98,203,250,30,105,22,57,186,186,135,9,45,45,109,
893 113,113,113,107,157,90,183,110,29,27,111,107,235,53,164,241,61,116,118,
894 13,208,215,217,142,216,96,100,100,100,101,101,181,33,205,136,130,229,230,
895 142,101,209,142,119,127,235,216,226,135,5,187,237,219,190,101,191,238,88,
896 219,55,83,108,235,13,214,95,5,17,182,127,57,241,237,216,234,238,190,208,
897 124,88,194,147,0,70,109,109,45,163,94,46,143,150,250,122,29,221,93,142,
898 94,255,95,199,35,192,150,152,152,136,201,98,22,46,34,153,193,99,208,48,
899 80,229,229,229,120,2,44,242,119,227,198,141,252,197,52,137,231,235,197,
900 75,69,88,133,109,4,129,68,98,187,68,246,112,86,200,130,80,60,25,99,0,33,
901 189,135,94,66,87,96,30,68,55,162,7,128,61,18,32,38,80,76,175,232,31,116,
902 122,226,215,175,95,47,102,91,226,146,33,121,217,72,65,65,1,93,135,141,71,
903 69,69,105,157,207,119,16,150,215,57,22,70,13,19,150,69,212,175,93,187,65,
904 112,75,232,151,136,58,67,26,223,195,146,200,14,185,21,151,86,175,79,88,
905 28,213,111,72,230,99,136,206,112,244,122,43,95,96,213,223,235,40,94,231,
906 120,115,95,3,210,70,20,122,237,91,23,218,247,125,195,126,227,129,182,197,
907 234,94,80,47,97,202,43,73,47,108,168,232,13,230,7,231,153,134,142,40,244,
908 15,12,217,10,236,128,24,56,76,34,177,24,134,52,126,4,71,127,159,163,177,
909 204,145,191,210,145,189,208,81,184,214,209,94,63,48,48,104,72,227,54,24,
910 132,41,107,109,109,5,120,216,46,205,22,49,131,199,70,117,116,116,96,142,
911 152,1,19,223,216,216,8,246,176,99,164,199,160,97,187,96,97,70,70,6,63,16,
912 222,66,81,81,17,63,68,118,168,15,71,153,253,227,39,240,91,68,178,53,178,
913 147,70,60,131,40,34,67,79,33,123,106,20,218,209,204,112,139,158,161,181,
914 52,93,7,193,188,152,152,24,26,88,184,140,116,11,144,217,210,210,194,42,
915 82,10,40,10,82,130,73,250,147,200,14,228,240,8,217,44,25,241,8,5,29,145,
916 56,183,64,23,97,110,53,44,8,23,68,13,19,86,172,207,16,3,79,211,242,141,
917 149,134,52,190,135,95,134,176,186,153,86,175,139,91,28,217,99,72,230,99,
918 136,74,183,12,8,251,58,29,145,175,57,94,219,197,0,54,223,67,143,125,155,
919 101,246,211,239,178,61,125,152,237,71,117,33,208,123,56,244,173,180,111,
920 211,27,6,130,249,74,82,103,143,35,33,111,100,33,41,187,9,95,74,14,27,167,
921 98,99,99,19,115,123,12,201,70,26,26,54,213,59,178,23,232,67,89,65,151,33,
922 141,219,208,97,122,98,19,43,167,1,79,196,0,66,22,5,8,153,208,99,163,72,
923 131,1,132,100,34,1,120,99,190,142,185,19,191,97,36,116,20,171,16,25,49,
924 98,88,197,170,170,42,10,43,34,177,138,208,145,77,1,93,102,6,34,50,244,20,
925 154,32,68,116,5,218,114,205,154,53,226,220,38,72,163,201,233,49,17,17,17,
926 203,151,47,167,43,128,55,58,205,138,21,43,104,123,154,25,16,210,239,87,
927 175,94,45,102,79,80,16,183,143,24,126,176,200,6,129,28,233,215,173,91,199,
928 54,153,28,209,141,196,9,7,58,205,202,149,43,153,67,177,150,93,208,183,60,
929 225,208,23,16,254,178,177,98,237,90,57,9,21,90,18,209,106,72,227,123,88,
930 20,217,45,183,226,210,170,245,137,11,162,6,13,201,124,12,22,2,33,20,124,
931 121,123,3,219,124,14,19,74,103,157,122,137,237,237,157,108,107,149,23,56,
932 108,216,253,245,228,21,5,45,193,254,14,181,150,14,99,103,30,46,12,174,216,
933 80,32,199,140,78,63,71,52,153,82,142,44,180,101,172,53,128,176,62,173,208,
934 144,198,109,104,118,119,254,210,12,66,189,71,40,102,240,26,8,89,11,5,197,
935 75,183,89,4,120,169,169,169,194,184,9,145,49,55,55,23,55,0,123,136,161,
936 19,115,125,5,194,144,18,60,19,87,143,253,22,120,163,75,109,201,133,101,
937 186,159,225,146,155,57,180,182,245,38,37,37,139,81,71,95,100,90,215,217,
938 213,111,72,51,130,208,53,64,39,214,78,239,224,7,183,180,180,25,211,140,
939 36,140,191,87,208,94,235,88,254,136,137,109,62,132,23,38,14,157,71,253,
940 230,10,71,193,74,199,64,223,7,9,181,187,189,150,108,48,250,42,232,195,4,
941 123,252,225,111,167,173,42,12,133,215,46,143,28,132,76,73,203,197,168,209,
942 235,231,136,22,67,178,145,6,176,103,0,97,73,82,157,33,141,219,224,29,132,
943 240,12,206,129,43,113,141,16,242,49,77,23,144,19,32,100,85,94,94,94,102,
944 102,38,89,68,122,102,240,172,18,219,17,18,30,161,184,142,152,146,146,66,
945 22,140,30,233,115,114,114,248,75,98,182,12,68,5,32,67,76,225,2,66,90,84,
946 204,131,252,22,217,113,4,233,43,114,121,204,196,161,210,137,241,92,153,
947 130,121,114,46,125,23,189,150,169,159,184,15,104,11,167,2,227,175,214,138,
948 33,146,189,184,181,17,114,195,134,183,15,115,68,78,119,84,37,59,250,93,
949 115,231,254,193,159,243,155,143,125,63,195,96,253,85,16,97,235,23,18,110,
950 252,161,32,167,78,94,40,10,118,245,245,59,42,26,70,22,74,171,134,30,178,
951 146,0,116,138,65,84,94,215,103,72,54,210,208,83,223,184,25,8,11,35,90,27,
952 123,13,105,220,6,183,39,99,186,187,187,129,19,86,2,182,137,231,196,152,
953 241,67,172,161,9,180,107,176,139,107,123,164,132,103,8,112,194,57,172,89,
954 125,125,189,97,90,47,64,136,215,72,246,174,174,46,224,199,214,48,32,197,
955 197,197,228,226,111,75,75,11,241,248,136,122,63,50,52,20,46,32,28,21,5,
956 160,249,217,5,162,183,197,198,197,210,191,135,22,28,91,180,83,231,246,134,
957 30,38,17,51,68,36,87,4,153,6,29,45,229,142,57,167,140,236,97,65,144,57,
958 235,0,71,252,187,142,174,38,188,64,185,37,151,168,137,250,142,190,191,124,
959 147,55,209,158,96,192,64,152,135,109,95,76,120,108,101,89,91,79,8,78,252,
960 71,36,248,177,113,227,198,117,235,214,109,216,176,1,79,75,59,3,185,101,
961 26,116,244,116,56,138,35,134,40,88,188,209,209,179,165,83,13,49,162,113,
962 7,153,55,139,1,14,228,144,88,139,68,36,63,68,188,144,62,94,147,56,53,10,
963 255,12,9,68,22,36,98,144,51,121,72,73,129,208,66,162,135,149,212,149,100,
964 148,102,164,22,165,174,76,90,153,94,146,206,239,250,230,95,223,10,63,82,
965 117,247,116,179,5,66,116,118,116,116,78,52,63,114,202,115,58,186,130,237,
966 93,57,131,3,142,226,245,142,247,143,54,114,206,75,152,190,147,99,222,165,
967 142,132,247,28,29,195,212,94,115,87,255,147,171,202,118,123,93,157,38,29,
968 10,19,108,241,199,188,151,254,67,86,99,8,127,95,112,68,194,145,194,73,218,
969 242,19,51,70,117,180,56,242,126,150,191,71,67,152,142,45,63,99,9,233,197,
970 83,209,114,57,156,164,64,104,33,49,231,138,222,20,109,120,171,83,81,117,
971 145,92,61,114,53,181,53,25,182,182,60,125,121,107,71,176,61,86,159,179,
972 200,249,53,9,223,30,22,124,109,154,227,167,251,134,158,47,236,254,245,165,
973 7,222,213,211,63,184,161,184,245,247,31,168,211,164,241,127,159,159,159,
974 91,223,165,40,136,218,59,219,27,91,26,107,26,106,226,211,227,235,154,234,
975 248,221,214,209,182,229,206,80,115,91,51,155,106,172,41,107,204,90,58,244,
976 163,165,145,24,185,78,105,252,20,238,32,28,242,243,157,146,203,78,25,98,
977 244,139,250,223,163,46,5,66,163,250,123,29,137,31,58,94,241,225,6,209,23,
978 183,113,204,216,221,177,248,14,71,125,174,249,44,232,176,162,69,55,53,118,
979 95,62,47,111,135,87,18,13,108,8,147,176,251,235,201,211,35,42,59,195,236,
980 121,121,79,98,140,103,149,101,45,74,89,68,88,152,188,80,252,200,174,200,
981 222,242,177,191,50,107,165,216,218,162,228,5,226,71,126,121,112,124,254,
982 62,180,21,214,32,20,183,165,20,20,20,84,85,85,1,33,17,201,143,242,242,242,
983 194,194,194,122,231,123,137,58,59,59,139,156,234,234,234,234,233,233,97,
984 85,101,101,229,24,177,80,129,112,51,245,119,59,54,190,52,252,55,149,94,
985 218,214,49,247,76,71,196,171,142,250,60,153,209,95,225,26,206,207,104,56,
986 103,110,246,214,47,132,209,85,195,157,167,39,221,252,99,65,68,105,155,114,
987 4,53,49,192,51,203,50,13,99,103,84,64,184,60,115,185,97,179,249,101,10,
988 132,227,175,176,6,97,83,83,147,120,190,208,249,92,129,188,77,188,185,185,
989 57,37,37,133,191,155,54,109,106,111,111,207,203,203,19,15,208,228,230,230,
990 214,214,214,86,87,87,147,5,40,138,196,163,43,5,194,95,213,211,234,88,120,
991 171,227,229,201,70,236,25,194,167,167,59,242,151,13,189,116,123,112,116,
992 238,236,192,208,213,180,247,206,138,169,158,250,106,146,1,24,33,25,14,127,
993 59,109,89,126,115,123,143,114,4,55,147,2,97,184,73,157,26,29,122,59,67,
994 108,108,172,246,134,133,186,186,58,252,63,113,211,48,228,203,116,190,171,
995 26,242,241,131,85,224,144,248,209,191,120,238,148,2,161,84,91,165,227,187,
996 191,15,61,249,103,192,158,12,19,28,51,118,115,204,187,204,145,183,212,49,
997 48,38,119,54,98,237,114,234,186,46,253,42,119,74,136,158,41,157,96,143,
998 223,115,70,242,191,127,41,109,234,10,247,91,67,221,42,100,64,200,252,158,
999 105,125,82,82,18,166,76,59,120,140,27,243,251,196,196,68,97,232,74,74,74,
1000 72,192,188,159,223,164,79,77,77,13,225,87,169,121,82,184,131,16,164,225,
1001 225,225,17,106,78,94,103,103,103,90,90,26,192,163,67,84,58,5,2,233,55,44,
1002 118,116,116,136,19,164,34,229,168,139,158,90,214,80,150,93,153,157,86,146,
1003 182,50,97,101,86,121,22,191,235,154,235,228,234,145,171,171,167,139,45,
1004 16,162,50,163,98,115,99,249,177,169,106,19,145,114,181,53,85,147,238,248,
1005 242,143,238,41,248,194,4,199,187,191,115,172,121,218,81,178,209,209,55,
1006 230,165,104,233,238,95,148,211,116,253,247,5,59,188,28,82,56,220,247,141,
1007 148,71,126,41,141,41,111,239,83,39,67,61,40,100,64,200,36,158,137,190,120,
1008 64,176,215,245,41,155,138,138,10,108,26,134,142,153,125,115,115,115,86,
1009 86,22,191,49,131,192,146,85,213,213,213,204,245,69,202,240,81,56,130,176,
1010 187,187,123,205,154,53,120,129,252,96,17,63,12,200,137,247,239,9,65,59,
1011 58,16,211,37,58,10,179,36,241,96,105,78,78,142,72,63,166,98,164,33,14,32,
1012 54,46,150,93,139,69,185,206,47,137,45,4,205,115,132,101,209,142,119,60,
1013 124,77,98,230,158,67,15,197,183,150,15,221,65,19,64,181,245,12,172,45,106,
1014 57,255,179,28,3,78,130,49,108,253,66,194,189,75,139,243,27,186,194,237,
1015 35,18,35,21,195,36,100,78,141,194,191,154,154,26,38,247,24,58,17,195,111,
1016 104,7,29,89,213,214,214,134,47,136,63,80,85,85,133,107,216,208,208,144,
1017 144,144,176,37,239,207,10,82,133,181,71,72,87,160,31,208,27,152,46,209,
1018 246,116,20,58,58,125,2,10,50,69,42,40,40,224,135,240,2,89,43,190,93,34,
1019 115,142,177,32,110,92,92,156,214,113,183,92,76,247,144,92,176,166,6,7,28,
1020 69,107,29,239,28,110,228,223,244,157,28,31,159,52,244,114,209,54,255,61,
1021 227,45,87,255,192,224,226,156,166,11,191,200,217,53,56,95,204,182,255,155,
1022 169,119,46,46,202,168,9,242,87,11,5,80,253,3,253,93,221,93,45,109,45,169,
1023 153,169,29,157,29,252,30,149,225,223,221,211,205,166,186,234,43,187,114,
1024 126,26,250,193,82,207,232,79,175,57,84,237,220,21,108,203,200,200,192,154,
1025 105,246,36,50,50,146,105,61,179,127,226,197,109,16,184,128,226,188,151,
1026 213,39,202,99,166,176,6,33,156,203,206,206,134,112,64,130,174,131,255,7,
1027 240,0,33,145,116,11,17,73,12,221,5,82,226,20,202,108,99,175,176,3,97,127,
1028 143,35,106,230,144,207,167,71,224,203,219,57,22,221,230,216,244,139,163,
1029 54,207,81,26,229,168,47,145,137,199,79,237,61,3,27,74,90,31,91,81,118,200,
1030 236,52,3,105,172,25,182,121,33,225,156,185,217,111,70,87,167,213,116,142,
1031 255,71,148,154,170,3,236,205,111,185,24,137,65,241,64,189,65,224,45,63,
1032 63,191,178,178,82,44,50,215,199,136,105,167,70,177,45,248,136,20,13,211,
1033 135,125,227,7,198,173,180,180,180,188,188,92,36,8,67,133,251,53,66,80,71,
1034 47,103,30,132,26,27,27,233,22,34,18,9,14,17,47,22,157,201,3,164,177,0,161,
1035 118,106,212,114,234,235,113,68,207,116,188,186,163,228,223,11,91,13,253,
1036 6,129,117,57,142,142,70,71,209,6,71,238,146,161,247,81,213,22,208,24,178,
1037 60,227,170,158,254,193,150,238,254,255,101,54,156,54,39,107,242,75,137,
1038 91,217,141,248,25,247,176,245,11,9,211,166,39,221,252,67,65,100,105,27,
1039 240,198,157,149,135,62,190,42,73,113,228,46,117,52,86,14,121,255,65,162,
1040 32,5,33,163,74,88,176,138,138,10,241,130,80,92,64,98,136,103,45,145,185,
1041 185,185,109,109,109,201,201,201,24,189,170,170,42,138,137,59,40,172,95,
1042 120,42,220,65,168,23,221,61,192,192,243,164,81,7,97,125,125,61,62,46,147,
1043 68,171,169,56,43,190,109,201,35,131,47,109,11,2,7,95,152,216,54,243,176,
1044 234,47,111,170,76,92,218,94,93,48,88,149,249,235,187,137,179,23,180,231,
1045 197,12,193,124,203,196,132,128,185,240,104,169,178,186,250,151,148,162,
1046 123,231,39,31,55,43,102,151,87,226,182,50,1,41,192,97,107,123,252,1,51,
1047 19,47,156,147,242,202,234,77,89,229,245,173,173,173,24,59,191,69,39,28,
1048 93,245,111,138,148,173,89,176,218,209,84,236,232,25,58,217,56,138,146,125,
1049 125,84,197,97,7,35,8,53,137,19,90,140,125,26,148,82,224,243,117,116,116,
1050 96,88,74,74,74,136,199,101,20,191,211,210,210,196,29,164,50,91,248,73,129,
1051 208,138,98,248,141,46,8,153,9,178,205,206,45,19,134,149,113,53,154,42,205,
1052 108,251,248,124,248,55,116,143,232,231,231,13,102,124,219,90,158,89,93,
1053 85,89,83,93,213,94,95,49,88,147,175,81,144,208,87,158,81,93,93,85,189,101,
1054 98,228,51,224,71,87,133,69,69,41,121,197,171,51,74,62,141,46,186,227,135,
1055 156,223,189,157,18,96,31,17,255,239,247,111,197,63,178,32,253,139,141,89,
1056 43,18,115,211,115,242,228,44,99,11,132,199,64,15,28,93,117,101,44,213,55,
1057 232,96,193,154,210,140,216,132,209,19,254,205,168,43,49,49,49,168,65,136,
1058 134,78,186,56,29,65,236,9,19,98,188,67,45,18,25,126,135,173,20,8,173,168,
1059 81,7,161,245,52,232,232,168,117,124,253,167,161,123,97,230,156,234,200,
1060 93,236,232,237,100,68,202,149,66,44,246,116,57,74,34,29,185,63,13,153,206,
1061 81,58,53,42,7,253,24,104,96,112,176,111,96,176,171,111,32,171,182,243,145,
1062 239,226,207,153,147,190,215,140,148,105,211,147,118,120,37,113,155,23,19,
1063 38,152,0,230,71,0,177,147,94,74,152,242,74,210,174,175,37,239,247,70,202,
1064 181,255,219,244,117,122,125,73,93,107,76,124,98,119,47,59,31,77,209,253,
1065 70,87,142,226,36,73,65,26,180,60,125,176,179,205,249,5,217,81,19,86,190,
1066 110,180,197,54,199,228,113,169,0,130,80,47,154,85,254,82,218,92,10,132,
1067 86,84,136,131,112,232,6,209,53,67,143,204,47,189,199,81,176,66,251,70,160,
1068 71,117,182,56,42,83,28,245,214,190,235,117,115,197,198,198,54,52,52,214,
1069 180,247,38,84,182,47,200,110,156,29,83,253,248,202,210,155,127,44,184,240,
1070 139,156,163,223,75,223,231,141,148,93,166,39,121,191,190,136,159,183,227,
1071 43,137,187,189,158,188,255,155,41,39,126,152,121,197,215,121,119,46,46,
1072 122,118,109,249,199,137,181,203,242,155,51,106,59,181,215,193,224,172,227,
1073 184,4,193,121,173,146,100,71,254,170,161,166,108,111,30,149,57,77,16,107,
1074 156,64,168,228,73,10,132,86,84,136,131,176,46,219,145,245,131,163,97,147,
1075 163,207,231,187,249,97,103,255,152,188,205,103,140,4,8,13,175,231,192,242,
1076 119,244,14,212,117,244,149,182,244,108,106,232,206,169,239,202,172,237,
1077 76,173,238,136,46,107,91,190,169,249,187,204,134,79,146,106,63,75,169,131,
1078 154,171,11,91,226,43,218,211,107,58,179,234,186,114,235,187,10,26,187,43,
1079 90,123,155,186,250,187,61,60,0,31,52,32,108,172,114,116,181,57,66,249,60,
1080 135,207,82,32,180,152,20,8,173,168,16,7,225,208,123,209,66,211,33,24,28,
1081 28,236,235,239,35,68,199,70,215,213,215,137,223,190,156,143,34,133,22,124,
1082 23,61,132,237,183,180,182,36,36,37,244,244,244,240,59,100,251,76,136,73,
1083 129,208,98,82,32,180,162,194,224,26,97,104,170,174,169,46,118,83,108,204,
1084 166,152,159,147,126,222,152,189,145,31,4,90,83,174,30,109,21,87,21,179,
1085 253,13,217,27,150,167,44,23,251,42,168,41,144,235,148,172,44,5,66,139,73,
1086 129,208,138,82,32,12,82,149,84,149,44,76,94,104,120,135,214,216,129,48,
1087 181,48,213,176,175,164,146,36,185,78,201,202,82,32,180,152,20,8,173,40,
1088 5,194,32,149,2,161,146,79,82,32,180,152,20,8,173,40,5,194,32,149,2,161,
1089 146,79,82,32,180,152,20,8,173,40,5,194,32,149,2,161,146,79,82,32,180,152,
1090 20,8,173,40,5,194,32,149,2,161,146,79,82,32,180,152,20,8,173,40,5,194,32,
1091 85,107,123,107,89,125,25,97,109,194,218,77,21,155,196,239,177,107,199,250,
1092 230,122,182,207,142,54,36,109,40,169,45,225,119,99,91,216,125,91,60,40,
1093 165,64,104,49,41,16,90,81,10,132,65,173,193,193,193,152,152,152,134,134,
1094 6,185,236,179,200,40,36,151,125,83,71,71,71,98,98,226,232,191,15,83,105,
1095 236,164,64,104,49,41,16,90,76,3,253,142,190,222,222,206,142,204,196,216,
1096 129,158,110,126,135,251,203,168,130,77,96,172,166,166,102,227,198,141,105,
1097 105,105,141,141,141,190,83,173,189,189,189,192,169,226,226,98,237,211,113,
1098 195,10,10,230,230,230,70,70,70,22,22,22,142,201,91,49,149,198,66,10,132,
1099 22,147,2,161,197,212,84,227,40,92,51,184,105,101,111,214,82,71,193,74,71,
1100 193,42,71,99,248,126,45,115,88,85,87,87,131,156,69,139,22,125,245,213,87,
1101 115,231,206,253,238,187,239,126,254,249,231,212,212,84,240,32,83,140,182,
1102 186,186,135,9,133,133,69,28,210,90,167,34,34,34,106,235,90,13,9,220,134,
1103 150,150,182,216,216,88,145,107,221,186,117,206,79,135,247,25,210,152,67,
1104 99,83,71,116,116,52,233,69,198,248,248,248,150,214,94,67,26,67,240,153,
1105 176,74,99,41,5,66,139,73,129,208,98,234,237,113,228,175,144,47,233,39,148,
1106 198,90,237,29,155,184,56,101,101,101,153,155,43,203,169,108,167,114,156,
1107 194,77,17,202,203,27,250,42,208,166,77,155,112,116,202,203,203,241,150,
1108 90,90,90,252,62,143,215,214,214,86,84,84,244,201,39,159,92,115,205,53,187,
1109 237,182,219,196,137,19,183,50,137,200,73,147,38,29,123,236,177,247,220,
1110 115,207,252,249,243,217,175,47,92,196,9,227,56,101,121,156,114,91,168,117,
1111 17,185,239,205,31,10,239,127,151,247,193,255,54,125,240,125,193,199,11,
1112 74,62,93,92,241,197,178,186,111,215,180,253,20,209,190,118,237,122,129,
1113 37,161,213,235,51,23,70,59,134,13,203,55,150,65,64,153,199,169,37,145,237,
1114 134,52,34,252,24,57,240,206,55,89,111,127,157,73,152,243,229,106,240,175,
1115 211,231,31,126,185,65,172,18,225,147,69,101,90,198,207,127,174,37,102,222,
1116 162,204,212,84,89,64,47,50,52,16,213,46,87,108,177,180,182,168,171,171,
1117 147,81,195,137,106,23,31,15,18,162,33,228,138,225,132,123,45,243,88,71,
1118 29,173,142,214,90,71,67,217,208,55,138,249,65,8,170,151,232,134,170,20,
1119 8,173,167,166,106,73,193,156,197,142,134,18,171,125,206,27,19,249,247,191,
1120 255,253,55,46,77,152,48,65,176,103,155,109,182,217,118,219,109,33,208,228,
1121 201,147,183,223,126,251,29,118,216,97,71,167,166,78,157,58,109,218,52,160,
1122 181,255,254,251,31,121,228,145,127,248,195,31,174,184,226,138,123,239,189,
1123 119,214,172,89,81,81,81,35,186,163,114,201,146,37,87,95,125,245,62,251,
1124 236,35,247,237,131,56,188,67,14,57,228,134,27,110,88,186,116,169,247,125,
1125 149,150,150,254,238,119,191,147,217,60,151,107,251,237,119,220,110,242,
1126 80,216,126,135,157,118,156,186,203,212,105,187,239,190,247,65,7,28,124,
1127 244,145,199,157,117,218,185,127,251,235,117,247,63,246,216,227,95,124,241,
1128 197,234,213,171,37,208,214,174,93,16,229,24,54,172,88,159,38,83,187,180,
1129 124,99,181,33,141,8,95,173,104,222,122,155,109,229,81,14,167,51,47,188,
1130 78,203,120,237,237,207,78,156,184,181,92,49,156,106,107,107,101,189,56,
1131 69,237,201,21,91,44,188,100,177,205,151,95,126,89,70,13,167,189,246,218,
1132 43,49,49,81,228,66,116,39,185,98,56,157,124,242,201,50,143,117,212,82,247,
1133 235,52,151,80,18,237,232,30,171,179,23,74,190,75,129,208,122,26,232,119,
1134 20,69,15,13,146,220,159,28,157,109,50,210,50,50,128,208,111,129,150,93,
1135 119,221,245,226,139,47,198,200,202,77,123,22,126,228,29,119,220,177,243,
1136 206,59,195,39,153,127,36,34,215,78,59,237,116,235,173,183,226,217,200,45,
1137 154,100,0,161,127,98,71,148,11,75,125,225,133,23,126,244,209,71,240,108,
1138 197,134,18,13,69,94,194,47,27,140,30,225,226,200,54,67,26,17,70,6,194,139,
1139 174,215,50,142,8,132,184,107,178,94,156,10,82,16,158,114,202,41,50,143,
1140 117,52,56,232,40,142,255,21,132,53,121,234,38,0,43,72,129,208,146,106,44,
1141 117,228,44,114,52,215,200,69,43,105,180,64,168,9,151,235,182,219,110,43,
1142 42,42,146,59,48,169,176,176,240,220,115,207,149,169,183,76,71,31,125,244,
1143 134,13,27,220,222,142,59,42,32,212,11,159,24,199,183,162,162,66,238,192,
1144 171,122,122,123,177,245,226,226,226,250,245,235,11,10,10,250,251,221,159,
1145 9,104,110,110,198,67,149,251,24,78,184,194,50,155,195,241,236,179,207,110,
1146 189,117,80,130,112,239,189,247,78,74,250,245,249,72,223,65,120,234,169,
1147 167,202,60,150,82,107,205,208,201,30,40,88,180,193,209,167,238,111,178,
1148 132,20,8,173,168,129,238,206,182,236,245,131,61,62,127,174,47,128,26,117,
1149 16,34,28,169,51,207,60,211,96,124,133,160,224,31,254,240,7,153,110,52,116,
1150 212,81,71,165,167,167,203,173,235,52,234,32,68,120,135,56,178,114,7,195,
1151 137,138,197,241,141,140,140,172,173,173,245,242,228,140,2,161,239,32,164,
1152 231,200,60,150,82,127,175,163,56,194,145,189,208,209,80,108,181,11,31,97,
1153 43,5,66,43,170,187,187,187,40,53,102,208,146,207,17,142,5,8,17,44,124,232,
1154 161,135,12,0,24,28,28,124,240,193,7,183,218,106,43,153,104,52,196,142,174,
1155 186,234,42,51,105,198,2,132,8,246,124,242,201,39,190,60,68,65,154,206,206,
1156 206,152,216,24,142,205,75,250,17,129,240,198,27,111,148,217,130,28,132,
1157 201,201,201,34,23,242,29,132,167,157,118,154,204,99,53,53,148,15,221,44,
1158 211,209,34,23,149,198,91,10,132,86,148,149,31,168,31,35,16,162,157,119,
1159 222,121,229,202,149,114,55,78,165,165,165,237,191,255,254,114,245,168,106,
1160 209,162,69,114,31,46,141,17,8,209,17,71,28,225,229,196,47,2,123,37,117,
1161 37,89,101,89,105,197,105,43,147,86,102,150,101,242,187,161,197,253,243,
1162 248,35,2,225,77,55,221,36,179,133,37,8,79,63,253,116,153,199,106,82,143,
1163 79,88,76,10,132,86,84,120,130,16,207,239,241,199,31,215,158,10,7,15,111,
1164 189,245,214,196,137,19,229,234,81,213,223,254,246,55,177,23,77,99,7,66,
1165 184,181,112,225,66,47,78,94,255,64,127,68,126,132,225,173,161,197,213,197,
1166 114,245,230,26,17,8,111,190,249,102,153,45,44,65,120,198,25,103,200,60,
1167 86,147,2,161,197,164,64,104,69,133,39,8,17,83,120,205,4,83,252,171,175,
1168 190,90,174,24,78,152,248,41,83,166,76,158,60,121,130,111,183,149,30,115,
1169 204,49,141,141,155,189,150,115,236,64,136,238,189,247,94,47,175,125,25,
1170 59,16,254,227,31,255,144,217,130,25,132,251,236,179,79,74,74,138,200,133,
1171 124,7,225,153,103,158,41,243,88,77,10,132,22,147,2,161,21,21,182,32,220,
1172 121,231,157,75,74,74,180,29,249,248,200,224,164,73,147,30,123,236,177,53,
1173 107,214,204,155,55,239,184,227,142,147,177,94,117,192,1,7,100,102,102,138,
1174 29,9,141,41,8,79,62,249,100,47,15,245,143,29,8,111,185,229,22,153,45,44,
1175 65,120,214,89,103,201,60,86,147,2,161,197,164,64,104,69,133,18,8,191,255,
1176 254,251,185,115,231,222,116,211,77,190,248,106,164,73,72,72,16,59,170,174,
1177 174,246,209,189,187,241,198,27,197,155,71,6,7,7,223,126,251,237,237,182,
1178 219,78,174,240,172,221,119,223,61,50,50,82,236,72,104,68,32,60,251,236,
1179 179,23,46,92,200,190,46,189,244,82,25,229,85,187,238,186,171,151,71,24,
1180 199,14,132,183,222,122,171,204,22,228,32,76,77,77,21,185,144,239,32,164,
1181 153,100,30,171,73,129,208,98,82,32,180,162,66,6,132,7,29,116,16,158,16,
1182 124,162,44,159,125,246,217,14,59,236,32,87,120,214,130,5,11,196,142,162,
1183 163,163,101,212,112,90,190,124,185,200,130,86,172,88,177,203,46,187,200,
1184 21,158,53,117,234,84,125,46,52,34,16,82,3,20,10,245,247,247,191,246,218,
1185 107,190,92,200,172,169,241,248,84,104,40,129,144,185,11,160,2,93,158,164,
1186 77,116,2,0,194,115,206,57,71,230,177,154,20,8,45,38,5,66,43,42,100,64,120,
1187 240,193,7,119,118,202,167,33,27,27,27,47,188,240,66,185,194,179,62,248,
1188 224,3,145,126,254,252,249,50,106,56,193,48,145,5,197,196,196,224,237,201,
1189 21,158,53,121,242,100,92,58,153,199,41,63,64,40,50,102,102,102,30,112,192,
1190 1,114,133,103,185,125,120,81,136,77,13,221,53,90,145,149,82,148,178,34,
1191 97,69,102,121,38,191,235,155,235,229,234,205,53,34,16,222,118,219,109,50,
1192 91,160,64,184,205,54,219,48,51,16,175,105,117,43,166,14,98,155,35,2,97,
1193 90,90,154,200,133,124,7,225,185,231,158,43,243,88,77,10,132,22,147,2,161,
1194 21,21,146,32,164,80,216,101,185,194,179,94,125,245,85,145,254,227,143,63,
1195 150,81,94,133,55,214,218,218,42,178,160,216,216,216,61,246,216,67,174,243,
1196 172,73,147,38,125,255,253,247,50,143,83,126,131,176,170,170,234,132,19,
1197 78,144,43,60,107,195,134,13,34,189,91,13,121,151,131,131,120,207,49,177,
1198 49,160,66,44,202,117,155,107,68,32,188,253,246,219,101,54,135,227,185,231,
1199 158,11,0,8,57,182,175,190,250,74,102,243,170,0,128,240,188,243,206,147,
1200 121,172,38,5,66,139,73,129,208,138,10,73,16,146,241,254,251,239,151,43,
1201 60,235,249,231,159,23,233,223,124,243,77,25,53,156,244,30,161,143,32,196,
1202 113,193,227,148,121,156,242,27,132,245,245,245,190,188,251,102,197,138,
1203 21,34,189,23,117,117,117,225,209,122,111,119,191,65,72,197,6,41,8,247,221,
1204 119,95,189,63,237,59,8,207,63,255,124,153,199,106,82,32,180,152,20,8,173,
1205 168,144,4,33,197,249,215,191,254,37,87,120,150,6,66,92,67,25,53,156,22,
1206 47,94,44,178,32,31,65,8,18,190,254,250,107,153,199,41,191,65,216,216,216,
1207 120,250,233,167,203,21,158,53,46,32,212,191,224,45,12,65,120,193,5,23,200,
1208 60,86,147,2,161,197,164,64,104,69,133,12,8,15,57,228,16,191,65,232,187,
1209 71,248,223,255,254,87,100,65,209,209,209,190,92,35,68,159,125,246,153,204,
1210 227,84,72,130,240,206,59,239,148,217,28,14,155,205,22,110,32,188,240,194,
1211 11,101,30,171,73,129,208,98,82,32,180,162,20,8,209,156,57,115,100,212,112,
1212 58,242,200,35,53,195,157,153,153,121,253,245,215,95,230,131,12,175,115,
1213 179,2,8,123,123,123,135,109,119,191,65,104,183,219,131,23,132,25,25,25,
1214 50,219,72,64,120,209,69,23,201,60,86,147,2,161,197,164,64,104,69,41,16,
1215 162,245,235,215,203,168,225,52,113,226,196,123,238,185,71,187,101,6,156,
1216 244,248,32,67,245,142,8,132,87,95,125,117,80,120,132,119,221,117,151,204,
1217 22,150,32,252,227,31,255,40,243,88,77,10,132,22,147,2,161,21,21,146,32,
1218 236,239,239,31,17,8,171,170,170,124,255,238,4,44,188,247,222,123,155,154,
1219 154,252,174,52,43,128,144,186,45,77,31,230,171,35,35,2,225,221,119,223,
1220 45,179,57,28,47,188,240,66,184,129,240,226,139,47,150,121,172,38,5,66,139,
1221 73,129,208,138,10,73,16,226,168,97,151,229,10,207,210,64,8,56,127,251,219,
1222 223,202,88,223,116,234,169,167,206,155,55,143,218,19,91,24,145,252,6,97,
1223 109,109,237,201,39,159,44,87,120,150,47,32,116,244,246,56,10,86,59,154,
1224 107,229,162,59,249,13,194,23,95,124,113,155,109,182,145,43,134,83,0,64,
1225 248,202,43,175,200,60,195,201,0,66,95,94,152,32,116,201,37,151,200,60,86,
1226 147,2,161,197,164,64,104,69,133,36,8,249,113,227,141,55,202,21,158,133,
1227 227,34,210,83,252,187,238,186,75,198,250,172,169,83,167,94,117,213,85,250,
1228 143,21,248,40,191,65,88,86,86,118,236,177,199,202,21,158,181,106,213,42,
1229 145,222,155,90,202,29,57,139,28,133,107,29,253,125,50,198,164,17,129,240,
1230 158,123,238,145,217,172,7,66,223,239,10,54,128,112,215,93,119,149,43,134,
1231 211,165,151,94,42,243,88,77,10,132,22,147,2,161,21,21,146,32,108,104,104,
1232 56,247,220,115,229,10,207,154,62,125,186,72,143,22,45,90,228,187,237,214,
1233 52,97,194,132,221,118,219,237,227,143,63,102,143,114,67,62,200,111,16,166,
1234 167,167,239,183,223,126,114,133,103,105,239,216,244,40,54,88,153,230,200,
1235 94,48,20,106,179,88,150,241,155,107,68,32,188,239,190,251,100,54,135,227,
1236 165,151,94,10,0,8,39,78,156,248,143,127,252,99,150,59,189,245,214,91,250,
1237 239,50,210,208,50,207,112,50,128,144,198,149,43,134,211,101,151,93,38,243,
1238 88,77,10,132,22,147,2,161,21,21,122,32,164,44,31,125,244,209,78,59,237,
1239 36,87,120,22,230,82,236,8,85,87,87,159,120,226,137,114,197,8,133,209,191,
1240 232,162,139,150,47,95,206,1,203,205,121,149,127,32,4,75,79,61,245,148,47,
1241 215,222,180,119,108,122,212,64,223,144,47,40,64,88,176,202,209,245,235,
1242 235,114,244,178,56,8,189,104,231,157,119,214,191,94,199,111,16,250,248,
1243 120,12,186,252,242,203,101,30,171,73,129,208,98,82,32,180,162,66,6,132,
1244 144,239,233,167,159,198,28,159,125,246,217,83,166,76,145,177,94,53,111,
1245 222,60,185,39,231,139,199,102,207,158,237,135,83,168,105,143,61,246,152,
1246 49,99,134,47,44,28,17,8,15,59,236,176,255,254,247,191,184,62,199,28,115,
1247 140,47,31,187,64,222,63,82,63,164,230,26,73,65,17,202,113,10,221,104,68,
1248 32,188,255,254,251,101,54,231,205,41,150,2,225,107,175,189,38,87,12,39,
1249 3,8,125,121,97,130,208,159,254,244,39,153,199,106,82,32,180,152,20,8,173,
1250 168,144,1,161,31,90,179,102,141,220,147,83,56,148,87,94,121,165,143,223,
1251 99,242,164,107,174,185,38,63,63,95,123,221,179,91,141,8,132,35,213,164,
1252 73,147,244,47,68,117,175,226,13,142,194,53,61,185,43,218,50,151,59,106,
1253 75,134,66,175,155,111,249,142,8,132,15,60,240,128,204,230,188,57,197,82,
1254 32,100,130,34,87,12,39,3,8,247,220,115,79,185,98,56,93,113,197,21,50,143,
1255 213,164,64,104,49,41,16,142,191,240,123,42,42,42,228,203,249,157,74,79,
1256 79,223,184,113,99,102,102,166,92,118,170,113,243,47,170,143,151,198,20,
1257 132,120,141,16,75,238,201,37,16,117,206,57,231,200,20,126,9,142,30,126,
1258 248,225,223,124,243,141,118,97,207,172,49,5,225,177,199,30,235,229,195,
1259 188,82,112,186,191,175,182,182,54,38,38,70,198,184,211,136,64,248,224,131,
1260 15,202,108,206,155,83,44,5,194,153,51,103,202,21,195,201,111,16,50,133,
1261 146,121,172,38,5,66,139,73,129,208,18,170,169,169,193,70,172,245,42,96,
1262 41,83,143,171,198,20,132,199,29,119,92,117,117,181,220,147,75,208,43,53,
1263 53,21,146,109,161,95,184,253,246,219,191,247,222,123,158,88,56,166,32,188,
1264 233,166,155,240,242,229,158,188,170,169,169,41,54,54,86,46,184,147,2,225,
1265 94,123,237,37,87,12,167,63,255,249,207,50,207,184,139,94,167,15,237,77,
1266 67,32,52,68,18,148,198,73,10,132,150,16,116,73,76,76,148,196,115,167,236,
1267 236,108,239,103,246,2,166,177,3,33,156,195,112,139,111,205,155,85,82,82,
1268 114,247,221,119,251,114,187,141,23,237,176,195,14,239,190,251,110,79,143,
1269 155,83,142,99,7,66,240,243,229,151,95,138,19,221,56,124,81,81,81,145,158,
1270 245,203,47,191,124,252,241,199,114,193,37,124,196,150,150,22,113,156,35,
1271 2,225,191,254,245,47,145,11,77,159,62,221,82,32,124,227,141,55,228,138,
1272 225,100,0,225,222,123,239,45,87,12,167,191,252,229,47,50,207,248,138,145,
1273 91,18,189,217,5,96,183,161,44,78,166,87,10,184,20,8,173,34,12,156,132,158,
1274 73,17,17,17,13,13,13,94,78,235,5,82,99,7,194,93,118,217,133,194,202,221,
1275 184,19,0,251,226,139,47,246,217,103,31,153,193,47,77,155,54,109,206,156,
1276 57,114,139,58,141,29,8,143,58,234,40,54,46,246,178,98,197,138,221,119,223,
1277 157,146,122,18,180,152,58,117,170,92,112,233,176,195,14,211,110,58,29,17,
1278 8,31,122,232,33,145,11,89,13,132,179,102,205,146,43,134,147,1,132,190,119,
1279 128,171,174,186,74,230,25,119,181,183,56,178,23,26,201,103,8,125,110,230,
1280 103,74,129,145,2,161,133,148,153,153,41,200,103,80,108,108,172,39,63,41,
1281 240,26,35,16,98,220,159,121,230,153,97,239,15,34,65,97,97,225,101,151,93,
1282 230,187,77,55,139,125,197,197,25,103,223,99,4,194,201,147,39,207,155,55,
1283 79,155,196,0,66,223,223,115,166,9,118,198,199,199,139,45,140,8,132,15,63,
1284 252,176,200,133,94,123,237,53,75,129,112,246,236,217,114,197,112,10,5,16,
1285 162,178,116,35,249,244,161,174,64,38,83,26,15,41,16,90,72,141,141,141,27,
1286 55,110,148,244,211,105,68,15,134,143,181,198,2,132,123,238,185,231,171,
1287 175,190,234,251,93,178,173,173,173,47,190,248,226,72,95,192,166,215,223,
1288 254,246,183,246,246,118,185,57,167,70,29,132,19,38,76,192,23,196,133,149,
1289 59,112,106,203,65,216,210,210,226,31,8,95,127,253,245,208,0,33,139,114,
1290 197,112,178,22,8,59,155,29,185,203,140,252,19,97,211,10,71,207,112,247,
1291 82,41,141,165,20,8,45,36,24,147,156,156,44,233,231,82,126,126,62,241,50,
1292 133,5,52,186,32,156,52,105,210,117,215,93,23,29,29,221,219,219,43,119,224,
1293 155,72,191,105,211,166,107,174,185,198,191,59,104,118,221,117,87,189,81,
1294 70,163,11,194,93,118,217,229,241,199,31,231,8,13,116,223,114,16,50,9,8,
1295 13,16,190,245,214,91,114,197,112,50,128,208,151,247,248,8,89,11,132,3,253,
1296 142,178,120,35,2,69,168,74,85,119,202,140,175,20,8,173,165,154,154,154,
1297 245,235,215,75,6,174,93,139,225,168,172,172,148,235,172,161,17,129,16,203,
1298 59,205,41,192,179,219,110,187,237,177,199,30,123,239,189,247,254,251,239,
1299 127,232,161,135,94,122,233,165,211,167,79,47,43,43,219,146,155,128,218,
1300 218,218,94,121,229,21,223,239,167,215,235,157,119,222,209,83,106,68,32,
1301 4,69,20,10,218,137,114,113,0,251,236,179,207,129,7,30,120,248,225,135,95,
1302 127,253,245,159,126,250,41,126,155,91,7,119,203,65,72,145,253,3,225,140,
1303 25,51,2,0,66,118,49,107,214,172,34,15,210,63,67,242,246,219,111,203,60,
1304 195,201,0,66,250,143,92,49,156,172,5,66,212,82,239,200,253,201,72,65,98,
1305 186,54,59,57,161,20,120,41,16,90,75,80,33,53,53,85,98,112,237,218,244,244,
1306 116,75,185,131,104,68,32,60,228,144,67,126,249,229,23,10,2,209,163,162,
1307 162,146,146,146,178,178,178,202,203,203,71,247,146,103,100,100,36,88,245,
1308 221,202,11,225,137,234,237,242,136,64,120,206,57,231,172,94,189,154,114,
1309 109,220,184,49,38,38,38,37,37,37,39,39,167,186,186,122,216,198,10,121,16,
1310 114,108,62,190,116,219,111,16,30,112,192,1,114,197,112,178,28,8,113,10,
1311 75,19,140,32,172,76,149,107,149,198,79,10,132,150,19,206,132,19,130,67,
1312 70,182,169,169,201,34,55,139,106,26,41,8,181,151,110,143,157,168,162,198,
1313 198,198,7,31,124,208,247,239,23,34,188,55,253,197,215,17,129,80,255,210,
1314 237,17,105,28,65,56,115,230,76,5,194,241,87,103,155,17,132,234,102,81,11,
1315 72,129,208,114,194,194,138,219,71,19,18,18,2,64,145,145,42,96,32,28,24,
1316 24,248,194,55,225,55,139,44,175,188,242,202,212,169,83,229,190,135,211,
1317 118,219,109,167,127,71,129,149,65,184,219,110,187,225,79,139,45,40,16,30,
1318 120,224,129,114,197,112,178,34,8,81,121,198,175,20,172,43,80,87,7,173,32,
1319 5,66,43,10,79,5,119,208,96,140,44,162,128,129,144,29,249,232,225,189,248,
1320 226,139,34,75,79,79,207,11,47,188,224,227,91,176,145,254,189,166,86,6,225,
1321 46,187,236,50,111,222,60,241,206,29,191,65,248,198,27,111,132,6,8,15,58,
1322 232,32,185,98,56,89,20,132,29,205,142,188,95,134,40,184,105,165,163,71,
1323 93,29,180,132,20,8,173,40,24,80,91,91,235,251,227,4,129,84,32,65,56,121,
1324 242,100,185,33,175,154,174,251,132,97,101,101,165,239,167,206,222,123,239,
1325 61,153,45,80,32,220,180,105,211,243,207,63,255,228,147,79,222,126,251,237,
1326 80,234,89,223,4,221,33,65,116,116,52,189,130,250,244,15,132,111,190,249,
1327 166,239,25,3,0,194,247,223,127,95,230,25,78,6,16,30,124,240,193,114,197,
1328 112,178,40,8,135,174,20,58,95,52,83,30,235,240,240,213,73,165,0,75,129,
1329 208,162,26,233,227,4,1,83,32,65,184,243,206,59,203,13,121,21,190,142,204,
1330 227,212,157,119,222,41,87,12,167,151,94,122,73,230,9,20,8,81,119,119,119,
1331 90,90,90,73,73,137,92,246,89,212,100,74,74,10,136,154,52,105,146,60,142,
1332 225,164,7,225,172,89,179,44,5,194,207,63,255,92,230,25,78,6,16,210,169,
1333 228,138,225,100,81,16,162,150,58,117,179,168,165,164,64,168,52,50,5,18,
1334 132,62,62,23,129,137,151,121,156,154,51,103,142,143,15,23,62,254,248,227,
1335 50,79,0,65,8,204,202,203,203,253,115,247,219,218,218,146,146,146,124,63,
1336 247,171,7,225,236,217,179,45,5,66,146,201,60,195,201,0,194,67,15,61,84,
1337 174,24,78,214,5,225,224,128,163,185,92,254,86,178,128,20,8,149,70,166,64,
1338 130,208,199,71,167,13,32,92,187,118,173,143,32,212,127,192,61,48,32,108,
1339 104,104,136,141,141,29,254,147,76,158,85,86,86,22,0,16,54,53,53,201,108,
1340 78,141,5,8,231,205,155,39,243,12,39,3,8,15,59,236,48,185,98,56,209,81,101,
1341 30,37,37,175,82,32,84,26,153,2,9,66,31,175,6,25,64,24,23,23,231,35,8,111,
1342 191,253,118,153,39,32,32,236,239,239,143,143,143,111,110,110,150,203,126,
1343 169,183,183,119,151,93,118,145,199,49,156,244,32,244,253,57,66,106,207,
1344 128,234,177,0,225,194,133,11,101,158,225,100,0,161,239,15,212,223,120,227,
1345 141,50,143,146,146,87,41,16,42,141,76,1,3,33,216,56,238,184,227,228,134,
1346 188,202,0,194,180,180,52,31,65,168,255,74,81,0,64,88,83,83,99,126,233,154,
1347 31,242,253,110,17,61,8,95,124,241,69,31,65,56,121,242,100,195,215,19,199,
1348 2,132,171,87,175,150,121,134,147,1,132,187,237,182,155,92,49,156,238,190,
1349 251,110,153,71,73,201,171,20,8,149,70,166,64,130,240,130,11,46,144,27,242,
1350 42,195,205,50,235,214,173,243,17,132,79,63,253,180,204,51,246,32,36,125,
1351 81,81,81,109,109,173,92,222,2,157,112,194,9,242,56,134,147,254,195,188,
1352 207,60,243,140,143,79,110,28,112,192,1,134,79,54,142,5,8,113,142,101,158,
1353 225,4,8,181,71,69,33,244,180,105,211,228,138,225,244,223,255,254,87,228,
1354 82,82,242,46,5,66,165,145,41,96,32,196,115,186,241,198,27,229,134,188,234,
1355 201,39,159,148,121,156,154,59,119,174,143,32,156,61,123,182,204,19,16,16,
1356 230,230,230,106,223,215,221,18,93,118,217,101,242,56,134,211,205,55,223,
1357 44,243,56,28,184,191,19,39,78,148,43,188,234,180,211,78,51,220,180,60,22,
1358 32,44,40,40,240,209,67,221,115,207,61,181,207,102,49,147,240,253,227,204,
1359 31,125,244,145,200,165,164,228,93,10,132,74,35,83,192,64,8,57,158,123,238,
1360 57,185,33,175,186,252,242,203,101,30,167,174,188,242,74,185,98,56,45,88,
1361 176,64,230,25,123,16,194,245,252,252,124,191,107,67,175,71,30,121,68,30,
1362 199,112,58,239,188,243,68,22,246,126,213,85,87,201,216,225,116,237,181,
1363 215,210,202,34,163,208,88,128,176,186,186,26,87,79,102,243,42,92,192,149,
1364 43,87,138,92,137,137,137,59,238,184,163,92,49,156,86,173,90,37,114,41,41,
1365 121,151,2,161,210,200,20,48,16,162,249,243,231,251,242,114,25,44,227,178,
1366 101,203,234,234,234,106,106,106,190,248,226,11,31,61,6,220,163,228,228,
1367 100,185,167,177,7,33,245,150,146,146,50,42,143,135,126,249,229,151,242,
1368 56,134,211,62,251,236,179,110,221,186,202,202,202,168,168,40,223,111,182,
1369 124,233,165,151,12,23,50,199,2,132,141,141,141,103,156,113,134,204,230,
1370 85,180,20,78,127,69,69,5,236,124,226,137,39,124,244,35,39,77,154,68,127,
1371 144,59,83,82,242,42,5,66,165,145,41,144,32,140,139,139,219,99,143,61,228,
1372 182,188,106,215,93,119,61,243,204,51,79,59,237,52,223,47,32,5,248,165,219,
1373 253,253,253,217,217,217,134,155,80,252,83,97,97,161,239,95,158,58,224,128,
1374 3,78,62,249,100,223,95,75,54,117,234,212,141,27,55,202,61,185,52,22,32,
1375 100,78,240,239,127,255,91,102,27,78,83,166,76,57,229,148,83,254,240,135,
1376 63,248,238,14,94,126,249,229,150,125,43,133,146,213,164,64,168,52,50,5,
1377 18,132,56,1,199,31,127,188,220,214,104,107,75,62,195,228,247,169,209,81,
1378 249,254,84,91,91,219,95,255,250,87,121,40,163,45,96,99,254,4,230,88,128,
1379 16,177,89,223,39,46,35,21,135,49,210,54,82,10,91,41,16,42,141,76,129,4,
1380 33,122,226,137,39,124,188,197,99,68,218,102,155,109,230,206,157,171,55,
1381 148,1,0,97,70,70,198,168,220,44,131,115,249,225,135,31,238,176,195,14,242,
1382 104,70,79,84,139,254,253,171,154,198,8,132,16,253,226,139,47,150,57,71,
1383 85,103,156,113,134,213,190,104,173,100,101,41,16,42,141,76,1,6,97,77,77,
1384 205,201,39,159,44,55,55,122,58,246,216,99,245,223,96,66,99,13,66,210,23,
1385 23,23,215,215,215,203,229,45,16,32,204,201,201,185,239,190,251,124,188,
1386 57,214,119,93,121,229,149,110,81,61,70,32,68,84,251,17,71,28,33,51,143,
1387 146,192,249,252,249,243,149,59,168,228,187,20,8,149,70,166,0,131,16,37,
1388 39,39,251,126,73,204,23,77,158,60,121,193,130,5,6,67,57,214,32,68,85,85,
1389 85,153,153,153,91,110,160,169,210,172,172,44,254,254,229,47,127,25,209,
1390 183,136,189,8,166,158,122,234,169,158,238,46,25,59,16,162,85,171,86,249,
1391 254,174,156,97,197,1,60,245,212,83,204,21,228,214,149,148,124,144,2,161,
1392 210,200,20,120,16,98,212,190,255,254,251,195,15,63,92,110,116,203,116,208,
1393 65,7,125,251,237,183,114,211,58,5,0,132,189,189,189,113,113,113,94,156,
1394 194,129,129,1,170,183,171,171,139,191,94,182,159,155,155,43,190,77,200,
1395 223,107,174,185,198,143,15,28,154,117,210,73,39,1,105,177,125,179,198,20,
1396 132,61,61,61,31,125,244,145,239,183,243,120,209,14,59,236,96,183,219,13,
1397 111,3,80,82,26,86,10,132,74,35,83,224,65,136,196,201,64,28,32,185,93,127,
1398 117,238,185,231,70,69,69,185,117,23,2,0,66,132,83,152,144,144,64,29,202,
1399 101,167,88,172,172,172,76,74,74,98,21,164,140,141,141,229,47,191,43,42,
1400 42,26,27,27,13,79,50,180,182,182,198,196,196,104,145,96,245,173,183,222,
1401 218,66,143,249,236,179,207,78,79,79,247,82,162,49,5,33,162,6,160,187,239,
1402 79,58,122,210,243,207,63,191,37,47,52,87,10,91,41,16,42,141,76,227,2,66,
1403 161,246,246,246,89,179,102,225,26,142,244,62,17,210,31,121,228,145,239,
1404 190,251,46,190,130,39,115,31,24,16,162,194,194,194,154,154,26,178,163,238,
1405 238,110,16,24,25,25,9,6,138,139,139,155,155,155,177,227,112,154,31,16,46,
1406 63,63,63,58,58,58,43,43,171,174,174,78,192,27,103,177,168,168,8,58,138,
1407 77,9,1,69,242,226,26,238,177,199,30,62,62,99,39,68,226,131,15,62,120,246,
1408 236,217,195,194,99,172,65,40,68,251,226,26,30,118,216,97,59,238,184,227,
1409 136,46,127,146,254,138,43,174,72,73,73,49,76,26,148,148,124,148,2,161,210,
1410 200,132,173,153,63,127,254,115,190,9,110,141,250,179,92,181,181,181,255,
1411 251,223,255,30,124,240,193,211,79,63,125,202,148,41,210,22,186,19,107,73,
1412 115,223,125,247,125,251,237,183,184,98,50,191,7,181,180,180,188,253,246,
1413 219,242,184,135,211,55,223,124,35,179,141,92,80,39,53,53,181,186,186,154,
1414 67,194,118,231,229,229,177,107,79,88,133,220,16,58,51,51,83,220,113,202,
1415 15,79,55,67,178,133,248,248,248,215,94,123,13,36,28,116,208,65,94,174,29,
1416 178,234,232,163,143,190,229,150,91,40,47,148,149,249,189,10,36,203,146,
1417 15,39,187,221,158,150,150,38,179,249,165,134,134,134,31,127,252,241,222,
1418 123,239,253,195,31,254,48,117,234,84,121,208,238,52,109,218,180,139,46,
1419 186,232,177,199,30,251,225,135,31,70,229,118,92,165,176,149,2,161,210,136,
1420 229,116,102,124,149,204,51,218,194,151,130,136,24,232,21,43,86,188,249,
1421 230,155,79,61,245,212,191,254,245,175,59,238,184,227,161,135,30,122,250,
1422 233,167,49,241,235,214,173,219,180,105,19,105,124,127,116,79,30,177,111,
1423 146,121,252,82,83,83,83,76,76,76,66,66,2,80,244,197,137,97,50,129,207,23,
1424 21,21,5,183,188,239,26,199,145,141,195,78,182,63,119,238,220,103,158,121,
1425 230,158,123,238,185,225,134,27,110,188,241,198,71,31,125,116,198,140,25,
1426 184,107,73,73,73,21,21,21,184,95,35,42,133,179,208,62,73,102,216,50,117,
1427 118,118,226,55,83,222,37,75,150,188,241,198,27,15,63,252,240,237,183,223,
1428 126,221,117,215,81,28,112,251,254,251,239,47,90,180,168,160,160,0,106,26,
1429 206,51,43,41,249,33,5,66,165,80,144,180,193,46,201,88,75,138,195,195,171,
1430 131,130,128,13,63,175,185,185,217,237,53,75,77,24,122,112,30,23,23,87,84,
1431 84,132,179,53,162,107,96,162,54,52,201,216,32,148,44,128,75,50,86,73,105,
1432 148,164,64,168,164,20,80,181,181,181,101,102,102,226,167,226,147,193,182,
1433 13,27,54,128,55,80,103,184,215,17,47,16,175,168,176,176,48,37,37,5,94,214,
1434 215,215,3,0,254,146,88,221,21,169,164,52,186,82,32,84,82,10,156,240,255,
1435 240,237,90,91,91,197,34,108,19,87,1,137,140,136,136,16,119,205,0,63,104,
1436 199,34,130,130,141,141,141,154,203,72,250,146,146,18,210,139,69,37,37,165,
1437 81,145,2,161,146,82,128,52,48,48,80,94,94,238,233,94,146,238,238,110,48,
1438 89,85,85,85,81,81,129,131,136,59,232,214,243,35,50,49,49,113,84,222,89,
1439 170,164,164,36,164,64,168,164,20,32,225,8,70,69,69,109,249,7,40,106,106,
1440 106,138,139,139,213,165,50,37,165,209,146,2,161,146,82,32,4,183,160,215,
1441 168,0,172,183,183,55,47,47,79,93,41,84,82,26,45,41,16,42,41,5,66,240,47,
1442 55,55,215,203,251,213,124,87,127,127,127,90,90,154,118,161,81,73,73,105,
1443 11,165,64,168,164,20,8,1,194,210,210,210,81,121,207,14,155,194,35,212,127,
1444 85,88,73,73,105,75,164,64,168,164,20,8,225,198,21,21,21,141,214,123,118,
1445 216,84,93,93,157,92,80,82,82,218,50,41,16,42,41,5,66,125,125,125,41,41,
1446 41,163,8,194,178,178,50,185,160,164,164,180,101,82,32,84,82,10,132,240,
1447 8,115,115,115,183,252,150,81,33,5,66,37,165,81,148,2,161,146,82,32,52,48,
1448 48,144,159,159,63,42,215,8,217,20,76,53,124,131,66,73,73,201,111,41,16,
1449 42,41,5,66,131,131,131,5,5,5,163,117,215,104,70,70,198,136,94,58,170,164,
1450 164,228,69,10,132,74,74,129,16,32,44,46,46,30,149,183,163,117,117,117,101,
1451 102,102,170,175,46,40,41,141,150,20,8,149,148,2,164,182,182,182,232,232,
1452 232,45,127,16,30,207,18,249,242,253,38,37,37,37,95,164,64,168,164,20,32,
1453 225,20,110,218,180,41,61,61,93,46,251,165,246,246,246,168,168,40,117,94,
1454 84,73,105,20,165,64,168,164,20,56,117,118,118,198,198,198,226,26,202,229,
1455 17,10,148,166,164,164,212,214,214,242,67,70,41,41,41,109,177,20,8,149,148,
1456 2,42,241,61,66,63,94,144,6,252,202,203,203,11,10,10,212,91,70,149,148,70,
1457 87,10,132,74,74,1,21,60,107,104,104,72,72,72,24,41,11,203,202,202,112,7,
1458 213,73,81,37,165,81,151,2,161,146,210,152,11,248,245,247,247,247,246,246,
1459 106,119,184,52,54,54,194,194,230,230,102,226,69,140,39,145,183,171,171,
1460 75,124,188,215,239,115,170,74,74,74,94,164,64,168,164,52,230,106,106,106,
1461 202,204,204,76,76,76,204,206,206,214,92,58,88,152,145,145,65,124,69,69,
1462 133,91,28,130,64,188,198,77,155,54,37,39,39,87,86,86,142,214,235,217,148,
1463 148,148,12,82,32,84,82,26,91,1,176,148,148,148,181,46,149,148,148,136,120,
1464 225,38,66,184,252,252,252,152,152,152,248,248,120,126,55,52,52,64,202,170,
1465 170,42,146,197,198,198,70,70,70,22,23,23,227,17,146,88,228,82,82,82,26,
1466 117,41,16,42,41,141,173,122,122,122,18,18,18,36,6,215,174,45,42,42,146,
1467 43,92,26,24,24,104,110,110,6,129,185,185,185,16,113,253,250,245,56,142,
1468 165,165,165,248,145,234,169,121,37,165,0,72,129,80,73,105,108,37,222,50,
1469 186,110,221,58,40,8,17,189,127,71,16,248,225,8,202,5,37,37,165,128,72,129,
1470 80,73,105,204,37,78,129,22,20,20,224,249,121,63,201,169,64,168,164,20,120,
1471 41,16,42,41,89,72,10,132,74,110,85,92,92,76,199,136,113,41,45,45,109,216,
1472 251,141,149,124,151,2,161,82,56,42,58,58,250,243,207,63,159,49,99,198,139,
1473 47,190,248,241,199,31,47,90,180,168,186,186,90,174,27,87,41,16,42,153,149,
1474 157,157,125,198,25,103,76,157,58,117,138,75,123,239,189,247,71,31,125,36,
1475 87,43,109,177,198,13,132,221,221,221,211,166,77,219,201,165,157,119,222,
1476 121,247,221,119,223,103,159,125,14,62,248,224,99,143,61,246,204,51,207,
1477 252,231,63,255,137,133,42,43,43,211,38,62,252,120,254,249,231,101,6,157,
1478 254,241,143,127,136,4,150,82,79,79,207,198,141,27,239,189,247,222,63,252,
1479 225,15,135,31,126,248,126,251,237,39,142,182,182,182,86,166,80,114,170,
1480 190,190,126,223,125,247,21,149,163,233,176,195,14,243,126,45,205,63,181,
1481 180,180,204,156,57,147,62,182,195,14,59,76,154,52,105,27,167,248,49,121,
1482 242,100,44,203,237,183,223,158,153,153,169,159,104,115,12,242,128,116,250,
1483 237,111,127,59,42,31,145,112,43,5,66,79,58,250,232,163,101,3,184,180,199,
1484 30,123,124,250,233,167,114,245,40,233,164,147,78,146,91,119,106,215,93,
1485 119,165,99,28,112,192,1,71,29,117,212,105,167,157,118,253,245,215,211,127,
1486 242,243,243,3,249,114,159,230,230,230,191,255,253,239,19,38,76,248,205,
1487 230,218,126,251,237,127,252,241,199,241,186,157,184,174,174,238,143,127,
1488 252,163,172,38,157,222,125,247,93,153,34,168,52,110,32,236,234,234,218,
1489 106,171,173,100,147,122,214,254,251,239,255,244,211,79,87,86,86,146,5,11,
1490 245,228,147,79,202,21,58,209,75,196,54,253,16,219,172,169,169,1,183,6,109,
1491 97,247,162,116,15,63,252,48,230,85,30,162,78,236,78,38,82,114,138,17,101,
1492 174,40,108,220,168,124,186,79,47,236,215,165,151,94,42,119,224,65,59,238,
1493 184,227,91,111,189,69,243,137,44,28,131,92,161,211,94,123,237,165,61,2,
1494 49,82,185,237,108,250,185,145,2,161,39,97,10,100,3,184,196,12,230,131,15,
1495 62,144,171,71,73,204,114,228,214,61,107,151,93,118,185,245,214,91,243,242,
1496 242,100,30,191,132,133,145,205,191,185,12,247,9,51,58,112,9,228,142,127,
1497 243,27,144,204,196,90,46,252,230,55,135,28,114,72,66,66,194,184,176,144,
1498 78,139,147,42,143,67,167,55,222,120,67,166,8,42,89,29,132,136,169,16,221,
1499 174,179,179,115,44,64,136,165,187,246,218,107,153,238,25,36,208,235,183,
1500 150,44,89,194,40,149,199,183,185,20,8,13,98,68,109,189,245,214,178,118,
1501 92,26,117,16,86,87,87,95,112,193,5,230,105,181,89,83,167,78,157,59,119,
1502 174,200,53,234,32,196,165,144,61,76,167,23,95,124,81,174,86,32,244,44,235,
1503 128,16,209,145,46,191,252,242,45,57,187,131,79,41,155,95,39,124,44,253,
1504 54,91,90,90,174,187,238,58,205,78,238,188,243,206,223,127,255,61,166,233,
1505 146,75,46,17,49,232,176,195,14,107,111,111,151,25,2,40,5,194,209,145,239,
1506 32,68,140,1,113,113,120,212,65,136,125,60,229,148,83,228,134,116,42,46,
1507 46,150,41,252,210,244,233,211,39,78,156,40,183,229,20,179,200,227,142,59,
1508 238,152,99,142,25,117,71,39,216,197,204,64,214,145,78,163,14,194,165,75,
1509 151,238,180,211,78,114,235,195,233,172,179,206,18,179,236,198,198,70,230,
1510 224,6,157,124,242,201,229,229,229,98,179,35,149,126,58,175,233,223,255,
1511 254,183,92,173,64,232,89,150,2,33,218,113,199,29,55,108,216,32,179,141,
1512 92,221,221,221,114,67,58,29,122,232,161,85,85,85,34,1,61,240,211,79,63,
1513 61,232,160,131,14,60,240,64,104,119,194,9,39,204,154,53,75,188,162,111,
1514 211,166,77,87,92,113,5,198,132,85,8,124,138,44,129,20,195,243,175,127,253,
1515 171,28,18,58,205,153,51,71,166,8,42,89,11,132,204,179,68,211,202,101,151,
1516 182,217,102,27,12,89,95,95,159,239,32,108,110,110,78,79,79,95,191,126,253,
1517 34,167,86,173,90,149,151,151,103,254,150,233,72,65,88,88,88,24,23,23,183,
1518 108,217,178,5,11,22,252,252,243,207,9,9,9,110,237,245,99,143,61,102,40,
1519 29,137,229,58,147,196,253,96,36,192,143,228,128,221,30,39,106,109,109,197,
1520 74,26,132,163,204,170,222,222,222,152,152,152,200,200,72,50,186,77,38,182,
1521 80,86,86,182,102,205,154,159,126,250,137,221,49,14,69,164,16,229,90,190,
1522 124,57,229,74,77,77,53,172,210,139,29,101,101,101,109,220,184,113,241,226,
1523 197,162,86,51,51,51,181,19,137,190,136,196,28,42,133,101,95,217,217,217,
1524 180,169,239,32,164,116,184,98,81,81,81,20,225,151,95,126,161,20,44,186,
1525 173,43,131,72,131,215,37,55,173,211,249,231,159,255,248,227,143,155,45,
1526 236,182,219,110,203,100,92,228,109,115,39,243,78,169,91,170,133,3,163,99,
1527 80,147,116,12,183,239,212,30,17,8,217,81,124,124,252,138,21,43,22,46,92,
1528 24,17,17,65,205,123,122,227,182,104,101,189,68,163,48,119,36,23,117,69,
1529 109,231,231,231,235,207,161,209,202,73,73,73,52,196,234,213,171,105,8,25,
1530 235,78,117,117,117,76,67,215,174,93,203,97,208,238,235,214,173,43,42,42,
1531 242,126,58,142,54,165,153,216,47,181,193,174,105,241,17,93,241,165,155,
1532 49,120,87,174,92,73,125,82,3,162,147,251,14,66,138,79,253,211,10,28,45,
1533 245,70,233,124,127,59,157,91,16,238,187,239,190,102,163,132,152,239,82,
1534 195,50,167,75,184,74,137,137,137,162,213,24,110,84,157,219,1,50,44,8,245,
1535 162,191,49,66,197,192,161,92,252,192,104,184,237,249,212,149,232,0,122,
1536 137,131,100,85,116,116,52,134,84,180,160,72,239,86,88,197,228,228,100,234,
1537 159,49,78,175,206,205,205,117,187,47,202,37,134,131,94,114,221,230,194,
1538 139,101,131,152,11,250,3,86,142,70,25,187,171,236,254,201,90,32,196,139,
1539 162,247,100,100,100,48,37,151,81,46,189,255,254,251,61,61,61,190,128,144,
1540 89,252,59,239,188,131,197,161,251,238,190,251,238,59,59,181,235,174,187,
1541 50,144,46,190,248,98,134,189,76,231,112,48,216,72,121,200,33,135,200,13,
1542 233,132,131,255,229,151,95,210,135,100,82,231,125,134,215,95,127,61,19,
1543 180,189,246,218,11,247,14,247,98,218,180,105,252,62,234,168,163,94,122,
1544 233,37,205,66,97,217,231,207,159,127,229,149,87,26,74,55,123,246,108,226,
1545 145,118,153,29,83,130,201,251,199,63,254,33,182,201,214,56,78,14,152,227,
1546 196,64,99,62,12,157,239,254,251,239,63,252,240,195,153,27,106,250,221,239,
1547 126,247,246,219,111,83,222,59,239,188,115,207,61,247,252,207,127,254,131,
1548 57,166,140,114,181,78,28,222,140,25,51,200,190,219,110,187,137,195,190,
1549 236,178,203,68,95,164,239,2,3,198,57,133,66,251,236,179,207,45,183,220,
1550 98,54,184,140,162,185,115,231,158,122,234,169,251,237,183,31,148,210,106,
1551 149,197,115,206,57,199,199,139,246,204,160,79,63,253,116,14,149,99,96,95,
1552 228,125,232,161,135,240,174,100,29,233,100,6,33,163,247,214,91,111,165,
1553 174,180,236,148,130,69,142,150,85,50,145,7,81,231,212,158,220,180,75,59,
1554 236,176,131,24,225,127,251,219,223,204,167,76,1,60,25,233,0,88,70,131,206,
1555 60,243,204,138,138,10,177,101,68,74,166,198,7,31,124,48,199,204,129,209,
1556 49,56,182,189,247,222,251,184,227,142,123,253,245,215,53,35,200,49,124,
1557 241,197,23,88,58,185,3,157,46,185,228,18,86,9,84,12,217,173,236,13,52,141,
1558 205,102,163,107,81,70,42,153,109,178,113,170,235,236,179,207,254,236,179,
1559 207,12,29,3,255,64,54,179,78,140,20,118,253,224,131,15,146,107,168,93,119,
1560 217,133,217,58,149,32,0,207,52,241,186,235,174,227,32,57,96,186,4,105,158,
1561 121,230,25,141,253,154,48,202,175,188,242,202,241,199,31,79,175,32,25,135,
1562 33,186,40,189,133,65,7,71,101,58,157,64,224,221,119,223,77,45,209,76,236,
1563 84,212,6,191,57,36,218,218,151,43,14,84,20,253,153,193,75,193,69,95,165,
1564 194,193,137,47,32,4,66,79,61,245,212,17,71,28,65,46,246,203,209,138,122,
1565 163,215,205,155,55,207,203,12,79,19,71,46,183,174,19,123,161,171,48,168,
1566 229,178,75,119,220,113,135,30,177,24,174,71,30,121,132,38,166,98,69,171,
1567 81,105,84,29,199,207,216,209,15,16,6,194,39,159,124,34,183,162,19,71,203,
1568 136,6,255,250,43,133,152,130,171,174,186,138,58,215,122,62,63,88,188,237,
1569 182,219,152,37,200,68,78,81,192,71,31,125,84,116,0,189,56,126,26,235,140,
1570 51,206,16,91,160,5,41,38,6,65,179,69,154,176,6,88,179,35,143,60,146,195,
1571 166,8,162,2,169,121,28,80,208,174,47,44,221,21,123,56,52,30,54,215,231,
1572 159,127,46,83,56,69,79,166,107,105,27,20,93,136,109,138,145,91,80,80,32,
1573 211,141,183,44,7,66,38,146,204,95,48,205,50,202,165,153,51,103,210,204,
1574 222,65,40,208,114,226,137,39,154,183,172,105,202,148,41,140,109,49,199,
1575 124,247,221,119,61,165,196,50,98,56,152,133,145,12,210,188,252,242,203,
1576 94,182,73,98,220,74,198,42,137,41,23,189,193,108,88,137,17,18,215,8,5,87,
1577 24,39,196,200,20,155,139,248,155,110,186,137,93,147,88,136,98,202,117,46,
1578 109,189,245,214,255,247,127,255,71,31,21,27,193,4,112,192,208,81,172,213,
1579 235,217,103,159,53,31,63,21,133,187,240,240,195,15,227,112,203,40,167,216,
1580 26,36,214,59,52,240,149,189,123,58,84,196,42,140,172,91,31,72,19,19,115,
1581 72,44,51,184,68,70,179,129,67,12,21,13,132,24,133,143,63,254,152,1,236,
1582 246,0,136,220,110,187,237,152,155,123,154,141,34,122,14,163,78,102,112,
1583 9,83,34,216,131,65,49,87,14,238,53,171,56,6,185,172,19,70,86,92,35,164,
1584 173,103,205,154,53,117,234,84,185,194,36,142,237,152,99,142,193,90,209,
1585 51,105,74,183,199,143,136,71,24,154,161,99,109,170,72,93,252,206,201,39,
1586 158,232,37,49,224,164,50,53,28,66,98,185,78,39,140,148,249,154,40,197,132,
1587 250,228,61,247,220,115,101,148,75,244,1,208,171,89,58,198,32,254,28,67,
1588 192,211,97,32,218,8,107,174,101,161,153,152,59,98,100,189,28,57,67,3,63,
1589 195,173,123,33,68,23,210,250,179,94,160,197,208,75,145,30,132,212,112,92,
1590 92,28,195,208,203,222,193,9,179,46,239,51,54,142,80,102,208,233,127,255,
1591 251,31,185,64,20,61,77,70,57,197,100,66,43,62,29,6,4,122,217,251,69,23,
1592 93,148,147,147,35,246,126,195,13,55,120,73,201,20,10,47,156,100,204,71,
1593 159,123,238,57,115,193,133,72,137,1,193,140,104,227,142,14,201,196,90,174,
1594 214,233,158,123,238,49,155,5,178,235,167,17,20,132,185,254,239,127,255,
1595 123,79,7,198,97,252,191,255,247,255,180,75,152,195,94,35,132,178,223,126,
1596 251,173,167,97,139,136,103,12,254,240,195,15,102,175,58,240,178,22,8,177,
1597 236,52,6,107,237,118,187,140,114,9,20,13,11,194,188,188,60,166,63,50,214,
1598 179,182,221,118,91,236,23,233,1,161,167,70,66,24,104,184,66,95,252,215,
1599 191,254,229,169,47,234,197,188,143,97,70,185,204,230,94,47,1,66,60,81,195,
1600 160,50,139,105,193,63,255,249,79,38,239,206,194,185,7,33,229,197,28,136,
1601 197,167,159,126,218,19,8,61,9,63,70,203,174,23,77,243,230,155,111,138,253,
1602 226,112,156,118,218,105,114,133,103,81,171,180,154,151,73,183,254,230,183,
1603 97,165,7,225,87,95,125,181,227,142,59,202,21,30,52,121,242,228,39,158,120,
1604 194,147,133,165,81,110,188,241,70,153,212,165,237,183,223,94,56,118,215,
1605 92,115,141,185,27,48,43,103,149,119,16,226,156,185,189,49,216,32,236,26,
1606 237,2,8,229,178,7,13,129,176,175,55,117,217,167,135,29,176,183,140,242,
1607 32,142,22,23,71,59,135,230,22,132,248,187,134,171,212,66,244,228,67,14,
1608 57,196,109,183,167,206,181,25,122,68,68,4,236,145,43,60,139,189,204,159,
1609 63,95,100,97,82,229,118,78,99,16,182,123,205,154,53,34,139,89,179,103,207,
1610 166,35,201,164,195,73,15,66,236,6,216,150,43,60,139,65,234,253,242,191,
1611 23,16,226,235,80,94,25,229,20,100,21,78,21,30,30,189,66,198,122,16,99,10,
1612 22,138,185,23,211,20,25,235,78,199,30,123,44,32,164,51,227,180,13,219,193,
1613 72,128,85,116,30,187,71,16,226,138,201,95,155,11,183,91,123,124,118,221,
1614 186,117,190,84,224,95,254,242,23,97,145,134,5,225,194,133,11,113,94,101,
1615 172,103,225,32,46,95,190,92,100,25,71,89,20,132,47,188,240,130,140,114,
1616 137,152,97,65,232,189,123,233,133,99,78,87,243,5,132,76,226,112,231,101,
1617 148,87,49,44,151,46,93,234,11,8,139,138,138,232,235,114,217,171,48,10,204,
1618 152,196,44,210,12,66,164,175,195,103,158,121,198,19,8,169,88,236,190,92,
1619 216,92,48,198,45,230,255,250,215,191,50,83,67,56,10,230,150,114,171,163,
1620 143,62,90,27,87,102,185,53,172,12,81,183,123,215,64,88,89,89,137,147,33,
1621 99,189,138,250,95,182,108,153,216,151,65,244,156,59,238,184,67,166,211,
1622 233,195,15,63,100,45,238,242,229,38,225,15,177,202,11,8,241,233,175,190,
1623 250,106,25,165,211,62,251,236,35,127,185,68,237,225,42,185,221,148,94,67,
1624 32,108,46,253,219,31,79,247,210,39,53,177,205,199,30,123,76,116,12,183,
1625 32,68,123,238,185,167,252,101,146,167,137,157,118,94,203,124,109,194,147,
1626 78,62,249,100,113,126,5,38,153,143,28,83,43,127,233,116,243,205,55,235,
1627 79,253,105,162,56,76,74,100,34,157,24,5,83,166,76,145,11,58,105,32,228,
1628 0,216,166,47,245,198,228,0,75,162,63,197,103,144,23,16,126,241,197,23,6,
1629 16,254,249,207,127,6,132,45,45,45,84,130,140,242,42,246,254,223,255,254,
1630 151,189,248,2,66,182,140,59,37,163,188,10,222,172,95,191,158,205,122,2,
1631 33,189,197,237,240,231,120,196,132,143,233,62,80,247,165,2,105,136,5,11,
1632 22,144,101,88,16,98,13,100,212,112,186,242,202,43,221,246,135,64,202,162,
1633 32,196,248,202,40,151,134,5,33,131,193,108,49,201,197,76,220,220,185,153,
1634 134,108,220,184,113,229,202,149,255,254,247,191,221,26,232,71,30,121,4,
1635 255,134,238,136,9,147,81,46,225,132,225,122,46,94,188,216,220,111,158,123,
1636 238,57,14,131,174,64,23,49,175,61,241,196,19,95,121,229,149,182,182,182,
1637 85,171,86,153,225,138,223,147,155,155,123,160,233,154,252,5,23,92,32,28,
1638 29,183,32,212,203,19,8,169,85,140,44,131,217,108,77,166,78,157,202,100,
1639 150,25,153,217,123,184,248,226,139,25,30,8,34,202,40,151,24,204,180,133,
1640 249,170,27,18,231,135,205,162,212,28,134,76,228,18,254,104,118,118,118,
1641 70,70,134,217,46,107,32,252,244,211,79,205,46,2,245,140,159,106,54,19,76,
1642 87,197,238,12,98,152,129,13,153,72,39,218,232,189,247,222,243,114,70,215,
1643 11,8,65,190,249,206,23,14,140,146,154,189,207,255,252,231,63,236,133,191,
1644 110,193,112,234,169,167,178,42,41,49,97,83,196,162,195,15,52,246,70,97,
1645 109,49,22,134,30,69,107,138,179,193,110,65,120,217,101,151,209,243,33,189,
1646 92,214,233,156,115,206,161,151,178,71,115,163,211,63,217,32,190,166,185,
1647 206,197,21,104,243,16,195,141,96,178,72,174,59,239,188,83,70,185,4,213,
1648 128,196,235,175,191,46,151,93,186,240,194,11,245,231,252,53,113,84,244,
1649 58,153,72,167,247,223,127,159,233,227,126,251,237,39,151,93,210,64,88,94,
1650 94,126,212,81,71,201,88,151,216,59,117,126,219,109,183,201,101,151,126,
1651 255,251,223,123,105,113,47,32,156,59,119,174,1,39,52,10,77,19,23,23,103,
1652 182,33,15,63,252,48,158,19,45,43,151,93,98,224,183,183,183,127,251,237,
1653 183,79,60,241,132,140,210,9,164,145,241,205,55,223,36,47,220,149,177,46,
1654 49,90,225,22,85,97,56,153,132,33,125,252,241,199,177,18,158,64,136,149,
1655 163,200,216,31,185,236,18,25,197,92,144,206,140,167,46,99,93,98,52,145,
1656 235,186,235,174,147,203,46,221,123,239,189,236,200,59,8,49,68,134,238,74,
1657 99,125,252,241,199,249,249,249,102,36,211,34,91,248,184,218,150,203,138,
1658 32,196,200,222,125,247,221,50,202,165,97,79,141,38,37,37,153,79,160,189,
1659 244,210,75,172,50,95,31,34,37,36,99,21,61,192,237,93,163,140,249,161,163,
1660 116,56,32,162,140,114,233,204,51,207,164,19,208,114,230,139,67,247,221,
1661 119,31,7,73,46,102,124,102,16,10,51,205,136,154,61,123,182,121,45,150,189,
1662 161,161,225,236,179,207,150,203,46,209,129,196,115,66,126,131,240,152,99,
1663 142,193,177,75,73,73,49,91,49,120,195,144,131,118,102,74,225,19,112,60,
1664 77,77,77,199,29,119,156,140,114,9,191,129,82,208,173,229,178,78,158,110,
1665 142,165,198,204,187,56,225,132,19,42,42,42,216,139,217,198,105,32,4,42,
1666 230,186,18,119,18,153,125,47,28,125,183,22,22,125,243,205,55,110,39,197,
1667 147,39,79,134,52,158,110,183,241,2,194,210,210,82,195,156,151,254,140,77,
1668 36,23,46,166,225,152,177,110,194,11,113,123,146,249,255,254,239,255,134,
1669 118,214,214,240,203,199,207,238,60,117,51,159,3,209,169,88,137,45,51,115,
1670 75,92,86,116,11,66,113,162,56,53,53,213,140,180,167,158,122,138,254,64,
1671 133,152,199,203,131,15,62,200,6,241,134,205,83,19,236,50,171,206,59,239,
1672 60,185,236,18,181,33,110,217,48,220,75,66,109,136,231,35,89,43,163,92,162,
1673 147,139,107,96,6,193,117,24,41,19,233,36,158,82,48,123,93,26,8,25,251,230,
1674 98,206,152,49,131,58,103,210,38,151,93,162,31,98,142,157,59,116,35,47,32,
1675 132,79,236,81,70,57,37,78,141,50,87,54,119,45,241,202,27,253,3,127,154,
1676 214,174,93,203,42,12,133,92,214,137,189,107,103,188,205,19,208,93,119,221,
1677 85,84,133,249,156,211,21,87,92,193,80,245,4,66,142,144,92,87,95,125,181,
1678 161,91,210,70,76,83,88,133,87,32,163,116,154,57,115,38,253,4,252,203,101,
1679 151,206,63,255,124,198,172,119,16,206,159,63,223,176,47,156,105,113,163,
1680 34,230,72,70,185,132,201,26,247,187,102,172,5,66,134,31,189,132,249,157,
1681 249,204,12,240,160,207,121,1,33,238,157,185,59,138,11,24,230,201,23,41,
1682 191,254,250,107,86,13,11,66,243,236,158,206,205,68,137,121,153,249,138,
1683 200,13,55,220,64,185,200,229,5,132,244,45,243,241,80,112,12,43,76,162,147,
1684 201,40,157,196,189,206,126,131,144,254,202,78,233,106,230,203,24,56,40,
1685 67,133,116,56,112,145,101,148,75,228,2,3,200,224,164,82,46,81,117,63,254,
1686 248,163,140,210,201,112,207,152,38,183,32,60,233,164,147,24,246,160,11,
1687 128,201,40,151,4,8,49,229,127,252,227,31,101,148,78,140,91,182,105,190,
1688 30,76,1,161,130,216,163,65,204,51,220,218,56,68,137,40,254,107,175,189,
1689 102,118,20,56,6,153,72,39,1,66,26,197,188,65,38,236,88,204,231,159,127,
1690 158,190,205,102,53,49,137,166,247,178,65,183,182,131,233,252,208,206,170,
1691 139,254,247,217,71,147,77,87,142,233,45,172,196,33,51,87,160,184,142,235,
1692 22,132,164,167,246,112,208,205,151,162,95,125,245,85,86,45,90,180,200,124,
1693 90,130,227,100,131,95,125,245,149,121,95,226,228,27,61,92,46,187,132,117,
1694 22,171,46,184,224,2,25,229,18,94,56,59,98,6,38,107,193,37,42,193,237,41,
1695 116,79,32,20,103,137,152,128,202,101,151,52,16,174,90,181,74,70,233,196,
1696 42,246,206,4,90,46,235,180,112,225,66,231,14,221,200,109,39,161,66,56,96,
1697 198,175,92,118,233,166,155,110,130,181,180,130,217,148,125,247,221,119,
1698 108,13,152,81,94,25,229,210,188,121,243,88,229,22,132,71,28,113,132,86,
1699 51,102,187,196,160,16,51,45,92,40,25,229,18,137,153,83,122,2,161,48,131,
1700 56,199,134,131,225,176,167,79,159,206,42,183,99,249,157,119,222,161,2,127,
1701 248,225,7,185,236,210,177,199,30,203,176,245,14,194,183,222,122,203,176,
1702 47,220,134,244,244,116,86,153,155,152,225,159,149,149,197,170,113,148,181,
1703 64,136,48,205,230,137,42,41,105,203,62,175,207,17,126,255,253,247,230,49,
1704 255,165,115,42,196,124,92,46,187,36,252,116,86,13,11,194,203,46,187,76,
1705 70,185,132,105,134,88,100,52,115,229,242,203,47,199,187,34,151,23,16,82,
1706 10,230,248,50,202,37,1,194,150,150,22,183,32,204,118,62,230,229,5,132,7,
1707 31,124,48,174,198,71,31,125,228,22,132,167,159,126,186,39,16,210,5,135,
1708 10,233,112,152,157,69,122,57,211,118,186,187,153,145,98,36,227,82,200,101,
1709 157,180,43,4,6,249,7,194,206,206,206,115,206,57,71,70,233,180,124,249,114,
1710 236,136,217,35,220,101,151,93,196,148,217,173,222,125,247,93,47,119,120,
1711 226,111,49,193,55,220,143,238,5,132,149,149,149,230,115,77,244,13,188,141,
1712 5,11,22,220,185,185,240,15,196,85,16,179,199,143,112,209,196,238,240,186,
1713 204,181,244,192,3,15,80,88,188,70,179,71,40,30,64,116,11,66,182,233,9,132,
1714 204,244,89,181,116,233,82,115,203,222,125,247,221,108,240,237,183,223,54,
1715 239,235,219,111,191,165,111,83,69,114,217,37,104,42,110,118,48,51,18,139,
1716 9,195,232,216,212,192,45,183,220,114,221,117,215,221,113,199,29,252,126,
1717 233,165,151,24,65,67,5,222,92,158,64,24,19,19,195,90,47,32,196,56,200,40,
1718 157,152,58,211,127,204,119,27,32,106,192,185,67,55,114,11,194,61,157,143,
1719 130,200,5,157,48,71,128,208,237,35,170,56,145,108,205,45,8,63,249,228,19,
1720 86,209,166,230,74,62,234,168,163,52,16,154,31,235,218,109,183,221,232,222,
1721 116,164,35,143,60,82,70,185,196,164,144,177,239,9,132,226,66,224,237,183,
1722 223,110,6,33,179,34,86,49,127,149,81,58,121,2,33,227,14,243,232,29,132,
1723 207,61,247,156,92,118,137,161,151,156,156,204,42,179,147,195,6,153,45,177,
1724 106,28,101,57,16,186,213,180,105,211,34,34,34,176,230,94,64,136,17,49,156,
1725 184,64,248,245,212,190,217,117,0,60,140,19,114,13,11,66,243,89,126,1,66,
1726 183,179,102,204,156,56,141,233,5,132,140,28,179,151,233,29,132,226,194,
1727 155,91,16,82,51,204,121,33,37,68,97,215,110,65,248,135,63,252,193,19,8,
1728 241,246,134,10,233,14,132,224,19,16,82,63,230,102,2,132,108,208,237,237,
1729 39,226,94,0,179,252,3,33,150,209,108,254,16,246,2,240,83,105,114,217,37,
1730 44,251,202,149,43,229,46,77,162,230,63,251,236,51,115,73,245,58,244,208,
1731 67,33,4,227,95,100,241,2,66,26,203,237,137,175,227,142,59,14,143,89,248,
1732 127,102,153,159,91,64,79,63,253,180,88,139,137,52,119,27,172,48,133,221,
1733 123,239,189,205,171,104,2,114,141,20,132,51,102,204,240,4,66,40,197,6,177,
1734 236,102,27,77,161,126,254,249,103,243,13,56,76,91,133,131,229,22,57,116,
1735 48,124,14,90,57,53,53,149,89,63,221,102,168,156,30,228,55,8,153,103,200,
1736 40,157,152,29,210,243,221,222,9,137,153,118,238,208,141,60,157,54,112,43,
1737 38,7,116,42,183,70,201,11,8,197,101,57,64,104,30,17,199,28,115,140,184,
1738 171,28,49,4,100,172,75,164,39,1,248,49,183,233,126,251,237,151,151,151,
1739 231,9,132,226,130,133,91,16,98,61,88,229,246,50,135,0,225,138,21,43,152,
1740 208,8,177,119,132,63,58,44,8,31,122,232,33,185,236,210,148,41,83,146,146,
1741 146,18,19,19,205,231,33,0,188,240,116,199,81,193,1,66,58,52,99,201,59,8,
1742 89,203,54,53,181,182,182,130,150,57,115,230,28,113,196,17,230,190,72,151,
1743 194,28,144,107,88,16,98,209,228,22,187,186,152,96,210,252,76,114,153,222,
1744 154,161,139,56,78,6,51,185,188,131,208,124,253,217,59,8,49,34,100,116,11,
1745 66,34,245,147,107,183,32,164,128,158,64,184,255,254,251,139,140,102,60,
1746 96,124,41,236,224,224,160,44,188,83,148,174,162,162,130,9,56,99,192,108,
1747 43,209,99,143,61,38,54,104,144,127,32,164,17,221,130,208,147,152,117,98,
1748 223,229,46,221,73,0,128,221,121,233,123,76,155,180,19,53,94,64,200,90,122,
1749 163,219,74,160,164,120,78,244,19,58,140,216,142,38,243,249,67,164,205,30,
1750 220,130,208,139,232,102,228,26,41,8,95,123,237,53,79,32,252,231,63,255,
1751 201,6,241,57,100,123,119,117,37,36,36,48,22,138,139,139,241,162,204,46,
1752 56,154,60,121,50,19,35,42,138,13,154,247,133,168,162,227,143,63,254,173,
1753 183,222,98,74,42,220,98,79,26,93,16,122,145,188,40,235,78,190,131,16,195,
1754 130,247,79,137,204,15,61,35,47,32,20,199,12,8,205,54,132,89,148,23,16,122,
1755 17,137,115,114,114,104,47,183,32,20,131,194,45,8,197,93,20,94,64,136,176,
1756 129,6,97,22,188,131,16,43,39,250,143,16,99,156,186,122,254,249,231,221,
1757 78,67,241,182,69,19,143,163,172,14,66,134,25,243,110,241,116,179,119,16,
1758 106,98,56,253,242,203,47,143,60,242,8,61,85,166,48,201,119,16,106,162,159,
1759 209,198,151,95,126,185,151,211,107,1,6,33,21,248,204,51,207,12,29,156,75,
1760 110,65,8,111,60,129,80,187,70,104,62,243,35,64,40,214,34,122,255,154,53,
1761 107,48,175,108,205,140,52,77,227,11,66,188,147,31,127,252,81,238,210,179,
1762 168,207,123,239,189,215,203,189,233,116,9,218,130,148,222,65,200,28,220,
1763 173,225,22,218,97,135,29,152,48,25,78,213,186,189,228,137,129,16,107,71,
1764 10,194,43,175,188,146,92,94,64,72,73,205,214,86,92,35,116,11,194,219,110,
1765 187,77,28,137,16,77,67,159,191,230,154,107,204,119,51,105,98,132,126,241,
1766 197,23,204,232,217,215,141,55,222,232,118,102,32,68,223,94,180,104,17,93,
1767 81,110,221,164,128,129,80,92,10,117,43,95,64,200,184,99,164,47,88,176,0,
1768 30,108,9,8,169,58,25,229,18,206,150,54,232,70,4,66,58,51,221,0,163,234,
1769 22,132,226,198,64,51,8,89,196,143,103,149,23,16,58,143,197,141,188,131,
1770 80,19,201,240,155,57,42,183,179,40,33,5,66,35,8,177,149,135,31,126,56,38,
1771 24,248,93,123,237,181,143,62,250,40,8,20,143,160,162,97,65,72,191,140,141,
1772 141,61,251,236,179,169,89,239,148,213,64,200,252,139,62,45,99,117,210,131,
1773 144,182,164,187,224,60,153,207,197,25,116,234,169,167,6,18,132,24,29,113,
1774 102,67,147,91,16,158,112,194,9,158,64,184,247,222,123,139,140,102,155,72,
1775 181,104,147,83,14,224,134,27,110,216,109,183,221,134,157,187,140,47,8,97,
1776 143,48,64,195,10,95,237,235,175,191,118,123,225,71,72,156,77,242,14,66,
1777 68,21,185,125,154,80,136,62,64,65,244,175,33,118,123,54,85,24,35,52,82,
1778 16,94,116,209,69,228,242,14,66,243,237,148,244,25,79,32,196,96,137,35,161,
1779 195,252,244,211,79,52,16,115,11,239,135,180,253,246,219,99,233,146,146,
1780 146,104,44,134,170,151,215,38,176,29,42,220,211,201,115,20,48,16,222,117,
1781 215,93,206,29,186,145,91,16,30,124,240,193,204,141,168,109,198,224,3,15,
1782 60,176,106,213,42,250,173,72,191,37,32,52,60,149,136,78,60,241,68,255,64,
1783 72,51,165,167,167,123,2,161,56,119,125,235,173,183,26,14,134,69,155,205,
1784 198,170,177,0,33,83,231,175,190,250,234,232,163,143,118,251,12,168,94,10,
1785 132,70,171,10,15,162,162,162,168,125,33,192,38,83,59,53,44,8,233,124,134,
1786 27,109,216,5,0,51,179,1,163,252,218,107,175,145,5,67,6,119,101,172,78,26,
1787 8,113,25,207,58,235,44,67,7,162,105,233,4,230,46,206,104,9,36,8,41,133,
1788 184,214,173,201,45,8,143,63,254,120,79,32,36,70,100,52,119,86,160,78,229,
1789 208,4,32,129,49,105,40,14,25,177,11,114,65,39,79,39,157,70,23,132,107,215,
1790 174,165,68,8,51,100,144,161,207,104,98,47,212,128,65,155,54,109,250,243,
1791 159,255,236,118,126,35,238,228,28,22,132,136,86,19,243,36,79,206,16,19,
1792 136,117,235,214,137,3,187,236,178,203,204,29,67,156,158,66,110,65,248,175,
1793 127,253,203,83,97,137,36,151,23,16,166,164,164,152,75,199,238,88,229,22,
1794 132,55,223,124,179,56,146,55,223,124,211,80,28,22,15,60,240,64,243,211,
1795 102,184,53,76,41,216,81,123,123,123,101,101,37,7,243,225,135,31,30,114,
1796 200,33,230,230,22,226,120,94,127,253,117,14,64,236,72,175,209,5,225,251,
1797 239,191,47,170,72,212,149,94,162,222,220,202,45,8,191,251,238,59,178,12,
1798 153,36,147,81,98,107,126,131,208,60,232,24,17,94,64,72,229,111,220,184,
1799 145,35,113,43,14,204,19,8,197,105,18,243,59,7,88,20,103,35,198,2,132,255,
1800 249,207,127,12,187,99,78,118,220,113,199,153,207,168,225,206,138,27,131,
1801 199,81,150,3,161,151,26,161,177,189,128,144,65,200,196,77,70,185,180,223,
1802 126,251,49,87,165,59,202,101,151,24,213,2,33,158,154,83,3,33,189,214,112,
1803 156,12,191,183,222,122,11,110,153,79,58,49,161,11,36,8,201,101,56,17,225,
1804 22,132,199,30,123,44,85,135,221,247,2,66,243,228,84,128,16,235,118,249,
1805 229,151,203,40,151,14,56,224,0,44,251,130,5,11,228,178,78,250,15,41,232,
1806 53,186,32,100,182,196,54,151,45,91,118,207,230,122,232,161,135,196,157,
1807 105,6,49,158,103,205,154,5,171,12,162,207,224,196,92,105,122,67,58,18,103,
1808 29,125,1,161,80,90,90,26,54,197,211,187,172,232,15,24,62,146,185,125,145,
1809 166,0,97,122,69,250,243,51,158,55,175,21,72,46,46,46,134,136,178,156,46,
1810 137,27,190,188,131,208,92,237,96,155,85,110,65,136,223,207,6,243,242,242,
1811 204,190,242,225,135,31,206,216,52,223,40,43,174,17,82,252,142,142,14,90,
1812 51,33,33,33,35,35,131,201,19,123,49,119,69,161,19,78,56,193,124,233,1,141,
1813 46,8,49,238,20,19,63,233,145,71,30,145,245,229,146,120,254,199,173,220,
1814 130,16,170,121,154,96,109,9,8,205,183,141,120,7,225,238,187,239,46,190,
1815 76,178,124,249,242,251,55,215,255,251,127,255,143,206,236,29,132,230,71,
1816 114,89,124,246,217,103,89,229,5,132,216,37,187,221,254,196,19,79,80,76,
1817 77,140,11,239,32,164,63,24,30,102,99,95,140,169,186,186,58,243,96,167,31,
1818 138,17,61,142,10,29,16,174,95,191,222,252,28,33,93,132,182,188,245,214,
1819 91,229,178,75,128,80,188,68,131,230,116,107,106,181,129,106,62,213,115,
1820 212,81,71,193,27,186,157,121,106,163,189,180,34,96,32,20,47,77,213,228,
1821 22,132,71,31,125,244,176,32,52,223,230,32,64,8,39,204,247,220,62,252,240,
1822 195,12,99,183,32,196,88,139,13,26,52,186,32,20,157,196,124,219,58,150,197,
1823 237,91,214,232,3,110,239,113,47,119,126,86,240,243,207,63,55,159,63,196,
1824 185,39,151,239,32,68,180,44,224,113,251,17,124,134,186,152,33,225,128,154,
1825 59,134,0,225,146,180,37,15,62,247,160,121,45,51,107,214,98,1,205,221,251,
1826 218,107,175,101,149,23,16,50,45,48,143,50,1,194,37,75,150,152,65,72,191,
1827 101,131,56,64,230,198,162,2,233,69,230,7,234,233,57,226,230,73,80,193,102,
1828 233,24,8,60,16,3,80,111,185,229,22,115,137,240,132,12,143,169,8,141,5,8,
1829 127,250,233,39,243,197,96,204,136,115,135,110,20,72,16,154,15,204,59,8,
1830 137,17,245,102,126,56,146,85,217,217,217,222,65,104,54,74,44,138,155,12,
1831 230,204,153,35,163,116,18,32,76,76,76,220,119,223,125,233,69,154,176,123,
1832 69,69,69,222,65,248,225,135,31,26,246,69,63,249,234,171,175,88,117,140,
1833 233,129,122,134,173,184,11,100,28,21,58,32,92,184,112,161,249,226,243,103,
1834 159,125,198,170,7,30,120,64,46,187,196,174,133,245,97,134,226,246,181,138,
1835 26,8,13,239,203,64,23,92,112,1,182,27,11,110,238,169,56,254,190,128,144,
1836 181,50,202,37,239,32,196,210,145,209,111,143,240,200,35,143,28,22,132,102,
1837 18,8,16,82,63,230,27,189,24,54,216,5,183,32,100,230,33,54,104,144,127,32,
1838 244,244,28,161,232,36,211,167,79,151,203,46,97,217,221,62,62,193,120,54,
1839 219,14,36,64,200,32,116,123,219,2,46,142,23,16,82,57,230,171,203,17,17,
1840 17,228,98,242,100,238,219,180,47,251,114,107,25,53,16,62,252,226,195,230,
1841 243,171,226,225,138,184,184,56,51,8,135,125,124,34,41,41,201,188,59,1,194,
1842 197,139,23,155,65,120,205,53,215,176,193,247,222,123,207,124,24,226,229,
1843 171,120,180,114,217,37,12,220,55,223,124,195,42,243,227,52,226,200,217,
1844 26,29,85,70,185,164,255,26,154,38,191,65,232,246,57,66,1,194,21,43,86,152,
1845 221,244,145,62,62,49,186,32,228,192,88,5,8,205,7,166,7,161,249,57,66,13,
1846 132,76,226,101,148,75,251,239,191,191,151,199,39,4,8,153,54,25,14,134,69,
1847 209,70,110,159,9,22,32,100,22,110,184,85,10,46,98,30,189,131,144,62,38,
1848 151,93,98,246,147,144,144,192,42,243,165,40,200,202,192,97,213,56,42,116,
1849 64,200,96,48,187,53,68,178,10,163,32,151,93,98,215,52,21,171,240,120,204,
1850 147,92,164,129,208,124,155,223,197,23,95,12,177,176,131,230,71,148,152,
1851 236,12,11,66,70,142,249,5,114,222,65,8,45,200,104,6,33,104,17,183,252,104,
1852 114,11,66,98,134,5,161,153,82,2,132,116,119,179,185,20,51,59,102,30,230,
1853 50,222,115,207,61,98,131,6,249,7,66,14,219,237,149,72,209,73,102,207,158,
1854 45,151,93,194,178,184,61,199,130,21,99,124,202,68,58,81,39,172,101,168,
1855 251,1,66,86,153,31,10,20,247,136,82,63,134,107,213,40,35,35,131,85,110,
1856 59,134,6,194,199,94,123,108,219,73,198,25,137,48,85,32,205,12,66,76,48,
1857 171,188,131,80,46,235,36,64,72,243,153,79,205,93,125,245,213,108,208,124,
1858 129,16,137,215,199,152,31,129,133,70,226,76,227,255,251,127,255,79,70,185,
1859 36,188,13,42,217,124,211,41,24,54,163,197,111,16,46,95,190,92,70,233,36,
1860 64,184,102,205,26,243,117,77,76,188,115,135,110,52,82,16,178,11,243,139,
1861 145,145,23,16,126,255,253,247,172,234,233,233,49,223,72,169,7,161,249,149,
1862 114,26,8,25,245,50,202,37,198,56,94,154,119,16,98,64,12,7,195,34,253,132,
1863 85,76,23,100,148,78,2,132,233,233,233,6,67,71,21,85,86,86,122,7,33,157,
1864 86,46,187,4,237,196,155,101,204,22,21,70,138,119,69,141,163,66,28,132,226,
1865 5,137,143,62,250,168,92,118,137,93,139,219,165,154,154,154,220,222,209,
1866 46,230,239,200,188,150,177,74,46,32,97,30,222,71,29,117,212,176,32,164,
1867 20,230,247,31,34,24,198,102,205,14,16,54,26,118,146,209,45,8,197,27,146,
1868 52,185,5,225,225,135,31,62,186,32,252,244,211,79,177,11,230,87,78,32,241,
1869 68,182,89,110,65,8,108,42,42,42,0,33,243,89,25,229,146,0,33,25,111,112,
1870 247,229,54,241,106,208,87,95,125,85,46,187,68,113,4,111,204,114,123,254,
1871 83,204,67,113,34,205,61,7,51,68,165,121,1,97,115,115,179,185,111,8,183,
1872 9,75,103,56,109,78,17,240,173,89,101,190,133,29,105,32,124,246,221,103,
1873 119,152,98,188,88,11,96,88,203,184,48,131,80,24,29,255,64,136,67,111,6,
1874 225,223,254,246,55,54,56,107,214,44,51,8,197,123,77,241,42,228,178,75,212,
1875 170,120,211,144,249,101,34,79,60,241,4,253,4,3,109,112,110,24,125,110,13,
1876 159,39,16,138,230,54,251,223,26,8,211,210,210,204,198,68,216,113,24,105,
1877 190,222,41,192,224,86,35,5,33,98,71,230,190,45,222,53,248,167,63,253,201,
1878 220,220,98,174,6,8,205,247,52,232,65,104,30,239,16,93,228,53,159,231,167,
1879 187,122,121,197,154,40,175,153,202,44,138,23,248,101,101,101,153,143,243,
1880 229,151,95,198,242,36,39,39,227,2,202,40,167,56,72,97,25,188,128,144,57,
1881 144,92,118,9,218,209,27,89,101,158,235,51,107,244,242,66,168,192,40,116,
1882 64,184,100,201,18,243,188,158,246,96,94,111,30,189,180,186,56,61,2,123,
1883 220,190,240,158,173,177,59,18,208,123,100,148,75,39,156,112,2,152,164,235,
1884 152,175,17,2,33,188,58,114,121,1,33,35,138,185,170,121,45,123,100,158,69,
1885 39,147,203,46,129,70,198,51,25,221,130,80,92,233,212,228,22,132,135,30,
1886 122,168,223,32,196,124,155,115,49,221,99,24,207,156,57,83,46,235,228,9,
1887 132,96,195,188,11,6,54,51,92,106,210,108,226,53,16,2,9,115,70,124,65,240,
1888 105,190,212,122,228,145,71,106,15,219,24,228,214,32,222,122,235,173,107,
1889 215,174,189,233,166,155,204,118,159,118,39,151,23,16,118,119,119,155,31,
1890 156,160,78,176,29,120,84,6,178,146,69,92,35,188,227,142,59,204,77,47,222,
1891 68,186,56,117,241,27,223,190,177,219,158,70,247,5,56,209,135,231,204,153,
1892 131,221,151,81,46,137,19,140,254,129,144,121,140,185,3,139,82,211,63,205,
1893 117,254,222,123,239,209,183,205,231,181,0,225,151,206,23,25,126,98,250,
1894 228,250,205,55,223,220,222,222,142,63,103,168,249,105,211,166,37,38,38,
1895 146,197,32,138,233,118,86,250,216,99,143,209,220,230,19,48,26,8,233,246,
1896 230,89,41,185,104,35,186,138,161,119,97,118,197,231,50,220,202,15,16,50,
1897 5,55,159,0,184,239,190,251,40,142,25,21,76,62,68,23,165,197,25,152,50,214,
1898 37,208,152,157,45,63,185,108,62,243,143,125,99,102,79,161,232,177,50,202,
1899 37,108,11,173,227,29,132,164,49,244,61,22,197,73,5,183,147,209,107,174,
1900 185,6,243,200,44,199,80,129,140,26,154,213,59,8,205,147,84,54,178,104,209,
1901 34,118,100,174,225,29,118,216,65,156,111,24,71,133,14,8,99,99,99,205,183,
1902 62,98,79,25,186,230,110,74,15,16,207,51,225,192,153,175,2,34,186,197,89,
1903 103,157,133,123,97,190,190,136,141,99,254,101,190,228,139,240,189,134,5,
1904 33,98,90,199,129,201,88,151,24,3,116,44,51,203,177,47,98,16,154,65,136,
1905 249,22,206,132,38,183,32,100,203,126,131,144,142,107,254,174,216,238,187,
1906 239,206,180,206,48,79,20,242,4,66,198,182,249,12,21,29,224,148,83,78,113,
1907 251,221,50,13,132,28,182,25,147,108,234,196,19,79,52,55,183,151,107,63,
1908 212,140,249,174,31,132,141,54,151,29,189,253,246,219,228,242,2,66,214,62,
1909 255,252,243,244,88,25,235,212,222,123,239,125,222,121,231,153,63,202,67,
1910 219,97,191,200,130,123,103,238,246,28,3,77,127,203,61,183,196,101,197,157,
1911 119,225,121,134,158,67,49,113,134,48,244,134,120,178,136,109,250,7,66,179,
1912 219,138,174,186,234,42,58,48,6,203,92,39,28,0,141,101,40,47,34,70,120,63,
1913 216,50,195,64,219,121,231,157,169,13,243,123,45,142,63,254,120,81,129,6,
1914 113,84,230,121,39,18,163,216,188,107,13,132,76,50,204,47,65,165,147,80,
1915 69,123,238,185,167,161,222,152,190,152,223,248,163,201,15,16,82,255,102,
1916 72,51,144,105,53,115,23,213,30,97,236,237,237,253,189,233,221,217,84,251,
1917 177,199,30,123,249,229,151,167,164,164,84,87,87,27,46,34,210,115,56,188,
1918 211,79,63,29,239,74,70,57,69,61,188,255,254,251,28,161,119,16,98,232,12,
1919 85,193,226,163,143,62,202,42,42,4,236,201,88,151,68,199,51,156,191,165,
1920 137,191,251,238,59,246,229,29,132,95,125,245,149,97,95,28,60,3,144,97,107,
1921 136,71,12,112,79,159,127,9,152,66,7,132,152,108,51,93,132,204,67,8,137,
1922 11,24,108,243,254,251,239,55,183,141,16,7,195,236,216,124,156,66,230,120,
1923 166,120,190,128,16,247,8,144,120,218,169,38,18,92,122,233,165,94,78,149,
1924 0,66,113,165,83,147,91,16,30,116,208,65,20,115,211,166,77,126,128,144,169,
1925 159,249,254,8,47,242,4,66,132,103,35,19,249,32,13,132,12,57,220,44,243,
1926 89,77,131,168,43,156,105,1,6,183,98,59,76,125,204,78,149,91,81,99,226,186,
1927 172,119,16,226,235,184,157,13,24,68,221,126,244,209,71,98,154,255,245,215,
1928 95,187,229,46,194,148,115,144,224,196,96,230,220,138,52,218,36,218,63,16,
1929 98,206,204,59,186,248,226,139,241,213,114,115,115,205,115,71,33,243,80,
1930 162,19,50,87,195,15,102,176,156,112,194,9,190,244,234,27,111,188,145,225,
1931 47,14,222,160,23,95,124,209,237,104,117,43,13,132,104,217,178,101,94,62,
1932 68,172,137,52,222,47,71,249,1,66,86,61,252,240,195,190,20,156,250,169,116,
1933 125,120,143,33,233,22,90,136,137,17,141,75,27,209,99,205,231,42,204,98,
1934 82,46,222,179,232,29,132,230,243,180,44,10,16,162,149,43,87,122,178,159,
1935 122,157,115,206,57,226,234,143,119,16,186,253,200,168,144,185,255,51,105,
1936 16,159,166,26,71,133,14,8,209,140,25,51,204,23,123,112,95,204,8,65,226,
1937 174,116,148,144,144,96,126,58,74,136,131,41,43,43,115,235,178,224,20,154,
1938 207,198,28,114,200,33,190,128,16,165,165,165,185,189,28,162,23,211,49,241,
1939 224,132,144,185,20,84,160,246,118,46,33,47,32,204,203,203,243,3,132,140,
1940 198,79,63,253,212,108,22,217,53,254,129,185,5,189,128,48,50,50,210,45,54,
1941 220,62,32,161,129,16,129,55,218,221,60,185,214,196,97,48,38,105,71,47,214,
1942 10,245,244,244,192,0,179,99,170,23,118,135,130,107,182,210,59,8,209,234,
1943 213,171,241,111,228,10,15,186,253,246,219,181,19,182,76,215,152,88,184,
1944 181,110,128,16,156,212,213,213,113,144,7,30,120,160,23,195,138,163,48,123,
1945 246,108,141,250,254,129,112,254,252,249,102,16,210,39,241,69,168,168,71,
1946 30,121,196,124,144,248,61,230,11,60,36,155,53,107,22,221,30,124,82,111,
1947 248,43,114,133,7,177,5,38,16,28,0,115,172,142,142,14,67,147,81,177,110,
1948 251,3,99,208,60,180,245,32,68,248,184,230,147,141,122,209,112,120,78,148,
1949 78,102,112,39,63,64,136,232,39,120,84,230,35,212,11,127,104,249,242,229,
1950 20,92,100,97,131,63,255,252,179,121,72,34,1,66,210,224,20,222,118,219,109,
1951 94,88,200,170,179,206,58,139,38,19,219,244,14,66,243,131,61,122,16,210,
1952 157,222,126,251,109,47,19,59,38,163,248,247,204,167,69,122,239,32,68,110,
1953 159,156,57,252,240,195,205,185,168,183,53,107,214,136,92,227,165,144,2,
1954 33,67,139,129,161,191,221,127,167,157,118,98,14,238,246,59,221,26,8,17,
1955 180,163,67,48,95,195,226,235,187,29,7,195,78,177,224,250,171,65,28,54,139,
1956 233,233,233,230,51,27,190,131,16,225,115,188,254,250,235,102,154,34,138,
1957 128,181,210,238,92,21,114,11,66,195,201,64,47,32,204,201,201,49,79,153,
1958 135,5,33,171,58,59,59,191,252,242,75,189,185,167,86,153,185,187,253,238,
1959 149,23,16,98,229,241,66,244,166,10,67,252,244,211,79,99,199,205,39,132,
1960 245,32,68,88,76,144,115,229,149,87,154,79,147,82,168,39,158,120,130,137,
1961 182,102,98,188,168,183,183,23,215,129,134,144,153,55,23,21,5,63,104,23,
1962 109,83,195,130,16,97,26,30,123,236,49,179,9,166,117,112,82,191,248,226,
1963 139,166,166,38,153,212,41,106,245,205,55,223,60,251,236,179,41,163,190,
1964 179,253,249,207,127,206,206,206,142,136,136,192,40,124,245,213,87,119,223,
1965 125,183,249,174,66,42,156,100,224,77,239,251,250,7,66,183,31,230,165,134,
1966 217,26,168,128,220,36,211,159,59,229,104,23,47,94,124,215,93,119,201,101,
1967 151,40,2,221,152,244,128,80,248,133,76,206,142,61,246,88,115,255,135,238,
1968 240,187,162,162,130,233,29,13,193,15,90,205,12,152,210,210,82,124,23,125,
1969 205,92,114,201,37,20,196,108,163,13,32,68,89,89,89,15,62,248,160,249,129,
1970 31,140,248,117,215,93,39,246,43,147,122,144,127,32,68,12,252,207,63,255,
1971 220,252,161,124,180,243,206,59,115,84,140,77,134,161,76,237,20,7,195,212,
1972 129,42,61,242,200,35,245,243,60,13,132,8,87,143,30,203,236,193,236,96,77,
1973 155,54,13,151,145,106,212,142,205,59,8,205,55,67,232,65,136,104,190,228,
1974 228,100,38,100,230,19,48,180,29,132,19,6,65,104,88,16,114,96,255,247,127,
1975 255,167,63,7,67,49,99,99,99,205,143,217,132,53,8,17,221,194,44,239,29,142,
1976 1,44,211,233,164,183,128,100,103,76,174,88,177,226,221,119,223,157,55,111,
1977 30,83,42,98,16,134,195,32,90,93,230,113,138,52,98,227,196,211,159,176,254,
1978 72,219,50,63,24,69,115,231,206,125,231,157,119,24,234,164,33,61,246,66,
1979 110,75,39,45,189,56,54,189,244,199,41,196,70,136,103,66,135,185,196,70,
1980 188,246,218,107,88,64,230,203,140,16,86,201,68,46,185,221,157,161,20,136,
1981 188,114,157,78,98,149,121,11,218,236,88,46,235,164,55,25,28,12,181,177,
1982 118,237,90,14,242,179,207,62,131,208,162,186,100,82,157,204,101,212,75,
1983 228,194,158,50,49,199,16,99,242,68,49,69,253,24,36,178,232,69,94,134,226,
1984 79,63,253,244,241,199,31,51,222,112,85,161,99,91,91,155,185,174,188,139,
1985 237,48,45,120,235,173,183,152,12,97,134,30,126,248,225,233,211,167,179,
1986 89,179,131,130,228,209,184,212,211,211,159,95,220,159,150,231,208,135,212,
1987 220,193,164,172,190,255,45,78,123,253,173,31,30,123,230,237,255,123,114,
1988 214,203,51,190,254,250,199,196,148,156,129,212,188,65,67,98,2,233,89,149,
1989 156,211,159,156,221,31,159,222,29,155,214,73,72,76,46,166,134,53,97,26,
1990 18,83,235,62,251,38,242,133,215,190,124,228,201,55,159,122,238,253,153,
1991 111,255,248,203,218,18,50,26,182,70,96,35,134,144,156,221,71,60,59,50,196,
1992 19,234,26,134,218,136,178,200,54,211,137,86,22,32,36,1,85,129,45,163,195,
1993 207,156,57,147,153,80,92,92,28,248,103,150,80,84,84,4,243,168,118,176,205,
1994 68,1,204,243,67,3,97,94,94,30,131,142,26,230,7,243,30,38,106,175,190,250,
1995 234,71,31,125,196,100,84,140,26,246,75,135,167,119,149,151,151,187,5,33,
1996 34,37,19,130,57,115,230,208,196,105,105,105,162,83,57,171,223,40,115,118,
1997 98,200,30,21,21,5,150,102,204,152,65,79,3,3,236,75,108,100,88,145,76,110,
1998 90,39,183,7,105,22,201,200,206,196,232,219,111,191,165,222,216,59,131,133,
1999 46,218,218,218,234,101,11,100,17,59,229,176,157,86,103,72,44,202,213,78,
2000 145,128,202,167,32,212,9,91,198,92,172,91,183,142,246,50,111,150,141,136,
2001 166,212,75,36,115,107,25,72,47,50,106,98,95,140,142,165,75,151,210,106,
2002 88,36,140,222,134,13,27,200,107,222,151,56,108,131,244,201,248,93,92,92,
2003 188,96,193,2,124,205,69,139,22,137,251,197,200,37,247,173,19,145,34,203,
2004 120,105,60,65,168,164,20,116,194,64,197,231,56,22,68,141,126,88,177,161,
2005 68,50,208,165,149,235,51,13,105,70,37,84,12,61,199,225,94,24,50,13,132,
2006 66,224,13,200,65,187,140,140,12,216,134,203,133,115,150,144,144,208,216,
2007 216,8,17,197,170,252,252,124,108,61,214,19,11,142,75,33,174,87,161,246,
2008 246,118,166,143,76,43,73,67,188,48,118,236,2,16,98,251,176,236,122,111,
2009 70,73,105,28,165,64,168,164,52,2,141,29,8,87,174,207,151,0,116,233,151,
2010 141,181,134,52,163,18,124,1,33,30,0,168,3,93,117,117,117,48,12,248,1,45,
2011 188,7,225,201,137,179,124,120,135,184,107,172,194,77,103,21,200,36,37,98,
2012 149,216,26,32,76,76,76,36,13,34,13,14,55,188,100,155,208,20,172,194,72,
2013 60,66,216,41,238,75,82,82,26,71,41,16,42,41,141,64,56,48,109,237,142,198,
2014 230,209,15,245,13,29,145,145,145,146,129,107,215,198,197,197,85,84,245,
2015 24,210,140,74,232,115,115,214,89,10,255,76,156,31,6,120,240,9,188,193,45,
2016 252,57,164,225,77,156,97,227,7,49,56,127,240,82,172,34,18,7,17,176,57,83,
2017 13,9,16,194,188,218,218,90,146,137,109,138,140,164,33,37,80,36,134,93,136,
2018 51,102,74,74,227,40,5,66,37,37,171,8,54,20,21,21,109,216,176,33,63,63,95,
2019 48,99,188,4,255,56,128,45,60,111,41,64,104,190,10,165,164,100,53,41,16,
2020 42,41,89,72,93,93,93,209,209,209,250,171,116,193,43,56,170,249,145,74,74,
2021 86,150,2,161,146,146,37,84,209,84,81,222,84,94,88,83,184,54,110,109,113,
2022 93,49,191,219,187,218,229,58,37,37,165,177,148,2,161,146,146,37,180,36,
2023 109,201,130,228,5,250,80,92,85,44,215,41,41,41,141,165,20,8,149,148,44,
2024 33,5,66,37,165,241,146,2,161,146,146,37,100,125,16,246,244,244,148,151,
2025 151,235,223,188,131,250,251,251,43,43,43,137,23,55,197,180,181,181,21,23,
2026 23,139,71,200,91,90,90,248,173,46,19,110,161,178,178,178,62,217,92,93,30,
2027 222,212,170,228,183,20,8,149,148,44,33,139,131,16,248,229,230,230,150,150,
2028 150,166,167,167,55,233,94,26,87,81,81,65,124,78,78,14,204,235,236,236,140,
2029 142,142,174,174,174,78,76,76,132,139,252,16,224,148,73,149,70,174,188,188,
2030 188,195,14,59,108,187,205,37,190,213,172,52,138,26,127,16,166,165,165,77,
2031 52,233,128,3,14,40,42,42,98,166,121,210,73,39,201,40,157,222,127,255,125,
2032 153,217,47,157,123,238,185,114,67,58,93,121,229,149,114,117,208,234,201,
2033 39,159,148,133,209,233,154,107,174,97,122,46,83,184,19,118,237,160,131,
2034 14,146,169,93,154,60,121,50,35,80,166,24,61,21,20,20,236,191,255,254,114,
2035 31,46,77,155,54,77,124,119,123,180,196,124,121,235,173,183,150,91,247,160,
2036 41,83,166,44,89,178,68,102,24,61,61,248,224,131,219,108,179,141,220,135,
2037 75,151,94,122,169,92,237,85,129,7,225,137,39,158,40,15,81,167,127,254,243,
2038 159,114,245,230,194,29,220,180,105,83,71,71,71,109,109,109,73,73,137,246,
2039 100,69,102,102,38,67,120,175,189,246,18,217,183,218,106,43,241,99,215,93,
2040 119,93,186,116,41,224,36,189,72,185,133,162,67,138,45,235,181,247,222,123,
2041 231,231,231,215,212,212,156,126,250,233,50,74,167,153,51,103,146,177,187,
2042 187,123,219,109,183,149,81,46,29,127,252,241,144,91,108,57,240,90,182,108,
2043 217,212,169,83,229,161,184,180,207,62,251,36,36,36,200,20,78,149,149,149,
2044 157,112,194,9,242,141,156,206,87,131,138,31,228,253,246,219,111,245,126,
2045 249,88,232,214,91,111,149,71,166,211,237,183,223,46,214,154,135,216,78,
2046 59,237,148,170,251,72,64,112,105,252,65,72,221,137,214,213,107,191,253,
2047 246,19,32,212,247,3,77,91,8,194,179,207,62,91,110,72,167,63,253,233,79,
2048 114,117,208,234,241,199,31,151,133,209,233,239,127,255,187,119,16,98,197,
2049 204,223,228,196,154,143,17,8,205,47,146,102,84,199,197,197,201,20,163,33,
2050 64,104,126,227,179,65,219,111,191,253,226,197,139,101,134,209,211,253,247,
2051 223,111,126,149,252,31,255,248,71,185,218,171,226,242,227,162,115,163,9,
2052 63,39,255,44,126,84,215,87,203,117,99,35,183,223,205,184,237,182,219,228,
2053 234,205,69,173,2,66,254,54,52,52,20,22,22,106,32,76,73,73,129,133,230,47,
2054 248,236,178,203,46,235,214,173,171,171,171,27,45,123,77,135,148,155,214,
2055 105,207,61,247,20,32,252,131,233,251,245,72,188,0,26,16,98,166,101,148,
2056 75,71,29,117,20,165,16,91,14,188,126,254,249,103,243,215,84,40,139,30,132,
2057 28,246,101,151,93,38,215,57,223,8,175,255,216,19,51,0,88,40,147,142,141,
2058 220,190,191,27,58,138,181,230,33,182,227,142,59,42,16,250,47,183,32,196,
2059 52,123,1,225,71,31,125,36,51,251,37,5,66,189,20,8,71,81,119,223,125,183,
2060 121,215,62,130,176,175,191,175,183,175,183,189,163,61,42,38,170,179,171,
2061 147,223,99,61,229,31,107,16,142,110,179,186,5,33,158,40,71,229,9,132,179,
2062 102,205,34,163,91,16,30,113,196,17,100,20,91,14,188,124,1,225,121,231,253,
2063 250,137,102,86,69,69,69,81,243,122,52,78,155,54,205,251,183,21,183,80,10,
2064 132,1,149,91,16,30,120,224,129,197,197,197,158,64,56,103,206,28,153,217,
2065 47,221,119,223,125,103,154,164,255,28,73,144,234,221,119,223,149,133,209,
2066 233,63,255,249,79,71,71,135,76,225,78,10,132,163,40,40,226,55,8,133,56,
2067 248,232,232,232,222,225,190,22,52,42,26,17,8,123,122,122,232,18,109,109,
2068 109,140,74,241,249,17,17,159,157,157,157,148,148,52,94,32,196,49,242,2,
2069 194,217,179,103,147,209,45,8,127,251,219,223,226,74,138,45,7,94,195,130,
2070 144,35,63,231,156,115,206,58,235,44,112,120,197,21,87,204,157,59,87,204,
2071 138,50,50,50,110,185,229,150,75,47,189,148,217,60,107,31,120,224,129,177,
2072 123,65,157,119,16,74,251,162,211,69,23,93,52,142,85,186,133,178,40,8,15,
2073 58,232,32,47,32,252,244,211,79,69,222,90,119,194,136,48,74,115,115,115,
2074 191,254,250,235,247,223,127,127,249,242,229,140,4,145,94,168,189,189,189,
2075 217,36,34,91,90,90,234,76,146,121,28,14,185,172,19,89,228,58,167,250,251,
2076 251,41,203,194,133,11,113,88,63,251,236,179,95,126,249,133,110,225,246,
2077 150,57,142,71,30,171,78,34,37,219,196,64,139,239,135,105,194,56,174,93,
2078 187,118,222,188,121,160,142,141,127,243,205,55,89,89,89,230,45,51,36,100,
2079 97,116,34,175,92,237,20,222,225,178,101,203,196,189,103,177,177,177,140,
2080 46,102,244,230,111,34,186,5,33,123,132,154,140,97,38,34,111,191,253,54,
2081 173,176,106,213,42,142,92,174,54,137,250,164,242,73,198,190,48,238,52,202,
2082 136,64,200,1,44,93,186,244,227,143,63,102,119,63,253,244,19,214,86,51,190,
2083 222,229,55,8,203,203,203,57,96,218,238,195,15,63,92,176,96,1,245,227,253,
2084 245,96,88,165,239,190,251,238,131,15,62,248,254,251,239,201,75,140,219,
2085 239,80,186,5,33,125,96,221,186,117,52,37,38,143,191,27,54,108,192,154,19,
2086 111,6,97,125,125,189,232,33,154,240,12,196,42,126,179,119,179,41,196,69,
2087 19,5,97,227,116,24,106,175,168,168,72,174,211,105,68,32,164,242,75,75,75,
2088 227,227,227,87,175,94,77,229,208,46,239,188,243,78,100,100,36,7,195,34,
2089 222,137,204,239,146,39,16,210,172,75,150,44,209,55,171,92,49,156,220,130,
2090 144,238,228,5,132,28,33,25,221,130,240,176,195,14,99,131,116,233,228,228,
2091 100,70,22,45,206,200,21,77,224,86,180,8,135,202,192,36,229,151,95,126,185,
2092 114,229,74,79,103,86,69,27,25,36,58,18,63,230,207,159,191,98,197,10,95,
2093 60,66,77,49,49,49,212,24,44,196,154,125,241,197,23,152,2,183,199,217,216,
2094 216,40,246,165,23,22,128,85,88,21,74,135,245,224,248,13,95,57,21,194,14,
2095 164,167,167,127,251,237,183,148,110,209,162,69,226,83,160,222,65,40,204,
2096 139,65,110,205,93,78,78,14,198,144,222,248,214,91,111,209,27,177,63,213,
2097 213,99,123,206,223,15,5,37,8,169,83,50,82,239,12,182,157,55,23,233,169,
2098 247,23,94,120,129,145,57,121,242,228,73,147,38,209,225,126,247,187,223,
2099 97,170,52,51,122,249,229,151,179,214,160,235,174,187,14,231,105,215,93,
2100 119,149,203,78,145,81,59,61,245,251,223,255,94,198,58,181,219,110,187,137,
2101 19,47,136,230,167,247,92,114,201,37,216,116,44,172,184,179,139,253,238,
2102 180,211,78,87,93,117,21,253,94,223,63,248,253,228,147,79,202,195,213,41,
2103 34,34,2,107,197,196,138,140,247,222,123,175,72,76,143,121,228,145,71,246,
2104 218,107,175,29,119,220,81,20,135,45,243,131,29,93,112,193,5,12,39,253,150,
2105 159,123,238,57,42,68,30,159,75,116,92,97,40,41,8,35,234,244,211,79,103,
2106 251,226,8,167,76,153,242,215,191,254,245,171,175,190,50,195,201,0,66,134,
2107 49,76,58,247,220,115,41,145,200,46,142,132,223,187,239,190,251,227,143,
2108 63,174,255,136,46,162,170,177,197,76,105,245,251,250,211,159,254,68,45,
2109 49,133,151,251,112,201,0,66,142,19,204,83,111,148,69,95,153,108,129,13,
2110 98,115,13,104,55,203,45,8,41,209,73,39,157,196,60,90,232,252,243,207,215,
2111 190,5,202,209,210,151,238,191,255,126,142,77,43,29,187,102,143,71,30,121,
2112 36,163,23,19,35,82,106,162,66,158,125,246,89,220,32,209,40,36,230,55,76,
2113 162,140,195,130,144,249,193,107,175,189,118,224,129,7,106,109,202,95,126,
2114 83,147,143,61,246,24,125,64,15,66,172,237,161,135,30,42,187,136,75,116,
2115 75,226,63,255,252,115,92,121,178,51,76,68,98,142,10,50,253,229,47,127,49,
2116 55,19,135,71,167,194,50,234,39,19,35,2,33,162,179,129,13,144,163,109,156,
2117 195,166,200,152,105,243,183,112,13,32,212,154,149,62,105,104,86,250,21,
2118 102,122,216,102,117,11,194,125,247,221,151,217,149,39,16,190,247,222,123,
2119 100,244,4,66,136,206,232,224,0,180,70,164,110,153,180,105,67,94,136,90,
2120 101,140,208,247,72,73,26,209,94,28,57,22,0,231,140,10,55,164,103,76,137,
2121 102,210,68,145,193,12,199,201,65,146,247,245,215,95,247,5,132,244,129,255,
2122 253,239,127,167,158,122,170,216,175,168,112,254,82,231,148,154,238,39,158,
2123 81,209,18,227,32,202,253,185,68,19,48,19,250,225,135,31,232,39,226,200,
2124 249,75,222,231,159,127,94,111,55,40,32,70,134,97,168,213,3,173,9,119,111,
2125 188,241,70,121,100,58,105,32,52,155,26,230,211,76,13,197,90,196,46,96,54,
2126 181,193,150,181,14,35,26,157,146,222,115,207,61,250,243,10,227,46,139,130,
2127 240,144,67,14,41,41,41,241,4,66,166,69,100,108,106,106,50,223,152,64,147,
2128 95,122,233,165,230,120,236,14,166,89,236,17,59,40,99,117,98,60,51,27,162,
2129 169,228,178,75,90,143,161,127,200,40,167,88,100,34,79,60,152,1,108,52,176,
2130 92,97,18,41,233,121,120,144,98,59,108,240,161,135,30,146,235,116,218,184,
2131 113,35,131,141,31,88,82,122,9,41,153,129,30,119,220,113,98,173,91,109,187,
2132 237,182,79,61,245,148,230,152,122,191,70,136,139,64,103,149,177,58,49,158,
2133 25,0,114,193,37,61,8,43,42,42,56,30,239,62,214,41,167,156,130,137,20,233,
2134 17,140,49,195,21,17,105,254,248,181,30,132,0,233,149,87,94,97,140,201,117,
2135 38,209,178,12,69,239,103,96,60,129,48,49,49,81,166,208,169,167,167,135,
2136 121,149,249,251,242,122,93,124,241,197,250,251,90,59,59,59,129,138,92,167,
2137 211,214,91,111,77,89,228,130,78,122,16,226,82,211,63,229,10,119,194,64,
2138 191,252,242,203,212,131,72,143,187,195,228,76,174,115,9,96,51,9,131,118,
2139 98,145,6,34,101,85,85,213,51,207,60,131,209,20,145,110,69,253,99,91,49,
2140 124,98,227,35,5,161,167,102,197,2,82,189,114,193,37,61,8,41,206,171,175,
2141 190,106,46,136,94,64,197,251,69,59,183,32,100,215,94,64,40,190,95,239,22,
2142 132,28,12,230,88,46,232,196,24,193,79,213,12,52,91,190,227,142,59,188,140,
2143 110,198,206,244,233,211,245,87,31,104,110,185,206,37,58,237,119,223,125,
2144 119,244,209,71,139,197,153,51,103,14,11,66,220,128,7,30,120,64,174,240,
2145 32,154,15,12,139,67,5,132,230,214,100,191,151,93,118,25,3,92,46,235,36,
2146 124,101,132,245,160,197,205,6,147,34,187,237,75,26,8,205,67,12,66,99,204,
2147 197,90,204,221,211,79,63,237,118,56,104,162,47,225,41,234,145,60,142,178,
2148 40,8,49,76,94,64,248,229,151,95,146,209,45,8,25,144,230,78,143,72,137,133,
2149 21,38,192,19,8,233,85,230,222,169,157,0,145,203,46,49,96,98,99,99,137,103,
2150 179,102,124,26,68,130,187,238,186,75,108,199,19,8,127,251,219,223,138,31,
2151 244,48,236,44,29,20,119,68,196,120,17,253,21,187,41,6,131,23,16,98,187,
2152 233,193,222,97,166,151,6,66,50,222,126,251,237,152,120,185,194,179,240,
2153 152,197,253,232,216,157,155,111,190,217,220,52,158,164,129,144,153,53,19,
2154 88,51,149,205,186,240,194,11,181,137,133,89,35,2,33,179,13,28,110,153,200,
2155 179,14,63,252,112,109,182,187,110,221,58,183,198,197,147,52,16,226,237,
2156 49,193,31,182,21,152,203,127,255,253,247,34,139,91,16,210,157,244,64,2,
2157 132,20,153,102,242,165,206,245,55,137,140,8,132,204,24,174,189,246,90,223,
2158 187,144,6,66,154,245,141,55,222,240,194,18,77,76,56,188,52,171,91,16,50,
2159 241,245,2,66,113,87,157,91,16,122,209,245,215,95,79,183,23,59,101,36,14,
2160 91,100,102,186,184,248,26,59,205,32,100,242,167,111,47,106,195,59,8,91,
2161 90,90,174,187,238,58,95,90,243,180,211,78,19,167,58,221,130,16,121,170,
2162 118,70,171,120,190,51,42,42,202,251,4,197,32,95,64,72,139,223,121,231,157,
2163 190,28,63,38,206,124,186,101,92,100,81,16,50,47,46,45,45,245,3,132,196,
2164 48,54,232,82,230,118,186,242,202,43,69,255,246,4,194,134,134,6,109,150,
2165 173,105,233,210,165,100,161,211,200,101,151,216,5,145,244,66,179,139,131,
2166 33,219,125,247,221,13,7,192,80,20,87,254,60,129,80,19,25,239,191,255,126,
2167 246,107,222,242,65,7,29,132,213,54,108,153,73,177,56,147,230,5,132,216,
2168 151,51,206,56,67,70,233,196,248,196,249,54,87,163,6,66,108,153,193,136,
2169 0,197,61,246,216,195,92,81,0,108,222,188,121,100,169,173,173,117,187,47,
2170 114,225,151,155,219,69,3,33,230,236,164,147,78,146,177,46,177,150,170,54,
2171 28,33,251,210,159,235,54,200,119,16,178,5,236,190,33,49,182,131,74,54,240,
2172 152,3,160,81,128,1,185,222,127,255,125,179,125,33,134,81,109,56,109,32,
2173 36,64,200,190,62,252,240,67,67,101,114,84,236,139,14,35,151,93,58,255,252,
2174 243,5,18,220,130,208,32,64,200,32,50,224,92,52,19,52,50,148,142,69,142,
2175 95,156,205,27,17,8,105,29,252,126,153,72,39,90,135,17,103,174,112,13,132,
2176 110,71,177,167,102,93,176,96,129,167,102,117,11,194,3,14,56,128,169,170,
2177 31,32,36,134,201,141,219,9,13,213,162,157,68,49,55,52,61,223,92,171,212,
2178 182,230,12,153,65,104,16,222,188,119,16,50,195,54,172,229,104,221,14,58,
2179 226,241,95,201,226,9,132,100,161,138,204,197,167,183,136,214,249,230,155,
2180 111,100,148,78,236,29,82,154,237,15,242,5,132,203,150,45,163,138,100,172,
2181 83,28,0,123,196,121,48,247,70,237,2,211,248,202,162,32,164,143,250,7,194,
2182 131,15,62,56,39,39,135,177,97,54,31,39,159,124,178,184,90,230,9,132,172,
2183 50,88,19,52,125,250,116,226,153,55,201,101,151,192,15,35,118,198,140,25,
2184 134,166,197,180,253,240,195,15,28,185,217,179,249,219,223,254,134,1,242,
2185 5,132,15,60,240,128,221,110,55,116,95,70,2,38,207,237,16,18,183,66,120,
2186 1,33,25,181,51,51,154,166,76,153,130,157,165,104,230,82,107,32,124,241,
2187 197,23,101,148,75,199,28,115,12,54,122,209,162,69,114,89,167,255,254,247,
2188 191,148,142,201,193,177,199,30,43,163,92,162,165,240,189,126,249,229,23,
2189 243,233,89,13,132,209,209,209,134,74,163,6,104,107,26,218,60,200,111,186,
2190 233,38,79,119,195,250,14,66,166,222,230,178,223,115,207,61,108,225,193,
2191 7,31,148,203,46,97,26,232,147,228,122,233,165,151,204,150,133,227,161,63,
2192 184,117,187,5,8,217,230,53,215,92,35,163,92,58,239,188,243,154,155,155,
2193 177,254,6,159,27,251,43,234,196,71,16,46,94,188,216,176,5,6,14,157,16,147,
2194 106,182,158,183,220,114,139,56,53,50,34,16,150,148,148,28,117,212,81,50,
2195 145,78,216,110,241,120,184,92,118,73,3,97,68,68,132,97,126,64,103,96,206,
2196 68,47,50,159,249,191,249,230,155,169,40,177,71,131,220,130,144,169,149,
2197 127,32,20,134,34,61,61,29,243,45,163,92,98,66,67,199,32,35,238,160,217,
2198 194,64,199,13,27,54,152,115,105,183,157,15,11,194,217,179,103,123,7,225,
2199 59,239,188,35,163,92,194,118,137,177,111,104,101,100,179,217,24,116,158,
2200 78,141,98,190,104,107,186,174,140,114,137,185,215,234,213,171,233,177,112,
2201 72,70,233,196,54,25,92,127,254,243,159,229,178,78,190,128,16,171,200,112,
2202 147,177,78,29,113,196,17,108,144,126,98,30,254,194,240,142,187,44,10,194,
2203 223,254,246,183,254,129,240,196,19,79,196,16,227,148,104,103,26,53,209,
2204 24,98,162,231,5,132,24,38,185,236,146,176,11,243,231,207,151,203,46,49,
2205 59,38,254,226,139,47,150,203,46,49,141,90,181,106,21,171,232,214,50,202,
2206 37,186,35,78,167,47,32,252,215,191,254,69,26,67,233,40,26,155,197,30,153,
2207 77,91,86,86,22,171,188,128,176,188,188,252,119,191,251,157,140,114,137,
2208 217,6,70,135,188,88,19,25,229,146,6,194,107,175,189,86,70,185,116,234,169,
2209 167,50,234,168,97,185,172,19,135,141,209,225,8,205,208,197,80,50,32,1,182,
2210 249,34,147,6,194,153,51,103,202,40,151,168,204,53,107,214,224,199,155,15,
2211 3,30,211,1,200,101,150,39,16,2,111,184,34,36,78,40,97,209,228,106,157,176,
2212 2,24,136,215,95,127,93,46,187,196,24,78,75,75,35,23,9,204,29,239,249,231,
2213 159,103,213,51,207,60,99,94,37,64,136,109,53,95,137,196,214,48,57,99,46,
2214 98,190,30,131,53,228,48,56,84,239,32,164,164,12,147,55,223,124,83,46,187,
2215 68,19,208,232,84,248,97,135,29,38,163,92,186,228,146,75,252,0,33,188,97,
2216 4,201,68,46,1,108,230,118,197,197,197,204,210,100,148,75,26,8,223,120,227,
2217 13,25,229,18,214,60,50,50,178,189,189,157,169,161,140,114,9,8,137,65,106,
2218 150,91,16,30,116,208,65,254,129,144,254,195,97,211,141,205,157,31,70,50,
2219 59,161,93,78,63,253,116,25,165,19,118,137,61,154,199,32,227,66,28,231,150,
2220 131,208,124,117,240,234,171,175,230,120,10,10,10,12,158,22,34,49,227,209,
2221 45,8,41,181,120,232,254,170,171,174,146,81,46,1,45,142,129,14,246,218,107,
2222 175,201,40,157,196,221,15,247,221,119,159,185,51,15,11,66,236,219,195,15,
2223 63,44,163,92,58,228,144,67,0,33,51,209,125,247,221,87,70,185,132,85,20,
2224 27,28,95,89,20,132,88,109,76,21,35,28,235,47,163,116,242,2,66,166,78,140,
2225 127,38,155,116,116,25,229,18,219,28,22,132,79,60,241,132,92,118,233,140,
2226 51,206,32,158,190,43,151,93,194,111,160,27,153,167,90,147,38,77,194,174,
2227 145,133,225,36,163,92,194,14,138,7,42,134,5,33,9,238,190,251,110,67,233,
2228 246,222,123,111,144,80,85,85,197,96,96,149,94,226,70,149,145,130,16,163,
2229 3,51,114,115,115,177,38,50,202,37,13,132,231,158,123,174,140,114,233,180,
2230 211,78,195,246,245,244,244,152,207,156,48,72,176,110,110,65,200,49,99,124,
2231 49,34,230,145,160,129,208,124,252,120,18,176,138,131,196,137,145,81,46,
2232 97,71,60,221,132,237,22,132,136,138,194,52,8,81,10,82,154,231,55,100,20,
2233 231,0,222,123,239,61,25,165,211,218,181,107,89,229,22,132,184,206,172,2,
2234 135,230,85,2,132,216,86,243,116,248,186,235,174,163,198,40,190,249,236,
2235 168,232,96,195,130,144,178,48,76,158,126,250,105,185,236,18,83,52,102,93,
2236 180,187,217,235,98,140,96,55,57,164,45,7,33,182,143,206,192,94,204,211,
2237 62,13,132,230,49,133,223,31,19,19,131,101,188,225,134,27,100,148,75,12,
2238 31,195,29,200,154,220,130,144,81,6,236,1,33,13,42,163,116,242,2,66,12,11,
2239 135,205,190,204,51,102,1,66,24,233,118,22,142,217,97,12,154,219,139,209,
2240 45,142,124,203,65,72,175,144,81,46,49,17,4,132,140,172,253,77,143,252,94,
2241 127,253,245,12,70,79,32,252,225,135,31,216,224,77,55,221,36,163,92,98,239,
2242 94,64,248,191,255,253,143,92,204,107,205,157,121,88,16,82,219,255,252,231,
2243 63,101,148,75,204,189,24,149,217,217,217,102,171,200,204,88,108,112,124,
2244 101,81,16,50,228,252,3,33,147,56,236,35,32,52,159,157,195,1,26,22,132,11,
2245 23,46,148,203,46,97,71,136,127,234,169,167,228,178,75,159,124,242,9,35,
2246 25,150,200,101,151,192,195,242,229,203,177,110,230,203,15,48,0,98,121,1,
2247 33,121,153,191,51,251,251,244,211,79,49,169,230,209,251,232,163,143,82,
2248 39,12,239,183,55,23,131,150,131,28,11,16,154,11,40,64,216,216,216,104,174,
2249 124,142,156,125,249,13,66,243,248,161,66,24,174,24,116,179,197,68,250,123,
2250 181,245,242,4,66,189,196,252,221,124,14,10,81,243,52,159,219,83,70,116,
2251 60,108,135,127,32,164,20,230,243,90,87,94,121,37,70,28,190,154,61,194,75,
2252 47,189,212,59,8,169,210,203,47,191,28,27,199,64,48,159,200,101,6,195,40,
2253 160,194,205,45,72,31,19,23,59,183,28,132,28,246,176,32,188,243,206,59,101,
2254 148,75,212,195,234,213,171,57,60,243,185,98,148,158,158,46,246,104,144,
2255 91,16,226,106,248,7,194,147,78,58,169,162,162,2,116,153,11,37,64,72,213,
2256 153,187,49,34,23,85,97,6,33,136,162,177,216,157,39,16,210,153,207,57,231,
2257 28,184,181,100,201,18,239,32,52,223,87,140,235,204,200,162,164,230,122,
2258 190,236,178,203,40,160,39,16,178,35,54,232,22,132,226,230,216,81,7,33,86,
2259 145,50,202,40,151,206,60,243,76,70,37,107,15,56,224,0,25,229,18,83,31,14,
2260 67,108,115,28,101,81,16,50,122,1,33,51,47,243,221,19,200,63,16,50,254,135,
2261 5,33,152,145,203,46,29,117,212,81,52,161,217,70,211,101,91,90,90,204,116,
2262 161,127,236,177,199,30,180,183,249,216,232,196,152,6,47,32,252,240,195,
2263 15,41,50,7,73,207,166,47,26,206,179,35,198,18,115,67,113,115,166,89,99,
2264 1,66,243,41,32,1,66,179,139,140,176,203,52,138,223,32,52,15,87,68,101,98,
2265 98,204,86,3,225,85,56,203,109,148,239,32,52,159,255,68,226,254,2,179,247,
2266 134,62,248,224,3,191,65,232,246,100,50,190,209,126,251,237,71,199,48,31,
2267 48,182,195,11,8,207,56,227,140,180,180,52,113,6,143,100,230,254,73,39,103,
2268 143,52,147,249,118,143,221,119,223,61,144,32,116,251,92,54,233,41,184,219,
2269 123,139,196,9,21,179,220,130,16,63,76,156,225,116,123,26,115,75,64,8,117,
2270 204,171,16,135,77,31,54,183,50,145,226,10,133,91,16,82,222,31,127,252,145,
2271 201,16,237,69,229,123,7,33,157,83,70,185,36,64,136,125,48,239,151,126,226,
2272 5,132,203,150,45,99,131,230,145,69,205,47,93,186,116,44,64,200,36,210,124,
2273 33,227,148,83,78,17,147,75,179,77,99,23,172,18,219,28,71,141,63,8,153,215,
2274 203,42,209,9,252,8,16,158,124,242,201,50,74,39,47,32,196,76,147,203,45,
2275 8,153,60,14,11,66,154,4,216,200,40,167,176,137,140,64,102,238,114,217,37,
2276 38,62,110,65,232,69,248,136,12,114,79,32,52,24,32,138,192,144,147,235,54,
2277 23,166,237,153,103,158,201,206,206,198,6,201,212,78,141,5,8,245,98,176,
2278 209,40,191,252,242,203,37,151,92,98,118,110,16,38,0,79,113,116,65,232,69,
2279 120,21,226,192,12,218,66,16,122,209,204,153,51,169,243,81,4,161,23,253,
2280 254,247,191,247,4,66,108,232,119,223,125,55,84,84,15,98,8,96,1,111,188,
2281 241,70,183,245,0,233,199,29,132,94,180,114,229,74,177,71,131,242,243,243,
2282 101,10,157,152,221,10,16,50,51,144,81,58,141,5,8,61,105,239,189,247,78,
2283 73,73,97,119,110,65,72,79,163,53,157,229,24,146,119,16,234,197,160,99,212,
2284 44,92,184,240,226,139,47,118,219,154,244,100,58,188,39,16,138,123,74,221,
2285 130,16,199,116,44,64,40,214,106,98,23,244,70,160,139,155,104,222,26,34,
2286 18,75,46,83,143,159,198,31,132,153,153,153,178,74,116,18,32,196,183,115,
2287 123,199,182,23,16,254,225,15,127,192,171,115,11,66,204,253,176,32,236,236,
2288 236,52,92,92,196,51,88,181,106,149,225,48,152,83,211,249,70,10,194,157,
2289 119,222,121,253,250,245,158,64,40,94,151,163,23,22,193,140,13,33,122,33,
2290 92,127,244,209,71,161,142,76,61,198,32,220,184,113,227,125,247,221,199,
2291 96,51,76,20,244,10,48,8,197,77,73,102,141,29,8,177,26,1,3,33,38,222,19,
2292 8,153,81,185,125,38,146,244,184,137,116,3,74,231,214,135,22,178,56,8,87,
2293 172,88,33,246,104,80,65,65,129,76,161,147,6,66,28,35,25,165,83,32,65,72,
2294 13,136,70,113,11,66,195,217,11,95,64,72,107,146,235,206,59,239,60,238,184,
2295 227,204,183,160,107,242,14,66,104,199,166,204,35,139,13,46,94,188,120,76,
2296 65,200,198,41,206,19,79,60,129,51,99,62,45,161,73,129,80,10,207,70,86,137,
2297 78,126,131,144,110,225,9,132,7,30,120,224,176,32,196,64,24,238,176,162,
2298 9,231,205,155,103,56,181,125,222,121,231,145,210,19,8,161,200,36,119,218,
2299 99,143,61,188,128,208,240,126,81,68,79,162,31,51,60,60,153,117,220,178,
2300 11,46,184,128,241,44,210,143,17,8,49,52,247,222,123,47,184,210,91,19,115,
2301 205,163,177,0,161,167,202,68,218,59,210,12,114,11,66,182,195,200,199,152,
2302 10,81,33,164,116,11,66,106,85,238,192,164,81,247,8,73,44,55,173,215,182,
2303 67,69,62,244,208,67,233,0,110,65,72,71,210,94,147,164,137,222,200,222,129,
2304 156,193,89,55,87,133,21,64,232,165,89,61,205,111,32,147,204,172,147,0,33,
2305 227,61,96,32,148,71,105,18,38,66,188,55,213,12,66,90,196,224,42,121,7,33,
2306 237,206,72,185,251,238,187,169,94,183,3,77,47,239,32,20,47,212,13,60,8,
2307 57,158,103,158,121,6,135,65,223,27,221,218,49,118,161,64,56,164,156,156,
2308 28,89,37,58,105,32,164,153,101,148,78,222,65,72,255,102,96,152,239,26,165,
2309 167,98,44,200,232,5,132,80,202,112,95,12,141,247,194,11,47,24,222,144,249,
2310 224,131,15,98,214,221,130,144,33,17,17,17,49,84,48,231,27,22,12,162,231,
2311 121,2,225,162,69,139,68,46,131,152,227,255,243,159,255,244,116,199,4,186,
2312 248,226,139,25,234,164,28,11,16,98,14,204,151,105,247,217,103,159,71,30,
2313 121,68,46,232,116,209,69,23,141,46,8,25,201,226,68,25,245,38,107,80,39,
2314 226,221,202,19,8,205,94,148,91,16,190,244,210,75,98,173,220,141,78,34,126,
2315 20,65,248,183,191,253,173,205,245,38,88,169,230,250,129,220,101,3,157,237,
2316 252,36,222,45,8,177,152,76,31,89,171,169,170,170,234,220,115,207,53,148,
2317 26,224,93,120,225,133,80,83,46,187,132,121,21,29,102,28,65,40,190,31,52,
2318 162,102,245,14,194,179,206,58,75,70,233,52,22,32,20,147,105,121,172,155,
2319 203,121,152,110,64,72,223,19,15,222,104,242,14,66,170,154,177,41,99,93,
2320 162,29,177,81,110,11,226,5,132,11,23,46,100,131,230,145,197,252,30,131,
2321 51,70,32,164,234,204,54,150,174,114,217,101,151,209,43,228,178,75,236,162,
2322 193,245,18,249,113,148,165,65,232,233,241,32,47,32,20,79,158,50,48,204,
2323 182,120,191,253,246,27,22,132,232,211,79,63,149,81,46,193,45,131,53,249,
2324 240,195,15,233,247,158,64,40,78,131,204,157,59,247,252,205,117,229,149,
2325 87,210,81,60,129,208,211,68,24,49,127,199,149,116,235,48,33,122,164,232,
2326 184,99,1,194,39,159,124,82,70,185,68,119,255,226,139,47,58,59,59,229,178,
2327 78,184,167,244,233,81,4,225,182,206,231,8,89,181,96,193,2,89,137,58,25,
2328 140,139,166,81,1,97,126,126,254,165,151,94,42,247,228,18,94,59,182,99,20,
2329 65,40,30,159,96,246,192,244,95,238,227,156,179,207,63,237,248,243,207,57,
2330 235,134,27,110,96,95,110,65,184,215,94,123,225,212,14,21,192,165,121,243,
2331 230,81,64,185,218,165,233,211,167,227,56,154,159,147,219,126,251,237,199,
2332 23,132,24,104,49,89,252,250,235,175,233,51,178,224,46,25,156,39,77,0,79,
2333 230,215,73,3,161,219,65,61,118,32,100,172,201,195,117,233,234,171,175,166,
2334 177,88,101,6,33,204,51,220,225,236,29,132,51,102,204,48,244,34,154,108,
2335 254,252,249,152,74,243,237,69,39,156,112,130,23,16,138,243,76,230,155,174,
2336 1,33,140,28,11,16,178,77,60,7,195,105,9,68,36,70,204,60,252,217,5,173,32,
2337 182,57,142,26,127,16,98,55,101,149,232,164,129,208,237,93,209,222,65,200,
2338 176,196,232,152,167,84,248,49,190,128,144,78,96,176,41,24,104,195,68,102,
2339 221,186,117,164,244,4,66,241,14,210,103,159,125,86,70,185,4,77,97,164,39,
2340 16,26,78,244,225,40,224,16,51,211,215,68,133,96,56,14,57,228,16,115,23,
2341 196,101,36,203,88,128,208,60,170,177,14,28,9,108,150,203,58,157,119,222,
2342 121,91,2,194,155,111,190,89,70,185,196,112,21,85,253,222,123,239,153,75,
2343 237,233,171,164,190,131,16,139,35,87,235,36,64,200,144,102,96,203,40,151,
2344 222,126,251,109,236,254,40,130,16,11,5,8,105,104,243,99,66,39,157,120,162,
2345 39,16,238,189,247,222,152,233,161,2,184,196,33,201,117,46,9,66,144,140,
2346 31,50,202,37,106,53,144,32,52,63,3,202,252,70,220,26,106,182,248,8,115,
2347 233,220,161,81,212,146,76,161,147,40,38,150,52,192,32,196,92,200,101,151,
2348 48,47,130,118,230,33,67,71,26,17,8,205,53,38,110,125,160,51,152,31,219,
2349 56,238,184,227,188,128,80,188,180,214,252,96,34,102,74,188,205,110,212,
2350 65,136,101,184,235,174,187,100,148,75,20,13,107,73,233,20,8,61,138,90,144,
2351 85,162,147,119,16,50,57,34,163,119,16,154,59,49,230,195,23,16,98,121,13,
2352 166,135,94,168,239,181,216,17,49,140,25,96,28,167,140,117,73,3,33,51,32,
2353 25,229,18,19,121,186,130,39,16,26,110,150,51,191,199,11,142,18,143,27,100,
2354 126,66,145,105,53,171,198,2,132,230,55,6,156,114,202,41,20,156,238,110,
2355 30,9,231,156,115,14,173,233,55,8,205,159,116,96,254,187,97,195,6,86,205,
2356 153,51,199,60,199,20,86,195,44,223,65,136,161,148,171,93,34,227,171,175,
2357 190,202,42,44,151,249,9,138,143,63,254,24,219,225,31,8,113,251,232,27,50,
2358 202,37,47,32,60,239,204,51,60,129,208,236,17,154,223,229,193,164,4,63,137,
2359 10,55,119,81,170,34,144,32,188,255,254,251,101,148,75,226,129,122,86,49,
2360 177,224,96,100,172,75,250,15,125,232,197,212,80,166,208,73,3,161,248,114,
2361 139,65,226,6,52,255,64,72,161,204,151,87,144,0,161,25,45,251,237,183,31,
2362 30,27,171,204,32,164,27,143,8,132,102,202,94,117,213,85,216,46,216,108,
2363 174,103,14,114,88,16,226,173,202,40,151,232,138,226,244,198,168,131,176,
2364 179,179,211,252,253,38,90,135,131,196,118,25,110,182,64,10,132,82,110,125,
2365 11,241,174,81,79,167,70,197,195,49,222,65,104,126,97,132,152,149,144,209,
2366 59,8,179,178,178,240,186,100,172,83,244,99,253,142,246,223,127,127,113,
2367 171,2,221,200,252,238,9,13,132,211,167,79,151,81,46,145,49,61,61,221,71,
2368 16,226,3,25,76,63,117,34,86,153,123,252,153,103,158,73,252,88,128,208,108,
2369 70,105,17,138,64,171,49,33,144,81,46,157,117,214,89,91,2,66,243,43,72,24,
2370 90,194,237,155,59,119,174,249,110,85,44,32,171,204,242,29,132,223,125,247,
2371 157,92,237,18,13,253,250,235,175,179,138,38,54,79,56,126,248,225,7,191,
2372 65,136,109,165,18,100,148,75,2,132,116,87,250,173,140,114,233,239,151,156,
2373 57,216,211,229,9,132,134,15,81,153,97,195,78,241,206,177,245,230,169,12,
2374 71,24,72,16,154,207,174,195,0,177,138,78,110,110,86,118,228,220,161,81,
2375 212,188,153,103,116,93,240,64,175,115,59,168,113,122,200,232,9,132,28,182,
2376 91,16,50,252,105,44,26,197,237,155,101,4,8,205,231,123,15,60,240,64,186,
2377 55,171,204,32,100,164,24,222,18,224,29,132,230,23,55,94,115,205,53,204,
2378 3,24,89,230,55,203,136,81,236,29,132,230,87,217,81,237,162,51,143,58,8,
2379 59,58,58,204,179,4,234,132,131,100,162,192,36,67,70,185,196,46,20,8,165,
2380 24,78,178,86,92,194,92,210,191,113,10,205,38,21,9,210,120,1,33,4,5,27,50,
2381 202,37,60,42,95,64,200,60,218,108,59,244,98,120,112,96,34,177,249,37,126,
2382 128,80,56,49,207,60,243,140,140,114,9,54,51,200,125,4,225,87,95,125,101,
2383 152,44,227,209,138,85,102,47,25,218,17,63,82,16,50,224,233,157,88,124,243,
2384 52,77,3,161,185,254,169,97,114,33,179,139,118,198,25,103,120,2,33,195,30,
2385 16,226,199,120,121,215,168,249,173,102,218,169,209,15,62,248,192,96,203,
2386 118,218,105,39,90,138,85,102,113,108,62,130,16,187,35,87,235,244,242,203,
2387 47,179,138,217,43,187,144,81,78,209,217,196,149,45,183,32,20,239,92,254,
2388 207,127,254,99,94,37,64,72,43,152,79,215,211,58,24,184,202,202,74,115,151,
2389 123,248,174,219,7,219,155,125,4,161,249,237,148,226,205,50,116,84,183,110,
2390 141,31,32,116,123,170,16,123,74,127,102,21,131,75,70,185,164,129,208,220,
2391 172,140,145,232,232,104,86,189,249,230,155,134,94,68,63,97,92,59,119,232,
2392 70,230,170,0,30,116,84,42,208,45,180,196,89,86,183,32,60,238,184,227,232,
2393 168,116,87,243,140,153,26,195,80,224,217,184,189,19,21,219,194,54,205,3,
2394 31,131,3,62,89,101,6,33,181,52,162,155,101,46,185,228,18,25,229,210,95,
2395 254,242,23,14,137,153,159,121,248,48,174,57,84,239,32,36,187,140,114,73,
2396 3,161,219,203,228,226,218,147,219,119,142,251,7,66,166,200,140,74,214,42,
2397 143,208,155,46,184,224,2,89,43,46,209,132,255,253,239,127,177,56,84,174,
2398 140,114,137,121,58,147,53,114,121,7,161,249,210,8,25,69,79,245,14,66,6,
2399 182,219,59,208,52,209,209,5,80,209,171,175,190,106,232,16,28,249,204,153,
2400 51,57,6,243,120,56,231,156,115,152,254,251,8,194,200,200,72,195,153,52,
2401 182,204,152,135,91,134,91,88,17,190,20,89,188,128,16,207,192,45,156,112,
2402 7,87,175,94,189,187,233,243,226,26,8,97,155,140,114,137,1,207,128,196,198,
2403 201,101,157,78,63,253,116,97,124,205,239,183,164,150,50,50,50,160,154,217,
2404 43,210,64,200,252,198,224,101,210,190,31,125,244,17,67,200,236,241,208,
2405 136,90,43,24,228,59,8,129,144,217,130,223,117,215,93,88,150,207,62,251,
2406 204,96,61,153,140,139,115,95,175,188,242,138,97,21,194,104,210,187,176,
2407 143,230,93,11,16,114,84,230,137,185,184,201,57,38,38,198,252,242,4,113,
2408 254,223,71,16,154,189,46,154,41,43,43,11,211,99,118,193,145,31,32,116,59,
2409 191,65,152,248,53,107,214,152,175,93,105,32,164,39,27,30,131,163,89,63,
2410 253,244,83,42,217,252,246,53,134,30,99,68,236,209,172,203,46,187,76,166,
2411 115,137,218,166,236,184,227,244,34,25,229,210,180,105,211,168,91,114,185,
2412 5,33,214,128,106,231,216,204,179,112,154,146,142,65,70,122,130,217,194,
2413 172,90,181,138,30,110,56,105,132,254,252,231,63,195,21,114,153,7,62,176,
2414 167,33,134,10,224,146,119,16,50,102,101,148,75,167,156,114,10,245,31,21,
2415 21,101,190,89,134,134,30,22,132,230,247,129,48,28,88,197,1,191,245,214,
2416 91,50,74,167,155,111,190,153,86,48,159,161,69,195,130,144,126,78,26,25,
2417 229,18,38,11,195,69,169,205,151,27,20,8,127,21,243,125,89,43,58,129,1,3,
2418 9,132,254,249,207,127,226,91,144,203,59,8,205,61,149,145,233,11,8,209,181,
2419 94,63,64,122,253,245,215,139,30,143,176,251,230,174,201,152,196,250,208,
2420 213,228,178,75,204,127,201,226,35,8,123,122,122,24,24,114,157,75,108,150,
2421 41,161,249,216,196,51,200,94,64,200,113,186,157,222,210,65,217,139,185,
2422 26,53,16,154,223,6,201,168,62,240,192,3,205,199,134,4,8,189,236,139,131,
2423 55,239,75,3,33,243,27,243,153,112,44,44,187,51,84,50,53,192,76,150,154,
2424 28,170,41,147,124,7,33,237,120,247,221,119,203,20,46,177,47,246,104,182,
2425 236,88,58,113,90,236,195,15,63,52,159,22,38,134,217,174,57,30,9,16,178,
2426 47,172,191,225,76,32,71,5,2,1,155,161,90,112,74,196,89,7,31,65,104,254,
2427 194,3,70,144,218,166,206,205,21,142,252,0,33,173,227,246,89,38,79,205,170,
2428 129,176,202,221,251,161,220,54,43,98,18,233,169,89,17,179,19,153,78,39,
2429 170,212,173,161,192,154,131,7,114,185,5,33,61,132,106,52,79,131,16,195,
2430 31,180,144,145,121,155,161,189,16,179,70,183,229,21,79,236,33,51,8,73,60,
2431 34,16,154,253,123,209,79,220,14,58,12,221,176,32,52,35,141,81,44,206,127,
2432 154,175,14,32,74,205,164,199,109,103,30,22,132,110,237,155,168,109,183,
2433 166,134,24,5,66,41,198,60,166,211,92,179,102,225,231,137,89,57,242,14,66,
2434 243,201,104,198,158,143,32,52,127,11,80,19,7,137,233,148,233,156,122,231,
2435 157,119,204,227,217,32,142,243,252,243,207,23,233,125,4,33,154,62,125,186,
2436 151,55,74,104,58,225,132,19,132,237,240,2,66,216,224,227,55,163,133,52,
2437 16,186,125,247,180,39,9,16,50,38,49,166,190,239,75,3,33,250,252,243,207,
2438 13,39,36,221,10,139,92,180,249,109,147,122,249,14,66,148,158,158,110,254,
2439 58,146,89,76,65,196,73,90,132,27,97,246,161,133,220,246,97,1,66,132,131,
2440 114,206,57,231,12,219,207,49,235,179,103,207,22,109,234,35,8,153,9,153,
2441 77,54,162,21,40,184,92,208,201,15,16,210,172,158,222,217,230,86,26,8,209,
2442 156,57,115,124,105,214,211,78,59,13,191,71,100,113,43,42,240,188,243,206,
2443 243,229,24,160,172,118,127,138,39,16,186,221,14,41,241,47,5,65,17,99,202,
2444 45,101,245,162,230,239,191,255,254,1,207,207,17,178,35,241,246,53,77,222,
2445 65,8,239,205,215,29,16,219,49,199,31,116,208,65,195,130,208,252,22,111,
2446 182,35,222,210,23,27,27,235,118,54,224,73,195,130,144,85,111,191,253,182,
2447 219,74,99,167,102,179,64,140,2,225,175,202,206,206,118,251,29,72,189,246,
2448 223,127,255,69,139,22,9,119,16,121,1,97,117,117,53,35,65,70,185,196,80,
2449 244,17,132,76,238,220,154,15,68,223,98,210,42,211,57,213,209,209,1,56,189,
2450 16,139,230,103,142,169,221,2,224,59,8,25,192,47,191,252,178,249,212,141,
2451 38,250,226,41,167,156,162,217,119,47,32,100,109,84,84,148,217,75,230,216,
2452 206,58,235,44,179,145,210,64,136,233,57,201,221,123,207,111,184,225,6,51,
2453 254,5,8,201,197,33,153,79,163,177,175,11,46,184,192,92,28,61,8,219,218,
2454 218,62,254,248,99,183,103,243,52,177,23,195,61,120,6,141,8,132,88,144,101,
2455 203,150,153,223,67,164,215,145,71,30,41,62,192,36,132,179,238,182,170,233,
2456 114,191,251,221,239,204,187,214,64,136,114,115,115,255,250,215,191,122,
2457 153,37,80,63,204,180,180,71,140,125,4,33,238,154,219,119,81,130,22,243,
2458 105,106,228,7,8,81,82,82,146,249,230,41,154,149,93,155,205,186,30,132,52,
2459 43,222,176,247,102,229,80,189,55,171,16,221,210,124,134,217,32,156,84,220,
2460 29,13,102,110,65,136,207,125,225,133,23,154,27,130,195,208,223,132,213,
2461 210,210,242,212,83,79,121,25,221,244,43,28,56,253,35,225,102,16,162,17,
2462 129,176,180,180,212,109,135,228,128,205,215,216,232,117,195,130,208,124,
2463 247,13,171,196,185,119,204,23,230,200,92,63,28,140,249,234,41,242,5,132,
2464 149,149,149,230,171,93,84,245,229,151,95,174,174,17,14,47,236,245,220,185,
2465 115,49,214,98,226,128,168,107,254,210,72,84,49,214,1,188,137,105,178,16,
2466 32,196,121,103,58,166,23,253,24,219,77,74,166,249,50,202,37,237,26,33,206,
2467 153,140,210,233,47,127,249,139,216,44,42,40,40,96,143,114,197,230,162,251,
2468 154,95,1,131,101,164,7,92,115,205,53,216,116,14,158,3,22,226,55,221,244,
2469 205,55,223,164,183,105,103,83,41,194,35,143,60,34,55,167,147,219,7,234,
2470 217,242,234,213,171,129,25,238,172,97,203,140,118,122,112,85,85,149,182,
2471 101,70,172,220,150,78,48,88,128,144,25,43,134,12,207,91,219,14,181,247,
2472 236,179,207,70,71,71,227,61,203,212,46,81,76,1,66,54,142,207,116,221,117,
2473 215,49,224,69,46,140,194,131,15,62,136,229,101,42,42,83,187,132,187,35,
2474 250,52,251,162,14,207,61,247,92,109,95,100,231,240,226,227,227,153,205,
2475 200,212,46,97,232,197,248,23,162,126,200,139,57,6,180,34,187,232,3,252,
2476 6,216,207,61,247,156,184,66,236,69,128,144,9,169,220,186,75,148,72,188,
2477 1,203,44,142,22,126,83,21,76,141,181,3,70,252,38,227,77,55,221,4,141,180,
2478 74,22,194,182,50,251,161,71,105,41,129,229,154,53,107,232,165,230,93,95,
2479 118,217,101,50,155,83,52,199,151,95,126,137,31,175,85,169,16,41,169,49,
2480 220,205,141,27,55,106,70,156,93,211,208,98,59,154,168,67,226,69,2,33,14,
2481 15,243,253,175,127,253,139,189,139,173,113,72,204,237,136,196,46,203,108,
2482 58,9,16,50,107,148,203,58,221,113,199,29,98,155,102,177,23,154,134,153,
2483 147,86,75,20,225,63,255,249,15,51,140,125,246,217,71,230,119,9,75,170,127,
2484 16,130,102,5,222,183,220,114,139,185,89,233,219,84,166,152,66,249,34,176,
2485 250,213,87,95,97,166,201,59,100,38,116,134,130,86,190,253,246,219,49,196,
2486 122,67,65,97,233,180,242,176,92,98,38,199,118,158,124,242,73,142,103,168,
2487 36,206,35,161,165,152,145,155,219,154,49,8,132,180,35,23,226,55,141,142,
2488 201,18,231,81,53,177,17,185,15,157,12,167,70,153,123,81,106,185,206,165,
2489 253,246,219,79,204,213,56,0,126,92,127,253,245,218,238,248,65,213,81,129,
2490 39,158,120,162,76,237,210,97,135,29,38,64,104,110,77,6,184,120,160,30,143,
2491 80,70,185,68,133,136,83,163,136,236,143,61,246,24,85,167,237,235,140,51,
2492 206,192,44,252,227,31,255,144,169,117,210,186,135,185,159,79,115,125,185,
2493 26,53,54,54,222,119,223,125,88,81,109,155,80,144,186,253,253,239,127,47,
2494 83,187,196,65,234,167,17,227,37,11,129,80,83,76,76,204,7,31,124,128,51,
2495 196,24,131,34,223,126,251,173,184,232,109,22,221,221,32,237,4,133,92,222,
2496 92,98,149,47,194,239,244,36,153,194,157,192,192,250,245,235,233,97,159,
2497 127,254,57,188,196,242,106,22,77,47,58,186,60,32,157,228,58,15,98,203,177,
2498 177,177,108,147,45,51,203,139,136,136,0,174,114,221,72,68,174,13,27,54,
2499 124,253,245,215,191,252,242,203,136,250,95,78,78,206,130,5,11,190,251,238,
2500 59,109,110,43,143,123,115,137,85,66,236,11,179,78,243,49,255,29,150,94,
2501 102,49,9,192,139,253,225,135,31,230,204,153,195,120,166,200,194,124,143,
2502 157,104,151,228,228,100,42,25,247,133,146,2,54,198,179,92,231,78,80,97,
2503 233,210,165,20,16,179,165,117,60,223,85,84,84,132,65,196,166,35,154,67,
2504 176,13,138,99,131,244,221,70,214,236,230,146,235,54,23,199,95,86,86,198,
2505 33,177,65,10,34,250,42,7,38,243,232,36,210,251,167,246,246,118,154,21,127,
2506 194,191,102,165,17,245,205,10,245,41,178,92,55,66,225,113,98,40,94,121,
2507 229,21,12,197,27,111,188,65,175,22,23,86,71,36,230,10,11,23,46,100,204,
2508 178,53,183,163,85,19,211,235,181,107,215,82,240,47,190,248,98,201,146,37,
2509 12,4,183,233,101,21,111,46,3,92,125,17,89,178,178,178,104,77,198,59,128,
2510 97,35,114,133,7,137,29,25,228,101,149,254,144,248,77,61,208,243,169,7,202,
2511 229,221,202,249,174,146,146,146,159,126,250,137,105,31,219,20,3,68,238,
2512 123,115,137,196,227,43,43,130,80,73,41,108,101,6,161,146,146,210,88,75,
2513 129,80,73,201,66,82,32,84,82,10,188,20,8,149,148,44,36,5,66,37,165,192,
2514 75,129,80,73,201,66,82,32,84,82,10,188,20,8,149,148,44,36,5,66,37,165,192,
2515 75,129,80,73,201,66,82,32,84,82,10,188,20,8,149,148,44,36,5,66,37,165,192,
2516 75,129,80,73,201,66,82,32,84,82,10,188,20,8,149,148,172,162,254,254,254,
2517 230,230,230,168,168,168,182,182,54,63,30,193,86,82,82,242,79,10,132,74,
2518 74,227,41,128,215,218,218,90,90,90,186,105,211,166,200,200,200,136,136,
2519 136,245,235,215,243,151,223,133,133,133,149,149,149,117,117,117,10,138,
2520 74,74,99,42,5,66,37,165,241,81,111,111,47,144,131,127,41,41,41,197,197,
2521 197,48,15,71,176,187,187,27,236,181,183,183,227,26,54,54,54,230,229,229,
2522 37,36,36,68,71,71,87,85,85,141,245,27,230,148,148,194,86,10,132,74,74,129,
2523 86,95,95,95,117,117,117,106,106,42,142,32,204,243,254,158,82,120,89,83,
2524 83,19,19,19,19,31,31,95,80,80,96,145,119,51,42,41,133,146,20,8,149,148,
2525 2,42,192,150,149,149,133,171,167,255,38,201,176,2,150,176,51,34,34,2,223,
2526 209,143,23,124,43,41,41,121,145,2,161,146,82,224,212,221,221,157,147,147,
2527 131,35,232,31,204,128,104,110,110,238,166,77,155,70,235,251,0,74,74,74,
2528 72,129,80,73,41,64,130,130,41,41,41,229,229,229,91,226,210,245,247,247,
2529 23,21,21,229,231,231,143,244,28,105,93,93,93,161,83,248,148,237,237,237,
2530 34,178,182,182,86,191,29,14,172,170,170,170,164,164,68,124,228,139,181,
2531 164,175,168,168,208,184,11,137,89,212,190,192,215,208,208,64,250,198,198,
2532 198,150,150,22,22,113,112,197,201,94,126,179,133,166,166,38,103,42,165,
2533 255,223,222,185,54,165,145,132,97,244,255,255,165,88,101,188,113,21,48,
2534 32,32,72,68,238,33,10,137,128,17,48,169,202,158,226,237,237,154,29,98,228,
2535 146,65,118,247,57,31,168,238,153,183,123,154,79,167,158,161,103,16,251,
2536 142,68,40,196,46,192,37,216,11,11,110,191,5,20,117,145,11,209,225,90,83,
2537 61,60,60,32,45,70,165,82,41,188,133,210,16,94,60,30,15,238,193,233,247,
2538 251,133,66,129,117,114,138,5,159,158,158,246,122,189,193,96,224,101,137,
2539 222,56,216,110,183,185,52,48,60,147,201,144,80,1,137,50,109,50,153,228,
2540 18,84,82,131,113,109,148,16,123,142,68,40,196,46,248,252,249,179,217,194,
2541 245,183,3,141,37,18,9,20,229,250,171,129,186,240,19,32,54,210,30,162,66,
2542 99,65,17,18,88,137,119,156,197,130,147,201,196,255,225,184,7,17,102,179,
2543 89,219,179,131,89,175,174,174,24,130,95,75,165,210,124,62,231,11,98,122,
2544 36,202,217,98,177,168,68,40,254,45,72,132,66,68,206,120,60,38,135,253,89,
2545 49,144,222,112,146,207,106,171,64,49,105,207,110,108,162,100,188,200,12,
2546 65,17,30,28,28,32,63,114,30,58,196,148,196,187,163,163,163,122,189,238,
2547 175,130,8,49,28,34,124,124,124,68,123,152,56,159,207,19,4,47,47,47,249,
2548 142,156,98,114,68,72,59,157,78,163,70,27,37,196,158,35,17,10,17,45,248,
2549 198,164,229,250,1,16,12,30,66,36,248,99,131,176,120,126,126,62,28,14,93,
2550 103,5,184,74,185,92,14,186,51,36,194,119,239,222,145,92,73,120,136,141,
2551 53,211,160,184,213,106,17,254,172,0,17,86,42,149,219,219,219,94,175,135,
2552 32,209,33,34,68,120,76,75,49,106,164,30,17,146,53,131,250,20,98,207,145,
2553 8,133,136,22,60,145,201,100,80,136,235,255,13,158,192,28,36,167,247,239,
2554 223,19,194,186,221,174,59,177,50,4,178,144,216,126,15,174,194,79,174,179,
2555 32,36,194,92,46,71,108,69,174,216,142,6,226,100,114,180,231,179,44,223,
2556 162,90,173,34,75,76,201,226,25,107,34,228,8,113,16,59,98,125,139,137,28,
2557 161,109,163,132,216,115,36,66,33,162,133,104,133,51,150,173,128,48,142,
2558 143,143,219,237,54,34,225,51,22,139,221,223,223,187,115,171,241,252,252,
2559 140,165,38,147,137,235,191,6,122,195,79,174,179,192,68,104,38,35,146,34,
2560 60,12,199,193,78,167,131,14,105,208,197,157,92,200,234,77,132,211,233,52,
2561 149,74,145,20,25,104,34,132,100,50,105,190,36,224,18,85,125,136,20,98,255,
2562 145,8,133,136,22,68,178,188,171,197,28,214,104,52,188,32,241,10,254,88,
2563 14,142,191,129,177,165,82,105,245,187,163,8,44,244,0,34,153,143,73,56,104,
2564 59,104,104,179,128,241,120,108,109,26,88,13,201,185,234,197,47,139,136,
2565 147,83,12,100,148,53,248,228,20,3,237,238,46,99,105,175,158,83,133,120,
2566 115,36,66,33,162,133,56,136,81,92,231,111,72,90,137,68,34,168,61,212,136,
2567 8,107,181,154,121,101,69,8,121,204,239,58,155,130,192,176,221,90,215,21,
2568 226,191,132,68,40,68,180,160,183,96,168,130,201,100,18,139,197,66,49,17,
2569 15,53,155,205,227,227,99,255,180,251,42,244,251,253,106,181,234,58,66,136,
2570 141,144,8,133,136,144,239,223,191,135,68,136,240,174,175,175,115,185,220,
2571 242,93,80,66,97,58,157,46,149,74,171,239,32,29,14,135,39,39,39,174,35,132,
2572 216,8,137,80,136,8,121,122,122,202,102,179,193,95,230,16,225,151,47,95,
2573 66,155,86,60,36,188,179,179,179,95,238,52,177,200,200,88,215,95,48,30,143,
2574 79,79,79,67,137,83,8,177,22,18,161,16,209,18,18,225,171,196,227,241,106,
2575 181,186,28,10,103,179,25,225,47,244,115,35,221,68,34,225,58,66,136,141,
2576 144,8,133,136,150,124,62,191,214,207,126,100,62,92,184,252,80,68,169,84,
2577 42,22,139,33,65,82,220,110,183,93,231,5,200,139,181,90,173,94,175,163,82,
2578 123,47,26,224,218,160,83,105,95,95,95,91,220,164,254,230,230,134,154,225,
2579 112,232,119,208,220,223,223,247,122,61,219,11,74,65,171,213,178,183,120,
2580 251,245,176,96,38,167,158,154,78,167,67,20,182,227,66,236,63,18,161,16,
2581 209,178,214,19,14,64,124,196,157,104,201,245,23,32,170,179,179,179,208,
2582 125,81,192,112,248,201,117,126,5,90,42,151,203,200,18,243,85,42,21,28,134,
2583 149,153,167,80,40,140,22,127,25,1,207,139,191,72,164,6,1,115,117,124,102,
2584 242,246,143,15,2,235,73,165,82,166,55,190,206,225,225,33,182,35,140,250,
2585 103,31,27,141,70,191,223,71,132,12,79,167,211,219,239,101,21,98,103,72,
2586 132,66,68,11,134,88,247,73,121,156,116,116,116,100,47,106,161,139,126,144,
2587 80,232,165,48,64,26,179,119,161,185,254,175,160,6,89,162,183,193,96,128,
2588 146,241,34,115,118,187,93,86,229,195,156,197,65,106,72,156,148,97,56,123,
2589 136,222,199,65,224,72,46,151,67,114,140,34,14,218,187,182,169,228,32,101,
2590 166,82,230,161,205,226,111,111,111,145,174,89,147,50,190,126,208,169,66,
2591 236,27,18,161,16,209,130,60,16,67,80,42,175,130,147,16,143,253,11,18,118,
2592 65,54,4,184,229,155,141,148,33,164,229,221,167,203,224,33,84,135,255,76,
2593 90,88,138,85,185,115,139,21,146,23,113,36,53,120,139,179,40,243,230,230,
2594 230,235,215,175,126,217,124,5,142,144,243,200,148,87,87,87,116,169,100,
2595 42,66,33,11,35,35,114,138,245,48,137,189,122,155,98,123,203,154,189,61,
2596 142,227,54,143,16,123,136,68,40,68,180,96,142,108,54,187,214,207,132,64,
2597 240,34,111,101,50,25,116,136,99,150,45,8,20,32,45,31,236,94,130,130,102,
2598 179,201,36,22,203,70,163,81,62,159,15,154,41,36,66,172,198,106,249,68,198,
2599 190,12,243,17,236,80,50,199,201,124,132,66,42,241,28,51,227,57,206,178,
2600 24,186,119,119,119,7,7,7,23,23,23,177,88,204,2,40,89,118,21,85,11,241,134,
2601 72,132,66,68,14,130,41,151,203,175,26,43,4,94,177,29,40,174,255,79,176,
2602 90,173,86,67,60,174,255,2,76,130,183,236,215,65,59,130,192,88,143,181,13,
2603 180,135,8,113,45,194,70,147,64,182,35,14,146,234,130,34,228,8,3,201,160,
2604 131,193,128,57,77,132,172,144,180,106,129,213,180,199,146,72,177,20,19,
2605 28,153,57,157,78,79,167,83,155,68,136,253,68,34,20,34,114,240,10,9,105,
2606 121,171,203,54,144,204,206,207,207,95,149,43,162,58,60,60,36,86,162,40,
2607 52,134,171,80,154,255,89,17,165,177,42,38,193,121,241,120,220,254,203,130,
2608 180,71,155,84,135,131,81,157,85,146,252,112,27,217,238,228,228,4,177,145,
2609 2,109,107,12,245,168,17,143,82,131,2,139,197,162,213,115,138,121,240,37,
2610 161,86,34,20,123,142,68,40,196,46,64,27,118,171,208,245,183,3,189,33,54,
2611 92,232,250,47,131,144,208,176,97,87,71,123,94,111,118,11,212,14,82,96,90,
2612 181,33,20,251,50,240,163,108,18,218,254,44,167,252,64,107,24,214,253,83,
2613 95,89,136,232,144,8,133,216,5,40,129,188,85,169,84,112,140,59,180,41,179,
2614 217,12,167,146,201,92,127,11,230,11,92,71,136,255,43,18,161,16,59,226,219,
2615 183,111,201,100,242,195,135,15,219,184,16,111,101,179,89,255,100,133,16,
2616 98,123,36,66,33,118,199,116,58,77,36,18,228,66,219,192,185,46,100,65,44,
2617 216,126,237,85,50,66,136,181,144,8,133,216,41,79,79,79,197,98,241,242,242,
2618 242,241,241,113,245,104,72,165,61,17,255,251,247,200,8,33,54,64,34,20,98,
2619 215,252,248,241,227,211,167,79,241,120,188,94,175,175,178,225,101,52,26,
2620 93,92,92,212,106,53,123,117,139,59,42,132,248,67,72,132,66,188,13,132,188,
2621 106,181,154,76,38,155,205,102,191,223,71,114,100,196,231,5,179,217,108,
2622 50,153,220,221,221,117,187,221,143,31,63,230,243,121,92,40,5,10,17,17,18,
2623 161,16,111,9,206,235,245,122,173,86,235,122,65,163,209,40,20,10,132,63,
2624 107,119,58,157,135,135,7,61,129,32,68,164,72,132,66,188,61,254,145,59,152,
2625 207,231,124,210,85,4,20,98,23,252,252,249,23,247,22,197,121,219,202,139,
2626 117,0,0,0,0,73,69,78,68,174,66,96,130};
2627 
2628 static size_t xml_res_size_1 = 242;
2629 static unsigned char xml_res_file_1[] = {
2630 60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101,
2631 110,99,111,100,105,110,103,61,34,85,84,70,45,56,34,63,62,10,60,114,101,
2632 115,111,117,114,99,101,32,120,109,108,110,115,61,34,104,116,116,112,58,
2633 47,47,119,119,119,46,119,120,119,105,100,103,101,116,115,46,111,114,103,
2634 47,119,120,120,114,99,34,62,10,32,32,60,33,45,45,32,72,97,110,100,108,101,
2635 114,32,71,101,110,101,114,97,116,105,111,110,32,105,115,32,79,78,32,45,
2636 45,62,10,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,
2637 120,66,105,116,109,97,112,34,32,110,97,109,101,61,34,65,98,111,117,116,
2638 50,48,49,55,34,62,80,114,111,112,101,114,116,105,101,115,70,111,114,109,
2639 66,105,116,109,97,112,115,46,99,112,112,36,100,97,116,97,95,105,109,97,
2640 103,101,115,95,65,98,111,117,116,50,48,49,55,46,112,110,103,60,47,111,98,
2641 106,101,99,116,62,10,60,47,114,101,115,111,117,114,99,101,62,10};
2642 
2643 void wxCDAD0InitBitmapResources()
2644 {
2645 
2646  // Check for memory FS. If not present, load the handler:
2647  {
2648  wxMemoryFSHandler::AddFile(wxT("XRC_resource/dummy_file"), wxT("dummy one"));
2649  wxFileSystem fsys;
2650  wxFSFile *f = fsys.OpenFile(wxT("memory:XRC_resource/dummy_file"));
2651  wxMemoryFSHandler::RemoveFile(wxT("XRC_resource/dummy_file"));
2652  if (f) delete f;
2653  else wxFileSystem::AddHandler(new wxMemoryFSHandlerBase);
2654  }
2655 
2656  XRC_ADD_FILE(wxT("XRC_resource/PropertiesFormBitmaps.cpp$data_images_About2017.png"), xml_res_file_0, xml_res_size_0, wxT("image/png"));
2657  XRC_ADD_FILE(wxT("XRC_resource/PropertiesFormBitmaps.cpp$C__Users_NDSE-69_Documents_GitHub_PSP_Project_PropertiesFormBitmaps.xrc"), xml_res_file_1, xml_res_size_1, wxT("text/xml"));
2658  wxXmlResource::Get()->Load(wxT("memory:XRC_resource/PropertiesFormBitmaps.cpp$C__Users_NDSE-69_Documents_GitHub_PSP_Project_PropertiesFormBitmaps.xrc"));
2659 }
+
1 //
2 // This file was automatically generated by wxrc, do not edit by hand.
3 //
4 
5 #include <wx/wxprec.h>
6 
7 #ifdef __BORLANDC__
8  #pragma hdrstop
9 #endif
10 
11 #include <wx/filesys.h>
12 #include <wx/fs_mem.h>
13 #include <wx/xrc/xmlres.h>
14 #include <wx/xrc/xh_all.h>
15 
16 #if wxCHECK_VERSION(2,8,5) && wxABI_VERSION >= 20805
17  #define XRC_ADD_FILE(name, data, size, mime) \
18  wxMemoryFSHandler::AddFileWithMimeType(name, data, size, mime)
19 #else
20  #define XRC_ADD_FILE(name, data, size, mime) \
21  wxMemoryFSHandler::AddFile(name, data, size)
22 #endif
23 
24 static size_t xml_res_size_0 = 52890;
25 static unsigned char xml_res_file_0[] = {
26 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,2,88,0,0,1,138,8,2,0,
27 0,0,95,26,168,50,0,0,0,1,115,82,71,66,0,174,206,28,233,0,0,0,4,103,65,77,
28 65,0,0,177,143,11,252,97,5,0,0,0,9,112,72,89,115,0,0,14,195,0,0,14,195,
29 1,199,111,168,100,0,0,0,25,116,69,88,116,83,111,102,116,119,97,114,101,
30 0,112,97,105,110,116,46,110,101,116,32,52,46,48,46,49,55,51,110,159,99,
31 0,0,206,10,73,68,65,84,120,94,236,157,7,152,27,197,253,247,99,12,24,3,54,
32 152,222,59,9,157,80,67,239,161,5,18,146,208,33,148,208,75,32,188,127,106,
33 32,128,68,53,216,96,211,139,193,52,3,38,128,43,24,247,118,189,247,234,235,
34 189,247,94,244,126,78,51,90,214,187,146,78,39,223,233,86,210,124,159,121,
35 238,180,179,51,187,59,237,247,153,223,214,223,56,148,148,148,148,148,148,
36 194,88,10,132,193,167,238,30,25,148,148,148,44,165,30,215,216,84,195,51,
37 184,164,64,24,124,250,37,209,177,36,118,40,180,119,202,24,37,37,37,43,168,
38 190,81,142,205,159,226,100,140,210,24,105,112,80,134,81,145,255,32,108,
39 110,149,161,191,95,198,40,5,70,140,177,5,81,67,161,173,67,198,40,5,181,
40 58,58,135,198,81,75,171,163,183,87,198,40,5,169,234,27,228,216,92,28,35,
41 99,148,198,66,237,29,142,172,34,71,90,129,163,162,118,116,88,232,63,8,151,
42 39,56,126,137,31,10,12,96,165,64,74,129,48,196,180,169,108,104,28,173,76,
43 116,212,54,200,24,165,32,149,2,97,96,84,215,40,205,96,122,129,99,96,64,
44 70,110,137,252,7,225,66,103,123,19,154,154,101,140,82,96,164,64,24,98,202,
45 43,25,106,77,76,103,117,157,140,81,10,82,41,16,6,70,10,132,74,10,132,161,
46 38,5,194,144,145,2,97,96,164,64,168,164,64,24,106,82,32,12,25,41,16,6,70,
47 10,132,74,10,132,161,38,5,194,144,145,2,97,96,164,64,168,164,64,24,106,
48 82,32,12,25,41,16,6,70,10,132,74,10,132,161,38,5,194,144,145,2,97,96,164,
49 64,168,164,64,24,106,82,32,12,25,41,16,6,70,10,132,74,10,132,161,38,5,194,
50 144,145,2,97,96,164,64,168,164,64,24,106,82,32,12,25,41,16,6,70,10,132,
51 74,10,132,161,38,5,194,144,145,2,97,96,164,64,168,164,64,24,106,82,32,12,
52 25,41,16,6,70,10,132,74,10,132,161,38,5,194,144,145,2,97,96,164,64,168,
53 164,64,24,106,82,32,12,25,41,16,6,70,10,132,142,158,158,158,198,198,198,
54 134,134,134,254,112,253,254,147,2,97,136,73,129,48,100,164,64,24,24,133,
55 59,8,123,123,123,55,109,218,180,110,221,186,181,107,215,242,99,96,84,234,
56 32,216,164,64,24,98,82,32,12,25,41,16,6,70,225,14,194,214,214,214,168,168,
57 40,40,40,212,210,210,34,87,184,4,26,113,25,73,86,235,20,176,108,106,106,
58 98,177,175,175,79,166,240,44,210,136,140,5,5,5,249,249,249,252,96,251,237,
59 237,237,86,115,61,21,8,67,76,10,132,33,35,107,130,16,147,216,217,217,89,
60 87,87,87,85,85,149,155,155,203,95,12,93,87,87,151,92,237,89,56,30,36,171,
61 175,175,175,174,174,38,99,101,101,37,25,209,184,123,32,10,132,155,129,176,
62 177,177,81,174,112,170,163,163,35,51,51,51,50,50,146,52,144,140,102,43,
63 47,47,79,76,76,140,136,136,136,143,143,167,45,7,61,124,204,152,198,166,
64 153,201,40,82,242,187,162,162,162,180,180,52,38,38,134,24,226,201,43,147,
65 90,64,10,132,33,38,5,194,144,145,213,64,200,36,30,83,134,61,196,142,101,
66 101,101,49,197,103,17,247,128,69,68,60,22,85,38,221,92,160,14,94,70,71,
67 71,147,12,163,74,22,50,146,29,219,72,12,38,17,58,118,119,119,203,212,1,
68 87,184,131,144,169,77,122,122,58,237,135,104,21,25,235,68,96,81,81,81,114,
69 114,50,179,30,183,205,195,132,40,47,47,15,200,209,156,250,169,16,241,180,
70 49,192,99,179,248,127,102,82,146,128,29,145,145,62,65,2,43,120,135,10,132,
71 33,38,5,194,144,145,69,64,136,29,195,12,50,125,207,206,206,46,44,44,196,
72 226,153,79,137,225,237,53,53,53,37,37,37,193,54,126,104,150,141,31,181,
73 181,181,105,105,105,184,16,13,13,13,36,19,241,154,216,84,115,115,51,25,
74 217,56,86,215,151,147,109,163,46,117,179,204,80,251,181,59,165,53,64,77,
75 77,13,205,166,111,75,79,162,115,224,38,166,164,164,136,115,170,109,109,
76 109,52,39,156,27,214,217,7,192,204,143,216,75,106,106,234,184,52,188,94,
77 10,132,33,38,5,194,144,145,69,64,136,49,132,82,229,229,229,204,227,61,157,
78 6,19,194,238,145,24,103,0,97,63,49,110,57,57,57,248,12,141,141,141,222,
79 77,34,155,5,135,80,54,35,35,35,240,174,161,2,161,81,80,16,239,16,143,80,
80 46,251,32,218,56,54,54,150,140,113,113,113,56,248,222,59,138,94,244,170,
81 200,200,72,124,199,241,245,11,21,8,67,76,10,132,33,35,43,128,16,39,1,251,
82 230,246,252,150,39,97,208,240,11,75,75,75,161,32,4,245,125,174,207,46,192,
83 109,102,102,102,128,77,162,2,225,102,98,74,130,151,54,34,10,10,225,23,174,
84 93,187,182,172,172,76,46,251,172,174,174,174,132,132,132,146,146,18,223,
85 59,217,168,75,129,48,196,164,64,24,50,26,119,16,226,222,97,160,26,26,26,
86 228,178,207,98,150,31,19,19,51,82,167,2,225,56,226,23,226,30,232,47,57,
87 141,181,20,8,127,85,107,107,107,82,82,146,56,201,57,82,37,38,38,22,23,23,
88 243,215,15,167,158,30,195,126,43,42,42,228,114,192,165,64,24,98,82,32,12,
89 25,141,47,8,113,203,112,206,96,161,92,246,89,76,235,139,138,138,242,243,
90 243,225,25,78,130,140,245,89,226,206,154,188,188,60,239,103,83,71,81,10,
91 132,82,180,92,92,92,156,225,174,81,31,85,95,95,207,164,137,45,192,51,154,
92 95,198,142,68,226,70,172,192,159,25,23,82,32,12,49,41,16,134,140,198,23,
93 132,109,109,109,57,57,57,126,156,165,236,235,235,203,206,206,38,59,22,213,
94 191,243,156,100,129,163,126,156,156,243,79,10,132,82,117,117,117,25,25,
95 25,114,97,36,162,201,161,96,123,123,59,191,241,237,162,163,163,249,43,86,
96 249,46,54,2,68,75,75,75,199,229,4,169,2,97,136,73,129,48,100,52,142,32,
97 236,234,234,130,97,24,70,185,60,18,149,148,148,100,101,101,225,207,97,217,
98 210,210,210,252,115,48,112,10,113,40,3,99,18,21,8,135,68,131,49,127,241,
99 244,4,140,119,137,167,236,181,214,42,44,44,244,227,84,0,18,119,156,246,
100 244,244,200,229,0,74,129,48,196,164,64,24,50,26,71,16,138,123,0,253,56,
101 57,137,33,141,137,137,209,78,168,86,87,87,179,40,126,143,72,24,67,14,32,
102 48,87,10,3,10,194,161,9,66,127,159,33,104,171,22,71,118,45,142,108,35,52,
103 52,74,63,186,163,187,163,186,169,90,31,26,90,26,6,6,61,31,230,96,191,163,
104 215,159,90,235,237,237,205,203,203,243,3,66,240,15,255,189,166,166,70,46,
105 59,121,6,83,253,59,153,192,49,248,116,118,20,232,246,25,159,197,241,174,
106 182,206,182,162,234,34,125,168,109,170,21,240,230,80,87,199,212,255,18,
107 81,71,104,109,147,205,65,187,52,119,54,235,67,123,119,251,184,120,171,163,
108 35,142,220,213,211,66,67,189,125,189,45,157,45,134,54,146,235,134,64,216,
109 191,40,178,123,105,116,79,117,157,28,44,140,175,238,222,238,238,158,205,
110 130,88,165,52,238,162,117,12,146,43,134,64,136,97,28,178,138,75,162,101,
111 7,102,24,214,183,212,27,12,99,103,183,207,103,161,24,11,189,221,190,24,
112 251,132,132,132,250,250,122,185,48,18,53,55,55,199,199,199,203,5,167,117,
113 141,142,142,246,143,103,165,165,165,197,197,197,114,193,71,1,136,1,247,
114 230,215,208,255,25,17,90,85,215,53,14,46,139,237,89,20,217,147,81,48,168,
115 213,141,121,200,248,110,216,189,129,176,160,166,32,58,63,90,31,242,202,
116 243,104,87,113,58,120,205,186,24,241,122,151,204,204,60,168,64,124,94,85,
117 222,130,228,5,250,16,147,23,163,177,211,141,186,154,29,5,171,29,85,201,
118 142,238,145,185,54,52,82,70,70,134,31,244,26,58,200,188,60,26,94,46,59,
119 207,142,102,101,101,113,252,114,217,103,209,36,226,65,84,185,236,69,244,
120 227,210,228,161,98,118,182,250,104,223,169,121,67,77,166,20,167,244,15,
121 80,226,126,220,89,241,170,85,148,158,158,14,200,73,95,211,92,99,72,191,
122 33,119,67,79,239,56,120,171,163,163,254,94,71,101,186,163,42,197,225,187,
123 189,176,182,202,107,203,23,165,44,50,180,145,88,213,222,222,158,144,144,
124 182,102,93,252,218,245,241,121,249,133,162,87,55,181,54,69,230,70,174,203,
125 90,167,15,125,3,161,50,57,232,108,115,180,143,199,5,149,209,16,6,45,187,
126 34,59,161,40,65,31,90,58,134,110,217,99,90,156,153,153,43,198,230,154,245,
127 41,229,229,229,88,9,210,71,229,70,25,154,158,1,238,211,60,181,171,221,81,
128 149,238,40,140,28,170,49,175,162,219,196,197,197,249,119,146,12,199,192,
129 112,86,12,143,208,191,83,172,108,10,163,36,23,134,21,53,208,214,228,168,
130 72,118,52,253,234,153,232,181,62,123,189,190,255,111,204,217,88,223,60,
131 68,122,106,181,176,176,108,221,134,132,53,235,18,98,227,179,154,92,246,
132 60,34,55,66,159,158,80,89,231,235,217,62,111,32,76,42,77,50,180,95,74,65,
133 10,237,215,209,209,17,165,123,207,25,118,185,170,170,202,79,16,102,47,24,
134 10,121,63,59,106,243,135,234,197,55,65,50,255,64,72,13,130,112,253,69,65,
135 250,46,51,41,63,110,123,161,188,48,201,167,41,24,32,44,88,239,44,230,79,
136 142,154,92,71,203,240,89,60,129,176,165,165,101,253,250,245,178,222,157,
137 42,44,44,36,125,8,130,176,56,66,118,140,186,2,223,59,134,101,229,5,132,
138 177,177,177,178,45,215,174,165,113,133,1,98,192,255,148,246,147,33,189,
139 183,161,228,69,61,173,142,186,44,71,109,134,37,66,105,172,35,233,19,71,
140 252,7,142,156,101,142,26,211,90,115,104,200,119,12,140,236,108,202,88,11,
141 231,126,99,238,70,67,211,224,228,177,138,193,168,77,82,17,45,139,169,241,
142 19,132,12,222,234,194,161,254,159,189,208,145,187,116,88,16,178,35,232,
143 165,57,76,35,18,232,170,173,173,149,11,78,21,20,20,248,241,104,25,18,135,
144 225,147,95,209,211,229,40,207,116,228,254,52,84,192,250,114,25,185,185,
145 12,149,182,56,101,113,117,195,80,61,131,27,189,25,140,136,136,16,103,7,
146 151,164,45,49,100,41,174,242,213,61,253,13,62,141,39,197,108,138,49,108,
147 55,54,55,182,177,169,49,59,59,91,30,130,75,73,73,73,0,38,46,39,206,144,
148 126,73,226,146,236,220,108,86,25,68,69,23,21,21,85,20,102,73,16,138,144,
149 179,184,189,178,160,164,152,53,195,40,45,45,13,199,206,167,41,213,230,130,
150 157,201,201,201,250,151,6,209,102,169,169,169,122,52,250,174,146,146,146,
151 148,148,20,121,76,158,85,86,144,211,151,185,88,87,204,69,125,101,185,37,
152 67,175,245,150,202,201,201,193,43,133,199,204,233,132,214,38,173,53,212,
153 228,242,164,229,177,113,177,209,209,209,178,198,93,162,230,153,205,101,
154 23,102,27,210,175,72,91,81,90,94,90,29,156,170,171,170,24,40,88,247,107,
155 141,229,46,233,171,43,170,173,169,146,171,131,80,217,69,52,208,162,121,
156 241,11,231,68,45,126,123,227,146,153,235,150,190,182,230,167,149,185,181,
157 75,210,43,94,95,24,249,236,119,27,31,253,122,227,3,95,69,60,244,85,196,
158 75,63,165,206,75,170,250,38,177,112,250,154,21,175,174,254,233,245,181,
159 63,189,177,110,233,123,17,75,230,198,44,42,40,175,168,26,97,29,52,231,71,
160 245,127,122,150,195,62,193,97,255,77,176,133,9,189,111,29,222,153,248,85,
161 103,123,27,195,115,11,213,213,213,197,168,31,21,117,116,118,172,207,89,
162 111,24,110,149,13,149,236,5,107,32,135,165,75,152,202,252,130,124,204,160,
163 33,125,82,254,208,253,234,158,212,81,158,231,200,91,161,245,255,193,156,
164 197,181,133,57,114,157,7,97,15,225,174,31,38,17,118,98,67,12,19,122,40,
165 136,141,149,11,35,17,64,138,140,140,148,199,228,65,45,181,149,142,234,28,
166 71,206,82,173,128,61,229,67,167,214,204,50,84,26,83,201,130,178,2,226,177,
167 153,178,126,93,42,45,29,178,117,144,210,144,37,179,48,83,12,132,97,245,
168 155,161,87,235,120,208,250,12,99,123,47,77,88,154,191,41,159,214,221,176,
169 97,131,60,4,167,152,83,224,149,103,150,102,26,210,111,200,218,208,220,210,
170 220,102,18,133,97,230,219,88,85,164,213,133,163,96,163,163,190,176,167,
171 185,186,161,174,150,85,222,85,92,92,76,93,248,7,194,248,248,120,189,255,
172 39,64,232,223,93,191,128,144,170,96,50,37,15,203,131,26,107,171,6,133,71,
173 56,84,204,13,20,115,160,179,173,163,93,86,5,106,111,111,231,144,244,202,
174 175,204,55,212,100,98,65,34,35,141,173,201,26,119,137,177,87,94,94,158,
175 177,41,195,144,126,117,230,234,146,178,18,86,5,163,170,74,139,122,115,87,
176 254,218,55,74,18,250,234,139,171,42,202,228,234,32,81,105,89,89,108,118,
177 209,188,168,92,251,207,233,55,204,139,57,253,163,13,199,188,19,113,208,
178 155,81,187,189,22,179,227,203,177,219,189,20,183,141,61,110,130,45,254,
179 55,30,194,86,246,184,109,94,136,155,252,82,236,148,87,98,247,124,61,250,
180 176,217,145,39,189,21,125,201,135,177,247,125,151,244,250,242,204,5,241,
181 249,89,5,94,219,183,172,172,106,253,71,237,51,14,52,1,38,8,194,224,75,219,
182 53,205,191,189,56,105,149,115,162,56,10,202,205,205,77,28,37,197,39,198,
183 255,156,252,179,97,184,69,165,68,49,145,221,184,113,163,28,150,46,97,247,
184 171,107,170,215,101,174,51,164,79,45,76,245,98,55,122,155,171,29,117,155,
185 112,12,68,255,31,204,89,210,90,85,34,215,121,16,13,206,1,248,97,18,17,54,
186 4,43,36,23,156,106,104,104,240,207,35,100,162,16,21,21,133,199,38,15,203,
187 164,138,138,138,166,170,18,71,85,150,211,23,148,3,188,49,107,189,68,206,
188 230,50,84,218,194,228,133,81,105,81,196,155,39,28,248,226,212,128,25,132,
189 105,155,210,156,131,97,120,253,134,186,243,164,164,18,227,169,209,164,77,
190 73,204,32,168,38,188,81,121,8,206,83,163,148,144,244,126,157,26,93,56,212,
191 222,53,133,142,190,30,223,207,128,193,81,122,182,31,231,1,200,66,70,136,
192 34,151,93,32,132,61,114,217,103,81,94,154,132,130,203,101,47,162,6,74,98,
193 112,4,29,133,107,135,174,134,250,80,76,79,167,70,153,216,14,249,139,46,
194 81,243,248,214,28,73,77,147,251,83,163,67,173,24,140,162,51,20,69,12,213,
195 216,166,53,142,150,218,161,107,233,114,133,165,53,48,56,216,211,63,208,
196 222,211,159,90,221,241,242,198,202,51,62,201,218,233,213,196,237,95,78,
197 156,244,98,194,68,187,145,115,254,5,192,185,245,11,9,108,112,135,151,19,
198 119,153,158,120,229,215,121,115,147,235,42,90,122,58,123,7,122,251,229,
199 97,12,105,160,111,48,109,158,99,198,238,6,192,4,67,152,224,120,117,71,71,
200 236,91,3,61,29,140,214,209,18,51,96,70,250,168,168,179,171,115,67,206,6,
201 195,112,171,168,175,192,25,202,202,202,146,35,211,169,152,152,24,102,216,
202 126,158,26,101,109,127,239,16,48,48,143,48,99,184,83,163,16,72,156,137,
203 149,203,35,17,6,80,92,97,209,132,167,225,223,19,20,88,102,14,67,46,184,
204 147,232,158,67,165,107,174,117,228,46,25,178,255,217,11,7,91,27,68,188,
205 65,134,74,131,115,85,245,67,215,224,0,144,254,20,244,250,245,235,49,140,
206 196,47,73,117,115,106,212,185,165,225,229,207,53,66,122,21,147,172,213,
207 235,18,196,113,228,228,228,211,63,136,47,173,43,141,200,139,208,135,236,
208 178,108,204,183,220,156,89,189,29,142,154,188,161,147,197,35,148,232,115,
209 236,84,46,251,44,14,50,35,35,67,127,179,12,53,152,151,151,231,223,229,70,
210 142,65,60,143,56,140,0,118,253,38,71,219,8,94,122,84,221,92,29,83,16,163,
211 15,5,213,5,236,145,85,244,245,245,17,169,171,215,37,173,90,159,90,81,81,
212 35,142,188,190,165,126,77,230,26,125,72,40,72,8,230,107,132,125,142,234,
213 44,71,67,57,243,20,25,99,97,13,12,58,74,91,122,86,21,182,188,19,87,115,
214 243,143,5,135,191,157,182,213,40,97,207,199,0,26,79,250,40,243,223,191,
215 148,124,153,90,31,83,222,222,218,214,226,136,123,199,241,250,46,38,198,
216 88,62,188,180,141,227,203,63,58,74,35,100,205,90,82,94,174,17,182,182,182,
217 38,38,166,9,171,136,132,97,65,233,197,233,6,195,88,217,232,243,35,91,93,
218 29,206,187,198,134,57,101,197,94,152,34,251,119,179,12,94,90,102,102,166,
219 92,112,90,182,232,232,104,255,64,40,62,91,33,23,134,21,104,168,203,115,
220 20,71,58,218,221,223,114,104,168,100,64,40,174,17,82,88,160,179,206,121,
221 153,48,54,54,190,177,81,102,223,162,107,132,242,191,59,53,181,55,149,55,
222 148,235,131,184,105,71,104,113,100,247,146,136,102,66,83,179,244,204,56,
223 62,122,137,62,12,127,121,223,7,247,200,44,118,84,82,82,226,223,227,19,76,
224 118,244,87,134,219,156,239,98,16,140,25,145,192,112,81,81,17,19,49,185,
225 60,170,226,56,57,36,131,228,58,135,99,89,92,239,162,200,222,69,81,253,218,
226 115,132,84,72,103,119,167,62,116,245,12,77,145,228,234,224,211,224,208,
227 236,193,242,194,7,139,42,109,187,255,167,226,163,223,203,152,54,61,41,192,
228 252,51,135,137,47,36,28,61,115,125,194,7,215,58,94,222,206,200,24,235,135,
229 23,182,114,172,253,175,163,99,179,187,54,44,40,198,90,126,69,126,114,65,
230 178,62,52,182,72,108,212,212,246,173,220,80,188,130,16,89,77,74,98,112,
231 127,12,86,145,224,237,161,50,183,242,97,44,87,58,63,191,42,23,70,34,108,
232 96,84,84,148,230,87,224,197,70,70,70,250,119,181,8,231,82,255,112,154,79,
233 194,241,245,128,9,3,125,42,26,42,58,152,22,56,85,223,216,255,75,76,11,244,
234 201,220,212,173,153,138,134,246,134,250,246,122,125,232,246,249,161,35,
235 111,32,244,174,113,124,160,30,19,95,80,80,224,211,105,73,147,160,32,78,
236 161,198,21,184,232,223,3,245,85,85,85,129,127,231,186,144,122,160,126,28,
237 133,65,234,236,29,168,110,235,253,34,181,254,228,143,50,39,189,152,48,238,
238 252,211,194,110,182,149,159,219,254,212,111,223,202,200,24,139,7,16,248,
239 246,97,67,247,84,123,57,123,100,37,97,127,12,146,43,228,3,245,131,132,192,
240 63,80,223,220,220,28,27,27,235,135,123,64,22,64,168,1,108,211,166,77,27,
241 55,110,20,191,71,164,246,246,246,248,120,252,51,127,92,201,145,74,189,89,
242 70,138,74,199,7,247,227,236,40,8,20,119,184,240,187,171,171,139,174,227,
243 135,87,71,198,172,172,172,234,113,250,108,189,2,225,120,169,177,171,127,
244 126,70,195,205,63,22,236,243,70,138,1,66,227,27,38,216,226,254,96,155,187,
245 210,126,170,145,49,214,15,47,110,227,88,112,243,208,3,30,67,115,140,160,
246 215,248,190,107,52,221,249,202,108,61,152,125,84,69,69,5,206,28,230,20,
247 40,98,18,253,248,120,5,59,45,44,44,44,41,41,145,203,99,44,5,66,41,234,29,
248 167,208,191,79,64,136,153,11,173,158,146,146,226,31,204,154,154,154,162,
249 163,163,245,167,43,3,41,5,194,192,171,127,96,240,127,153,13,184,128,83,
250 94,77,50,64,200,10,225,20,219,231,57,246,3,7,131,238,49,137,25,187,59,82,
251 62,115,116,251,243,1,25,107,106,124,65,216,218,218,42,120,38,151,125,22,
252 206,64,82,82,18,252,171,114,126,126,220,191,45,144,209,191,187,117,252,
253 144,2,225,175,234,238,238,78,76,76,244,239,51,76,120,132,184,116,204,125,
254 252,152,61,181,57,223,50,26,152,51,0,110,165,64,24,72,53,116,246,45,201,
255 109,58,103,110,182,117,78,129,234,195,182,182,168,243,109,239,87,217,119,
256 53,50,198,226,225,197,173,29,31,28,239,40,222,224,203,213,175,32,210,248,
257 130,176,127,232,46,146,161,39,14,71,122,201,6,51,136,51,135,67,185,126,
258 253,122,63,46,21,177,187,178,178,161,167,155,252,32,168,127,82,32,220,76,
259 80,48,35,35,3,255,76,46,251,172,210,210,210,181,107,215,230,231,231,203,
260 101,159,197,156,139,238,226,199,30,71,81,10,132,129,81,125,103,223,59,113,
261 53,231,125,150,179,221,75,137,6,252,88,36,108,111,219,248,180,237,190,38,
262 251,20,35,102,44,30,94,155,230,88,243,140,163,213,159,59,59,44,174,241,
263 5,33,194,51,219,180,105,83,110,110,238,72,153,84,81,81,1,5,35,35,35,13,
264 207,20,14,43,118,148,231,212,24,221,57,232,86,10,132,70,137,179,148,35,
265 242,11,113,255,201,130,83,24,23,23,55,162,147,171,80,48,38,38,166,161,97,
266 232,169,23,25,53,30,82,32,12,128,178,235,58,207,254,52,219,178,8,20,225,
267 101,219,109,93,246,73,70,204,88,60,188,58,213,145,245,157,163,63,104,159,
268 237,241,170,113,7,33,26,112,126,50,30,249,126,237,6,203,182,113,227,70,
269 140,97,113,113,241,72,79,141,146,5,244,6,248,182,65,5,66,55,130,130,201,
270 201,201,180,71,119,183,183,215,141,211,45,58,157,175,216,142,143,143,23,
271 143,18,246,244,244,20,21,21,17,211,216,216,232,165,237,193,94,87,87,151,
272 184,158,236,199,101,228,81,151,2,225,216,105,96,208,81,220,212,253,226,
273 134,202,41,175,88,241,90,160,8,19,108,241,251,218,126,250,194,126,249,160,
274 129,49,22,15,47,77,114,124,125,153,163,62,71,214,117,40,202,10,32,68,88,
275 179,236,236,108,88,88,93,93,237,221,81,195,178,149,151,151,227,18,212,215,
276 215,99,33,17,84,99,177,172,172,204,251,5,63,118,129,49,36,49,134,81,24,
277 79,242,178,145,146,146,18,156,147,177,118,21,20,8,221,171,163,163,3,16,
278 38,37,37,9,170,49,193,17,68,164,61,160,35,139,120,129,57,57,57,249,206,
279 111,48,233,123,6,9,232,43,52,39,40,229,7,76,213,136,200,22,200,75,163,226,
280 245,199,198,198,150,150,150,250,113,107,242,88,72,129,112,140,212,221,55,
281 240,118,108,205,209,239,165,79,180,39,24,216,99,169,240,91,219,15,235,236,
282 39,246,219,39,26,73,99,229,240,234,20,71,204,155,142,174,113,187,178,30,
283 24,89,4,132,8,59,86,87,87,7,14,19,19,19,177,126,88,54,152,39,86,97,199,
284 248,93,91,91,155,153,153,137,221,195,25,208,191,24,4,158,145,0,147,136,
285 107,152,145,145,65,70,141,136,88,78,97,18,217,96,122,122,58,38,23,211,74,
286 122,86,97,72,177,144,226,213,155,17,17,17,254,61,219,230,187,20,8,61,138,
287 150,160,157,196,236,38,210,169,168,168,40,241,3,17,73,219,184,245,23,201,
288 136,160,96,74,74,138,76,173,19,8,100,114,68,207,32,141,204,48,222,82,32,
289 28,117,209,180,185,245,93,23,124,158,51,233,69,75,35,112,130,45,238,247,
290 182,121,5,246,125,131,233,6,209,23,38,56,62,56,206,81,17,239,8,153,207,
291 72,121,150,117,64,40,4,165,196,189,160,210,156,233,4,228,112,12,112,33,
292 220,90,54,34,155,155,155,221,102,132,115,185,185,185,176,83,159,145,29,
293 225,105,12,189,80,199,41,126,203,21,99,35,5,66,159,68,11,209,192,204,122,
294 218,218,218,152,194,140,136,97,76,127,152,4,225,56,178,5,242,202,88,43,
295 73,129,112,116,213,217,55,240,99,118,227,145,239,166,27,168,99,181,48,209,
296 22,251,87,219,107,165,246,61,141,164,177,114,120,117,7,199,194,91,29,205,
297 35,252,88,107,208,202,106,32,212,11,63,1,203,134,48,107,222,207,151,26,
298 68,98,60,63,50,98,81,61,157,21,195,198,230,229,229,73,12,174,93,139,67,
299 41,87,140,141,20,8,149,20,8,71,83,13,157,125,119,45,41,154,106,201,167,
300 3,245,97,43,91,236,99,246,135,106,237,59,27,73,99,229,240,206,225,67,159,
301 23,232,13,163,110,106,101,16,142,181,240,32,179,178,178,54,110,220,8,17,
302 199,250,129,66,5,66,37,247,32,100,70,102,144,92,161,228,65,3,131,131,229,
303 45,61,151,205,203,181,230,3,130,250,176,163,109,195,76,251,141,221,246,
304 109,140,164,177,108,120,113,27,199,156,83,29,53,233,244,75,89,221,225,161,
305 112,6,33,194,236,128,192,0,24,31,5,194,112,87,127,127,255,138,152,166,159,
306 55,150,16,154,154,37,9,219,187,218,51,202,51,244,161,168,182,200,219,119,
307 63,194,94,93,125,3,159,37,215,29,246,86,154,1,57,22,12,123,216,86,124,104,
308 255,107,48,81,112,230,94,142,245,118,71,215,120,62,107,59,94,10,115,16,
309 6,76,10,132,97,173,190,190,190,204,204,204,181,235,228,199,32,227,226,226,
310 196,41,136,154,102,247,223,35,20,185,148,204,154,21,83,109,253,211,161,
311 132,35,108,255,139,180,31,23,76,239,209,126,235,96,71,209,154,161,79,10,
312 132,165,20,8,3,35,5,194,176,86,71,71,71,116,116,180,160,160,80,126,254,
313 208,199,32,43,235,43,13,32,92,159,179,190,179,171,147,85,66,94,30,175,12,
314 55,181,116,247,63,183,174,220,250,167,67,9,191,183,205,75,182,255,206,72,
315 26,203,134,151,39,59,126,188,209,250,223,81,218,66,13,14,14,118,116,119,
316 180,116,181,232,131,246,189,185,250,134,129,69,145,61,132,37,209,161,127,
317 139,236,56,74,129,48,172,85,95,95,47,1,232,18,92,76,77,77,141,76,142,52,
318 128,112,89,202,178,228,180,100,86,9,101,103,103,143,232,62,177,80,85,99,
319 87,223,29,139,139,44,254,140,4,97,107,91,204,141,182,23,242,236,251,27,
320 97,99,217,240,230,126,142,196,15,29,61,35,123,59,87,48,170,215,243,135,
321 121,187,187,187,179,178,242,214,172,139,31,10,27,210,2,240,92,121,216,74,
322 129,48,172,101,246,8,115,115,115,135,222,13,81,87,110,24,153,235,178,215,
323 181,182,183,178,74,136,100,250,239,242,135,167,58,123,7,174,154,159,191,
324 205,11,86,167,224,68,91,204,253,182,39,26,236,83,141,176,177,108,248,252,
325 60,71,93,118,176,124,77,112,11,229,5,132,133,133,133,235,214,173,147,35,
326 115,237,218,248,248,248,177,190,121,50,108,165,64,24,214,234,235,235,203,
327 202,202,210,6,91,98,98,162,143,215,8,55,109,218,196,252,84,46,132,165,138,
328 154,186,255,248,101,238,4,19,117,172,22,166,218,214,253,219,246,255,58,
329 236,65,242,137,249,215,118,118,44,185,203,209,49,182,175,17,25,95,49,232,
330 202,203,203,139,93,42,40,44,88,153,190,210,48,220,178,10,179,160,96,76,
331 76,140,24,152,66,81,81,81,250,55,182,40,141,162,20,8,195,93,189,189,189,
332 203,163,107,151,111,44,35,180,180,202,231,253,155,219,154,179,202,178,244,
333 161,168,186,72,187,110,129,194,28,132,245,29,125,23,127,153,59,209,242,
334 215,5,247,179,45,253,198,126,113,175,125,107,35,111,172,24,38,56,230,156,
335 226,200,255,41,228,239,139,169,172,172,204,201,201,169,169,169,169,117,
336 170,178,170,114,117,230,106,3,8,115,75,114,171,171,171,147,147,147,37,3,
337 157,138,28,249,151,28,148,124,148,2,161,210,80,15,88,24,53,72,208,158,35,
338 28,28,28,28,24,28,208,7,195,197,137,112,6,97,103,239,192,159,191,201,183,
339 254,221,49,211,108,171,151,218,207,26,8,138,27,68,95,156,232,248,242,34,
340 71,83,113,56,60,38,88,234,148,92,240,122,106,148,81,166,63,53,154,148,148,
341 164,46,204,143,145,20,8,149,100,15,32,248,254,102,153,176,5,97,115,87,255,
342 237,139,138,44,254,18,237,173,108,177,167,217,62,141,177,31,109,228,141,
343 37,67,153,125,143,232,239,158,29,232,179,226,219,7,199,66,6,16,246,245,
344 245,37,22,38,226,20,234,67,93,243,208,201,97,86,149,149,213,172,94,151,
345 68,88,179,49,112,159,107,15,67,41,16,42,41,16,250,42,220,149,167,86,149,
346 77,122,201,234,119,199,92,106,155,93,104,223,39,40,222,163,29,105,63,238,
347 84,219,103,123,189,150,48,47,173,94,214,114,168,203,0,194,193,193,193,238,
348 158,238,142,174,14,125,208,61,62,225,88,28,217,75,88,18,163,30,88,26,67,
349 41,16,42,41,16,250,164,222,254,193,183,98,170,39,90,251,30,209,73,182,168,
350 171,108,175,183,216,119,48,240,198,130,161,195,190,221,44,219,13,83,108,
351 235,196,13,71,187,189,158,188,166,168,53,28,158,14,48,128,208,187,124,121,
352 160,126,96,96,0,223,81,72,124,195,200,15,137,141,132,237,243,193,10,132,
353 74,10,132,195,171,111,96,240,189,248,154,237,173,253,125,121,160,242,130,
354 237,142,206,96,248,196,124,166,253,224,219,109,207,110,103,139,212,31,255,
355 9,31,100,102,215,201,79,220,133,176,70,29,132,218,183,81,81,113,113,177,
356 31,215,17,161,96,121,121,57,217,139,138,138,44,242,145,212,0,75,129,80,
357 73,129,112,120,101,212,118,30,48,43,85,111,181,173,22,182,181,69,125,102,
358 191,162,203,190,173,1,57,86,11,253,246,173,190,178,95,122,184,237,199,9,
359 182,56,67,17,112,13,207,255,60,167,187,127,52,236,144,133,53,234,32,44,
360 41,41,129,133,221,221,221,93,93,93,89,89,89,13,13,13,114,133,207,34,99,
361 118,118,118,91,91,91,101,101,229,88,127,2,215,63,225,173,82,64,33,126,203,
362 216,17,106,232,44,180,243,139,81,230,247,18,88,26,132,29,29,29,5,46,209,
363 117,104,45,185,98,36,98,130,195,44,137,153,78,120,222,220,225,139,20,8,
364 189,171,181,167,255,226,175,114,13,86,219,58,1,162,28,100,91,188,220,126,
365 154,245,47,10,214,219,119,122,213,126,235,14,182,13,134,34,104,1,22,62,
366 186,162,180,167,63,148,207,144,142,58,8,177,111,108,176,165,165,133,33,
367 153,146,146,130,197,171,169,169,137,142,142,142,140,140,196,238,53,54,54,
368 38,37,37,49,96,89,149,150,150,6,50,49,167,17,17,17,171,87,175,214,44,106,
369 103,103,39,238,32,132,128,130,21,21,21,102,78,140,187,0,60,197,73,112,42,
370 35,35,195,191,251,134,202,202,202,98,99,99,19,19,19,235,235,141,23,164,
371 45,13,66,90,5,151,159,214,69,52,36,19,31,63,206,128,179,5,58,10,173,75,
372 85,250,125,2,125,188,196,1,211,120,148,29,21,22,22,250,215,252,76,244,196,
373 22,16,163,69,198,234,164,64,232,69,237,189,3,247,44,41,50,216,107,75,133,
374 83,108,159,71,217,143,181,248,99,18,28,222,106,251,41,23,218,222,51,59,
375 130,134,176,211,171,73,223,103,53,14,132,46,10,71,29,132,88,6,8,199,144,
376 4,102,201,201,201,140,113,224,199,223,230,230,230,244,244,116,160,200,95,
377 232,8,0,202,203,203,161,29,49,237,237,237,169,169,169,24,70,177,133,254,
378 254,126,232,136,133,204,204,204,36,210,154,32,172,173,149,111,157,165,188,
379 24,31,108,99,181,83,226,99,233,148,23,94,136,178,19,195,15,86,145,69,239,
380 62,82,33,44,98,81,153,31,24,202,104,117,16,2,63,113,196,20,30,183,157,223,
381 113,113,113,76,103,192,27,69,162,237,227,227,227,137,167,165,233,4,20,62,
382 38,38,134,181,148,83,108,1,137,194,211,240,164,9,186,75,193,244,90,102,
383 115,52,167,104,102,255,138,192,70,200,142,214,172,89,227,150,94,10,132,
384 158,68,215,251,40,177,118,135,151,173,123,105,240,34,219,187,229,246,61,
385 172,239,11,206,181,95,177,167,109,249,176,20,20,225,168,247,210,43,91,67,
386 246,74,213,168,131,144,173,225,226,96,27,97,67,94,94,30,147,126,44,6,118,
387 3,99,8,237,192,30,145,216,64,64,200,152,197,128,96,84,49,155,107,215,174,
388 213,64,136,136,199,65,36,49,46,163,53,65,136,51,231,124,207,113,42,176,
389 199,37,192,236,243,59,59,59,27,79,151,34,243,23,194,177,72,74,76,37,94,
390 35,200,32,1,201,228,38,156,167,70,153,10,80,15,36,144,81,46,89,29,132,235,
391 215,175,223,232,212,134,13,27,4,225,105,84,168,70,177,27,26,26,168,145,
392 214,214,86,166,0,76,100,48,247,84,4,29,130,233,0,205,172,191,228,75,27,
393 211,87,168,23,11,54,176,119,9,16,82,70,250,49,109,15,254,137,161,248,20,
394 83,76,118,40,44,164,39,1,156,163,151,83,106,170,133,181,44,234,11,203,111,
395 102,124,204,21,228,242,230,42,175,118,148,86,14,133,46,159,31,229,10,19,
396 16,102,213,118,254,238,157,116,131,153,182,72,216,218,22,115,189,253,197,
397 58,107,127,98,30,66,23,217,247,254,167,237,191,91,217,98,13,199,239,61,
398 92,54,47,183,165,59,52,239,96,116,114,208,87,16,118,247,200,177,89,246,
399 171,61,55,10,176,97,223,49,11,216,1,44,33,246,16,30,8,164,193,3,126,48,
400 240,177,129,2,132,152,11,76,10,38,2,72,104,14,3,107,177,39,100,39,198,143,
401 75,140,1,16,120,3,219,206,249,124,11,8,224,248,193,54,128,160,224,120,195,
402 212,0,9,40,69,110,110,46,228,99,66,64,49,41,8,102,202,224,224,146,11,75,
403 104,246,122,131,198,35,20,119,70,137,115,217,148,60,33,33,129,114,82,120,
404 156,98,90,23,200,81,120,168,64,15,16,83,6,226,197,70,168,29,0,73,221,233,
405 209,24,44,2,123,98,90,71,73,113,7,105,102,74,65,97,41,81,84,84,20,117,66,
406 121,169,22,166,8,204,12,232,1,84,5,105,68,231,232,232,248,213,191,163,54,
407 216,130,127,103,86,221,42,28,64,216,221,55,112,225,23,57,6,3,109,145,176,
408 189,109,227,75,246,219,45,254,30,109,40,248,189,253,130,223,219,230,77,
409 28,33,5,69,120,124,101,89,127,176,205,92,125,209,136,64,232,139,160,2,198,
410 29,134,33,120,134,197,3,126,88,9,246,130,101,0,111,24,82,113,145,5,11,128,
411 1,33,158,148,88,9,18,139,45,96,99,201,66,36,105,152,94,139,72,75,9,243,
412 37,142,150,67,229,248,41,17,38,8,22,80,112,1,66,129,0,98,4,35,49,131,148,
413 69,92,23,211,152,71,205,240,151,188,102,16,182,180,58,178,139,29,153,133,
414 142,202,186,161,243,64,91,46,255,65,216,220,38,131,230,151,136,35,166,120,
415 72,52,30,5,163,252,76,10,152,233,0,66,48,64,187,98,145,89,69,26,106,132,
416 90,64,144,67,3,33,120,0,18,84,141,161,228,65,33,131,71,72,1,5,248,105,254,
417 216,216,88,234,68,80,144,25,0,63,168,10,90,154,254,13,245,41,50,145,114,
418 43,14,7,147,68,106,82,244,131,81,81,200,131,144,190,50,43,166,122,107,75,
419 62,53,56,197,182,126,174,253,202,30,107,127,98,190,221,190,221,147,182,
420 7,57,84,195,193,251,30,14,156,149,154,86,19,130,239,82,97,216,34,185,48,
421 26,194,178,9,35,137,132,149,19,49,252,213,36,34,157,201,55,91,43,98,144,
422 22,41,151,45,38,64,8,234,176,57,152,119,126,99,220,240,16,64,29,134,8,79,
423 23,16,10,4,0,66,184,128,193,4,16,224,3,231,129,92,90,161,176,153,208,148,
424 196,218,12,64,19,73,112,4,9,163,85,1,254,131,208,44,138,77,73,48,235,224,
425 29,67,79,225,241,129,68,12,139,130,127,160,130,120,225,14,83,102,208,200,
426 90,106,71,248,127,240,3,40,34,34,41,63,105,196,150,131,69,148,14,239,86,
427 248,118,176,60,51,51,83,76,2,232,1,241,241,241,148,136,154,161,225,169,
428 1,138,76,98,166,117,98,42,68,145,245,32,164,222,208,40,246,242,144,7,97,
429 86,109,231,33,179,173,248,188,196,126,182,159,62,177,255,185,223,62,209,
430 0,30,235,132,1,251,86,169,246,195,110,176,189,184,181,45,198,112,240,35,
431 10,19,108,241,15,254,92,210,19,114,79,83,140,58,8,195,65,88,57,32,39,4,
432 11,49,101,205,205,205,252,102,222,207,44,159,223,136,72,140,18,118,146,
433 25,127,69,69,5,54,10,39,129,120,185,9,231,109,131,100,97,213,40,186,4,158,
434 52,154,32,132,91,56,64,136,178,97,229,41,167,136,1,114,16,142,223,252,37,
435 18,137,130,241,87,172,229,7,145,196,240,151,69,178,35,129,198,224,18,165,
436 142,140,140,100,238,3,246,152,206,192,123,252,66,126,196,197,197,225,41,
437 226,23,26,64,8,237,72,207,20,9,143,16,100,138,141,80,9,160,145,100,98,113,
438 84,20,218,32,236,233,31,124,120,89,137,5,95,40,122,166,109,78,156,253,40,
439 43,223,26,211,109,223,246,77,251,13,7,219,22,25,142,220,191,176,253,203,
440 137,63,102,53,202,86,9,21,41,16,134,131,70,19,132,74,8,222,195,117,33,65,
441 119,17,195,95,22,133,136,212,254,138,85,98,237,80,126,167,134,18,233,22,
442 183,92,161,13,194,212,234,142,41,175,88,235,78,209,9,182,184,83,108,159,
443 91,249,19,243,224,185,201,62,229,33,251,163,219,218,162,12,7,191,37,225,
444 192,89,169,117,29,86,188,106,229,183,20,8,195,65,10,132,97,161,16,6,97,
445 67,103,223,153,159,102,27,204,241,248,134,237,108,17,183,216,158,47,179,
446 239,97,96,143,117,66,159,125,226,82,251,89,167,218,62,51,28,249,150,7,252,
447 242,39,86,149,133,210,35,246,10,132,225,32,5,194,176,80,8,131,208,190,190,
448 194,82,247,200,76,178,69,61,107,187,199,202,239,209,238,179,111,253,156,
449 237,174,93,109,171,124,124,76,112,164,225,128,55,83,179,66,232,29,164,91,
450 8,194,126,231,109,240,237,186,79,213,247,246,246,102,103,103,111,216,176,
451 65,92,39,99,237,250,245,235,51,51,51,251,156,175,37,75,78,78,142,136,136,
452 16,119,81,144,184,173,173,173,160,160,128,44,34,175,210,24,73,129,48,44,
453 20,170,32,172,104,237,57,254,131,12,131,33,30,199,176,179,109,141,221,118,
454 7,164,49,176,199,34,97,208,62,33,199,126,224,101,182,89,254,61,32,225,123,
455 120,110,109,121,200,60,74,177,37,32,4,96,133,133,133,113,113,113,218,29,
456 0,168,166,166,166,184,184,184,177,177,49,49,49,177,179,179,147,4,93,93,
457 93,169,169,169,21,21,21,37,37,37,112,177,163,163,35,61,61,157,72,32,154,
458 155,155,155,148,148,164,191,97,2,64,18,47,238,183,144,81,206,72,254,18,
459 35,126,4,94,148,212,176,107,98,40,130,136,228,104,41,41,152,31,186,228,
460 227,188,17,68,44,178,138,69,113,167,136,51,211,184,105,139,64,88,95,95,
461 175,191,201,7,177,200,212,134,150,22,165,205,203,203,203,200,200,16,38,
462 152,72,86,177,72,60,245,66,147,231,228,228,136,186,80,26,107,133,42,8,191,
463 74,171,223,206,50,159,27,60,220,246,195,15,246,243,7,172,122,107,76,183,
464 125,219,79,108,127,62,218,54,127,140,28,65,125,216,253,245,228,252,134,
465 16,113,10,183,4,132,152,251,242,242,114,12,93,107,107,171,140,114,190,66,
466 83,60,41,40,104,135,169,196,108,2,66,208,136,255,7,63,200,69,22,86,145,
467 11,223,81,216,76,145,23,4,194,75,214,138,231,13,68,36,155,34,146,52,152,
468 211,170,170,170,192,179,16,127,23,168,235,203,200,145,80,58,142,19,204,
469 99,237,249,139,9,202,114,190,68,134,2,66,119,220,92,106,134,226,112,192,
470 196,147,120,124,89,232,39,8,105,60,138,29,25,25,73,163,202,40,231,3,3,81,
471 81,81,52,39,5,19,51,29,154,135,54,142,143,143,103,85,90,90,26,181,192,100,
472 71,52,91,126,126,62,44,244,187,135,89,68,148,133,18,81,27,114,217,25,67,
473 205,208,161,69,119,228,7,21,34,186,59,173,14,141,196,162,126,149,51,223,
474 216,42,36,65,56,48,56,120,150,101,174,14,238,101,251,37,210,126,92,191,
475 85,223,32,218,108,223,241,118,219,179,59,110,193,99,130,35,13,247,44,249,
476 245,125,96,65,173,45,1,161,24,245,88,66,61,36,216,26,46,4,246,1,199,64,
477 88,134,218,218,218,132,132,4,225,84,16,143,191,72,26,225,45,8,255,65,131,
478 4,20,1,141,36,192,150,110,220,184,81,68,146,18,115,138,201,197,22,1,24,
479 97,121,2,38,14,27,179,47,206,244,202,40,103,25,41,53,199,3,224,41,29,30,
480 17,71,46,158,169,192,57,102,21,139,20,28,94,82,28,76,19,9,32,162,204,60,
481 30,242,19,132,20,131,26,103,22,0,213,101,148,243,217,17,34,105,120,218,
482 143,150,22,147,20,26,9,46,138,199,42,169,41,22,105,39,18,144,152,150,163,
483 252,164,23,217,153,86,80,23,172,210,79,106,168,35,226,73,3,51,200,43,34,
484 45,34,42,129,246,214,159,184,160,105,57,120,218,94,188,76,142,38,7,255,
485 180,180,152,25,80,100,18,51,27,162,44,84,5,201,136,39,65,0,88,24,146,32,
486 92,146,219,100,48,190,227,18,182,182,197,156,105,155,99,217,27,68,123,237,
487 91,167,217,15,251,163,237,157,0,56,130,250,128,83,152,89,27,10,207,215,
488 51,198,145,92,24,185,220,130,80,120,132,120,117,218,216,103,132,18,47,224,
489 135,197,128,16,164,33,1,6,86,188,163,3,219,66,50,108,14,44,193,146,176,
490 217,149,43,87,178,72,228,248,130,144,99,64,88,51,61,8,41,2,252,195,48,98,
491 226,196,105,97,142,159,178,20,21,21,81,46,14,18,192,99,216,57,96,12,32,
492 71,206,42,34,69,94,81,99,192,21,145,94,20,28,197,198,198,226,60,128,18,
493 168,49,234,44,240,223,35,164,186,57,116,104,39,163,92,175,88,35,158,82,
494 137,119,1,240,155,34,209,72,172,74,73,73,161,0,44,82,108,138,135,93,166,
495 19,64,5,173,72,32,132,74,33,35,205,79,75,139,72,242,86,87,87,211,45,248,
496 17,24,231,201,71,81,3,180,37,199,79,185,52,16,82,22,14,158,162,137,57,29,
497 109,198,111,34,41,56,63,136,209,202,37,124,98,58,16,200,164,117,69,36,41,
498 73,64,21,81,129,218,252,128,178,3,78,106,146,58,244,187,6,66,15,132,245,
499 157,125,199,190,111,137,171,131,55,218,94,40,183,239,110,192,143,69,66,
500 155,125,251,231,237,119,237,109,91,102,56,230,0,132,137,47,36,60,179,166,
501 188,55,248,63,75,193,176,69,114,97,228,210,131,80,216,116,236,6,246,1,108,
502 224,72,0,3,172,40,118,64,24,73,204,2,182,2,123,66,74,178,176,200,218,184,
503 184,56,44,128,200,75,74,44,140,240,52,0,3,145,136,93,96,136,48,35,88,143,
504 156,156,28,108,133,72,28,72,121,7,33,135,132,121,23,30,48,197,164,248,84,
505 2,135,138,81,114,11,66,42,129,2,146,61,61,61,29,3,40,226,173,8,66,33,26,
506 216,45,8,203,202,202,168,5,126,96,127,169,32,202,67,97,40,51,173,72,25,
507 200,226,9,132,84,16,185,72,64,207,19,109,105,89,16,34,142,92,204,104,52,
508 16,10,176,17,73,89,104,87,90,148,82,176,72,183,224,47,61,152,57,14,224,
509 228,183,40,81,116,116,52,37,213,152,71,135,136,143,143,167,86,233,61,98,
510 38,129,168,40,81,75,212,36,227,65,68,142,84,161,7,194,143,18,107,183,27,
511 239,15,208,79,180,197,222,107,123,178,195,190,157,1,63,86,8,226,49,193,
512 191,219,166,111,107,139,54,28,118,192,194,113,239,103,148,183,140,231,133,
513 159,81,145,147,131,254,131,80,216,67,113,90,139,97,136,173,64,24,141,245,
514 235,215,51,156,69,36,191,5,255,24,227,107,215,174,101,17,70,10,115,135,
515 233,39,1,134,69,108,77,152,208,200,200,72,76,7,219,196,98,104,190,199,198,
516 141,27,177,45,24,79,17,169,101,9,140,12,32,196,184,113,36,88,57,72,6,209,
517 43,43,43,41,178,152,241,115,180,136,31,216,67,144,193,95,10,130,229,231,
518 152,157,89,135,64,136,241,36,23,70,143,181,20,71,196,3,66,34,131,0,132,
519 226,76,32,13,64,203,81,41,192,128,234,160,117,89,69,163,82,6,168,0,18,0,
520 27,29,139,181,164,161,192,162,82,144,72,47,106,129,223,34,146,223,36,166,
521 46,196,213,99,17,105,29,209,210,94,64,72,209,56,114,230,65,76,127,40,59,
522 49,52,57,179,54,74,68,171,211,69,88,164,199,139,83,7,136,196,130,121,164,
523 39,129,152,10,0,48,202,78,36,189,92,115,40,71,170,16,3,97,107,119,255,37,
524 227,253,233,221,157,109,107,94,183,223,108,205,55,136,114,84,11,236,231,
525 30,97,251,222,112,204,1,14,19,108,241,159,167,212,5,218,55,25,109,13,97,
526 112,52,110,101,96,56,99,247,183,208,130,99,97,48,146,126,219,129,177,147,
527 0,33,101,196,136,81,70,126,99,217,112,120,32,25,191,19,18,18,64,29,197,
528 199,226,49,197,231,55,127,197,5,35,76,19,96,211,159,24,3,1,96,130,120,224,
529 66,97,41,50,22,85,176,131,148,196,243,3,147,171,153,205,81,209,22,129,144,
530 242,96,241,57,68,74,5,168,177,251,148,13,71,30,107,78,129,113,110,112,128,
531 248,75,36,86,24,96,176,74,160,142,50,80,114,225,242,203,109,57,65,40,222,
532 70,70,57,97,30,211,40,129,79,166,63,73,73,73,2,132,64,148,186,147,25,44,
533 32,3,8,233,1,96,143,66,209,3,24,60,180,31,253,3,170,9,216,115,228,212,21,
534 85,193,4,2,40,130,58,210,83,57,90,37,144,128,69,26,94,204,21,72,76,164,
535 0,33,187,160,99,41,16,10,101,214,118,238,49,35,217,96,118,3,25,118,181,
536 173,90,96,63,175,219,190,173,129,64,86,8,141,246,169,247,217,158,216,197,
537 182,218,112,204,227,18,78,250,40,51,216,79,142,58,57,56,10,32,68,152,62,
538 49,168,253,22,150,4,174,88,208,37,224,168,48,92,148,14,115,7,210,248,129,
539 89,131,11,28,42,70,146,72,196,34,171,48,101,192,66,172,34,35,107,1,36,214,
540 73,243,136,132,47,36,78,43,146,134,69,12,41,107,197,118,176,129,192,69,
541 176,86,164,31,21,109,17,8,41,45,226,7,199,36,108,52,139,28,183,40,18,127,
542 249,45,22,137,23,139,34,189,182,86,252,22,2,132,144,149,18,106,217,69,188,
543 115,27,114,155,67,251,219,178,158,52,186,162,109,152,242,208,180,116,2,
544 209,150,204,98,64,35,222,27,176,167,57,65,56,163,136,162,145,18,23,16,4,
545 34,26,24,192,179,138,223,164,212,186,53,32,100,222,64,46,102,18,84,41,139,
546 52,57,127,217,5,41,163,163,163,169,100,18,147,87,164,247,93,33,6,194,15,
547 18,106,241,54,12,54,55,48,97,130,45,238,183,182,31,226,236,71,89,240,49,
548 9,14,41,213,126,248,169,182,207,198,250,49,65,223,195,4,123,124,92,197,
549 175,207,146,7,163,70,17,132,33,47,12,32,252,195,214,201,101,191,132,181,
550 199,145,208,28,196,192,104,139,64,168,73,144,64,46,248,43,44,53,83,3,185,
551 16,36,162,225,193,18,127,169,1,88,5,164,1,185,152,224,208,156,176,16,4,
552 34,98,72,0,195,248,13,204,88,69,94,210,224,249,49,217,17,155,66,194,35,
553 172,116,126,167,144,109,210,159,196,57,1,182,195,84,136,72,42,153,72,232,
554 40,51,248,172,80,2,33,179,170,83,62,206,52,24,220,128,133,243,108,31,36,
555 216,143,176,224,123,180,155,237,59,126,96,255,219,33,182,133,134,3,30,247,
556 112,231,226,34,43,205,93,71,44,5,194,0,11,139,135,221,195,144,202,229,128,
557 104,116,64,56,42,26,242,245,130,118,196,192,45,61,210,252,19,32,204,211,
558 61,79,50,138,10,37,16,70,149,182,77,28,143,119,170,225,11,222,102,127,174,
559 194,146,55,136,86,218,119,187,202,246,250,100,91,132,225,152,173,16,14,
560 127,59,45,168,111,153,81,32,12,7,89,8,132,74,104,140,166,2,33,3,194,129,
561 65,199,109,11,11,13,166,54,0,97,146,45,242,30,219,83,120,93,6,2,89,36,212,
562 216,167,37,217,127,151,104,63,34,192,97,189,253,196,231,237,119,121,255,
563 156,239,148,87,146,22,229,6,113,223,11,0,8,153,70,27,6,62,179,97,225,18,
564 17,207,15,33,34,197,34,233,69,50,165,209,146,2,97,88,40,100,64,184,169,
565 177,123,191,55,3,253,1,222,93,109,171,94,183,255,163,213,190,189,1,63,225,
566 28,6,236,91,69,218,143,187,214,246,10,83,4,67,117,153,195,191,127,41,237,
567 238,11,86,219,61,214,32,236,238,238,102,251,157,186,123,0,219,156,143,76,
568 228,58,223,188,209,213,213,197,239,252,252,252,196,196,68,146,53,59,63,
569 111,27,116,151,144,172,47,5,194,176,80,200,128,240,139,212,250,29,2,251,
570 233,65,40,248,163,253,188,94,171,190,71,123,92,194,160,125,194,91,246,107,
571 247,178,45,219,202,183,183,213,252,254,195,140,250,206,128,94,242,25,69,
572 57,57,56,86,32,236,112,222,88,30,31,31,175,191,55,164,164,164,164,162,162,
573 130,24,241,52,90,79,79,79,107,107,43,105,160,32,241,13,13,13,85,206,123,
574 245,101,106,165,209,208,88,129,16,231,189,182,182,150,14,164,191,197,81,
575 68,150,149,149,213,212,212,224,224,51,21,162,93,73,67,147,211,222,213,213,
576 213,172,85,13,60,22,10,13,16,246,15,14,254,223,138,210,9,118,163,157,29,
577 187,112,128,109,201,247,182,11,44,120,107,204,120,133,126,251,86,9,246,
578 35,47,181,189,229,35,2,69,216,230,133,132,224,125,221,154,147,131,99,8,
579 66,140,33,206,159,30,132,197,197,197,245,245,245,88,72,113,75,57,38,177,
580 188,188,156,72,236,39,241,233,233,233,252,149,73,131,68,152,247,184,205,
581 63,193,1,221,41,93,84,84,84,102,102,38,107,169,225,232,232,104,210,0,123,
582 74,23,27,27,11,236,101,210,128,104,172,64,136,243,46,30,36,79,78,78,214,
583 30,15,192,211,207,201,201,161,156,52,60,127,197,195,34,176,48,43,43,139,
584 148,162,177,183,240,214,91,75,9,246,20,22,22,210,162,218,253,47,116,110,
585 202,72,36,18,159,28,3,255,69,69,69,52,63,221,157,191,116,136,177,184,0,
586 16,26,32,108,238,10,220,115,244,19,108,113,151,219,102,37,217,127,103,32,
587 65,56,135,74,251,110,143,219,254,181,191,109,169,161,174,124,9,175,70,84,
588 202,86,12,54,57,57,56,86,32,100,212,99,28,176,132,122,16,50,84,147,146,
589 146,196,83,88,237,206,87,210,96,46,132,71,65,122,108,72,112,121,11,28,45,
590 62,238,198,141,27,245,32,196,232,229,231,231,83,22,202,69,217,197,179,227,
591 24,127,113,107,61,70,18,52,200,164,1,209,88,129,16,170,81,84,154,144,249,
592 139,118,70,187,211,249,90,88,12,61,245,2,6,104,126,220,124,98,104,114,24,
593 73,74,236,181,198,140,96,23,109,204,84,128,70,205,203,203,3,243,162,239,
594 138,57,29,142,111,66,66,2,253,128,226,147,134,170,200,200,200,160,30,40,
595 62,53,163,247,161,71,75,161,1,194,178,150,158,3,103,5,226,2,33,20,60,219,
596 246,113,153,125,207,65,19,12,194,51,224,19,167,218,15,63,209,246,229,214,
597 182,24,67,93,249,24,206,250,52,91,182,98,176,105,76,65,136,204,32,196,86,
598 136,7,165,48,11,128,1,179,137,231,64,140,92,29,108,130,229,152,184,248,
599 248,120,61,8,197,37,79,108,32,150,31,139,71,1,177,147,226,29,35,88,66,126,
600 232,47,154,6,64,99,5,66,204,46,38,30,28,26,62,213,132,104,114,252,66,106,
601 7,36,128,64,230,62,84,19,189,129,134,15,222,198,118,43,10,5,249,112,121,
602 41,160,126,18,71,195,227,4,211,197,1,36,94,32,109,79,135,160,151,16,73,
603 231,208,15,137,209,82,104,128,112,99,73,219,86,99,127,94,116,71,219,134,
604 91,108,207,55,218,167,24,96,16,158,1,4,22,217,247,121,217,126,219,206,182,
605 181,134,138,26,81,216,250,133,132,186,142,160,188,76,232,228,96,32,64,40,
606 248,199,95,126,131,7,204,99,106,106,42,107,49,17,194,169,144,25,130,74,
607 20,167,186,186,26,139,135,157,215,131,48,42,42,10,248,97,27,147,147,147,
608 249,11,23,73,134,25,12,176,35,168,105,12,111,150,161,240,120,60,76,106,
609 48,247,50,202,73,65,156,33,218,152,10,194,238,99,157,225,63,200,236,113,
610 189,165,44,148,68,25,233,226,244,0,186,178,140,114,70,194,69,237,114,55,
611 127,89,75,159,16,83,63,126,139,248,209,85,104,128,240,169,213,101,6,243,
612 58,234,97,7,219,134,55,108,55,182,91,242,61,218,227,18,230,219,47,58,222,
613 246,245,168,188,170,102,126,134,229,222,144,233,139,198,26,132,204,149,
614 107,107,107,113,3,196,164,25,22,98,7,176,27,216,4,49,39,198,144,194,197,
615 177,48,11,1,16,197,137,137,137,1,123,191,252,242,11,204,211,236,60,191,
616 197,107,70,40,38,213,43,78,147,194,11,10,62,46,37,29,43,16,82,66,124,62,
617 90,55,58,58,26,212,81,54,196,15,42,133,210,50,187,97,145,42,160,129,105,
618 236,80,5,33,162,115,211,204,120,198,148,87,196,136,9,32,157,155,223,68,
619 82,124,230,10,244,9,45,193,88,40,4,64,72,237,156,248,225,216,190,80,102,
620 138,109,221,199,246,191,244,219,39,26,96,16,134,1,71,176,220,190,199,237,
621 182,255,78,178,69,25,106,201,239,112,239,210,160,252,84,175,147,131,99,
622 8,66,36,198,190,32,34,60,16,49,44,58,87,14,105,76,141,195,88,11,139,135,
623 240,249,48,65,20,4,52,82,52,102,252,105,105,105,120,68,248,69,216,192,28,
624 231,39,153,48,140,56,9,50,91,96,53,86,32,196,191,201,203,203,203,206,206,
625 198,169,167,240,0,15,191,24,55,136,137,0,70,153,72,10,79,201,97,33,130,
626 19,250,86,15,13,81,34,104,71,217,233,220,154,255,135,168,25,166,63,76,17,
627 248,77,37,136,27,133,198,186,248,33,0,194,138,214,158,109,95,28,195,23,
628 202,108,103,139,124,192,246,248,66,251,185,139,236,231,140,105,88,108,63,
629 59,215,126,160,149,239,68,109,181,239,240,133,253,114,28,193,209,253,150,
630 239,233,159,100,181,247,6,223,48,15,0,8,53,1,12,249,43,228,132,149,195,
631 219,161,128,101,206,143,82,17,195,236,95,179,75,194,9,166,158,197,60,32,
632 240,26,195,83,163,20,27,163,143,137,135,1,120,129,20,152,66,18,131,192,
633 0,53,66,60,63,80,232,81,16,81,64,60,221,164,164,36,80,71,195,211,210,21,
634 206,79,86,65,71,154,92,92,12,96,30,180,110,221,58,145,102,76,47,14,135,
635 0,8,127,202,107,26,211,55,171,77,180,197,78,177,173,159,106,91,55,214,225,
636 47,182,153,101,246,61,44,11,194,108,251,65,151,217,102,239,96,219,96,168,
637 159,45,15,71,190,155,94,218,28,124,39,126,2,9,194,144,23,70,143,217,63,
638 214,79,46,91,70,99,8,66,189,160,2,146,11,97,35,166,2,224,13,210,211,252,
639 76,2,10,11,11,137,132,250,218,172,135,4,29,29,29,164,17,51,6,17,57,22,10,
640 1,16,206,136,170,10,192,157,50,99,26,118,180,109,248,151,237,209,78,251,
641 36,3,123,44,18,154,237,59,206,183,95,180,175,237,167,209,117,4,181,176,
642 223,155,41,169,213,91,250,62,222,192,75,129,48,28,20,32,16,42,1,63,113,
643 66,96,92,20,2,32,188,109,97,97,32,31,165,31,245,112,128,109,201,103,246,
644 63,117,89,149,130,17,246,227,175,180,189,225,247,211,17,190,132,169,175,
645 38,173,45,26,253,71,131,198,90,10,132,225,32,5,194,144,214,224,160,163,
646 187,147,80,93,148,223,209,80,59,244,187,55,40,223,87,48,48,56,120,250,156,
647 44,131,97,13,162,112,166,237,147,44,251,193,253,246,173,12,248,177,66,192,
648 67,181,219,238,216,205,182,114,140,28,65,45,224,208,255,144,245,235,135,
649 184,131,69,10,132,225,32,5,194,144,86,127,183,35,239,103,71,246,130,95,
650 67,121,188,92,21,84,170,237,232,61,242,221,116,131,97,13,138,48,201,22,
651 121,141,237,149,106,251,174,6,252,88,33,244,218,183,142,181,31,125,190,
652 237,131,173,2,245,33,223,153,81,85,253,193,246,197,250,198,198,198,252,
653 252,124,185,160,20,162,82,32,12,105,225,17,214,102,111,6,194,222,160,124,
654 76,37,189,166,243,128,128,188,83,102,116,195,65,182,197,31,217,175,178,
655 230,103,43,138,236,251,252,203,246,216,94,182,95,12,199,60,166,225,238,
656 37,69,221,253,65,2,194,129,1,71,75,157,163,177,170,179,44,187,62,43,194,
657 209,88,201,111,199,64,216,221,232,16,38,82,32,12,117,117,181,57,242,151,
658 75,10,214,14,221,173,19,140,90,93,216,178,219,235,201,6,171,106,241,112,
659 160,109,113,148,253,56,11,158,14,29,180,79,136,179,31,117,220,208,99,242,
660 99,120,69,208,109,184,232,139,156,142,32,122,130,162,174,204,145,187,212,
661 145,189,104,48,123,161,35,103,137,163,34,85,129,48,84,165,64,24,6,42,79,
662 24,162,32,56,236,147,111,63,15,58,125,159,213,184,99,96,191,190,180,37,
663 97,123,219,198,43,109,51,11,236,251,26,8,52,238,1,4,22,218,247,125,204,
664 254,144,47,31,17,28,139,112,196,187,233,173,61,193,195,146,190,94,199,166,
665 85,114,18,153,179,216,209,82,46,227,149,66,78,10,132,97,32,198,115,206,
666 66,71,93,206,208,153,210,224,212,87,105,245,219,189,20,28,32,156,98,91,
667 255,150,237,186,86,251,14,6,8,141,123,232,179,79,156,99,251,203,81,182,
668 249,163,242,190,52,255,194,190,111,164,180,116,7,149,83,213,84,37,65,88,
669 176,82,185,131,33,44,5,194,176,80,123,73,110,111,107,240,221,176,167,233,
670 147,164,186,109,198,242,105,250,81,9,91,217,226,246,181,253,180,220,126,
671 154,213,78,135,226,8,150,218,247,188,198,183,175,201,143,105,216,233,213,
672 164,230,224,2,97,127,159,163,40,106,8,132,173,234,163,240,161,44,5,194,
673 176,80,176,63,71,248,110,92,205,4,147,85,181,84,192,205,250,171,237,245,
674 108,251,65,6,8,141,123,168,179,239,252,169,253,202,99,108,223,26,14,120,
675 92,194,214,47,36,52,118,5,215,55,40,6,29,13,69,253,155,214,15,253,80,10,
676 93,41,16,134,133,130,26,132,88,160,25,81,85,6,147,106,169,176,173,45,234,
677 69,251,63,235,237,59,25,32,52,238,33,211,126,240,31,109,239,108,103,139,
678 48,28,240,56,134,242,214,32,187,111,185,171,165,177,172,64,61,62,17,226,
679 82,32,12,11,5,53,8,7,6,7,95,88,95,97,176,167,214,9,251,219,150,254,104,
680 63,191,207,74,223,172,24,180,255,166,201,62,229,125,251,223,118,182,173,
681 25,235,199,228,71,26,50,107,3,250,193,213,45,23,3,71,61,71,24,242,82,32,
682 12,11,5,53,8,251,6,6,159,92,53,230,95,34,244,35,108,101,139,189,204,54,
683 59,210,126,220,128,149,222,160,61,104,159,176,194,254,135,75,108,111,111,
684 99,139,54,28,176,21,66,100,233,232,127,119,122,76,165,64,24,14,82,32,12,
685 11,5,53,8,123,251,7,31,94,86,98,176,167,227,30,192,204,227,246,127,213,
686 218,167,25,56,52,190,161,217,190,227,195,182,255,219,213,182,202,106,142,
687 160,22,150,229,253,250,145,234,160,144,2,97,56,72,129,48,44,164,64,56,186,
688 97,47,219,47,175,217,254,209,99,223,198,192,161,113,12,157,246,73,49,246,
689 99,206,177,125,100,89,4,138,176,44,95,129,80,201,114,82,32,12,11,5,251,
690 169,209,167,86,91,229,212,232,86,182,216,63,218,222,137,176,31,63,104,66,
691 209,56,134,18,251,94,119,218,158,158,102,91,109,56,90,11,134,232,50,117,
692 106,84,201,114,82,32,12,11,169,155,101,70,37,224,108,93,105,155,89,101,
693 223,205,58,159,213,229,72,214,217,79,252,173,237,135,113,124,76,126,68,
694 33,75,221,44,163,100,61,41,16,134,133,130,26,132,131,14,199,204,232,106,
695 131,61,13,124,216,211,182,252,37,219,237,189,246,173,13,40,26,199,144,103,
696 223,255,1,219,227,219,218,162,12,135,106,229,80,17,108,143,79,40,16,134,
697 131,20,8,195,66,65,13,66,244,94,124,205,248,126,149,247,40,219,119,107,
698 236,39,91,135,130,237,246,201,51,109,55,253,206,246,125,192,190,160,52,
699 42,97,155,224,123,160,94,129,48,44,164,64,24,22,10,118,16,142,227,43,214,
700 182,182,197,252,197,54,163,218,190,139,69,78,135,14,216,183,42,181,239,
701 249,87,219,235,193,229,8,138,176,243,244,96,123,197,154,2,97,120,72,129,
702 48,44,20,236,32,156,55,78,47,221,158,106,91,247,148,253,129,38,251,20,3,
703 141,198,43,212,216,167,205,182,95,119,144,109,177,225,56,131,37,236,247,
704 102,176,189,116,91,129,48,60,164,64,24,22,10,118,16,142,203,103,152,142,
705 180,253,111,133,253,15,221,150,121,70,34,201,254,187,115,109,31,142,251,
706 139,179,183,36,28,25,92,159,97,114,74,129,48,28,164,64,24,22,10,118,16,
707 174,41,10,232,135,121,39,218,98,78,183,125,146,109,63,200,34,207,72,52,
708 216,167,190,100,187,125,7,219,6,139,191,121,124,216,240,199,47,115,131,
709 233,195,188,78,41,16,134,131,20,8,195,66,193,14,194,204,218,206,3,103,165,
710 26,172,234,24,133,93,109,171,158,178,61,80,109,223,197,64,163,113,9,61,
711 246,109,150,216,207,254,163,237,29,107,190,47,109,164,225,254,159,138,123,
712 250,131,236,51,14,10,132,225,32,5,194,176,80,176,131,176,190,163,239,168,
713 247,210,13,86,117,44,194,52,219,234,249,182,139,44,114,58,180,217,190,227,
714 61,182,167,118,9,134,199,228,125,12,111,68,87,245,7,219,215,161,21,8,195,
715 65,10,132,97,161,96,7,225,192,224,224,153,159,100,25,172,234,232,6,92,174,
716 147,108,95,198,219,143,50,208,104,92,66,187,125,242,90,251,73,28,143,225,
717 32,131,58,76,180,199,255,152,21,124,95,135,86,32,12,7,41,16,134,133,130,
718 29,132,232,174,37,69,99,247,40,33,20,252,183,237,255,85,218,119,51,0,105,
719 92,66,190,125,255,91,109,207,77,177,173,55,28,100,176,135,157,166,39,173,
720 47,110,149,205,25,60,82,32,12,7,41,16,134,133,66,0,132,51,163,170,182,26,
721 27,16,78,182,69,124,104,255,107,151,125,146,1,72,129,15,3,246,9,223,216,
722 47,222,215,246,83,176,188,47,109,68,97,191,55,83,83,171,131,236,253,106,
723 72,129,48,28,164,64,24,22,10,1,16,254,146,223,60,113,12,158,169,63,206,
724 246,245,26,251,73,227,254,176,60,8,204,178,31,116,175,237,169,160,126,58,
725 194,123,56,242,221,244,178,150,32,123,191,26,82,32,12,7,41,16,134,133,66,
726 0,132,181,237,189,147,94,28,77,16,78,180,197,220,105,127,122,147,125,191,
727 113,167,96,155,125,123,187,253,206,67,109,11,130,253,233,8,239,225,204,
728 79,179,58,251,130,236,217,9,164,64,24,14,82,32,12,11,133,0,8,7,29,142,83,
729 62,206,52,216,86,191,195,84,219,186,153,246,155,58,236,219,25,152,20,224,
730 208,111,159,88,102,223,227,10,219,27,91,219,98,12,71,24,122,225,129,159,
731 138,101,91,6,149,20,8,195,65,10,132,97,161,16,0,33,122,126,221,40,124,140,
732 9,175,235,120,219,215,223,218,47,238,179,79,52,96,41,192,161,198,62,237,
733 85,251,173,123,218,150,27,142,48,84,195,130,236,224,187,101,20,41,16,134,
734 131,20,8,195,66,161,1,194,152,178,246,137,91,118,191,204,68,91,236,245,
735 182,151,242,236,251,27,152,20,248,176,202,126,202,169,182,207,38,5,225,
736 139,179,253,11,219,188,144,208,212,25,100,47,87,19,82,32,12,7,41,16,134,
737 133,66,3,132,101,45,61,7,207,246,255,253,50,83,108,235,239,183,61,209,106,
738 223,222,192,164,0,7,28,193,255,218,238,217,49,228,158,142,240,30,206,253,
739 44,91,182,98,176,73,129,48,28,164,64,24,22,10,13,16,182,116,247,95,241,
740 117,158,193,194,250,18,38,216,226,142,182,205,255,214,254,199,126,251,86,
741 6,44,5,50,116,216,183,251,198,126,241,217,182,143,130,235,35,130,163,18,
742 102,199,84,203,86,12,54,41,16,134,131,20,8,195,66,161,1,194,129,193,193,
743 199,86,150,250,241,88,253,201,182,207,51,237,135,12,140,43,5,91,236,59,
744 220,97,123,102,170,109,157,225,216,194,33,108,243,66,66,78,93,240,61,65,
745 40,164,64,24,14,82,32,12,11,133,6,8,209,188,180,250,17,125,143,105,7,219,
746 134,123,109,79,182,141,235,233,80,28,193,133,246,115,15,179,253,104,56,
747 182,240,9,39,125,148,89,223,25,100,31,166,215,164,64,24,14,82,32,12,11,
748 133,12,8,203,90,122,124,255,12,197,158,182,229,159,218,175,28,223,103,36,
749 50,236,135,220,100,179,135,219,21,65,125,152,96,139,127,106,85,89,208,125,
750 116,66,147,2,97,56,72,129,48,44,20,50,32,196,154,254,115,113,145,193,212,
751 186,13,39,216,190,74,183,31,54,142,23,5,251,236,19,63,180,253,117,111,219,
752 178,173,108,113,134,99,11,171,48,245,213,164,37,185,65,220,247,20,8,195,
753 65,10,132,97,161,144,1,33,138,43,111,223,218,235,187,214,38,217,162,254,
754 102,123,173,196,190,151,129,76,129,12,61,246,109,222,180,223,112,178,237,
755 139,227,109,95,7,32,28,109,155,111,217,151,116,255,238,157,244,202,214,
756 94,217,120,65,40,5,194,112,144,2,97,88,40,148,64,56,48,56,120,238,220,108,
757 131,181,213,194,62,182,159,63,177,255,185,213,190,131,129,76,1,14,128,176,
758 202,190,107,0,66,165,125,183,165,246,51,255,98,155,177,147,109,173,161,
759 42,44,18,30,90,86,18,172,103,69,157,82,32,12,7,41,16,134,133,66,9,132,104,
760 78,82,173,249,181,156,19,108,113,7,216,150,172,177,159,60,190,207,72,4,
761 38,12,218,39,116,219,183,205,180,31,124,181,237,213,41,182,117,150,125,
762 30,99,43,123,124,82,85,135,108,182,224,148,2,97,56,72,129,48,44,20,98,32,
763 204,169,239,218,247,141,20,189,193,157,108,139,184,198,246,74,174,253,0,
764 3,48,66,50,224,8,126,99,191,24,4,82,106,125,37,88,48,156,61,55,123,32,168,
765 253,65,5,194,240,144,2,97,88,40,196,64,216,214,51,240,167,121,191,62,89,
766 63,201,22,249,154,237,31,45,227,125,58,52,0,161,218,190,235,115,182,187,
767 143,177,125,187,131,109,131,86,124,203,6,188,246,111,211,27,130,156,131,
768 10,132,97,33,5,194,176,80,136,129,16,125,146,84,55,249,165,196,173,156,
769 167,67,23,219,207,25,223,135,229,199,58,116,219,183,41,182,239,253,178,
770 253,246,125,109,63,7,209,91,105,78,248,48,179,162,53,248,62,64,104,144,
771 2,97,56,72,129,48,44,20,122,32,108,233,238,63,125,78,214,149,182,55,210,
772 237,135,142,251,7,5,199,46,180,218,183,255,217,126,198,189,182,39,247,177,
773 253,28,92,95,43,220,230,133,132,151,54,84,246,5,251,137,81,5,194,240,144,
774 2,97,88,40,244,64,232,24,232,203,90,240,76,131,125,170,129,28,161,20,22,
775 217,207,57,211,54,103,154,109,245,132,32,124,18,113,247,25,201,121,245,
776 93,178,177,130,89,10,132,225,32,5,194,176,80,168,129,176,165,204,241,227,
777 205,142,23,183,54,144,35,4,66,191,125,171,114,251,30,95,219,47,57,217,246,
778 69,48,242,79,11,15,45,43,145,141,21,228,82,32,12,7,41,16,134,133,66,7,132,
779 131,131,142,252,159,29,159,156,230,120,33,212,46,10,14,216,39,36,218,127,
780 247,136,237,145,223,219,230,109,99,139,54,112,37,184,194,126,111,166,150,
781 183,4,253,213,65,33,5,194,112,144,2,97,88,40,68,64,56,208,239,136,127,207,
782 49,99,119,3,66,66,32,100,219,15,186,205,246,220,46,182,85,19,67,226,11,
783 77,47,110,168,232,103,202,18,18,82,32,12,7,41,16,134,133,66,1,132,189,29,
784 142,152,89,142,55,247,115,204,216,77,31,250,95,219,173,206,190,179,31,97,
785 124,95,198,77,24,180,79,224,48,54,218,127,127,135,253,153,160,120,28,194,
786 199,112,200,236,180,156,144,184,58,40,164,64,24,14,82,32,12,11,133,2,8,
787 123,218,28,21,241,142,242,88,67,232,43,141,121,230,203,31,79,181,125,54,
788 162,112,133,237,13,156,48,3,153,2,25,64,224,12,219,77,167,219,62,217,49,
789 132,16,72,216,250,133,132,23,214,87,132,192,205,162,154,20,8,195,65,225,
790 5,194,193,205,37,99,71,174,45,204,30,120,133,218,205,50,155,43,171,182,
791 115,167,87,147,12,22,217,83,152,96,139,159,102,91,179,220,126,218,184,60,
792 122,216,103,159,88,111,223,105,186,237,150,125,108,63,7,251,133,64,183,
793 225,208,183,82,155,186,250,101,195,132,132,20,8,195,65,225,5,194,250,250,
794 250,194,194,194,162,162,162,226,226,226,234,234,234,190,62,127,62,22,218,
795 214,214,198,22,74,74,74,248,33,163,44,175,208,6,97,111,255,224,83,171,202,
796 188,127,146,66,132,173,108,177,167,217,62,141,179,31,101,224,83,0,66,183,
797 125,219,141,246,223,63,105,127,240,64,219,98,195,81,133,76,152,250,106,
798 210,242,77,205,178,85,66,69,10,132,225,160,240,2,97,65,65,1,8,4,96,173,
799 173,173,176,161,161,161,65,174,24,137,64,96,101,101,101,123,123,187,127,
800 28,29,23,133,54,8,209,166,198,238,195,223,78,51,216,101,115,56,215,246,
801 193,38,251,126,1,126,0,191,199,190,205,247,182,11,254,104,123,103,15,219,
802 242,16,254,54,33,174,246,19,43,203,152,148,200,38,9,21,41,16,134,131,194,
803 14,132,101,101,101,157,157,157,29,29,29,176,1,34,242,35,45,45,45,57,57,
804 25,79,177,185,185,153,30,79,26,254,162,170,170,170,210,210,82,86,197,199,
805 199,147,69,108,97,112,112,144,4,141,141,141,61,61,61,65,116,118,52,228,
806 65,72,75,188,23,95,179,141,103,167,112,91,91,244,223,108,175,5,242,125,
807 164,3,246,173,26,236,59,45,179,159,126,142,237,195,109,108,209,193,245,
808 94,24,63,194,193,179,211,50,106,229,48,9,37,5,17,8,153,154,167,167,167,
809 71,56,21,29,29,93,94,94,238,135,141,34,11,70,114,227,198,141,169,169,169,
810 65,52,215,223,66,133,29,8,83,82,82,4,231,232,49,45,45,45,32,13,191,16,7,
811 49,41,41,137,230,103,45,116,228,47,41,129,31,44,100,85,102,102,38,126,164,
812 216,194,192,192,0,224,204,205,205,21,104,9,22,22,134,60,8,81,79,255,224,
813 181,255,219,164,55,205,90,216,214,22,245,168,237,225,38,251,20,3,171,198,
814 40,244,219,183,74,181,31,246,138,253,182,83,108,159,135,198,227,16,190,
815 132,87,54,86,134,208,45,50,191,42,136,64,216,219,219,203,72,103,114,143,
816 93,234,234,234,74,76,76,228,119,127,127,63,241,136,72,204,23,108,35,134,
817 191,136,24,254,138,181,114,19,14,7,254,64,66,66,2,19,253,186,186,186,238,
818 238,110,25,27,234,10,59,16,194,54,122,3,93,1,182,85,84,84,180,183,183,199,
819 198,198,174,93,187,54,38,38,6,16,230,229,229,209,51,152,10,209,9,232,37,
820 76,169,152,25,173,88,177,130,238,37,55,225,112,208,195,216,2,195,131,236,
821 10,132,150,210,166,134,238,163,222,77,55,24,104,188,177,89,246,235,219,
822 237,147,13,184,26,163,80,96,223,247,118,219,179,251,219,150,134,228,189,
823 48,158,194,85,223,230,119,244,14,200,102,8,45,5,23,8,115,114,114,176,75,
824 76,238,43,43,43,147,147,147,177,102,216,180,184,184,56,236,27,147,126,86,
825 17,201,42,24,201,252,158,152,140,140,140,248,248,248,245,235,215,147,82,
826 108,132,52,133,133,133,108,1,151,32,88,236,219,150,43,236,64,8,219,152,
827 236,0,179,162,162,34,26,155,126,80,91,91,203,36,8,63,175,180,180,148,30,
828 47,64,200,42,34,133,215,136,255,71,70,177,5,122,6,171,152,40,213,215,215,
829 211,159,44,222,81,134,38,128,76,254,250,251,178,114,179,26,26,27,196,239,
830 16,238,220,148,108,110,114,221,212,87,19,53,3,189,187,109,197,151,246,203,
831 2,240,169,222,102,251,142,209,246,99,110,183,253,119,59,91,100,200,159,
832 5,53,132,19,62,204,168,12,254,175,76,120,82,112,129,16,147,133,77,3,135,
833 112,78,156,223,98,234,207,95,216,134,74,156,194,44,192,197,214,214,86,113,
834 210,11,103,32,50,50,18,131,38,54,130,97,196,24,178,5,204,32,14,165,136,
835 12,121,133,23,8,65,87,86,86,22,83,36,4,246,232,55,120,129,52,57,14,19,205,
836 15,17,153,13,225,44,210,99,232,37,192,146,1,64,74,254,146,76,108,1,138,
837 144,17,52,146,222,250,189,164,174,169,46,58,63,154,240,115,210,207,17,185,
838 17,252,72,45,73,165,128,114,117,40,170,171,111,224,153,53,229,194,64,139,
839 47,52,245,217,39,26,160,53,186,161,206,190,243,219,246,107,47,179,205,222,
840 217,182,70,99,67,248,132,221,94,79,94,190,169,57,36,79,138,10,5,227,169,
841 81,126,51,221,7,138,117,117,117,197,197,197,204,227,249,141,201,194,142,
842 65,62,140,24,94,32,246,13,16,178,10,69,71,71,107,32,196,190,177,17,96,73,
843 70,220,0,17,25,242,10,47,16,14,121,72,46,241,91,139,129,13,252,16,34,146,
844 69,225,54,241,67,91,59,148,223,41,126,139,72,185,108,97,149,215,149,47,
845 72,94,160,15,107,115,214,6,197,145,111,137,96,225,229,243,242,142,182,205,
846 79,183,31,58,48,150,55,136,182,217,183,127,215,118,205,225,182,31,240,2,
847 13,120,8,159,240,212,170,178,80,122,124,94,19,195,164,177,165,145,169,100,
848 86,97,86,102,126,38,63,8,29,157,150,158,251,234,65,8,195,18,18,18,152,220,
849 51,245,7,120,217,217,217,0,15,16,86,87,87,99,220,88,5,8,153,247,51,167,
850 111,110,110,94,183,110,157,6,66,50,226,11,82,124,178,224,74,138,200,144,
851 87,120,129,48,220,20,158,32,68,85,89,235,54,189,116,168,129,91,163,21,58,
852 237,147,50,237,135,188,97,191,225,32,219,162,112,59,11,170,15,19,236,241,
853 87,124,157,215,211,31,154,151,6,187,123,186,215,100,175,49,12,159,134,22,
854 127,30,184,10,152,152,160,67,175,40,167,226,226,226,240,101,241,11,1,33,
855 14,31,192,43,47,47,135,139,141,141,141,128,144,69,86,129,204,228,228,228,
856 196,196,196,146,146,18,13,132,136,100,108,33,47,47,47,28,108,133,144,2,
857 97,40,43,28,65,56,216,239,72,154,227,152,117,128,129,94,163,18,250,237,
858 19,151,218,207,186,218,246,234,126,182,159,12,84,8,195,112,214,167,217,
859 69,77,33,123,87,97,48,130,80,201,111,41,16,134,178,194,14,132,253,189,142,
860 152,217,142,233,59,25,0,182,133,97,208,62,1,47,112,149,253,148,51,108,159,
861 108,111,219,24,212,159,9,28,173,176,231,140,148,136,210,182,208,189,50,
862 168,64,24,94,82,32,12,101,133,23,8,187,155,29,27,95,118,188,186,163,1,99,
863 91,24,54,217,247,253,200,126,213,5,182,247,182,182,197,24,96,16,182,97,
864 191,55,83,23,231,134,248,211,56,10,132,97,165,144,5,97,95,95,95,81,81,81,
865 74,74,74,123,123,187,140,114,222,243,153,151,151,39,238,152,98,177,161,
866 161,33,41,41,73,188,127,129,244,249,249,249,172,202,205,205,5,21,36,200,
867 204,204,12,246,27,136,187,123,187,43,26,42,8,169,121,169,155,202,55,241,
868 163,182,165,86,220,7,20,106,106,171,118,124,127,173,227,165,109,13,24,243,
869 59,12,218,127,147,110,63,244,1,219,227,191,181,253,176,173,45,202,64,130,
870 112,14,248,130,75,243,154,66,247,25,28,41,5,194,176,82,104,130,16,91,95,
871 93,93,157,157,157,93,89,89,9,14,53,211,47,30,150,104,107,107,139,138,138,
872 2,144,201,201,201,245,245,245,208,142,223,144,15,70,246,246,246,14,12,12,
873 144,94,60,80,81,82,82,82,92,92,172,191,101,148,85,218,214,132,180,69,67,
874 252,22,202,185,159,209,217,32,219,201,223,148,223,216,216,40,151,67,79,
875 237,213,142,255,93,61,42,223,172,135,127,237,246,201,185,246,3,238,183,
876 63,190,147,109,109,8,191,26,212,191,48,249,165,196,25,81,85,33,243,209,
877 93,47,98,18,25,145,31,177,44,99,217,207,105,63,47,77,93,202,15,66,83,155,
878 229,252,96,131,149,96,17,123,165,63,235,51,100,71,156,105,248,75,60,18,
879 49,226,55,226,183,72,25,206,10,89,16,150,150,150,214,213,213,129,55,252,
880 60,188,61,17,95,88,88,8,26,233,40,192,175,162,162,2,40,146,0,218,129,189,
881 230,230,102,214,194,72,241,104,4,140,132,28,172,213,40,200,15,60,72,210,
882 192,75,18,139,72,84,85,85,213,227,84,77,77,141,30,153,126,11,24,179,23,
883 14,155,191,252,150,177,254,138,45,192,114,28,95,28,220,214,214,86,25,27,
884 58,26,116,148,69,57,62,63,207,192,51,255,66,141,125,218,215,246,75,174,
885 181,189,50,213,182,206,0,0,21,8,59,188,156,248,210,134,202,208,123,173,
886 182,39,245,245,15,189,126,140,185,50,243,200,158,222,30,126,91,141,25,216,
887 43,236,152,102,223,80,75,75,139,176,81,226,245,200,88,36,102,255,20,129,
888 35,199,106,97,85,80,83,83,19,150,13,163,135,48,11,44,138,188,225,172,208,
889 4,33,205,143,245,23,175,128,161,79,104,29,5,52,226,38,210,51,162,163,163,
890 33,98,110,110,46,157,6,40,166,167,167,131,49,224,199,15,214,210,227,215,
891 172,89,147,149,149,69,140,120,215,26,121,217,8,224,164,27,145,50,33,33,
892 65,99,94,90,90,26,14,37,98,203,250,30,105,22,57,186,186,135,9,45,45,109,
893 113,113,113,107,157,90,183,110,29,27,111,107,235,53,164,241,61,116,118,
894 13,208,215,217,142,216,96,100,100,100,101,101,181,33,205,136,130,229,230,
895 142,101,209,142,119,127,235,216,226,135,5,187,237,219,190,101,191,238,88,
896 219,55,83,108,235,13,214,95,5,17,182,127,57,241,237,216,234,238,190,208,
897 124,88,194,147,0,70,109,109,45,163,94,46,143,150,250,122,29,221,93,142,
898 94,255,95,199,35,192,150,152,152,136,201,98,22,46,34,153,193,99,208,48,
899 80,229,229,229,120,2,44,242,119,227,198,141,252,197,52,137,231,235,197,
900 75,69,88,133,109,4,129,68,98,187,68,246,112,86,200,130,80,60,25,99,0,33,
901 189,135,94,66,87,96,30,68,55,162,7,128,61,18,32,38,80,76,175,232,31,116,
902 122,226,215,175,95,47,102,91,226,146,33,121,217,72,65,65,1,93,135,141,71,
903 69,69,105,157,207,119,16,150,215,57,22,70,13,19,150,69,212,175,93,187,65,
904 112,75,232,151,136,58,67,26,223,195,146,200,14,185,21,151,86,175,79,88,
905 28,213,111,72,230,99,136,206,112,244,122,43,95,96,213,223,235,40,94,231,
906 120,115,95,3,210,70,20,122,237,91,23,218,247,125,195,126,227,129,182,197,
907 234,94,80,47,97,202,43,73,47,108,168,232,13,230,7,231,153,134,142,40,244,
908 15,12,217,10,236,128,24,56,76,34,177,24,134,52,126,4,71,127,159,163,177,
909 204,145,191,210,145,189,208,81,184,214,209,94,63,48,48,104,72,227,54,24,
910 132,41,107,109,109,5,120,216,46,205,22,49,131,199,70,117,116,116,96,142,
911 152,1,19,223,216,216,8,246,176,99,164,199,160,97,187,96,97,70,70,6,63,16,
912 222,66,81,81,17,63,68,118,168,15,71,153,253,227,39,240,91,68,178,53,178,
913 147,70,60,131,40,34,67,79,33,123,106,20,218,209,204,112,139,158,161,181,
914 52,93,7,193,188,152,152,24,26,88,184,140,116,11,144,217,210,210,194,42,
915 82,10,40,10,82,130,73,250,147,200,14,228,240,8,217,44,25,241,8,5,29,145,
916 56,183,64,23,97,110,53,44,8,23,68,13,19,86,172,207,16,3,79,211,242,141,
917 149,134,52,190,135,95,134,176,186,153,86,175,139,91,28,217,99,72,230,99,
918 136,74,183,12,8,251,58,29,145,175,57,94,219,197,0,54,223,67,143,125,155,
919 101,246,211,239,178,61,125,152,237,71,117,33,208,123,56,244,173,180,111,
920 211,27,6,130,249,74,82,103,143,35,33,111,100,33,41,187,9,95,74,14,27,167,
921 98,99,99,19,115,123,12,201,70,26,26,54,213,59,178,23,232,67,89,65,151,33,
922 141,219,208,97,122,98,19,43,167,1,79,196,0,66,22,5,8,153,208,99,163,72,
923 131,1,132,100,34,1,120,99,190,142,185,19,191,97,36,116,20,171,16,25,49,
924 98,88,197,170,170,42,10,43,34,177,138,208,145,77,1,93,102,6,34,50,244,20,
925 154,32,68,116,5,218,114,205,154,53,226,220,38,72,163,201,233,49,17,17,17,
926 203,151,47,167,43,128,55,58,205,138,21,43,104,123,154,25,16,210,239,87,
927 175,94,45,102,79,80,16,183,143,24,126,176,200,6,129,28,233,215,173,91,199,
928 54,153,28,209,141,196,9,7,58,205,202,149,43,153,67,177,150,93,208,183,60,
929 225,208,23,16,254,178,177,98,237,90,57,9,21,90,18,209,106,72,227,123,88,
930 20,217,45,183,226,210,170,245,137,11,162,6,13,201,124,12,22,2,33,20,124,
931 121,123,3,219,124,14,19,74,103,157,122,137,237,237,157,108,107,149,23,56,
932 108,216,253,245,228,21,5,45,193,254,14,181,150,14,99,103,30,46,12,174,216,
933 80,32,199,140,78,63,71,52,153,82,142,44,180,101,172,53,128,176,62,173,208,
934 144,198,109,104,118,119,254,210,12,66,189,71,40,102,240,26,8,89,11,5,197,
935 75,183,89,4,120,169,169,169,194,184,9,145,49,55,55,23,55,0,123,136,161,
936 19,115,125,5,194,144,18,60,19,87,143,253,22,120,163,75,109,201,133,101,
937 186,159,225,146,155,57,180,182,245,38,37,37,139,81,71,95,100,90,215,217,
938 213,111,72,51,130,208,53,64,39,214,78,239,224,7,183,180,180,25,211,140,
939 36,140,191,87,208,94,235,88,254,136,137,109,62,132,23,38,14,157,71,253,
940 230,10,71,193,74,199,64,223,7,9,181,187,189,150,108,48,250,42,232,195,4,
941 123,252,225,111,167,173,42,12,133,215,46,143,28,132,76,73,203,197,168,209,
942 235,231,136,22,67,178,145,6,176,103,0,97,73,82,157,33,141,219,224,29,132,
943 240,12,206,129,43,113,141,16,242,49,77,23,144,19,32,100,85,94,94,94,102,
944 102,38,89,68,122,102,240,172,18,219,17,18,30,161,184,142,152,146,146,66,
945 22,140,30,233,115,114,114,248,75,98,182,12,68,5,32,67,76,225,2,66,90,84,
946 204,131,252,22,217,113,4,233,43,114,121,204,196,161,210,137,241,92,153,
947 130,121,114,46,125,23,189,150,169,159,184,15,104,11,167,2,227,175,214,138,
948 33,146,189,184,181,17,114,195,134,183,15,115,68,78,119,84,37,59,250,93,
949 115,231,254,193,159,243,155,143,125,63,195,96,253,85,16,97,235,23,18,110,
950 252,161,32,167,78,94,40,10,118,245,245,59,42,26,70,22,74,171,134,30,178,
951 146,0,116,138,65,84,94,215,103,72,54,210,208,83,223,184,25,8,11,35,90,27,
952 123,13,105,220,6,183,39,99,186,187,187,129,19,86,2,182,137,231,196,152,
953 241,67,172,161,9,180,107,176,139,107,123,164,132,103,8,112,194,57,172,89,
954 125,125,189,97,90,47,64,136,215,72,246,174,174,46,224,199,214,48,32,197,
955 197,197,228,226,111,75,75,11,241,248,136,122,63,50,52,20,46,32,28,21,5,
956 160,249,217,5,162,183,197,198,197,210,191,135,22,28,91,180,83,231,246,134,
957 30,38,17,51,68,36,87,4,153,6,29,45,229,142,57,167,140,236,97,65,144,57,
958 235,0,71,252,187,142,174,38,188,64,185,37,151,168,137,250,142,190,191,124,
959 147,55,209,158,96,192,64,152,135,109,95,76,120,108,101,89,91,79,8,78,252,
960 71,36,248,177,113,227,198,117,235,214,109,216,176,1,79,75,59,3,185,101,
961 26,116,244,116,56,138,35,134,40,88,188,209,209,179,165,83,13,49,162,113,
962 7,153,55,139,1,14,228,144,88,139,68,36,63,68,188,144,62,94,147,56,53,10,
963 255,12,9,68,22,36,98,144,51,121,72,73,129,208,66,162,135,149,212,149,100,
964 148,102,164,22,165,174,76,90,153,94,146,206,239,250,230,95,223,10,63,82,
965 117,247,116,179,5,66,116,118,116,116,78,52,63,114,202,115,58,186,130,237,
966 93,57,131,3,142,226,245,142,247,143,54,114,206,75,152,190,147,99,222,165,
967 142,132,247,28,29,195,212,94,115,87,255,147,171,202,118,123,93,157,38,29,
968 10,19,108,241,199,188,151,254,67,86,99,8,127,95,112,68,194,145,194,73,218,
969 242,19,51,70,117,180,56,242,126,150,191,71,67,152,142,45,63,99,9,233,197,
970 83,209,114,57,156,164,64,104,33,49,231,138,222,20,109,120,171,83,81,117,
971 145,92,61,114,53,181,53,25,182,182,60,125,121,107,71,176,61,86,159,179,
972 200,249,53,9,223,30,22,124,109,154,227,167,251,134,158,47,236,254,245,165,
973 7,222,213,211,63,184,161,184,245,247,31,168,211,164,241,127,159,159,159,
974 91,223,165,40,136,218,59,219,27,91,26,107,26,106,226,211,227,235,154,234,
975 248,221,214,209,182,229,206,80,115,91,51,155,106,172,41,107,204,90,58,244,
976 163,165,145,24,185,78,105,252,20,238,32,28,242,243,157,146,203,78,25,98,
977 244,139,250,223,163,46,5,66,163,250,123,29,137,31,58,94,241,225,6,209,23,
978 183,113,204,216,221,177,248,14,71,125,174,249,44,232,176,162,69,55,53,118,
979 95,62,47,111,135,87,18,13,108,8,147,176,251,235,201,211,35,42,59,195,236,
980 121,121,79,98,140,103,149,101,45,74,89,68,88,152,188,80,252,200,174,200,
981 222,242,177,191,50,107,165,216,218,162,228,5,226,71,126,121,112,124,254,
982 62,180,21,214,32,20,183,165,20,20,20,84,85,85,1,33,17,201,143,242,242,242,
983 194,194,194,122,231,123,137,58,59,59,139,156,234,234,234,234,233,233,97,
984 85,101,101,229,24,177,80,129,112,51,245,119,59,54,190,52,252,55,149,94,
985 218,214,49,247,76,71,196,171,142,250,60,153,209,95,225,26,206,207,104,56,
986 103,110,246,214,47,132,209,85,195,157,167,39,221,252,99,65,68,105,155,114,
987 4,53,49,192,51,203,50,13,99,103,84,64,184,60,115,185,97,179,249,101,10,
988 132,227,175,176,6,97,83,83,147,120,190,208,249,92,129,188,77,188,185,185,
989 57,37,37,133,191,155,54,109,106,111,111,207,203,203,19,15,208,228,230,230,
990 214,214,214,86,87,87,147,5,40,138,196,163,43,5,194,95,213,211,234,88,120,
991 171,227,229,201,70,236,25,194,167,167,59,242,151,13,189,116,123,112,116,
992 238,236,192,208,213,180,247,206,138,169,158,250,106,146,1,24,33,25,14,127,
993 59,109,89,126,115,123,143,114,4,55,147,2,97,184,73,157,26,29,122,59,67,
994 108,108,172,246,134,133,186,186,58,252,63,113,211,48,228,203,116,190,171,
995 26,242,241,131,85,224,144,248,209,191,120,238,148,2,161,84,91,165,227,187,
996 191,15,61,249,103,192,158,12,19,28,51,118,115,204,187,204,145,183,212,49,
997 48,38,119,54,98,237,114,234,186,46,253,42,119,74,136,158,41,157,96,143,
998 223,115,70,242,191,127,41,109,234,10,247,91,67,221,42,100,64,200,252,158,
999 105,125,82,82,18,166,76,59,120,140,27,243,251,196,196,68,97,232,74,74,74,
1000 72,192,188,159,223,164,79,77,77,13,225,87,169,121,82,184,131,16,164,225,
1001 225,225,17,106,78,94,103,103,103,90,90,26,192,163,67,84,58,5,2,233,55,44,
1002 118,116,116,136,19,164,34,229,168,139,158,90,214,80,150,93,153,157,86,146,
1003 182,50,97,101,86,121,22,191,235,154,235,228,234,145,171,171,167,139,45,
1004 16,162,50,163,98,115,99,249,177,169,106,19,145,114,181,53,85,147,238,248,
1005 242,143,238,41,248,194,4,199,187,191,115,172,121,218,81,178,209,209,55,
1006 230,165,104,233,238,95,148,211,116,253,247,5,59,188,28,82,56,220,247,141,
1007 148,71,126,41,141,41,111,239,83,39,67,61,40,100,64,200,36,158,137,190,120,
1008 64,176,215,245,41,155,138,138,10,108,26,134,142,153,125,115,115,115,86,
1009 86,22,191,49,131,192,146,85,213,213,213,204,245,69,202,240,81,56,130,176,
1010 187,187,123,205,154,53,120,129,252,96,17,63,12,200,137,247,239,9,65,59,
1011 58,16,211,37,58,10,179,36,241,96,105,78,78,142,72,63,166,98,164,33,14,32,
1012 54,46,150,93,139,69,185,206,47,137,45,4,205,115,132,101,209,142,119,60,
1013 124,77,98,230,158,67,15,197,183,150,15,221,65,19,64,181,245,12,172,45,106,
1014 57,255,179,28,3,78,130,49,108,253,66,194,189,75,139,243,27,186,194,237,
1015 35,18,35,21,195,36,100,78,141,194,191,154,154,26,38,247,24,58,17,195,111,
1016 104,7,29,89,213,214,214,134,47,136,63,80,85,85,133,107,216,208,208,144,
1017 144,144,176,37,239,207,10,82,133,181,71,72,87,160,31,208,27,152,46,209,
1018 246,116,20,58,58,125,2,10,50,69,42,40,40,224,135,240,2,89,43,190,93,34,
1019 115,142,177,32,110,92,92,156,214,113,183,92,76,247,144,92,176,166,6,7,28,
1020 69,107,29,239,28,110,228,223,244,157,28,31,159,52,244,114,209,54,255,61,
1021 227,45,87,255,192,224,226,156,166,11,191,200,217,53,56,95,204,182,255,155,
1022 169,119,46,46,202,168,9,242,87,11,5,80,253,3,253,93,221,93,45,109,45,169,
1023 153,169,29,157,29,252,30,149,225,223,221,211,205,166,186,234,43,187,114,
1024 126,26,250,193,82,207,232,79,175,57,84,237,220,21,108,203,200,200,192,154,
1025 105,246,36,50,50,146,105,61,179,127,226,197,109,16,184,128,226,188,151,
1026 213,39,202,99,166,176,6,33,156,203,206,206,134,112,64,130,174,131,255,7,
1027 240,0,33,145,116,11,17,73,12,221,5,82,226,20,202,108,99,175,176,3,97,127,
1028 143,35,106,230,144,207,167,71,224,203,219,57,22,221,230,216,244,139,163,
1029 54,207,81,26,229,168,47,145,137,199,79,237,61,3,27,74,90,31,91,81,118,200,
1030 236,52,3,105,172,25,182,121,33,225,156,185,217,111,70,87,167,213,116,142,
1031 255,71,148,154,170,3,236,205,111,185,24,137,65,241,64,189,65,224,45,63,
1032 63,191,178,178,82,44,50,215,199,136,105,167,70,177,45,248,136,20,13,211,
1033 135,125,227,7,198,173,180,180,180,188,188,92,36,8,67,133,251,53,66,80,71,
1034 47,103,30,132,26,27,27,233,22,34,18,9,14,17,47,22,157,201,3,164,177,0,161,
1035 118,106,212,114,234,235,113,68,207,116,188,186,163,228,223,11,91,13,253,
1036 6,129,117,57,142,142,70,71,209,6,71,238,146,161,247,81,213,22,208,24,178,
1037 60,227,170,158,254,193,150,238,254,255,101,54,156,54,39,107,242,75,137,
1038 91,217,141,248,25,247,176,245,11,9,211,166,39,221,252,67,65,100,105,27,
1039 240,198,157,149,135,62,190,42,73,113,228,46,117,52,86,14,121,255,65,162,
1040 32,5,33,163,74,88,176,138,138,10,241,130,80,92,64,98,136,103,45,145,185,
1041 185,185,109,109,109,201,201,201,24,189,170,170,42,138,137,59,40,172,95,
1042 120,42,220,65,168,23,221,61,192,192,243,164,81,7,97,125,125,61,62,46,147,
1043 68,171,169,56,43,190,109,201,35,131,47,109,11,2,7,95,152,216,54,243,176,
1044 234,47,111,170,76,92,218,94,93,48,88,149,249,235,187,137,179,23,180,231,
1045 197,12,193,124,203,196,132,128,185,240,104,169,178,186,250,151,148,162,
1046 123,231,39,31,55,43,102,151,87,226,182,50,1,41,192,97,107,123,252,1,51,
1047 19,47,156,147,242,202,234,77,89,229,245,173,173,173,24,59,191,69,39,28,
1048 93,245,111,138,148,173,89,176,218,209,84,236,232,25,58,217,56,138,146,125,
1049 125,84,197,97,7,35,8,53,137,19,90,140,125,26,148,82,224,243,117,116,116,
1050 96,88,74,74,74,136,199,101,20,191,211,210,210,196,29,164,50,91,248,73,129,
1051 208,138,98,248,141,46,8,153,9,178,205,206,45,19,134,149,113,53,154,42,205,
1052 108,251,248,124,248,55,116,143,232,231,231,13,102,124,219,90,158,89,93,
1053 85,89,83,93,213,94,95,49,88,147,175,81,144,208,87,158,81,93,93,85,189,101,
1054 98,228,51,224,71,87,133,69,69,41,121,197,171,51,74,62,141,46,186,227,135,
1055 156,223,189,157,18,96,31,17,255,239,247,111,197,63,178,32,253,139,141,89,
1056 43,18,115,211,115,242,228,44,99,11,132,199,64,15,28,93,117,101,44,213,55,
1057 232,96,193,154,210,140,216,132,209,19,254,205,168,43,49,49,49,168,65,136,
1058 134,78,186,56,29,65,236,9,19,98,188,67,45,18,25,126,135,173,20,8,173,168,
1059 81,7,161,245,52,232,232,168,117,124,253,167,161,123,97,230,156,234,200,
1060 93,236,232,237,100,68,202,149,66,44,246,116,57,74,34,29,185,63,13,153,206,
1061 81,58,53,42,7,253,24,104,96,112,176,111,96,176,171,111,32,171,182,243,145,
1062 239,226,207,153,147,190,215,140,148,105,211,147,118,120,37,113,155,23,19,
1063 38,152,0,230,71,0,177,147,94,74,152,242,74,210,174,175,37,239,247,70,202,
1064 181,255,219,244,117,122,125,73,93,107,76,124,98,119,47,59,31,77,209,253,
1065 70,87,142,226,36,73,65,26,180,60,125,176,179,205,249,5,217,81,19,86,190,
1066 110,180,197,54,199,228,113,169,0,130,80,47,154,85,254,82,218,92,10,132,
1067 86,84,136,131,112,232,6,209,53,67,143,204,47,189,199,81,176,66,251,70,160,
1068 71,117,182,56,42,83,28,245,214,190,235,117,115,197,198,198,54,52,52,214,
1069 180,247,38,84,182,47,200,110,156,29,83,253,248,202,210,155,127,44,184,240,
1070 139,156,163,223,75,223,231,141,148,93,166,39,121,191,190,136,159,183,227,
1071 43,137,187,189,158,188,255,155,41,39,126,152,121,197,215,121,119,46,46,
1072 122,118,109,249,199,137,181,203,242,155,51,106,59,181,215,193,224,172,227,
1073 184,4,193,121,173,146,100,71,254,170,161,166,108,111,30,149,57,77,16,107,
1074 156,64,168,228,73,10,132,86,84,136,131,176,46,219,145,245,131,163,97,147,
1075 163,207,231,187,249,97,103,255,152,188,205,103,140,4,8,13,175,231,192,242,
1076 119,244,14,212,117,244,149,182,244,108,106,232,206,169,239,202,172,237,
1077 76,173,238,136,46,107,91,190,169,249,187,204,134,79,146,106,63,75,169,131,
1078 154,171,11,91,226,43,218,211,107,58,179,234,186,114,235,187,10,26,187,43,
1079 90,123,155,186,250,187,61,60,0,31,52,32,108,172,114,116,181,57,66,249,60,
1080 135,207,82,32,180,152,20,8,173,168,16,7,225,208,123,209,66,211,33,24,28,
1081 28,236,235,239,35,68,199,70,215,213,215,137,223,190,156,143,34,133,22,124,
1082 23,61,132,237,183,180,182,36,36,37,244,244,244,240,59,100,251,76,136,73,
1083 129,208,98,82,32,180,162,194,224,26,97,104,170,174,169,46,118,83,108,204,
1084 166,152,159,147,126,222,152,189,145,31,4,90,83,174,30,109,21,87,21,179,
1085 253,13,217,27,150,167,44,23,251,42,168,41,144,235,148,172,44,5,66,139,73,
1086 129,208,138,82,32,12,82,149,84,149,44,76,94,104,120,135,214,216,129,48,
1087 181,48,213,176,175,164,146,36,185,78,201,202,82,32,180,152,20,8,173,40,
1088 5,194,32,149,2,161,146,79,82,32,180,152,20,8,173,40,5,194,32,149,2,161,
1089 146,79,82,32,180,152,20,8,173,40,5,194,32,149,2,161,146,79,82,32,180,152,
1090 20,8,173,40,5,194,32,149,2,161,146,79,82,32,180,152,20,8,173,40,5,194,32,
1091 85,107,123,107,89,125,25,97,109,194,218,77,21,155,196,239,177,107,199,250,
1092 230,122,182,207,142,54,36,109,40,169,45,225,119,99,91,216,125,91,60,40,
1093 165,64,104,49,41,16,90,81,10,132,65,173,193,193,193,152,152,152,134,134,
1094 6,185,236,179,200,40,36,151,125,83,71,71,71,98,98,226,232,191,15,83,105,
1095 236,164,64,104,49,41,16,90,76,3,253,142,190,222,222,206,142,204,196,216,
1096 129,158,110,126,135,251,203,168,130,77,96,172,166,166,102,227,198,141,105,
1097 105,105,141,141,141,190,83,173,189,189,189,192,169,226,226,98,237,211,113,
1098 195,10,10,230,230,230,70,70,70,22,22,22,142,201,91,49,149,198,66,10,132,
1099 22,147,2,161,197,212,84,227,40,92,51,184,105,101,111,214,82,71,193,74,71,
1100 193,42,71,99,248,126,45,115,88,85,87,87,131,156,69,139,22,125,245,213,87,
1101 115,231,206,253,238,187,239,126,254,249,231,212,212,84,240,32,83,140,182,
1102 186,186,135,9,133,133,69,28,210,90,167,34,34,34,106,235,90,13,9,220,134,
1103 150,150,182,216,216,88,145,107,221,186,117,206,79,135,247,25,210,152,67,
1104 99,83,71,116,116,52,233,69,198,248,248,248,150,214,94,67,26,67,240,153,
1105 176,74,99,41,5,66,139,73,129,208,98,234,237,113,228,175,144,47,233,39,148,
1106 198,90,237,29,155,184,56,101,101,101,153,155,43,203,169,108,167,114,156,
1107 194,77,17,202,203,27,250,42,208,166,77,155,112,116,202,203,203,241,150,
1108 90,90,90,252,62,143,215,214,214,86,84,84,244,201,39,159,92,115,205,53,187,
1109 237,182,219,196,137,19,183,50,137,200,73,147,38,29,123,236,177,247,220,
1110 115,207,252,249,243,217,175,47,92,196,9,227,56,101,121,156,114,91,168,117,
1111 17,185,239,205,31,10,239,127,151,247,193,255,54,125,240,125,193,199,11,
1112 74,62,93,92,241,197,178,186,111,215,180,253,20,209,190,118,237,122,129,
1113 37,161,213,235,51,23,70,59,134,13,203,55,150,65,64,153,199,169,37,145,237,
1114 134,52,34,252,24,57,240,206,55,89,111,127,157,73,152,243,229,106,240,175,
1115 211,231,31,126,185,65,172,18,225,147,69,101,90,198,207,127,174,37,102,222,
1116 162,204,212,84,89,64,47,50,52,16,213,46,87,108,177,180,182,168,171,171,
1117 147,81,195,137,106,23,31,15,18,162,33,228,138,225,132,123,45,243,88,71,
1118 29,173,142,214,90,71,67,217,208,55,138,249,65,8,170,151,232,134,170,20,
1119 8,173,167,166,106,73,193,156,197,142,134,18,171,125,206,27,19,249,247,191,
1120 255,253,55,46,77,152,48,65,176,103,155,109,182,217,118,219,109,33,208,228,
1121 201,147,183,223,126,251,29,118,216,97,71,167,166,78,157,58,109,218,52,160,
1122 181,255,254,251,31,121,228,145,127,248,195,31,174,184,226,138,123,239,189,
1123 119,214,172,89,81,81,81,35,186,163,114,201,146,37,87,95,125,245,62,251,
1124 236,35,247,237,131,56,188,67,14,57,228,134,27,110,88,186,116,169,247,125,
1125 149,150,150,254,238,119,191,147,217,60,151,107,251,237,119,220,110,242,
1126 80,216,126,135,157,118,156,186,203,212,105,187,239,190,247,65,7,28,124,
1127 244,145,199,157,117,218,185,127,251,235,117,247,63,246,216,227,95,124,241,
1128 197,234,213,171,37,208,214,174,93,16,229,24,54,172,88,159,38,83,187,180,
1129 124,99,181,33,141,8,95,173,104,222,122,155,109,229,81,14,167,51,47,188,
1130 78,203,120,237,237,207,78,156,184,181,92,49,156,106,107,107,101,189,56,
1131 69,237,201,21,91,44,188,100,177,205,151,95,126,89,70,13,167,189,246,218,
1132 43,49,49,81,228,66,116,39,185,98,56,157,124,242,201,50,143,117,212,82,247,
1133 235,52,151,80,18,237,232,30,171,179,23,74,190,75,129,208,122,26,232,119,
1134 20,69,15,13,146,220,159,28,157,109,50,210,50,50,128,208,111,129,150,93,
1135 119,221,245,226,139,47,198,200,202,77,123,22,126,228,29,119,220,177,243,
1136 206,59,195,39,153,127,36,34,215,78,59,237,116,235,173,183,226,217,200,45,
1137 154,100,0,161,127,98,71,148,11,75,125,225,133,23,126,244,209,71,240,108,
1138 197,134,18,13,69,94,194,47,27,140,30,225,226,200,54,67,26,17,70,6,194,139,
1139 174,215,50,142,8,132,184,107,178,94,156,10,82,16,158,114,202,41,50,143,
1140 117,52,56,232,40,142,255,21,132,53,121,234,38,0,43,72,129,208,146,106,44,
1141 117,228,44,114,52,215,200,69,43,105,180,64,168,9,151,235,182,219,110,43,
1142 42,42,146,59,48,169,176,176,240,220,115,207,149,169,183,76,71,31,125,244,
1143 134,13,27,220,222,142,59,42,32,212,11,159,24,199,183,162,162,66,238,192,
1144 171,122,122,123,177,245,226,226,226,250,245,235,11,10,10,250,251,221,159,
1145 9,104,110,110,198,67,149,251,24,78,184,194,50,155,195,241,236,179,207,110,
1146 189,117,80,130,112,239,189,247,78,74,250,245,249,72,223,65,120,234,169,
1147 167,202,60,150,82,107,205,208,201,30,40,88,180,193,209,167,238,111,178,
1148 132,20,8,173,168,129,238,206,182,236,245,131,61,62,127,174,47,128,26,117,
1149 16,34,28,169,51,207,60,211,96,124,133,160,224,31,254,240,7,153,110,52,116,
1150 212,81,71,165,167,167,203,173,235,52,234,32,68,120,135,56,178,114,7,195,
1151 137,138,197,241,141,140,140,172,173,173,245,242,228,140,2,161,239,32,164,
1152 231,200,60,150,82,127,175,163,56,194,145,189,208,209,80,108,181,11,31,97,
1153 43,5,66,43,170,187,187,187,40,53,102,208,146,207,17,142,5,8,17,44,124,232,
1154 161,135,12,0,24,28,28,124,240,193,7,183,218,106,43,153,104,52,196,142,174,
1155 186,234,42,51,105,198,2,132,8,246,124,242,201,39,190,60,68,65,154,206,206,
1156 206,152,216,24,142,205,75,250,17,129,240,198,27,111,148,217,130,28,132,
1157 201,201,201,34,23,242,29,132,167,157,118,154,204,99,53,53,148,15,221,44,
1158 211,209,34,23,149,198,91,10,132,86,148,149,31,168,31,35,16,162,157,119,
1159 222,121,229,202,149,114,55,78,165,165,165,237,191,255,254,114,245,168,106,
1160 209,162,69,114,31,46,141,17,8,209,17,71,28,225,229,196,47,2,123,37,117,
1161 37,89,101,89,105,197,105,43,147,86,102,150,101,242,187,161,197,253,243,
1162 248,35,2,225,77,55,221,36,179,133,37,8,79,63,253,116,153,199,106,82,143,
1163 79,88,76,10,132,86,84,120,130,16,207,239,241,199,31,215,158,10,7,15,111,
1164 189,245,214,196,137,19,229,234,81,213,223,254,246,55,177,23,77,99,7,66,
1165 184,181,112,225,66,47,78,94,255,64,127,68,126,132,225,173,161,197,213,197,
1166 114,245,230,26,17,8,111,190,249,102,153,45,44,65,120,198,25,103,200,60,
1167 86,147,2,161,197,164,64,104,69,133,39,8,17,83,120,205,4,83,252,171,175,
1168 190,90,174,24,78,152,248,41,83,166,76,158,60,121,130,111,183,149,30,115,
1169 204,49,141,141,155,189,150,115,236,64,136,238,189,247,94,47,175,125,25,
1170 59,16,254,227,31,255,144,217,130,25,132,251,236,179,79,74,74,138,200,133,
1171 124,7,225,153,103,158,41,243,88,77,10,132,22,147,2,161,21,21,182,32,220,
1172 121,231,157,75,74,74,180,29,249,248,200,224,164,73,147,30,123,236,177,53,
1173 107,214,204,155,55,239,184,227,142,147,177,94,117,192,1,7,100,102,102,138,
1174 29,9,141,41,8,79,62,249,100,47,15,245,143,29,8,111,185,229,22,153,45,44,
1175 65,120,214,89,103,201,60,86,147,2,161,197,164,64,104,69,133,18,8,191,255,
1176 254,251,185,115,231,222,116,211,77,190,248,106,164,73,72,72,16,59,170,174,
1177 174,246,209,189,187,241,198,27,197,155,71,6,7,7,223,126,251,237,237,182,
1178 219,78,174,240,172,221,119,223,61,50,50,82,236,72,104,68,32,60,251,236,
1179 179,23,46,92,200,190,46,189,244,82,25,229,85,187,238,186,171,151,71,24,
1180 199,14,132,183,222,122,171,204,22,228,32,76,77,77,21,185,144,239,32,164,
1181 153,100,30,171,73,129,208,98,82,32,180,162,66,6,132,7,29,116,16,158,16,
1182 124,162,44,159,125,246,217,14,59,236,32,87,120,214,130,5,11,196,142,162,
1183 163,163,101,212,112,90,190,124,185,200,130,86,172,88,177,203,46,187,200,
1184 21,158,53,117,234,84,125,46,52,34,16,82,3,20,10,245,247,247,191,246,218,
1185 107,190,92,200,172,169,241,248,84,104,40,129,144,185,11,160,2,93,158,164,
1186 77,116,2,0,194,115,206,57,71,230,177,154,20,8,45,38,5,66,43,42,100,64,120,
1187 240,193,7,119,118,202,167,33,27,27,27,47,188,240,66,185,194,179,62,248,
1188 224,3,145,126,254,252,249,50,106,56,193,48,145,5,197,196,196,224,237,201,
1189 21,158,53,121,242,100,92,58,153,199,41,63,64,40,50,102,102,102,30,112,192,
1190 1,114,133,103,185,125,120,81,136,77,13,221,53,90,145,149,82,148,178,34,
1191 97,69,102,121,38,191,235,155,235,229,234,205,53,34,16,222,118,219,109,50,
1192 91,160,64,184,205,54,219,48,51,16,175,105,117,43,166,14,98,155,35,2,97,
1193 90,90,154,200,133,124,7,225,185,231,158,43,243,88,77,10,132,22,147,2,161,
1194 21,21,146,32,164,80,216,101,185,194,179,94,125,245,85,145,254,227,143,63,
1195 150,81,94,133,55,214,218,218,42,178,160,216,216,216,61,246,216,67,174,243,
1196 172,73,147,38,125,255,253,247,50,143,83,126,131,176,170,170,234,132,19,
1197 78,144,43,60,107,195,134,13,34,189,91,13,121,151,131,131,120,207,49,177,
1198 49,160,66,44,202,117,155,107,68,32,188,253,246,219,101,54,135,227,185,231,
1199 158,11,0,8,57,182,175,190,250,74,102,243,170,0,128,240,188,243,206,147,
1200 121,172,38,5,66,139,73,129,208,138,10,73,16,146,241,254,251,239,151,43,
1201 60,235,249,231,159,23,233,223,124,243,77,25,53,156,244,30,161,143,32,196,
1202 113,193,227,148,121,156,242,27,132,245,245,245,190,188,251,102,197,138,
1203 21,34,189,23,117,117,117,225,209,122,111,119,191,65,72,197,6,41,8,247,221,
1204 119,95,189,63,237,59,8,207,63,255,124,153,199,106,82,32,180,152,20,8,173,
1205 168,144,4,33,197,249,215,191,254,37,87,120,150,6,66,92,67,25,53,156,22,
1206 47,94,44,178,32,31,65,8,18,190,254,250,107,153,199,41,191,65,216,216,216,
1207 120,250,233,167,203,21,158,53,46,32,212,191,224,45,12,65,120,193,5,23,200,
1208 60,86,147,2,161,197,164,64,104,69,133,12,8,15,57,228,16,191,65,232,187,
1209 71,248,223,255,254,87,100,65,209,209,209,190,92,35,68,159,125,246,153,204,
1210 227,84,72,130,240,206,59,239,148,217,28,14,155,205,22,110,32,188,240,194,
1211 11,101,30,171,73,129,208,98,82,32,180,162,20,8,209,156,57,115,100,212,112,
1212 58,242,200,35,53,195,157,153,153,121,253,245,215,95,230,131,12,175,115,
1213 179,2,8,123,123,123,135,109,119,191,65,104,183,219,131,23,132,25,25,25,
1214 50,219,72,64,120,209,69,23,201,60,86,147,2,161,197,164,64,104,69,41,16,
1215 162,245,235,215,203,168,225,52,113,226,196,123,238,185,71,187,101,6,156,
1216 244,248,32,67,245,142,8,132,87,95,125,117,80,120,132,119,221,117,151,204,
1217 22,150,32,252,227,31,255,40,243,88,77,10,132,22,147,2,161,21,21,146,32,
1218 236,239,239,31,17,8,171,170,170,124,255,238,4,44,188,247,222,123,155,154,
1219 154,252,174,52,43,128,144,186,45,77,31,230,171,35,35,2,225,221,119,223,
1220 45,179,57,28,47,188,240,66,184,129,240,226,139,47,150,121,172,38,5,66,139,
1221 73,129,208,138,10,73,16,226,168,97,151,229,10,207,210,64,8,56,127,251,219,
1222 223,202,88,223,116,234,169,167,206,155,55,143,218,19,91,24,145,252,6,97,
1223 109,109,237,201,39,159,44,87,120,150,47,32,116,244,246,56,10,86,59,154,
1224 107,229,162,59,249,13,194,23,95,124,113,155,109,182,145,43,134,83,0,64,
1225 248,202,43,175,200,60,195,201,0,66,95,94,152,32,116,201,37,151,200,60,86,
1226 147,2,161,197,164,64,104,69,133,36,8,249,113,227,141,55,202,21,158,133,
1227 227,34,210,83,252,187,238,186,75,198,250,172,169,83,167,94,117,213,85,250,
1228 143,21,248,40,191,65,88,86,86,118,236,177,199,202,21,158,181,106,213,42,
1229 145,222,155,90,202,29,57,139,28,133,107,29,253,125,50,198,164,17,129,240,
1230 158,123,238,145,217,172,7,66,223,239,10,54,128,112,215,93,119,149,43,134,
1231 211,165,151,94,42,243,88,77,10,132,22,147,2,161,21,21,146,32,108,104,104,
1232 56,247,220,115,229,10,207,154,62,125,186,72,143,22,45,90,228,187,237,214,
1233 52,97,194,132,221,118,219,237,227,143,63,102,143,114,67,62,200,111,16,166,
1234 167,167,239,183,223,126,114,133,103,105,239,216,244,40,54,88,153,230,200,
1235 94,48,20,106,179,88,150,241,155,107,68,32,188,239,190,251,100,54,135,227,
1236 165,151,94,10,0,8,39,78,156,248,143,127,252,99,150,59,189,245,214,91,250,
1237 239,50,210,208,50,207,112,50,128,144,198,149,43,134,211,101,151,93,38,243,
1238 88,77,10,132,22,147,2,161,21,21,122,32,164,44,31,125,244,209,78,59,237,
1239 36,87,120,22,230,82,236,8,85,87,87,159,120,226,137,114,197,8,133,209,191,
1240 232,162,139,150,47,95,206,1,203,205,121,149,127,32,4,75,79,61,245,148,47,
1241 215,222,180,119,108,122,212,64,223,144,47,40,64,88,176,202,209,245,235,
1242 235,114,244,178,56,8,189,104,231,157,119,214,191,94,199,111,16,250,248,
1243 120,12,186,252,242,203,101,30,171,73,129,208,98,82,32,180,162,66,6,132,
1244 144,239,233,167,159,198,28,159,125,246,217,83,166,76,145,177,94,53,111,
1245 222,60,185,39,231,139,199,102,207,158,237,135,83,168,105,143,61,246,152,
1246 49,99,134,47,44,28,17,8,15,59,236,176,255,254,247,191,184,62,199,28,115,
1247 140,47,31,187,64,222,63,82,63,164,230,26,73,65,17,202,113,10,221,104,68,
1248 32,188,255,254,251,101,54,231,205,41,150,2,225,107,175,189,38,87,12,39,
1249 3,8,125,121,97,130,208,159,254,244,39,153,199,106,82,32,180,152,20,8,173,
1250 168,144,1,161,31,90,179,102,141,220,147,83,56,148,87,94,121,165,143,223,
1251 99,242,164,107,174,185,38,63,63,95,123,221,179,91,141,8,132,35,213,164,
1252 73,147,244,47,68,117,175,226,13,142,194,53,61,185,43,218,50,151,59,106,
1253 75,134,66,175,155,111,249,142,8,132,15,60,240,128,204,230,188,57,197,82,
1254 32,100,130,34,87,12,39,3,8,247,220,115,79,185,98,56,93,113,197,21,50,143,
1255 213,164,64,104,49,41,16,142,191,240,123,42,42,42,228,203,249,157,74,79,
1256 79,223,184,113,99,102,102,166,92,118,170,113,243,47,170,143,151,198,20,
1257 132,120,141,16,75,238,201,37,16,117,206,57,231,200,20,126,9,142,30,126,
1258 248,225,223,124,243,141,118,97,207,172,49,5,225,177,199,30,235,229,195,
1259 188,82,112,186,191,175,182,182,54,38,38,70,198,184,211,136,64,248,224,131,
1260 15,202,108,206,155,83,44,5,194,153,51,103,202,21,195,201,111,16,50,133,
1261 146,121,172,38,5,66,139,73,129,208,18,170,169,169,193,70,172,245,42,96,
1262 41,83,143,171,198,20,132,199,29,119,92,117,117,181,220,147,75,208,43,53,
1263 53,21,146,109,161,95,184,253,246,219,191,247,222,123,158,88,56,166,32,188,
1264 233,166,155,240,242,229,158,188,170,169,169,41,54,54,86,46,184,147,2,225,
1265 94,123,237,37,87,12,167,63,255,249,207,50,207,184,139,94,167,15,237,77,
1266 67,32,52,68,18,148,198,73,10,132,150,16,116,73,76,76,148,196,115,167,236,
1267 236,108,239,103,246,2,166,177,3,33,156,195,112,139,111,205,155,85,82,82,
1268 114,247,221,119,251,114,187,141,23,237,176,195,14,239,190,251,110,79,143,
1269 155,83,142,99,7,66,240,243,229,151,95,138,19,221,56,124,81,81,81,145,158,
1270 245,203,47,191,124,252,241,199,114,193,37,124,196,150,150,22,113,156,35,
1271 2,225,191,254,245,47,145,11,77,159,62,221,82,32,124,227,141,55,228,138,
1272 225,100,0,225,222,123,239,45,87,12,167,191,252,229,47,50,207,248,138,145,
1273 91,18,189,217,5,96,183,161,44,78,166,87,10,184,20,8,173,34,12,156,132,158,
1274 73,17,17,17,13,13,13,94,78,235,5,82,99,7,194,93,118,217,133,194,202,221,
1275 184,19,0,251,226,139,47,246,217,103,31,153,193,47,77,155,54,109,206,156,
1276 57,114,139,58,141,29,8,143,58,234,40,54,46,246,178,98,197,138,221,119,223,
1277 157,146,122,18,180,152,58,117,170,92,112,233,176,195,14,211,110,58,29,17,
1278 8,31,122,232,33,145,11,89,13,132,179,102,205,146,43,134,147,1,132,190,119,
1279 128,171,174,186,74,230,25,119,181,183,56,178,23,26,201,103,8,125,110,230,
1280 103,74,129,145,2,161,133,148,153,153,41,200,103,80,108,108,172,39,63,41,
1281 240,26,35,16,98,220,159,121,230,153,97,239,15,34,65,97,97,225,101,151,93,
1282 230,187,77,55,139,125,197,197,25,103,223,99,4,194,201,147,39,207,155,55,
1283 79,155,196,0,66,223,223,115,166,9,118,198,199,199,139,45,140,8,132,15,63,
1284 252,176,200,133,94,123,237,53,75,129,112,246,236,217,114,197,112,10,5,16,
1285 162,178,116,35,249,244,161,174,64,38,83,26,15,41,16,90,72,141,141,141,27,
1286 55,110,148,244,211,105,68,15,134,143,181,198,2,132,123,238,185,231,171,
1287 175,190,234,251,93,178,173,173,173,47,190,248,226,72,95,192,166,215,223,
1288 254,246,183,246,246,118,185,57,167,70,29,132,19,38,76,192,23,196,133,149,
1289 59,112,106,203,65,216,210,210,226,31,8,95,127,253,245,208,0,33,139,114,
1290 197,112,178,22,8,59,155,29,185,203,140,252,19,97,211,10,71,207,112,247,
1291 82,41,141,165,20,8,45,36,24,147,156,156,44,233,231,82,126,126,62,241,50,
1292 133,5,52,186,32,156,52,105,210,117,215,93,23,29,29,221,219,219,43,119,224,
1293 155,72,191,105,211,166,107,174,185,198,191,59,104,118,221,117,87,189,81,
1294 70,163,11,194,93,118,217,229,241,199,31,231,8,13,116,223,114,16,50,9,8,
1295 13,16,190,245,214,91,114,197,112,50,128,208,151,247,248,8,89,11,132,3,253,
1296 142,178,120,35,2,69,168,74,85,119,202,140,175,20,8,173,165,154,154,154,
1297 245,235,215,75,6,174,93,139,225,168,172,172,148,235,172,161,17,129,16,203,
1298 59,205,41,192,179,219,110,187,237,177,199,30,123,239,189,247,254,251,239,
1299 127,232,161,135,94,122,233,165,211,167,79,47,43,43,219,146,155,128,218,
1300 218,218,94,121,229,21,223,239,167,215,235,157,119,222,209,83,106,68,32,
1301 4,69,20,10,218,137,114,113,0,251,236,179,207,129,7,30,120,248,225,135,95,
1302 127,253,245,159,126,250,41,126,155,91,7,119,203,65,72,145,253,3,225,140,
1303 25,51,2,0,66,118,49,107,214,172,34,15,210,63,67,242,246,219,111,203,60,
1304 195,201,0,66,250,143,92,49,156,172,5,66,212,82,239,200,253,201,72,65,98,
1305 186,54,59,57,161,20,120,41,16,90,75,80,33,53,53,85,98,112,237,218,244,244,
1306 116,75,185,131,104,68,32,60,228,144,67,126,249,229,23,10,2,209,163,162,
1307 162,146,146,146,178,178,178,202,203,203,71,247,146,103,100,100,36,88,245,
1308 221,202,11,225,137,234,237,242,136,64,120,206,57,231,172,94,189,154,114,
1309 109,220,184,49,38,38,38,37,37,37,39,39,167,186,186,122,216,198,10,121,16,
1310 114,108,62,190,116,219,111,16,30,112,192,1,114,197,112,178,28,8,113,10,
1311 75,19,140,32,172,76,149,107,149,198,79,10,132,150,19,206,132,19,130,67,
1312 70,182,169,169,201,34,55,139,106,26,41,8,181,151,110,143,157,168,162,198,
1313 198,198,7,31,124,208,247,239,23,34,188,55,253,197,215,17,129,80,255,210,
1314 237,17,105,28,65,56,115,230,76,5,194,241,87,103,155,17,132,234,102,81,11,
1315 72,129,208,114,194,194,138,219,71,19,18,18,2,64,145,145,42,96,32,28,24,
1316 24,248,194,55,225,55,139,44,175,188,242,202,212,169,83,229,190,135,211,
1317 118,219,109,167,127,71,129,149,65,184,219,110,187,225,79,139,45,40,16,30,
1318 120,224,129,114,197,112,178,34,8,81,121,198,175,20,172,43,80,87,7,173,32,
1319 5,66,43,10,79,5,119,208,96,140,44,162,128,129,144,29,249,232,225,189,248,
1320 226,139,34,75,79,79,207,11,47,188,224,227,91,176,145,254,189,166,86,6,225,
1321 46,187,236,50,111,222,60,241,206,29,191,65,248,198,27,111,132,6,8,15,58,
1322 232,32,185,98,56,89,20,132,29,205,142,188,95,134,40,184,105,165,163,71,
1323 93,29,180,132,20,8,173,40,24,80,91,91,235,251,227,4,129,84,32,65,56,121,
1324 242,100,185,33,175,154,174,251,132,97,101,101,165,239,167,206,222,123,239,
1325 61,153,45,80,32,220,180,105,211,243,207,63,255,228,147,79,222,126,251,237,
1326 80,234,89,223,4,221,33,65,116,116,52,189,130,250,244,15,132,111,190,249,
1327 166,239,25,3,0,194,247,223,127,95,230,25,78,6,16,30,124,240,193,114,197,
1328 112,178,40,8,135,174,20,58,95,52,83,30,235,240,240,213,73,165,0,75,129,
1329 208,162,26,233,227,4,1,83,32,65,184,243,206,59,203,13,121,21,190,142,204,
1330 227,212,157,119,222,41,87,12,167,151,94,122,73,230,9,20,8,81,119,119,119,
1331 90,90,90,73,73,137,92,246,89,212,100,74,74,10,136,154,52,105,146,60,142,
1332 225,164,7,225,172,89,179,44,5,194,207,63,255,92,230,25,78,6,16,210,169,
1333 228,138,225,100,81,16,162,150,58,117,179,168,165,164,64,168,52,50,5,18,
1334 132,62,62,23,129,137,151,121,156,154,51,103,142,143,15,23,62,254,248,227,
1335 50,79,0,65,8,204,202,203,203,253,115,247,219,218,218,146,146,146,124,63,
1336 247,171,7,225,236,217,179,45,5,66,146,201,60,195,201,0,194,67,15,61,84,
1337 174,24,78,214,5,225,224,128,163,185,92,254,86,178,128,20,8,149,70,166,64,
1338 130,208,199,71,167,13,32,92,187,118,173,143,32,212,127,192,61,48,32,108,
1339 104,104,136,141,141,29,254,147,76,158,85,86,86,22,0,16,54,53,53,201,108,
1340 78,141,5,8,231,205,155,39,243,12,39,3,8,15,59,236,48,185,98,56,209,81,101,
1341 30,37,37,175,82,32,84,26,153,2,9,66,31,175,6,25,64,24,23,23,231,35,8,111,
1342 191,253,118,153,39,32,32,236,239,239,143,143,143,111,110,110,150,203,126,
1343 169,183,183,119,151,93,118,145,199,49,156,244,32,244,253,57,66,106,207,
1344 128,234,177,0,225,194,133,11,101,158,225,100,0,161,239,15,212,223,120,227,
1345 141,50,143,146,146,87,41,16,42,141,76,1,3,33,216,56,238,184,227,228,134,
1346 188,202,0,194,180,180,52,31,65,168,255,74,81,0,64,88,83,83,99,126,233,154,
1347 31,242,253,110,17,61,8,95,124,241,69,31,65,56,121,242,100,195,215,19,199,
1348 2,132,171,87,175,150,121,134,147,1,132,187,237,182,155,92,49,156,238,190,
1349 251,110,153,71,73,201,171,20,8,149,70,166,64,130,240,130,11,46,144,27,242,
1350 42,195,205,50,235,214,173,243,17,132,79,63,253,180,204,51,246,32,36,125,
1351 81,81,81,109,109,173,92,222,2,157,112,194,9,242,56,134,147,254,195,188,
1352 207,60,243,140,143,79,110,28,112,192,1,134,79,54,142,5,8,113,142,101,158,
1353 225,4,8,181,71,69,33,244,180,105,211,228,138,225,244,223,255,254,87,228,
1354 82,82,242,46,5,66,165,145,41,96,32,196,115,186,241,198,27,229,134,188,234,
1355 201,39,159,148,121,156,154,59,119,174,143,32,156,61,123,182,204,19,16,16,
1356 230,230,230,106,223,215,221,18,93,118,217,101,242,56,134,211,205,55,223,
1357 44,243,56,28,184,191,19,39,78,148,43,188,234,180,211,78,51,220,180,60,22,
1358 32,44,40,40,240,209,67,221,115,207,61,181,207,102,49,147,240,253,227,204,
1359 31,125,244,145,200,165,164,228,93,10,132,74,35,83,192,64,8,57,158,123,238,
1360 57,185,33,175,186,252,242,203,101,30,167,174,188,242,74,185,98,56,45,88,
1361 176,64,230,25,123,16,194,245,252,252,124,191,107,67,175,71,30,121,68,30,
1362 199,112,58,239,188,243,68,22,246,126,213,85,87,201,216,225,116,237,181,
1363 215,210,202,34,163,208,88,128,176,186,186,26,87,79,102,243,42,92,192,149,
1364 43,87,138,92,137,137,137,59,238,184,163,92,49,156,86,173,90,37,114,41,41,
1365 121,151,2,161,210,200,20,48,16,162,249,243,231,251,242,114,25,44,227,178,
1366 101,203,234,234,234,106,106,106,190,248,226,11,31,61,6,220,163,228,228,
1367 100,185,167,177,7,33,245,150,146,146,50,42,143,135,126,249,229,151,242,
1368 56,134,211,62,251,236,179,110,221,186,202,202,202,168,168,40,223,111,182,
1369 124,233,165,151,12,23,50,199,2,132,141,141,141,103,156,113,134,204,230,
1370 85,180,20,78,127,69,69,5,236,124,226,137,39,124,244,35,39,77,154,68,127,
1371 144,59,83,82,242,42,5,66,165,145,41,144,32,140,139,139,219,99,143,61,228,
1372 182,188,106,215,93,119,61,243,204,51,79,59,237,52,223,47,32,5,248,165,219,
1373 253,253,253,217,217,217,134,155,80,252,83,97,97,161,239,95,158,58,224,128,
1374 3,78,62,249,100,223,95,75,54,117,234,212,141,27,55,202,61,185,52,22,32,
1375 100,78,240,239,127,255,91,102,27,78,83,166,76,57,229,148,83,254,240,135,
1376 63,248,238,14,94,126,249,229,150,125,43,133,146,213,164,64,168,52,50,5,
1377 18,132,56,1,199,31,127,188,220,214,104,107,75,62,195,228,247,169,209,81,
1378 249,254,84,91,91,219,95,255,250,87,121,40,163,45,96,99,254,4,230,88,128,
1379 16,177,89,223,39,46,35,21,135,49,210,54,82,10,91,41,16,42,141,76,129,4,
1380 33,122,226,137,39,124,188,197,99,68,218,102,155,109,230,206,157,171,55,
1381 148,1,0,97,70,70,198,168,220,44,131,115,249,225,135,31,238,176,195,14,242,
1382 104,70,79,84,139,254,253,171,154,198,8,132,16,253,226,139,47,150,57,71,
1383 85,103,156,113,134,213,190,104,173,100,101,41,16,42,141,76,1,6,97,77,77,
1384 205,201,39,159,44,55,55,122,58,246,216,99,245,223,96,66,99,13,66,210,23,
1385 23,23,215,215,215,203,229,45,16,32,204,201,201,185,239,190,251,124,188,
1386 57,214,119,93,121,229,149,110,81,61,70,32,68,84,251,17,71,28,33,51,143,
1387 146,192,249,252,249,243,149,59,168,228,187,20,8,149,70,166,0,131,16,37,
1388 39,39,251,126,73,204,23,77,158,60,121,193,130,5,6,67,57,214,32,68,85,85,
1389 85,153,153,153,91,110,160,169,210,172,172,44,254,254,229,47,127,25,209,
1390 183,136,189,8,166,158,122,234,169,158,238,46,25,59,16,162,85,171,86,249,
1391 254,174,156,97,197,1,60,245,212,83,204,21,228,214,149,148,124,144,2,161,
1392 210,200,20,120,16,98,212,190,255,254,251,195,15,63,92,110,116,203,116,208,
1393 65,7,125,251,237,183,114,211,58,5,0,132,189,189,189,113,113,113,94,156,
1394 194,129,129,1,170,183,171,171,139,191,94,182,159,155,155,43,190,77,200,
1395 223,107,174,185,198,143,15,28,154,117,210,73,39,1,105,177,125,179,198,20,
1396 132,61,61,61,31,125,244,145,239,183,243,120,209,14,59,236,96,183,219,13,
1397 111,3,80,82,26,86,10,132,74,35,83,224,65,136,196,201,64,28,32,185,93,127,
1398 117,238,185,231,70,69,69,185,117,23,2,0,66,132,83,152,144,144,64,29,202,
1399 101,167,88,172,172,172,76,74,74,98,21,164,140,141,141,229,47,191,43,42,
1400 42,26,27,27,13,79,50,180,182,182,198,196,196,104,145,96,245,173,183,222,
1401 218,66,143,249,236,179,207,78,79,79,247,82,162,49,5,33,162,6,160,187,239,
1402 79,58,122,210,243,207,63,191,37,47,52,87,10,91,41,16,42,141,76,227,2,66,
1403 161,246,246,246,89,179,102,225,26,142,244,62,17,210,31,121,228,145,239,
1404 190,251,46,190,130,39,115,31,24,16,162,194,194,194,154,154,26,178,163,238,
1405 238,110,16,24,25,25,9,6,138,139,139,155,155,155,177,227,112,154,31,16,46,
1406 63,63,63,58,58,58,43,43,171,174,174,78,192,27,103,177,168,168,8,58,138,
1407 77,9,1,69,242,226,26,238,177,199,30,62,62,99,39,68,226,131,15,62,120,246,
1408 236,217,195,194,99,172,65,40,68,251,226,26,30,118,216,97,59,238,184,227,
1409 136,46,127,146,254,138,43,174,72,73,73,49,76,26,148,148,124,148,2,161,210,
1410 200,132,173,153,63,127,254,115,190,9,110,141,250,179,92,181,181,181,255,
1411 251,223,255,30,124,240,193,211,79,63,125,202,148,41,210,22,186,19,107,73,
1412 115,223,125,247,125,251,237,183,184,98,50,191,7,181,180,180,188,253,246,
1413 219,242,184,135,211,55,223,124,35,179,141,92,80,39,53,53,181,186,186,154,
1414 67,194,118,231,229,229,177,107,79,88,133,220,16,58,51,51,83,220,113,202,
1415 15,79,55,67,178,133,248,248,248,215,94,123,13,36,28,116,208,65,94,174,29,
1416 178,234,232,163,143,190,229,150,91,40,47,148,149,249,189,10,36,203,146,
1417 15,39,187,221,158,150,150,38,179,249,165,134,134,134,31,127,252,241,222,
1418 123,239,253,195,31,254,48,117,234,84,121,208,238,52,109,218,180,139,46,
1419 186,232,177,199,30,251,225,135,31,70,229,118,92,165,176,149,2,161,210,136,
1420 229,116,102,124,149,204,51,218,194,151,130,136,24,232,21,43,86,188,249,
1421 230,155,79,61,245,212,191,254,245,175,59,238,184,227,161,135,30,122,250,
1422 233,167,49,241,235,214,173,219,180,105,19,105,124,127,116,79,30,177,111,
1423 146,121,252,82,83,83,83,76,76,76,66,66,2,80,244,197,137,97,50,129,207,23,
1424 21,21,5,183,188,239,26,199,145,141,195,78,182,63,119,238,220,103,158,121,
1425 230,158,123,238,185,225,134,27,110,188,241,198,71,31,125,116,198,140,25,
1426 184,107,73,73,73,21,21,21,184,95,35,42,133,179,208,62,73,102,216,50,117,
1427 118,118,226,55,83,222,37,75,150,188,241,198,27,15,63,252,240,237,183,223,
1428 126,221,117,215,81,28,112,251,254,251,239,47,90,180,168,160,160,0,106,26,
1429 206,51,43,41,249,33,5,66,165,80,144,180,193,46,201,88,75,138,195,195,171,
1430 131,130,128,13,63,175,185,185,217,237,53,75,77,24,122,112,30,23,23,87,84,
1431 84,132,179,53,162,107,96,162,54,52,201,216,32,148,44,128,75,50,86,73,105,
1432 148,164,64,168,164,20,80,181,181,181,101,102,102,226,167,226,147,193,182,
1433 13,27,54,128,55,80,103,184,215,17,47,16,175,168,176,176,48,37,37,5,94,214,
1434 215,215,3,0,254,146,88,221,21,169,164,52,186,82,32,84,82,10,156,240,255,
1435 240,237,90,91,91,197,34,108,19,87,1,137,140,136,136,16,119,205,0,63,104,
1436 199,34,130,130,141,141,141,154,203,72,250,146,146,18,210,139,69,37,37,165,
1437 81,145,2,161,146,82,128,52,48,48,80,94,94,238,233,94,146,238,238,110,48,
1438 89,85,85,85,81,81,129,131,136,59,232,214,243,35,50,49,49,113,84,222,89,
1439 170,164,164,36,164,64,168,164,20,32,225,8,70,69,69,109,249,7,40,106,106,
1440 106,138,139,139,213,165,50,37,165,209,146,2,161,146,82,32,4,183,160,215,
1441 168,0,172,183,183,55,47,47,79,93,41,84,82,26,45,41,16,42,41,5,66,240,47,
1442 55,55,215,203,251,213,124,87,127,127,127,90,90,154,118,161,81,73,73,105,
1443 11,165,64,168,164,20,8,1,194,210,210,210,81,121,207,14,155,194,35,212,127,
1444 85,88,73,73,105,75,164,64,168,164,20,8,225,198,21,21,21,141,214,123,118,
1445 216,84,93,93,157,92,80,82,82,218,50,41,16,42,41,5,66,125,125,125,41,41,
1446 41,163,8,194,178,178,50,185,160,164,164,180,101,82,32,84,82,10,132,240,
1447 8,115,115,115,183,252,150,81,33,5,66,37,165,81,148,2,161,146,82,32,52,48,
1448 48,144,159,159,63,42,215,8,217,20,76,53,124,131,66,73,73,201,111,41,16,
1449 42,41,5,66,131,131,131,5,5,5,163,117,215,104,70,70,198,136,94,58,170,164,
1450 164,228,69,10,132,74,74,129,16,32,44,46,46,30,149,183,163,117,117,117,101,
1451 102,102,170,175,46,40,41,141,150,20,8,149,148,2,164,182,182,182,232,232,
1452 232,45,127,16,30,207,18,249,242,253,38,37,37,37,95,164,64,168,164,20,32,
1453 225,20,110,218,180,41,61,61,93,46,251,165,246,246,246,168,168,40,117,94,
1454 84,73,105,20,165,64,168,164,20,56,117,118,118,198,198,198,226,26,202,229,
1455 17,10,148,166,164,164,212,214,214,242,67,70,41,41,41,109,177,20,8,149,148,
1456 2,42,241,61,66,63,94,144,6,252,202,203,203,11,10,10,212,91,70,149,148,70,
1457 87,10,132,74,74,1,21,60,107,104,104,72,72,72,24,41,11,203,202,202,112,7,
1458 213,73,81,37,165,81,151,2,161,146,210,152,11,248,245,247,247,247,246,246,
1459 106,119,184,52,54,54,194,194,230,230,102,226,69,140,39,145,183,171,171,
1460 75,124,188,215,239,115,170,74,74,74,94,164,64,168,164,52,230,106,106,106,
1461 202,204,204,76,76,76,204,206,206,214,92,58,88,152,145,145,65,124,69,69,
1462 133,91,28,130,64,188,198,77,155,54,37,39,39,87,86,86,142,214,235,217,148,
1463 148,148,12,82,32,84,82,26,91,1,176,148,148,148,181,46,149,148,148,136,120,
1464 225,38,66,184,252,252,252,152,152,152,248,248,120,126,55,52,52,64,202,170,
1465 170,42,146,197,198,198,70,70,70,22,23,23,227,17,146,88,228,82,82,82,26,
1466 117,41,16,42,41,141,173,122,122,122,18,18,18,36,6,215,174,45,42,42,146,
1467 43,92,26,24,24,104,110,110,6,129,185,185,185,16,113,253,250,245,56,142,
1468 165,165,165,248,145,234,169,121,37,165,0,72,129,80,73,105,108,37,222,50,
1469 186,110,221,58,40,8,17,189,127,71,16,248,225,8,202,5,37,37,165,128,72,129,
1470 80,73,105,204,37,78,129,22,20,20,224,249,121,63,201,169,64,168,164,20,120,
1471 41,16,42,41,89,72,10,132,74,110,85,92,92,76,199,136,113,41,45,45,109,216,
1472 251,141,149,124,151,2,161,82,56,42,58,58,250,243,207,63,159,49,99,198,139,
1473 47,190,248,241,199,31,47,90,180,168,186,186,90,174,27,87,41,16,42,153,149,
1474 157,157,125,198,25,103,76,157,58,117,138,75,123,239,189,247,71,31,125,36,
1475 87,43,109,177,198,13,132,221,221,221,211,166,77,219,201,165,157,119,222,
1476 121,247,221,119,223,103,159,125,14,62,248,224,99,143,61,246,204,51,207,
1477 252,231,63,255,137,133,42,43,43,211,38,62,252,120,254,249,231,101,6,157,
1478 254,241,143,127,136,4,150,82,79,79,207,198,141,27,239,189,247,222,63,252,
1479 225,15,135,31,126,248,126,251,237,39,142,182,182,182,86,166,80,114,170,
1480 190,190,126,223,125,247,21,149,163,233,176,195,14,243,126,45,205,63,181,
1481 180,180,204,156,57,147,62,182,195,14,59,76,154,52,105,27,167,248,49,121,
1482 242,100,44,203,237,183,223,158,153,153,169,159,104,115,12,242,128,116,250,
1483 237,111,127,59,42,31,145,112,43,5,66,79,58,250,232,163,101,3,184,180,199,
1484 30,123,124,250,233,167,114,245,40,233,164,147,78,146,91,119,106,215,93,
1485 119,165,99,28,112,192,1,71,29,117,212,105,167,157,118,253,245,215,211,127,
1486 242,243,243,3,249,114,159,230,230,230,191,255,253,239,19,38,76,248,205,
1487 230,218,126,251,237,127,252,241,199,241,186,157,184,174,174,238,143,127,
1488 252,163,172,38,157,222,125,247,93,153,34,168,52,110,32,236,234,234,218,
1489 106,171,173,100,147,122,214,254,251,239,255,244,211,79,87,86,86,146,5,11,
1490 245,228,147,79,202,21,58,209,75,196,54,253,16,219,172,169,169,1,183,6,109,
1491 97,247,162,116,15,63,252,48,230,85,30,162,78,236,78,38,82,114,138,17,101,
1492 174,40,108,220,168,124,186,79,47,236,215,165,151,94,42,119,224,65,59,238,
1493 184,227,91,111,189,69,243,137,44,28,131,92,161,211,94,123,237,165,61,2,
1494 49,82,185,237,108,250,185,145,2,161,39,97,10,100,3,184,196,12,230,131,15,
1495 62,144,171,71,73,204,114,228,214,61,107,151,93,118,185,245,214,91,243,242,
1496 242,100,30,191,132,133,145,205,191,185,12,247,9,51,58,112,9,228,142,127,
1497 243,27,144,204,196,90,46,252,230,55,135,28,114,72,66,66,194,184,176,144,
1498 78,139,147,42,143,67,167,55,222,120,67,166,8,42,89,29,132,136,169,16,221,
1499 174,179,179,115,44,64,136,165,187,246,218,107,153,238,25,36,208,235,183,
1500 150,44,89,194,40,149,199,183,185,20,8,13,98,68,109,189,245,214,178,118,
1501 92,26,117,16,86,87,87,95,112,193,5,230,105,181,89,83,167,78,157,59,119,
1502 174,200,53,234,32,196,165,144,61,76,167,23,95,124,81,174,86,32,244,44,235,
1503 128,16,209,145,46,191,252,242,45,57,187,131,79,41,155,95,39,124,44,253,
1504 54,91,90,90,174,187,238,58,205,78,238,188,243,206,223,127,255,61,166,233,
1505 146,75,46,17,49,232,176,195,14,107,111,111,151,25,2,40,5,194,209,145,239,
1506 32,68,140,1,113,113,120,212,65,136,125,60,229,148,83,228,134,116,42,46,
1507 46,150,41,252,210,244,233,211,39,78,156,40,183,229,20,179,200,227,142,59,
1508 238,152,99,142,25,117,71,39,216,197,204,64,214,145,78,163,14,194,165,75,
1509 151,238,180,211,78,114,235,195,233,172,179,206,18,179,236,198,198,70,230,
1510 224,6,157,124,242,201,229,229,229,98,179,35,149,126,58,175,233,223,255,
1511 254,183,92,173,64,232,89,150,2,33,218,113,199,29,55,108,216,32,179,141,
1512 92,221,221,221,114,67,58,29,122,232,161,85,85,85,34,1,61,240,211,79,63,
1513 61,232,160,131,14,60,240,64,104,119,194,9,39,204,154,53,75,188,162,111,
1514 211,166,77,87,92,113,5,198,132,85,8,124,138,44,129,20,195,243,175,127,253,
1515 171,28,18,58,205,153,51,71,166,8,42,89,11,132,204,179,68,211,202,101,151,
1516 182,217,102,27,12,89,95,95,159,239,32,108,110,110,78,79,79,95,191,126,253,
1517 34,167,86,173,90,149,151,151,103,254,150,233,72,65,88,88,88,24,23,23,183,
1518 108,217,178,5,11,22,252,252,243,207,9,9,9,110,237,245,99,143,61,102,40,
1519 29,137,229,58,147,196,253,96,36,192,143,228,128,221,30,39,106,109,109,197,
1520 74,26,132,163,204,170,222,222,222,152,152,152,200,200,72,50,186,77,38,182,
1521 80,86,86,182,102,205,154,159,126,250,137,221,49,14,69,164,16,229,90,190,
1522 124,57,229,74,77,77,53,172,210,139,29,101,101,101,109,220,184,113,241,226,
1523 197,162,86,51,51,51,181,19,137,190,136,196,28,42,133,101,95,217,217,217,
1524 180,169,239,32,164,116,184,98,81,81,81,20,225,151,95,126,161,20,44,186,
1525 173,43,131,72,131,215,37,55,173,211,249,231,159,255,248,227,143,155,45,
1526 236,182,219,110,203,100,92,228,109,115,39,243,78,169,91,170,133,3,163,99,
1527 80,147,116,12,183,239,212,30,17,8,217,81,124,124,252,138,21,43,22,46,92,
1528 24,17,17,65,205,123,122,227,182,104,101,189,68,163,48,119,36,23,117,69,
1529 109,231,231,231,235,207,161,209,202,73,73,73,52,196,234,213,171,105,8,25,
1530 235,78,117,117,117,76,67,215,174,93,203,97,208,238,235,214,173,43,42,42,
1531 242,126,58,142,54,165,153,216,47,181,193,174,105,241,17,93,241,165,155,
1532 49,120,87,174,92,73,125,82,3,162,147,251,14,66,138,79,253,211,10,28,45,
1533 245,70,233,124,127,59,157,91,16,238,187,239,190,102,163,132,152,239,82,
1534 195,50,167,75,184,74,137,137,137,162,213,24,110,84,157,219,1,50,44,8,245,
1535 162,191,49,66,197,192,161,92,252,192,104,184,237,249,212,149,232,0,122,
1536 137,131,100,85,116,116,52,134,84,180,160,72,239,86,88,197,228,228,100,234,
1537 159,49,78,175,206,205,205,117,187,47,202,37,134,131,94,114,221,230,194,
1538 139,101,131,152,11,250,3,86,142,70,25,187,171,236,254,201,90,32,196,139,
1539 162,247,100,100,100,48,37,151,81,46,189,255,254,251,61,61,61,190,128,144,
1540 89,252,59,239,188,131,197,161,251,238,190,251,238,59,59,181,235,174,187,
1541 50,144,46,190,248,98,134,189,76,231,112,48,216,72,121,200,33,135,200,13,
1542 233,132,131,255,229,151,95,210,135,100,82,231,125,134,215,95,127,61,19,
1543 180,189,246,218,11,247,14,247,98,218,180,105,252,62,234,168,163,94,122,
1544 233,37,205,66,97,217,231,207,159,127,229,149,87,26,74,55,123,246,108,226,
1545 145,118,153,29,83,130,201,251,199,63,254,33,182,201,214,56,78,14,152,227,
1546 196,64,99,62,12,157,239,254,251,239,63,252,240,195,153,27,106,250,221,239,
1547 126,247,246,219,111,83,222,59,239,188,115,207,61,247,252,207,127,254,131,
1548 57,166,140,114,181,78,28,222,140,25,51,200,190,219,110,187,137,195,190,
1549 236,178,203,68,95,164,239,2,3,198,57,133,66,251,236,179,207,45,183,220,
1550 98,54,184,140,162,185,115,231,158,122,234,169,251,237,183,31,148,210,106,
1551 149,197,115,206,57,199,199,139,246,204,160,79,63,253,116,14,149,99,96,95,
1552 228,125,232,161,135,240,174,100,29,233,100,6,33,163,247,214,91,111,165,
1553 174,180,236,148,130,69,142,150,85,50,145,7,81,231,212,158,220,180,75,59,
1554 236,176,131,24,225,127,251,219,223,204,167,76,1,60,25,233,0,88,70,131,206,
1555 60,243,204,138,138,10,177,101,68,74,166,198,7,31,124,48,199,204,129,209,
1556 49,56,182,189,247,222,251,184,227,142,123,253,245,215,53,35,200,49,124,
1557 241,197,23,88,58,185,3,157,46,185,228,18,86,9,84,12,217,173,236,13,52,141,
1558 205,102,163,107,81,70,42,153,109,178,113,170,235,236,179,207,254,236,179,
1559 207,12,29,3,255,64,54,179,78,140,20,118,253,224,131,15,146,107,168,93,119,
1560 217,133,217,58,149,32,0,207,52,241,186,235,174,227,32,57,96,186,4,105,158,
1561 121,230,25,141,253,154,48,202,175,188,242,202,241,199,31,79,175,32,25,135,
1562 33,186,40,189,133,65,7,71,101,58,157,64,224,221,119,223,77,45,209,76,236,
1563 84,212,6,191,57,36,218,218,151,43,14,84,20,253,153,193,75,193,69,95,165,
1564 194,193,137,47,32,4,66,79,61,245,212,17,71,28,65,46,246,203,209,138,122,
1565 163,215,205,155,55,207,203,12,79,19,71,46,183,174,19,123,161,171,48,168,
1566 229,178,75,119,220,113,135,30,177,24,174,71,30,121,132,38,166,98,69,171,
1567 81,105,84,29,199,207,216,209,15,16,6,194,39,159,124,34,183,162,19,71,203,
1568 136,6,255,250,43,133,152,130,171,174,186,138,58,215,122,62,63,88,188,237,
1569 182,219,152,37,200,68,78,81,192,71,31,125,84,116,0,189,56,126,26,235,140,
1570 51,206,16,91,160,5,41,38,6,65,179,69,154,176,6,88,179,35,143,60,146,195,
1571 166,8,162,2,169,121,28,80,208,174,47,44,221,21,123,56,52,30,54,215,231,
1572 159,127,46,83,56,69,79,166,107,105,27,20,93,136,109,138,145,91,80,80,32,
1573 211,141,183,44,7,66,38,146,204,95,48,205,50,202,165,153,51,103,210,204,
1574 222,65,40,208,114,226,137,39,154,183,172,105,202,148,41,140,109,49,199,
1575 124,247,221,119,61,165,196,50,98,56,152,133,145,12,210,188,252,242,203,
1576 94,182,73,98,220,74,198,42,137,41,23,189,193,108,88,137,17,18,215,8,5,87,
1577 24,39,196,200,20,155,139,248,155,110,186,137,93,147,88,136,98,202,117,46,
1578 109,189,245,214,255,247,127,255,71,31,21,27,193,4,112,192,208,81,172,213,
1579 235,217,103,159,53,31,63,21,133,187,240,240,195,15,227,112,203,40,167,216,
1580 26,36,214,59,52,240,149,189,123,58,84,196,42,140,172,91,31,72,19,19,115,
1581 72,44,51,184,68,70,179,129,67,12,21,13,132,24,133,143,63,254,152,1,236,
1582 246,0,136,220,110,187,237,152,155,123,154,141,34,122,14,163,78,102,112,
1583 9,83,34,216,131,65,49,87,14,238,53,171,56,6,185,172,19,70,86,92,35,164,
1584 173,103,205,154,53,117,234,84,185,194,36,142,237,152,99,142,193,90,209,
1585 51,105,74,183,199,143,136,71,24,154,161,99,109,170,72,93,252,206,201,39,
1586 158,232,37,49,224,164,50,53,28,66,98,185,78,39,140,148,249,154,40,197,132,
1587 250,228,61,247,220,115,101,148,75,244,1,208,171,89,58,198,32,254,28,67,
1588 192,211,97,32,218,8,107,174,101,161,153,152,59,98,100,189,28,57,67,3,63,
1589 195,173,123,33,68,23,210,250,179,94,160,197,208,75,145,30,132,212,112,92,
1590 92,28,195,208,203,222,193,9,179,46,239,51,54,142,80,102,208,233,127,255,
1591 251,31,185,64,20,61,77,70,57,197,100,66,43,62,29,6,4,122,217,251,69,23,
1592 93,148,147,147,35,246,126,195,13,55,120,73,201,20,10,47,156,100,204,71,
1593 159,123,238,57,115,193,133,72,137,1,193,140,104,227,142,14,201,196,90,174,
1594 214,233,158,123,238,49,155,5,178,235,167,17,20,132,185,254,239,127,255,
1595 123,79,7,198,97,252,191,255,247,255,180,75,152,195,94,35,132,178,223,126,
1596 251,173,167,97,139,136,103,12,254,240,195,15,102,175,58,240,178,22,8,177,
1597 236,52,6,107,237,118,187,140,114,9,20,13,11,194,188,188,60,166,63,50,214,
1598 179,182,221,118,91,236,23,233,1,161,167,70,66,24,104,184,66,95,252,215,
1599 191,254,229,169,47,234,197,188,143,97,70,185,204,230,94,47,1,66,60,81,195,
1600 160,50,139,105,193,63,255,249,79,38,239,206,194,185,7,33,229,197,28,136,
1601 197,167,159,126,218,19,8,61,9,63,70,203,174,23,77,243,230,155,111,138,253,
1602 226,112,156,118,218,105,114,133,103,81,171,180,154,151,73,183,254,230,183,
1603 97,165,7,225,87,95,125,181,227,142,59,202,21,30,52,121,242,228,39,158,120,
1604 194,147,133,165,81,110,188,241,70,153,212,165,237,183,223,94,56,118,215,
1605 92,115,141,185,27,48,43,103,149,119,16,226,156,185,189,49,216,32,236,26,
1606 237,2,8,229,178,7,13,129,176,175,55,117,217,167,135,29,176,183,140,242,
1607 32,142,22,23,71,59,135,230,22,132,248,187,134,171,212,66,244,228,67,14,
1608 57,196,109,183,167,206,181,25,122,68,68,4,236,145,43,60,139,189,204,159,
1609 63,95,100,97,82,229,118,78,99,16,182,123,205,154,53,34,139,89,179,103,207,
1610 166,35,201,164,195,73,15,66,236,6,216,150,43,60,139,65,234,253,242,191,
1611 23,16,226,235,80,94,25,229,20,100,21,78,21,30,30,189,66,198,122,16,99,10,
1612 22,138,185,23,211,20,25,235,78,199,30,123,44,32,164,51,227,180,13,219,193,
1613 72,128,85,116,30,187,71,16,226,138,201,95,155,11,183,91,123,124,118,221,
1614 186,117,190,84,224,95,254,242,23,97,145,134,5,225,194,133,11,113,94,101,
1615 172,103,225,32,46,95,190,92,100,25,71,89,20,132,47,188,240,130,140,114,
1616 137,152,97,65,232,189,123,233,133,99,78,87,243,5,132,76,226,112,231,101,
1617 148,87,49,44,151,46,93,234,11,8,139,138,138,232,235,114,217,171,48,10,204,
1618 152,196,44,210,12,66,164,175,195,103,158,121,198,19,8,169,88,236,190,92,
1619 216,92,48,198,45,230,255,250,215,191,50,83,67,56,10,230,150,114,171,163,
1620 143,62,90,27,87,102,185,53,172,12,81,183,123,215,64,88,89,89,137,147,33,
1621 99,189,138,250,95,182,108,153,216,151,65,244,156,59,238,184,67,166,211,
1622 233,195,15,63,100,45,238,242,229,38,225,15,177,202,11,8,241,233,175,190,
1623 250,106,25,165,211,62,251,236,35,127,185,68,237,225,42,185,221,148,94,67,
1624 32,108,46,253,219,31,79,247,210,39,53,177,205,199,30,123,76,116,12,183,
1625 32,68,123,238,185,167,252,101,146,167,137,157,118,94,203,124,109,194,147,
1626 78,62,249,100,113,126,5,38,153,143,28,83,43,127,233,116,243,205,55,235,
1627 79,253,105,162,56,76,74,100,34,157,24,5,83,166,76,145,11,58,105,32,228,
1628 0,216,166,47,245,198,228,0,75,162,63,197,103,144,23,16,126,241,197,23,6,
1629 16,254,249,207,127,6,132,45,45,45,84,130,140,242,42,246,254,223,255,254,
1630 151,189,248,2,66,182,140,59,37,163,188,10,222,172,95,191,158,205,122,2,
1631 33,189,197,237,240,231,120,196,132,143,233,62,80,247,165,2,105,136,5,11,
1632 22,144,101,88,16,98,13,100,212,112,186,242,202,43,221,246,135,64,202,162,
1633 32,196,248,202,40,151,134,5,33,131,193,108,49,201,197,76,220,220,185,153,
1634 134,108,220,184,113,229,202,149,255,254,247,191,221,26,232,71,30,121,4,
1635 255,134,238,136,9,147,81,46,225,132,225,122,46,94,188,216,220,111,158,123,
1636 238,57,14,131,174,64,23,49,175,61,241,196,19,95,121,229,149,182,182,182,
1637 85,171,86,153,225,138,223,147,155,155,123,160,233,154,252,5,23,92,32,28,
1638 29,183,32,212,203,19,8,169,85,140,44,131,217,108,77,166,78,157,202,100,
1639 150,25,153,217,123,184,248,226,139,25,30,8,34,202,40,151,24,204,180,133,
1640 249,170,27,18,231,135,205,162,212,28,134,76,228,18,254,104,118,118,118,
1641 70,70,134,217,46,107,32,252,244,211,79,205,46,2,245,140,159,106,54,19,76,
1642 87,197,238,12,98,152,129,13,153,72,39,218,232,189,247,222,243,114,70,215,
1643 11,8,65,190,249,206,23,14,140,146,154,189,207,255,252,231,63,236,133,191,
1644 110,193,112,234,169,167,178,42,41,49,97,83,196,162,195,15,52,246,70,97,
1645 109,49,22,134,30,69,107,138,179,193,110,65,120,217,101,151,209,243,33,189,
1646 92,214,233,156,115,206,161,151,178,71,115,163,211,63,217,32,190,166,185,
1647 206,197,21,104,243,16,195,141,96,178,72,174,59,239,188,83,70,185,4,213,
1648 128,196,235,175,191,46,151,93,186,240,194,11,245,231,252,53,113,84,244,
1649 58,153,72,167,247,223,127,159,233,227,126,251,237,39,151,93,210,64,88,94,
1650 94,126,212,81,71,201,88,151,216,59,117,126,219,109,183,201,101,151,126,
1651 255,251,223,123,105,113,47,32,156,59,119,174,1,39,52,10,77,19,23,23,103,
1652 182,33,15,63,252,48,158,19,45,43,151,93,98,224,183,183,183,127,251,237,
1653 183,79,60,241,132,140,210,9,164,145,241,205,55,223,36,47,220,149,177,46,
1654 49,90,225,22,85,97,56,153,132,33,125,252,241,199,177,18,158,64,136,149,
1655 163,200,216,31,185,236,18,25,197,92,144,206,140,167,46,99,93,98,52,145,
1656 235,186,235,174,147,203,46,221,123,239,189,236,200,59,8,49,68,134,238,74,
1657 99,125,252,241,199,249,249,249,102,36,211,34,91,248,184,218,150,203,138,
1658 32,196,200,222,125,247,221,50,202,165,97,79,141,38,37,37,153,79,160,189,
1659 244,210,75,172,50,95,31,34,37,36,99,21,61,192,237,93,163,140,249,161,163,
1660 116,56,32,162,140,114,233,204,51,207,164,19,208,114,230,139,67,247,221,
1661 119,31,7,73,46,102,124,102,16,10,51,205,136,154,61,123,182,121,45,150,189,
1662 161,161,225,236,179,207,150,203,46,209,129,196,115,66,126,131,240,152,99,
1663 142,193,177,75,73,73,49,91,49,120,195,144,131,118,102,74,225,19,112,60,
1664 77,77,77,199,29,119,156,140,114,9,191,129,82,208,173,229,178,78,158,110,
1665 142,165,198,204,187,56,225,132,19,42,42,42,216,139,217,198,105,32,4,42,
1666 230,186,18,119,18,153,125,47,28,125,183,22,22,125,243,205,55,110,39,197,
1667 147,39,79,134,52,158,110,183,241,2,194,210,210,82,195,156,151,254,140,77,
1668 36,23,46,166,225,152,177,110,194,11,113,123,146,249,255,254,239,255,134,
1669 118,214,214,240,203,199,207,238,60,117,51,159,3,209,169,88,137,45,51,115,
1670 75,92,86,116,11,66,113,162,56,53,53,213,140,180,167,158,122,138,254,64,
1671 133,152,199,203,131,15,62,200,6,241,134,205,83,19,236,50,171,206,59,239,
1672 60,185,236,18,181,33,110,217,48,220,75,66,109,136,231,35,89,43,163,92,162,
1673 147,139,107,96,6,193,117,24,41,19,233,36,158,82,48,123,93,26,8,25,251,230,
1674 98,206,152,49,131,58,103,210,38,151,93,162,31,98,142,157,59,116,35,47,32,
1675 132,79,236,81,70,57,37,78,141,50,87,54,119,45,241,202,27,253,3,127,154,
1676 214,174,93,203,42,12,133,92,214,137,189,107,103,188,205,19,208,93,119,221,
1677 85,84,133,249,156,211,21,87,92,193,80,245,4,66,142,144,92,87,95,125,181,
1678 161,91,210,70,76,83,88,133,87,32,163,116,154,57,115,38,253,4,252,203,101,
1679 151,206,63,255,124,198,172,119,16,206,159,63,223,176,47,156,105,113,163,
1680 34,230,72,70,185,132,201,26,247,187,102,172,5,66,134,31,189,132,249,157,
1681 249,204,12,240,160,207,121,1,33,238,157,185,59,138,11,24,230,201,23,41,
1682 191,254,250,107,86,13,11,66,243,236,158,206,205,68,137,121,153,249,138,
1683 200,13,55,220,64,185,200,229,5,132,244,45,243,241,80,112,12,43,76,162,147,
1684 201,40,157,196,189,206,126,131,144,254,202,78,233,106,230,203,24,56,40,
1685 67,133,116,56,112,145,101,148,75,228,2,3,200,224,164,82,46,81,117,63,254,
1686 248,163,140,210,201,112,207,152,38,183,32,60,233,164,147,24,246,160,11,
1687 128,201,40,151,4,8,49,229,127,252,227,31,101,148,78,140,91,182,105,190,
1688 30,76,1,161,130,216,163,65,204,51,220,218,56,68,137,40,254,107,175,189,
1689 102,118,20,56,6,153,72,39,1,66,26,197,188,65,38,236,88,204,231,159,127,
1690 158,190,205,102,53,49,137,166,247,178,65,183,182,131,233,252,208,206,170,
1691 139,254,247,217,71,147,77,87,142,233,45,172,196,33,51,87,160,184,142,235,
1692 22,132,164,167,246,112,208,205,151,162,95,125,245,85,86,45,90,180,200,124,
1693 90,130,227,100,131,95,125,245,149,121,95,226,228,27,61,92,46,187,132,117,
1694 22,171,46,184,224,2,25,229,18,94,56,59,98,6,38,107,193,37,42,193,237,41,
1695 116,79,32,20,103,137,152,128,202,101,151,52,16,174,90,181,74,70,233,196,
1696 42,246,206,4,90,46,235,180,112,225,66,231,14,221,200,109,39,161,66,56,96,
1697 198,175,92,118,233,166,155,110,130,181,180,130,217,148,125,247,221,119,
1698 108,13,152,81,94,25,229,210,188,121,243,88,229,22,132,71,28,113,132,86,
1699 51,102,187,196,160,16,51,45,92,40,25,229,18,137,153,83,122,2,161,48,131,
1700 56,199,134,131,225,176,167,79,159,206,42,183,99,249,157,119,222,161,2,127,
1701 248,225,7,185,236,210,177,199,30,203,176,245,14,194,183,222,122,203,176,
1702 47,220,134,244,244,116,86,153,155,152,225,159,149,149,197,170,113,148,181,
1703 64,136,48,205,230,137,42,41,105,203,62,175,207,17,126,255,253,247,230,49,
1704 255,165,115,42,196,124,92,46,187,36,252,116,86,13,11,194,203,46,187,76,
1705 70,185,132,105,134,88,100,52,115,229,242,203,47,199,187,34,151,23,16,82,
1706 10,230,248,50,202,37,1,194,150,150,22,183,32,204,118,62,230,229,5,132,7,
1707 31,124,48,174,198,71,31,125,228,22,132,167,159,126,186,39,16,210,5,135,
1708 10,233,112,152,157,69,122,57,211,118,186,187,153,145,98,36,227,82,200,101,
1709 157,180,43,4,6,249,7,194,206,206,206,115,206,57,71,70,233,180,124,249,114,
1710 236,136,217,35,220,101,151,93,196,148,217,173,222,125,247,93,47,119,120,
1711 226,111,49,193,55,220,143,238,5,132,149,149,149,230,115,77,244,13,188,141,
1712 5,11,22,220,185,185,240,15,196,85,16,179,199,143,112,209,196,238,240,186,
1713 204,181,244,192,3,15,80,88,188,70,179,71,40,30,64,116,11,66,182,233,9,132,
1714 204,244,89,181,116,233,82,115,203,222,125,247,221,108,240,237,183,223,54,
1715 239,235,219,111,191,165,111,83,69,114,217,37,104,42,110,118,48,51,18,139,
1716 9,195,232,216,212,192,45,183,220,114,221,117,215,221,113,199,29,252,126,
1717 233,165,151,24,65,67,5,222,92,158,64,24,19,19,195,90,47,32,196,56,200,40,
1718 157,152,58,211,127,204,119,27,32,106,192,185,67,55,114,11,194,61,157,143,
1719 130,200,5,157,48,71,128,208,237,35,170,56,145,108,205,45,8,63,249,228,19,
1720 86,209,166,230,74,62,234,168,163,52,16,154,31,235,218,109,183,221,232,222,
1721 116,164,35,143,60,82,70,185,196,164,144,177,239,9,132,226,66,224,237,183,
1722 223,110,6,33,179,34,86,49,127,149,81,58,121,2,33,227,14,243,232,29,132,
1723 207,61,247,156,92,118,137,161,151,156,156,204,42,179,147,195,6,153,45,177,
1724 106,28,101,57,16,186,213,180,105,211,34,34,34,176,230,94,64,136,17,49,156,
1725 184,64,248,245,212,190,217,117,0,60,140,19,114,13,11,66,243,89,126,1,66,
1726 183,179,102,204,156,56,141,233,5,132,140,28,179,151,233,29,132,226,194,
1727 155,91,16,82,51,204,121,33,37,68,97,215,110,65,248,135,63,252,193,19,8,
1728 241,246,134,10,233,14,132,224,19,16,82,63,230,102,2,132,108,208,237,237,
1729 39,226,94,0,179,252,3,33,150,209,108,254,16,246,2,240,83,105,114,217,37,
1730 44,251,202,149,43,229,46,77,162,230,63,251,236,51,115,73,245,58,244,208,
1731 67,33,4,227,95,100,241,2,66,26,203,237,137,175,227,142,59,14,143,89,248,
1732 127,102,153,159,91,64,79,63,253,180,88,139,137,52,119,27,172,48,133,221,
1733 123,239,189,205,171,104,2,114,141,20,132,51,102,204,240,4,66,40,197,6,177,
1734 236,102,27,77,161,126,254,249,103,243,13,56,76,91,133,131,229,22,57,116,
1735 48,124,14,90,57,53,53,149,89,63,221,102,168,156,30,228,55,8,153,103,200,
1736 40,157,152,29,210,243,221,222,9,137,153,118,238,208,141,60,157,54,112,43,
1737 38,7,116,42,183,70,201,11,8,197,101,57,64,104,30,17,199,28,115,140,184,
1738 171,28,49,4,100,172,75,164,39,1,248,49,183,233,126,251,237,151,151,151,
1739 231,9,132,226,130,133,91,16,98,61,88,229,246,50,135,0,225,138,21,43,152,
1740 208,8,177,119,132,63,58,44,8,31,122,232,33,185,236,210,148,41,83,146,146,
1741 146,18,19,19,205,231,33,0,188,240,116,199,81,193,1,66,58,52,99,201,59,8,
1742 89,203,54,53,181,182,182,130,150,57,115,230,28,113,196,17,230,190,72,151,
1743 194,28,144,107,88,16,98,209,228,22,187,186,152,96,210,252,76,114,153,222,
1744 154,161,139,56,78,6,51,185,188,131,208,124,253,217,59,8,49,34,100,116,11,
1745 66,34,245,147,107,183,32,164,128,158,64,184,255,254,251,139,140,102,60,
1746 96,124,41,236,224,224,160,44,188,83,148,174,162,162,130,9,56,99,192,108,
1747 43,209,99,143,61,38,54,104,144,127,32,164,17,221,130,208,147,152,117,98,
1748 223,229,46,221,73,0,128,221,121,233,123,76,155,180,19,53,94,64,200,90,122,
1749 163,219,74,160,164,120,78,244,19,58,140,216,142,38,243,249,67,164,205,30,
1750 220,130,208,139,232,102,228,26,41,8,95,123,237,53,79,32,252,231,63,255,
1751 201,6,241,57,100,123,119,117,37,36,36,48,22,138,139,139,241,162,204,46,
1752 56,154,60,121,50,19,35,42,138,13,154,247,133,168,162,227,143,63,254,173,
1753 183,222,98,74,42,220,98,79,26,93,16,122,145,188,40,235,78,190,131,16,195,
1754 130,247,79,137,204,15,61,35,47,32,20,199,12,8,205,54,132,89,148,23,16,122,
1755 17,137,115,114,114,104,47,183,32,20,131,194,45,8,197,93,20,94,64,136,176,
1756 129,6,97,22,188,131,16,43,39,250,143,16,99,156,186,122,254,249,231,221,
1757 78,67,241,182,69,19,143,163,172,14,66,134,25,243,110,241,116,179,119,16,
1758 106,98,56,253,242,203,47,143,60,242,8,61,85,166,48,201,119,16,106,162,159,
1759 209,198,151,95,126,185,151,211,107,1,6,33,21,248,204,51,207,12,29,156,75,
1760 110,65,8,111,60,129,80,187,70,104,62,243,35,64,40,214,34,122,255,154,53,
1761 107,48,175,108,205,140,52,77,227,11,66,188,147,31,127,252,81,238,210,179,
1762 168,207,123,239,189,215,203,189,233,116,9,218,130,148,222,65,200,28,220,
1763 173,225,22,218,97,135,29,152,48,25,78,213,186,189,228,137,129,16,107,71,
1764 10,194,43,175,188,146,92,94,64,72,73,205,214,86,92,35,116,11,194,219,110,
1765 187,77,28,137,16,77,67,159,191,230,154,107,204,119,51,105,98,132,126,241,
1766 197,23,204,232,217,215,141,55,222,232,118,102,32,68,223,94,180,104,17,93,
1767 81,110,221,164,128,129,80,92,10,117,43,95,64,200,184,99,164,47,88,176,0,
1768 30,108,9,8,169,58,25,229,18,206,150,54,232,70,4,66,58,51,221,0,163,234,
1769 22,132,226,198,64,51,8,89,196,143,103,149,23,16,58,143,197,141,188,131,
1770 80,19,201,240,155,57,42,183,179,40,33,5,66,35,8,177,149,135,31,126,56,38,
1771 24,248,93,123,237,181,143,62,250,40,8,20,143,160,162,97,65,72,191,140,141,
1772 141,61,251,236,179,169,89,239,148,213,64,200,252,139,62,45,99,117,210,131,
1773 144,182,164,187,224,60,153,207,197,25,116,234,169,167,6,18,132,24,29,113,
1774 102,67,147,91,16,158,112,194,9,158,64,184,247,222,123,139,140,102,155,72,
1775 181,104,147,83,14,224,134,27,110,216,109,183,221,134,157,187,140,47,8,97,
1776 143,48,64,195,10,95,237,235,175,191,118,123,225,71,72,156,77,242,14,66,
1777 68,21,185,125,154,80,136,62,64,65,244,175,33,118,123,54,85,24,35,52,82,
1778 16,94,116,209,69,228,242,14,66,243,237,148,244,25,79,32,196,96,137,35,161,
1779 195,252,244,211,79,52,16,115,11,239,135,180,253,246,219,99,233,146,146,
1780 146,104,44,134,170,151,215,38,176,29,42,220,211,201,115,20,48,16,222,117,
1781 215,93,206,29,186,145,91,16,30,124,240,193,204,141,168,109,198,224,3,15,
1782 60,176,106,213,42,250,173,72,191,37,32,52,60,149,136,78,60,241,68,255,64,
1783 72,51,165,167,167,123,2,161,56,119,125,235,173,183,26,14,134,69,155,205,
1784 198,170,177,0,33,83,231,175,190,250,234,232,163,143,118,251,12,168,94,10,
1785 132,70,171,10,15,162,162,162,168,125,33,192,38,83,59,53,44,8,233,124,134,
1786 27,109,216,5,0,51,179,1,163,252,218,107,175,145,5,67,6,119,101,172,78,26,
1787 8,113,25,207,58,235,44,67,7,162,105,233,4,230,46,206,104,9,36,8,41,133,
1788 184,214,173,201,45,8,143,63,254,120,79,32,36,70,100,52,119,86,160,78,229,
1789 208,4,32,129,49,105,40,14,25,177,11,114,65,39,79,39,157,70,23,132,107,215,
1790 174,165,68,8,51,100,144,161,207,104,98,47,212,128,65,155,54,109,250,243,
1791 159,255,236,118,126,35,238,228,28,22,132,136,86,19,243,36,79,206,16,19,
1792 136,117,235,214,137,3,187,236,178,203,204,29,67,156,158,66,110,65,248,175,
1793 127,253,203,83,97,137,36,151,23,16,166,164,164,152,75,199,238,88,229,22,
1794 132,55,223,124,179,56,146,55,223,124,211,80,28,22,15,60,240,64,243,211,
1795 102,184,53,76,41,216,81,123,123,123,101,101,37,7,243,225,135,31,30,114,
1796 200,33,230,230,22,226,120,94,127,253,117,14,64,236,72,175,209,5,225,251,
1797 239,191,47,170,72,212,149,94,162,222,220,202,45,8,191,251,238,59,178,12,
1798 153,36,147,81,98,107,126,131,208,60,232,24,17,94,64,72,229,111,220,184,
1799 145,35,113,43,14,204,19,8,197,105,18,243,59,7,88,20,103,35,198,2,132,255,
1800 249,207,127,12,187,99,78,118,220,113,199,153,207,168,225,206,138,27,131,
1801 199,81,150,3,161,151,26,161,177,189,128,144,65,200,196,77,70,185,180,223,
1802 126,251,49,87,165,59,202,101,151,24,213,2,33,158,154,83,3,33,189,214,112,
1803 156,12,191,183,222,122,11,110,153,79,58,49,161,11,36,8,201,101,56,17,225,
1804 22,132,199,30,123,44,85,135,221,247,2,66,243,228,84,128,16,235,118,249,
1805 229,151,203,40,151,14,56,224,0,44,251,130,5,11,228,178,78,250,15,41,232,
1806 53,186,32,100,182,196,54,151,45,91,118,207,230,122,232,161,135,196,157,
1807 105,6,49,158,103,205,154,5,171,12,162,207,224,196,92,105,122,67,58,18,103,
1808 29,125,1,161,80,90,90,26,54,197,211,187,172,232,15,24,62,146,185,125,145,
1809 166,0,97,122,69,250,243,51,158,55,175,21,72,46,46,46,134,136,178,156,46,
1810 137,27,190,188,131,208,92,237,96,155,85,110,65,136,223,207,6,243,242,242,
1811 204,190,242,225,135,31,206,216,52,223,40,43,174,17,82,252,142,142,14,90,
1812 51,33,33,33,35,35,131,201,19,123,49,119,69,161,19,78,56,193,124,233,1,141,
1813 46,8,49,238,20,19,63,233,145,71,30,145,245,229,146,120,254,199,173,220,
1814 130,16,170,121,154,96,109,9,8,205,183,141,120,7,225,238,187,239,46,190,
1815 76,178,124,249,242,251,55,215,255,251,127,255,143,206,236,29,132,230,71,
1816 114,89,124,246,217,103,89,229,5,132,216,37,187,221,254,196,19,79,80,76,
1817 77,140,11,239,32,164,63,24,30,102,99,95,140,169,186,186,58,243,96,167,31,
1818 138,17,61,142,10,29,16,174,95,191,222,252,28,33,93,132,182,188,245,214,
1819 91,229,178,75,128,80,188,68,131,230,116,107,106,181,129,106,62,213,115,
1820 212,81,71,193,27,186,157,121,106,163,189,180,34,96,32,20,47,77,213,228,
1821 22,132,71,31,125,244,176,32,52,223,230,32,64,8,39,204,247,220,62,252,240,
1822 195,12,99,183,32,196,88,139,13,26,52,186,32,20,157,196,124,219,58,150,197,
1823 237,91,214,232,3,110,239,113,47,119,126,86,240,243,207,63,55,159,63,196,
1824 185,39,151,239,32,68,180,44,224,113,251,17,124,134,186,152,33,225,128,154,
1825 59,134,0,225,146,180,37,15,62,247,160,121,45,51,107,214,98,1,205,221,251,
1826 218,107,175,101,149,23,16,50,45,48,143,50,1,194,37,75,150,152,65,72,191,
1827 101,131,56,64,230,198,162,2,233,69,230,7,234,233,57,226,230,73,80,193,102,
1828 233,24,8,60,16,3,80,111,185,229,22,115,137,240,132,12,143,169,8,141,5,8,
1829 127,250,233,39,243,197,96,204,136,115,135,110,20,72,16,154,15,204,59,8,
1830 137,17,245,102,126,56,146,85,217,217,217,222,65,104,54,74,44,138,155,12,
1831 230,204,153,35,163,116,18,32,76,76,76,220,119,223,125,233,69,154,176,123,
1832 69,69,69,222,65,248,225,135,31,26,246,69,63,249,234,171,175,88,117,140,
1833 233,129,122,134,173,184,11,100,28,21,58,32,92,184,112,161,249,226,243,103,
1834 159,125,198,170,7,30,120,64,46,187,196,174,133,245,97,134,226,246,181,138,
1835 26,8,13,239,203,64,23,92,112,1,182,27,11,110,238,169,56,254,190,128,144,
1836 181,50,202,37,239,32,196,210,145,209,111,143,240,200,35,143,28,22,132,102,
1837 18,8,16,82,63,230,27,189,24,54,216,5,183,32,100,230,33,54,104,144,127,32,
1838 244,244,28,161,232,36,211,167,79,151,203,46,97,217,221,62,62,193,120,54,
1839 219,14,36,64,200,32,116,123,219,2,46,142,23,16,82,57,230,171,203,17,17,
1840 17,228,98,242,100,238,219,180,47,251,114,107,25,53,16,62,252,226,195,230,
1841 243,171,226,225,138,184,184,56,51,8,135,125,124,34,41,41,201,188,59,1,194,
1842 197,139,23,155,65,120,205,53,215,176,193,247,222,123,207,124,24,226,229,
1843 171,120,180,114,217,37,12,220,55,223,124,195,42,243,227,52,226,200,217,
1844 26,29,85,70,185,164,255,26,154,38,191,65,232,246,57,66,1,194,21,43,86,152,
1845 221,244,145,62,62,49,186,32,228,192,88,5,8,205,7,166,7,161,249,57,66,13,
1846 132,76,226,101,148,75,251,239,191,191,151,199,39,4,8,153,54,25,14,134,69,
1847 209,70,110,159,9,22,32,100,22,110,184,85,10,46,98,30,189,131,144,62,38,
1848 151,93,98,246,147,144,144,192,42,243,165,40,200,202,192,97,213,56,42,116,
1849 64,200,96,48,187,53,68,178,10,163,32,151,93,98,215,52,21,171,240,120,204,
1850 147,92,164,129,208,124,155,223,197,23,95,12,177,176,131,230,71,148,152,
1851 236,12,11,66,70,142,249,5,114,222,65,8,45,200,104,6,33,104,17,183,252,104,
1852 114,11,66,98,134,5,161,153,82,2,132,116,119,179,185,20,51,59,102,30,230,
1853 50,222,115,207,61,98,131,6,249,7,66,14,219,237,149,72,209,73,102,207,158,
1854 45,151,93,194,178,184,61,199,130,21,99,124,202,68,58,81,39,172,101,168,
1855 251,1,66,86,153,31,10,20,247,136,82,63,134,107,213,40,35,35,131,85,110,
1856 59,134,6,194,199,94,123,108,219,73,198,25,137,48,85,32,205,12,66,76,48,
1857 171,188,131,80,46,235,36,64,72,243,153,79,205,93,125,245,213,108,208,124,
1858 129,16,137,215,199,152,31,129,133,70,226,76,227,255,251,127,255,79,70,185,
1859 36,188,13,42,217,124,211,41,24,54,163,197,111,16,46,95,190,92,70,233,36,
1860 64,184,102,205,26,243,117,77,76,188,115,135,110,52,82,16,178,11,243,139,
1861 145,145,23,16,126,255,253,247,172,234,233,233,49,223,72,169,7,161,249,149,
1862 114,26,8,25,245,50,202,37,198,56,94,154,119,16,98,64,12,7,195,34,253,132,
1863 85,76,23,100,148,78,2,132,233,233,233,6,67,71,21,85,86,86,122,7,33,157,
1864 86,46,187,4,237,196,155,101,204,22,21,70,138,119,69,141,163,66,28,132,226,
1865 5,137,143,62,250,168,92,118,137,93,139,219,165,154,154,154,220,222,209,
1866 46,230,239,200,188,150,177,74,46,32,97,30,222,71,29,117,212,176,32,164,
1867 20,230,247,31,34,24,198,102,205,14,16,54,26,118,146,209,45,8,197,27,146,
1868 52,185,5,225,225,135,31,62,186,32,252,244,211,79,177,11,230,87,78,32,241,
1869 68,182,89,110,65,8,108,42,42,42,0,33,243,89,25,229,146,0,33,25,111,112,
1870 247,229,54,241,106,208,87,95,125,85,46,187,68,113,4,111,204,114,123,254,
1871 83,204,67,113,34,205,61,7,51,68,165,121,1,97,115,115,179,185,111,8,183,
1872 9,75,103,56,109,78,17,240,173,89,101,190,133,29,105,32,124,246,221,103,
1873 119,152,98,188,88,11,96,88,203,184,48,131,80,24,29,255,64,136,67,111,6,
1874 225,223,254,246,55,54,56,107,214,44,51,8,197,123,77,241,42,228,178,75,212,
1875 170,120,211,144,249,101,34,79,60,241,4,253,4,3,109,112,110,24,125,110,13,
1876 159,39,16,138,230,54,251,223,26,8,211,210,210,204,198,68,216,113,24,105,
1877 190,222,41,192,224,86,35,5,33,98,71,230,190,45,222,53,248,167,63,253,201,
1878 220,220,98,174,6,8,205,247,52,232,65,104,30,239,16,93,228,53,159,231,167,
1879 187,122,121,197,154,40,175,153,202,44,138,23,248,101,101,101,153,143,243,
1880 229,151,95,198,242,36,39,39,227,2,202,40,167,56,72,97,25,188,128,144,57,
1881 144,92,118,9,218,209,27,89,101,158,235,51,107,244,242,66,168,192,40,116,
1882 64,184,100,201,18,243,188,158,246,96,94,111,30,189,180,186,56,61,2,123,
1883 220,190,240,158,173,177,59,18,208,123,100,148,75,39,156,112,2,152,164,235,
1884 152,175,17,2,33,188,58,114,121,1,33,35,138,185,170,121,45,123,100,158,69,
1885 39,147,203,46,129,70,198,51,25,221,130,80,92,233,212,228,22,132,135,30,
1886 122,168,223,32,196,124,155,115,49,221,99,24,207,156,57,83,46,235,228,9,
1887 132,96,195,188,11,6,54,51,92,106,210,108,226,53,16,2,9,115,70,124,65,240,
1888 105,190,212,122,228,145,71,106,15,219,24,228,214,32,222,122,235,173,107,
1889 215,174,189,233,166,155,204,118,159,118,39,151,23,16,118,119,119,155,31,
1890 156,160,78,176,29,120,84,6,178,146,69,92,35,188,227,142,59,204,77,47,222,
1891 68,186,56,117,241,27,223,190,177,219,158,70,247,5,56,209,135,231,204,153,
1892 131,221,151,81,46,137,19,140,254,129,144,121,140,185,3,139,82,211,63,205,
1893 117,254,222,123,239,209,183,205,231,181,0,225,151,206,23,25,126,98,250,
1894 228,250,205,55,223,220,222,222,142,63,103,168,249,105,211,166,37,38,38,
1895 146,197,32,138,233,118,86,250,216,99,143,209,220,230,19,48,26,8,233,246,
1896 230,89,41,185,104,35,186,138,161,119,97,118,197,231,50,220,202,15,16,50,
1897 5,55,159,0,184,239,190,251,40,142,25,21,76,62,68,23,165,197,25,152,50,214,
1898 37,208,152,157,45,63,185,108,62,243,143,125,99,102,79,161,232,177,50,202,
1899 37,108,11,173,227,29,132,164,49,244,61,22,197,73,5,183,147,209,107,174,
1900 185,6,243,200,44,199,80,129,140,26,154,213,59,8,205,147,84,54,178,104,209,
1901 34,118,100,174,225,29,118,216,65,156,111,24,71,133,14,8,99,99,99,205,183,
1902 62,98,79,25,186,230,110,74,15,16,207,51,225,192,153,175,2,34,186,197,89,
1903 103,157,133,123,97,190,190,136,141,99,254,101,190,228,139,240,189,134,5,
1904 33,98,90,199,129,201,88,151,24,3,116,44,51,203,177,47,98,16,154,65,136,
1905 249,22,206,132,38,183,32,100,203,126,131,144,142,107,254,174,216,238,187,
1906 239,206,180,206,48,79,20,242,4,66,198,182,249,12,21,29,224,148,83,78,113,
1907 251,221,50,13,132,28,182,25,147,108,234,196,19,79,52,55,183,151,107,63,
1908 212,140,249,174,31,132,141,54,151,29,189,253,246,219,228,242,2,66,214,62,
1909 255,252,243,244,88,25,235,212,222,123,239,125,222,121,231,153,63,202,67,
1910 219,97,191,200,130,123,103,238,246,28,3,77,127,203,61,183,196,101,197,157,
1911 119,225,121,134,158,67,49,113,134,48,244,134,120,178,136,109,250,7,66,179,
1912 219,138,174,186,234,42,58,48,6,203,92,39,28,0,141,101,40,47,34,70,120,63,
1913 216,50,195,64,219,121,231,157,169,13,243,123,45,142,63,254,120,81,129,6,
1914 113,84,230,121,39,18,163,216,188,107,13,132,76,50,204,47,65,165,147,80,
1915 69,123,238,185,167,161,222,152,190,152,223,248,163,201,15,16,82,255,102,
1916 72,51,144,105,53,115,23,213,30,97,236,237,237,253,189,233,221,217,84,251,
1917 177,199,30,123,249,229,151,167,164,164,84,87,87,27,46,34,210,115,56,188,
1918 211,79,63,29,239,74,70,57,69,61,188,255,254,251,28,161,119,16,98,232,12,
1919 85,193,226,163,143,62,202,42,42,4,236,201,88,151,68,199,51,156,191,165,
1920 137,191,251,238,59,246,229,29,132,95,125,245,149,97,95,28,60,3,144,97,107,
1921 136,71,12,112,79,159,127,9,152,66,7,132,152,108,51,93,132,204,67,8,137,
1922 11,24,108,243,254,251,239,55,183,141,16,7,195,236,216,124,156,66,230,120,
1923 166,120,190,128,16,247,8,144,120,218,169,38,18,92,122,233,165,94,78,149,
1924 0,66,113,165,83,147,91,16,30,116,208,65,20,115,211,166,77,126,128,144,169,
1925 159,249,254,8,47,242,4,66,132,103,35,19,249,32,13,132,12,57,220,44,243,
1926 89,77,131,168,43,156,105,1,6,183,98,59,76,125,204,78,149,91,81,99,226,186,
1927 172,119,16,226,235,184,157,13,24,68,221,126,244,209,71,98,154,255,245,215,
1928 95,187,229,46,194,148,115,144,224,196,96,230,220,138,52,218,36,218,63,16,
1929 98,206,204,59,186,248,226,139,241,213,114,115,115,205,115,71,33,243,80,
1930 162,19,50,87,195,15,102,176,156,112,194,9,190,244,234,27,111,188,145,225,
1931 47,14,222,160,23,95,124,209,237,104,117,43,13,132,104,217,178,101,94,62,
1932 68,172,137,52,222,47,71,249,1,66,86,61,252,240,195,190,20,156,250,169,116,
1933 125,120,143,33,233,22,90,136,137,17,141,75,27,209,99,205,231,42,204,98,
1934 82,46,222,179,232,29,132,230,243,180,44,10,16,162,149,43,87,122,178,159,
1935 122,157,115,206,57,226,234,143,119,16,186,253,200,168,144,185,255,51,105,
1936 16,159,166,26,71,133,14,8,209,140,25,51,204,23,123,112,95,204,8,65,226,
1937 174,116,148,144,144,96,126,58,74,136,131,41,43,43,115,235,178,224,20,154,
1938 207,198,28,114,200,33,190,128,16,165,165,165,185,189,28,162,23,211,49,241,
1939 224,132,144,185,20,84,160,246,118,46,33,47,32,204,203,203,243,3,132,140,
1940 198,79,63,253,212,108,22,217,53,254,129,185,5,189,128,48,50,50,210,45,54,
1941 220,62,32,161,129,16,129,55,218,221,60,185,214,196,97,48,38,105,71,47,214,
1942 10,245,244,244,192,0,179,99,170,23,118,135,130,107,182,210,59,8,209,234,
1943 213,171,241,111,228,10,15,186,253,246,219,181,19,182,76,215,152,88,184,
1944 181,110,128,16,156,212,213,213,113,144,7,30,120,160,23,195,138,163,48,123,
1945 246,108,141,250,254,129,112,254,252,249,102,16,210,39,241,69,168,168,71,
1946 30,121,196,124,144,248,61,230,11,60,36,155,53,107,22,221,30,124,82,111,
1947 248,43,114,133,7,177,5,38,16,28,0,115,172,142,142,14,67,147,81,177,110,
1948 251,3,99,208,60,180,245,32,68,248,184,230,147,141,122,209,112,120,78,148,
1949 78,102,112,39,63,64,136,232,39,120,84,230,35,212,11,127,104,249,242,229,
1950 20,92,100,97,131,63,255,252,179,121,72,34,1,66,210,224,20,222,118,219,109,
1951 94,88,200,170,179,206,58,139,38,19,219,244,14,66,243,131,61,122,16,210,
1952 157,222,126,251,109,47,19,59,38,163,248,247,204,167,69,122,239,32,68,110,
1953 159,156,57,252,240,195,205,185,168,183,53,107,214,136,92,227,165,144,2,
1954 33,67,139,129,161,191,221,127,167,157,118,98,14,238,246,59,221,26,8,17,
1955 180,163,67,48,95,195,226,235,187,29,7,195,78,177,224,250,171,65,28,54,139,
1956 233,233,233,230,51,27,190,131,16,225,115,188,254,250,235,102,154,34,138,
1957 128,181,210,238,92,21,114,11,66,195,201,64,47,32,204,201,201,49,79,153,
1958 135,5,33,171,58,59,59,191,252,242,75,189,185,167,86,153,185,187,253,238,
1959 149,23,16,98,229,241,66,244,166,10,67,252,244,211,79,99,199,205,39,132,
1960 245,32,68,88,76,144,115,229,149,87,154,79,147,82,168,39,158,120,130,137,
1961 182,102,98,188,168,183,183,23,215,129,134,144,153,55,23,21,5,63,104,23,
1962 109,83,195,130,16,97,26,30,123,236,49,179,9,166,117,112,82,191,248,226,
1963 139,166,166,38,153,212,41,106,245,205,55,223,60,251,236,179,41,163,190,
1964 179,253,249,207,127,206,206,206,142,136,136,192,40,124,245,213,87,119,223,
1965 125,183,249,174,66,42,156,100,224,77,239,251,250,7,66,183,31,230,165,134,
1966 217,26,168,128,220,36,211,159,59,229,104,23,47,94,124,215,93,119,201,101,
1967 151,40,2,221,152,244,128,80,248,133,76,206,142,61,246,88,115,255,135,238,
1968 240,187,162,162,130,233,29,13,193,15,90,205,12,152,210,210,82,124,23,125,
1969 205,92,114,201,37,20,196,108,163,13,32,68,89,89,89,15,62,248,160,249,129,
1970 31,140,248,117,215,93,39,246,43,147,122,144,127,32,68,12,252,207,63,255,
1971 220,252,161,124,180,243,206,59,115,84,140,77,134,161,76,237,20,7,195,212,
1972 129,42,61,242,200,35,245,243,60,13,132,8,87,143,30,203,236,193,236,96,77,
1973 155,54,13,151,145,106,212,142,205,59,8,205,55,67,232,65,136,104,190,228,
1974 228,100,38,100,230,19,48,180,29,132,19,6,65,104,88,16,114,96,255,247,127,
1975 255,167,63,7,67,49,99,99,99,205,143,217,132,53,8,17,221,194,44,239,29,142,
1976 1,44,211,233,164,183,128,100,103,76,174,88,177,226,221,119,223,157,55,111,
1977 30,83,42,98,16,134,195,32,90,93,230,113,138,52,98,227,196,211,159,176,254,
1978 72,219,50,63,24,69,115,231,206,125,231,157,119,24,234,164,33,61,246,66,
1979 110,75,39,45,189,56,54,189,244,199,41,196,70,136,103,66,135,185,196,70,
1980 188,246,218,107,88,64,230,203,140,16,86,201,68,46,185,221,157,161,20,136,
1981 188,114,157,78,98,149,121,11,218,236,88,46,235,164,55,25,28,12,181,177,
1982 118,237,90,14,242,179,207,62,131,208,162,186,100,82,157,204,101,212,75,
1983 228,194,158,50,49,199,16,99,242,68,49,69,253,24,36,178,232,69,94,134,226,
1984 79,63,253,244,241,199,31,51,222,112,85,161,99,91,91,155,185,174,188,139,
1985 237,48,45,120,235,173,183,152,12,97,134,30,126,248,225,233,211,167,179,
1986 89,179,131,130,228,209,184,212,211,211,159,95,220,159,150,231,208,135,212,
1987 220,193,164,172,190,255,45,78,123,253,173,31,30,123,230,237,255,123,114,
1988 214,203,51,190,254,250,199,196,148,156,129,212,188,65,67,98,2,233,89,149,
1989 156,211,159,156,221,31,159,222,29,155,214,73,72,76,46,166,134,53,97,26,
1990 18,83,235,62,251,38,242,133,215,190,124,228,201,55,159,122,238,253,153,
1991 111,255,248,203,218,18,50,26,182,70,96,35,134,144,156,221,71,60,59,50,196,
1992 19,234,26,134,218,136,178,200,54,211,137,86,22,32,36,1,85,129,45,163,195,
1993 207,156,57,147,153,80,92,92,28,248,103,150,80,84,84,4,243,168,118,176,205,
1994 68,1,204,243,67,3,97,94,94,30,131,142,26,230,7,243,30,38,106,175,190,250,
1995 234,71,31,125,196,100,84,140,26,246,75,135,167,119,149,151,151,187,5,33,
1996 34,37,19,130,57,115,230,208,196,105,105,105,162,83,57,171,223,40,115,118,
1997 98,200,30,21,21,5,150,102,204,152,65,79,3,3,236,75,108,100,88,145,76,110,
1998 90,39,183,7,105,22,201,200,206,196,232,219,111,191,165,222,216,59,131,133,
1999 46,218,218,218,234,101,11,100,17,59,229,176,157,86,103,72,44,202,213,78,
2000 145,128,202,167,32,212,9,91,198,92,172,91,183,142,246,50,111,150,141,136,
2001 166,212,75,36,115,107,25,72,47,50,106,98,95,140,142,165,75,151,210,106,
2002 88,36,140,222,134,13,27,200,107,222,151,56,108,131,244,201,248,93,92,92,
2003 188,96,193,2,124,205,69,139,22,137,251,197,200,37,247,173,19,145,34,203,
2004 120,105,60,65,168,164,20,116,194,64,197,231,56,22,68,141,126,88,177,161,
2005 68,50,208,165,149,235,51,13,105,70,37,84,12,61,199,225,94,24,50,13,132,
2006 66,224,13,200,65,187,140,140,12,216,134,203,133,115,150,144,144,208,216,
2007 216,8,17,197,170,252,252,124,108,61,214,19,11,142,75,33,174,87,161,246,
2008 246,118,166,143,76,43,73,67,188,48,118,236,2,16,98,251,176,236,122,111,
2009 70,73,105,28,165,64,168,164,52,2,141,29,8,87,174,207,151,0,116,233,151,
2010 141,181,134,52,163,18,124,1,33,30,0,168,3,93,117,117,117,48,12,248,1,45,
2011 188,7,225,201,137,179,124,120,135,184,107,172,194,77,103,21,200,36,37,98,
2012 149,216,26,32,76,76,76,36,13,34,13,14,55,188,100,155,208,20,172,194,72,
2013 60,66,216,41,238,75,82,82,26,71,41,16,42,41,141,64,56,48,109,237,142,198,
2014 230,209,15,245,13,29,145,145,145,146,129,107,215,198,197,197,85,84,245,
2015 24,210,140,74,232,115,115,214,89,10,255,76,156,31,6,120,240,9,188,193,45,
2016 252,57,164,225,77,156,97,227,7,49,56,127,240,82,172,34,18,7,17,176,57,83,
2017 13,9,16,194,188,218,218,90,146,137,109,138,140,164,33,37,80,36,134,93,136,
2018 51,102,74,74,227,40,5,66,37,37,171,8,54,20,21,21,109,216,176,33,63,63,95,
2019 48,99,188,4,255,56,128,45,60,111,41,64,104,190,10,165,164,100,53,41,16,
2020 42,41,89,72,93,93,93,209,209,209,250,171,116,193,43,56,170,249,145,74,74,
2021 86,150,2,161,146,146,37,84,209,84,81,222,84,94,88,83,184,54,110,109,113,
2022 93,49,191,219,187,218,229,58,37,37,165,177,148,2,161,146,146,37,180,36,
2023 109,201,130,228,5,250,80,92,85,44,215,41,41,41,141,165,20,8,149,148,44,
2024 33,5,66,37,165,241,146,2,161,146,146,37,100,125,16,246,244,244,148,151,
2025 151,235,223,188,131,250,251,251,43,43,43,137,23,55,197,180,181,181,21,23,
2026 23,139,71,200,91,90,90,248,173,46,19,110,161,178,178,178,62,217,92,93,30,
2027 222,212,170,228,183,20,8,149,148,44,33,139,131,16,248,229,230,230,150,150,
2028 150,166,167,167,55,233,94,26,87,81,81,65,124,78,78,14,204,235,236,236,140,
2029 142,142,174,174,174,78,76,76,132,139,252,16,224,148,73,149,70,174,188,188,
2030 188,195,14,59,108,187,205,37,190,213,172,52,138,26,127,16,166,165,165,77,
2031 52,233,128,3,14,40,42,42,98,166,121,210,73,39,201,40,157,222,127,255,125,
2032 153,217,47,157,123,238,185,114,67,58,93,121,229,149,114,117,208,234,201,
2033 39,159,148,133,209,233,154,107,174,97,122,46,83,184,19,118,237,160,131,
2034 14,146,169,93,154,60,121,50,35,80,166,24,61,21,20,20,236,191,255,254,114,
2035 31,46,77,155,54,77,124,119,123,180,196,124,121,235,173,183,150,91,247,160,
2036 41,83,166,44,89,178,68,102,24,61,61,248,224,131,219,108,179,141,220,135,
2037 75,151,94,122,169,92,237,85,129,7,225,137,39,158,40,15,81,167,127,254,243,
2038 159,114,245,230,194,29,220,180,105,83,71,71,71,109,109,109,73,73,137,246,
2039 100,69,102,102,38,67,120,175,189,246,18,217,183,218,106,43,241,99,215,93,
2040 119,93,186,116,41,224,36,189,72,185,133,162,67,138,45,235,181,247,222,123,
2041 231,231,231,215,212,212,156,126,250,233,50,74,167,153,51,103,146,177,187,
2042 187,123,219,109,183,149,81,46,29,127,252,241,144,91,108,57,240,90,182,108,
2043 217,212,169,83,229,161,184,180,207,62,251,36,36,36,200,20,78,149,149,149,
2044 157,112,194,9,242,141,156,206,87,131,138,31,228,253,246,219,111,245,126,
2045 249,88,232,214,91,111,149,71,166,211,237,183,223,46,214,154,135,216,78,
2046 59,237,148,170,251,72,64,112,105,252,65,72,221,137,214,213,107,191,253,
2047 246,19,32,212,247,3,77,91,8,194,179,207,62,91,110,72,167,63,253,233,79,
2048 114,117,208,234,241,199,31,151,133,209,233,239,127,255,187,119,16,98,197,
2049 204,223,228,196,154,143,17,8,205,47,146,102,84,199,197,197,201,20,163,33,
2050 64,104,126,227,179,65,219,111,191,253,226,197,139,101,134,209,211,253,247,
2051 223,111,126,149,252,31,255,248,71,185,218,171,226,242,227,162,115,163,9,
2052 63,39,255,44,126,84,215,87,203,117,99,35,183,223,205,184,237,182,219,228,
2053 234,205,69,173,2,66,254,54,52,52,20,22,22,106,32,76,73,73,129,133,230,47,
2054 248,236,178,203,46,235,214,173,171,171,171,27,45,123,77,135,148,155,214,
2055 105,207,61,247,20,32,252,131,233,251,245,72,188,0,26,16,98,166,101,148,
2056 75,71,29,117,20,165,16,91,14,188,126,254,249,103,243,215,84,40,139,30,132,
2057 28,246,101,151,93,38,215,57,223,8,175,255,216,19,51,0,88,40,147,142,141,
2058 220,190,191,27,58,138,181,230,33,182,227,142,59,42,16,250,47,183,32,196,
2059 52,123,1,225,71,31,125,36,51,251,37,5,66,189,20,8,71,81,119,223,125,183,
2060 121,215,62,130,176,175,191,175,183,175,183,189,163,61,42,38,170,179,171,
2061 147,223,99,61,229,31,107,16,142,110,179,186,5,33,158,40,71,229,9,132,179,
2062 102,205,34,163,91,16,30,113,196,17,100,20,91,14,188,124,1,225,121,231,253,
2063 250,137,102,86,69,69,69,81,243,122,52,78,155,54,205,251,183,21,183,80,10,
2064 132,1,149,91,16,30,120,224,129,197,197,197,158,64,56,103,206,28,153,217,
2065 47,221,119,223,125,103,154,164,255,28,73,144,234,221,119,223,149,133,209,
2066 233,63,255,249,79,71,71,135,76,225,78,10,132,163,40,40,226,55,8,133,56,
2067 248,232,232,232,222,225,190,22,52,42,26,17,8,123,122,122,232,18,109,109,
2068 109,140,74,241,249,17,17,159,157,157,157,148,148,52,94,32,196,49,242,2,
2069 194,217,179,103,147,209,45,8,127,251,219,223,226,74,138,45,7,94,195,130,
2070 144,35,63,231,156,115,206,58,235,44,112,120,197,21,87,204,157,59,87,204,
2071 138,50,50,50,110,185,229,150,75,47,189,148,217,60,107,31,120,224,129,177,
2072 123,65,157,119,16,74,251,162,211,69,23,93,52,142,85,186,133,178,40,8,15,
2073 58,232,32,47,32,252,244,211,79,69,222,90,119,194,136,48,74,115,115,115,
2074 191,254,250,235,247,223,127,127,249,242,229,140,4,145,94,168,189,189,189,
2075 217,36,34,91,90,90,234,76,146,121,28,14,185,172,19,89,228,58,167,250,251,
2076 251,41,203,194,133,11,113,88,63,251,236,179,95,126,249,133,110,225,246,
2077 150,57,142,71,30,171,78,34,37,219,196,64,139,239,135,105,194,56,174,93,
2078 187,118,222,188,121,160,142,141,127,243,205,55,89,89,89,230,45,51,36,100,
2079 97,116,34,175,92,237,20,222,225,178,101,203,196,189,103,177,177,177,140,
2080 46,102,244,230,111,34,186,5,33,123,132,154,140,97,38,34,111,191,253,54,
2081 173,176,106,213,42,142,92,174,54,137,250,164,242,73,198,190,48,238,52,202,
2082 136,64,200,1,44,93,186,244,227,143,63,102,119,63,253,244,19,214,86,51,190,
2083 222,229,55,8,203,203,203,57,96,218,238,195,15,63,92,176,96,1,245,227,253,
2084 245,96,88,165,239,190,251,238,131,15,62,248,254,251,239,201,75,140,219,
2085 239,80,186,5,33,125,96,221,186,117,52,37,38,143,191,27,54,108,192,154,19,
2086 111,6,97,125,125,189,232,33,154,240,12,196,42,126,179,119,179,41,196,69,
2087 19,5,97,227,116,24,106,175,168,168,72,174,211,105,68,32,164,242,75,75,75,
2088 227,227,227,87,175,94,77,229,208,46,239,188,243,78,100,100,36,7,195,34,
2089 222,137,204,239,146,39,16,210,172,75,150,44,209,55,171,92,49,156,220,130,
2090 144,238,228,5,132,28,33,25,221,130,240,176,195,14,99,131,116,233,228,228,
2091 100,70,22,45,206,200,21,77,224,86,180,8,135,202,192,36,229,151,95,126,185,
2092 114,229,74,79,103,86,69,27,25,36,58,18,63,230,207,159,191,98,197,10,95,
2093 60,66,77,49,49,49,212,24,44,196,154,125,241,197,23,152,2,183,199,217,216,
2094 216,40,246,165,23,22,128,85,88,21,74,135,245,224,248,13,95,57,21,194,14,
2095 164,167,167,127,251,237,183,148,110,209,162,69,226,83,160,222,65,40,204,
2096 139,65,110,205,93,78,78,14,198,144,222,248,214,91,111,209,27,177,63,213,
2097 213,99,123,206,223,15,5,37,8,169,83,50,82,239,12,182,157,55,23,233,169,
2098 247,23,94,120,129,145,57,121,242,228,73,147,38,209,225,126,247,187,223,
2099 97,170,52,51,122,249,229,151,179,214,160,235,174,187,14,231,105,215,93,
2100 119,149,203,78,145,81,59,61,245,251,223,255,94,198,58,181,219,110,187,137,
2101 19,47,136,230,167,247,92,114,201,37,216,116,44,172,184,179,139,253,238,
2102 180,211,78,87,93,117,21,253,94,223,63,248,253,228,147,79,202,195,213,41,
2103 34,34,2,107,197,196,138,140,247,222,123,175,72,76,143,121,228,145,71,246,
2104 218,107,175,29,119,220,81,20,135,45,243,131,29,93,112,193,5,12,39,253,150,
2105 159,123,238,57,42,68,30,159,75,116,92,97,40,41,8,35,234,244,211,79,103,
2106 251,226,8,167,76,153,242,215,191,254,245,171,175,190,50,195,201,0,66,134,
2107 49,76,58,247,220,115,41,145,200,46,142,132,223,187,239,190,251,227,143,
2108 63,174,255,136,46,162,170,177,197,76,105,245,251,250,211,159,254,68,45,
2109 49,133,151,251,112,201,0,66,142,19,204,83,111,148,69,95,153,108,129,13,
2110 98,115,13,104,55,203,45,8,41,209,73,39,157,196,60,90,232,252,243,207,215,
2111 190,5,202,209,210,151,238,191,255,126,142,77,43,29,187,102,143,71,30,121,
2112 36,163,23,19,35,82,106,162,66,158,125,246,89,220,32,209,40,36,230,55,76,
2113 162,140,195,130,144,249,193,107,175,189,118,224,129,7,106,109,202,95,126,
2114 83,147,143,61,246,24,125,64,15,66,172,237,161,135,30,42,187,136,75,116,
2115 75,226,63,255,252,115,92,121,178,51,76,68,98,142,10,50,253,229,47,127,49,
2116 55,19,135,71,167,194,50,234,39,19,35,2,33,162,179,129,13,144,163,109,156,
2117 195,166,200,152,105,243,183,112,13,32,212,154,149,62,105,104,86,250,21,
2118 102,122,216,102,117,11,194,125,247,221,151,217,149,39,16,190,247,222,123,
2119 100,244,4,66,136,206,232,224,0,180,70,164,110,153,180,105,67,94,136,90,
2120 101,140,208,247,72,73,26,209,94,28,57,22,0,231,140,10,55,164,103,76,137,
2121 102,210,68,145,193,12,199,201,65,146,247,245,215,95,247,5,132,244,129,255,
2122 253,239,127,167,158,122,170,216,175,168,112,254,82,231,148,154,238,39,158,
2123 81,209,18,227,32,202,253,185,68,19,48,19,250,225,135,31,232,39,226,200,
2124 249,75,222,231,159,127,94,111,55,40,32,70,134,97,168,213,3,173,9,119,111,
2125 188,241,70,121,100,58,105,32,52,155,26,230,211,76,13,197,90,196,46,96,54,
2126 181,193,150,181,14,35,26,157,146,222,115,207,61,250,243,10,227,46,139,130,
2127 240,144,67,14,41,41,41,241,4,66,166,69,100,108,106,106,50,223,152,64,147,
2128 95,122,233,165,230,120,236,14,166,89,236,17,59,40,99,117,98,60,51,27,162,
2129 169,228,178,75,90,143,161,127,200,40,167,88,100,34,79,60,152,1,108,52,176,
2130 92,97,18,41,233,121,120,144,98,59,108,240,161,135,30,146,235,116,218,184,
2131 113,35,131,141,31,88,82,122,9,41,153,129,30,119,220,113,98,173,91,109,187,
2132 237,182,79,61,245,148,230,152,122,191,70,136,139,64,103,149,177,58,49,158,
2133 25,0,114,193,37,61,8,43,42,42,56,30,239,62,214,41,167,156,130,137,20,233,
2134 17,140,49,195,21,17,105,254,248,181,30,132,0,233,149,87,94,97,140,201,117,
2135 38,209,178,12,69,239,103,96,60,129,48,49,49,81,166,208,169,167,167,135,
2136 121,149,249,251,242,122,93,124,241,197,250,251,90,59,59,59,129,138,92,167,
2137 211,214,91,111,77,89,228,130,78,122,16,226,82,211,63,229,10,119,194,64,
2138 191,252,242,203,212,131,72,143,187,195,228,76,174,115,9,96,51,9,131,118,
2139 98,145,6,34,101,85,85,213,51,207,60,131,209,20,145,110,69,253,99,91,49,
2140 124,98,227,35,5,161,167,102,197,2,82,189,114,193,37,61,8,41,206,171,175,
2141 190,106,46,136,94,64,197,251,69,59,183,32,100,215,94,64,40,190,95,239,22,
2142 132,28,12,230,88,46,232,196,24,193,79,213,12,52,91,190,227,142,59,188,140,
2143 110,198,206,244,233,211,245,87,31,104,110,185,206,37,58,237,119,223,125,
2144 119,244,209,71,139,197,153,51,103,14,11,66,220,128,7,30,120,64,174,240,
2145 32,154,15,12,139,67,5,132,230,214,100,191,151,93,118,25,3,92,46,235,36,
2146 124,101,132,245,160,197,205,6,147,34,187,237,75,26,8,205,67,12,66,99,204,
2147 197,90,204,221,211,79,63,237,118,56,104,162,47,225,41,234,145,60,142,178,
2148 40,8,49,76,94,64,248,229,151,95,146,209,45,8,25,144,230,78,143,72,137,133,
2149 21,38,192,19,8,233,85,230,222,169,157,0,145,203,46,49,96,98,99,99,137,103,
2150 179,102,124,26,68,130,187,238,186,75,108,199,19,8,127,251,219,223,138,31,
2151 244,48,236,44,29,20,119,68,196,120,17,253,21,187,41,6,131,23,16,98,187,
2152 233,193,222,97,166,151,6,66,50,222,126,251,237,152,120,185,194,179,240,
2153 152,197,253,232,216,157,155,111,190,217,220,52,158,164,129,144,153,53,19,
2154 88,51,149,205,186,240,194,11,181,137,133,89,35,2,33,179,13,28,110,153,200,
2155 179,14,63,252,112,109,182,187,110,221,58,183,198,197,147,52,16,226,237,
2156 49,193,31,182,21,152,203,127,255,253,247,34,139,91,16,210,157,244,64,2,
2157 132,20,153,102,242,165,206,245,55,137,140,8,132,204,24,174,189,246,90,223,
2158 187,144,6,66,154,245,141,55,222,240,194,18,77,76,56,188,52,171,91,16,50,
2159 241,245,2,66,113,87,157,91,16,122,209,245,215,95,79,183,23,59,101,36,14,
2160 91,100,102,186,184,248,26,59,205,32,100,242,167,111,47,106,195,59,8,91,
2161 90,90,174,187,238,58,95,90,243,180,211,78,19,167,58,221,130,16,121,170,
2162 118,70,171,120,190,51,42,42,202,251,4,197,32,95,64,72,139,223,121,231,157,
2163 190,28,63,38,206,124,186,101,92,100,81,16,50,47,46,45,45,245,3,132,196,
2164 48,54,232,82,230,118,186,242,202,43,69,255,246,4,194,134,134,6,109,150,
2165 173,105,233,210,165,100,161,211,200,101,151,216,5,145,244,66,179,139,131,
2166 33,219,125,247,221,13,7,192,80,20,87,254,60,129,80,19,25,239,191,255,126,
2167 246,107,222,242,65,7,29,132,213,54,108,153,73,177,56,147,230,5,132,216,
2168 151,51,206,56,67,70,233,196,248,196,249,54,87,163,6,66,108,153,193,136,
2169 0,197,61,246,216,195,92,81,0,108,222,188,121,100,169,173,173,117,187,47,
2170 114,225,151,155,219,69,3,33,230,236,164,147,78,146,177,46,177,150,170,54,
2171 28,33,251,210,159,235,54,200,119,16,178,5,236,190,33,49,182,131,74,54,240,
2172 152,3,160,81,128,1,185,222,127,255,125,179,125,33,134,81,109,56,109,32,
2173 36,64,200,190,62,252,240,67,67,101,114,84,236,139,14,35,151,93,58,255,252,
2174 243,5,18,220,130,208,32,64,200,32,50,224,92,52,19,52,50,148,142,69,142,
2175 95,156,205,27,17,8,105,29,252,126,153,72,39,90,135,17,103,174,112,13,132,
2176 110,71,177,167,102,93,176,96,129,167,102,117,11,194,3,14,56,128,169,170,
2177 31,32,36,134,201,141,219,9,13,213,162,157,68,49,55,52,61,223,92,171,212,
2178 182,230,12,153,65,104,16,222,188,119,16,50,195,54,172,229,104,221,14,58,
2179 226,241,95,201,226,9,132,100,161,138,204,197,167,183,136,214,249,230,155,
2180 111,100,148,78,236,29,82,154,237,15,242,5,132,203,150,45,163,138,100,172,
2181 83,28,0,123,196,121,48,247,70,237,2,211,248,202,162,32,164,143,250,7,194,
2182 131,15,62,56,39,39,135,177,97,54,31,39,159,124,178,184,90,230,9,132,172,
2183 50,88,19,52,125,250,116,226,153,55,201,101,151,192,15,35,118,198,140,25,
2184 134,166,197,180,253,240,195,15,28,185,217,179,249,219,223,254,134,1,242,
2185 5,132,15,60,240,128,221,110,55,116,95,70,2,38,207,237,16,18,183,66,120,
2186 1,33,25,181,51,51,154,166,76,153,130,157,165,104,230,82,107,32,124,241,
2187 197,23,101,148,75,199,28,115,12,54,122,209,162,69,114,89,167,255,254,247,
2188 191,148,142,201,193,177,199,30,43,163,92,162,165,240,189,126,249,229,23,
2189 243,233,89,13,132,209,209,209,134,74,163,6,104,107,26,218,60,200,111,186,
2190 233,38,79,119,195,250,14,66,166,222,230,178,223,115,207,61,108,225,193,
2191 7,31,148,203,46,97,26,232,147,228,122,233,165,151,204,150,133,227,161,63,
2192 184,117,187,5,8,217,230,53,215,92,35,163,92,58,239,188,243,154,155,155,
2193 177,254,6,159,27,251,43,234,196,71,16,46,94,188,216,176,5,6,14,157,16,147,
2194 106,182,158,183,220,114,139,56,53,50,34,16,150,148,148,28,117,212,81,50,
2195 145,78,216,110,241,120,184,92,118,73,3,97,68,68,132,97,126,64,103,96,206,
2196 68,47,50,159,249,191,249,230,155,169,40,177,71,131,220,130,144,169,149,
2197 127,32,20,134,34,61,61,29,243,45,163,92,98,66,67,199,32,35,238,160,217,
2198 194,64,199,13,27,54,152,115,105,183,157,15,11,194,217,179,103,123,7,225,
2199 59,239,188,35,163,92,194,118,137,177,111,104,101,100,179,217,24,116,158,
2200 78,141,98,190,104,107,186,174,140,114,137,185,215,234,213,171,233,177,112,
2201 72,70,233,196,54,25,92,127,254,243,159,229,178,78,190,128,16,171,200,112,
2202 147,177,78,29,113,196,17,108,144,126,98,30,254,194,240,142,187,44,10,194,
2203 223,254,246,183,254,129,240,196,19,79,196,16,227,148,104,103,26,53,209,
2204 24,98,162,231,5,132,24,38,185,236,146,176,11,243,231,207,151,203,46,49,
2205 59,38,254,226,139,47,150,203,46,49,141,90,181,106,21,171,232,214,50,202,
2206 37,186,35,78,167,47,32,252,215,191,254,69,26,67,233,40,26,155,197,30,153,
2207 77,91,86,86,22,171,188,128,176,188,188,252,119,191,251,157,140,114,137,
2208 217,6,70,135,188,88,19,25,229,146,6,194,107,175,189,86,70,185,116,234,169,
2209 167,50,234,168,97,185,172,19,135,141,209,225,8,205,208,197,80,50,32,1,182,
2210 249,34,147,6,194,153,51,103,202,40,151,168,204,53,107,214,224,199,155,15,
2211 3,30,211,1,200,101,150,39,16,2,111,184,34,36,78,40,97,209,228,106,157,176,
2212 2,24,136,215,95,127,93,46,187,196,24,78,75,75,35,23,9,204,29,239,249,231,
2213 159,103,213,51,207,60,99,94,37,64,136,109,53,95,137,196,214,48,57,99,46,
2214 98,190,30,131,53,228,48,56,84,239,32,164,164,12,147,55,223,124,83,46,187,
2215 68,19,208,232,84,248,97,135,29,38,163,92,186,228,146,75,252,0,33,188,97,
2216 4,201,68,46,1,108,230,118,197,197,197,204,210,100,148,75,26,8,223,120,227,
2217 13,25,229,18,214,60,50,50,178,189,189,157,169,161,140,114,9,8,137,65,106,
2218 150,91,16,30,116,208,65,254,129,144,254,195,97,211,141,205,157,31,70,50,
2219 59,161,93,78,63,253,116,25,165,19,118,137,61,154,199,32,227,66,28,231,150,
2220 131,208,124,117,240,234,171,175,230,120,10,10,10,12,158,22,34,49,227,209,
2221 45,8,41,181,120,232,254,170,171,174,146,81,46,1,45,142,129,14,246,218,107,
2222 175,201,40,157,196,221,15,247,221,119,159,185,51,15,11,66,236,219,195,15,
2223 63,44,163,92,58,228,144,67,0,33,51,209,125,247,221,87,70,185,132,85,20,
2224 27,28,95,89,20,132,88,109,76,21,35,28,235,47,163,116,242,2,66,166,78,140,
2225 127,38,155,116,116,25,229,18,219,28,22,132,79,60,241,132,92,118,233,140,
2226 51,206,32,158,190,43,151,93,194,111,160,27,153,167,90,147,38,77,194,174,
2227 145,133,225,36,163,92,194,14,138,7,42,134,5,33,9,238,190,251,110,67,233,
2228 246,222,123,111,144,80,85,85,197,96,96,149,94,226,70,149,145,130,16,163,
2229 3,51,114,115,115,177,38,50,202,37,13,132,231,158,123,174,140,114,233,180,
2230 211,78,195,246,245,244,244,152,207,156,48,72,176,110,110,65,200,49,99,124,
2231 49,34,230,145,160,129,208,124,252,120,18,176,138,131,196,137,145,81,46,
2232 97,71,60,221,132,237,22,132,136,138,194,52,8,81,10,82,154,231,55,100,20,
2233 231,0,222,123,239,61,25,165,211,218,181,107,89,229,22,132,184,206,172,2,
2234 135,230,85,2,132,216,86,243,116,248,186,235,174,163,198,40,190,249,236,
2235 168,232,96,195,130,144,178,48,76,158,126,250,105,185,236,18,83,52,102,93,
2236 180,187,217,235,98,140,96,55,57,164,45,7,33,182,143,206,192,94,204,211,
2237 62,13,132,230,49,133,223,31,19,19,131,101,188,225,134,27,100,148,75,12,
2238 31,195,29,200,154,220,130,144,81,6,236,1,33,13,42,163,116,242,2,66,12,11,
2239 135,205,190,204,51,102,1,66,24,233,118,22,142,217,97,12,154,219,139,209,
2240 45,142,124,203,65,72,175,144,81,46,49,17,4,132,140,172,253,77,143,252,94,
2241 127,253,245,12,70,79,32,252,225,135,31,216,224,77,55,221,36,163,92,98,239,
2242 94,64,248,191,255,253,143,92,204,107,205,157,121,88,16,82,219,255,252,231,
2243 63,101,148,75,204,189,24,149,217,217,217,102,171,200,204,88,108,112,124,
2244 101,81,16,50,228,252,3,33,147,56,236,35,32,52,159,157,195,1,26,22,132,11,
2245 23,46,148,203,46,97,71,136,127,234,169,167,228,178,75,159,124,242,9,35,
2246 25,150,200,101,151,192,195,242,229,203,177,110,230,203,15,48,0,98,121,1,
2247 33,121,153,191,51,251,251,244,211,79,49,169,230,209,251,232,163,143,82,
2248 39,12,239,183,55,23,131,150,131,28,11,16,154,11,40,64,216,216,216,104,174,
2249 124,142,156,125,249,13,66,243,248,161,66,24,174,24,116,179,197,68,250,123,
2250 181,245,242,4,66,189,196,252,221,124,14,10,81,243,52,159,219,83,70,116,
2251 60,108,135,127,32,164,20,230,243,90,87,94,121,37,70,28,190,154,61,194,75,
2252 47,189,212,59,8,169,210,203,47,191,28,27,199,64,48,159,200,101,6,195,40,
2253 160,194,205,45,72,31,19,23,59,183,28,132,28,246,176,32,188,243,206,59,101,
2254 148,75,212,195,234,213,171,57,60,243,185,98,148,158,158,46,246,104,144,
2255 91,16,226,106,248,7,194,147,78,58,169,162,162,2,116,153,11,37,64,72,213,
2256 153,187,49,34,23,85,97,6,33,136,162,177,216,157,39,16,210,153,207,57,231,
2257 28,184,181,100,201,18,239,32,52,223,87,140,235,204,200,162,164,230,122,
2258 190,236,178,203,40,160,39,16,178,35,54,232,22,132,226,230,216,81,7,33,86,
2259 145,50,202,40,151,206,60,243,76,70,37,107,15,56,224,0,25,229,18,83,31,14,
2260 67,108,115,28,101,81,16,50,122,1,33,51,47,243,221,19,200,63,16,50,254,135,
2261 5,33,152,145,203,46,29,117,212,81,52,161,217,70,211,101,91,90,90,204,116,
2262 161,127,236,177,199,30,180,183,249,216,232,196,152,6,47,32,252,240,195,
2263 15,41,50,7,73,207,166,47,26,206,179,35,198,18,115,67,113,115,166,89,99,
2264 1,66,243,41,32,1,66,179,139,140,176,203,52,138,223,32,52,15,87,68,101,98,
2265 98,204,86,3,225,85,56,203,109,148,239,32,52,159,255,68,226,254,2,179,247,
2266 134,62,248,224,3,191,65,232,246,100,50,190,209,126,251,237,71,199,48,31,
2267 48,182,195,11,8,207,56,227,140,180,180,52,113,6,143,100,230,254,73,39,103,
2268 143,52,147,249,118,143,221,119,223,61,144,32,116,251,92,54,233,41,184,219,
2269 123,139,196,9,21,179,220,130,16,63,76,156,225,116,123,26,115,75,64,8,117,
2270 204,171,16,135,77,31,54,183,50,145,226,10,133,91,16,82,222,31,127,252,145,
2271 201,16,237,69,229,123,7,33,157,83,70,185,36,64,136,125,48,239,151,126,226,
2272 5,132,203,150,45,99,131,230,145,69,205,47,93,186,116,44,64,200,36,210,124,
2273 33,227,148,83,78,17,147,75,179,77,99,23,172,18,219,28,71,141,63,8,153,215,
2274 203,42,209,9,252,8,16,158,124,242,201,50,74,39,47,32,196,76,147,203,45,
2275 8,153,60,14,11,66,154,4,216,200,40,167,176,137,140,64,102,238,114,217,37,
2276 38,62,110,65,232,69,248,136,12,114,79,32,52,24,32,138,192,144,147,235,54,
2277 23,166,237,153,103,158,201,206,206,198,6,201,212,78,141,5,8,245,98,176,
2278 209,40,191,252,242,203,37,151,92,98,118,110,16,38,0,79,113,116,65,232,69,
2279 120,21,226,192,12,218,66,16,122,209,204,153,51,169,243,81,4,161,23,253,
2280 254,247,191,247,4,66,108,232,119,223,125,55,84,84,15,98,8,96,1,111,188,
2281 241,70,183,245,0,233,199,29,132,94,180,114,229,74,177,71,131,242,243,243,
2282 101,10,157,152,221,10,16,50,51,144,81,58,141,5,8,61,105,239,189,247,78,
2283 73,73,97,119,110,65,72,79,163,53,157,229,24,146,119,16,234,197,160,99,212,
2284 44,92,184,240,226,139,47,118,219,154,244,100,58,188,39,16,138,123,74,221,
2285 130,16,199,116,44,64,40,214,106,98,23,244,70,160,139,155,104,222,26,34,
2286 18,75,46,83,143,159,198,31,132,153,153,153,178,74,116,18,32,196,183,115,
2287 123,199,182,23,16,254,225,15,127,192,171,115,11,66,204,253,176,32,236,236,
2288 236,52,92,92,196,51,88,181,106,149,225,48,152,83,211,249,70,10,194,157,
2289 119,222,121,253,250,245,158,64,40,94,151,163,23,22,193,140,13,33,122,33,
2290 92,127,244,209,71,161,142,76,61,198,32,220,184,113,227,125,247,221,199,
2291 96,51,76,20,244,10,48,8,197,77,73,102,141,29,8,177,26,1,3,33,38,222,19,
2292 8,153,81,185,125,38,146,244,184,137,116,3,74,231,214,135,22,178,56,8,87,
2293 172,88,33,246,104,80,65,65,129,76,161,147,6,66,28,35,25,165,83,32,65,72,
2294 13,136,70,113,11,66,195,217,11,95,64,72,107,146,235,206,59,239,60,238,184,
2295 227,204,183,160,107,242,14,66,104,199,166,204,35,139,13,46,94,188,120,76,
2296 65,200,198,41,206,19,79,60,129,51,99,62,45,161,73,129,80,10,207,70,86,137,
2297 78,126,131,144,110,225,9,132,7,30,120,224,176,32,196,64,24,238,176,162,
2298 9,231,205,155,103,56,181,125,222,121,231,145,210,19,8,161,200,36,119,218,
2299 99,143,61,188,128,208,240,126,81,68,79,162,31,51,60,60,153,117,220,178,
2300 11,46,184,128,241,44,210,143,17,8,49,52,247,222,123,47,184,210,91,19,115,
2301 205,163,177,0,161,167,202,68,218,59,210,12,114,11,66,182,195,200,199,152,
2302 10,81,33,164,116,11,66,106,85,238,192,164,81,247,8,73,44,55,173,215,182,
2303 67,69,62,244,208,67,233,0,110,65,72,71,210,94,147,164,137,222,200,222,129,
2304 156,193,89,55,87,133,21,64,232,165,89,61,205,111,32,147,204,172,147,0,33,
2305 227,61,96,32,148,71,105,18,38,66,188,55,213,12,66,90,196,224,42,121,7,33,
2306 237,206,72,185,251,238,187,169,94,183,3,77,47,239,32,20,47,212,13,60,8,
2307 57,158,103,158,121,6,135,65,223,27,221,218,49,118,161,64,56,164,156,156,
2308 28,89,37,58,105,32,164,153,101,148,78,222,65,72,255,102,96,152,239,26,165,
2309 167,98,44,200,232,5,132,80,202,112,95,12,141,247,194,11,47,24,222,144,249,
2310 224,131,15,98,214,221,130,144,33,17,17,17,49,84,48,231,27,22,12,162,231,
2311 121,2,225,162,69,139,68,46,131,152,227,255,243,159,255,244,116,199,4,186,
2312 248,226,139,25,234,164,28,11,16,98,14,204,151,105,247,217,103,159,71,30,
2313 121,68,46,232,116,209,69,23,141,46,8,25,201,226,68,25,245,38,107,80,39,
2314 226,221,202,19,8,205,94,148,91,16,190,244,210,75,98,173,220,141,78,34,126,
2315 20,65,248,183,191,253,173,205,245,38,88,169,230,250,129,220,101,3,157,237,
2316 252,36,222,45,8,177,152,76,31,89,171,169,170,170,234,220,115,207,53,148,
2317 26,224,93,120,225,133,80,83,46,187,132,121,21,29,102,28,65,40,190,31,52,
2318 162,102,245,14,194,179,206,58,75,70,233,52,22,32,20,147,105,121,172,155,
2319 203,121,152,110,64,72,223,19,15,222,104,242,14,66,170,154,177,41,99,93,
2320 162,29,177,81,110,11,226,5,132,11,23,46,100,131,230,145,197,252,30,131,
2321 51,70,32,164,234,204,54,150,174,114,217,101,151,209,43,228,178,75,236,162,
2322 193,245,18,249,113,148,165,65,232,233,241,32,47,32,20,79,158,50,48,204,
2323 182,120,191,253,246,27,22,132,232,211,79,63,149,81,46,193,45,131,53,249,
2324 240,195,15,233,247,158,64,40,78,131,204,157,59,247,252,205,117,229,149,
2325 87,210,81,60,129,208,211,68,24,49,127,199,149,116,235,48,33,122,164,232,
2326 184,99,1,194,39,159,124,82,70,185,68,119,255,226,139,47,58,59,59,229,178,
2327 78,184,167,244,233,81,4,225,182,206,231,8,89,181,96,193,2,89,137,58,25,
2328 140,139,166,81,1,97,126,126,254,165,151,94,42,247,228,18,94,59,182,99,20,
2329 65,40,30,159,96,246,192,244,95,238,227,156,179,207,63,237,248,243,207,57,
2330 235,134,27,110,96,95,110,65,184,215,94,123,225,212,14,21,192,165,121,243,
2331 230,81,64,185,218,165,233,211,167,227,56,154,159,147,219,126,251,237,199,
2332 23,132,24,104,49,89,252,250,235,175,233,51,178,224,46,25,156,39,77,0,79,
2333 230,215,73,3,161,219,65,61,118,32,100,172,201,195,117,233,234,171,175,166,
2334 177,88,101,6,33,204,51,220,225,236,29,132,51,102,204,48,244,34,154,108,
2335 254,252,249,152,74,243,237,69,39,156,112,130,23,16,138,243,76,230,155,174,
2336 1,33,140,28,11,16,178,77,60,7,195,105,9,68,36,70,204,60,252,217,5,173,32,
2337 182,57,142,26,127,16,98,55,101,149,232,164,129,208,237,93,209,222,65,200,
2338 176,196,232,152,167,84,248,49,190,128,144,78,96,176,41,24,104,195,68,102,
2339 221,186,117,164,244,4,66,241,14,210,103,159,125,86,70,185,4,77,97,164,39,
2340 16,26,78,244,225,40,224,16,51,211,215,68,133,96,56,14,57,228,16,115,23,
2341 196,101,36,203,88,128,208,60,170,177,14,28,9,108,150,203,58,157,119,222,
2342 121,91,2,194,155,111,190,89,70,185,196,112,21,85,253,222,123,239,153,75,
2343 237,233,171,164,190,131,16,139,35,87,235,36,64,200,144,102,96,203,40,151,
2344 222,126,251,109,236,254,40,130,16,11,5,8,105,104,243,99,66,39,157,120,162,
2345 39,16,238,189,247,222,152,233,161,2,184,196,33,201,117,46,9,66,144,140,
2346 31,50,202,37,106,53,144,32,52,63,3,202,252,70,220,26,106,182,248,8,115,
2347 233,220,161,81,212,146,76,161,147,40,38,150,52,192,32,196,92,200,101,151,
2348 48,47,130,118,230,33,67,71,26,17,8,205,53,38,110,125,160,51,152,31,219,
2349 56,238,184,227,188,128,80,188,180,214,252,96,34,102,74,188,205,110,212,
2350 65,136,101,184,235,174,187,100,148,75,20,13,107,73,233,20,8,61,138,90,144,
2351 85,162,147,119,16,50,57,34,163,119,16,154,59,49,230,195,23,16,98,121,13,
2352 166,135,94,168,239,181,216,17,49,140,25,96,28,167,140,117,73,3,33,51,32,
2353 25,229,18,19,121,186,130,39,16,26,110,150,51,191,199,11,142,18,143,27,100,
2354 126,66,145,105,53,171,198,2,132,230,55,6,156,114,202,41,20,156,238,110,
2355 30,9,231,156,115,14,173,233,55,8,205,159,116,96,254,187,97,195,6,86,205,
2356 153,51,199,60,199,20,86,195,44,223,65,136,161,148,171,93,34,227,171,175,
2357 190,202,42,44,151,249,9,138,143,63,254,24,219,225,31,8,113,251,232,27,50,
2358 202,37,47,32,60,239,204,51,60,129,208,236,17,154,223,229,193,164,4,63,137,
2359 10,55,119,81,170,34,144,32,188,255,254,251,101,148,75,226,129,122,86,49,
2360 177,224,96,100,172,75,250,15,125,232,197,212,80,166,208,73,3,161,248,114,
2361 139,65,226,6,52,255,64,72,161,204,151,87,144,0,161,25,45,251,237,183,31,
2362 30,27,171,204,32,164,27,143,8,132,102,202,94,117,213,85,216,46,216,108,
2363 174,103,14,114,88,16,226,173,202,40,151,232,138,226,244,198,168,131,176,
2364 179,179,211,252,253,38,90,135,131,196,118,25,110,182,64,10,132,82,110,125,
2365 11,241,174,81,79,167,70,197,195,49,222,65,104,126,97,132,152,149,144,209,
2366 59,8,179,178,178,240,186,100,172,83,244,99,253,142,246,223,127,127,113,
2367 171,2,221,200,252,238,9,13,132,211,167,79,151,81,46,145,49,61,61,221,71,
2368 16,226,3,25,76,63,117,34,86,153,123,252,153,103,158,73,252,88,128,208,108,
2369 70,105,17,138,64,171,49,33,144,81,46,157,117,214,89,91,2,66,243,43,72,24,
2370 90,194,237,155,59,119,174,249,110,85,44,32,171,204,242,29,132,223,125,247,
2371 157,92,237,18,13,253,250,235,175,179,138,38,54,79,56,126,248,225,7,191,
2372 65,136,109,165,18,100,148,75,2,132,116,87,250,173,140,114,233,239,151,156,
2373 57,216,211,229,9,132,134,15,81,153,97,195,78,241,206,177,245,230,169,12,
2374 71,24,72,16,154,207,174,195,0,177,138,78,110,110,86,118,228,220,161,81,
2375 212,188,153,103,116,93,240,64,175,115,59,168,113,122,200,232,9,132,28,182,
2376 91,16,50,252,105,44,26,197,237,155,101,4,8,205,231,123,15,60,240,64,186,
2377 55,171,204,32,100,164,24,222,18,224,29,132,230,23,55,94,115,205,53,204,
2378 3,24,89,230,55,203,136,81,236,29,132,230,87,217,81,237,162,51,143,58,8,
2379 59,58,58,204,179,4,234,132,131,100,162,192,36,67,70,185,196,46,20,8,165,
2380 24,78,178,86,92,194,92,210,191,113,10,205,38,21,9,210,120,1,33,4,5,27,50,
2381 202,37,60,42,95,64,200,60,218,108,59,244,98,120,112,96,34,177,249,37,126,
2382 128,80,56,49,207,60,243,140,140,114,9,54,51,200,125,4,225,87,95,125,101,
2383 152,44,227,209,138,85,102,47,25,218,17,63,82,16,50,224,233,157,88,124,243,
2384 52,77,3,161,185,254,169,97,114,33,179,139,118,198,25,103,120,2,33,195,30,
2385 16,226,199,120,121,215,168,249,173,102,218,169,209,15,62,248,192,96,203,
2386 118,218,105,39,90,138,85,102,113,108,62,130,16,187,35,87,235,244,242,203,
2387 47,179,138,217,43,187,144,81,78,209,217,196,149,45,183,32,20,239,92,254,
2388 207,127,254,99,94,37,64,72,43,152,79,215,211,58,24,184,202,202,74,115,151,
2389 123,248,174,219,7,219,155,125,4,161,249,237,148,226,205,50,116,84,183,110,
2390 141,31,32,116,123,170,16,123,74,127,102,21,131,75,70,185,164,129,208,220,
2391 172,140,145,232,232,104,86,189,249,230,155,134,94,68,63,97,92,59,119,232,
2392 70,230,170,0,30,116,84,42,208,45,180,196,89,86,183,32,60,238,184,227,232,
2393 168,116,87,243,140,153,26,195,80,224,217,184,189,19,21,219,194,54,205,3,
2394 31,131,3,62,89,101,6,33,181,52,162,155,101,46,185,228,18,25,229,210,95,
2395 254,242,23,14,137,153,159,121,248,48,174,57,84,239,32,36,187,140,114,73,
2396 3,161,219,203,228,226,218,147,219,119,142,251,7,66,166,200,140,74,214,42,
2397 143,208,155,46,184,224,2,89,43,46,209,132,255,253,239,127,177,56,84,174,
2398 140,114,137,121,58,147,53,114,121,7,161,249,210,8,25,69,79,245,14,66,6,
2399 182,219,59,208,52,209,209,5,80,209,171,175,190,106,232,16,28,249,204,153,
2400 51,57,6,243,120,56,231,156,115,152,254,251,8,194,200,200,72,195,153,52,
2401 182,204,152,135,91,134,91,88,17,190,20,89,188,128,16,207,192,45,156,112,
2402 7,87,175,94,189,187,233,243,226,26,8,97,155,140,114,137,1,207,128,196,198,
2403 201,101,157,78,63,253,116,97,124,205,239,183,164,150,50,50,50,160,154,217,
2404 43,210,64,200,252,198,224,101,210,190,31,125,244,17,67,200,236,241,208,
2405 136,90,43,24,228,59,8,129,144,217,130,223,117,215,93,88,150,207,62,251,
2406 204,96,61,153,140,139,115,95,175,188,242,138,97,21,194,104,210,187,176,
2407 143,230,93,11,16,114,84,230,137,185,184,201,57,38,38,198,252,242,4,113,
2408 254,223,71,16,154,189,46,154,41,43,43,11,211,99,118,193,145,31,32,116,59,
2409 191,65,152,248,53,107,214,152,175,93,105,32,164,39,27,30,131,163,89,63,
2410 253,244,83,42,217,252,246,53,134,30,99,68,236,209,172,203,46,187,76,166,
2411 115,137,218,166,236,184,227,244,34,25,229,210,180,105,211,168,91,114,185,
2412 5,33,214,128,106,231,216,204,179,112,154,146,142,65,70,122,130,217,194,
2413 172,90,181,138,30,110,56,105,132,254,252,231,63,195,21,114,153,7,62,176,
2414 167,33,134,10,224,146,119,16,50,102,101,148,75,167,156,114,10,245,31,21,
2415 21,101,190,89,134,134,30,22,132,230,247,129,48,28,88,197,1,191,245,214,
2416 91,50,74,167,155,111,190,153,86,48,159,161,69,195,130,144,126,78,26,25,
2417 229,18,38,11,195,69,169,205,151,27,20,8,127,21,243,125,89,43,58,129,1,3,
2418 9,132,254,249,207,127,226,91,144,203,59,8,205,61,149,145,233,11,8,209,181,
2419 94,63,64,122,253,245,215,139,30,143,176,251,230,174,201,152,196,250,208,
2420 213,228,178,75,204,127,201,226,35,8,123,122,122,24,24,114,157,75,108,150,
2421 41,161,249,216,196,51,200,94,64,200,113,186,157,222,210,65,217,139,185,
2422 26,53,16,154,223,6,201,168,62,240,192,3,205,199,134,4,8,189,236,139,131,
2423 55,239,75,3,33,243,27,243,153,112,44,44,187,51,84,50,53,192,76,150,154,
2424 28,170,41,147,124,7,33,237,120,247,221,119,203,20,46,177,47,246,104,182,
2425 236,88,58,113,90,236,195,15,63,52,159,22,38,134,217,174,57,30,9,16,178,
2426 47,172,191,225,76,32,71,5,2,1,155,161,90,112,74,196,89,7,31,65,104,254,
2427 194,3,70,144,218,166,206,205,21,142,252,0,33,173,227,246,89,38,79,205,170,
2428 129,176,202,221,251,161,220,54,43,98,18,233,169,89,17,179,19,153,78,39,
2429 170,212,173,161,192,154,131,7,114,185,5,33,61,132,106,52,79,131,16,195,
2430 31,180,144,145,121,155,161,189,16,179,70,183,229,21,79,236,33,51,8,73,60,
2431 34,16,154,253,123,209,79,220,14,58,12,221,176,32,52,35,141,81,44,206,127,
2432 154,175,14,32,74,205,164,199,109,103,30,22,132,110,237,155,168,109,183,
2433 166,134,24,5,66,41,198,60,166,211,92,179,102,225,231,137,89,57,242,14,66,
2434 243,201,104,198,158,143,32,52,127,11,80,19,7,137,233,148,233,156,122,231,
2435 157,119,204,227,217,32,142,243,252,243,207,23,233,125,4,33,154,62,125,186,
2436 151,55,74,104,58,225,132,19,132,237,240,2,66,216,224,227,55,163,133,52,
2437 16,186,125,247,180,39,9,16,50,38,49,166,190,239,75,3,33,250,252,243,207,
2438 13,39,36,221,10,139,92,180,249,109,147,122,249,14,66,148,158,158,110,254,
2439 58,146,89,76,65,196,73,90,132,27,97,246,161,133,220,246,97,1,66,132,131,
2440 114,206,57,231,12,219,207,49,235,179,103,207,22,109,234,35,8,153,9,153,
2441 77,54,162,21,40,184,92,208,201,15,16,210,172,158,222,217,230,86,26,8,209,
2442 156,57,115,124,105,214,211,78,59,13,191,71,100,113,43,42,240,188,243,206,
2443 243,229,24,160,172,118,127,138,39,16,186,221,14,41,241,47,5,65,17,99,202,
2444 45,101,245,162,230,239,191,255,254,1,207,207,17,178,35,241,246,53,77,222,
2445 65,8,239,205,215,29,16,219,49,199,31,116,208,65,195,130,208,252,22,111,
2446 182,35,222,210,23,27,27,235,118,54,224,73,195,130,144,85,111,191,253,182,
2447 219,74,99,167,102,179,64,140,2,225,175,202,206,206,118,251,29,72,189,246,
2448 223,127,255,69,139,22,9,119,16,121,1,97,117,117,53,35,65,70,185,196,80,
2449 244,17,132,76,238,220,154,15,68,223,98,210,42,211,57,213,209,209,1,56,189,
2450 16,139,230,103,142,169,221,2,224,59,8,25,192,47,191,252,178,249,212,141,
2451 38,250,226,41,167,156,162,217,119,47,32,100,109,84,84,148,217,75,230,216,
2452 206,58,235,44,179,145,210,64,136,233,57,201,221,123,207,111,184,225,6,51,
2453 254,5,8,201,197,33,153,79,163,177,175,11,46,184,192,92,28,61,8,219,218,
2454 218,62,254,248,99,183,103,243,52,177,23,195,61,120,6,141,8,132,88,144,101,
2455 203,150,153,223,67,164,215,145,71,30,41,62,192,36,132,179,238,182,170,233,
2456 114,191,251,221,239,204,187,214,64,136,114,115,115,255,250,215,191,122,
2457 153,37,80,63,204,180,180,71,140,125,4,33,238,154,219,119,81,130,22,243,
2458 105,106,228,7,8,81,82,82,146,249,230,41,154,149,93,155,205,186,30,132,52,
2459 43,222,176,247,102,229,80,189,55,171,16,221,210,124,134,217,32,156,84,220,
2460 29,13,102,110,65,136,207,125,225,133,23,154,27,130,195,208,223,132,213,
2461 210,210,242,212,83,79,121,25,221,244,43,28,56,253,35,225,102,16,162,17,
2462 129,176,180,180,212,109,135,228,128,205,215,216,232,117,195,130,208,124,
2463 247,13,171,196,185,119,204,23,230,200,92,63,28,140,249,234,41,242,5,132,
2464 149,149,149,230,171,93,84,245,229,151,95,174,174,17,14,47,236,245,220,185,
2465 115,49,214,98,226,128,168,107,254,210,72,84,49,214,1,188,137,105,178,16,
2466 32,196,121,103,58,166,23,253,24,219,77,74,166,249,50,202,37,237,26,33,206,
2467 153,140,210,233,47,127,249,139,216,44,42,40,40,96,143,114,197,230,162,251,
2468 154,95,1,131,101,164,7,92,115,205,53,216,116,14,158,3,22,226,55,221,244,
2469 205,55,223,164,183,105,103,83,41,194,35,143,60,34,55,167,147,219,7,234,
2470 217,242,234,213,171,129,25,238,172,97,203,140,118,122,112,85,85,149,182,
2471 101,70,172,220,150,78,48,88,128,144,25,43,134,12,207,91,219,14,181,247,
2472 236,179,207,70,71,71,227,61,203,212,46,81,76,1,66,54,142,207,116,221,117,
2473 215,49,224,69,46,140,194,131,15,62,136,229,101,42,42,83,187,132,187,35,
2474 250,52,251,162,14,207,61,247,92,109,95,100,231,240,226,227,227,153,205,
2475 200,212,46,97,232,197,248,23,162,126,200,139,57,6,180,34,187,232,3,252,
2476 6,216,207,61,247,156,184,66,236,69,128,144,9,169,220,186,75,148,72,188,
2477 1,203,44,142,22,126,83,21,76,141,181,3,70,252,38,227,77,55,221,4,141,180,
2478 74,22,194,182,50,251,161,71,105,41,129,229,154,53,107,232,165,230,93,95,
2479 118,217,101,50,155,83,52,199,151,95,126,137,31,175,85,169,16,41,169,49,
2480 220,205,141,27,55,106,70,156,93,211,208,98,59,154,168,67,226,69,2,33,14,
2481 15,243,253,175,127,253,139,189,139,173,113,72,204,237,136,196,46,203,108,
2482 58,9,16,50,107,148,203,58,221,113,199,29,98,155,102,177,23,154,134,153,
2483 147,86,75,20,225,63,255,249,15,51,140,125,246,217,71,230,119,9,75,170,127,
2484 16,130,102,5,222,183,220,114,139,185,89,233,219,84,166,152,66,249,34,176,
2485 250,213,87,95,97,166,201,59,100,38,116,134,130,86,190,253,246,219,49,196,
2486 122,67,65,97,233,180,242,176,92,98,38,199,118,158,124,242,73,142,103,168,
2487 36,206,35,161,165,152,145,155,219,154,49,8,132,180,35,23,226,55,141,142,
2488 201,18,231,81,53,177,17,185,15,157,12,167,70,153,123,81,106,185,206,165,
2489 253,246,219,79,204,213,56,0,126,92,127,253,245,218,238,248,65,213,81,129,
2490 39,158,120,162,76,237,210,97,135,29,38,64,104,110,77,6,184,120,160,30,143,
2491 80,70,185,68,133,136,83,163,136,236,143,61,246,24,85,167,237,235,140,51,
2492 206,192,44,252,227,31,255,144,169,117,210,186,135,185,159,79,115,125,185,
2493 26,53,54,54,222,119,223,125,88,81,109,155,80,144,186,253,253,239,127,47,
2494 83,187,196,65,234,167,17,227,37,11,129,80,83,76,76,204,7,31,124,128,51,
2495 196,24,131,34,223,126,251,173,184,232,109,22,221,221,32,237,4,133,92,222,
2496 92,98,149,47,194,239,244,36,153,194,157,192,192,250,245,235,233,97,159,
2497 127,254,57,188,196,242,106,22,77,47,58,186,60,32,157,228,58,15,98,203,177,
2498 177,177,108,147,45,51,203,139,136,136,0,174,114,221,72,68,174,13,27,54,
2499 124,253,245,215,191,252,242,203,136,250,95,78,78,206,130,5,11,190,251,238,
2500 59,109,110,43,143,123,115,137,85,66,236,11,179,78,243,49,255,29,150,94,
2501 102,49,9,192,139,253,225,135,31,230,204,153,195,120,166,200,194,124,143,
2502 157,104,151,228,228,100,42,25,247,133,146,2,54,198,179,92,231,78,80,97,
2503 233,210,165,20,16,179,165,117,60,223,85,84,84,132,65,196,166,35,154,67,
2504 176,13,138,99,131,244,221,70,214,236,230,146,235,54,23,199,95,86,86,198,
2505 33,177,65,10,34,250,42,7,38,243,232,36,210,251,167,246,246,118,154,21,127,
2506 194,191,102,165,17,245,205,10,245,41,178,92,55,66,225,113,98,40,94,121,
2507 229,21,12,197,27,111,188,65,175,22,23,86,71,36,230,10,11,23,46,100,204,
2508 178,53,183,163,85,19,211,235,181,107,215,82,240,47,190,248,98,201,146,37,
2509 12,4,183,233,101,21,111,46,3,92,125,17,89,178,178,178,104,77,198,59,128,
2510 97,35,114,133,7,137,29,25,228,101,149,254,144,248,77,61,208,243,169,7,202,
2511 229,221,202,249,174,146,146,146,159,126,250,137,105,31,219,20,3,68,238,
2512 123,115,137,196,227,43,43,130,80,73,41,108,101,6,161,146,146,210,88,75,
2513 129,80,73,201,66,82,32,84,82,10,188,20,8,149,148,44,36,5,66,37,165,192,
2514 75,129,80,73,201,66,82,32,84,82,10,188,20,8,149,148,44,36,5,66,37,165,192,
2515 75,129,80,73,201,66,82,32,84,82,10,188,20,8,149,148,44,36,5,66,37,165,192,
2516 75,129,80,73,201,66,82,32,84,82,10,188,20,8,149,148,172,162,254,254,254,
2517 230,230,230,168,168,168,182,182,54,63,30,193,86,82,82,242,79,10,132,74,
2518 74,227,41,128,215,218,218,90,90,90,186,105,211,166,200,200,200,136,136,
2519 136,245,235,215,243,151,223,133,133,133,149,149,149,117,117,117,10,138,
2520 74,74,99,42,5,66,37,165,241,81,111,111,47,144,131,127,41,41,41,197,197,
2521 197,48,15,71,176,187,187,27,236,181,183,183,227,26,54,54,54,230,229,229,
2522 37,36,36,68,71,71,87,85,85,141,245,27,230,148,148,194,86,10,132,74,74,129,
2523 86,95,95,95,117,117,117,106,106,42,142,32,204,243,254,158,82,120,89,83,
2524 83,19,19,19,19,31,31,95,80,80,96,145,119,51,42,41,133,146,20,8,149,148,
2525 2,42,192,150,149,149,133,171,167,255,38,201,176,2,150,176,51,34,34,2,223,
2526 209,143,23,124,43,41,41,121,145,2,161,146,82,224,212,221,221,157,147,147,
2527 131,35,232,31,204,128,104,110,110,238,166,77,155,70,235,251,0,74,74,74,
2528 72,129,80,73,41,64,130,130,41,41,41,229,229,229,91,226,210,245,247,247,
2529 23,21,21,229,231,231,143,244,28,105,93,93,93,161,83,248,148,237,237,237,
2530 34,178,182,182,86,191,29,14,172,170,170,170,164,164,68,124,228,139,181,
2531 164,175,168,168,208,184,11,137,89,212,190,192,215,208,208,64,250,198,198,
2532 198,150,150,22,22,113,112,197,201,94,126,179,133,166,166,38,103,42,165,
2533 255,223,222,185,54,165,145,132,97,244,255,255,165,88,101,188,113,21,48,
2534 32,32,72,68,238,33,10,137,128,17,48,169,202,158,226,237,237,154,29,98,228,
2535 146,65,118,247,57,31,168,238,153,183,123,154,79,167,158,161,103,16,251,
2536 142,68,40,196,46,192,37,216,11,11,110,191,5,20,117,145,11,209,225,90,83,
2537 61,60,60,32,45,70,165,82,41,188,133,210,16,94,60,30,15,238,193,233,247,
2538 251,133,66,129,117,114,138,5,159,158,158,246,122,189,193,96,224,101,137,
2539 222,56,216,110,183,185,52,48,60,147,201,144,80,1,137,50,109,50,153,228,
2540 18,84,82,131,113,109,148,16,123,142,68,40,196,46,248,252,249,179,217,194,
2541 245,183,3,141,37,18,9,20,229,250,171,129,186,240,19,32,54,210,30,162,66,
2542 99,65,17,18,88,137,119,156,197,130,147,201,196,255,225,184,7,17,102,179,
2543 89,219,179,131,89,175,174,174,24,130,95,75,165,210,124,62,231,11,98,122,
2544 36,202,217,98,177,168,68,40,254,45,72,132,66,68,206,120,60,38,135,253,89,
2545 49,144,222,112,146,207,106,171,64,49,105,207,110,108,162,100,188,200,12,
2546 65,17,30,28,28,32,63,114,30,58,196,148,196,187,163,163,163,122,189,238,
2547 175,130,8,49,28,34,124,124,124,68,123,152,56,159,207,19,4,47,47,47,249,
2548 142,156,98,114,68,72,59,157,78,163,70,27,37,196,158,35,17,10,17,45,248,
2549 198,164,229,250,1,16,12,30,66,36,248,99,131,176,120,126,126,62,28,14,93,
2550 103,5,184,74,185,92,14,186,51,36,194,119,239,222,145,92,73,120,136,141,
2551 53,211,160,184,213,106,17,254,172,0,17,86,42,149,219,219,219,94,175,135,
2552 32,209,33,34,68,120,76,75,49,106,164,30,17,146,53,131,250,20,98,207,145,
2553 8,133,136,22,60,145,201,100,80,136,235,255,13,158,192,28,36,167,247,239,
2554 223,19,194,186,221,174,59,177,50,4,178,144,216,126,15,174,194,79,174,179,
2555 32,36,194,92,46,71,108,69,174,216,142,6,226,100,114,180,231,179,44,223,
2556 162,90,173,34,75,76,201,226,25,107,34,228,8,113,16,59,98,125,139,137,28,
2557 161,109,163,132,216,115,36,66,33,162,133,104,133,51,150,173,128,48,142,
2558 143,143,219,237,54,34,225,51,22,139,221,223,223,187,115,171,241,252,252,
2559 140,165,38,147,137,235,191,6,122,195,79,174,179,192,68,104,38,35,146,34,
2560 60,12,199,193,78,167,131,14,105,208,197,157,92,200,234,77,132,211,233,52,
2561 149,74,145,20,25,104,34,132,100,50,105,190,36,224,18,85,125,136,20,98,255,
2562 145,8,133,136,22,68,178,188,171,197,28,214,104,52,188,32,241,10,254,88,
2563 14,142,191,129,177,165,82,105,245,187,163,8,44,244,0,34,153,143,73,56,104,
2564 59,104,104,179,128,241,120,108,109,26,88,13,201,185,234,197,47,139,136,
2565 147,83,12,100,148,53,248,228,20,3,237,238,46,99,105,175,158,83,133,120,
2566 115,36,66,33,162,133,56,136,81,92,231,111,72,90,137,68,34,168,61,212,136,
2567 8,107,181,154,121,101,69,8,121,204,239,58,155,130,192,176,221,90,215,21,
2568 226,191,132,68,40,68,180,160,183,96,168,130,201,100,18,139,197,66,49,17,
2569 15,53,155,205,227,227,99,255,180,251,42,244,251,253,106,181,234,58,66,136,
2570 141,144,8,133,136,144,239,223,191,135,68,136,240,174,175,175,115,185,220,
2571 242,93,80,66,97,58,157,46,149,74,171,239,32,29,14,135,39,39,39,174,35,132,
2572 216,8,137,80,136,8,121,122,122,202,102,179,193,95,230,16,225,151,47,95,
2573 66,155,86,60,36,188,179,179,179,95,238,52,177,200,200,88,215,95,48,30,143,
2574 79,79,79,67,137,83,8,177,22,18,161,16,209,18,18,225,171,196,227,241,106,
2575 181,186,28,10,103,179,25,225,47,244,115,35,221,68,34,225,58,66,136,141,
2576 144,8,133,136,150,124,62,191,214,207,126,100,62,92,184,252,80,68,169,84,
2577 42,22,139,33,65,82,220,110,183,93,231,5,200,139,181,90,173,94,175,163,82,
2578 123,47,26,224,218,160,83,105,95,95,95,91,220,164,254,230,230,134,154,225,
2579 112,232,119,208,220,223,223,247,122,61,219,11,74,65,171,213,178,183,120,
2580 251,245,176,96,38,167,158,154,78,167,67,20,182,227,66,236,63,18,161,16,
2581 209,178,214,19,14,64,124,196,157,104,201,245,23,32,170,179,179,179,208,
2582 125,81,192,112,248,201,117,126,5,90,42,151,203,200,18,243,85,42,21,28,134,
2583 149,153,167,80,40,140,22,127,25,1,207,139,191,72,164,6,1,115,117,124,102,
2584 242,246,143,15,2,235,73,165,82,166,55,190,206,225,225,33,182,35,140,250,
2585 103,31,27,141,70,191,223,71,132,12,79,167,211,219,239,101,21,98,103,72,
2586 132,66,68,11,134,88,247,73,121,156,116,116,116,100,47,106,161,139,126,144,
2587 80,232,165,48,64,26,179,119,161,185,254,175,160,6,89,162,183,193,96,128,
2588 146,241,34,115,118,187,93,86,229,195,156,197,65,106,72,156,148,97,56,123,
2589 136,222,199,65,224,72,46,151,67,114,140,34,14,218,187,182,169,228,32,101,
2590 166,82,230,161,205,226,111,111,111,145,174,89,147,50,190,126,208,169,66,
2591 236,27,18,161,16,209,130,60,16,67,80,42,175,130,147,16,143,253,11,18,118,
2592 65,54,4,184,229,155,141,148,33,164,229,221,167,203,224,33,84,135,255,76,
2593 90,88,138,85,185,115,139,21,146,23,113,36,53,120,139,179,40,243,230,230,
2594 230,235,215,175,126,217,124,5,142,144,243,200,148,87,87,87,116,169,100,
2595 42,66,33,11,35,35,114,138,245,48,137,189,122,155,98,123,203,154,189,61,
2596 142,227,54,143,16,123,136,68,40,68,180,96,142,108,54,187,214,207,132,64,
2597 240,34,111,101,50,25,116,136,99,150,45,8,20,32,45,31,236,94,130,130,102,
2598 179,201,36,22,203,70,163,81,62,159,15,154,41,36,66,172,198,106,249,68,198,
2599 190,12,243,17,236,80,50,199,201,124,132,66,42,241,28,51,227,57,206,178,
2600 24,186,119,119,119,7,7,7,23,23,23,177,88,204,2,40,89,118,21,85,11,241,134,
2601 72,132,66,68,14,130,41,151,203,175,26,43,4,94,177,29,40,174,255,79,176,
2602 90,173,86,67,60,174,255,2,76,130,183,236,215,65,59,130,192,88,143,181,13,
2603 180,135,8,113,45,194,70,147,64,182,35,14,146,234,130,34,228,8,3,201,160,
2604 131,193,128,57,77,132,172,144,180,106,129,213,180,199,146,72,177,20,19,
2605 28,153,57,157,78,79,167,83,155,68,136,253,68,34,20,34,114,240,10,9,105,
2606 121,171,203,54,144,204,206,207,207,95,149,43,162,58,60,60,36,86,162,40,
2607 52,134,171,80,154,255,89,17,165,177,42,38,193,121,241,120,220,254,203,130,
2608 180,71,155,84,135,131,81,157,85,146,252,112,27,217,238,228,228,4,177,145,
2609 2,109,107,12,245,168,17,143,82,131,2,139,197,162,213,115,138,121,240,37,
2610 161,86,34,20,123,142,68,40,196,46,64,27,118,171,208,245,183,3,189,33,54,
2611 92,232,250,47,131,144,208,176,97,87,71,123,94,111,118,11,212,14,82,96,90,
2612 181,33,20,251,50,240,163,108,18,218,254,44,167,252,64,107,24,214,253,83,
2613 95,89,136,232,144,8,133,216,5,40,129,188,85,169,84,112,140,59,180,41,179,
2614 217,12,167,146,201,92,127,11,230,11,92,71,136,255,43,18,161,16,59,226,219,
2615 183,111,201,100,242,195,135,15,219,184,16,111,101,179,89,255,100,133,16,
2616 98,123,36,66,33,118,199,116,58,77,36,18,228,66,219,192,185,46,100,65,44,
2617 216,126,237,85,50,66,136,181,144,8,133,216,41,79,79,79,197,98,241,242,242,
2618 242,241,241,113,245,104,72,165,61,17,255,251,247,200,8,33,54,64,34,20,98,
2619 215,252,248,241,227,211,167,79,241,120,188,94,175,175,178,225,101,52,26,
2620 93,92,92,212,106,53,123,117,139,59,42,132,248,67,72,132,66,188,13,132,188,
2621 106,181,154,76,38,155,205,102,191,223,71,114,100,196,231,5,179,217,108,
2622 50,153,220,221,221,117,187,221,143,31,63,230,243,121,92,40,5,10,17,17,18,
2623 161,16,111,9,206,235,245,122,173,86,235,122,65,163,209,40,20,10,132,63,
2624 107,119,58,157,135,135,7,61,129,32,68,164,72,132,66,188,61,254,145,59,152,
2625 207,231,124,210,85,4,20,98,23,252,252,249,23,247,22,197,121,219,202,139,
2626 117,0,0,0,0,73,69,78,68,174,66,96,130};
2627 
2628 static size_t xml_res_size_1 = 242;
2629 static unsigned char xml_res_file_1[] = {
2630 60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101,
2631 110,99,111,100,105,110,103,61,34,85,84,70,45,56,34,63,62,10,60,114,101,
2632 115,111,117,114,99,101,32,120,109,108,110,115,61,34,104,116,116,112,58,
2633 47,47,119,119,119,46,119,120,119,105,100,103,101,116,115,46,111,114,103,
2634 47,119,120,120,114,99,34,62,10,32,32,60,33,45,45,32,72,97,110,100,108,101,
2635 114,32,71,101,110,101,114,97,116,105,111,110,32,105,115,32,79,78,32,45,
2636 45,62,10,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,
2637 120,66,105,116,109,97,112,34,32,110,97,109,101,61,34,65,98,111,117,116,
2638 50,48,49,55,34,62,80,114,111,112,101,114,116,105,101,115,70,111,114,109,
2639 66,105,116,109,97,112,115,46,99,112,112,36,100,97,116,97,95,105,109,97,
2640 103,101,115,95,65,98,111,117,116,50,48,49,55,46,112,110,103,60,47,111,98,
2641 106,101,99,116,62,10,60,47,114,101,115,111,117,114,99,101,62,10};
2642 
2643 void wxCDAD0InitBitmapResources()
2644 {
2645 
2646  // Check for memory FS. If not present, load the handler:
2647  {
2648  wxMemoryFSHandler::AddFile(wxT("XRC_resource/dummy_file"), wxT("dummy one"));
2649  wxFileSystem fsys;
2650  wxFSFile *f = fsys.OpenFile(wxT("memory:XRC_resource/dummy_file"));
2651  wxMemoryFSHandler::RemoveFile(wxT("XRC_resource/dummy_file"));
2652  if (f) delete f;
2653  else wxFileSystem::AddHandler(new wxMemoryFSHandlerBase);
2654  }
2655 
2656  XRC_ADD_FILE(wxT("XRC_resource/PropertiesFormBitmaps.cpp$data_images_About2017.png"), xml_res_file_0, xml_res_size_0, wxT("image/png"));
2657  XRC_ADD_FILE(wxT("XRC_resource/PropertiesFormBitmaps.cpp$_home_thales_Documentos_GitHub_PSP_Project_PropertiesFormBitmaps.xrc"), xml_res_file_1, xml_res_size_1, wxT("text/xml"));
2658  wxXmlResource::Get()->Load(wxT("memory:XRC_resource/PropertiesFormBitmaps.cpp$_home_thales_Documentos_GitHub_PSP_Project_PropertiesFormBitmaps.xrc"));
2659 }
1 /*
2  * Copyright (C) 2017 Thales Lima Oliveira <thales@ufu.br>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program. If not, see <https://www.gnu.org/licenses/>.
16  */
17 
18 #include "RateLimiterForm.h"
19 #include "RateLimiter.h"
20 
21 RateLimiterForm::RateLimiterForm(wxWindow* parent, RateLimiter* rateLimiter) : RateLimiterFormBase(parent)
22 {
23  SetSize(GetBestSize());
24 
25  m_rateLimiter = rateLimiter;
26  m_parent = parent;
27 
28  m_textCtrlUpLimit->SetValue(m_rateLimiter->StringFromDouble(m_rateLimiter->GetUpLimit()));
29  m_textCtrlLowLimit->SetValue(m_rateLimiter->StringFromDouble(m_rateLimiter->GetLowLimit()));
30 }
31 
32 RateLimiterForm::~RateLimiterForm() {}
33 bool RateLimiterForm::ValidateData()
34 {
35  double upLimit;
36  double lowLimit;
37 
38  if(!m_rateLimiter->DoubleFromString(this, m_textCtrlUpLimit->GetValue(), upLimit,
39  _("Value entered incorrectly in the field \"Upper limit\".")))
40  return false;
41  if(!m_rateLimiter->DoubleFromString(this, m_textCtrlLowLimit->GetValue(), lowLimit,
42  _("Value entered incorrectly in the field \"Lower limit\".")))
43  return false;
44 
45  m_rateLimiter->SetUpLimit(upLimit);
46  m_rateLimiter->SetLowLimit(lowLimit);
47 
48  return true;
49 }
50 
51 void RateLimiterForm::OnOKButtonClick(wxCommandEvent& event)
52 {
53  if(ValidateData()) EndModal(wxID_OK);
54 }
Limits the rising and/or falling rate.
Definition: RateLimiter.h:32
- +
diff --git a/docs/doxygen/html/_rate_limiter_form_8h_source.html b/docs/doxygen/html/_rate_limiter_form_8h_source.html index 900c9e8..8973a65 100644 --- a/docs/doxygen/html/_rate_limiter_form_8h_source.html +++ b/docs/doxygen/html/_rate_limiter_form_8h_source.html @@ -89,7 +89,7 @@ $(document).ready(function(){initNavTree('_rate_limiter_form_8h_source.html','')
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2017 Thales Lima Oliveira <thales@ufu.br>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program. If not, see <https://www.gnu.org/licenses/>.
16  */
17 
18 #ifndef RATELIMITERFORM_H
19 #define RATELIMITERFORM_H
20 #include "ElementForm.h"
21 
22 class RateLimiter;
23 
32 {
33  public:
34  RateLimiterForm(wxWindow* parent, RateLimiter* rateLimiter);
35  virtual ~RateLimiterForm();
36  bool ValidateData();
37 
38  protected:
39  virtual void OnCancelButtonClick(wxCommandEvent& event) { EndModal(wxID_OK); }
40  virtual void OnOKButtonClick(wxCommandEvent& event);
41 
42  wxWindow* m_parent = NULL;
43  RateLimiter* m_rateLimiter = NULL;
44 };
45 #endif // RATELIMITERFORM_H
Limits the rising and/or falling rate.
Definition: RateLimiter.h:32
- +
Form to edit the rate limit control data.
diff --git a/docs/doxygen/html/_reactive_shunt_element_form_8cpp_source.html b/docs/doxygen/html/_reactive_shunt_element_form_8cpp_source.html index 223e470..7d13283 100644 --- a/docs/doxygen/html/_reactive_shunt_element_form_8cpp_source.html +++ b/docs/doxygen/html/_reactive_shunt_element_form_8cpp_source.html @@ -91,7 +91,7 @@ $(document).ready(function(){initNavTree('_reactive_shunt_element_form_8cpp_sour
1 /*
2  * Copyright (C) 2017 Thales Lima Oliveira <thales@ufu.br>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program. If not, see <https://www.gnu.org/licenses/>.
16  */
17 
19 #include "SwitchingForm.h"
20 #include "Capacitor.h"
21 #include "Inductor.h"
22 
23 ReactiveShuntElementForm::ReactiveShuntElementForm(wxWindow* parent, Capacitor* capacitor)
25 {
26  SetSize(GetBestSize());
27  CapacitorElectricalData data = capacitor->GetElectricalData();
28 
29  m_textCtrlName->SetValue(data.name);
30 
31  m_textCtrlReactivePower->SetValue(Capacitor::StringFromDouble(data.reactivePower));
32  switch(data.reactivePowerUnit) {
33  case UNIT_PU: {
34  m_choiceReactivePower->SetSelection(0);
35  } break;
36  case UNIT_VAr: {
37  m_choiceReactivePower->SetSelection(1);
38  } break;
39  case UNIT_kVAr: {
40  m_choiceReactivePower->SetSelection(2);
41  } break;
42  case UNIT_MVAr: {
43  m_choiceReactivePower->SetSelection(3);
44  } break;
45  default:
46  break;
47  }
48 
49  m_parent = parent;
50  m_capacitor = capacitor;
51 }
52 
53 ReactiveShuntElementForm::ReactiveShuntElementForm(wxWindow* parent, Inductor* inductor)
55 {
56  InductorElectricalData data = inductor->GetElectricalData();
57 
58  m_textCtrlName->SetValue(data.name);
59 
60  m_textCtrlReactivePower->SetValue(Inductor::StringFromDouble(data.reactivePower));
61  switch(data.reactivePowerUnit) {
62  case UNIT_PU: {
63  m_choiceReactivePower->SetSelection(0);
64  } break;
65  case UNIT_VAr: {
66  m_choiceReactivePower->SetSelection(1);
67  } break;
68  case UNIT_kVAr: {
69  m_choiceReactivePower->SetSelection(2);
70  } break;
71  case UNIT_MVAr: {
72  m_choiceReactivePower->SetSelection(3);
73  } break;
74  default:
75  break;
76  }
77 
78  m_parent = parent;
79  m_inductor = inductor;
80 }
81 
82 ReactiveShuntElementForm::~ReactiveShuntElementForm() {}
83 void ReactiveShuntElementForm::OnOKButtonClick(wxCommandEvent& event)
84 {
85  if(ValidateData()) EndModal(wxID_OK);
86 }
87 
88 void ReactiveShuntElementForm::OnStabilityButtonClick(wxCommandEvent& event)
89 {
90  if(ValidateData()) {
91  if(m_capacitor) {
92  SwitchingForm swForm(m_parent, m_capacitor);
93  swForm.SetTitle(_("Capacitor: Switching"));
94  swForm.ShowModal();
95  } else if(m_inductor) {
96  SwitchingForm swForm(m_parent, m_inductor);
97  swForm.SetTitle(_("Inductor: Switching"));
98  swForm.ShowModal();
99  }
100 
101  EndModal(wxID_OK);
102  }
103 }
104 
105 bool ReactiveShuntElementForm::ValidateData()
106 {
107  if(m_capacitor) {
109 
110  data.name = m_textCtrlName->GetValue();
111 
112  if(!m_capacitor->DoubleFromString(m_parent, m_textCtrlReactivePower->GetValue(), data.reactivePower,
113  _("Value entered incorrectly in the field \"Reactive power\".")))
114  return false;
115  switch(m_choiceReactivePower->GetSelection()) {
116  case 0: {
117  data.reactivePowerUnit = UNIT_PU;
118  } break;
119  case 1: {
120  data.reactivePowerUnit = UNIT_VAr;
121  } break;
122  case 2: {
123  data.reactivePowerUnit = UNIT_kVAr;
124  } break;
125  case 3: {
126  data.reactivePowerUnit = UNIT_MVAr;
127  } break;
128  }
129 
130  m_capacitor->SetElectricalData(data);
131  } else if(m_inductor) {
133 
134  data.name = m_textCtrlName->GetValue();
135 
136  if(!m_inductor->DoubleFromString(m_parent, m_textCtrlReactivePower->GetValue(), data.reactivePower,
137  _("Value entered incorrectly in the field \"Reactive power\".")))
138  return false;
139  switch(m_choiceReactivePower->GetSelection()) {
140  case 0: {
141  data.reactivePowerUnit = UNIT_PU;
142  } break;
143  case 1: {
144  data.reactivePowerUnit = UNIT_VAr;
145  } break;
146  case 2: {
147  data.reactivePowerUnit = UNIT_kVAr;
148  } break;
149  case 3: {
150  data.reactivePowerUnit = UNIT_MVAr;
151  } break;
152  }
153 
154  m_inductor->SetElectricalData(data);
155  }
156  return true;
157 }
Form to edit the switching data of power elements for electromechanical transient studies...
Definition: SwitchingForm.h:32
- + diff --git a/docs/doxygen/html/_reactive_shunt_element_form_8h_source.html b/docs/doxygen/html/_reactive_shunt_element_form_8h_source.html index 90b36ac..06693ba 100644 --- a/docs/doxygen/html/_reactive_shunt_element_form_8h_source.html +++ b/docs/doxygen/html/_reactive_shunt_element_form_8h_source.html @@ -89,7 +89,7 @@ $(document).ready(function(){initNavTree('_reactive_shunt_element_form_8h_source
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2017 Thales Lima Oliveira <thales@ufu.br>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program. If not, see <https://www.gnu.org/licenses/>.
16  */
17 
18 #ifndef REACTIVESHUNTELEMENTFORM_H
19 #define REACTIVESHUNTELEMENTFORM_H
20 #include "ElementForm.h"
21 #include <wx/log.h>
22 
23 class Capacitor;
24 class Inductor;
25 class SwitchingForm;
26 
35 {
36  public:
37  ReactiveShuntElementForm(wxWindow* parent, Capacitor* capacitor);
38  ReactiveShuntElementForm(wxWindow* parent, Inductor* inductor);
39  virtual ~ReactiveShuntElementForm();
40  virtual bool ValidateData();
41 
42  protected:
43  virtual void OnCancelButtonClick(wxCommandEvent& event) { EndModal(wxID_CANCEL); }
44  virtual void OnOKButtonClick(wxCommandEvent& event);
45  virtual void OnStabilityButtonClick(wxCommandEvent& event);
46 
47  wxWindow* m_parent;
48  Capacitor* m_capacitor = NULL;
49  Inductor* m_inductor = NULL;
50 };
51 #endif // REACTIVESHUNTELEMENTFORM_H
Form to edit the switching data of power elements for electromechanical transient studies...
Definition: SwitchingForm.h:32
- +
Shunt capactior power element.
Definition: Capacitor.h:38
Inductor shunt power element.
Definition: Inductor.h:38
Form to edit the reactive shunt element power data.
diff --git a/docs/doxygen/html/_simulations_settings_form_8cpp_source.html b/docs/doxygen/html/_simulations_settings_form_8cpp_source.html index 3050651..38f5b6c 100644 --- a/docs/doxygen/html/_simulations_settings_form_8cpp_source.html +++ b/docs/doxygen/html/_simulations_settings_form_8cpp_source.html @@ -88,7 +88,7 @@ $(document).ready(function(){initNavTree('_simulations_settings_form_8cpp_source
SimulationsSettingsForm.cpp
-
1 /*
2  * Copyright (C) 2017 Thales Lima Oliveira <thales@ufu.br>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program. If not, see <https://www.gnu.org/licenses/>.
16  */
17 
19 #include "PropertiesData.h"
20 
21 SimulationsSettingsForm::SimulationsSettingsForm(wxWindow* parent, PropertiesData* properties)
23 {
24  m_properties = properties;
25  auto data = m_properties->GetSimulationPropertiesData();
26 
27  m_textCtrlbasePower->SetValue(Element::StringFromDouble(data.basePower));
28  switch(data.basePowerUnit) {
29  case UNIT_VA: {
30  m_choiceBasePower->SetSelection(0);
31  } break;
32  case UNIT_kVA: {
33  m_choiceBasePower->SetSelection(1);
34  } break;
35  case UNIT_MVA: {
36  m_choiceBasePower->SetSelection(2);
37  } break;
38  default: {
39  m_choiceBasePower->SetSelection(wxNOT_FOUND);
40  } break;
41  }
42  m_checkBoxFaultAfterPF->SetValue(data.faultAfterPowerFlow);
43  m_checkBoxSCPowerAfterPF->SetValue(data.scPowerAfterPowerFlow);
44  switch(data.powerFlowMethod) {
45  case GAUSS_SEIDEL: {
46  m_choicePFMethod->SetSelection(0);
47  } break;
48  case NEWTON_RAPHSON: {
49  m_choicePFMethod->SetSelection(1);
50  m_textCtrlAccFactor->Enable(false);
51  } break;
52  default: {
53  m_choicePFMethod->SetSelection(wxNOT_FOUND);
54  } break;
55  }
56  m_textCtrlAccFactor->SetValue(Element::StringFromDouble(data.accFator));
57  m_textCtrlPFTolerance->SetValue(wxString::Format("%g", data.powerFlowTolerance));
58  m_textCtrlPFMaxIterations->SetValue(wxString::Format("%d", data.powerFlowMaxIterations));
59  m_textCtrlTimeStep->SetValue(wxString::Format("%g", data.timeStep));
60  m_textCtrlSimTime->SetValue(Element::StringFromDouble(data.stabilitySimulationTime));
61  m_textCtrlFreq->SetValue(Element::StringFromDouble(data.stabilityFrequency));
62  m_textCtrlStabTolerance->SetValue(wxString::Format("%g", data.stabilityTolerance));
63  m_textCtrlStabMaxIterations->SetValue(wxString::Format("%d", data.stabilityMaxIterations));
64  m_textCtrlCtrlStepRatio->SetValue(wxString::Format("%d", data.controlTimeStepRatio));
65  m_textCtrlPrintTime->SetValue(wxString::Format("%g", data.plotTime));
66 
67  m_checkBoxUseCOI->SetValue(data.useCOI);
68 }
69 
70 SimulationsSettingsForm::~SimulationsSettingsForm() {}
71 void SimulationsSettingsForm::OnButtonOKClick(wxCommandEvent& event)
72 {
73  if(ValidateData()) EndModal(wxID_OK);
74 }
75 
76 bool SimulationsSettingsForm::ValidateData()
77 {
78  auto data = m_properties->GetSimulationPropertiesData();
79  if(!Element::DoubleFromString(this, m_textCtrlbasePower->GetValue(), data.basePower,
80  _("Value entered incorrectly in the field \"Base power\".")))
81  return false;
82  switch(m_choiceBasePower->GetSelection()) {
83  case 0: {
84  data.basePowerUnit = UNIT_VA;
85  } break;
86  case 1: {
87  data.basePowerUnit = UNIT_kVA;
88  } break;
89  default: {
90  data.basePowerUnit = UNIT_MVA;
91  } break;
92  }
93  data.faultAfterPowerFlow = m_checkBoxFaultAfterPF->GetValue();
94  data.scPowerAfterPowerFlow = m_checkBoxSCPowerAfterPF->GetValue();
95  switch(m_choicePFMethod->GetSelection()) {
96  case 0: {
97  data.powerFlowMethod = GAUSS_SEIDEL;
98  } break;
99  case 1: {
100  data.powerFlowMethod = NEWTON_RAPHSON;
101  } break;
102  }
103  if(!Element::DoubleFromString(this, m_textCtrlAccFactor->GetValue(), data.accFator,
104  _("Value entered incorrectly in the field \"Acceleration factor\".")))
105  return false;
106  if(!Element::DoubleFromString(this, m_textCtrlPFTolerance->GetValue(), data.powerFlowTolerance,
107  _("Value entered incorrectly in the field \"Tolerance (Power flow)\".")))
108  return false;
109  if(!Element::IntFromString(this, m_textCtrlPFMaxIterations->GetValue(), data.powerFlowMaxIterations,
110  _("Value entered incorrectly in the field \"Max. iterations (Power flow)\".")))
111  return false;
112  if(!Element::DoubleFromString(this, m_textCtrlTimeStep->GetValue(), data.timeStep,
113  _("Value entered incorrectly in the field \"Time step\".")))
114  return false;
115  if(!Element::DoubleFromString(this, m_textCtrlSimTime->GetValue(), data.stabilitySimulationTime,
116  _("Value entered incorrectly in the field \"Simulation time\".")))
117  return false;
118  if(!Element::DoubleFromString(this, m_textCtrlFreq->GetValue(), data.stabilityFrequency,
119  _("Value entered incorrectly in the field \"System frequency\".")))
120  return false;
121  if(!Element::DoubleFromString(this, m_textCtrlStabTolerance->GetValue(), data.stabilityTolerance,
122  _("Value entered incorrectly in the field \"Tolerance (Stability)\".")))
123  return false;
124  if(!Element::IntFromString(this, m_textCtrlStabMaxIterations->GetValue(), data.stabilityMaxIterations,
125  _("Value entered incorrectly in the field \"Max. iterations (Stability)\".")))
126  return false;
127  if(!Element::IntFromString(this, m_textCtrlCtrlStepRatio->GetValue(), data.controlTimeStepRatio,
128  _("Value entered incorrectly in the field \"Controls step ratio\".")))
129  return false;
130  if(!Element::DoubleFromString(this, m_textCtrlPrintTime->GetValue(), data.plotTime,
131  _("Value entered incorrectly in the field \"Plot time\".")))
132  return false;
133  data.useCOI = m_checkBoxUseCOI->GetValue();
134 
135  m_properties->SetSimulationPropertiesData(data);
136  return true;
137 }
138 void SimulationsSettingsForm::OnPFMethodChoiceSelected(wxCommandEvent& event)
139 {
140  if(m_choicePFMethod->GetSelection() == 0)
141  m_textCtrlAccFactor->Enable();
142  else
143  m_textCtrlAccFactor->Enable(false);
144 }
General and simulation data manager.
+
1 /*
2  * Copyright (C) 2017 Thales Lima Oliveira <thales@ufu.br>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program. If not, see <https://www.gnu.org/licenses/>.
16  */
17 
19 #include "PropertiesData.h"
20 
21 SimulationsSettingsForm::SimulationsSettingsForm(wxWindow* parent, PropertiesData* properties)
23 {
24  m_properties = properties;
25  auto data = m_properties->GetSimulationPropertiesData();
26 
27  m_textCtrlbasePower->SetValue(Element::StringFromDouble(data.basePower));
28  switch(data.basePowerUnit) {
29  case UNIT_VA: {
30  m_choiceBasePower->SetSelection(0);
31  } break;
32  case UNIT_kVA: {
33  m_choiceBasePower->SetSelection(1);
34  } break;
35  case UNIT_MVA: {
36  m_choiceBasePower->SetSelection(2);
37  } break;
38  default: {
39  m_choiceBasePower->SetSelection(wxNOT_FOUND);
40  } break;
41  }
42  m_checkBoxFaultAfterPF->SetValue(data.faultAfterPowerFlow);
43  m_checkBoxSCPowerAfterPF->SetValue(data.scPowerAfterPowerFlow);
44  switch(data.powerFlowMethod) {
45  case GAUSS_SEIDEL: {
46  m_choicePFMethod->SetSelection(0);
47  } break;
48  case NEWTON_RAPHSON: {
49  m_choicePFMethod->SetSelection(1);
50  m_textCtrlAccFactor->Enable(false);
51  } break;
52  default: {
53  m_choicePFMethod->SetSelection(wxNOT_FOUND);
54  } break;
55  }
56  m_textCtrlAccFactor->SetValue(Element::StringFromDouble(data.accFator));
57  m_textCtrlPFTolerance->SetValue(wxString::Format("%g", data.powerFlowTolerance));
58  m_textCtrlPFMaxIterations->SetValue(wxString::Format("%d", data.powerFlowMaxIterations));
59  m_textCtrlTimeStep->SetValue(wxString::Format("%g", data.timeStep));
60  m_textCtrlSimTime->SetValue(Element::StringFromDouble(data.stabilitySimulationTime));
61  m_textCtrlFreq->SetValue(Element::StringFromDouble(data.stabilityFrequency));
62  m_textCtrlStabTolerance->SetValue(wxString::Format("%g", data.stabilityTolerance));
63  m_textCtrlStabMaxIterations->SetValue(wxString::Format("%d", data.stabilityMaxIterations));
64  m_textCtrlCtrlStepRatio->SetValue(wxString::Format("%d", data.controlTimeStepRatio));
65  m_textCtrlPrintTime->SetValue(wxString::Format("%g", data.plotTime));
66 
67  m_checkBoxUseCOI->SetValue(data.useCOI);
68 
69  m_checkBoxUseCompLoads->SetValue(data.useCompLoads);
70 
71  m_textCtrlActivePowerImp->SetValue(Element::StringFromDouble(data.constImpedanceActive));
72  m_textCtrlActivePowerCur->SetValue(Element::StringFromDouble(data.constCurrentActive));
73  m_textCtrlActivePowerPow->SetValue(Element::StringFromDouble(data.constPowerActive));
74  m_textCtrlReactivePowerImp->SetValue(Element::StringFromDouble(data.constImpedanceReactive));
75  m_textCtrlReactivePowerCur->SetValue(Element::StringFromDouble(data.constCurrentReactive));
76  m_textCtrlReactivePowerPow->SetValue(Element::StringFromDouble(data.constPowerReactive));
77 
78  m_textCtrlUVCur->SetValue(Element::StringFromDouble(data.underVoltageConstCurrent));
79  m_textCtrlUVPow->SetValue(Element::StringFromDouble(data.underVoltageConstPower));
80 
81  UpdateZIPLoadFieldStatus();
82 }
83 
84 SimulationsSettingsForm::~SimulationsSettingsForm() {}
85 void SimulationsSettingsForm::OnButtonOKClick(wxCommandEvent& event)
86 {
87  if(ValidateData()) EndModal(wxID_OK);
88 }
89 
90 bool SimulationsSettingsForm::ValidateData()
91 {
92  auto data = m_properties->GetSimulationPropertiesData();
93  if(!Element::DoubleFromString(this, m_textCtrlbasePower->GetValue(), data.basePower,
94  _("Value entered incorrectly in the field \"Base power\".")))
95  return false;
96  switch(m_choiceBasePower->GetSelection()) {
97  case 0: {
98  data.basePowerUnit = UNIT_VA;
99  } break;
100  case 1: {
101  data.basePowerUnit = UNIT_kVA;
102  } break;
103  default: {
104  data.basePowerUnit = UNIT_MVA;
105  } break;
106  }
107  data.faultAfterPowerFlow = m_checkBoxFaultAfterPF->GetValue();
108  data.scPowerAfterPowerFlow = m_checkBoxSCPowerAfterPF->GetValue();
109  switch(m_choicePFMethod->GetSelection()) {
110  case 0: {
111  data.powerFlowMethod = GAUSS_SEIDEL;
112  } break;
113  case 1: {
114  data.powerFlowMethod = NEWTON_RAPHSON;
115  } break;
116  }
117  if(!Element::DoubleFromString(this, m_textCtrlAccFactor->GetValue(), data.accFator,
118  _("Value entered incorrectly in the field \"Acceleration factor\".")))
119  return false;
120  if(!Element::DoubleFromString(this, m_textCtrlPFTolerance->GetValue(), data.powerFlowTolerance,
121  _("Value entered incorrectly in the field \"Tolerance (Power flow)\".")))
122  return false;
123  if(!Element::IntFromString(this, m_textCtrlPFMaxIterations->GetValue(), data.powerFlowMaxIterations,
124  _("Value entered incorrectly in the field \"Max. iterations (Power flow)\".")))
125  return false;
126  if(!Element::DoubleFromString(this, m_textCtrlTimeStep->GetValue(), data.timeStep,
127  _("Value entered incorrectly in the field \"Time step\".")))
128  return false;
129  if(!Element::DoubleFromString(this, m_textCtrlSimTime->GetValue(), data.stabilitySimulationTime,
130  _("Value entered incorrectly in the field \"Simulation time\".")))
131  return false;
132  if(!Element::DoubleFromString(this, m_textCtrlFreq->GetValue(), data.stabilityFrequency,
133  _("Value entered incorrectly in the field \"System frequency\".")))
134  return false;
135  if(!Element::DoubleFromString(this, m_textCtrlStabTolerance->GetValue(), data.stabilityTolerance,
136  _("Value entered incorrectly in the field \"Tolerance (Stability)\".")))
137  return false;
138  if(!Element::IntFromString(this, m_textCtrlStabMaxIterations->GetValue(), data.stabilityMaxIterations,
139  _("Value entered incorrectly in the field \"Max. iterations (Stability)\".")))
140  return false;
141  if(!Element::IntFromString(this, m_textCtrlCtrlStepRatio->GetValue(), data.controlTimeStepRatio,
142  _("Value entered incorrectly in the field \"Controls step ratio\".")))
143  return false;
144  if(!Element::DoubleFromString(this, m_textCtrlPrintTime->GetValue(), data.plotTime,
145  _("Value entered incorrectly in the field \"Plot time\".")))
146  return false;
147  data.useCOI = m_checkBoxUseCOI->GetValue();
148 
149  data.useCompLoads = m_checkBoxUseCompLoads->GetValue();
150 
152  this, m_textCtrlActivePowerImp->GetValue(), data.constImpedanceActive,
153  _("Value entered incorrectly in the field \"Constant impedance portion of active power (ZIP load)\".")))
154  return false;
156  this, m_textCtrlActivePowerCur->GetValue(), data.constCurrentActive,
157  _("Value entered incorrectly in the field \"Constant current portion of active power (ZIP load)\".")))
158  return false;
160  this, m_textCtrlActivePowerPow->GetValue(), data.constPowerActive,
161  _("Value entered incorrectly in the field \"Constant power portion of active power (ZIP load)\".")))
162  return false;
164  this, m_textCtrlReactivePowerImp->GetValue(), data.constImpedanceReactive,
165  _("Value entered incorrectly in the field \"Constant impedance portion of reactive power (ZIP load)\".")))
166  return false;
168  this, m_textCtrlReactivePowerCur->GetValue(), data.constCurrentReactive,
169  _("Value entered incorrectly in the field \"Constant current portion of reactive power (ZIP load)\".")))
170  return false;
172  this, m_textCtrlReactivePowerPow->GetValue(), data.constPowerReactive,
173  _("Value entered incorrectly in the field \"Constant power portion of reactive power (ZIP load)\".")))
174  return false;
175 
177  this, m_textCtrlUVCur->GetValue(), data.underVoltageConstCurrent,
178  _("Value entered incorrectly in the field \"Constant current undervoltage limit (ZIP load)\".")))
179  return false;
180 
182  this, m_textCtrlUVPow->GetValue(), data.underVoltageConstPower,
183  _("Value entered incorrectly in the field \"Constant power undervoltage limit (ZIP load)\".")))
184  return false;
185 
186  double sum = data.constImpedanceActive + data.constCurrentActive + data.constPowerActive;
187  if(sum > 100.01 || sum < 99.99) {
188  wxMessageDialog msgDialog(this, _("The sum of active power load composition must be 100%."), _("Error"),
189  wxOK | wxCENTRE | wxICON_ERROR);
190  msgDialog.ShowModal();
191  return false;
192  }
193  sum = data.constImpedanceReactive + data.constCurrentReactive + data.constPowerReactive;
194  if(sum > 100.01 || sum < 99.99) {
195  wxMessageDialog msgDialog(this, _("The sum of reactive power load composition must be 100%."), _("Error"),
196  wxOK | wxCENTRE | wxICON_ERROR);
197  msgDialog.ShowModal();
198  return false;
199  }
200 
201  m_properties->SetSimulationPropertiesData(data);
202  return true;
203 }
204 
205 void SimulationsSettingsForm::OnPFMethodChoiceSelected(wxCommandEvent& event)
206 {
207  if(m_choicePFMethod->GetSelection() == 0)
208  m_textCtrlAccFactor->Enable();
209  else
210  m_textCtrlAccFactor->Enable(false);
211 }
212 
213 void SimulationsSettingsForm::UpdateZIPLoadFieldStatus()
214 {
215  m_textCtrlActivePowerImp->Enable(m_checkBoxUseCompLoads->GetValue());
216  m_textCtrlActivePowerCur->Enable(m_checkBoxUseCompLoads->GetValue());
217  m_textCtrlActivePowerPow->Enable(m_checkBoxUseCompLoads->GetValue());
218  m_textCtrlReactivePowerImp->Enable(m_checkBoxUseCompLoads->GetValue());
219  m_textCtrlReactivePowerCur->Enable(m_checkBoxUseCompLoads->GetValue());
220  m_textCtrlReactivePowerPow->Enable(m_checkBoxUseCompLoads->GetValue());
221 }
General and simulation data manager.
static bool DoubleFromString(wxWindow *parent, wxString strValue, double &value, wxString errorMsg)
Get a double value from a string. Show a error message if the conversion fail.
Definition: Element.cpp:292
diff --git a/docs/doxygen/html/_simulations_settings_form_8h_source.html b/docs/doxygen/html/_simulations_settings_form_8h_source.html index f10796a..84f24c1 100644 --- a/docs/doxygen/html/_simulations_settings_form_8h_source.html +++ b/docs/doxygen/html/_simulations_settings_form_8h_source.html @@ -88,7 +88,7 @@ $(document).ready(function(){initNavTree('_simulations_settings_form_8h_source.h
SimulationsSettingsForm.h
-Go to the documentation of this file.
1 /*
2  * Copyright (C) 2017 Thales Lima Oliveira <thales@ufu.br>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program. If not, see <https://www.gnu.org/licenses/>.
16  */
17 
18 #ifndef SIMULATIONSSETTINGSFORM_H
19 #define SIMULATIONSSETTINGSFORM_H
20 
21 #include "PropertiesForm.h"
22 
23 class PropertiesData;
24 
33 {
34  public:
35  SimulationsSettingsForm(wxWindow* parent, PropertiesData* properties);
36  virtual ~SimulationsSettingsForm();
37 
38  protected:
39  virtual void OnPFMethodChoiceSelected(wxCommandEvent& event);
40  virtual void OnButtonCancelClick(wxCommandEvent& event) { EndModal(wxID_CANCEL); }
41  virtual void OnButtonOKClick(wxCommandEvent& event);
42  virtual bool ValidateData();
43 
44  PropertiesData* m_properties;
45 };
46 #endif // SIMULATIONSSETTINGSFORM_H
General and simulation data manager.
+Go to the documentation of this file.
1 /*
2  * Copyright (C) 2017 Thales Lima Oliveira <thales@ufu.br>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program. If not, see <https://www.gnu.org/licenses/>.
16  */
17 
18 #ifndef SIMULATIONSSETTINGSFORM_H
19 #define SIMULATIONSSETTINGSFORM_H
20 
21 #include "PropertiesForm.h"
22 
23 class PropertiesData;
24 
33 {
34  public:
35  SimulationsSettingsForm(wxWindow* parent, PropertiesData* properties);
36  virtual ~SimulationsSettingsForm();
37 
38  protected:
39  virtual void OnCheckboxUseCompLoadClick(wxCommandEvent& event) { UpdateZIPLoadFieldStatus(); }
40  virtual void OnPFMethodChoiceSelected(wxCommandEvent& event);
41  virtual void OnButtonCancelClick(wxCommandEvent& event) { EndModal(wxID_CANCEL); }
42  virtual void OnButtonOKClick(wxCommandEvent& event);
43  virtual bool ValidateData();
44  virtual void UpdateZIPLoadFieldStatus();
45 
46  PropertiesData* m_properties;
47 };
48 #endif // SIMULATIONSSETTINGSFORM_H
General and simulation data manager.
Form to edit the simulation data.
diff --git a/docs/doxygen/html/_sum_form_8cpp_source.html b/docs/doxygen/html/_sum_form_8cpp_source.html index 82c6d7b..e6f7b01 100644 --- a/docs/doxygen/html/_sum_form_8cpp_source.html +++ b/docs/doxygen/html/_sum_form_8cpp_source.html @@ -91,7 +91,7 @@ $(document).ready(function(){initNavTree('_sum_form_8cpp_source.html','');});
1 /*
2  * Copyright (C) 2017 Thales Lima Oliveira <thales@ufu.br>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program. If not, see <https://www.gnu.org/licenses/>.
16  */
17 
18 #include "SumForm.h"
19 #include "Sum.h"
20 
21 SumForm::SumForm(wxWindow* parent, Sum* sum) : SumFormBase(parent)
22 {
23  SetSize(GetBestSize());
24 
25  m_parent = parent;
26  m_sum = sum;
27 
28  wxString signalStr = "";
29  auto signalList = m_sum->GetSignalList();
30  for(auto it = signalList.begin(), itEnd = signalList.end(); it != itEnd; ++it) {
31  Sum::Signal signal = *it;
32  switch(signal) {
33  case Sum::SIGNAL_POSITIVE: {
34  signalStr += "+";
35  } break;
36  case Sum::SIGNAL_NEGATIVE: {
37  signalStr += "-";
38  } break;
39  }
40  if(it != itEnd - 1) signalStr += " ";
41  }
42  m_textCtrlSigns->SetValue(signalStr);
43 }
44 
45 SumForm::~SumForm() {}
46 void SumForm::OnOKClick(wxCommandEvent& event)
47 {
48  if(ValidateData()) EndModal(wxID_OK);
49 }
50 
51 bool SumForm::ValidateData()
52 {
53  wxString signalStr = "";
54  for(int i = 0; i < (int)m_textCtrlSigns->GetValue().length(); ++i) {
55  if(m_textCtrlSigns->GetValue()[i] != ' ') signalStr += m_textCtrlSigns->GetValue()[i];
56  }
57  if(signalStr.size() < 2) {
58  wxMessageDialog msg(this, _("You must assign at least two signals."), _("Error"),
59  wxOK | wxCENTRE | wxICON_ERROR);
60  msg.ShowModal();
61  return false;
62  }
63 
64  std::vector<Sum::Signal> signalList;
65  for(int i = 0; i < (int)signalStr.length(); ++i) {
66  switch(signalStr[i].GetValue()) {
67  case '+': {
68  signalList.push_back(Sum::SIGNAL_POSITIVE);
69  } break;
70  case '-': {
71  signalList.push_back(Sum::SIGNAL_NEGATIVE);
72  } break;
73  default: {
74  wxMessageDialog msg(this, _("Value entered incorrectly in the field \"Signs\"."), _("Error"),
75  wxOK | wxCENTRE | wxICON_ERROR);
76  msg.ShowModal();
77  return false;
78  }
79  }
80  }
81 
82  int diff = (int)signalList.size() - (int)m_sum->GetSignalList().size();
83 
84  if(diff < 0) {
85  diff = std::abs(diff);
86  for(int i = 0; i < diff; ++i) {
87  m_sum->RemoveInNode();
88  }
89  } else if(diff > 0) {
90  for(int i = 0; i < diff; ++i) {
91  m_sum->AddInNode();
92  }
93  }
94  m_sum->SetSignalList(signalList);
95  m_sum->UpdatePoints();
96  return true;
97 }
Sum the all inputs (can choose the input signal).
Definition: Sum.h:33
- +
diff --git a/docs/doxygen/html/_sum_form_8h_source.html b/docs/doxygen/html/_sum_form_8h_source.html index d5fa8d7..63580bd 100644 --- a/docs/doxygen/html/_sum_form_8h_source.html +++ b/docs/doxygen/html/_sum_form_8h_source.html @@ -90,7 +90,7 @@ $(document).ready(function(){initNavTree('_sum_form_8h_source.html','');});
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2017 Thales Lima Oliveira <thales@ufu.br>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program. If not, see <https://www.gnu.org/licenses/>.
16  */
17 
18 #ifndef SUMFORM_H
19 #define SUMFORM_H
20 
21 #include "ElementForm.h"
22 
23 class Sum;
24 
32 class SumForm : public SumFormBase
33 {
34  public:
35  SumForm(wxWindow* parent, Sum* sum);
36  virtual ~SumForm();
37 
38  bool ValidateData();
39 
40  protected:
41  virtual void OnCancelClick(wxCommandEvent& event) { EndModal(wxID_CANCEL); }
42  virtual void OnOKClick(wxCommandEvent& event);
43  wxWindow* m_parent = NULL;
44  Sum* m_sum = NULL;
45 };
46 #endif // SUMFORM_H
Form to edit the sum control data.
Definition: SumForm.h:32
Sum the all inputs (can choose the input signal).
Definition: Sum.h:33
- +
diff --git a/docs/doxygen/html/_switching_form_8cpp_source.html b/docs/doxygen/html/_switching_form_8cpp_source.html index 0c4cba4..2ce41ad 100644 --- a/docs/doxygen/html/_switching_form_8cpp_source.html +++ b/docs/doxygen/html/_switching_form_8cpp_source.html @@ -91,7 +91,7 @@ $(document).ready(function(){initNavTree('_switching_form_8cpp_source.html','');
1 /*
2  * Copyright (C) 2017 Thales Lima Oliveira <thales@ufu.br>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program. If not, see <https://www.gnu.org/licenses/>.
16  */
17 
18 #include "SwitchingForm.h"
19 #include "PowerElement.h"
20 
21 SwitchingForm::SwitchingForm(wxWindow* parent) : SwitchingFormBase(parent)
22 {
23  m_listCtrlSwitchings->AppendColumn(_("Type"));
24  m_listCtrlSwitchings->AppendColumn(_("Time (s)"));
25 
26  SetSize(GetBestSize());
27  Layout();
28 }
29 
30 SwitchingForm::SwitchingForm(wxWindow* parent, PowerElement* element) : SwitchingFormBase(parent)
31 {
32  m_listCtrlSwitchings->AppendColumn(_("Type"));
33  m_listCtrlSwitchings->AppendColumn(_("Time (s)"));
34 
35  SetSize(GetBestSize());
36  Layout();
37 
38  SwitchingData data = element->GetSwitchingData();
39  for(int i = 0; i < (int)data.swType.size(); i++) {
40  long index = m_listCtrlSwitchings->InsertItem(m_maxID, data.swType[i] == SW_INSERT ? _("Insert") : _("Remove"));
41  m_listCtrlSwitchings->SetItem(index, 1, wxString::FromDouble(data.swTime[i]));
42  m_maxID++;
43  }
44 
45  m_element = element;
46 }
47 
48 SwitchingForm::~SwitchingForm() {}
49 void SwitchingForm::OnCancelButtonClick(wxCommandEvent& event) { EndModal(wxID_CANCEL); }
50 void SwitchingForm::OnInsertButtonClick(wxCommandEvent& event)
51 {
52  long index = m_listCtrlSwitchings->InsertItem(
53  m_maxID, m_pgPropType->GetValue().GetInteger() == 0 ? _("Insert") : _("Remove"));
54  m_listCtrlSwitchings->SetItem(index, 1, m_pgPropTime->GetValue().GetString());
55  m_maxID++;
56 }
57 void SwitchingForm::OnOKButtonClick(wxCommandEvent& event)
58 {
59  std::vector<long> itemList;
60  long item = -1;
61  while(true) {
62  item = m_listCtrlSwitchings->GetNextItem(item);
63  if(item == -1) break;
64  itemList.push_back(item);
65  }
66 
67  SwitchingData data;
68  for(int i = 0; i < (int)itemList.size(); i++) {
69  if(m_listCtrlSwitchings->GetItemText(itemList[i], 0) == _("Insert"))
70  data.swType.push_back(SW_INSERT);
71  else
72  data.swType.push_back(SW_REMOVE);
73 
74  double swTime;
75  m_listCtrlSwitchings->GetItemText(itemList[i], 1).ToDouble(&swTime);
76  data.swTime.push_back(swTime);
77  }
78  m_element->SetSwitchingData(data);
79 
80  if(data.swTime.size() != 0)
81  m_element->SetDynamicEvent(true);
82  else
83  m_element->SetDynamicEvent(false);
84 
85  EndModal(wxID_OK);
86 }
87 
88 void SwitchingForm::OnRemoveButtonClick(wxCommandEvent& event)
89 {
90  std::vector<long> itemList;
91  long item = -1;
92  while(true) {
93  item = m_listCtrlSwitchings->GetNextItem(item, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
94  if(item == -1) break;
95  itemList.push_back(item);
96  }
97  for(int i = (int)itemList.size() - 1; i >= 0; i--) {
98  m_listCtrlSwitchings->DeleteItem(itemList[i]);
99  }
100 }
101 void SwitchingForm::OnChangeProperties(wxPropertyGridEvent& event) {}
102 void SwitchingForm::OnSelectItem(wxListEvent& event) {}
103 void SwitchingForm::OnDownButtonClick(wxCommandEvent& event)
104 {
105  std::vector<long> selectedList;
106  std::vector<long> itemList;
107  long item = -1;
108  while(true) {
109  item = m_listCtrlSwitchings->GetNextItem(item, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
110  if(item == -1) break;
111  selectedList.push_back(item);
112  }
113  while(true) {
114  item = m_listCtrlSwitchings->GetNextItem(item);
115  if(item == -1) break;
116  itemList.push_back(item);
117  }
118 
119  for(int i = 1; i < (int)itemList.size(); i++) {
120  for(int j = 0; j < (int)selectedList.size(); j++) {
121  if(itemList[i - 1] == selectedList[j]) {
122  wxString col1Str[2];
123  wxString col2Str[2];
124 
125  col1Str[0] = m_listCtrlSwitchings->GetItemText(itemList[i], 0);
126  col1Str[1] = m_listCtrlSwitchings->GetItemText(selectedList[j], 0);
127  col2Str[0] = m_listCtrlSwitchings->GetItemText(itemList[i], 1);
128  col2Str[1] = m_listCtrlSwitchings->GetItemText(selectedList[j], 1);
129 
130  m_listCtrlSwitchings->SetItem(itemList[i], 0, col1Str[1]);
131  m_listCtrlSwitchings->SetItem(selectedList[j], 0, col1Str[0]);
132  m_listCtrlSwitchings->SetItem(itemList[i], 1, col2Str[1]);
133  m_listCtrlSwitchings->SetItem(selectedList[j], 1, col2Str[0]);
134 
135  m_listCtrlSwitchings->SetItemState(itemList[i], wxLIST_STATE_SELECTED, wxLIST_STATE_SELECTED);
136  m_listCtrlSwitchings->SetItemState(selectedList[j], 0, wxLIST_STATE_SELECTED);
137 
138  i++;
139  break;
140  }
141  }
142  }
143 }
144 void SwitchingForm::OnUpButtonClick(wxCommandEvent& event)
145 {
146  std::vector<long> selectedList;
147  std::vector<long> itemList;
148  long item = -1;
149  while(true) {
150  item = m_listCtrlSwitchings->GetNextItem(item, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
151  if(item == -1) break;
152  selectedList.push_back(item);
153  }
154  while(true) {
155  item = m_listCtrlSwitchings->GetNextItem(item);
156  if(item == -1) break;
157  itemList.push_back(item);
158  }
159 
160  for(int i = 0; i < (int)itemList.size(); i++) {
161  for(int j = 0; j < (int)selectedList.size(); j++) {
162  if(i + 1 < (int)itemList.size()) {
163  if(itemList[i + 1] == selectedList[j]) {
164  wxString col1Str[2];
165  wxString col2Str[2];
166 
167  col1Str[0] = m_listCtrlSwitchings->GetItemText(itemList[i], 0);
168  col1Str[1] = m_listCtrlSwitchings->GetItemText(selectedList[j], 0);
169  col2Str[0] = m_listCtrlSwitchings->GetItemText(itemList[i], 1);
170  col2Str[1] = m_listCtrlSwitchings->GetItemText(selectedList[j], 1);
171 
172  m_listCtrlSwitchings->SetItem(itemList[i], 0, col1Str[1]);
173  m_listCtrlSwitchings->SetItem(selectedList[j], 0, col1Str[0]);
174  m_listCtrlSwitchings->SetItem(itemList[i], 1, col2Str[1]);
175  m_listCtrlSwitchings->SetItem(selectedList[j], 1, col2Str[0]);
176 
177  m_listCtrlSwitchings->SetItemState(itemList[i], wxLIST_STATE_SELECTED, wxLIST_STATE_SELECTED);
178  m_listCtrlSwitchings->SetItemState(selectedList[j], 0, wxLIST_STATE_SELECTED);
179 
180  i++;
181  break;
182  }
183  }
184  }
185  }
186 }
std::vector< double > swTime
Definition: PowerElement.h:95
std::vector< SwitchingType > swType
Definition: PowerElement.h:94
- +
Switching data of power elements.
Definition: PowerElement.h:93
diff --git a/docs/doxygen/html/_switching_form_8h_source.html b/docs/doxygen/html/_switching_form_8h_source.html index 42c55b4..f168f71 100644 --- a/docs/doxygen/html/_switching_form_8h_source.html +++ b/docs/doxygen/html/_switching_form_8h_source.html @@ -89,7 +89,7 @@ $(document).ready(function(){initNavTree('_switching_form_8h_source.html','');})
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2017 Thales Lima Oliveira <thales@ufu.br>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program. If not, see <https://www.gnu.org/licenses/>.
16  */
17 
18 #ifndef SWITCHINGFORM_H
19 #define SWITCHINGFORM_H
20 
21 #include "ElementForm.h"
22 
23 class PowerElement;
24 
33 {
34  public:
35  SwitchingForm(wxWindow* parent);
36  SwitchingForm(wxWindow* parent, PowerElement* element);
37  virtual ~SwitchingForm();
38 
39  protected:
40  virtual void OnDownButtonClick(wxCommandEvent& event);
41  virtual void OnUpButtonClick(wxCommandEvent& event);
42  virtual void OnChangeProperties(wxPropertyGridEvent& event);
43  virtual void OnSelectItem(wxListEvent& event);
44  virtual void OnCancelButtonClick(wxCommandEvent& event);
45  virtual void OnInsertButtonClick(wxCommandEvent& event);
46  virtual void OnOKButtonClick(wxCommandEvent& event);
47  virtual void OnRemoveButtonClick(wxCommandEvent& event);
48 
49  int m_maxID = 0;
50 
51  PowerElement* m_element = NULL;
52 };
53 #endif // SWITCHINGFORM_H
Form to edit the switching data of power elements for electromechanical transient studies...
Definition: SwitchingForm.h:32
- +
Abstract class of power elements.
Definition: PowerElement.h:117
diff --git a/docs/doxygen/html/_sync_generator_8cpp_source.html b/docs/doxygen/html/_sync_generator_8cpp_source.html index 337f0d2..662946a 100644 --- a/docs/doxygen/html/_sync_generator_8cpp_source.html +++ b/docs/doxygen/html/_sync_generator_8cpp_source.html @@ -105,7 +105,7 @@ $(document).ready(function(){initNavTree('_sync_generator_8cpp_source.html','');
virtual wxString GetTipText() const
Get the tip text.
Definition: PowerElement.h:41
virtual bool ShowForm(wxWindow *parent, Element *element)
Show element data form.
-
Class that can contain all control elements. Can identify (using RTTI) the elements from a generic li...
+
Class that can contain all control elements. Can identify (using RTTI) the elements from a generic li...
virtual void SetNominalVoltage(std::vector< double > nominalVoltage, std::vector< ElectricalUnit > nominalVoltageUnit)
Set nominal voltage of the element.
Definition: PowerElement.h:40
diff --git a/docs/doxygen/html/_sync_generator_8h_source.html b/docs/doxygen/html/_sync_generator_8h_source.html index 98223ed..a1126c6 100644 --- a/docs/doxygen/html/_sync_generator_8h_source.html +++ b/docs/doxygen/html/_sync_generator_8h_source.html @@ -101,7 +101,7 @@ $(document).ready(function(){initNavTree('_sync_generator_8h_source.html','');})
Definition: PowerElement.h:39
Definition: PowerElement.h:42
-
Class that can contain all control elements. Can identify (using RTTI) the elements from a generic li...
+
Class that can contain all control elements. Can identify (using RTTI) the elements from a generic li...
Abstract class for rotary machines power elements.
Definition: Machines.h:33
diff --git a/docs/doxygen/html/_sync_motor_8h_source.html b/docs/doxygen/html/_sync_motor_8h_source.html index c14907d..ecccd02 100644 --- a/docs/doxygen/html/_sync_motor_8h_source.html +++ b/docs/doxygen/html/_sync_motor_8h_source.html @@ -98,7 +98,7 @@ $(document).ready(function(){initNavTree('_sync_motor_8h_source.html','');});
Form to edit the synchronous machine power data.
Definition: PowerElement.h:39
Definition: PowerElement.h:42
-
Class that can contain all control elements. Can identify (using RTTI) the elements from a generic li...
+
Class that can contain all control elements. Can identify (using RTTI) the elements from a generic li...
Synchronous motor (synchronous compensator) power element.
Definition: SyncMotor.h:134
Abstract class for rotary machines power elements.
Definition: Machines.h:33
Definition: SyncMotor.h:25
diff --git a/docs/doxygen/html/_text_8cpp_source.html b/docs/doxygen/html/_text_8cpp_source.html index d7d9290..a1482c9 100644 --- a/docs/doxygen/html/_text_8cpp_source.html +++ b/docs/doxygen/html/_text_8cpp_source.html @@ -88,14 +88,14 @@ $(document).ready(function(){initNavTree('_text_8cpp_source.html','');});
Text.cpp
-
1 /*
2  * Copyright (C) 2017 Thales Lima Oliveira <thales@ufu.br>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program. If not, see <https://www.gnu.org/licenses/>.
16  */
17 
18 #include "TextForm.h"
19 #include "Text.h"
20 
21 #ifdef USING_WX_3_0_X
22 #include "DegreesAndRadians.h"
23 #endif
24 #include "ElectricCalculation.h"
25 #include "Bus.h"
26 #include "Line.h"
27 #include "Transformer.h"
28 #include "SyncGenerator.h"
29 #include "IndMotor.h"
30 #include "SyncMotor.h"
31 #include "Load.h"
32 #include "Inductor.h"
33 #include "Capacitor.h"
34 
35 Text::Text() : GraphicalElement() { SetText(m_text); }
36 Text::Text(wxPoint2DDouble position) : GraphicalElement()
37 {
38  m_position = position;
39  SetText(m_text);
40 }
41 
42 Text::~Text()
43 {
44  if(m_glString) delete m_glString;
45  if(m_glStringArray) delete m_glStringArray;
46 }
47 bool Text::Contains(wxPoint2DDouble position) const
48 {
49  wxPoint2DDouble ptR = RotateAtPosition(position, -m_angle);
50  return m_rect.Contains(ptR);
51 }
52 
53 void Text::Draw(wxPoint2DDouble translation, double scale)
54 {
55  wxScreenDC dc;
56 
57  // Draw selection rectangle
58 
59  // Push the current matrix on stack.
60  glPushMatrix();
61  // Rotate the matrix around the object position.
62  glTranslated(m_position.m_x, m_position.m_y, 0.0);
63  glRotated(m_angle, 0.0, 0.0, 1.0);
64  glTranslated(-m_position.m_x, -m_position.m_y, 0.0);
65 
66  if(m_selected) {
67  glColor4d(0.0, 0.5, 1.0, 0.5);
68  DrawRectangle(m_position + wxPoint2DDouble(m_borderSize / 2.0, m_borderSize / 2.0), m_rect.m_width,
69  m_rect.m_height);
70  }
71 
72  // Draw text (layer 2)
73  glEnable(GL_TEXTURE_2D);
74  glColor4d(0.0, 0.0, 0.0, 1.0);
75  if(!m_isMultlineText) { // Only one line
76  m_glString->bind();
77  m_glString->render(m_position.m_x, m_position.m_y);
78  } else { // Multiples lines
79  m_glStringArray->bind();
80  // The text will be printed centralized.
81  double lineHeight = m_height / (double)m_numberOfLines;
82  for(int i = 0; i < m_numberOfLines; i++) {
83  m_glStringArray->get(i)
84  .render(m_position.m_x, m_position.m_y - m_height / 2.0 + lineHeight / 2.0 + lineHeight * double(i));
85  }
86  }
87  glDisable(GL_TEXTURE_2D);
88 
89  glPopMatrix();
90 }
91 
92 bool Text::Intersects(wxRect2DDouble rect) const
93 {
94  if(m_angle == 0.0 || m_angle == 180.0) return m_rect.Intersects(rect);
95  return RotatedRectanglesIntersects(m_rect, rect, m_angle, 0.0);
96 }
97 
98 void Text::SetText(wxString text)
99 {
100  glEnable(GL_TEXTURE_2D);
101  m_text = text;
102  wxFont font(m_fontSize, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL);
103 
104  wxScreenDC dc;
105  GLuint* idString = NULL;
106  GLuint* idStringArray = NULL;
107 
108  if(m_glString) {
109  delete m_glString;
110  m_glString = NULL;
111 
112  idString = new GLuint;
113  glGenTextures(1, idString);
114  }
115  if(m_glStringArray) {
116  delete m_glStringArray;
117  m_glStringArray = NULL;
118 
119  idStringArray = new GLuint;
120  glGenTextures(1, idStringArray);
121  }
122 
123  m_numberOfLines = m_text.Freq('\n') + 1;
124  if(m_numberOfLines == 1) { // Only one line
125  m_isMultlineText = false;
126  m_glString = new wxGLString(m_text);
127  m_glString->setFont(font);
128  m_glString->consolidate(&dc);
129  m_width = m_glString->getWidth();
130  m_height = m_glString->getheight();
131  } else {
132  m_isMultlineText = true;
133  m_glStringArray = new wxGLStringArray();
134  dc.SetFont(font);
135 
136  m_width = 0.0;
137  m_height = 0.0;
138  wxString multText = m_text;
139  for(int i = 0; i < m_numberOfLines; ++i) {
140  wxString nextLine;
141  wxString currentLine = multText.BeforeFirst('\n', &nextLine);
142  multText = nextLine;
143  m_glStringArray->addString(currentLine);
144 
145  wxSize size = dc.GetTextExtent(currentLine);
146  if(size.GetWidth() > m_width) m_width = size.GetWidth();
147  m_height += size.GetHeight();
148  }
149 
150  m_glStringArray->setFont(font);
151  m_glStringArray->consolidate(&dc);
152  }
153 
154  if(idString) glDeleteTextures(1, idString);
155  if(idStringArray) glDeleteTextures(1, idStringArray);
156 
157  // Update text rectangle.
158  SetPosition(m_position);
159  glDisable(GL_TEXTURE_2D);
160 }
161 
162 void Text::Rotate(bool clockwise)
163 {
164  double rotAngle = m_rotationAngle;
165  if(!clockwise) rotAngle = -m_rotationAngle;
166 
167  m_angle += rotAngle;
168  if(m_angle >= 360 || m_angle <= -360) m_angle = 0.0;
169 }
170 
171 bool Text::ShowForm(wxWindow* parent, std::vector<Element*> elementList)
172 {
173  TextForm* textForm = new TextForm(parent, this, elementList);
174  if(textForm->ShowModal() == wxID_OK) {
175  textForm->Destroy();
176  return true;
177  }
178  textForm->Destroy();
179  return false;
180 }
181 
182 void Text::UpdateText(double systemPowerBase)
183 {
184  switch(m_elementType) {
185  case TYPE_NONE:
186  SetText(m_text);
187  break;
188  case TYPE_BUS: {
189  Bus* bus = static_cast<Bus*>(m_element);
190  if(bus) {
191  BusElectricalData data = bus->GetElectricalData();
192  double baseVoltage = data.nominalVoltage;
193  if(data.nominalVoltageUnit == UNIT_kV) baseVoltage *= 1e3;
194  double baseCurrent = systemPowerBase / (std::sqrt(3.0) * baseVoltage);
195 
196  switch(m_dataType) {
197  case DATA_NAME: {
198  SetText(bus->GetElectricalData().name);
199  } break;
200  case DATA_VOLTAGE: {
201  double voltage = std::abs(data.voltage);
202  switch(m_unit) {
203  case UNIT_PU: {
204  SetText(wxString::FromDouble(voltage, m_decimalPlaces) + " p.u.");
205  } break;
206  case UNIT_V: {
207  SetText(wxString::FromDouble(voltage * baseVoltage, m_decimalPlaces) + " V");
208  } break;
209  case UNIT_kV: {
210  SetText(wxString::FromDouble(voltage * baseVoltage / 1e3, m_decimalPlaces) + " kV");
211  } break;
212  default:
213  break;
214  }
215  } break;
216  case DATA_ANGLE: {
217  double angle = std::arg(data.voltage);
218  switch(m_unit) {
219  case UNIT_RADIAN: {
220  SetText(wxString::FromDouble(angle, m_decimalPlaces) + " rad");
221  } break;
222  case UNIT_DEGREE: {
223  SetText(wxString::FromDouble(wxRadToDeg(angle), m_decimalPlaces) + (wxString)L'\u00B0');
224  } break;
225  default:
226  break;
227  }
228  } break;
229  case DATA_SC_CURRENT: {
230  double faultCurrent[3] = {std::abs(data.faultCurrent[0]), std::abs(data.faultCurrent[1]),
231  std::abs(data.faultCurrent[2])};
232  switch(m_unit) {
233  case UNIT_PU: {
234  wxString str =
235  "Ia = " + wxString::FromDouble(faultCurrent[0], m_decimalPlaces) + " p.u.";
236  str += "\nIb = " + wxString::FromDouble(faultCurrent[1], m_decimalPlaces) + " p.u.";
237  str += "\nIc = " + wxString::FromDouble(faultCurrent[2], m_decimalPlaces) + " p.u.";
238  SetText(str);
239  } break;
240  case UNIT_A: {
241  wxString str = "Ia = " +
242  wxString::FromDouble(faultCurrent[0] * baseCurrent, m_decimalPlaces) +
243  " A";
244  str += "\nIb = " +
245  wxString::FromDouble(faultCurrent[1] * baseCurrent, m_decimalPlaces) + " A";
246  str += "\nIc = " +
247  wxString::FromDouble(faultCurrent[2] * baseCurrent, m_decimalPlaces) + " A";
248  SetText(str);
249  } break;
250  case UNIT_kA: {
251  wxString str =
252  "Ia = " +
253  wxString::FromDouble(faultCurrent[0] * baseCurrent / 1e3, m_decimalPlaces) + " kA";
254  str += "\nIb = " +
255  wxString::FromDouble(faultCurrent[1] * baseCurrent / 1e3, m_decimalPlaces) +
256  " kA";
257  str += "\nIc = " +
258  wxString::FromDouble(faultCurrent[2] * baseCurrent / 1e3, m_decimalPlaces) +
259  " kA";
260  SetText(str);
261  } break;
262  default:
263  break;
264  }
265  } break;
266  case DATA_SC_VOLTAGE: {
267  double faultVoltage[3] = {std::abs(data.faultVoltage[0]), std::abs(data.faultVoltage[1]),
268  std::abs(data.faultVoltage[2])};
269  switch(m_unit) {
270  case UNIT_PU: {
271  wxString str =
272  "Va = " + wxString::FromDouble(faultVoltage[0], m_decimalPlaces) + " p.u.";
273  str += "\nVb = " + wxString::FromDouble(faultVoltage[1], m_decimalPlaces) + " p.u.";
274  str += "\nVc = " + wxString::FromDouble(faultVoltage[2], m_decimalPlaces) + " p.u.";
275  SetText(str);
276  } break;
277  case UNIT_V: {
278  wxString str = "Va = " +
279  wxString::FromDouble(faultVoltage[0] * baseVoltage, m_decimalPlaces) +
280  " V";
281  str += "\nVb = " +
282  wxString::FromDouble(faultVoltage[1] * baseVoltage, m_decimalPlaces) + " V";
283  str += "\nVc = " +
284  wxString::FromDouble(faultVoltage[2] * baseVoltage, m_decimalPlaces) + " V";
285  SetText(str);
286  } break;
287  case UNIT_kV: {
288  wxString str =
289  "Va = " +
290  wxString::FromDouble(faultVoltage[0] * baseVoltage / 1e3, m_decimalPlaces) + " kV";
291  str += "\nVb = " +
292  wxString::FromDouble(faultVoltage[1] * baseVoltage / 1e3, m_decimalPlaces) +
293  " kV";
294  str += "\nVc = " +
295  wxString::FromDouble(faultVoltage[2] * baseVoltage / 1e3, m_decimalPlaces) +
296  " kV";
297  SetText(str);
298  } break;
299  default:
300  break;
301  }
302  } break;
303  case DATA_SC_POWER: {
304  switch(m_unit) {
305  case UNIT_PU: {
306  SetText(wxString::FromDouble(data.scPower, m_decimalPlaces) + " p.u.");
307  } break;
308  case UNIT_VA: {
309  SetText(wxString::FromDouble(data.scPower * systemPowerBase, m_decimalPlaces) + " VA");
310  } break;
311  case UNIT_kVA: {
312  SetText(wxString::FromDouble(data.scPower * systemPowerBase / 1e3, m_decimalPlaces) +
313  " kVA");
314  } break;
315  case UNIT_MVA: {
316  SetText(wxString::FromDouble(data.scPower * systemPowerBase / 1e6, m_decimalPlaces) +
317  " MVA");
318  } break;
319  default:
320  break;
321  }
322  } break;
323  default:
324  break;
325  }
326  }
327  } break;
328  case TYPE_SYNC_GENERATOR: {
329  SyncGenerator* syncGenerator = static_cast<SyncGenerator*>(m_element);
330  if(syncGenerator) {
331  SyncGeneratorElectricalData data = syncGenerator->GetPUElectricalData(systemPowerBase);
332  double baseVoltage = syncGenerator->GetValueFromUnit(data.nominalVoltage, data.nominalVoltageUnit);
333  double baseCurrent = systemPowerBase / (std::sqrt(3.0) * baseVoltage);
334  switch(m_dataType) {
335  case DATA_NAME: {
336  SetText(data.name);
337  } break;
338  case DATA_ACTIVE_POWER: {
339  double activePower = data.activePower;
340  if(!syncGenerator->IsOnline()) activePower = 0.0;
341  switch(m_unit) {
342  case UNIT_PU: {
343  SetText(wxString::FromDouble(activePower, m_decimalPlaces) + " p.u.");
344  } break;
345  case UNIT_W: {
346  SetText(wxString::FromDouble(activePower * systemPowerBase, m_decimalPlaces) + " W");
347  } break;
348  case UNIT_kW: {
349  SetText(wxString::FromDouble(activePower * systemPowerBase / 1e3, m_decimalPlaces) +
350  " kW");
351  } break;
352  case UNIT_MW: {
353  SetText(wxString::FromDouble(activePower * systemPowerBase / 1e6, m_decimalPlaces) +
354  " MW");
355  } break;
356  default:
357  break;
358  }
359  } break;
360  case DATA_REACTIVE_POWER: {
361  double reactivePower = data.reactivePower;
362  if(!syncGenerator->IsOnline()) reactivePower = 0.0;
363  switch(m_unit) {
364  case UNIT_PU: {
365  SetText(wxString::FromDouble(reactivePower, m_decimalPlaces) + " p.u.");
366  } break;
367  case UNIT_VAr: {
368  SetText(wxString::FromDouble(reactivePower * systemPowerBase, m_decimalPlaces) +
369  " VAr");
370  } break;
371  case UNIT_kVAr: {
372  SetText(wxString::FromDouble(reactivePower * systemPowerBase / 1e3, m_decimalPlaces) +
373  " kVAr");
374  } break;
375  case UNIT_MVAr: {
376  SetText(wxString::FromDouble(reactivePower * systemPowerBase / 1e6, m_decimalPlaces) +
377  " MVAr");
378  } break;
379  default:
380  break;
381  }
382  } break;
383  case DATA_SC_CURRENT: {
384  double faultCurrent[3] = {std::abs(data.faultCurrent[0]), std::abs(data.faultCurrent[1]),
385  std::abs(data.faultCurrent[2])};
386  switch(m_unit) {
387  case UNIT_PU: {
388  wxString str =
389  "Ia = " + wxString::FromDouble(faultCurrent[0], m_decimalPlaces) + " p.u.";
390  str += "\nIb = " + wxString::FromDouble(faultCurrent[1], m_decimalPlaces) + " p.u.";
391  str += "\nIc = " + wxString::FromDouble(faultCurrent[2], m_decimalPlaces) + " p.u.";
392  SetText(str);
393  } break;
394  case UNIT_A: {
395  wxString str = "Ia = " +
396  wxString::FromDouble(faultCurrent[0] * baseCurrent, m_decimalPlaces) +
397  " A";
398  str += "\nIb = " +
399  wxString::FromDouble(faultCurrent[1] * baseCurrent, m_decimalPlaces) + " A";
400  str += "\nIc = " +
401  wxString::FromDouble(faultCurrent[2] * baseCurrent, m_decimalPlaces) + " A";
402  SetText(str);
403  } break;
404  case UNIT_kA: {
405  wxString str =
406  "Ia = " +
407  wxString::FromDouble(faultCurrent[0] * baseCurrent / 1e3, m_decimalPlaces) + " kA";
408  str += "\nIb = " +
409  wxString::FromDouble(faultCurrent[1] * baseCurrent / 1e3, m_decimalPlaces) +
410  " kA";
411  str += "\nIc = " +
412  wxString::FromDouble(faultCurrent[2] * baseCurrent / 1e3, m_decimalPlaces) +
413  " kA";
414  SetText(str);
415  } break;
416  default:
417  break;
418  }
419  } break;
420  default:
421  break;
422  }
423  }
424  } break;
425  case TYPE_LINE: {
426  Line* line = static_cast<Line*>(m_element);
427  if(line) {
428  LineElectricalData data = line->GetElectricalData();
429  double baseVoltage = data.nominalVoltage;
430  if(data.nominalVoltageUnit == UNIT_kV) baseVoltage *= 1e3;
431  double baseCurrent = systemPowerBase / (std::sqrt(3.0) * baseVoltage);
432  switch(m_dataType) {
433  case DATA_NAME: {
434  SetText(data.name);
435  } break;
436  case DATA_PF_ACTIVE: {
437  double activePF = std::real(data.powerFlow[m_direction]);
438  if(!line->IsOnline()) activePF = 0.0;
439  switch(m_unit) {
440  case UNIT_PU: {
441  SetText(wxString::FromDouble(activePF, m_decimalPlaces) + " p.u.");
442  } break;
443  case UNIT_W: {
444  SetText(wxString::FromDouble(activePF * systemPowerBase, m_decimalPlaces) + " W");
445  } break;
446  case UNIT_kW: {
447  SetText(wxString::FromDouble(activePF * systemPowerBase / 1e3, m_decimalPlaces) +
448  " kW");
449  } break;
450  case UNIT_MW: {
451  SetText(wxString::FromDouble(activePF * systemPowerBase / 1e6, m_decimalPlaces) +
452  " MW");
453  } break;
454  default:
455  break;
456  }
457  } break;
458  case DATA_PF_REACTIVE: {
459  double reactivePF = std::imag(data.powerFlow[m_direction]);
460  if(!line->IsOnline()) reactivePF = 0.0;
461  switch(m_unit) {
462  case UNIT_PU: {
463  SetText(wxString::FromDouble(reactivePF, m_decimalPlaces) + " p.u.");
464  } break;
465  case UNIT_VAr: {
466  SetText(wxString::FromDouble(reactivePF * systemPowerBase, m_decimalPlaces) + " VAr");
467  } break;
468  case UNIT_kVAr: {
469  SetText(wxString::FromDouble(reactivePF * systemPowerBase / 1e3, m_decimalPlaces) +
470  " kVAr");
471  } break;
472  case UNIT_MVAr: {
473  SetText(wxString::FromDouble(reactivePF * systemPowerBase / 1e6, m_decimalPlaces) +
474  " MVAr");
475  } break;
476  default:
477  break;
478  }
479  } break;
480  case DATA_PF_LOSSES: {
481  double losses = std::abs(std::real(data.powerFlow[0]) + std::real(data.powerFlow[1]));
482  if(!line->IsOnline()) losses = 0.0;
483  switch(m_unit) {
484  case UNIT_PU: {
485  SetText(wxString::FromDouble(losses, m_decimalPlaces) + " p.u.");
486  } break;
487  case UNIT_W: {
488  SetText(wxString::FromDouble(losses * systemPowerBase, m_decimalPlaces) + " W");
489  } break;
490  case UNIT_kW: {
491  SetText(wxString::FromDouble(losses * systemPowerBase / 1e3, m_decimalPlaces) + " kW");
492  } break;
493  case UNIT_MW: {
494  SetText(wxString::FromDouble(losses * systemPowerBase / 1e6, m_decimalPlaces) + " MW");
495  } break;
496  default:
497  break;
498  }
499  } break;
500  case DATA_PF_CURRENT: {
501  double current = std::abs(data.current[m_direction]);
502  if(!line->IsOnline()) current = 0.0;
503  switch(m_unit) {
504  case UNIT_PU: {
505  SetText(wxString::FromDouble(current, m_decimalPlaces) + " p.u.");
506  } break;
507  case UNIT_A: {
508  SetText(wxString::FromDouble(current * baseCurrent, m_decimalPlaces) + " A");
509  } break;
510  case UNIT_kA: {
511  SetText(wxString::FromDouble(current * baseCurrent / 1e3, m_decimalPlaces) + " kA");
512  } break;
513  default:
514  break;
515  }
516  } break;
517  case DATA_SC_CURRENT: {
518  double faultCurrent[3] = {std::abs(data.faultCurrent[m_direction][0]),
519  std::abs(data.faultCurrent[m_direction][1]),
520  std::abs(data.faultCurrent[m_direction][2])};
521  if(!line->IsOnline()) faultCurrent[0] = faultCurrent[1] = faultCurrent[2] = 0.0;
522  switch(m_unit) {
523  case UNIT_PU: {
524  wxString str =
525  "Ia = " + wxString::FromDouble(faultCurrent[0], m_decimalPlaces) + " p.u.";
526  str += "\nIb = " + wxString::FromDouble(faultCurrent[1], m_decimalPlaces) + " p.u.";
527  str += "\nIc = " + wxString::FromDouble(faultCurrent[2], m_decimalPlaces) + " p.u.";
528  SetText(str);
529  } break;
530  case UNIT_A: {
531  wxString str = "Ia = " +
532  wxString::FromDouble(faultCurrent[0] * baseCurrent, m_decimalPlaces) +
533  " A";
534  str += "\nIb = " +
535  wxString::FromDouble(faultCurrent[1] * baseCurrent, m_decimalPlaces) + " A";
536  str += "\nIc = " +
537  wxString::FromDouble(faultCurrent[2] * baseCurrent, m_decimalPlaces) + " A";
538  SetText(str);
539  } break;
540  case UNIT_kA: {
541  wxString str =
542  "Ia = " +
543  wxString::FromDouble(faultCurrent[0] * baseCurrent / 1e3, m_decimalPlaces) + " kA";
544  str += "\nIb = " +
545  wxString::FromDouble(faultCurrent[1] * baseCurrent / 1e3, m_decimalPlaces) +
546  " kA";
547  str += "\nIc = " +
548  wxString::FromDouble(faultCurrent[2] * baseCurrent / 1e3, m_decimalPlaces) +
549  " kA";
550  SetText(str);
551  } break;
552  default:
553  break;
554  }
555  } break;
556  default:
557  break;
558  }
559  }
560  } break;
561  case TYPE_TRANSFORMER: {
562  Transformer* transformer = static_cast<Transformer*>(m_element);
563  if(transformer) {
564  TransformerElectricalData data = transformer->GetElectricalData();
565  double baseVoltage[2] = {data.primaryNominalVoltage, data.secondaryNominalVoltage};
566 
567  if(data.primaryNominalVoltageUnit == UNIT_kV) baseVoltage[0] *= 1e3;
568  if(data.secondaryNominalVoltageUnit == UNIT_kV) baseVoltage[1] *= 1e3;
569 
570  double baseCurrent[2] = {systemPowerBase / (std::sqrt(3.0) * baseVoltage[0]),
571  systemPowerBase / (std::sqrt(3.0) * baseVoltage[1])};
572  switch(m_dataType) {
573  case DATA_NAME: {
574  SetText(data.name);
575  } break;
576  case DATA_PF_ACTIVE: {
577  double activePF = std::real(data.powerFlow[m_direction]);
578  if(!transformer->IsOnline()) activePF = 0.0;
579  switch(m_unit) {
580  case UNIT_PU: {
581  SetText(wxString::FromDouble(activePF, m_decimalPlaces) + " p.u.");
582  } break;
583  case UNIT_W: {
584  SetText(wxString::FromDouble(activePF * systemPowerBase, m_decimalPlaces) + " W");
585  } break;
586  case UNIT_kW: {
587  SetText(wxString::FromDouble(activePF * systemPowerBase / 1e3, m_decimalPlaces) +
588  " kW");
589  } break;
590  case UNIT_MW: {
591  SetText(wxString::FromDouble(activePF * systemPowerBase / 1e6, m_decimalPlaces) +
592  " MW");
593  } break;
594  default:
595  break;
596  }
597  } break;
598  case DATA_PF_REACTIVE: {
599  double reactivePF = std::imag(data.powerFlow[m_direction]);
600  if(!transformer->IsOnline()) reactivePF = 0.0;
601  switch(m_unit) {
602  case UNIT_PU: {
603  SetText(wxString::FromDouble(reactivePF, m_decimalPlaces) + " p.u.");
604  } break;
605  case UNIT_VAr: {
606  SetText(wxString::FromDouble(reactivePF * systemPowerBase, m_decimalPlaces) + " VAr");
607  } break;
608  case UNIT_kVAr: {
609  SetText(wxString::FromDouble(reactivePF * systemPowerBase / 1e3, m_decimalPlaces) +
610  " kVAr");
611  } break;
612  case UNIT_MVAr: {
613  SetText(wxString::FromDouble(reactivePF * systemPowerBase / 1e6, m_decimalPlaces) +
614  " MVAr");
615  } break;
616  default:
617  break;
618  }
619  } break;
620  case DATA_PF_LOSSES: {
621  double losses = std::abs(std::real(data.powerFlow[0]) + std::real(data.powerFlow[1]));
622  if(!transformer->IsOnline()) losses = 0.0;
623  switch(m_unit) {
624  case UNIT_PU: {
625  SetText(wxString::FromDouble(losses, m_decimalPlaces) + " p.u.");
626  } break;
627  case UNIT_W: {
628  SetText(wxString::FromDouble(losses * systemPowerBase, m_decimalPlaces) + " W");
629  } break;
630  case UNIT_kW: {
631  SetText(wxString::FromDouble(losses * systemPowerBase / 1e3, m_decimalPlaces) + " kW");
632  } break;
633  case UNIT_MW: {
634  SetText(wxString::FromDouble(losses * systemPowerBase / 1e6, m_decimalPlaces) + " MW");
635  } break;
636  default:
637  break;
638  }
639  } break;
640  case DATA_PF_CURRENT: {
641  double current = std::abs(data.current[m_direction]);
642  if(!transformer->IsOnline()) current = 0.0;
643  switch(m_unit) {
644  case UNIT_PU: {
645  SetText(wxString::FromDouble(current, m_decimalPlaces) + " p.u.");
646  } break;
647  case UNIT_A: {
648  SetText(wxString::FromDouble(current * baseCurrent[m_direction], m_decimalPlaces) +
649  " A");
650  } break;
651  case UNIT_kA: {
652  SetText(
653  wxString::FromDouble(current * baseCurrent[m_direction] / 1e3, m_decimalPlaces) +
654  " kA");
655  } break;
656  default:
657  break;
658  }
659  } break;
660  case DATA_SC_CURRENT: {
661  double faultCurrent[3] = {std::abs(data.faultCurrent[m_direction][0]),
662  std::abs(data.faultCurrent[m_direction][1]),
663  std::abs(data.faultCurrent[m_direction][2])};
664  if(!transformer->IsOnline()) faultCurrent[0] = faultCurrent[1] = faultCurrent[2] = 0.0;
665  switch(m_unit) {
666  case UNIT_PU: {
667  wxString str =
668  "Ia = " + wxString::FromDouble(faultCurrent[0], m_decimalPlaces) + " p.u.";
669  str += "\nIb = " + wxString::FromDouble(faultCurrent[1], m_decimalPlaces) + " p.u.";
670  str += "\nIc = " + wxString::FromDouble(faultCurrent[2], m_decimalPlaces) + " p.u.";
671  SetText(str);
672  } break;
673  case UNIT_A: {
674  wxString str =
675  "Ia = " +
676  wxString::FromDouble(faultCurrent[0] * baseCurrent[m_direction], m_decimalPlaces) +
677  " A";
678  str += "\nIb = " + wxString::FromDouble(faultCurrent[1] * baseCurrent[m_direction],
679  m_decimalPlaces) +
680  " A";
681  str += "\nIc = " + wxString::FromDouble(faultCurrent[2] * baseCurrent[m_direction],
682  m_decimalPlaces) +
683  " A";
684  SetText(str);
685  } break;
686  case UNIT_kA: {
687  wxString str = "Ia = " +
688  wxString::FromDouble(faultCurrent[0] * baseCurrent[m_direction] / 1e3,
689  m_decimalPlaces) +
690  " kA";
691  str += "\nIb = " +
692  wxString::FromDouble(faultCurrent[1] * baseCurrent[m_direction] / 1e3,
693  m_decimalPlaces) +
694  " kA";
695  str += "\nIc = " +
696  wxString::FromDouble(faultCurrent[2] * baseCurrent[m_direction] / 1e3,
697  m_decimalPlaces) +
698  " kA";
699  SetText(str);
700  } break;
701  default:
702  break;
703  }
704  } break;
705  default:
706  break;
707  }
708  }
709  } break;
710  case TYPE_LOAD: {
711  Load* load = static_cast<Load*>(m_element);
712  if(load) {
713  LoadElectricalData data = load->GetPUElectricalData(systemPowerBase);
714  std::complex<double> sPower(data.activePower, data.reactivePower);
715  if(data.loadType == CONST_IMPEDANCE && load->IsOnline()) {
716  std::complex<double> v = static_cast<Bus*>(load->GetParentList()[0])->GetElectricalData().voltage;
717  sPower = std::pow(std::abs(v), 2) * sPower;
718  }
719  if(!load->IsOnline()) sPower = std::complex<double>(0.0, 0.0);
720  switch(m_dataType) {
721  case DATA_NAME: {
722  SetText(data.name);
723  } break;
724  case DATA_ACTIVE_POWER: {
725  switch(m_unit) {
726  case UNIT_PU: {
727  SetText(wxString::FromDouble(sPower.real(), m_decimalPlaces) + " p.u.");
728  }
729  case UNIT_W: {
730  SetText(wxString::FromDouble(sPower.real() * systemPowerBase, m_decimalPlaces) + " W");
731  }
732  case UNIT_kW: {
733  SetText(wxString::FromDouble(sPower.real() * systemPowerBase / 1e3, m_decimalPlaces) +
734  " kW");
735  }
736  case UNIT_MW: {
737  SetText(wxString::FromDouble(sPower.real() * systemPowerBase / 1e6, m_decimalPlaces) +
738  " MW");
739  }
740  default:
741  break;
742  }
743  } break;
744  case DATA_REACTIVE_POWER: {
745  switch(m_unit) {
746  case UNIT_PU: {
747  SetText(wxString::FromDouble(sPower.imag(), m_decimalPlaces) + " p.u.");
748  }
749  case UNIT_VAr: {
750  SetText(wxString::FromDouble(sPower.imag() * systemPowerBase, m_decimalPlaces) +
751  " VAr");
752  }
753  case UNIT_kVAr: {
754  SetText(wxString::FromDouble(sPower.imag() * systemPowerBase / 1e3, m_decimalPlaces) +
755  " kVAr");
756  }
757  case UNIT_MVAr: {
758  SetText(wxString::FromDouble(sPower.imag() * systemPowerBase / 1e6, m_decimalPlaces) +
759  " MVAr");
760  }
761  default:
762  break;
763  }
764  } break;
765  default:
766  break;
767  }
768  }
769  } break;
770  case TYPE_SYNC_MOTOR: {
771  SyncMotor* syncMotor = static_cast<SyncMotor*>(m_element);
772  if(syncMotor) {
773  SyncMotorElectricalData data = syncMotor->GetPUElectricalData(systemPowerBase);
774  std::complex<double> sPower(data.activePower, data.reactivePower);
775  if(!syncMotor->IsOnline()) sPower = std::complex<double>(0.0, 0.0);
776  switch(m_dataType) {
777  case DATA_NAME: {
778  SetText(data.name);
779  } break;
780  case DATA_ACTIVE_POWER: {
781  switch(m_unit) {
782  case UNIT_PU: {
783  SetText(wxString::FromDouble(sPower.real(), m_decimalPlaces) + " p.u.");
784  }
785  case UNIT_W: {
786  SetText(wxString::FromDouble(sPower.real() * systemPowerBase, m_decimalPlaces) + " W");
787  }
788  case UNIT_kW: {
789  SetText(wxString::FromDouble(sPower.real() * systemPowerBase / 1e3, m_decimalPlaces) +
790  " kW");
791  }
792  case UNIT_MW: {
793  SetText(wxString::FromDouble(sPower.real() * systemPowerBase / 1e6, m_decimalPlaces) +
794  " MW");
795  }
796  default:
797  break;
798  }
799  } break;
800  case DATA_REACTIVE_POWER: {
801  switch(m_unit) {
802  case UNIT_PU: {
803  SetText(wxString::FromDouble(sPower.imag(), m_decimalPlaces) + " p.u.");
804  }
805  case UNIT_VAr: {
806  SetText(wxString::FromDouble(sPower.imag() * systemPowerBase, m_decimalPlaces) +
807  " VAr");
808  }
809  case UNIT_kVAr: {
810  SetText(wxString::FromDouble(sPower.imag() * systemPowerBase / 1e3, m_decimalPlaces) +
811  " kVAr");
812  }
813  case UNIT_MVAr: {
814  SetText(wxString::FromDouble(sPower.imag() * systemPowerBase / 1e6, m_decimalPlaces) +
815  " MVAr");
816  }
817  default:
818  break;
819  }
820  } break;
821  default:
822  break;
823  }
824  }
825  } break;
826  case TYPE_IND_MOTOR: {
827  IndMotor* indMotor = static_cast<IndMotor*>(m_element);
828  if(indMotor) {
829  IndMotorElectricalData data = indMotor->GetPUElectricalData(systemPowerBase);
830  std::complex<double> sPower(data.activePower, data.reactivePower);
831  if(!indMotor->IsOnline()) sPower = std::complex<double>(0.0, 0.0);
832  switch(m_dataType) {
833  case DATA_NAME: {
834  SetText(data.name);
835  } break;
836  case DATA_ACTIVE_POWER: {
837  switch(m_unit) {
838  case UNIT_PU: {
839  SetText(wxString::FromDouble(sPower.real(), m_decimalPlaces) + " p.u.");
840  }
841  case UNIT_W: {
842  SetText(wxString::FromDouble(sPower.real() * systemPowerBase, m_decimalPlaces) + " W");
843  }
844  case UNIT_kW: {
845  SetText(wxString::FromDouble(sPower.real() * systemPowerBase / 1e3, m_decimalPlaces) +
846  " kW");
847  }
848  case UNIT_MW: {
849  SetText(wxString::FromDouble(sPower.real() * systemPowerBase / 1e6, m_decimalPlaces) +
850  " MW");
851  }
852  default:
853  break;
854  }
855  } break;
856  case DATA_REACTIVE_POWER: {
857  switch(m_unit) {
858  case UNIT_PU: {
859  SetText(wxString::FromDouble(sPower.imag(), m_decimalPlaces) + " p.u.");
860  }
861  case UNIT_VAr: {
862  SetText(wxString::FromDouble(sPower.imag() * systemPowerBase, m_decimalPlaces) +
863  " VAr");
864  }
865  case UNIT_kVAr: {
866  SetText(wxString::FromDouble(sPower.imag() * systemPowerBase / 1e3, m_decimalPlaces) +
867  " kVAr");
868  }
869  case UNIT_MVAr: {
870  SetText(wxString::FromDouble(sPower.imag() * systemPowerBase / 1e6, m_decimalPlaces) +
871  " MVAr");
872  }
873  default:
874  break;
875  }
876  } break;
877  default:
878  break;
879  }
880  }
881  } break;
882  case TYPE_CAPACITOR: {
883  Capacitor* capacitor = static_cast<Capacitor*>(m_element);
884  if(capacitor) {
885  CapacitorElectricalData data = capacitor->GetPUElectricalData(systemPowerBase);
886  double reativePower = data.reactivePower;
887  if(!capacitor->IsOnline())
888  reativePower = 0.0;
889  else {
890  std::complex<double> v =
891  static_cast<Bus*>(capacitor->GetParentList()[0])->GetElectricalData().voltage;
892  reativePower *= std::pow(std::abs(v), 2);
893  }
894  switch(m_dataType) {
895  case DATA_NAME: {
896  SetText(data.name);
897  } break;
898  case DATA_REACTIVE_POWER: {
899  switch(m_unit) {
900  case UNIT_PU: {
901  SetText(wxString::FromDouble(reativePower, m_decimalPlaces) + " p.u.");
902  }
903  case UNIT_VAr: {
904  SetText(wxString::FromDouble(reativePower * systemPowerBase, m_decimalPlaces) + " VAr");
905  }
906  case UNIT_kVAr: {
907  SetText(wxString::FromDouble(reativePower * systemPowerBase / 1e3, m_decimalPlaces) +
908  " kVAr");
909  }
910  case UNIT_MVAr: {
911  SetText(wxString::FromDouble(reativePower * systemPowerBase / 1e6, m_decimalPlaces) +
912  " MVAr");
913  }
914  default:
915  break;
916  }
917  } break;
918  default:
919  break;
920  }
921  }
922  } break;
923  case TYPE_INDUCTOR: {
924  Inductor* inductor = static_cast<Inductor*>(m_element);
925  if(inductor) {
926  InductorElectricalData data = inductor->GetPUElectricalData(systemPowerBase);
927  double reativePower = data.reactivePower;
928  if(!inductor->IsOnline())
929  reativePower = 0.0;
930  else {
931  std::complex<double> v =
932  static_cast<Bus*>(inductor->GetParentList()[0])->GetElectricalData().voltage;
933  reativePower *= std::pow(std::abs(v), 2);
934  }
935  switch(m_dataType) {
936  case DATA_NAME: {
937  SetText(data.name);
938  } break;
939  case DATA_REACTIVE_POWER: {
940  switch(m_unit) {
941  case UNIT_PU: {
942  SetText(wxString::FromDouble(reativePower, m_decimalPlaces) + " p.u.");
943  }
944  case UNIT_VAr: {
945  SetText(wxString::FromDouble(reativePower * systemPowerBase, m_decimalPlaces) + " VAr");
946  }
947  case UNIT_kVAr: {
948  SetText(wxString::FromDouble(reativePower * systemPowerBase / 1e3, m_decimalPlaces) +
949  " kVAr");
950  }
951  case UNIT_MVAr: {
952  SetText(wxString::FromDouble(reativePower * systemPowerBase / 1e6, m_decimalPlaces) +
953  " MVAr");
954  }
955  default:
956  break;
957  }
958  } break;
959  default:
960  break;
961  }
962  }
963  } break;
964  }
965 }
966 
968 {
969  Text* copy = new Text();
970  *copy = *this;
971  // The pointers to wxGLString must be different or can cause crashes.
972  copy->m_glString = NULL;
973  copy->m_glStringArray = NULL;
974  copy->SetText(copy->m_text);
975  return copy;
976 }
virtual bool Contains(wxPoint2DDouble position) const
Checks if the element contains a position.
Definition: Text.cpp:47
-
Element that shows power element informations in workspace.
Definition: Text.h:72
+
1 /*
2  * Copyright (C) 2017 Thales Lima Oliveira <thales@ufu.br>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program. If not, see <https://www.gnu.org/licenses/>.
16  */
17 
18 #include "TextForm.h"
19 #include "Text.h"
20 
21 #ifdef USING_WX_3_0_X
22 #include "DegreesAndRadians.h"
23 #endif
24 #include "ElectricCalculation.h"
25 #include "Bus.h"
26 #include "Line.h"
27 #include "Transformer.h"
28 #include "SyncGenerator.h"
29 #include "IndMotor.h"
30 #include "SyncMotor.h"
31 #include "Load.h"
32 #include "Inductor.h"
33 #include "Capacitor.h"
34 
35 Text::Text() : GraphicalElement() { SetText(m_text); }
36 Text::Text(wxPoint2DDouble position) : GraphicalElement()
37 {
38  m_position = position;
39  SetText(m_text);
40 }
41 
42 Text::~Text() {}
43 bool Text::Contains(wxPoint2DDouble position) const
44 {
45  wxPoint2DDouble ptR = RotateAtPosition(position, -m_angle);
46  return m_rect.Contains(ptR);
47 }
48 
49 void Text::Draw(wxPoint2DDouble translation, double scale)
50 {
51  // Draw selection rectangle
52 
53  // Push the current matrix on stack.
54  glPushMatrix();
55  // Rotate the matrix around the object position.
56  glTranslated(m_position.m_x, m_position.m_y, 0.0);
57  glRotated(m_angle, 0.0, 0.0, 1.0);
58  glTranslated(-m_position.m_x, -m_position.m_y, 0.0);
59 
60  if(m_selected) {
61  glColor4d(0.0, 0.5, 1.0, 0.5);
62  DrawRectangle(m_position + wxPoint2DDouble(m_borderSize / 2.0, m_borderSize / 2.0), m_rect.m_width,
63  m_rect.m_height);
64  }
65 
66  // Draw text (layer 2)
67  glColor4d(0.0, 0.0, 0.0, 1.0);
68  if(m_isMultlineText) {
69  for(unsigned int i = 0; i < m_openGLTextList.size(); ++i) {
70  m_openGLTextList[i]->Draw(
71  m_position +
72  wxPoint2DDouble(0.0, (m_height * static_cast<double>(i) / static_cast<double>(m_numberOfLines)) -
73  (m_height * static_cast<double>(m_numberOfLines - 1) /
74  static_cast<double>(2 * m_numberOfLines))));
75  }
76  } else if(m_openGLTextList.size() > 0) {
77  m_openGLTextList[0]->Draw(m_position);
78  }
79  glPopMatrix();
80 }
81 
82 bool Text::Intersects(wxRect2DDouble rect) const
83 {
84  if(m_angle == 0.0 || m_angle == 180.0) return m_rect.Intersects(rect);
85  return RotatedRectanglesIntersects(m_rect, rect, m_angle, 0.0);
86 }
87 
88 void Text::SetText(wxString text)
89 {
90  m_text = text;
91 
92  // Clear OpenGL text list
93  for(auto it = m_openGLTextList.begin(), itEnd = m_openGLTextList.end(); it != itEnd; ++it) {
94  delete *it;
95  }
96  m_openGLTextList.clear();
97 
98  m_numberOfLines = m_text.Freq('\n') + 1;
99  if(m_numberOfLines > 1) m_isMultlineText = true;
100  m_width = 0.0;
101  m_height = 0.0;
102  wxString multText = m_text;
103  for(int i = 0; i < m_numberOfLines; ++i) {
104  wxString nextLine;
105  wxString currentLine = multText.BeforeFirst('\n', &nextLine);
106  multText = nextLine;
107  m_openGLTextList.push_back(new OpenGLText(currentLine));
108  if(m_openGLTextList[i]->GetWidth() > m_width) m_width = m_openGLTextList[i]->GetWidth();
109  m_height += m_openGLTextList[i]->GetHeight();
110  }
111  SetPosition(m_position); // Update element rectangle.
112 }
113 
114 void Text::Rotate(bool clockwise)
115 {
116  double rotAngle = m_rotationAngle;
117  if(!clockwise) rotAngle = -m_rotationAngle;
118 
119  m_angle += rotAngle;
120  if(m_angle >= 360 || m_angle <= -360) m_angle = 0.0;
121 }
122 
123 bool Text::ShowForm(wxWindow* parent, std::vector<Element*> elementList)
124 {
125  TextForm* textForm = new TextForm(parent, this, elementList);
126  if(textForm->ShowModal() == wxID_OK) {
127  textForm->Destroy();
128  return true;
129  }
130  textForm->Destroy();
131  return false;
132 }
133 
134 void Text::UpdateText(double systemPowerBase)
135 {
136  switch(m_elementType) {
137  case TYPE_NONE:
138  SetText(m_text);
139  break;
140  case TYPE_BUS: {
141  Bus* bus = static_cast<Bus*>(m_element);
142  if(bus) {
143  BusElectricalData data = bus->GetElectricalData();
144  double baseVoltage = data.nominalVoltage;
145  if(data.nominalVoltageUnit == UNIT_kV) baseVoltage *= 1e3;
146  double baseCurrent = systemPowerBase / (std::sqrt(3.0) * baseVoltage);
147 
148  switch(m_dataType) {
149  case DATA_NAME: {
150  SetText(bus->GetElectricalData().name);
151  } break;
152  case DATA_VOLTAGE: {
153  double voltage = std::abs(data.voltage);
154  switch(m_unit) {
155  case UNIT_PU: {
156  SetText(wxString::FromDouble(voltage, m_decimalPlaces) + " p.u.");
157  } break;
158  case UNIT_V: {
159  SetText(wxString::FromDouble(voltage * baseVoltage, m_decimalPlaces) + " V");
160  } break;
161  case UNIT_kV: {
162  SetText(wxString::FromDouble(voltage * baseVoltage / 1e3, m_decimalPlaces) + " kV");
163  } break;
164  default:
165  break;
166  }
167  } break;
168  case DATA_ANGLE: {
169  double angle = std::arg(data.voltage);
170  switch(m_unit) {
171  case UNIT_RADIAN: {
172  SetText(wxString::FromDouble(angle, m_decimalPlaces) + " rad");
173  } break;
174  case UNIT_DEGREE: {
175  SetText(wxString::FromDouble(wxRadToDeg(angle), m_decimalPlaces) + (wxString)L'\u00B0');
176  } break;
177  default:
178  break;
179  }
180  } break;
181  case DATA_SC_CURRENT: {
182  double faultCurrent[3] = {std::abs(data.faultCurrent[0]), std::abs(data.faultCurrent[1]),
183  std::abs(data.faultCurrent[2])};
184  switch(m_unit) {
185  case UNIT_PU: {
186  wxString str =
187  "Ia = " + wxString::FromDouble(faultCurrent[0], m_decimalPlaces) + " p.u.";
188  str += "\nIb = " + wxString::FromDouble(faultCurrent[1], m_decimalPlaces) + " p.u.";
189  str += "\nIc = " + wxString::FromDouble(faultCurrent[2], m_decimalPlaces) + " p.u.";
190  SetText(str);
191  } break;
192  case UNIT_A: {
193  wxString str = "Ia = " +
194  wxString::FromDouble(faultCurrent[0] * baseCurrent, m_decimalPlaces) +
195  " A";
196  str += "\nIb = " +
197  wxString::FromDouble(faultCurrent[1] * baseCurrent, m_decimalPlaces) + " A";
198  str += "\nIc = " +
199  wxString::FromDouble(faultCurrent[2] * baseCurrent, m_decimalPlaces) + " A";
200  SetText(str);
201  } break;
202  case UNIT_kA: {
203  wxString str =
204  "Ia = " +
205  wxString::FromDouble(faultCurrent[0] * baseCurrent / 1e3, m_decimalPlaces) + " kA";
206  str += "\nIb = " +
207  wxString::FromDouble(faultCurrent[1] * baseCurrent / 1e3, m_decimalPlaces) +
208  " kA";
209  str += "\nIc = " +
210  wxString::FromDouble(faultCurrent[2] * baseCurrent / 1e3, m_decimalPlaces) +
211  " kA";
212  SetText(str);
213  } break;
214  default:
215  break;
216  }
217  } break;
218  case DATA_SC_VOLTAGE: {
219  double faultVoltage[3] = {std::abs(data.faultVoltage[0]), std::abs(data.faultVoltage[1]),
220  std::abs(data.faultVoltage[2])};
221  switch(m_unit) {
222  case UNIT_PU: {
223  wxString str =
224  "Va = " + wxString::FromDouble(faultVoltage[0], m_decimalPlaces) + " p.u.";
225  str += "\nVb = " + wxString::FromDouble(faultVoltage[1], m_decimalPlaces) + " p.u.";
226  str += "\nVc = " + wxString::FromDouble(faultVoltage[2], m_decimalPlaces) + " p.u.";
227  SetText(str);
228  } break;
229  case UNIT_V: {
230  wxString str = "Va = " +
231  wxString::FromDouble(faultVoltage[0] * baseVoltage, m_decimalPlaces) +
232  " V";
233  str += "\nVb = " +
234  wxString::FromDouble(faultVoltage[1] * baseVoltage, m_decimalPlaces) + " V";
235  str += "\nVc = " +
236  wxString::FromDouble(faultVoltage[2] * baseVoltage, m_decimalPlaces) + " V";
237  SetText(str);
238  } break;
239  case UNIT_kV: {
240  wxString str =
241  "Va = " +
242  wxString::FromDouble(faultVoltage[0] * baseVoltage / 1e3, m_decimalPlaces) + " kV";
243  str += "\nVb = " +
244  wxString::FromDouble(faultVoltage[1] * baseVoltage / 1e3, m_decimalPlaces) +
245  " kV";
246  str += "\nVc = " +
247  wxString::FromDouble(faultVoltage[2] * baseVoltage / 1e3, m_decimalPlaces) +
248  " kV";
249  SetText(str);
250  } break;
251  default:
252  break;
253  }
254  } break;
255  case DATA_SC_POWER: {
256  switch(m_unit) {
257  case UNIT_PU: {
258  SetText(wxString::FromDouble(data.scPower, m_decimalPlaces) + " p.u.");
259  } break;
260  case UNIT_VA: {
261  SetText(wxString::FromDouble(data.scPower * systemPowerBase, m_decimalPlaces) + " VA");
262  } break;
263  case UNIT_kVA: {
264  SetText(wxString::FromDouble(data.scPower * systemPowerBase / 1e3, m_decimalPlaces) +
265  " kVA");
266  } break;
267  case UNIT_MVA: {
268  SetText(wxString::FromDouble(data.scPower * systemPowerBase / 1e6, m_decimalPlaces) +
269  " MVA");
270  } break;
271  default:
272  break;
273  }
274  } break;
275  default:
276  break;
277  }
278  }
279  } break;
280  case TYPE_SYNC_GENERATOR: {
281  SyncGenerator* syncGenerator = static_cast<SyncGenerator*>(m_element);
282  if(syncGenerator) {
283  SyncGeneratorElectricalData data = syncGenerator->GetPUElectricalData(systemPowerBase);
284  double baseVoltage = syncGenerator->GetValueFromUnit(data.nominalVoltage, data.nominalVoltageUnit);
285  double baseCurrent = systemPowerBase / (std::sqrt(3.0) * baseVoltage);
286  switch(m_dataType) {
287  case DATA_NAME: {
288  SetText(data.name);
289  } break;
290  case DATA_ACTIVE_POWER: {
291  double activePower = data.activePower;
292  if(!syncGenerator->IsOnline()) activePower = 0.0;
293  switch(m_unit) {
294  case UNIT_PU: {
295  SetText(wxString::FromDouble(activePower, m_decimalPlaces) + " p.u.");
296  } break;
297  case UNIT_W: {
298  SetText(wxString::FromDouble(activePower * systemPowerBase, m_decimalPlaces) + " W");
299  } break;
300  case UNIT_kW: {
301  SetText(wxString::FromDouble(activePower * systemPowerBase / 1e3, m_decimalPlaces) +
302  " kW");
303  } break;
304  case UNIT_MW: {
305  SetText(wxString::FromDouble(activePower * systemPowerBase / 1e6, m_decimalPlaces) +
306  " MW");
307  } break;
308  default:
309  break;
310  }
311  } break;
312  case DATA_REACTIVE_POWER: {
313  double reactivePower = data.reactivePower;
314  if(!syncGenerator->IsOnline()) reactivePower = 0.0;
315  switch(m_unit) {
316  case UNIT_PU: {
317  SetText(wxString::FromDouble(reactivePower, m_decimalPlaces) + " p.u.");
318  } break;
319  case UNIT_VAr: {
320  SetText(wxString::FromDouble(reactivePower * systemPowerBase, m_decimalPlaces) +
321  " VAr");
322  } break;
323  case UNIT_kVAr: {
324  SetText(wxString::FromDouble(reactivePower * systemPowerBase / 1e3, m_decimalPlaces) +
325  " kVAr");
326  } break;
327  case UNIT_MVAr: {
328  SetText(wxString::FromDouble(reactivePower * systemPowerBase / 1e6, m_decimalPlaces) +
329  " MVAr");
330  } break;
331  default:
332  break;
333  }
334  } break;
335  case DATA_SC_CURRENT: {
336  double faultCurrent[3] = {std::abs(data.faultCurrent[0]), std::abs(data.faultCurrent[1]),
337  std::abs(data.faultCurrent[2])};
338  switch(m_unit) {
339  case UNIT_PU: {
340  wxString str =
341  "Ia = " + wxString::FromDouble(faultCurrent[0], m_decimalPlaces) + " p.u.";
342  str += "\nIb = " + wxString::FromDouble(faultCurrent[1], m_decimalPlaces) + " p.u.";
343  str += "\nIc = " + wxString::FromDouble(faultCurrent[2], m_decimalPlaces) + " p.u.";
344  SetText(str);
345  } break;
346  case UNIT_A: {
347  wxString str = "Ia = " +
348  wxString::FromDouble(faultCurrent[0] * baseCurrent, m_decimalPlaces) +
349  " A";
350  str += "\nIb = " +
351  wxString::FromDouble(faultCurrent[1] * baseCurrent, m_decimalPlaces) + " A";
352  str += "\nIc = " +
353  wxString::FromDouble(faultCurrent[2] * baseCurrent, m_decimalPlaces) + " A";
354  SetText(str);
355  } break;
356  case UNIT_kA: {
357  wxString str =
358  "Ia = " +
359  wxString::FromDouble(faultCurrent[0] * baseCurrent / 1e3, m_decimalPlaces) + " kA";
360  str += "\nIb = " +
361  wxString::FromDouble(faultCurrent[1] * baseCurrent / 1e3, m_decimalPlaces) +
362  " kA";
363  str += "\nIc = " +
364  wxString::FromDouble(faultCurrent[2] * baseCurrent / 1e3, m_decimalPlaces) +
365  " kA";
366  SetText(str);
367  } break;
368  default:
369  break;
370  }
371  } break;
372  default:
373  break;
374  }
375  }
376  } break;
377  case TYPE_LINE: {
378  Line* line = static_cast<Line*>(m_element);
379  if(line) {
380  LineElectricalData data = line->GetElectricalData();
381  double baseVoltage = data.nominalVoltage;
382  if(data.nominalVoltageUnit == UNIT_kV) baseVoltage *= 1e3;
383  double baseCurrent = systemPowerBase / (std::sqrt(3.0) * baseVoltage);
384  switch(m_dataType) {
385  case DATA_NAME: {
386  SetText(data.name);
387  } break;
388  case DATA_PF_ACTIVE: {
389  double activePF = std::real(data.powerFlow[m_direction]);
390  if(!line->IsOnline()) activePF = 0.0;
391  switch(m_unit) {
392  case UNIT_PU: {
393  SetText(wxString::FromDouble(activePF, m_decimalPlaces) + " p.u.");
394  } break;
395  case UNIT_W: {
396  SetText(wxString::FromDouble(activePF * systemPowerBase, m_decimalPlaces) + " W");
397  } break;
398  case UNIT_kW: {
399  SetText(wxString::FromDouble(activePF * systemPowerBase / 1e3, m_decimalPlaces) +
400  " kW");
401  } break;
402  case UNIT_MW: {
403  SetText(wxString::FromDouble(activePF * systemPowerBase / 1e6, m_decimalPlaces) +
404  " MW");
405  } break;
406  default:
407  break;
408  }
409  } break;
410  case DATA_PF_REACTIVE: {
411  double reactivePF = std::imag(data.powerFlow[m_direction]);
412  if(!line->IsOnline()) reactivePF = 0.0;
413  switch(m_unit) {
414  case UNIT_PU: {
415  SetText(wxString::FromDouble(reactivePF, m_decimalPlaces) + " p.u.");
416  } break;
417  case UNIT_VAr: {
418  SetText(wxString::FromDouble(reactivePF * systemPowerBase, m_decimalPlaces) + " VAr");
419  } break;
420  case UNIT_kVAr: {
421  SetText(wxString::FromDouble(reactivePF * systemPowerBase / 1e3, m_decimalPlaces) +
422  " kVAr");
423  } break;
424  case UNIT_MVAr: {
425  SetText(wxString::FromDouble(reactivePF * systemPowerBase / 1e6, m_decimalPlaces) +
426  " MVAr");
427  } break;
428  default:
429  break;
430  }
431  } break;
432  case DATA_PF_LOSSES: {
433  double losses = std::abs(std::real(data.powerFlow[0]) + std::real(data.powerFlow[1]));
434  if(!line->IsOnline()) losses = 0.0;
435  switch(m_unit) {
436  case UNIT_PU: {
437  SetText(wxString::FromDouble(losses, m_decimalPlaces) + " p.u.");
438  } break;
439  case UNIT_W: {
440  SetText(wxString::FromDouble(losses * systemPowerBase, m_decimalPlaces) + " W");
441  } break;
442  case UNIT_kW: {
443  SetText(wxString::FromDouble(losses * systemPowerBase / 1e3, m_decimalPlaces) + " kW");
444  } break;
445  case UNIT_MW: {
446  SetText(wxString::FromDouble(losses * systemPowerBase / 1e6, m_decimalPlaces) + " MW");
447  } break;
448  default:
449  break;
450  }
451  } break;
452  case DATA_PF_CURRENT: {
453  double current = std::abs(data.current[m_direction]);
454  if(!line->IsOnline()) current = 0.0;
455  switch(m_unit) {
456  case UNIT_PU: {
457  SetText(wxString::FromDouble(current, m_decimalPlaces) + " p.u.");
458  } break;
459  case UNIT_A: {
460  SetText(wxString::FromDouble(current * baseCurrent, m_decimalPlaces) + " A");
461  } break;
462  case UNIT_kA: {
463  SetText(wxString::FromDouble(current * baseCurrent / 1e3, m_decimalPlaces) + " kA");
464  } break;
465  default:
466  break;
467  }
468  } break;
469  case DATA_SC_CURRENT: {
470  double faultCurrent[3] = {std::abs(data.faultCurrent[m_direction][0]),
471  std::abs(data.faultCurrent[m_direction][1]),
472  std::abs(data.faultCurrent[m_direction][2])};
473  if(!line->IsOnline()) faultCurrent[0] = faultCurrent[1] = faultCurrent[2] = 0.0;
474  switch(m_unit) {
475  case UNIT_PU: {
476  wxString str =
477  "Ia = " + wxString::FromDouble(faultCurrent[0], m_decimalPlaces) + " p.u.";
478  str += "\nIb = " + wxString::FromDouble(faultCurrent[1], m_decimalPlaces) + " p.u.";
479  str += "\nIc = " + wxString::FromDouble(faultCurrent[2], m_decimalPlaces) + " p.u.";
480  SetText(str);
481  } break;
482  case UNIT_A: {
483  wxString str = "Ia = " +
484  wxString::FromDouble(faultCurrent[0] * baseCurrent, m_decimalPlaces) +
485  " A";
486  str += "\nIb = " +
487  wxString::FromDouble(faultCurrent[1] * baseCurrent, m_decimalPlaces) + " A";
488  str += "\nIc = " +
489  wxString::FromDouble(faultCurrent[2] * baseCurrent, m_decimalPlaces) + " A";
490  SetText(str);
491  } break;
492  case UNIT_kA: {
493  wxString str =
494  "Ia = " +
495  wxString::FromDouble(faultCurrent[0] * baseCurrent / 1e3, m_decimalPlaces) + " kA";
496  str += "\nIb = " +
497  wxString::FromDouble(faultCurrent[1] * baseCurrent / 1e3, m_decimalPlaces) +
498  " kA";
499  str += "\nIc = " +
500  wxString::FromDouble(faultCurrent[2] * baseCurrent / 1e3, m_decimalPlaces) +
501  " kA";
502  SetText(str);
503  } break;
504  default:
505  break;
506  }
507  } break;
508  default:
509  break;
510  }
511  }
512  } break;
513  case TYPE_TRANSFORMER: {
514  Transformer* transformer = static_cast<Transformer*>(m_element);
515  if(transformer) {
516  TransformerElectricalData data = transformer->GetElectricalData();
517  double baseVoltage[2] = {data.primaryNominalVoltage, data.secondaryNominalVoltage};
518 
519  if(data.primaryNominalVoltageUnit == UNIT_kV) baseVoltage[0] *= 1e3;
520  if(data.secondaryNominalVoltageUnit == UNIT_kV) baseVoltage[1] *= 1e3;
521 
522  double baseCurrent[2] = {systemPowerBase / (std::sqrt(3.0) * baseVoltage[0]),
523  systemPowerBase / (std::sqrt(3.0) * baseVoltage[1])};
524  switch(m_dataType) {
525  case DATA_NAME: {
526  SetText(data.name);
527  } break;
528  case DATA_PF_ACTIVE: {
529  double activePF = std::real(data.powerFlow[m_direction]);
530  if(!transformer->IsOnline()) activePF = 0.0;
531  switch(m_unit) {
532  case UNIT_PU: {
533  SetText(wxString::FromDouble(activePF, m_decimalPlaces) + " p.u.");
534  } break;
535  case UNIT_W: {
536  SetText(wxString::FromDouble(activePF * systemPowerBase, m_decimalPlaces) + " W");
537  } break;
538  case UNIT_kW: {
539  SetText(wxString::FromDouble(activePF * systemPowerBase / 1e3, m_decimalPlaces) +
540  " kW");
541  } break;
542  case UNIT_MW: {
543  SetText(wxString::FromDouble(activePF * systemPowerBase / 1e6, m_decimalPlaces) +
544  " MW");
545  } break;
546  default:
547  break;
548  }
549  } break;
550  case DATA_PF_REACTIVE: {
551  double reactivePF = std::imag(data.powerFlow[m_direction]);
552  if(!transformer->IsOnline()) reactivePF = 0.0;
553  switch(m_unit) {
554  case UNIT_PU: {
555  SetText(wxString::FromDouble(reactivePF, m_decimalPlaces) + " p.u.");
556  } break;
557  case UNIT_VAr: {
558  SetText(wxString::FromDouble(reactivePF * systemPowerBase, m_decimalPlaces) + " VAr");
559  } break;
560  case UNIT_kVAr: {
561  SetText(wxString::FromDouble(reactivePF * systemPowerBase / 1e3, m_decimalPlaces) +
562  " kVAr");
563  } break;
564  case UNIT_MVAr: {
565  SetText(wxString::FromDouble(reactivePF * systemPowerBase / 1e6, m_decimalPlaces) +
566  " MVAr");
567  } break;
568  default:
569  break;
570  }
571  } break;
572  case DATA_PF_LOSSES: {
573  double losses = std::abs(std::real(data.powerFlow[0]) + std::real(data.powerFlow[1]));
574  if(!transformer->IsOnline()) losses = 0.0;
575  switch(m_unit) {
576  case UNIT_PU: {
577  SetText(wxString::FromDouble(losses, m_decimalPlaces) + " p.u.");
578  } break;
579  case UNIT_W: {
580  SetText(wxString::FromDouble(losses * systemPowerBase, m_decimalPlaces) + " W");
581  } break;
582  case UNIT_kW: {
583  SetText(wxString::FromDouble(losses * systemPowerBase / 1e3, m_decimalPlaces) + " kW");
584  } break;
585  case UNIT_MW: {
586  SetText(wxString::FromDouble(losses * systemPowerBase / 1e6, m_decimalPlaces) + " MW");
587  } break;
588  default:
589  break;
590  }
591  } break;
592  case DATA_PF_CURRENT: {
593  double current = std::abs(data.current[m_direction]);
594  if(!transformer->IsOnline()) current = 0.0;
595  switch(m_unit) {
596  case UNIT_PU: {
597  SetText(wxString::FromDouble(current, m_decimalPlaces) + " p.u.");
598  } break;
599  case UNIT_A: {
600  SetText(wxString::FromDouble(current * baseCurrent[m_direction], m_decimalPlaces) +
601  " A");
602  } break;
603  case UNIT_kA: {
604  SetText(
605  wxString::FromDouble(current * baseCurrent[m_direction] / 1e3, m_decimalPlaces) +
606  " kA");
607  } break;
608  default:
609  break;
610  }
611  } break;
612  case DATA_SC_CURRENT: {
613  double faultCurrent[3] = {std::abs(data.faultCurrent[m_direction][0]),
614  std::abs(data.faultCurrent[m_direction][1]),
615  std::abs(data.faultCurrent[m_direction][2])};
616  if(!transformer->IsOnline()) faultCurrent[0] = faultCurrent[1] = faultCurrent[2] = 0.0;
617  switch(m_unit) {
618  case UNIT_PU: {
619  wxString str =
620  "Ia = " + wxString::FromDouble(faultCurrent[0], m_decimalPlaces) + " p.u.";
621  str += "\nIb = " + wxString::FromDouble(faultCurrent[1], m_decimalPlaces) + " p.u.";
622  str += "\nIc = " + wxString::FromDouble(faultCurrent[2], m_decimalPlaces) + " p.u.";
623  SetText(str);
624  } break;
625  case UNIT_A: {
626  wxString str =
627  "Ia = " +
628  wxString::FromDouble(faultCurrent[0] * baseCurrent[m_direction], m_decimalPlaces) +
629  " A";
630  str += "\nIb = " + wxString::FromDouble(faultCurrent[1] * baseCurrent[m_direction],
631  m_decimalPlaces) +
632  " A";
633  str += "\nIc = " + wxString::FromDouble(faultCurrent[2] * baseCurrent[m_direction],
634  m_decimalPlaces) +
635  " A";
636  SetText(str);
637  } break;
638  case UNIT_kA: {
639  wxString str = "Ia = " +
640  wxString::FromDouble(faultCurrent[0] * baseCurrent[m_direction] / 1e3,
641  m_decimalPlaces) +
642  " kA";
643  str += "\nIb = " +
644  wxString::FromDouble(faultCurrent[1] * baseCurrent[m_direction] / 1e3,
645  m_decimalPlaces) +
646  " kA";
647  str += "\nIc = " +
648  wxString::FromDouble(faultCurrent[2] * baseCurrent[m_direction] / 1e3,
649  m_decimalPlaces) +
650  " kA";
651  SetText(str);
652  } break;
653  default:
654  break;
655  }
656  } break;
657  default:
658  break;
659  }
660  }
661  } break;
662  case TYPE_LOAD: {
663  Load* load = static_cast<Load*>(m_element);
664  if(load) {
665  LoadElectricalData data = load->GetPUElectricalData(systemPowerBase);
666  std::complex<double> sPower(data.activePower, data.reactivePower);
667  if(data.loadType == CONST_IMPEDANCE && load->IsOnline()) {
668  std::complex<double> v = static_cast<Bus*>(load->GetParentList()[0])->GetElectricalData().voltage;
669  sPower = std::pow(std::abs(v), 2) * sPower;
670  }
671  if(!load->IsOnline()) sPower = std::complex<double>(0.0, 0.0);
672  switch(m_dataType) {
673  case DATA_NAME: {
674  SetText(data.name);
675  } break;
676  case DATA_ACTIVE_POWER: {
677  switch(m_unit) {
678  case UNIT_PU: {
679  SetText(wxString::FromDouble(sPower.real(), m_decimalPlaces) + " p.u.");
680  }
681  case UNIT_W: {
682  SetText(wxString::FromDouble(sPower.real() * systemPowerBase, m_decimalPlaces) + " W");
683  }
684  case UNIT_kW: {
685  SetText(wxString::FromDouble(sPower.real() * systemPowerBase / 1e3, m_decimalPlaces) +
686  " kW");
687  }
688  case UNIT_MW: {
689  SetText(wxString::FromDouble(sPower.real() * systemPowerBase / 1e6, m_decimalPlaces) +
690  " MW");
691  }
692  default:
693  break;
694  }
695  } break;
696  case DATA_REACTIVE_POWER: {
697  switch(m_unit) {
698  case UNIT_PU: {
699  SetText(wxString::FromDouble(sPower.imag(), m_decimalPlaces) + " p.u.");
700  }
701  case UNIT_VAr: {
702  SetText(wxString::FromDouble(sPower.imag() * systemPowerBase, m_decimalPlaces) +
703  " VAr");
704  }
705  case UNIT_kVAr: {
706  SetText(wxString::FromDouble(sPower.imag() * systemPowerBase / 1e3, m_decimalPlaces) +
707  " kVAr");
708  }
709  case UNIT_MVAr: {
710  SetText(wxString::FromDouble(sPower.imag() * systemPowerBase / 1e6, m_decimalPlaces) +
711  " MVAr");
712  }
713  default:
714  break;
715  }
716  } break;
717  default:
718  break;
719  }
720  }
721  } break;
722  case TYPE_SYNC_MOTOR: {
723  SyncMotor* syncMotor = static_cast<SyncMotor*>(m_element);
724  if(syncMotor) {
725  SyncMotorElectricalData data = syncMotor->GetPUElectricalData(systemPowerBase);
726  std::complex<double> sPower(data.activePower, data.reactivePower);
727  if(!syncMotor->IsOnline()) sPower = std::complex<double>(0.0, 0.0);
728  switch(m_dataType) {
729  case DATA_NAME: {
730  SetText(data.name);
731  } break;
732  case DATA_ACTIVE_POWER: {
733  switch(m_unit) {
734  case UNIT_PU: {
735  SetText(wxString::FromDouble(sPower.real(), m_decimalPlaces) + " p.u.");
736  }
737  case UNIT_W: {
738  SetText(wxString::FromDouble(sPower.real() * systemPowerBase, m_decimalPlaces) + " W");
739  }
740  case UNIT_kW: {
741  SetText(wxString::FromDouble(sPower.real() * systemPowerBase / 1e3, m_decimalPlaces) +
742  " kW");
743  }
744  case UNIT_MW: {
745  SetText(wxString::FromDouble(sPower.real() * systemPowerBase / 1e6, m_decimalPlaces) +
746  " MW");
747  }
748  default:
749  break;
750  }
751  } break;
752  case DATA_REACTIVE_POWER: {
753  switch(m_unit) {
754  case UNIT_PU: {
755  SetText(wxString::FromDouble(sPower.imag(), m_decimalPlaces) + " p.u.");
756  }
757  case UNIT_VAr: {
758  SetText(wxString::FromDouble(sPower.imag() * systemPowerBase, m_decimalPlaces) +
759  " VAr");
760  }
761  case UNIT_kVAr: {
762  SetText(wxString::FromDouble(sPower.imag() * systemPowerBase / 1e3, m_decimalPlaces) +
763  " kVAr");
764  }
765  case UNIT_MVAr: {
766  SetText(wxString::FromDouble(sPower.imag() * systemPowerBase / 1e6, m_decimalPlaces) +
767  " MVAr");
768  }
769  default:
770  break;
771  }
772  } break;
773  default:
774  break;
775  }
776  }
777  } break;
778  case TYPE_IND_MOTOR: {
779  IndMotor* indMotor = static_cast<IndMotor*>(m_element);
780  if(indMotor) {
781  IndMotorElectricalData data = indMotor->GetPUElectricalData(systemPowerBase);
782  std::complex<double> sPower(data.activePower, data.reactivePower);
783  if(!indMotor->IsOnline()) sPower = std::complex<double>(0.0, 0.0);
784  switch(m_dataType) {
785  case DATA_NAME: {
786  SetText(data.name);
787  } break;
788  case DATA_ACTIVE_POWER: {
789  switch(m_unit) {
790  case UNIT_PU: {
791  SetText(wxString::FromDouble(sPower.real(), m_decimalPlaces) + " p.u.");
792  }
793  case UNIT_W: {
794  SetText(wxString::FromDouble(sPower.real() * systemPowerBase, m_decimalPlaces) + " W");
795  }
796  case UNIT_kW: {
797  SetText(wxString::FromDouble(sPower.real() * systemPowerBase / 1e3, m_decimalPlaces) +
798  " kW");
799  }
800  case UNIT_MW: {
801  SetText(wxString::FromDouble(sPower.real() * systemPowerBase / 1e6, m_decimalPlaces) +
802  " MW");
803  }
804  default:
805  break;
806  }
807  } break;
808  case DATA_REACTIVE_POWER: {
809  switch(m_unit) {
810  case UNIT_PU: {
811  SetText(wxString::FromDouble(sPower.imag(), m_decimalPlaces) + " p.u.");
812  }
813  case UNIT_VAr: {
814  SetText(wxString::FromDouble(sPower.imag() * systemPowerBase, m_decimalPlaces) +
815  " VAr");
816  }
817  case UNIT_kVAr: {
818  SetText(wxString::FromDouble(sPower.imag() * systemPowerBase / 1e3, m_decimalPlaces) +
819  " kVAr");
820  }
821  case UNIT_MVAr: {
822  SetText(wxString::FromDouble(sPower.imag() * systemPowerBase / 1e6, m_decimalPlaces) +
823  " MVAr");
824  }
825  default:
826  break;
827  }
828  } break;
829  default:
830  break;
831  }
832  }
833  } break;
834  case TYPE_CAPACITOR: {
835  Capacitor* capacitor = static_cast<Capacitor*>(m_element);
836  if(capacitor) {
837  CapacitorElectricalData data = capacitor->GetPUElectricalData(systemPowerBase);
838  double reativePower = data.reactivePower;
839  if(!capacitor->IsOnline())
840  reativePower = 0.0;
841  else {
842  std::complex<double> v =
843  static_cast<Bus*>(capacitor->GetParentList()[0])->GetElectricalData().voltage;
844  reativePower *= std::pow(std::abs(v), 2);
845  }
846  switch(m_dataType) {
847  case DATA_NAME: {
848  SetText(data.name);
849  } break;
850  case DATA_REACTIVE_POWER: {
851  switch(m_unit) {
852  case UNIT_PU: {
853  SetText(wxString::FromDouble(reativePower, m_decimalPlaces) + " p.u.");
854  }
855  case UNIT_VAr: {
856  SetText(wxString::FromDouble(reativePower * systemPowerBase, m_decimalPlaces) + " VAr");
857  }
858  case UNIT_kVAr: {
859  SetText(wxString::FromDouble(reativePower * systemPowerBase / 1e3, m_decimalPlaces) +
860  " kVAr");
861  }
862  case UNIT_MVAr: {
863  SetText(wxString::FromDouble(reativePower * systemPowerBase / 1e6, m_decimalPlaces) +
864  " MVAr");
865  }
866  default:
867  break;
868  }
869  } break;
870  default:
871  break;
872  }
873  }
874  } break;
875  case TYPE_INDUCTOR: {
876  Inductor* inductor = static_cast<Inductor*>(m_element);
877  if(inductor) {
878  InductorElectricalData data = inductor->GetPUElectricalData(systemPowerBase);
879  double reativePower = data.reactivePower;
880  if(!inductor->IsOnline())
881  reativePower = 0.0;
882  else {
883  std::complex<double> v =
884  static_cast<Bus*>(inductor->GetParentList()[0])->GetElectricalData().voltage;
885  reativePower *= std::pow(std::abs(v), 2);
886  }
887  switch(m_dataType) {
888  case DATA_NAME: {
889  SetText(data.name);
890  } break;
891  case DATA_REACTIVE_POWER: {
892  switch(m_unit) {
893  case UNIT_PU: {
894  SetText(wxString::FromDouble(reativePower, m_decimalPlaces) + " p.u.");
895  }
896  case UNIT_VAr: {
897  SetText(wxString::FromDouble(reativePower * systemPowerBase, m_decimalPlaces) + " VAr");
898  }
899  case UNIT_kVAr: {
900  SetText(wxString::FromDouble(reativePower * systemPowerBase / 1e3, m_decimalPlaces) +
901  " kVAr");
902  }
903  case UNIT_MVAr: {
904  SetText(wxString::FromDouble(reativePower * systemPowerBase / 1e6, m_decimalPlaces) +
905  " MVAr");
906  }
907  default:
908  break;
909  }
910  } break;
911  default:
912  break;
913  }
914  }
915  } break;
916  }
917 }
918 
920 {
921  Text* copy = new Text();
922  *copy = *this;
923  std::vector<OpenGLText*> copyList;
924  for(auto it = m_openGLTextList.begin(), itEnd = m_openGLTextList.end(); it != itEnd; ++it) {
925  copyList.push_back((*it)->GetCopy());
926  }
927  copy->m_openGLTextList = copyList;
928  return copy;
929 }
930 
931 bool Text::IsGLTextOK()
932 {
933  bool isOk = true;
934  for(auto it = m_openGLTextList.begin(), itEnd = m_openGLTextList.end(); it != itEnd; ++it) {
935  if(!(*it)->IsTextureOK()) isOk = false;
936  }
937  return isOk;
938 }
virtual bool Contains(wxPoint2DDouble position) const
Checks if the element contains a position.
Definition: Text.cpp:43
+
Element that shows power element informations in workspace.
Definition: Text.h:75
Abstract class for graphical elements shown with power elements in workspace.
Base class of all elements of the program. This class is responsible for manage graphical and his dat...
Definition: Element.h:113
-
virtual void Rotate(bool clockwise=true)
Rotate the element.
Definition: Text.cpp:162
+
virtual void Rotate(bool clockwise=true)
Rotate the element.
Definition: Text.cpp:114
virtual std::vector< Element * > GetParentList() const
Get the parent list.
Definition: Element.h:506
@@ -106,14 +106,14 @@ $(document).ready(function(){initNavTree('_text_8cpp_source.html','');});
Synchronous generator power element.
-
virtual bool Intersects(wxRect2DDouble rect) const
Check if the element&#39;s rect intersects other rect.
Definition: Text.cpp:92
+
virtual bool Intersects(wxRect2DDouble rect) const
Check if the element&#39;s rect intersects other rect.
Definition: Text.cpp:82
virtual wxPoint2DDouble RotateAtPosition(wxPoint2DDouble pointToRotate, double angle, bool degrees=true) const
Rotate a point as element position being the origin.
Definition: Element.cpp:107
virtual void DrawRectangle(wxPoint2DDouble position, double width, double height, GLenum mode=GL_QUADS) const
Draw rectangle.
Definition: Element.cpp:69
-
virtual Element * GetCopy()
Get a the element copy.
Definition: Text.cpp:967
+
virtual Element * GetCopy()
Get a the element copy.
Definition: Text.cpp:919
Node for power elements. All others power elements are connected through this.
Definition: Bus.h:69
bool IsOnline() const
Checks if the element is online or offline.
Definition: Element.h:227
@@ -121,17 +121,19 @@ $(document).ready(function(){initNavTree('_text_8cpp_source.html','');}); +
double GetWidth() const
Get the element width.
Definition: Element.h:207
void SetPosition(const wxPoint2DDouble position)
Set the element position and update the rectangle.
Definition: Element.cpp:25
Form to edit the text graphical data.
Definition: TextForm.h:32
Power line element.
Definition: Line.h:59
-
Loas shunt power element.
Definition: Load.h:42
+
Loas shunt power element.
Definition: Load.h:73
Synchronous motor (synchronous compensator) power element.
Definition: SyncMotor.h:134
+
Class to draw text on OpenGL using wxWidgets.
Definition: OpenGLText.h:31
Induction motor power element.
Definition: IndMotor.h:40
@@ -141,11 +143,9 @@ $(document).ready(function(){initNavTree('_text_8cpp_source.html','');}); -
virtual bool RotatedRectanglesIntersects(wxRect2DDouble rect1, wxRect2DDouble rect2, double angle1, double angle2) const
Check if two roteted rectangles intersect.
Definition: Element.cpp:147
-
Two-winding transformer power element.
Definition: Transformer.h:78
diff --git a/docs/doxygen/html/_text_8h.html b/docs/doxygen/html/_text_8h.html index 3c05a89..14f5dc8 100644 --- a/docs/doxygen/html/_text_8h.html +++ b/docs/doxygen/html/_text_8h.html @@ -91,9 +91,11 @@ $(document).ready(function(){initNavTree('_text_8h.html','');});
Text.h File Reference
-
#include "GraphicalElement.h"
+
#include <GL/gl.h>
+#include <wx/dcmemory.h>
+#include "GraphicalElement.h"
#include "PowerElement.h"
-#include "wxGLString.h"
+#include "OpenGLText.h"

Go to the source code of this file.

diff --git a/docs/doxygen/html/_text_8h_source.html b/docs/doxygen/html/_text_8h_source.html index 5b4f986..a839af7 100644 --- a/docs/doxygen/html/_text_8h_source.html +++ b/docs/doxygen/html/_text_8h_source.html @@ -88,28 +88,27 @@ $(document).ready(function(){initNavTree('_text_8h_source.html','');});
Text.h
-Go to the documentation of this file.
1 /*
2  * Copyright (C) 2017 Thales Lima Oliveira <thales@ufu.br>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program. If not, see <https://www.gnu.org/licenses/>.
16  */
17 
18 #ifndef TEXT_H
19 #define TEXT_H
20 
21 #include "GraphicalElement.h"
22 #include "PowerElement.h"
23 #include "wxGLString.h"
24 
25 class TextForm;
26 
27 class Bus;
28 class Line;
29 class Transformer;
30 class SyncGenerator;
31 class IndMotor;
32 class SyncMotor;
33 class Load;
34 class Inductor;
35 class Capacitor;
36 
37 enum ElementType {
38  TYPE_NONE = 0,
39  TYPE_BUS,
40  TYPE_CAPACITOR,
41  TYPE_IND_MOTOR,
42  TYPE_INDUCTOR,
43  TYPE_LINE,
44  TYPE_LOAD,
45  TYPE_SYNC_GENERATOR,
46  TYPE_SYNC_MOTOR,
47  TYPE_TRANSFORMER
48 };
49 
50 enum DataType {
51  DATA_NAME,
52  DATA_VOLTAGE,
53  DATA_ANGLE,
54  DATA_SC_CURRENT,
55  DATA_SC_VOLTAGE,
56  DATA_SC_POWER,
57  DATA_ACTIVE_POWER,
58  DATA_REACTIVE_POWER,
59  DATA_PF_ACTIVE,
60  DATA_PF_REACTIVE,
61  DATA_PF_LOSSES,
62  DATA_PF_CURRENT
63 };
64 
72 class Text : public GraphicalElement
73 {
74  public:
75  Text();
76  Text(wxPoint2DDouble position);
77  ~Text();
78 
79  virtual Element* GetCopy();
80  virtual bool AddParent(Element* parent, wxPoint2DDouble position) { return true; };
81  virtual bool Contains(wxPoint2DDouble position) const;
82  virtual void Draw(wxPoint2DDouble translation, double scale);
83  virtual bool Intersects(wxRect2DDouble rect) const;
84  virtual void Rotate(bool clockwise = true);
85  virtual bool ShowForm(wxWindow* parent, std::vector<Element*> elementList);
86  virtual void UpdateText(double systemPowerBase);
87  virtual wxString GetText() const { return m_text; }
88  virtual void SetText(wxString text);
89 
90  void SetDataType(const DataType& dataType) { m_dataType = dataType; }
91  void SetDirection(int direction) { m_direction = direction; }
92  void SetElement(Element* element) { m_element = element; }
93  void SetElementNumber(int elementNumber) { m_elementNumber = elementNumber; }
94  void SetElementType(const ElementType elementType) { m_elementType = elementType; }
95  void SetFontSize(int fontSize) { m_fontSize = fontSize; }
96  void SetUnit(const ElectricalUnit unit) { m_unit = unit; }
97  void SetDecimalPlaces(int decimalPlaces) { m_decimalPlaces = decimalPlaces; }
98  const DataType GetDataType() const { return m_dataType; }
99  int GetDirection() const { return m_direction; }
100  Element* GetElement() { return m_element; }
101  int GetElementNumber() const { return m_elementNumber; }
102  const ElementType GetElementType() const { return m_elementType; }
103  int GetFontSize() const { return m_fontSize; }
104  const ElectricalUnit GetUnit() const { return m_unit; }
105  int GetDecimalPlaces() const { return m_decimalPlaces; }
106  protected:
107  wxGLString* m_glString = NULL;
108  wxGLStringArray* m_glStringArray = NULL;
109 
110  wxString m_text = _("Text");
111  int m_numberOfLines;
112  bool m_isMultlineText = false;
113  int m_fontSize = 10;
114 
115  Element* m_element = NULL;
116  ElementType m_elementType = TYPE_NONE;
117  int m_elementNumber;
118  DataType m_dataType;
119  ElectricalUnit m_unit;
120  int m_direction = 0;
121  int m_decimalPlaces = 2;
122 };
123 
124 #endif // TEXT_H
virtual bool Contains(wxPoint2DDouble position) const
Checks if the element contains a position.
Definition: Text.cpp:47
-
Element that shows power element informations in workspace.
Definition: Text.h:72
+Go to the documentation of this file.
1 /*
2  * Copyright (C) 2017 Thales Lima Oliveira <thales@ufu.br>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program. If not, see <https://www.gnu.org/licenses/>.
16  */
17 
18 #ifndef TEXT_H
19 #define TEXT_H
20 
21 #include <GL/gl.h>
22 #include <wx/dcmemory.h>
23 
24 #include "GraphicalElement.h"
25 #include "PowerElement.h"
26 #include "OpenGLText.h"
27 
28 class TextForm;
29 
30 class Bus;
31 class Line;
32 class Transformer;
33 class SyncGenerator;
34 class IndMotor;
35 class SyncMotor;
36 class Load;
37 class Inductor;
38 class Capacitor;
39 
40 enum ElementType {
41  TYPE_NONE = 0,
42  TYPE_BUS,
43  TYPE_CAPACITOR,
44  TYPE_IND_MOTOR,
45  TYPE_INDUCTOR,
46  TYPE_LINE,
47  TYPE_LOAD,
48  TYPE_SYNC_GENERATOR,
49  TYPE_SYNC_MOTOR,
50  TYPE_TRANSFORMER
51 };
52 
53 enum DataType {
54  DATA_NAME,
55  DATA_VOLTAGE,
56  DATA_ANGLE,
57  DATA_SC_CURRENT,
58  DATA_SC_VOLTAGE,
59  DATA_SC_POWER,
60  DATA_ACTIVE_POWER,
61  DATA_REACTIVE_POWER,
62  DATA_PF_ACTIVE,
63  DATA_PF_REACTIVE,
64  DATA_PF_LOSSES,
65  DATA_PF_CURRENT
66 };
67 
75 class Text : public GraphicalElement
76 {
77  public:
78  Text();
79  Text(wxPoint2DDouble position);
80  ~Text();
81 
82  virtual Element* GetCopy();
83  virtual bool AddParent(Element* parent, wxPoint2DDouble position) { return true; };
84  virtual bool Contains(wxPoint2DDouble position) const;
85  virtual void Draw(wxPoint2DDouble translation, double scale);
86  virtual bool Intersects(wxRect2DDouble rect) const;
87  virtual void Rotate(bool clockwise = true);
88  virtual bool ShowForm(wxWindow* parent, std::vector<Element*> elementList);
89  virtual void UpdateText(double systemPowerBase);
90  virtual wxString GetText() const { return m_text; }
91  virtual void SetText(wxString text);
92  virtual bool IsGLTextOK();
93 
94  void SetDataType(const DataType& dataType) { m_dataType = dataType; }
95  void SetDirection(int direction) { m_direction = direction; }
96  void SetElement(Element* element) { m_element = element; }
97  void SetElementNumber(int elementNumber) { m_elementNumber = elementNumber; }
98  void SetElementType(const ElementType elementType) { m_elementType = elementType; }
99  void SetUnit(const ElectricalUnit unit) { m_unit = unit; }
100  void SetDecimalPlaces(int decimalPlaces) { m_decimalPlaces = decimalPlaces; }
101  const DataType GetDataType() const { return m_dataType; }
102  int GetDirection() const { return m_direction; }
103  Element* GetElement() { return m_element; }
104  int GetElementNumber() const { return m_elementNumber; }
105  const ElementType GetElementType() const { return m_elementType; }
106  const ElectricalUnit GetUnit() const { return m_unit; }
107  int GetDecimalPlaces() const { return m_decimalPlaces; }
108  protected:
109  wxString m_text = _("Text");
110  int m_numberOfLines = 0;
111  bool m_isMultlineText = false;
112 
113  std::vector<OpenGLText*> m_openGLTextList;
114 
115  Element* m_element = NULL;
116  ElementType m_elementType = TYPE_NONE;
117  int m_elementNumber;
118  DataType m_dataType;
119  ElectricalUnit m_unit;
120  int m_direction = 0;
121  int m_decimalPlaces = 2;
122 };
123 
124 #endif // TEXT_H
virtual bool Contains(wxPoint2DDouble position) const
Checks if the element contains a position.
Definition: Text.cpp:43
+
Element that shows power element informations in workspace.
Definition: Text.h:75
Abstract class for graphical elements shown with power elements in workspace.
Base class of all elements of the program. This class is responsible for manage graphical and his dat...
Definition: Element.h:113
-
virtual void Rotate(bool clockwise=true)
Rotate the element.
Definition: Text.cpp:162
+
virtual void Rotate(bool clockwise=true)
Rotate the element.
Definition: Text.cpp:114
Synchronous generator power element.
-
virtual bool Intersects(wxRect2DDouble rect) const
Check if the element&#39;s rect intersects other rect.
Definition: Text.cpp:92
+
virtual bool Intersects(wxRect2DDouble rect) const
Check if the element&#39;s rect intersects other rect.
Definition: Text.cpp:82
ElectricalUnit
Electrical units.
Definition: PowerElement.h:28
-
virtual Element * GetCopy()
Get a the element copy.
Definition: Text.cpp:967
+
virtual Element * GetCopy()
Get a the element copy.
Definition: Text.cpp:919
Node for power elements. All others power elements are connected through this.
Definition: Bus.h:69
-
virtual bool AddParent(Element *parent, wxPoint2DDouble position)
Add a parent to the element. This method must be used on power elements that connect to a bus...
Definition: Text.h:80
+ +
virtual bool AddParent(Element *parent, wxPoint2DDouble position)
Add a parent to the element. This method must be used on power elements that connect to a bus...
Definition: Text.h:83
Form to edit the text graphical data.
Definition: TextForm.h:32
Power line element.
Definition: Line.h:59
-
Loas shunt power element.
Definition: Load.h:42
+
Loas shunt power element.
Definition: Load.h:73
Synchronous motor (synchronous compensator) power element.
Definition: SyncMotor.h:134
Induction motor power element.
Definition: IndMotor.h:40
Shunt capactior power element.
Definition: Capacitor.h:38
Inductor shunt power element.
Definition: Inductor.h:38
- -
Two-winding transformer power element.
Definition: Transformer.h:78
diff --git a/docs/doxygen/html/_text_form_8cpp_source.html b/docs/doxygen/html/_text_form_8cpp_source.html index cec668f..23f3381 100644 --- a/docs/doxygen/html/_text_form_8cpp_source.html +++ b/docs/doxygen/html/_text_form_8cpp_source.html @@ -88,7 +88,7 @@ $(document).ready(function(){initNavTree('_text_form_8cpp_source.html','');});
TextForm.cpp
-
1 /*
2  * Copyright (C) 2017 Thales Lima Oliveira <thales@ufu.br>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program. If not, see <https://www.gnu.org/licenses/>.
16  */
17 
18 #include "TextForm.h"
19 
20 TextForm::TextForm(wxWindow* parent, Text* text, std::vector<Element*> elementList, double systemPowerBase)
21  : TextFormBase(parent)
22 {
23  SetSize(GetBestSize());
24  m_parent = parent;
25  m_textToEdit = text;
26  m_allElements.GetElementsFromList(elementList);
27  m_systemPowerBase = systemPowerBase;
28 
29  m_text = new Text();
30  m_text->SetElementType(text->GetElementType());
31  m_text->SetElementNumber(text->GetElementNumber());
32  m_text->SetElement(text->GetElement());
33  m_text->SetDataType(text->GetDataType());
34  m_text->SetDirection(text->GetDirection());
35  m_text->SetUnit(text->GetUnit());
36  m_text->SetDecimalPlaces(text->GetDecimalPlaces());
37 
38  if(!LoadChoices()) {
39  m_choiceName->Enable(false);
40  m_choiceTextType->Enable(false);
41  m_choiceTextFromBus->Enable(false);
42  m_choiceTextToBus->Enable(false);
43  m_choiceTextUnit->Enable(false);
44  }
45 }
46 
47 TextForm::~TextForm() {}
48 void TextForm::OnElementChoiceSelected(wxCommandEvent& event)
49 {
50  switch(m_choiceElement->GetSelection()) {
51  case 0: {
52  m_text->SetElementType(TYPE_BUS);
53  } break;
54  case 1: {
55  m_text->SetElementType(TYPE_SYNC_GENERATOR);
56  } break;
57  case 2: {
58  m_text->SetElementType(TYPE_LINE);
59  } break;
60  case 3: {
61  m_text->SetElementType(TYPE_TRANSFORMER);
62  } break;
63  case 4: {
64  m_text->SetElementType(TYPE_LOAD);
65  } break;
66  case 5: {
67  m_text->SetElementType(TYPE_CAPACITOR);
68  } break;
69  case 6: {
70  m_text->SetElementType(TYPE_INDUCTOR);
71  } break;
72  case 7: {
73  m_text->SetElementType(TYPE_SYNC_MOTOR);
74  } break;
75  case 8: {
76  m_text->SetElementType(TYPE_IND_MOTOR);
77  } break;
78 
79  default:
80  break;
81  }
82 
83  ElementTypeChoice();
84 }
85 
86 void TextForm::OnFromBusChoiceSelected(wxCommandEvent& event)
87 {
88  m_text->SetDirection(m_choiceTextFromBus->GetSelection());
89  m_choiceTextToBus->SetSelection(m_choiceTextFromBus->GetSelection());
90 }
91 
92 void TextForm::OnNameChoiceSelected(wxCommandEvent& event)
93 {
94  m_text->SetElementNumber(m_choiceName->GetSelection());
95  ElementNumberChoice();
96 }
97 
98 void TextForm::OnTextEnter(wxCommandEvent& event) { Preview(); }
99 void TextForm::OnToBusChoiceSelected(wxCommandEvent& event)
100 {
101  m_text->SetDirection(m_choiceTextToBus->GetSelection());
102  m_choiceTextFromBus->SetSelection(m_choiceTextToBus->GetSelection());
103 }
104 
105 void TextForm::OnUnitChoiceSelected(wxCommandEvent& event)
106 {
107  UnitChoice();
108  Preview();
109 }
110 
111 void TextForm::OnTypeChoiceSelected(wxCommandEvent& event)
112 {
113  switch(m_text->GetElementType()) {
114  case TYPE_BUS: {
115  switch(m_choiceTextType->GetSelection()) {
116  case 0: {
117  m_text->SetDataType(DATA_NAME);
118  } break;
119  case 1: {
120  m_text->SetDataType(DATA_VOLTAGE);
121  } break;
122  case 2: {
123  m_text->SetDataType(DATA_ANGLE);
124  } break;
125  case 3: {
126  m_text->SetDataType(DATA_SC_CURRENT);
127  } break;
128  case 4: {
129  m_text->SetDataType(DATA_SC_VOLTAGE);
130  } break;
131  case 5: {
132  m_text->SetDataType(DATA_SC_POWER);
133  } break;
134  }
135  } break;
136  case TYPE_SYNC_GENERATOR: {
137  switch(m_choiceTextType->GetSelection()) {
138  case 0: {
139  m_text->SetDataType(DATA_NAME);
140  } break;
141  case 1: {
142  m_text->SetDataType(DATA_ACTIVE_POWER);
143  } break;
144  case 2: {
145  m_text->SetDataType(DATA_REACTIVE_POWER);
146  } break;
147  case 3: {
148  m_text->SetDataType(DATA_SC_CURRENT);
149  } break;
150  }
151  } break;
152  case TYPE_LINE:
153  case TYPE_TRANSFORMER: {
154  switch(m_choiceTextType->GetSelection()) {
155  case 0: {
156  m_text->SetDataType(DATA_NAME);
157  } break;
158  case 1: {
159  m_text->SetDataType(DATA_PF_ACTIVE);
160  } break;
161  case 2: {
162  m_text->SetDataType(DATA_PF_REACTIVE);
163  } break;
164  case 3: {
165  m_text->SetDataType(DATA_PF_LOSSES);
166  } break;
167  case 4: {
168  m_text->SetDataType(DATA_PF_CURRENT);
169  } break;
170  case 5: {
171  m_text->SetDataType(DATA_SC_CURRENT);
172  } break;
173  }
174  } break;
175  case TYPE_LOAD:
176  case TYPE_SYNC_MOTOR:
177  case TYPE_IND_MOTOR: {
178  switch(m_choiceTextType->GetSelection()) {
179  case 0: {
180  m_text->SetDataType(DATA_NAME);
181  } break;
182  case 1: {
183  m_text->SetDataType(DATA_ACTIVE_POWER);
184  } break;
185  case 2: {
186  m_text->SetDataType(DATA_REACTIVE_POWER);
187  } break;
188  }
189  } break;
190  case TYPE_CAPACITOR:
191  case TYPE_INDUCTOR: {
192  switch(m_choiceTextType->GetSelection()) {
193  case 0: {
194  m_text->SetDataType(DATA_NAME);
195  } break;
196  case 1: {
197  m_text->SetDataType(DATA_REACTIVE_POWER);
198  } break;
199  }
200  } break;
201  default:
202  break;
203  }
204  DataTypeChoice();
205 
206  if(m_text->GetDataType() == DATA_NAME) Preview();
207 }
208 
209 bool TextForm::LoadChoices()
210 {
211  if(m_text->GetElementType() == TYPE_NONE) return false;
212 
213  // Fill the element possible choices.
214  ElementTypeChoice();
215  m_choiceName->SetSelection(m_text->GetElementNumber());
216  ElementNumberChoice();
217  DataTypeChoice();
218 
219  // Select the saved choices.
220  switch(m_text->GetElementType()) {
221  case TYPE_BUS: {
222  m_choiceElement->SetSelection(0);
223  switch(m_text->GetDataType()) {
224  case DATA_NAME: {
225  m_choiceTextType->SetSelection(0);
226  } break;
227  case DATA_VOLTAGE: {
228  m_choiceTextType->SetSelection(1);
229  switch(m_text->GetUnit()) {
230  case UNIT_PU: {
231  m_choiceTextUnit->SetSelection(0);
232  } break;
233  case UNIT_V: {
234  m_choiceTextUnit->SetSelection(1);
235  } break;
236  case UNIT_kV: {
237  m_choiceTextUnit->SetSelection(2);
238  } break;
239  default:
240  break;
241  }
242 
243  } break;
244  case DATA_ANGLE: {
245  m_choiceTextType->SetSelection(2);
246  switch(m_text->GetUnit()) {
247  case UNIT_DEGREE: {
248  m_choiceTextUnit->SetSelection(0);
249  } break;
250  case UNIT_RADIAN: {
251  m_choiceTextUnit->SetSelection(1);
252  } break;
253  default:
254  break;
255  }
256  } break;
257  case DATA_SC_CURRENT: {
258  m_choiceTextType->SetSelection(3);
259  switch(m_text->GetUnit()) {
260  case UNIT_PU: {
261  m_choiceTextUnit->SetSelection(0);
262  } break;
263  case UNIT_A: {
264  m_choiceTextUnit->SetSelection(1);
265  } break;
266  case UNIT_kA: {
267  m_choiceTextUnit->SetSelection(2);
268  } break;
269  default:
270  break;
271  }
272  } break;
273  case DATA_SC_VOLTAGE: {
274  m_choiceTextType->SetSelection(4);
275  switch(m_text->GetUnit()) {
276  case UNIT_PU: {
277  m_choiceTextUnit->SetSelection(0);
278  } break;
279  case UNIT_V: {
280  m_choiceTextUnit->SetSelection(1);
281  } break;
282  case UNIT_kV: {
283  m_choiceTextUnit->SetSelection(2);
284  } break;
285  default:
286  break;
287  }
288  } break;
289  case DATA_SC_POWER: {
290  m_choiceTextType->SetSelection(5);
291  switch(m_text->GetUnit()) {
292  case UNIT_PU: {
293  m_choiceTextUnit->SetSelection(0);
294  } break;
295  case UNIT_VA: {
296  m_choiceTextUnit->SetSelection(1);
297  } break;
298  case UNIT_kVA: {
299  m_choiceTextUnit->SetSelection(2);
300  } break;
301  case UNIT_MVA: {
302  m_choiceTextUnit->SetSelection(3);
303  } break;
304  default:
305  break;
306  }
307  } break;
308  default:
309  break;
310  }
311  } break;
312  case TYPE_SYNC_GENERATOR: {
313  m_choiceElement->SetSelection(1);
314  switch(m_text->GetDataType()) {
315  case DATA_NAME: {
316  m_choiceTextType->SetSelection(0);
317  } break;
318  case DATA_ACTIVE_POWER: {
319  m_choiceTextType->SetSelection(1);
320  switch(m_text->GetUnit()) {
321  case UNIT_PU: {
322  m_choiceTextUnit->SetSelection(0);
323  } break;
324  case UNIT_W: {
325  m_choiceTextUnit->SetSelection(1);
326  } break;
327  case UNIT_kW: {
328  m_choiceTextUnit->SetSelection(2);
329  } break;
330  case UNIT_MW: {
331  m_choiceTextUnit->SetSelection(3);
332  } break;
333  default:
334  break;
335  }
336  } break;
337  case DATA_REACTIVE_POWER: {
338  m_choiceTextType->SetSelection(2);
339  switch(m_text->GetUnit()) {
340  case UNIT_PU: {
341  m_choiceTextUnit->SetSelection(0);
342  } break;
343  case UNIT_VAr: {
344  m_choiceTextUnit->SetSelection(1);
345  } break;
346  case UNIT_kVAr: {
347  m_choiceTextUnit->SetSelection(2);
348  } break;
349  case UNIT_MVAr: {
350  m_choiceTextUnit->SetSelection(3);
351  } break;
352  default:
353  break;
354  }
355  } break;
356  case DATA_SC_CURRENT: {
357  m_choiceTextType->SetSelection(3);
358  switch(m_text->GetUnit()) {
359  case UNIT_PU: {
360  m_choiceTextUnit->SetSelection(0);
361  } break;
362  case UNIT_A: {
363  m_choiceTextUnit->SetSelection(1);
364  } break;
365  case UNIT_kA: {
366  m_choiceTextUnit->SetSelection(2);
367  } break;
368  default:
369  break;
370  }
371  } break;
372  default:
373  break;
374  }
375  } break;
376  case TYPE_LINE: {
377  m_choiceElement->SetSelection(2);
378  switch(m_text->GetDataType()) {
379  case DATA_NAME: {
380  m_choiceTextType->SetSelection(0);
381  } break;
382  case DATA_PF_ACTIVE: {
383  m_choiceTextType->SetSelection(1);
384  switch(m_text->GetUnit()) {
385  case UNIT_PU: {
386  m_choiceTextUnit->SetSelection(0);
387  } break;
388  case UNIT_W: {
389  m_choiceTextUnit->SetSelection(1);
390  } break;
391  case UNIT_kW: {
392  m_choiceTextUnit->SetSelection(2);
393  } break;
394  case UNIT_MW: {
395  m_choiceTextUnit->SetSelection(3);
396  } break;
397  default:
398  break;
399  }
400  } break;
401  case DATA_PF_REACTIVE: {
402  m_choiceTextType->SetSelection(2);
403  switch(m_text->GetUnit()) {
404  case UNIT_PU: {
405  m_choiceTextUnit->SetSelection(0);
406  } break;
407  case UNIT_VAr: {
408  m_choiceTextUnit->SetSelection(1);
409  } break;
410  case UNIT_kVAr: {
411  m_choiceTextUnit->SetSelection(2);
412  } break;
413  case UNIT_MVAr: {
414  m_choiceTextUnit->SetSelection(3);
415  } break;
416  default:
417  break;
418  }
419  } break;
420  case DATA_PF_LOSSES: {
421  m_choiceTextType->SetSelection(3);
422  switch(m_text->GetUnit()) {
423  case UNIT_PU: {
424  m_choiceTextUnit->SetSelection(0);
425  } break;
426  case UNIT_W: {
427  m_choiceTextUnit->SetSelection(1);
428  } break;
429  case UNIT_kW: {
430  m_choiceTextUnit->SetSelection(2);
431  } break;
432  case UNIT_MW: {
433  m_choiceTextUnit->SetSelection(3);
434  } break;
435  default:
436  break;
437  }
438  } break;
439  case DATA_PF_CURRENT: {
440  m_choiceTextType->SetSelection(4);
441  switch(m_text->GetUnit()) {
442  case UNIT_PU: {
443  m_choiceTextUnit->SetSelection(0);
444  } break;
445  case UNIT_A: {
446  m_choiceTextUnit->SetSelection(1);
447  } break;
448  case UNIT_kA: {
449  m_choiceTextUnit->SetSelection(2);
450  } break;
451  default:
452  break;
453  }
454  } break;
455  case DATA_SC_CURRENT: {
456  m_choiceTextType->SetSelection(5);
457  switch(m_text->GetUnit()) {
458  case UNIT_PU: {
459  m_choiceTextUnit->SetSelection(0);
460  } break;
461  case UNIT_A: {
462  m_choiceTextUnit->SetSelection(1);
463  } break;
464  case UNIT_kA: {
465  m_choiceTextUnit->SetSelection(2);
466  } break;
467  case UNIT_MW: {
468  m_choiceTextUnit->SetSelection(3);
469  } break;
470  default:
471  break;
472  }
473  } break;
474  default:
475  break;
476  }
477  } break;
478  case TYPE_TRANSFORMER: {
479  m_choiceElement->SetSelection(3);
480  switch(m_text->GetDataType()) {
481  case DATA_NAME: {
482  m_choiceTextType->SetSelection(0);
483  } break;
484  case DATA_PF_ACTIVE: {
485  m_choiceTextType->SetSelection(1);
486  switch(m_text->GetUnit()) {
487  case UNIT_PU: {
488  m_choiceTextUnit->SetSelection(0);
489  } break;
490  case UNIT_W: {
491  m_choiceTextUnit->SetSelection(1);
492  } break;
493  case UNIT_kW: {
494  m_choiceTextUnit->SetSelection(2);
495  } break;
496  case UNIT_MW: {
497  m_choiceTextUnit->SetSelection(3);
498  } break;
499  default:
500  break;
501  }
502  } break;
503  case DATA_PF_REACTIVE: {
504  m_choiceTextType->SetSelection(2);
505  switch(m_text->GetUnit()) {
506  case UNIT_PU: {
507  m_choiceTextUnit->SetSelection(0);
508  } break;
509  case UNIT_VAr: {
510  m_choiceTextUnit->SetSelection(1);
511  } break;
512  case UNIT_kVAr: {
513  m_choiceTextUnit->SetSelection(2);
514  } break;
515  case UNIT_MVAr: {
516  m_choiceTextUnit->SetSelection(3);
517  } break;
518  default:
519  break;
520  }
521  } break;
522  case DATA_PF_LOSSES: {
523  m_choiceTextType->SetSelection(3);
524  switch(m_text->GetUnit()) {
525  case UNIT_PU: {
526  m_choiceTextUnit->SetSelection(0);
527  } break;
528  case UNIT_W: {
529  m_choiceTextUnit->SetSelection(1);
530  } break;
531  case UNIT_kW: {
532  m_choiceTextUnit->SetSelection(2);
533  } break;
534  case UNIT_MW: {
535  m_choiceTextUnit->SetSelection(3);
536  } break;
537  default:
538  break;
539  }
540  } break;
541  case DATA_PF_CURRENT: {
542  m_choiceTextType->SetSelection(4);
543  switch(m_text->GetUnit()) {
544  case UNIT_PU: {
545  m_choiceTextUnit->SetSelection(0);
546  } break;
547  case UNIT_A: {
548  m_choiceTextUnit->SetSelection(1);
549  } break;
550  case UNIT_kA: {
551  m_choiceTextUnit->SetSelection(2);
552  } break;
553  default:
554  break;
555  }
556  } break;
557  case DATA_SC_CURRENT: {
558  m_choiceTextType->SetSelection(5);
559  switch(m_text->GetUnit()) {
560  case UNIT_PU: {
561  m_choiceTextUnit->SetSelection(0);
562  } break;
563  case UNIT_A: {
564  m_choiceTextUnit->SetSelection(1);
565  } break;
566  case UNIT_kA: {
567  m_choiceTextUnit->SetSelection(2);
568  } break;
569  default:
570  break;
571  }
572  } break;
573  default:
574  break;
575  }
576  } break;
577  case TYPE_LOAD: {
578  m_choiceElement->SetSelection(4);
579  switch(m_text->GetDataType()) {
580  case DATA_NAME: {
581  m_choiceTextType->SetSelection(0);
582  } break;
583  case DATA_ACTIVE_POWER: {
584  m_choiceTextType->SetSelection(1);
585  switch(m_text->GetUnit()) {
586  case UNIT_PU: {
587  m_choiceTextUnit->SetSelection(0);
588  } break;
589  case UNIT_W: {
590  m_choiceTextUnit->SetSelection(1);
591  } break;
592  case UNIT_kW: {
593  m_choiceTextUnit->SetSelection(2);
594  } break;
595  case UNIT_MW: {
596  m_choiceTextUnit->SetSelection(3);
597  } break;
598  default:
599  break;
600  }
601  } break;
602  case DATA_REACTIVE_POWER: {
603  m_choiceTextType->SetSelection(2);
604  switch(m_text->GetUnit()) {
605  case UNIT_PU: {
606  m_choiceTextUnit->SetSelection(0);
607  } break;
608  case UNIT_VAr: {
609  m_choiceTextUnit->SetSelection(1);
610  } break;
611  case UNIT_kVAr: {
612  m_choiceTextUnit->SetSelection(2);
613  } break;
614  case UNIT_MVAr: {
615  m_choiceTextUnit->SetSelection(3);
616  } break;
617  default:
618  break;
619  }
620  } break;
621  default:
622  break;
623  }
624  } break;
625  case TYPE_CAPACITOR: {
626  m_choiceElement->SetSelection(5);
627  switch(m_text->GetDataType()) {
628  case DATA_NAME: {
629  m_choiceTextType->SetSelection(0);
630  } break;
631  case DATA_REACTIVE_POWER: {
632  m_choiceTextType->SetSelection(1);
633 
634  } break;
635  default:
636  break;
637  }
638  } break;
639  case TYPE_INDUCTOR: {
640  m_choiceElement->SetSelection(6);
641  switch(m_text->GetDataType()) {
642  case DATA_NAME: {
643  m_choiceTextType->SetSelection(0);
644  } break;
645  case DATA_REACTIVE_POWER: {
646  m_choiceTextType->SetSelection(1);
647  switch(m_text->GetUnit()) {
648  case UNIT_PU: {
649  m_choiceTextUnit->SetSelection(0);
650  } break;
651  case UNIT_VAr: {
652  m_choiceTextUnit->SetSelection(1);
653  } break;
654  case UNIT_kVAr: {
655  m_choiceTextUnit->SetSelection(2);
656  } break;
657  case UNIT_MVAr: {
658  m_choiceTextUnit->SetSelection(3);
659  } break;
660  default:
661  break;
662  }
663  } break;
664  default:
665  break;
666  }
667  } break;
668  case TYPE_SYNC_MOTOR: {
669  m_choiceElement->SetSelection(7);
670  switch(m_text->GetDataType()) {
671  case DATA_NAME: {
672  m_choiceTextType->SetSelection(0);
673  } break;
674  case DATA_ACTIVE_POWER: {
675  m_choiceTextType->SetSelection(1);
676  switch(m_text->GetUnit()) {
677  case UNIT_PU: {
678  m_choiceTextUnit->SetSelection(0);
679  } break;
680  case UNIT_W: {
681  m_choiceTextUnit->SetSelection(1);
682  } break;
683  case UNIT_kW: {
684  m_choiceTextUnit->SetSelection(2);
685  } break;
686  case UNIT_MW: {
687  m_choiceTextUnit->SetSelection(3);
688  } break;
689  default:
690  break;
691  }
692  } break;
693  case DATA_REACTIVE_POWER: {
694  m_choiceTextType->SetSelection(2);
695  switch(m_text->GetUnit()) {
696  case UNIT_PU: {
697  m_choiceTextUnit->SetSelection(0);
698  } break;
699  case UNIT_VAr: {
700  m_choiceTextUnit->SetSelection(1);
701  } break;
702  case UNIT_kVAr: {
703  m_choiceTextUnit->SetSelection(2);
704  } break;
705  case UNIT_MVAr: {
706  m_choiceTextUnit->SetSelection(3);
707  } break;
708  default:
709  break;
710  }
711  } break;
712  default:
713  break;
714  }
715  } break;
716  case TYPE_IND_MOTOR: {
717  m_choiceElement->SetSelection(8);
718  switch(m_text->GetDataType()) {
719  case DATA_NAME: {
720  m_choiceTextType->SetSelection(0);
721  } break;
722  case DATA_ACTIVE_POWER: {
723  m_choiceTextType->SetSelection(1);
724  switch(m_text->GetUnit()) {
725  case UNIT_PU: {
726  m_choiceTextUnit->SetSelection(0);
727  } break;
728  case UNIT_W: {
729  m_choiceTextUnit->SetSelection(1);
730  } break;
731  case UNIT_kW: {
732  m_choiceTextUnit->SetSelection(2);
733  } break;
734  case UNIT_MW: {
735  m_choiceTextUnit->SetSelection(3);
736  } break;
737  default:
738  break;
739  }
740  } break;
741  case DATA_REACTIVE_POWER: {
742  m_choiceTextType->SetSelection(2);
743  switch(m_text->GetUnit()) {
744  case UNIT_PU: {
745  m_choiceTextUnit->SetSelection(0);
746  } break;
747  case UNIT_VAr: {
748  m_choiceTextUnit->SetSelection(1);
749  } break;
750  case UNIT_kVAr: {
751  m_choiceTextUnit->SetSelection(2);
752  } break;
753  case UNIT_MVAr: {
754  m_choiceTextUnit->SetSelection(3);
755  } break;
756  default:
757  break;
758  }
759  } break;
760  default:
761  break;
762  }
763  } break;
764  default:
765  break;
766  }
767 
768  if(m_choiceTextFromBus->IsEnabled()) m_choiceTextFromBus->SetSelection(m_text->GetDirection());
769  if(m_choiceTextToBus->IsEnabled()) m_choiceTextToBus->SetSelection(m_text->GetDirection());
770 
771  m_textCtrlDecimal->SetValue(wxString::Format("%d", m_text->GetDecimalPlaces()));
772  Preview();
773 
774  return true;
775 }
776 
777 void TextForm::ElementTypeChoice()
778 {
779  m_choiceTextType->Enable(false);
780  m_choiceTextFromBus->Enable(false);
781  m_choiceTextToBus->Enable(false);
782  m_choiceTextUnit->Enable(false);
783  m_choiceTextType->Clear();
784  m_choiceTextFromBus->Clear();
785  m_choiceTextToBus->Clear();
786  m_choiceTextUnit->Clear();
787 
788  m_choiceName->Clear();
789  wxArrayString arrayString;
790  switch(m_text->GetElementType()) {
791  case TYPE_BUS: {
792  for(int i = 0; i < (int)m_allElements.GetBusList().size(); i++) {
793  Bus* bus = m_allElements.GetBusList()[i];
794  arrayString.Add(bus->GetElectricalData().name);
795  }
796  } break;
797  case TYPE_SYNC_GENERATOR: {
798  for(int i = 0; i < (int)m_allElements.GetSyncGeneratorList().size(); i++) {
799  SyncGenerator* syncGenerator = m_allElements.GetSyncGeneratorList()[i];
800  arrayString.Add(syncGenerator->GetElectricalData().name);
801  }
802  } break;
803  case TYPE_LINE: {
804  for(int i = 0; i < (int)m_allElements.GetLineList().size(); i++) {
805  Line* line = m_allElements.GetLineList()[i];
806  arrayString.Add(line->GetElectricalData().name);
807  }
808  } break;
809  case TYPE_TRANSFORMER: {
810  for(int i = 0; i < (int)m_allElements.GetTransformerList().size(); i++) {
811  Transformer* transformer = m_allElements.GetTransformerList()[i];
812  arrayString.Add(transformer->GetElectricalData().name);
813  }
814  } break;
815  case TYPE_LOAD: {
816  for(int i = 0; i < (int)m_allElements.GetLoadList().size(); i++) {
817  Load* load = m_allElements.GetLoadList()[i];
818  arrayString.Add(load->GetElectricalData().name);
819  }
820  } break;
821  case TYPE_CAPACITOR: {
822  for(int i = 0; i < (int)m_allElements.GetCapacitorList().size(); i++) {
823  Capacitor* capacitor = m_allElements.GetCapacitorList()[i];
824  arrayString.Add(capacitor->GetElectricalData().name);
825  }
826  } break;
827  case TYPE_INDUCTOR: {
828  for(int i = 0; i < (int)m_allElements.GetInductorList().size(); i++) {
829  Inductor* inductor = m_allElements.GetInductorList()[i];
830  arrayString.Add(inductor->GetElectricalData().name);
831  }
832  } break;
833  case TYPE_SYNC_MOTOR: {
834  for(int i = 0; i < (int)m_allElements.GetSyncMotorList().size(); i++) {
835  SyncMotor* syncMotor = m_allElements.GetSyncMotorList()[i];
836  arrayString.Add(syncMotor->GetElectricalData().name);
837  }
838  } break;
839  case TYPE_IND_MOTOR: {
840  for(int i = 0; i < (int)m_allElements.GetIndMotorList().size(); i++) {
841  IndMotor* indMotor = m_allElements.GetIndMotorList()[i];
842  arrayString.Add(indMotor->GetElectricalData().name);
843  }
844  } break;
845 
846  default:
847  break;
848  }
849  m_choiceName->Append(arrayString);
850  m_choiceName->Enable();
851 }
852 
853 void TextForm::ElementNumberChoice()
854 {
855  m_choiceTextFromBus->Enable(false);
856  m_choiceTextToBus->Enable(false);
857  m_choiceTextUnit->Enable(false);
858  m_choiceTextFromBus->Clear();
859  m_choiceTextToBus->Clear();
860  m_choiceTextUnit->Clear();
861 
862  int index = m_choiceName->GetSelection();
863  m_text->SetElementNumber(index);
864 
865  m_choiceTextType->Clear();
866  wxArrayString arrayString;
867  switch(m_text->GetElementType()) {
868  case TYPE_BUS: {
869  Bus* bus = m_allElements.GetBusList()[index];
870  m_text->SetElement(bus);
871 
872  arrayString.Add(_("Name"));
873  arrayString.Add(_("Voltage"));
874  arrayString.Add(_("Angle"));
875  arrayString.Add(_("Fault current"));
876  arrayString.Add(_("Fault voltage"));
877  arrayString.Add(_("Short-circuit power"));
878  } break;
879  case TYPE_SYNC_GENERATOR: {
880  SyncGenerator* syncGenerator = m_allElements.GetSyncGeneratorList()[index];
881  m_text->SetElement(syncGenerator);
882 
883  arrayString.Add(_("Name"));
884  arrayString.Add(_("Active power"));
885  arrayString.Add(_("Reactive power"));
886  arrayString.Add(_("Fault current"));
887  } break;
888  case TYPE_LINE: {
889  Line* line = m_allElements.GetLineList()[index];
890  m_text->SetElement(line);
891 
892  arrayString.Add(_("Name"));
893  arrayString.Add(_("Active power flow"));
894  arrayString.Add(_("Reactive power flow"));
895  arrayString.Add(_("Losses"));
896  arrayString.Add(_("Current"));
897  arrayString.Add(_("Fault current"));
898  } break;
899  case TYPE_TRANSFORMER: {
900  Transformer* transformer = m_allElements.GetTransformerList()[index];
901  m_text->SetElement(transformer);
902 
903  arrayString.Add(_("Name"));
904  arrayString.Add(_("Active power flow"));
905  arrayString.Add(_("Reactive power flow"));
906  arrayString.Add(_("Losses"));
907  arrayString.Add(_("Current"));
908  arrayString.Add(_("Fault current"));
909  } break;
910  case TYPE_LOAD: {
911  Load* load = m_allElements.GetLoadList()[index];
912  m_text->SetElement(load);
913 
914  arrayString.Add(_("Name"));
915  arrayString.Add(_("Active power"));
916  arrayString.Add(_("Reactive power"));
917  } break;
918  case TYPE_CAPACITOR: {
919  Capacitor* capacitor = m_allElements.GetCapacitorList()[index];
920  m_text->SetElement(capacitor);
921 
922  arrayString.Add(_("Name"));
923  arrayString.Add(_("Reactive power"));
924  } break;
925  case TYPE_INDUCTOR: {
926  Inductor* inductor = m_allElements.GetInductorList()[index];
927  m_text->SetElement(inductor);
928 
929  arrayString.Add(_("Name"));
930  arrayString.Add(_("Reactive power"));
931  } break;
932  case TYPE_SYNC_MOTOR: {
933  SyncMotor* syncMotor = m_allElements.GetSyncMotorList()[index];
934  m_text->SetElement(syncMotor);
935 
936  arrayString.Add(_("Name"));
937  arrayString.Add(_("Active power"));
938  arrayString.Add(_("Reactive power"));
939  } break;
940  case TYPE_IND_MOTOR: {
941  IndMotor* indMotor = m_allElements.GetIndMotorList()[index];
942  m_text->SetElement(indMotor);
943 
944  arrayString.Add(_("Name"));
945  arrayString.Add(_("Active power"));
946  arrayString.Add(_("Reactive power"));
947  } break;
948 
949  default:
950  break;
951  }
952  m_choiceTextType->Append(arrayString);
953  m_choiceTextType->Enable();
954 }
955 
956 void TextForm::DataTypeChoice()
957 {
958  m_choiceTextFromBus->Enable(false);
959  m_choiceTextToBus->Enable(false);
960 
961  m_choiceTextToBus->Clear();
962  m_choiceTextFromBus->Clear();
963  m_choiceTextUnit->Clear();
964 
965  m_choiceTextUnit->Enable();
966 
967  wxArrayString arrayString;
968  switch(m_text->GetDataType()) {
969  case DATA_NAME: {
970  m_choiceTextUnit->Enable(false);
971  return;
972  } break;
973  case DATA_VOLTAGE:
974  case DATA_SC_VOLTAGE: {
975  arrayString.Add(_("p.u."));
976  arrayString.Add(_("V"));
977  arrayString.Add(_("kV"));
978  } break;
979  case DATA_ANGLE: {
980  arrayString.Add(_("Degrees"));
981  arrayString.Add(_("Radians"));
982  } break;
983  case DATA_SC_CURRENT:
984  case DATA_PF_CURRENT: {
985  arrayString.Add(_("p.u."));
986  arrayString.Add(_("A"));
987  arrayString.Add(_("kA"));
988  } break;
989  case DATA_SC_POWER: {
990  arrayString.Add(_("p.u."));
991  arrayString.Add(_("VA"));
992  arrayString.Add(_("kVA"));
993  arrayString.Add(_("MVA"));
994  } break;
995  case DATA_ACTIVE_POWER:
996  case DATA_PF_ACTIVE:
997  case DATA_PF_LOSSES: {
998  arrayString.Add(_("p.u."));
999  arrayString.Add(_("W"));
1000  arrayString.Add(_("kW"));
1001  arrayString.Add(_("MW"));
1002  m_choiceTextUnit->Enable();
1003  } break;
1004  case DATA_REACTIVE_POWER:
1005  case DATA_PF_REACTIVE: {
1006  arrayString.Add(_("p.u."));
1007  arrayString.Add(_("VAr"));
1008  arrayString.Add(_("kVAr"));
1009  arrayString.Add(_("MVAr"));
1010  } break;
1011  default:
1012  break;
1013  }
1014  m_choiceTextUnit->Append(arrayString);
1015 
1016  switch(m_text->GetElementType()) {
1017  case TYPE_LINE: {
1018  if(m_text->GetDataType() != DATA_PF_LOSSES) {
1019  auto it = m_allElements.GetLineList().begin();
1020  std::advance(it, m_text->GetElementNumber());
1021  Line* line = *it;
1022 
1023  Bus* bus1 = static_cast<Bus*>(line->GetParentList()[0]);
1024  Bus* bus2 = static_cast<Bus*>(line->GetParentList()[1]);
1025  wxString bus1Name = bus1->GetElectricalData().name;
1026  wxString bus2Name = bus2->GetElectricalData().name;
1027 
1028  m_choiceTextFromBus->Append(bus1Name);
1029  m_choiceTextFromBus->Append(bus2Name);
1030  m_choiceTextToBus->Append(bus2Name);
1031  m_choiceTextToBus->Append(bus1Name);
1032  m_choiceTextFromBus->SetSelection(0);
1033  m_choiceTextToBus->SetSelection(0);
1034 
1035  m_choiceTextFromBus->Enable();
1036  m_choiceTextToBus->Enable();
1037  }
1038  } break;
1039  case TYPE_TRANSFORMER: {
1040  if(m_text->GetDataType() != DATA_PF_LOSSES) {
1041  auto it = m_allElements.GetTransformerList().begin();
1042  std::advance(it, m_text->GetElementNumber());
1043  Transformer* transformer = *it;
1044 
1045  Bus* bus1 = static_cast<Bus*>(transformer->GetParentList()[0]);
1046  Bus* bus2 = static_cast<Bus*>(transformer->GetParentList()[1]);
1047  wxString bus1Name = bus1->GetElectricalData().name;
1048  wxString bus2Name = bus2->GetElectricalData().name;
1049 
1050  m_choiceTextFromBus->Append(bus1Name);
1051  m_choiceTextFromBus->Append(bus2Name);
1052  m_choiceTextToBus->Append(bus2Name);
1053  m_choiceTextToBus->Append(bus1Name);
1054  m_choiceTextFromBus->SetSelection(0);
1055  m_choiceTextToBus->SetSelection(0);
1056 
1057  m_choiceTextFromBus->Enable();
1058  m_choiceTextToBus->Enable();
1059  }
1060  } break;
1061  default:
1062  break;
1063  }
1064 }
1065 
1066 void TextForm::UnitChoice()
1067 {
1068  switch(m_text->GetDataType()) {
1069  case DATA_NAME: {
1070  m_choiceTextUnit->Enable(false);
1071  return;
1072  } break;
1073  case DATA_VOLTAGE:
1074  case DATA_SC_VOLTAGE: {
1075  switch(m_choiceTextUnit->GetSelection()) {
1076  case 0: {
1077  m_text->SetUnit(UNIT_PU);
1078  } break;
1079  case 1: {
1080  m_text->SetUnit(UNIT_V);
1081  } break;
1082  case 2: {
1083  m_text->SetUnit(UNIT_kV);
1084  } break;
1085  default:
1086  break;
1087  }
1088  } break;
1089  case DATA_ANGLE: {
1090  switch(m_choiceTextUnit->GetSelection()) {
1091  case 0: {
1092  m_text->SetUnit(UNIT_DEGREE);
1093  } break;
1094  case 1: {
1095  m_text->SetUnit(UNIT_RADIAN);
1096  } break;
1097  default:
1098  break;
1099  }
1100  } break;
1101  case DATA_SC_CURRENT:
1102  case DATA_PF_CURRENT: {
1103  switch(m_choiceTextUnit->GetSelection()) {
1104  case 0: {
1105  m_text->SetUnit(UNIT_PU);
1106  } break;
1107  case 1: {
1108  m_text->SetUnit(UNIT_A);
1109  } break;
1110  case 2: {
1111  m_text->SetUnit(UNIT_kA);
1112  } break;
1113  default:
1114  break;
1115  }
1116  } break;
1117  case DATA_SC_POWER: {
1118  switch(m_choiceTextUnit->GetSelection()) {
1119  case 0: {
1120  m_text->SetUnit(UNIT_PU);
1121  } break;
1122  case 1: {
1123  m_text->SetUnit(UNIT_VA);
1124  } break;
1125  case 2: {
1126  m_text->SetUnit(UNIT_kVA);
1127  } break;
1128  case 3: {
1129  m_text->SetUnit(UNIT_MVA);
1130  } break;
1131  default:
1132  break;
1133  }
1134  } break;
1135  case DATA_ACTIVE_POWER:
1136  case DATA_PF_ACTIVE:
1137  case DATA_PF_LOSSES: {
1138  switch(m_choiceTextUnit->GetSelection()) {
1139  case 0: {
1140  m_text->SetUnit(UNIT_PU);
1141  } break;
1142  case 1: {
1143  m_text->SetUnit(UNIT_W);
1144  } break;
1145  case 2: {
1146  m_text->SetUnit(UNIT_kW);
1147  } break;
1148  case 3: {
1149  m_text->SetUnit(UNIT_MW);
1150  } break;
1151  default:
1152  break;
1153  }
1154  } break;
1155  case DATA_REACTIVE_POWER:
1156  case DATA_PF_REACTIVE: {
1157  switch(m_choiceTextUnit->GetSelection()) {
1158  case 0: {
1159  m_text->SetUnit(UNIT_PU);
1160  } break;
1161  case 1: {
1162  m_text->SetUnit(UNIT_VAr);
1163  } break;
1164  case 2: {
1165  m_text->SetUnit(UNIT_kVAr);
1166  } break;
1167  case 3: {
1168  m_text->SetUnit(UNIT_MVAr);
1169  } break;
1170  default:
1171  break;
1172  }
1173  } break;
1174  default:
1175  break;
1176  }
1177 }
1178 
1179 void TextForm::Preview()
1180 {
1181  double decimalPlaces = m_text->GetDecimalPlaces();
1182  if(m_textCtrlDecimal->GetValue().ToDouble(&decimalPlaces)) m_text->SetDecimalPlaces(decimalPlaces);
1183 
1184  m_text->UpdateText(m_systemPowerBase);
1185 
1186  m_textCtrlPreview->SetValue(m_text->GetText());
1187 }
1188 
1189 bool TextForm::ValidateData()
1190 {
1191  if(m_choiceElement->GetSelection() == -1) return false;
1192  if(m_choiceName->GetSelection() == -1) return false;
1193  if(m_choiceTextType->GetSelection() == -1) return false;
1194  if(m_text->GetDataType() != DATA_NAME && m_choiceTextUnit->GetSelection() == -1) return false;
1195  if(m_text->GetElementType() == TYPE_LINE || m_text->GetElementType() == TYPE_TRANSFORMER) {
1196  if(m_text->GetDataType() != DATA_PF_LOSSES && m_text->GetDataType() != DATA_NAME) {
1197  if(m_choiceTextFromBus->GetSelection() == -1) return false;
1198  if(m_choiceTextToBus->GetSelection() == -1) return false;
1199  }
1200  }
1201 
1202  if(m_choiceTextFromBus->IsEnabled() && m_choiceTextToBus->IsEnabled())
1203  m_text->SetDirection(m_choiceTextFromBus->GetSelection());
1204  double decimalPlaces = m_text->GetDecimalPlaces();
1205  if(m_textCtrlDecimal->GetValue().ToDouble(&decimalPlaces)) m_text->SetDecimalPlaces(decimalPlaces);
1206 
1207  m_textToEdit->SetElementType(m_text->GetElementType());
1208  m_textToEdit->SetElementNumber(m_text->GetElementNumber());
1209  m_textToEdit->SetElement(m_text->GetElement());
1210  m_textToEdit->SetDataType(m_text->GetDataType());
1211  m_textToEdit->SetDirection(m_text->GetDirection());
1212  m_textToEdit->SetUnit(m_text->GetUnit());
1213  m_textToEdit->SetDecimalPlaces(decimalPlaces);
1214  m_textToEdit->UpdateText(m_systemPowerBase);
1215 
1216  return true;
1217 }
1218 
1219 void TextForm::OnOKButtonClick(wxCommandEvent& event)
1220 {
1221  if(ValidateData()) {
1222  EndModal(wxID_OK);
1223  } else {
1224  wxString errorMsg = _("There are blank fields.");
1225  wxMessageDialog msgDialog(this, errorMsg, _("Error"), wxOK | wxCENTRE | wxICON_ERROR);
1226  msgDialog.ShowModal();
1227  }
1228 }
Element that shows power element informations in workspace.
Definition: Text.h:72
+
1 /*
2  * Copyright (C) 2017 Thales Lima Oliveira <thales@ufu.br>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program. If not, see <https://www.gnu.org/licenses/>.
16  */
17 
18 #include "TextForm.h"
19 
20 TextForm::TextForm(wxWindow* parent, Text* text, std::vector<Element*> elementList, double systemPowerBase)
21  : TextFormBase(parent)
22 {
23  SetSize(GetBestSize());
24  m_parent = parent;
25  m_textToEdit = text;
26  m_allElements.GetElementsFromList(elementList);
27  m_systemPowerBase = systemPowerBase;
28 
29  m_text = new Text();
30  m_text->SetElementType(text->GetElementType());
31  m_text->SetElementNumber(text->GetElementNumber());
32  m_text->SetElement(text->GetElement());
33  m_text->SetDataType(text->GetDataType());
34  m_text->SetDirection(text->GetDirection());
35  m_text->SetUnit(text->GetUnit());
36  m_text->SetDecimalPlaces(text->GetDecimalPlaces());
37 
38  if(!LoadChoices()) {
39  m_choiceName->Enable(false);
40  m_choiceTextType->Enable(false);
41  m_choiceTextFromBus->Enable(false);
42  m_choiceTextToBus->Enable(false);
43  m_choiceTextUnit->Enable(false);
44  }
45 }
46 
47 TextForm::~TextForm() {}
48 void TextForm::OnElementChoiceSelected(wxCommandEvent& event)
49 {
50  switch(m_choiceElement->GetSelection()) {
51  case 0: {
52  m_text->SetElementType(TYPE_BUS);
53  } break;
54  case 1: {
55  m_text->SetElementType(TYPE_SYNC_GENERATOR);
56  } break;
57  case 2: {
58  m_text->SetElementType(TYPE_LINE);
59  } break;
60  case 3: {
61  m_text->SetElementType(TYPE_TRANSFORMER);
62  } break;
63  case 4: {
64  m_text->SetElementType(TYPE_LOAD);
65  } break;
66  case 5: {
67  m_text->SetElementType(TYPE_CAPACITOR);
68  } break;
69  case 6: {
70  m_text->SetElementType(TYPE_INDUCTOR);
71  } break;
72  case 7: {
73  m_text->SetElementType(TYPE_SYNC_MOTOR);
74  } break;
75  case 8: {
76  m_text->SetElementType(TYPE_IND_MOTOR);
77  } break;
78 
79  default:
80  break;
81  }
82 
83  ElementTypeChoice();
84 }
85 
86 void TextForm::OnFromBusChoiceSelected(wxCommandEvent& event)
87 {
88  m_text->SetDirection(m_choiceTextFromBus->GetSelection());
89  m_choiceTextToBus->SetSelection(m_choiceTextFromBus->GetSelection());
90 }
91 
92 void TextForm::OnNameChoiceSelected(wxCommandEvent& event)
93 {
94  m_text->SetElementNumber(m_choiceName->GetSelection());
95  ElementNumberChoice();
96 }
97 
98 void TextForm::OnTextEnter(wxCommandEvent& event) { Preview(); }
99 void TextForm::OnToBusChoiceSelected(wxCommandEvent& event)
100 {
101  m_text->SetDirection(m_choiceTextToBus->GetSelection());
102  m_choiceTextFromBus->SetSelection(m_choiceTextToBus->GetSelection());
103 }
104 
105 void TextForm::OnUnitChoiceSelected(wxCommandEvent& event)
106 {
107  UnitChoice();
108  Preview();
109 }
110 
111 void TextForm::OnTypeChoiceSelected(wxCommandEvent& event)
112 {
113  switch(m_text->GetElementType()) {
114  case TYPE_BUS: {
115  switch(m_choiceTextType->GetSelection()) {
116  case 0: {
117  m_text->SetDataType(DATA_NAME);
118  } break;
119  case 1: {
120  m_text->SetDataType(DATA_VOLTAGE);
121  } break;
122  case 2: {
123  m_text->SetDataType(DATA_ANGLE);
124  } break;
125  case 3: {
126  m_text->SetDataType(DATA_SC_CURRENT);
127  } break;
128  case 4: {
129  m_text->SetDataType(DATA_SC_VOLTAGE);
130  } break;
131  case 5: {
132  m_text->SetDataType(DATA_SC_POWER);
133  } break;
134  }
135  } break;
136  case TYPE_SYNC_GENERATOR: {
137  switch(m_choiceTextType->GetSelection()) {
138  case 0: {
139  m_text->SetDataType(DATA_NAME);
140  } break;
141  case 1: {
142  m_text->SetDataType(DATA_ACTIVE_POWER);
143  } break;
144  case 2: {
145  m_text->SetDataType(DATA_REACTIVE_POWER);
146  } break;
147  case 3: {
148  m_text->SetDataType(DATA_SC_CURRENT);
149  } break;
150  }
151  } break;
152  case TYPE_LINE:
153  case TYPE_TRANSFORMER: {
154  switch(m_choiceTextType->GetSelection()) {
155  case 0: {
156  m_text->SetDataType(DATA_NAME);
157  } break;
158  case 1: {
159  m_text->SetDataType(DATA_PF_ACTIVE);
160  } break;
161  case 2: {
162  m_text->SetDataType(DATA_PF_REACTIVE);
163  } break;
164  case 3: {
165  m_text->SetDataType(DATA_PF_LOSSES);
166  } break;
167  case 4: {
168  m_text->SetDataType(DATA_PF_CURRENT);
169  } break;
170  case 5: {
171  m_text->SetDataType(DATA_SC_CURRENT);
172  } break;
173  }
174  } break;
175  case TYPE_LOAD:
176  case TYPE_SYNC_MOTOR:
177  case TYPE_IND_MOTOR: {
178  switch(m_choiceTextType->GetSelection()) {
179  case 0: {
180  m_text->SetDataType(DATA_NAME);
181  } break;
182  case 1: {
183  m_text->SetDataType(DATA_ACTIVE_POWER);
184  } break;
185  case 2: {
186  m_text->SetDataType(DATA_REACTIVE_POWER);
187  } break;
188  }
189  } break;
190  case TYPE_CAPACITOR:
191  case TYPE_INDUCTOR: {
192  switch(m_choiceTextType->GetSelection()) {
193  case 0: {
194  m_text->SetDataType(DATA_NAME);
195  } break;
196  case 1: {
197  m_text->SetDataType(DATA_REACTIVE_POWER);
198  } break;
199  }
200  } break;
201  default:
202  break;
203  }
204  DataTypeChoice();
205 
206  if(m_text->GetDataType() == DATA_NAME) Preview();
207 }
208 
209 bool TextForm::LoadChoices()
210 {
211  if(m_text->GetElementType() == TYPE_NONE) return false;
212 
213  // Fill the element possible choices.
214  ElementTypeChoice();
215  m_choiceName->SetSelection(m_text->GetElementNumber());
216  ElementNumberChoice();
217  DataTypeChoice();
218 
219  // Select the saved choices.
220  switch(m_text->GetElementType()) {
221  case TYPE_BUS: {
222  m_choiceElement->SetSelection(0);
223  switch(m_text->GetDataType()) {
224  case DATA_NAME: {
225  m_choiceTextType->SetSelection(0);
226  } break;
227  case DATA_VOLTAGE: {
228  m_choiceTextType->SetSelection(1);
229  switch(m_text->GetUnit()) {
230  case UNIT_PU: {
231  m_choiceTextUnit->SetSelection(0);
232  } break;
233  case UNIT_V: {
234  m_choiceTextUnit->SetSelection(1);
235  } break;
236  case UNIT_kV: {
237  m_choiceTextUnit->SetSelection(2);
238  } break;
239  default:
240  break;
241  }
242 
243  } break;
244  case DATA_ANGLE: {
245  m_choiceTextType->SetSelection(2);
246  switch(m_text->GetUnit()) {
247  case UNIT_DEGREE: {
248  m_choiceTextUnit->SetSelection(0);
249  } break;
250  case UNIT_RADIAN: {
251  m_choiceTextUnit->SetSelection(1);
252  } break;
253  default:
254  break;
255  }
256  } break;
257  case DATA_SC_CURRENT: {
258  m_choiceTextType->SetSelection(3);
259  switch(m_text->GetUnit()) {
260  case UNIT_PU: {
261  m_choiceTextUnit->SetSelection(0);
262  } break;
263  case UNIT_A: {
264  m_choiceTextUnit->SetSelection(1);
265  } break;
266  case UNIT_kA: {
267  m_choiceTextUnit->SetSelection(2);
268  } break;
269  default:
270  break;
271  }
272  } break;
273  case DATA_SC_VOLTAGE: {
274  m_choiceTextType->SetSelection(4);
275  switch(m_text->GetUnit()) {
276  case UNIT_PU: {
277  m_choiceTextUnit->SetSelection(0);
278  } break;
279  case UNIT_V: {
280  m_choiceTextUnit->SetSelection(1);
281  } break;
282  case UNIT_kV: {
283  m_choiceTextUnit->SetSelection(2);
284  } break;
285  default:
286  break;
287  }
288  } break;
289  case DATA_SC_POWER: {
290  m_choiceTextType->SetSelection(5);
291  switch(m_text->GetUnit()) {
292  case UNIT_PU: {
293  m_choiceTextUnit->SetSelection(0);
294  } break;
295  case UNIT_VA: {
296  m_choiceTextUnit->SetSelection(1);
297  } break;
298  case UNIT_kVA: {
299  m_choiceTextUnit->SetSelection(2);
300  } break;
301  case UNIT_MVA: {
302  m_choiceTextUnit->SetSelection(3);
303  } break;
304  default:
305  break;
306  }
307  } break;
308  default:
309  break;
310  }
311  } break;
312  case TYPE_SYNC_GENERATOR: {
313  m_choiceElement->SetSelection(1);
314  switch(m_text->GetDataType()) {
315  case DATA_NAME: {
316  m_choiceTextType->SetSelection(0);
317  } break;
318  case DATA_ACTIVE_POWER: {
319  m_choiceTextType->SetSelection(1);
320  switch(m_text->GetUnit()) {
321  case UNIT_PU: {
322  m_choiceTextUnit->SetSelection(0);
323  } break;
324  case UNIT_W: {
325  m_choiceTextUnit->SetSelection(1);
326  } break;
327  case UNIT_kW: {
328  m_choiceTextUnit->SetSelection(2);
329  } break;
330  case UNIT_MW: {
331  m_choiceTextUnit->SetSelection(3);
332  } break;
333  default:
334  break;
335  }
336  } break;
337  case DATA_REACTIVE_POWER: {
338  m_choiceTextType->SetSelection(2);
339  switch(m_text->GetUnit()) {
340  case UNIT_PU: {
341  m_choiceTextUnit->SetSelection(0);
342  } break;
343  case UNIT_VAr: {
344  m_choiceTextUnit->SetSelection(1);
345  } break;
346  case UNIT_kVAr: {
347  m_choiceTextUnit->SetSelection(2);
348  } break;
349  case UNIT_MVAr: {
350  m_choiceTextUnit->SetSelection(3);
351  } break;
352  default:
353  break;
354  }
355  } break;
356  case DATA_SC_CURRENT: {
357  m_choiceTextType->SetSelection(3);
358  switch(m_text->GetUnit()) {
359  case UNIT_PU: {
360  m_choiceTextUnit->SetSelection(0);
361  } break;
362  case UNIT_A: {
363  m_choiceTextUnit->SetSelection(1);
364  } break;
365  case UNIT_kA: {
366  m_choiceTextUnit->SetSelection(2);
367  } break;
368  default:
369  break;
370  }
371  } break;
372  default:
373  break;
374  }
375  } break;
376  case TYPE_LINE: {
377  m_choiceElement->SetSelection(2);
378  switch(m_text->GetDataType()) {
379  case DATA_NAME: {
380  m_choiceTextType->SetSelection(0);
381  } break;
382  case DATA_PF_ACTIVE: {
383  m_choiceTextType->SetSelection(1);
384  switch(m_text->GetUnit()) {
385  case UNIT_PU: {
386  m_choiceTextUnit->SetSelection(0);
387  } break;
388  case UNIT_W: {
389  m_choiceTextUnit->SetSelection(1);
390  } break;
391  case UNIT_kW: {
392  m_choiceTextUnit->SetSelection(2);
393  } break;
394  case UNIT_MW: {
395  m_choiceTextUnit->SetSelection(3);
396  } break;
397  default:
398  break;
399  }
400  } break;
401  case DATA_PF_REACTIVE: {
402  m_choiceTextType->SetSelection(2);
403  switch(m_text->GetUnit()) {
404  case UNIT_PU: {
405  m_choiceTextUnit->SetSelection(0);
406  } break;
407  case UNIT_VAr: {
408  m_choiceTextUnit->SetSelection(1);
409  } break;
410  case UNIT_kVAr: {
411  m_choiceTextUnit->SetSelection(2);
412  } break;
413  case UNIT_MVAr: {
414  m_choiceTextUnit->SetSelection(3);
415  } break;
416  default:
417  break;
418  }
419  } break;
420  case DATA_PF_LOSSES: {
421  m_choiceTextType->SetSelection(3);
422  switch(m_text->GetUnit()) {
423  case UNIT_PU: {
424  m_choiceTextUnit->SetSelection(0);
425  } break;
426  case UNIT_W: {
427  m_choiceTextUnit->SetSelection(1);
428  } break;
429  case UNIT_kW: {
430  m_choiceTextUnit->SetSelection(2);
431  } break;
432  case UNIT_MW: {
433  m_choiceTextUnit->SetSelection(3);
434  } break;
435  default:
436  break;
437  }
438  } break;
439  case DATA_PF_CURRENT: {
440  m_choiceTextType->SetSelection(4);
441  switch(m_text->GetUnit()) {
442  case UNIT_PU: {
443  m_choiceTextUnit->SetSelection(0);
444  } break;
445  case UNIT_A: {
446  m_choiceTextUnit->SetSelection(1);
447  } break;
448  case UNIT_kA: {
449  m_choiceTextUnit->SetSelection(2);
450  } break;
451  default:
452  break;
453  }
454  } break;
455  case DATA_SC_CURRENT: {
456  m_choiceTextType->SetSelection(5);
457  switch(m_text->GetUnit()) {
458  case UNIT_PU: {
459  m_choiceTextUnit->SetSelection(0);
460  } break;
461  case UNIT_A: {
462  m_choiceTextUnit->SetSelection(1);
463  } break;
464  case UNIT_kA: {
465  m_choiceTextUnit->SetSelection(2);
466  } break;
467  case UNIT_MW: {
468  m_choiceTextUnit->SetSelection(3);
469  } break;
470  default:
471  break;
472  }
473  } break;
474  default:
475  break;
476  }
477  } break;
478  case TYPE_TRANSFORMER: {
479  m_choiceElement->SetSelection(3);
480  switch(m_text->GetDataType()) {
481  case DATA_NAME: {
482  m_choiceTextType->SetSelection(0);
483  } break;
484  case DATA_PF_ACTIVE: {
485  m_choiceTextType->SetSelection(1);
486  switch(m_text->GetUnit()) {
487  case UNIT_PU: {
488  m_choiceTextUnit->SetSelection(0);
489  } break;
490  case UNIT_W: {
491  m_choiceTextUnit->SetSelection(1);
492  } break;
493  case UNIT_kW: {
494  m_choiceTextUnit->SetSelection(2);
495  } break;
496  case UNIT_MW: {
497  m_choiceTextUnit->SetSelection(3);
498  } break;
499  default:
500  break;
501  }
502  } break;
503  case DATA_PF_REACTIVE: {
504  m_choiceTextType->SetSelection(2);
505  switch(m_text->GetUnit()) {
506  case UNIT_PU: {
507  m_choiceTextUnit->SetSelection(0);
508  } break;
509  case UNIT_VAr: {
510  m_choiceTextUnit->SetSelection(1);
511  } break;
512  case UNIT_kVAr: {
513  m_choiceTextUnit->SetSelection(2);
514  } break;
515  case UNIT_MVAr: {
516  m_choiceTextUnit->SetSelection(3);
517  } break;
518  default:
519  break;
520  }
521  } break;
522  case DATA_PF_LOSSES: {
523  m_choiceTextType->SetSelection(3);
524  switch(m_text->GetUnit()) {
525  case UNIT_PU: {
526  m_choiceTextUnit->SetSelection(0);
527  } break;
528  case UNIT_W: {
529  m_choiceTextUnit->SetSelection(1);
530  } break;
531  case UNIT_kW: {
532  m_choiceTextUnit->SetSelection(2);
533  } break;
534  case UNIT_MW: {
535  m_choiceTextUnit->SetSelection(3);
536  } break;
537  default:
538  break;
539  }
540  } break;
541  case DATA_PF_CURRENT: {
542  m_choiceTextType->SetSelection(4);
543  switch(m_text->GetUnit()) {
544  case UNIT_PU: {
545  m_choiceTextUnit->SetSelection(0);
546  } break;
547  case UNIT_A: {
548  m_choiceTextUnit->SetSelection(1);
549  } break;
550  case UNIT_kA: {
551  m_choiceTextUnit->SetSelection(2);
552  } break;
553  default:
554  break;
555  }
556  } break;
557  case DATA_SC_CURRENT: {
558  m_choiceTextType->SetSelection(5);
559  switch(m_text->GetUnit()) {
560  case UNIT_PU: {
561  m_choiceTextUnit->SetSelection(0);
562  } break;
563  case UNIT_A: {
564  m_choiceTextUnit->SetSelection(1);
565  } break;
566  case UNIT_kA: {
567  m_choiceTextUnit->SetSelection(2);
568  } break;
569  default:
570  break;
571  }
572  } break;
573  default:
574  break;
575  }
576  } break;
577  case TYPE_LOAD: {
578  m_choiceElement->SetSelection(4);
579  switch(m_text->GetDataType()) {
580  case DATA_NAME: {
581  m_choiceTextType->SetSelection(0);
582  } break;
583  case DATA_ACTIVE_POWER: {
584  m_choiceTextType->SetSelection(1);
585  switch(m_text->GetUnit()) {
586  case UNIT_PU: {
587  m_choiceTextUnit->SetSelection(0);
588  } break;
589  case UNIT_W: {
590  m_choiceTextUnit->SetSelection(1);
591  } break;
592  case UNIT_kW: {
593  m_choiceTextUnit->SetSelection(2);
594  } break;
595  case UNIT_MW: {
596  m_choiceTextUnit->SetSelection(3);
597  } break;
598  default:
599  break;
600  }
601  } break;
602  case DATA_REACTIVE_POWER: {
603  m_choiceTextType->SetSelection(2);
604  switch(m_text->GetUnit()) {
605  case UNIT_PU: {
606  m_choiceTextUnit->SetSelection(0);
607  } break;
608  case UNIT_VAr: {
609  m_choiceTextUnit->SetSelection(1);
610  } break;
611  case UNIT_kVAr: {
612  m_choiceTextUnit->SetSelection(2);
613  } break;
614  case UNIT_MVAr: {
615  m_choiceTextUnit->SetSelection(3);
616  } break;
617  default:
618  break;
619  }
620  } break;
621  default:
622  break;
623  }
624  } break;
625  case TYPE_CAPACITOR: {
626  m_choiceElement->SetSelection(5);
627  switch(m_text->GetDataType()) {
628  case DATA_NAME: {
629  m_choiceTextType->SetSelection(0);
630  } break;
631  case DATA_REACTIVE_POWER: {
632  m_choiceTextType->SetSelection(1);
633 
634  } break;
635  default:
636  break;
637  }
638  } break;
639  case TYPE_INDUCTOR: {
640  m_choiceElement->SetSelection(6);
641  switch(m_text->GetDataType()) {
642  case DATA_NAME: {
643  m_choiceTextType->SetSelection(0);
644  } break;
645  case DATA_REACTIVE_POWER: {
646  m_choiceTextType->SetSelection(1);
647  switch(m_text->GetUnit()) {
648  case UNIT_PU: {
649  m_choiceTextUnit->SetSelection(0);
650  } break;
651  case UNIT_VAr: {
652  m_choiceTextUnit->SetSelection(1);
653  } break;
654  case UNIT_kVAr: {
655  m_choiceTextUnit->SetSelection(2);
656  } break;
657  case UNIT_MVAr: {
658  m_choiceTextUnit->SetSelection(3);
659  } break;
660  default:
661  break;
662  }
663  } break;
664  default:
665  break;
666  }
667  } break;
668  case TYPE_SYNC_MOTOR: {
669  m_choiceElement->SetSelection(7);
670  switch(m_text->GetDataType()) {
671  case DATA_NAME: {
672  m_choiceTextType->SetSelection(0);
673  } break;
674  case DATA_ACTIVE_POWER: {
675  m_choiceTextType->SetSelection(1);
676  switch(m_text->GetUnit()) {
677  case UNIT_PU: {
678  m_choiceTextUnit->SetSelection(0);
679  } break;
680  case UNIT_W: {
681  m_choiceTextUnit->SetSelection(1);
682  } break;
683  case UNIT_kW: {
684  m_choiceTextUnit->SetSelection(2);
685  } break;
686  case UNIT_MW: {
687  m_choiceTextUnit->SetSelection(3);
688  } break;
689  default:
690  break;
691  }
692  } break;
693  case DATA_REACTIVE_POWER: {
694  m_choiceTextType->SetSelection(2);
695  switch(m_text->GetUnit()) {
696  case UNIT_PU: {
697  m_choiceTextUnit->SetSelection(0);
698  } break;
699  case UNIT_VAr: {
700  m_choiceTextUnit->SetSelection(1);
701  } break;
702  case UNIT_kVAr: {
703  m_choiceTextUnit->SetSelection(2);
704  } break;
705  case UNIT_MVAr: {
706  m_choiceTextUnit->SetSelection(3);
707  } break;
708  default:
709  break;
710  }
711  } break;
712  default:
713  break;
714  }
715  } break;
716  case TYPE_IND_MOTOR: {
717  m_choiceElement->SetSelection(8);
718  switch(m_text->GetDataType()) {
719  case DATA_NAME: {
720  m_choiceTextType->SetSelection(0);
721  } break;
722  case DATA_ACTIVE_POWER: {
723  m_choiceTextType->SetSelection(1);
724  switch(m_text->GetUnit()) {
725  case UNIT_PU: {
726  m_choiceTextUnit->SetSelection(0);
727  } break;
728  case UNIT_W: {
729  m_choiceTextUnit->SetSelection(1);
730  } break;
731  case UNIT_kW: {
732  m_choiceTextUnit->SetSelection(2);
733  } break;
734  case UNIT_MW: {
735  m_choiceTextUnit->SetSelection(3);
736  } break;
737  default:
738  break;
739  }
740  } break;
741  case DATA_REACTIVE_POWER: {
742  m_choiceTextType->SetSelection(2);
743  switch(m_text->GetUnit()) {
744  case UNIT_PU: {
745  m_choiceTextUnit->SetSelection(0);
746  } break;
747  case UNIT_VAr: {
748  m_choiceTextUnit->SetSelection(1);
749  } break;
750  case UNIT_kVAr: {
751  m_choiceTextUnit->SetSelection(2);
752  } break;
753  case UNIT_MVAr: {
754  m_choiceTextUnit->SetSelection(3);
755  } break;
756  default:
757  break;
758  }
759  } break;
760  default:
761  break;
762  }
763  } break;
764  default:
765  break;
766  }
767 
768  if(m_choiceTextFromBus->IsEnabled()) m_choiceTextFromBus->SetSelection(m_text->GetDirection());
769  if(m_choiceTextToBus->IsEnabled()) m_choiceTextToBus->SetSelection(m_text->GetDirection());
770 
771  m_textCtrlDecimal->SetValue(wxString::Format("%d", m_text->GetDecimalPlaces()));
772  Preview();
773 
774  return true;
775 }
776 
777 void TextForm::ElementTypeChoice()
778 {
779  m_choiceTextType->Enable(false);
780  m_choiceTextFromBus->Enable(false);
781  m_choiceTextToBus->Enable(false);
782  m_choiceTextUnit->Enable(false);
783  m_choiceTextType->Clear();
784  m_choiceTextFromBus->Clear();
785  m_choiceTextToBus->Clear();
786  m_choiceTextUnit->Clear();
787 
788  m_choiceName->Clear();
789  wxArrayString arrayString;
790  switch(m_text->GetElementType()) {
791  case TYPE_BUS: {
792  for(int i = 0; i < (int)m_allElements.GetBusList().size(); i++) {
793  Bus* bus = m_allElements.GetBusList()[i];
794  arrayString.Add(bus->GetElectricalData().name);
795  }
796  } break;
797  case TYPE_SYNC_GENERATOR: {
798  for(int i = 0; i < (int)m_allElements.GetSyncGeneratorList().size(); i++) {
799  SyncGenerator* syncGenerator = m_allElements.GetSyncGeneratorList()[i];
800  arrayString.Add(syncGenerator->GetElectricalData().name);
801  }
802  } break;
803  case TYPE_LINE: {
804  for(int i = 0; i < (int)m_allElements.GetLineList().size(); i++) {
805  Line* line = m_allElements.GetLineList()[i];
806  arrayString.Add(line->GetElectricalData().name);
807  }
808  } break;
809  case TYPE_TRANSFORMER: {
810  for(int i = 0; i < (int)m_allElements.GetTransformerList().size(); i++) {
811  Transformer* transformer = m_allElements.GetTransformerList()[i];
812  arrayString.Add(transformer->GetElectricalData().name);
813  }
814  } break;
815  case TYPE_LOAD: {
816  for(int i = 0; i < (int)m_allElements.GetLoadList().size(); i++) {
817  Load* load = m_allElements.GetLoadList()[i];
818  arrayString.Add(load->GetElectricalData().name);
819  }
820  } break;
821  case TYPE_CAPACITOR: {
822  for(int i = 0; i < (int)m_allElements.GetCapacitorList().size(); i++) {
823  Capacitor* capacitor = m_allElements.GetCapacitorList()[i];
824  arrayString.Add(capacitor->GetElectricalData().name);
825  }
826  } break;
827  case TYPE_INDUCTOR: {
828  for(int i = 0; i < (int)m_allElements.GetInductorList().size(); i++) {
829  Inductor* inductor = m_allElements.GetInductorList()[i];
830  arrayString.Add(inductor->GetElectricalData().name);
831  }
832  } break;
833  case TYPE_SYNC_MOTOR: {
834  for(int i = 0; i < (int)m_allElements.GetSyncMotorList().size(); i++) {
835  SyncMotor* syncMotor = m_allElements.GetSyncMotorList()[i];
836  arrayString.Add(syncMotor->GetElectricalData().name);
837  }
838  } break;
839  case TYPE_IND_MOTOR: {
840  for(int i = 0; i < (int)m_allElements.GetIndMotorList().size(); i++) {
841  IndMotor* indMotor = m_allElements.GetIndMotorList()[i];
842  arrayString.Add(indMotor->GetElectricalData().name);
843  }
844  } break;
845 
846  default:
847  break;
848  }
849  m_choiceName->Append(arrayString);
850  m_choiceName->Enable();
851 }
852 
853 void TextForm::ElementNumberChoice()
854 {
855  m_choiceTextFromBus->Enable(false);
856  m_choiceTextToBus->Enable(false);
857  m_choiceTextUnit->Enable(false);
858  m_choiceTextFromBus->Clear();
859  m_choiceTextToBus->Clear();
860  m_choiceTextUnit->Clear();
861 
862  int index = m_choiceName->GetSelection();
863  m_text->SetElementNumber(index);
864 
865  m_choiceTextType->Clear();
866  wxArrayString arrayString;
867  switch(m_text->GetElementType()) {
868  case TYPE_BUS: {
869  Bus* bus = m_allElements.GetBusList()[index];
870  m_text->SetElement(bus);
871 
872  arrayString.Add(_("Name"));
873  arrayString.Add(_("Voltage"));
874  arrayString.Add(_("Angle"));
875  arrayString.Add(_("Fault current"));
876  arrayString.Add(_("Fault voltage"));
877  arrayString.Add(_("Short-circuit power"));
878  } break;
879  case TYPE_SYNC_GENERATOR: {
880  SyncGenerator* syncGenerator = m_allElements.GetSyncGeneratorList()[index];
881  m_text->SetElement(syncGenerator);
882 
883  arrayString.Add(_("Name"));
884  arrayString.Add(_("Active power"));
885  arrayString.Add(_("Reactive power"));
886  arrayString.Add(_("Fault current"));
887  } break;
888  case TYPE_LINE: {
889  Line* line = m_allElements.GetLineList()[index];
890  m_text->SetElement(line);
891 
892  arrayString.Add(_("Name"));
893  arrayString.Add(_("Active power flow"));
894  arrayString.Add(_("Reactive power flow"));
895  arrayString.Add(_("Losses"));
896  arrayString.Add(_("Current"));
897  arrayString.Add(_("Fault current"));
898  } break;
899  case TYPE_TRANSFORMER: {
900  Transformer* transformer = m_allElements.GetTransformerList()[index];
901  m_text->SetElement(transformer);
902 
903  arrayString.Add(_("Name"));
904  arrayString.Add(_("Active power flow"));
905  arrayString.Add(_("Reactive power flow"));
906  arrayString.Add(_("Losses"));
907  arrayString.Add(_("Current"));
908  arrayString.Add(_("Fault current"));
909  } break;
910  case TYPE_LOAD: {
911  Load* load = m_allElements.GetLoadList()[index];
912  m_text->SetElement(load);
913 
914  arrayString.Add(_("Name"));
915  arrayString.Add(_("Active power"));
916  arrayString.Add(_("Reactive power"));
917  } break;
918  case TYPE_CAPACITOR: {
919  Capacitor* capacitor = m_allElements.GetCapacitorList()[index];
920  m_text->SetElement(capacitor);
921 
922  arrayString.Add(_("Name"));
923  arrayString.Add(_("Reactive power"));
924  } break;
925  case TYPE_INDUCTOR: {
926  Inductor* inductor = m_allElements.GetInductorList()[index];
927  m_text->SetElement(inductor);
928 
929  arrayString.Add(_("Name"));
930  arrayString.Add(_("Reactive power"));
931  } break;
932  case TYPE_SYNC_MOTOR: {
933  SyncMotor* syncMotor = m_allElements.GetSyncMotorList()[index];
934  m_text->SetElement(syncMotor);
935 
936  arrayString.Add(_("Name"));
937  arrayString.Add(_("Active power"));
938  arrayString.Add(_("Reactive power"));
939  } break;
940  case TYPE_IND_MOTOR: {
941  IndMotor* indMotor = m_allElements.GetIndMotorList()[index];
942  m_text->SetElement(indMotor);
943 
944  arrayString.Add(_("Name"));
945  arrayString.Add(_("Active power"));
946  arrayString.Add(_("Reactive power"));
947  } break;
948 
949  default:
950  break;
951  }
952  m_choiceTextType->Append(arrayString);
953  m_choiceTextType->Enable();
954 }
955 
956 void TextForm::DataTypeChoice()
957 {
958  m_choiceTextFromBus->Enable(false);
959  m_choiceTextToBus->Enable(false);
960 
961  m_choiceTextToBus->Clear();
962  m_choiceTextFromBus->Clear();
963  m_choiceTextUnit->Clear();
964 
965  m_choiceTextUnit->Enable();
966 
967  wxArrayString arrayString;
968  switch(m_text->GetDataType()) {
969  case DATA_NAME: {
970  m_choiceTextUnit->Enable(false);
971  return;
972  } break;
973  case DATA_VOLTAGE:
974  case DATA_SC_VOLTAGE: {
975  arrayString.Add(_("p.u."));
976  arrayString.Add(_("V"));
977  arrayString.Add(_("kV"));
978  } break;
979  case DATA_ANGLE: {
980  arrayString.Add(_("Degrees"));
981  arrayString.Add(_("Radians"));
982  } break;
983  case DATA_SC_CURRENT:
984  case DATA_PF_CURRENT: {
985  arrayString.Add(_("p.u."));
986  arrayString.Add(_("A"));
987  arrayString.Add(_("kA"));
988  } break;
989  case DATA_SC_POWER: {
990  arrayString.Add(_("p.u."));
991  arrayString.Add(_("VA"));
992  arrayString.Add(_("kVA"));
993  arrayString.Add(_("MVA"));
994  } break;
995  case DATA_ACTIVE_POWER:
996  case DATA_PF_ACTIVE:
997  case DATA_PF_LOSSES: {
998  arrayString.Add(_("p.u."));
999  arrayString.Add(_("W"));
1000  arrayString.Add(_("kW"));
1001  arrayString.Add(_("MW"));
1002  m_choiceTextUnit->Enable();
1003  } break;
1004  case DATA_REACTIVE_POWER:
1005  case DATA_PF_REACTIVE: {
1006  arrayString.Add(_("p.u."));
1007  arrayString.Add(_("VAr"));
1008  arrayString.Add(_("kVAr"));
1009  arrayString.Add(_("MVAr"));
1010  } break;
1011  default:
1012  break;
1013  }
1014  m_choiceTextUnit->Append(arrayString);
1015 
1016  switch(m_text->GetElementType()) {
1017  case TYPE_LINE: {
1018  if(m_text->GetDataType() != DATA_PF_LOSSES) {
1019  auto it = m_allElements.GetLineList().begin();
1020  std::advance(it, m_text->GetElementNumber());
1021  Line* line = *it;
1022 
1023  Bus* bus1 = static_cast<Bus*>(line->GetParentList()[0]);
1024  Bus* bus2 = static_cast<Bus*>(line->GetParentList()[1]);
1025  wxString bus1Name = bus1->GetElectricalData().name;
1026  wxString bus2Name = bus2->GetElectricalData().name;
1027 
1028  m_choiceTextFromBus->Append(bus1Name);
1029  m_choiceTextFromBus->Append(bus2Name);
1030  m_choiceTextToBus->Append(bus2Name);
1031  m_choiceTextToBus->Append(bus1Name);
1032  m_choiceTextFromBus->SetSelection(0);
1033  m_choiceTextToBus->SetSelection(0);
1034 
1035  m_choiceTextFromBus->Enable();
1036  m_choiceTextToBus->Enable();
1037  }
1038  } break;
1039  case TYPE_TRANSFORMER: {
1040  if(m_text->GetDataType() != DATA_PF_LOSSES) {
1041  auto it = m_allElements.GetTransformerList().begin();
1042  std::advance(it, m_text->GetElementNumber());
1043  Transformer* transformer = *it;
1044 
1045  Bus* bus1 = static_cast<Bus*>(transformer->GetParentList()[0]);
1046  Bus* bus2 = static_cast<Bus*>(transformer->GetParentList()[1]);
1047  wxString bus1Name = bus1->GetElectricalData().name;
1048  wxString bus2Name = bus2->GetElectricalData().name;
1049 
1050  m_choiceTextFromBus->Append(bus1Name);
1051  m_choiceTextFromBus->Append(bus2Name);
1052  m_choiceTextToBus->Append(bus2Name);
1053  m_choiceTextToBus->Append(bus1Name);
1054  m_choiceTextFromBus->SetSelection(0);
1055  m_choiceTextToBus->SetSelection(0);
1056 
1057  m_choiceTextFromBus->Enable();
1058  m_choiceTextToBus->Enable();
1059  }
1060  } break;
1061  default:
1062  break;
1063  }
1064 }
1065 
1066 void TextForm::UnitChoice()
1067 {
1068  switch(m_text->GetDataType()) {
1069  case DATA_NAME: {
1070  m_choiceTextUnit->Enable(false);
1071  return;
1072  } break;
1073  case DATA_VOLTAGE:
1074  case DATA_SC_VOLTAGE: {
1075  switch(m_choiceTextUnit->GetSelection()) {
1076  case 0: {
1077  m_text->SetUnit(UNIT_PU);
1078  } break;
1079  case 1: {
1080  m_text->SetUnit(UNIT_V);
1081  } break;
1082  case 2: {
1083  m_text->SetUnit(UNIT_kV);
1084  } break;
1085  default:
1086  break;
1087  }
1088  } break;
1089  case DATA_ANGLE: {
1090  switch(m_choiceTextUnit->GetSelection()) {
1091  case 0: {
1092  m_text->SetUnit(UNIT_DEGREE);
1093  } break;
1094  case 1: {
1095  m_text->SetUnit(UNIT_RADIAN);
1096  } break;
1097  default:
1098  break;
1099  }
1100  } break;
1101  case DATA_SC_CURRENT:
1102  case DATA_PF_CURRENT: {
1103  switch(m_choiceTextUnit->GetSelection()) {
1104  case 0: {
1105  m_text->SetUnit(UNIT_PU);
1106  } break;
1107  case 1: {
1108  m_text->SetUnit(UNIT_A);
1109  } break;
1110  case 2: {
1111  m_text->SetUnit(UNIT_kA);
1112  } break;
1113  default:
1114  break;
1115  }
1116  } break;
1117  case DATA_SC_POWER: {
1118  switch(m_choiceTextUnit->GetSelection()) {
1119  case 0: {
1120  m_text->SetUnit(UNIT_PU);
1121  } break;
1122  case 1: {
1123  m_text->SetUnit(UNIT_VA);
1124  } break;
1125  case 2: {
1126  m_text->SetUnit(UNIT_kVA);
1127  } break;
1128  case 3: {
1129  m_text->SetUnit(UNIT_MVA);
1130  } break;
1131  default:
1132  break;
1133  }
1134  } break;
1135  case DATA_ACTIVE_POWER:
1136  case DATA_PF_ACTIVE:
1137  case DATA_PF_LOSSES: {
1138  switch(m_choiceTextUnit->GetSelection()) {
1139  case 0: {
1140  m_text->SetUnit(UNIT_PU);
1141  } break;
1142  case 1: {
1143  m_text->SetUnit(UNIT_W);
1144  } break;
1145  case 2: {
1146  m_text->SetUnit(UNIT_kW);
1147  } break;
1148  case 3: {
1149  m_text->SetUnit(UNIT_MW);
1150  } break;
1151  default:
1152  break;
1153  }
1154  } break;
1155  case DATA_REACTIVE_POWER:
1156  case DATA_PF_REACTIVE: {
1157  switch(m_choiceTextUnit->GetSelection()) {
1158  case 0: {
1159  m_text->SetUnit(UNIT_PU);
1160  } break;
1161  case 1: {
1162  m_text->SetUnit(UNIT_VAr);
1163  } break;
1164  case 2: {
1165  m_text->SetUnit(UNIT_kVAr);
1166  } break;
1167  case 3: {
1168  m_text->SetUnit(UNIT_MVAr);
1169  } break;
1170  default:
1171  break;
1172  }
1173  } break;
1174  default:
1175  break;
1176  }
1177 }
1178 
1179 void TextForm::Preview()
1180 {
1181  double decimalPlaces = m_text->GetDecimalPlaces();
1182  if(m_textCtrlDecimal->GetValue().ToDouble(&decimalPlaces)) m_text->SetDecimalPlaces(decimalPlaces);
1183 
1184  m_text->UpdateText(m_systemPowerBase);
1185 
1186  m_textCtrlPreview->SetValue(m_text->GetText());
1187 }
1188 
1189 bool TextForm::ValidateData()
1190 {
1191  if(m_choiceElement->GetSelection() == -1) return false;
1192  if(m_choiceName->GetSelection() == -1) return false;
1193  if(m_choiceTextType->GetSelection() == -1) return false;
1194  if(m_text->GetDataType() != DATA_NAME && m_choiceTextUnit->GetSelection() == -1) return false;
1195  if(m_text->GetElementType() == TYPE_LINE || m_text->GetElementType() == TYPE_TRANSFORMER) {
1196  if(m_text->GetDataType() != DATA_PF_LOSSES && m_text->GetDataType() != DATA_NAME) {
1197  if(m_choiceTextFromBus->GetSelection() == -1) return false;
1198  if(m_choiceTextToBus->GetSelection() == -1) return false;
1199  }
1200  }
1201 
1202  if(m_choiceTextFromBus->IsEnabled() && m_choiceTextToBus->IsEnabled())
1203  m_text->SetDirection(m_choiceTextFromBus->GetSelection());
1204  double decimalPlaces = m_text->GetDecimalPlaces();
1205  if(m_textCtrlDecimal->GetValue().ToDouble(&decimalPlaces)) m_text->SetDecimalPlaces(decimalPlaces);
1206 
1207  m_textToEdit->SetElementType(m_text->GetElementType());
1208  m_textToEdit->SetElementNumber(m_text->GetElementNumber());
1209  m_textToEdit->SetElement(m_text->GetElement());
1210  m_textToEdit->SetDataType(m_text->GetDataType());
1211  m_textToEdit->SetDirection(m_text->GetDirection());
1212  m_textToEdit->SetUnit(m_text->GetUnit());
1213  m_textToEdit->SetDecimalPlaces(decimalPlaces);
1214  m_textToEdit->UpdateText(m_systemPowerBase);
1215 
1216  return true;
1217 }
1218 
1219 void TextForm::OnOKButtonClick(wxCommandEvent& event)
1220 {
1221  if(ValidateData()) {
1222  EndModal(wxID_OK);
1223  } else {
1224  wxString errorMsg = _("There are blank fields.");
1225  wxMessageDialog msgDialog(this, errorMsg, _("Error"), wxOK | wxCENTRE | wxICON_ERROR);
1226  msgDialog.ShowModal();
1227  }
1228 }
Element that shows power element informations in workspace.
Definition: Text.h:75
@@ -102,7 +102,7 @@ $(document).ready(function(){initNavTree('_text_form_8cpp_source.html','');});
Power line element.
Definition: Line.h:59
-
Loas shunt power element.
Definition: Load.h:42
+
Loas shunt power element.
Definition: Load.h:73
Synchronous motor (synchronous compensator) power element.
Definition: SyncMotor.h:134
Induction motor power element.
Definition: IndMotor.h:40
@@ -114,7 +114,7 @@ $(document).ready(function(){initNavTree('_text_form_8cpp_source.html','');});
Two-winding transformer power element.
Definition: Transformer.h:78
- +
diff --git a/docs/doxygen/html/_text_form_8h_source.html b/docs/doxygen/html/_text_form_8h_source.html index fa0168c..8b2b606 100644 --- a/docs/doxygen/html/_text_form_8h_source.html +++ b/docs/doxygen/html/_text_form_8h_source.html @@ -88,12 +88,12 @@ $(document).ready(function(){initNavTree('_text_form_8h_source.html','');});
TextForm.h
-Go to the documentation of this file.
1 /*
2  * Copyright (C) 2017 Thales Lima Oliveira <thales@ufu.br>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program. If not, see <https://www.gnu.org/licenses/>.
16  */
17 
18 #ifndef TEXTFORM_H
19 #define TEXTFORM_H
20 #include "ElementForm.h"
21 
22 #include "Text.h"
23 #include "ElectricCalculation.h"
24 
32 class TextForm : public TextFormBase
33 {
34  public:
35  TextForm(wxWindow* parent, Text* text, std::vector<Element*> elementList, double systemPowerBase = 100e6);
36  virtual ~TextForm();
37 
38  virtual bool LoadChoices();
39 
40  virtual void ElementTypeChoice();
41  virtual void ElementNumberChoice();
42  virtual void DataTypeChoice();
43  virtual void UnitChoice();
44 
45  virtual void Preview();
46  virtual bool ValidateData();
47 
48  protected:
49  virtual void OnUnitChoiceSelected(wxCommandEvent& event);
50  virtual void OnCancelButtonClick(wxCommandEvent& event) { EndModal(wxID_CANCEL); }
51  virtual void OnOKButtonClick(wxCommandEvent& event);
52  virtual void OnElementChoiceSelected(wxCommandEvent& event);
53  virtual void OnFromBusChoiceSelected(wxCommandEvent& event);
54  virtual void OnNameChoiceSelected(wxCommandEvent& event);
55  virtual void OnTextEnter(wxCommandEvent& event);
56  virtual void OnToBusChoiceSelected(wxCommandEvent& event);
57  virtual void OnTypeChoiceSelected(wxCommandEvent& event);
58 
59  Text* m_text = NULL;
60  Text* m_textToEdit = NULL;
61  wxWindow* m_parent = NULL;
62  ElectricCalculation m_allElements;
63  double m_systemPowerBase;
64 };
65 #endif // TEXTFORM_H
Element that shows power element informations in workspace.
Definition: Text.h:72
+Go to the documentation of this file.
1 /*
2  * Copyright (C) 2017 Thales Lima Oliveira <thales@ufu.br>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program. If not, see <https://www.gnu.org/licenses/>.
16  */
17 
18 #ifndef TEXTFORM_H
19 #define TEXTFORM_H
20 #include "ElementForm.h"
21 
22 #include "Text.h"
23 #include "ElectricCalculation.h"
24 
32 class TextForm : public TextFormBase
33 {
34  public:
35  TextForm(wxWindow* parent, Text* text, std::vector<Element*> elementList, double systemPowerBase = 100e6);
36  virtual ~TextForm();
37 
38  virtual bool LoadChoices();
39 
40  virtual void ElementTypeChoice();
41  virtual void ElementNumberChoice();
42  virtual void DataTypeChoice();
43  virtual void UnitChoice();
44 
45  virtual void Preview();
46  virtual bool ValidateData();
47 
48  protected:
49  virtual void OnUnitChoiceSelected(wxCommandEvent& event);
50  virtual void OnCancelButtonClick(wxCommandEvent& event) { EndModal(wxID_CANCEL); }
51  virtual void OnOKButtonClick(wxCommandEvent& event);
52  virtual void OnElementChoiceSelected(wxCommandEvent& event);
53  virtual void OnFromBusChoiceSelected(wxCommandEvent& event);
54  virtual void OnNameChoiceSelected(wxCommandEvent& event);
55  virtual void OnTextEnter(wxCommandEvent& event);
56  virtual void OnToBusChoiceSelected(wxCommandEvent& event);
57  virtual void OnTypeChoiceSelected(wxCommandEvent& event);
58 
59  Text* m_text = NULL;
60  Text* m_textToEdit = NULL;
61  wxWindow* m_parent = NULL;
62  ElectricCalculation m_allElements;
63  double m_systemPowerBase;
64 };
65 #endif // TEXTFORM_H
Element that shows power element informations in workspace.
Definition: Text.h:75
Form to edit the text graphical data.
Definition: TextForm.h:32
Base class of electric calculations, with general methods.
- +
diff --git a/docs/doxygen/html/_transfer_function_8cpp_source.html b/docs/doxygen/html/_transfer_function_8cpp_source.html index ea4db24..778f269 100644 --- a/docs/doxygen/html/_transfer_function_8cpp_source.html +++ b/docs/doxygen/html/_transfer_function_8cpp_source.html @@ -88,21 +88,22 @@ $(document).ready(function(){initNavTree('_transfer_function_8cpp_source.html','
TransferFunction.cpp
-
1 /*
2  * Copyright (C) 2017 Thales Lima Oliveira <thales@ufu.br>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program. If not, see <https://www.gnu.org/licenses/>.
16  */
17 
18 #include "TransferFunction.h"
19 #include "TransferFunctionForm.h"
20 
21 TransferFunction::TransferFunction(int id) : ControlElement(id)
22 {
23  // Superscript unicode numbers
24  m_supNumber[0] = L'\u2070';
25  m_supNumber[1] = L'\u00B9';
26  m_supNumber[2] = L'\u00B2';
27  m_supNumber[3] = L'\u00B3';
28  m_supNumber[4] = L'\u2074';
29  m_supNumber[5] = L'\u2075';
30  m_supNumber[6] = L'\u2076';
31  m_supNumber[7] = L'\u2077';
32  m_supNumber[8] = L'\u2078';
33  m_supNumber[9] = L'\u2079';
34 
35  m_numerator.clear();
36  m_numerator.push_back(1);
37  m_denominator.clear();
38  m_denominator.push_back(1);
39  m_denominator.push_back(1);
40  UpdateTFText();
41 
42  Node* node1 = new Node(m_position + wxPoint2DDouble(-m_width / 2, 0), Node::NODE_IN, m_borderSize);
43  node1->StartMove(m_position);
44  Node* node2 = new Node(m_position + wxPoint2DDouble(m_width / 2, 0), Node::NODE_OUT, m_borderSize);
45  node2->SetAngle(180.0);
46  node2->StartMove(m_position);
47  m_nodeList.push_back(node1);
48  m_nodeList.push_back(node2);
49 }
50 
51 TransferFunction::~TransferFunction() {}
52 void TransferFunction::Draw(wxPoint2DDouble translation, double scale) const
53 {
54  glLineWidth(1.0);
55  if(m_selected) {
56  glColor4dv(m_selectionColour.GetRGBA());
57  double borderSize = (m_borderSize * 2.0 + 1.0) / scale;
58  DrawRectangle(m_position, m_width + borderSize, m_height + borderSize);
59  }
60  glColor4d(1.0, 1.0, 1.0, 1.0);
61  DrawRectangle(m_position, m_width, m_height);
62  glColor4d(0.0, 0.0, 0.0, 1.0);
63  DrawRectangle(m_position, m_width, m_height, GL_LINE_LOOP);
64 
65  std::vector<wxPoint2DDouble> linePts;
66  linePts.push_back(wxPoint2DDouble(m_position.m_x - m_width / 2 + 5 + m_borderSize, m_position.m_y));
67  linePts.push_back(wxPoint2DDouble(m_position.m_x + m_width / 2 - 5 - m_borderSize, m_position.m_y));
68  DrawLine(linePts);
69 
70  DrawNodes();
71 
72  glEnable(GL_TEXTURE_2D);
73  glColor4d(0.0, 0.0, 0.0, 1.0);
74  m_glStringNum->bind();
75  m_glStringNum->render(m_position.m_x, m_position.m_y - m_height / 4);
76  m_glStringDen->bind();
77  m_glStringDen->render(m_position.m_x, m_position.m_y + m_height / 4);
78  glDisable(GL_TEXTURE_2D);
79 }
80 
81 void TransferFunction::SetText(wxString numerator, wxString denominator)
82 {
83  wxFont font(m_fontSize, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL);
84  wxScreenDC dc;
85 
86  if(m_glStringNum) {
87  delete m_glStringNum;
88  m_glStringNum = NULL;
89  }
90  m_glStringNum = new wxGLString(numerator);
91  m_glStringNum->setFont(font);
92  m_glStringNum->consolidate(&dc);
93 
94  if(m_glStringDen) {
95  delete m_glStringDen;
96  m_glStringDen = NULL;
97  }
98  m_glStringDen = new wxGLString(denominator);
99  m_glStringDen->setFont(font);
100  m_glStringDen->consolidate(&dc);
101 
102  double nWidth = m_glStringNum->getWidth() + 5 + m_borderSize;
103  double dWidth = m_glStringDen->getWidth() + 5 + m_borderSize;
104 
105  m_width = nWidth > dWidth ? nWidth : dWidth;
106  m_height = m_glStringNum->getheight() + m_glStringDen->getheight() + 2 * m_borderSize;
107  SetPosition(m_position); // Update rect properly.
108 }
109 
110 wxString TransferFunction::GetSuperscriptNumber(int number)
111 {
112  wxString strNumber = wxString::Format("%d", number);
113  wxString superscriptStr = "";
114  for(int i = 0; i < (int)strNumber.length(); ++i) {
115  wxString digitStr = strNumber[i];
116  long digit = 0;
117  digitStr.ToLong(&digit);
118  superscriptStr += wxString(m_supNumber[digit]);
119  }
120  return superscriptStr;
121 }
122 
123 void TransferFunction::GetTFString(wxString& numerator, wxString& denominator)
124 {
125  numerator = "";
126  denominator = "";
127  int index = static_cast<int>(m_numerator.size()) - 1;
128  for(auto it = m_numerator.begin(), itEnd = m_numerator.end(); it != itEnd; ++it) {
129  double value = *it;
130  if(value != 0.0) {
131  wxString signal;
132  if(index == static_cast<int>(m_numerator.size()) - 1) {
133  if(value >= 0.0)
134  signal += "";
135  else
136  signal += "-";
137  } else {
138  if(value >= 0.0)
139  signal += "+ ";
140  else
141  signal += "- ";
142  }
143 
144  if(index == 0) {
145  numerator += signal + StringFromDouble(std::abs(value), 0);
146  break;
147  } else if(index == 1) {
148  if(value == 1.0) {
149  numerator += signal + "s";
150  } else {
151  numerator += signal + StringFromDouble(std::abs(value), 0) + "s";
152  }
153  } else {
154  if(value == 1.0) {
155  numerator += signal + "s" + GetSuperscriptNumber(index);
156  } else {
157  numerator += signal + StringFromDouble(std::abs(value), 0) + "s" + GetSuperscriptNumber(index);
158  }
159  }
160  numerator += " ";
161  }
162  --index;
163  }
164 
165  index = static_cast<int>(m_denominator.size()) - 1;
166  for(auto it = m_denominator.begin(), itEnd = m_denominator.end(); it != itEnd; ++it) {
167  double value = *it;
168  if(value != 0.0) {
169  wxString signal;
170  if(index == static_cast<int>(m_denominator.size()) - 1) {
171  if(value >= 0.0)
172  signal += "";
173  else
174  signal += "-";
175  } else {
176  if(value >= 0.0)
177  signal += "+ ";
178  else
179  signal += "- ";
180  }
181 
182  if(index == 0) {
183  denominator += signal + StringFromDouble(std::abs(value), 0);
184  break;
185  } else if(index == 1) {
186  if(value == 1.0) {
187  denominator += signal + "s";
188  } else {
189  denominator += signal + StringFromDouble(std::abs(value), 0) + "s";
190  }
191  } else {
192  if(value == 1.0) {
193  denominator += signal + "s" + GetSuperscriptNumber(index);
194  } else {
195  denominator += signal + StringFromDouble(std::abs(value), 0) + "s" + GetSuperscriptNumber(index);
196  }
197  }
198  denominator += " ";
199  }
200  --index;
201  }
202 }
203 
204 void TransferFunction::UpdateTFText()
205 {
206  wxString num, den;
207  GetTFString(num, den);
208  SetText(num, den);
209  if(m_nodeList.size() == 2) {
210  if(m_angle == 0.0) {
211  m_nodeList[0]->SetPosition(m_position + wxPoint2DDouble(-m_width / 2, 0));
212  m_nodeList[1]->SetPosition(m_position + wxPoint2DDouble(m_width / 2, 0));
213  } else if(m_angle == 90.0) {
214  m_nodeList[0]->SetPosition(m_position + wxPoint2DDouble(0, -m_height / 2));
215  m_nodeList[1]->SetPosition(m_position + wxPoint2DDouble(0, m_height / 2));
216  } else if(m_angle == 180.0) {
217  m_nodeList[0]->SetPosition(m_position + wxPoint2DDouble(m_width / 2, 0));
218  m_nodeList[1]->SetPosition(m_position + wxPoint2DDouble(-m_width / 2, 0));
219  } else if(m_angle == 270.0) {
220  m_nodeList[0]->SetPosition(m_position + wxPoint2DDouble(0, m_height / 2));
221  m_nodeList[1]->SetPosition(m_position + wxPoint2DDouble(0, -m_height / 2));
222  }
223  }
224 }
225 
226 bool TransferFunction::ShowForm(wxWindow* parent, Element* element)
227 {
228  TransferFunctionForm* tfForm = new TransferFunctionForm(parent, this);
229  if(tfForm->ShowModal() == wxID_OK) {
230  tfForm->Destroy();
231  return true;
232  }
233  tfForm->Destroy();
234  return false;
235 }
236 
237 void TransferFunction::Rotate(bool clockwise)
238 {
239  if(clockwise)
240  m_angle += 90.0;
241  else
242  m_angle -= 90.0;
243  if(m_angle >= 360.0)
244  m_angle = 0.0;
245  else if(m_angle < 0)
246  m_angle = 270.0;
247 
248  if(m_angle == 0.0) {
249  m_nodeList[0]->SetPosition(m_position + wxPoint2DDouble(-m_width / 2, 0));
250  m_nodeList[1]->SetPosition(m_position + wxPoint2DDouble(m_width / 2, 0));
251  } else if(m_angle == 90.0) {
252  m_nodeList[0]->SetPosition(m_position + wxPoint2DDouble(0, -m_height / 2));
253  m_nodeList[1]->SetPosition(m_position + wxPoint2DDouble(0, m_height / 2));
254  } else if(m_angle == 180.0) {
255  m_nodeList[0]->SetPosition(m_position + wxPoint2DDouble(m_width / 2, 0));
256  m_nodeList[1]->SetPosition(m_position + wxPoint2DDouble(-m_width / 2, 0));
257  } else if(m_angle == 270.0) {
258  m_nodeList[0]->SetPosition(m_position + wxPoint2DDouble(0, m_height / 2));
259  m_nodeList[1]->SetPosition(m_position + wxPoint2DDouble(0, -m_height / 2));
260  }
261 
262  for(auto it = m_nodeList.begin(), itEnd = m_nodeList.end(); it != itEnd; ++it) {
263  Node* node = *it;
264  node->Rotate(clockwise);
265  }
266 }
267 
268 void TransferFunction::CalculateSpaceState(int maxIteration, double error)
269 {
270  m_maxIteration = maxIteration;
271  m_error = error;
272 
273  int order = static_cast<int>(m_denominator.size());
274  std::vector<double> denominator = m_denominator;
275  std::vector<double> numerator;
276 
277  //[Ref.] http://lpsa.swarthmore.edu/Representations/SysRepTransformations/TF2SS.html
278  int k = order;
279  for(int i = 0; i < order; i++) {
280  int numIndex = i - (order - static_cast<int>(m_numerator.size()));
281  if(numIndex < 0)
282  numerator.push_back(0.0);
283  else
284  numerator.push_back(m_numerator[numIndex]);
285  k--;
286  }
287 
288  SpaceState ss;
289  for(int i = 0; i < (order - 1); i++) {
290  std::vector<double> lineA;
291  for(int j = 0; j < (order - 1); j++) {
292  if(j == i + 1)
293  lineA.push_back(1.0);
294  else
295  lineA.push_back(0.0);
296  }
297  ss.A.push_back(lineA);
298  ss.B.push_back(0.0);
299  ss.C.push_back(0.0);
300  }
301  for(int i = 0; i < order - 1; i++) {
302  ss.A[order - 2][i] = -(denominator[order - 1 - i] / denominator[0]);
303  ss.C[i] = (numerator[order - 1 - i] - denominator[order - 1 - i] * numerator[0]) / denominator[0];
304  }
305  ss.B[order - 2] = 1.0;
306  ss.D = numerator[0];
307 
308  m_ss = ss;
309 
310  // Reset state
311  m_x.clear();
312  m_dx.clear();
313 
314  for(unsigned int i = 0; i < m_denominator.size(); ++i) {
315  m_x.push_back(0.0);
316  m_dx.push_back(0.0);
317  }
318 }
319 
320 bool TransferFunction::Solve(double input, double timeStep)
321 {
322  int order = static_cast<int>(m_ss.A.size());
323 
324  std::vector<double> x;
325  std::vector<double> oldx;
326  std::vector<double> dx;
327  std::vector<double> olddx;
328  for(int i = 0; i < order; i++) {
329  x.push_back(m_x[i]);
330  oldx.push_back(m_x[i]);
331 
332  dx.push_back(m_dx[i]);
333  olddx.push_back(m_dx[i]);
334  }
335 
336  bool exit = false;
337  int iter = 0;
338  while(!exit) {
339  double xError = 0.0;
340  double dxError = 0.0;
341  for(int i = 0; i < order; i++) {
342  // Trapezoidal method
343  x[i] = m_x[i] + 0.5 * timeStep * (m_dx[i] + dx[i]);
344 
345  if(std::abs(x[i] - oldx[i]) > xError) xError = std::abs(x[i] - oldx[i]);
346 
347  oldx[i] = x[i];
348  }
349  for(int i = 0; i < order; i++) {
350  // x' = Ax + Bu
351  dx[i] = 0.0;
352  for(int j = 0; j < order; j++) dx[i] += m_ss.A[i][j] * x[j];
353  dx[i] += m_ss.B[i] * input;
354 
355  if(std::abs(dx[i] - olddx[i]) > dxError) dxError = std::abs(dx[i] - olddx[i]);
356 
357  olddx[i] = dx[i];
358  }
359  if(std::max(xError, dxError) < m_error) exit = true;
360 
361  iter++;
362  if(iter >= m_maxIteration) return false;
363  }
364 
365  m_output = 0.0;
366  for(int i = 0; i < order; i++) {
367  m_output += m_ss.C[i] * x[i];
368  m_x[i] = x[i];
369  m_dx[i] = dx[i];
370  }
371 
372  m_output += m_ss.D * input;
373 
374  return true;
375 }
376 
378 {
379  TransferFunction* copy = new TransferFunction(m_elementID);
380  *copy = *this;
381  m_glStringNum = NULL;
382  m_glStringDen = NULL;
383  UpdateTFText();
384  return copy;
385 }
Base class of all elements of the program. This class is responsible for manage graphical and his dat...
Definition: Element.h:113
-
virtual bool ShowForm(wxWindow *parent, Element *element)
Show element data form.
+
1 /*
2  * Copyright (C) 2017 Thales Lima Oliveira <thales@ufu.br>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program. If not, see <https://www.gnu.org/licenses/>.
16  */
17 
18 #include "TransferFunction.h"
19 #include "TransferFunctionForm.h"
20 
21 TransferFunction::TransferFunction(int id) : ControlElement(id)
22 {
23  // Superscript unicode numbers
24  m_supNumber[0] = L'\u2070';
25  m_supNumber[1] = L'\u00B9';
26  m_supNumber[2] = L'\u00B2';
27  m_supNumber[3] = L'\u00B3';
28  m_supNumber[4] = L'\u2074';
29  m_supNumber[5] = L'\u2075';
30  m_supNumber[6] = L'\u2076';
31  m_supNumber[7] = L'\u2077';
32  m_supNumber[8] = L'\u2078';
33  m_supNumber[9] = L'\u2079';
34 
35  m_numerator.clear();
36  m_numerator.push_back(1);
37  m_denominator.clear();
38  m_denominator.push_back(1);
39  m_denominator.push_back(1);
40  UpdateTFText();
41 
42  Node* node1 = new Node(m_position + wxPoint2DDouble(-m_width / 2, 0), Node::NODE_IN, m_borderSize);
43  node1->StartMove(m_position);
44  Node* node2 = new Node(m_position + wxPoint2DDouble(m_width / 2, 0), Node::NODE_OUT, m_borderSize);
45  node2->SetAngle(180.0);
46  node2->StartMove(m_position);
47  m_nodeList.push_back(node1);
48  m_nodeList.push_back(node2);
49 }
50 
51 TransferFunction::~TransferFunction()
52 {
53  if(m_glTextDen) delete m_glTextDen;
54  if(m_glTextNum) delete m_glTextNum;
55 }
56 void TransferFunction::Draw(wxPoint2DDouble translation, double scale) const
57 {
58  glLineWidth(1.0);
59  if(m_selected) {
60  glColor4dv(m_selectionColour.GetRGBA());
61  double borderSize = (m_borderSize * 2.0 + 1.0) / scale;
62  DrawRectangle(m_position, m_width + borderSize, m_height + borderSize);
63  }
64  glColor4d(1.0, 1.0, 1.0, 1.0);
65  DrawRectangle(m_position, m_width, m_height);
66  glColor4d(0.0, 0.0, 0.0, 1.0);
67  DrawRectangle(m_position, m_width, m_height, GL_LINE_LOOP);
68 
69  std::vector<wxPoint2DDouble> linePts;
70  linePts.push_back(wxPoint2DDouble(m_position.m_x - m_width / 2 + 5 + m_borderSize, m_position.m_y));
71  linePts.push_back(wxPoint2DDouble(m_position.m_x + m_width / 2 - 5 - m_borderSize, m_position.m_y));
72  DrawLine(linePts);
73 
74  DrawNodes();
75 
76  glColor4d(0.0, 0.0, 0.0, 1.0);
77  m_glTextNum->Draw(m_position + wxPoint2DDouble(0.0, -m_height / 4));
78  m_glTextDen->Draw(m_position + wxPoint2DDouble(0.0, m_height / 4));
79 }
80 
81 void TransferFunction::SetText(wxString numerator, wxString denominator)
82 {
83  if(m_glTextNum)
84  m_glTextNum->SetText(numerator);
85  else
86  m_glTextNum = new OpenGLText(numerator);
87 
88  if(m_glTextDen)
89  m_glTextDen->SetText(denominator);
90  else
91  m_glTextDen = new OpenGLText(denominator);
92 
93  double nWidth = m_glTextNum->GetWidth() + 5 + m_borderSize;
94  double dWidth = m_glTextDen->GetWidth() + 5 + m_borderSize;
95 
96  m_width = nWidth > dWidth ? nWidth : dWidth;
97  m_height = m_glTextNum->GetHeight() + m_glTextDen->GetHeight() + 2 * m_borderSize;
98  SetPosition(m_position); // Update rect properly.
99 }
100 
101 wxString TransferFunction::GetSuperscriptNumber(int number)
102 {
103  wxString strNumber = wxString::Format("%d", number);
104  wxString superscriptStr = "";
105  for(int i = 0; i < (int)strNumber.length(); ++i) {
106  wxString digitStr = strNumber[i];
107  long digit = 0;
108  digitStr.ToLong(&digit);
109  superscriptStr += wxString(m_supNumber[digit]);
110  }
111  return superscriptStr;
112 }
113 
114 void TransferFunction::GetTFString(wxString& numerator, wxString& denominator)
115 {
116  numerator = "";
117  denominator = "";
118  int index = static_cast<int>(m_numerator.size()) - 1;
119  for(auto it = m_numerator.begin(), itEnd = m_numerator.end(); it != itEnd; ++it) {
120  double value = *it;
121  if(value != 0.0) {
122  wxString signal;
123  if(index == static_cast<int>(m_numerator.size()) - 1) {
124  if(value >= 0.0)
125  signal += "";
126  else
127  signal += "-";
128  } else {
129  if(value >= 0.0)
130  signal += "+ ";
131  else
132  signal += "- ";
133  }
134 
135  if(index == 0) {
136  numerator += signal + StringFromDouble(std::abs(value), 0);
137  break;
138  } else if(index == 1) {
139  if(value == 1.0) {
140  numerator += signal + "s";
141  } else {
142  numerator += signal + StringFromDouble(std::abs(value), 0) + "s";
143  }
144  } else {
145  if(value == 1.0) {
146  numerator += signal + "s" + GetSuperscriptNumber(index);
147  } else {
148  numerator += signal + StringFromDouble(std::abs(value), 0) + "s" + GetSuperscriptNumber(index);
149  }
150  }
151  numerator += " ";
152  }
153  --index;
154  }
155 
156  index = static_cast<int>(m_denominator.size()) - 1;
157  for(auto it = m_denominator.begin(), itEnd = m_denominator.end(); it != itEnd; ++it) {
158  double value = *it;
159  if(value != 0.0) {
160  wxString signal;
161  if(index == static_cast<int>(m_denominator.size()) - 1) {
162  if(value >= 0.0)
163  signal += "";
164  else
165  signal += "-";
166  } else {
167  if(value >= 0.0)
168  signal += "+ ";
169  else
170  signal += "- ";
171  }
172 
173  if(index == 0) {
174  denominator += signal + StringFromDouble(std::abs(value), 0);
175  break;
176  } else if(index == 1) {
177  if(value == 1.0) {
178  denominator += signal + "s";
179  } else {
180  denominator += signal + StringFromDouble(std::abs(value), 0) + "s";
181  }
182  } else {
183  if(value == 1.0) {
184  denominator += signal + "s" + GetSuperscriptNumber(index);
185  } else {
186  denominator += signal + StringFromDouble(std::abs(value), 0) + "s" + GetSuperscriptNumber(index);
187  }
188  }
189  denominator += " ";
190  }
191  --index;
192  }
193 }
194 
195 void TransferFunction::UpdateTFText()
196 {
197  wxString num, den;
198  GetTFString(num, den);
199  SetText(num, den);
200  if(m_nodeList.size() == 2) {
201  if(m_angle == 0.0) {
202  m_nodeList[0]->SetPosition(m_position + wxPoint2DDouble(-m_width / 2, 0));
203  m_nodeList[1]->SetPosition(m_position + wxPoint2DDouble(m_width / 2, 0));
204  } else if(m_angle == 90.0) {
205  m_nodeList[0]->SetPosition(m_position + wxPoint2DDouble(0, -m_height / 2));
206  m_nodeList[1]->SetPosition(m_position + wxPoint2DDouble(0, m_height / 2));
207  } else if(m_angle == 180.0) {
208  m_nodeList[0]->SetPosition(m_position + wxPoint2DDouble(m_width / 2, 0));
209  m_nodeList[1]->SetPosition(m_position + wxPoint2DDouble(-m_width / 2, 0));
210  } else if(m_angle == 270.0) {
211  m_nodeList[0]->SetPosition(m_position + wxPoint2DDouble(0, m_height / 2));
212  m_nodeList[1]->SetPosition(m_position + wxPoint2DDouble(0, -m_height / 2));
213  }
214  }
215 }
216 
217 bool TransferFunction::ShowForm(wxWindow* parent, Element* element)
218 {
219  TransferFunctionForm* tfForm = new TransferFunctionForm(parent, this);
220  if(tfForm->ShowModal() == wxID_OK) {
221  tfForm->Destroy();
222  return true;
223  }
224  tfForm->Destroy();
225  return false;
226 }
227 
228 void TransferFunction::Rotate(bool clockwise)
229 {
230  if(clockwise)
231  m_angle += 90.0;
232  else
233  m_angle -= 90.0;
234  if(m_angle >= 360.0)
235  m_angle = 0.0;
236  else if(m_angle < 0)
237  m_angle = 270.0;
238 
239  if(m_angle == 0.0) {
240  m_nodeList[0]->SetPosition(m_position + wxPoint2DDouble(-m_width / 2, 0));
241  m_nodeList[1]->SetPosition(m_position + wxPoint2DDouble(m_width / 2, 0));
242  } else if(m_angle == 90.0) {
243  m_nodeList[0]->SetPosition(m_position + wxPoint2DDouble(0, -m_height / 2));
244  m_nodeList[1]->SetPosition(m_position + wxPoint2DDouble(0, m_height / 2));
245  } else if(m_angle == 180.0) {
246  m_nodeList[0]->SetPosition(m_position + wxPoint2DDouble(m_width / 2, 0));
247  m_nodeList[1]->SetPosition(m_position + wxPoint2DDouble(-m_width / 2, 0));
248  } else if(m_angle == 270.0) {
249  m_nodeList[0]->SetPosition(m_position + wxPoint2DDouble(0, m_height / 2));
250  m_nodeList[1]->SetPosition(m_position + wxPoint2DDouble(0, -m_height / 2));
251  }
252 
253  for(auto it = m_nodeList.begin(), itEnd = m_nodeList.end(); it != itEnd; ++it) {
254  Node* node = *it;
255  node->Rotate(clockwise);
256  }
257 }
258 
259 void TransferFunction::CalculateSpaceState(int maxIteration, double error)
260 {
261  m_maxIteration = maxIteration;
262  m_error = error;
263 
264  int order = static_cast<int>(m_denominator.size());
265  std::vector<double> denominator = m_denominator;
266  std::vector<double> numerator;
267 
268  //[Ref.] http://lpsa.swarthmore.edu/Representations/SysRepTransformations/TF2SS.html
269  int k = order;
270  for(int i = 0; i < order; i++) {
271  int numIndex = i - (order - static_cast<int>(m_numerator.size()));
272  if(numIndex < 0)
273  numerator.push_back(0.0);
274  else
275  numerator.push_back(m_numerator[numIndex]);
276  k--;
277  }
278 
279  SpaceState ss;
280  for(int i = 0; i < (order - 1); i++) {
281  std::vector<double> lineA;
282  for(int j = 0; j < (order - 1); j++) {
283  if(j == i + 1)
284  lineA.push_back(1.0);
285  else
286  lineA.push_back(0.0);
287  }
288  ss.A.push_back(lineA);
289  ss.B.push_back(0.0);
290  ss.C.push_back(0.0);
291  }
292  for(int i = 0; i < order - 1; i++) {
293  ss.A[order - 2][i] = -(denominator[order - 1 - i] / denominator[0]);
294  ss.C[i] = (numerator[order - 1 - i] - denominator[order - 1 - i] * numerator[0]) / denominator[0];
295  }
296  ss.B[order - 2] = 1.0;
297  ss.D = numerator[0];
298 
299  m_ss = ss;
300 
301  // Reset state
302  m_x.clear();
303  m_dx.clear();
304 
305  for(unsigned int i = 0; i < m_denominator.size(); ++i) {
306  m_x.push_back(0.0);
307  m_dx.push_back(0.0);
308  }
309 }
310 
311 bool TransferFunction::Solve(double input, double timeStep)
312 {
313  int order = static_cast<int>(m_ss.A.size());
314 
315  std::vector<double> x;
316  std::vector<double> oldx;
317  std::vector<double> dx;
318  std::vector<double> olddx;
319  for(int i = 0; i < order; i++) {
320  x.push_back(m_x[i]);
321  oldx.push_back(m_x[i]);
322 
323  dx.push_back(m_dx[i]);
324  olddx.push_back(m_dx[i]);
325  }
326 
327  bool exit = false;
328  int iter = 0;
329  while(!exit) {
330  double xError = 0.0;
331  double dxError = 0.0;
332  for(int i = 0; i < order; i++) {
333  // Trapezoidal method
334  x[i] = m_x[i] + 0.5 * timeStep * (m_dx[i] + dx[i]);
335 
336  if(std::abs(x[i] - oldx[i]) > xError) xError = std::abs(x[i] - oldx[i]);
337 
338  oldx[i] = x[i];
339  }
340  for(int i = 0; i < order; i++) {
341  // x' = Ax + Bu
342  dx[i] = 0.0;
343  for(int j = 0; j < order; j++) dx[i] += m_ss.A[i][j] * x[j];
344  dx[i] += m_ss.B[i] * input;
345 
346  if(std::abs(dx[i] - olddx[i]) > dxError) dxError = std::abs(dx[i] - olddx[i]);
347 
348  olddx[i] = dx[i];
349  }
350  if(std::max(xError, dxError) < m_error) exit = true;
351 
352  iter++;
353  if(iter >= m_maxIteration) return false;
354  }
355 
356  m_output = 0.0;
357  for(int i = 0; i < order; i++) {
358  m_output += m_ss.C[i] * x[i];
359  m_x[i] = x[i];
360  m_dx[i] = dx[i];
361  }
362 
363  m_output += m_ss.D * input;
364 
365  return true;
366 }
367 
369 {
370  TransferFunction* copy = new TransferFunction(m_elementID);
371  *copy = *this;
372  copy->m_glTextNum = m_glTextNum->GetCopy();
373  copy->m_glTextDen = m_glTextDen->GetCopy();
374  return copy;
375 }
376 
378 {
379  UpdateTFText();
380  if(!m_glTextDen->IsTextureOK()) return false;
381  if(!m_glTextNum->IsTextureOK()) return false;
382  return true;
383 }
Base class of all elements of the program. This class is responsible for manage graphical and his dat...
Definition: Element.h:113
+
virtual bool ShowForm(wxWindow *parent, Element *element)
Show element data form.
Node of a control element. This class manages the user interaction with the connection and control el...
-
virtual Element * GetCopy()
Get a the element copy.
-
virtual void CalculateSpaceState(int maxIteration=100, double error=1e-3)
Convert the transfer function to space state on controllable canonical form (CCF).
+
virtual Element * GetCopy()
Get a the element copy.
+
virtual void CalculateSpaceState(int maxIteration=100, double error=1e-3)
Convert the transfer function to space state on controllable canonical form (CCF).
+
virtual bool UpdateText()
Update the OpenGL text in the element (if present).
Form to edit the transfer function control data.
-
virtual void Rotate(bool clockwise=true)
Rotate the element.
+
virtual void Rotate(bool clockwise=true)
Rotate the element.
+
Class to draw text on OpenGL using wxWidgets.
Definition: OpenGLText.h:31
Calculates the time response by a frequency domain transfer function.
-
virtual bool Solve(double input, double timeStep)
Calculates the time response by the space state form of transfer function.
-
virtual void Draw(wxPoint2DDouble translation, double scale) const
Draw the element.
+
virtual bool Solve(double input, double timeStep)
Calculates the time response by the space state form of transfer function.
+
virtual void Draw(wxPoint2DDouble translation, double scale) const
Draw the element.
-
diff --git a/docs/doxygen/html/_transfer_function_8h.html b/docs/doxygen/html/_transfer_function_8h.html index 5abcd43..5fa8e5d 100644 --- a/docs/doxygen/html/_transfer_function_8h.html +++ b/docs/doxygen/html/_transfer_function_8h.html @@ -92,7 +92,7 @@ $(document).ready(function(){initNavTree('_transfer_function_8h.html','');});
#include "ControlElement.h"
#include <wx/dcscreen.h>
-#include "wxGLString.h"
+#include "OpenGLText.h"

Go to the source code of this file.

diff --git a/docs/doxygen/html/_transfer_function_8h_source.html b/docs/doxygen/html/_transfer_function_8h_source.html index 6a75258..bc30f86 100644 --- a/docs/doxygen/html/_transfer_function_8h_source.html +++ b/docs/doxygen/html/_transfer_function_8h_source.html @@ -88,21 +88,23 @@ $(document).ready(function(){initNavTree('_transfer_function_8h_source.html','')
TransferFunction.h
-Go to the documentation of this file.
1 /*
2  * Copyright (C) 2017 Thales Lima Oliveira <thales@ufu.br>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program. If not, see <https://www.gnu.org/licenses/>.
16  */
17 
18 #ifndef TRANSFERFUNCTION_H
19 #define TRANSFERFUNCTION_H
20 
21 #include "ControlElement.h"
22 
23 #include <wx/dcscreen.h>
24 #include "wxGLString.h"
25 
27 
36 {
37  public:
38  struct SpaceState {
39  std::vector<std::vector<double> > A;
40  std::vector<double> B;
41  std::vector<double> C;
42  double D;
43  };
44 
45  TransferFunction(int id);
47 
48  virtual void Draw(wxPoint2DDouble translation, double scale) const;
49  virtual bool Contains(wxPoint2DDouble position) const { return m_rect.Contains(position); }
50  virtual bool Intersects(wxRect2DDouble rect) const { return m_rect.Intersects(rect); }
51  virtual bool ShowForm(wxWindow* parent, Element* element);
52  virtual void Rotate(bool clockwise = true);
53 
54  virtual std::vector<double> GetNumerator() const { return m_numerator; }
55  virtual std::vector<double> GetDenominator() const { return m_denominator; }
56  virtual void SetNumerator(std::vector<double> numerator) { m_numerator = numerator; }
57  virtual void SetDenominator(std::vector<double> denominator) { m_denominator = denominator; }
58  virtual void UpdateTFText();
59  virtual void UpdateText() { UpdateTFText(); }
60  virtual SpaceState GetSpaceState() { return m_ss; }
66  virtual void CalculateSpaceState(int maxIteration = 100, double error = 1e-3);
76  virtual bool Solve(double input, double timeStep);
77 
78  virtual Element* GetCopy();
79 
80  protected:
81  virtual void SetText(wxString numerator, wxString denominator);
82  virtual wxString GetSuperscriptNumber(int number);
83  virtual void GetTFString(wxString& numerator, wxString& denominator);
84 
85  wchar_t m_supNumber[10];
86 
87  wxGLString* m_glStringNum = NULL;
88  wxGLString* m_glStringDen = NULL;
89  int m_fontSize = 10;
90 
91  std::vector<double> m_numerator;
92  std::vector<double> m_denominator;
93  SpaceState m_ss;
94 
95  std::vector<double> m_x;
96  std::vector<double> m_dx;
97  double m_error = 1e-3;
98  int m_maxIteration = 100;
99 };
100 
101 #endif // TRANSFERFUNCTION_H
Base class of all elements of the program. This class is responsible for manage graphical and his dat...
Definition: Element.h:113
-
virtual bool ShowForm(wxWindow *parent, Element *element)
Show element data form.
-
virtual Element * GetCopy()
Get a the element copy.
+Go to the documentation of this file.
1 /*
2  * Copyright (C) 2017 Thales Lima Oliveira <thales@ufu.br>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program. If not, see <https://www.gnu.org/licenses/>.
16  */
17 
18 #ifndef TRANSFERFUNCTION_H
19 #define TRANSFERFUNCTION_H
20 
21 #include "ControlElement.h"
22 
23 #include <wx/dcscreen.h>
24 #include "OpenGLText.h"
25 
27 
36 {
37  public:
38  struct SpaceState {
39  std::vector<std::vector<double> > A;
40  std::vector<double> B;
41  std::vector<double> C;
42  double D;
43  };
44 
45  TransferFunction(int id);
47 
48  virtual void Draw(wxPoint2DDouble translation, double scale) const;
49  virtual bool Contains(wxPoint2DDouble position) const { return m_rect.Contains(position); }
50  virtual bool Intersects(wxRect2DDouble rect) const { return m_rect.Intersects(rect); }
51  virtual bool ShowForm(wxWindow* parent, Element* element);
52  virtual void Rotate(bool clockwise = true);
53 
54  virtual std::vector<double> GetNumerator() const { return m_numerator; }
55  virtual std::vector<double> GetDenominator() const { return m_denominator; }
56  virtual void SetNumerator(std::vector<double> numerator) { m_numerator = numerator; }
57  virtual void SetDenominator(std::vector<double> denominator) { m_denominator = denominator; }
58  virtual void UpdateTFText();
59  virtual bool UpdateText();
60  virtual SpaceState GetSpaceState() { return m_ss; }
66  virtual void CalculateSpaceState(int maxIteration = 100, double error = 1e-3);
76  virtual bool Solve(double input, double timeStep);
77 
78  virtual Element* GetCopy();
79 
80  protected:
81  virtual void SetText(wxString numerator, wxString denominator);
82  virtual wxString GetSuperscriptNumber(int number);
83  virtual void GetTFString(wxString& numerator, wxString& denominator);
84 
85  wchar_t m_supNumber[10];
86 
87  OpenGLText* m_glTextNum = NULL;
88  OpenGLText* m_glTextDen = NULL;
89  int m_fontSize = 10;
90 
91  std::vector<double> m_numerator;
92  std::vector<double> m_denominator;
93  SpaceState m_ss;
94 
95  std::vector<double> m_x;
96  std::vector<double> m_dx;
97  double m_error = 1e-3;
98  int m_maxIteration = 100;
99 };
100 
101 #endif // TRANSFERFUNCTION_H
Base class of all elements of the program. This class is responsible for manage graphical and his dat...
Definition: Element.h:113
+
virtual bool ShowForm(wxWindow *parent, Element *element)
Show element data form.
+
virtual Element * GetCopy()
Get a the element copy.
virtual bool Intersects(wxRect2DDouble rect) const
Check if the element&#39;s rect intersects other rect.
-
virtual void CalculateSpaceState(int maxIteration=100, double error=1e-3)
Convert the transfer function to space state on controllable canonical form (CCF).
+
virtual void CalculateSpaceState(int maxIteration=100, double error=1e-3)
Convert the transfer function to space state on controllable canonical form (CCF).
+
virtual bool UpdateText()
Update the OpenGL text in the element (if present).
Form to edit the transfer function control data.
-
virtual void Rotate(bool clockwise=true)
Rotate the element.
+ +
virtual void Rotate(bool clockwise=true)
Rotate the element.
virtual bool Contains(wxPoint2DDouble position) const
Checks if the element contains a position.
+
Class to draw text on OpenGL using wxWidgets.
Definition: OpenGLText.h:31
Calculates the time response by a frequency domain transfer function.
-
virtual bool Solve(double input, double timeStep)
Calculates the time response by the space state form of transfer function.
+
virtual bool Solve(double input, double timeStep)
Calculates the time response by the space state form of transfer function.
Base class of a control element. Provide general methods to other control classes.
-
virtual void Draw(wxPoint2DDouble translation, double scale) const
Draw the element.
+
virtual void Draw(wxPoint2DDouble translation, double scale) const
Draw the element.
-
diff --git a/docs/doxygen/html/_transfer_function_form_8cpp_source.html b/docs/doxygen/html/_transfer_function_form_8cpp_source.html index ae3e1b7..1aea44c 100644 --- a/docs/doxygen/html/_transfer_function_form_8cpp_source.html +++ b/docs/doxygen/html/_transfer_function_form_8cpp_source.html @@ -89,7 +89,7 @@ $(document).ready(function(){initNavTree('_transfer_function_form_8cpp_source.ht
1 /*
2  * Copyright (C) 2017 Thales Lima Oliveira <thales@ufu.br>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program. If not, see <https://www.gnu.org/licenses/>.
16  */
17 
18 #include "TransferFunctionForm.h"
19 #include "TransferFunction.h"
20 
21 TransferFunctionForm::TransferFunctionForm(wxWindow* parent, TransferFunction* transferFunction)
22  : TransferFunctionFormBase(parent)
23 {
24  SetSize(GetBestSize());
25 
26  m_parent = parent;
27  m_tf = transferFunction;
28  LoadTFData();
29 }
30 
31 TransferFunctionForm::~TransferFunctionForm() {}
32 void TransferFunctionForm::OnCancelClick(wxCommandEvent& event) { EndModal(wxID_CANCEL); }
33 void TransferFunctionForm::OnOKClick(wxCommandEvent& event)
34 {
35  if(ValidateData()) EndModal(wxID_OK);
36 }
37 
38 void TransferFunctionForm::LoadTFData()
39 {
40  auto num = m_tf->GetNumerator();
41  auto den = m_tf->GetDenominator();
42 
43  wxString numStr = "";
44  for(auto it = num.begin(), itEnd = num.end(); it != itEnd; ++it) {
45  double value = *it;
46  if(it == num.begin())
47  numStr = m_tf->StringFromDouble(value, 0);
48  else
49  numStr += " " + m_tf->StringFromDouble(value, 0);
50  }
51  m_textCtrlNumerator->SetValue(numStr);
52 
53  wxString denStr = "";
54  for(auto it = den.begin(), itEnd = den.end(); it != itEnd; ++it) {
55  double value = *it;
56  if(it == den.begin())
57  denStr = m_tf->StringFromDouble(value, 0);
58  else
59  denStr += " " + m_tf->StringFromDouble(value, 0);
60  }
61  m_textCtrlDenominator->SetValue(denStr);
62 }
63 
64 bool TransferFunctionForm::ValidateData()
65 {
66  wxString num = m_textCtrlNumerator->GetValue();
67  std::vector<double> numerator;
68  while(num != "") {
69  wxString rest;
70  wxString strValue = num.BeforeFirst(' ', &rest);
71  num = rest;
72  double value = 0;
73  if(!m_tf->DoubleFromString(this, strValue, value,
74  _("Value entered incorrectly in the field \"Numerator parameters\".")))
75  return false;
76  numerator.push_back(value);
77  }
78 
79  wxString den = m_textCtrlDenominator->GetValue();
80  std::vector<double> denominator;
81  while(den != "") {
82  wxString rest;
83  wxString strValue = den.BeforeFirst(' ', &rest);
84  den = rest;
85  double value = 0;
86  if(!m_tf->DoubleFromString(this, strValue, value,
87  _("Value entered incorrectly in the field \"Denominator parameters\".")))
88  return false;
89  denominator.push_back(value);
90  }
91  m_tf->SetNumerator(numerator);
92  m_tf->SetDenominator(denominator);
93  m_tf->UpdateTFText();
94  return true;
95 }
- +
Calculates the time response by a frequency domain transfer function.
diff --git a/docs/doxygen/html/_transfer_function_form_8h_source.html b/docs/doxygen/html/_transfer_function_form_8h_source.html index 1dfc2e7..e9187c9 100644 --- a/docs/doxygen/html/_transfer_function_form_8h_source.html +++ b/docs/doxygen/html/_transfer_function_form_8h_source.html @@ -89,7 +89,7 @@ $(document).ready(function(){initNavTree('_transfer_function_form_8h_source.html
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2017 Thales Lima Oliveira <thales@ufu.br>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program. If not, see <https://www.gnu.org/licenses/>.
16  */
17 
18 #ifndef TRANSFERFUNCTIONFORM_H
19 #define TRANSFERFUNCTIONFORM_H
20 
21 #include "ElementForm.h"
22 
23 class TransferFunction;
24 
33 {
34  public:
35  TransferFunctionForm(wxWindow* parent, TransferFunction* transferFunction);
36  virtual ~TransferFunctionForm();
37  bool ValidateData();
38 
39  protected:
40  virtual void OnCancelClick(wxCommandEvent& event);
41  virtual void OnOKClick(wxCommandEvent& event);
42  void LoadTFData();
43 
44  wxWindow* m_parent = NULL;
45  TransferFunction* m_tf = NULL;
46 };
47 #endif // TRANSFERFUNCTIONFORM_H
Form to edit the transfer function control data.
- +
Calculates the time response by a frequency domain transfer function.
diff --git a/docs/doxygen/html/_workspace_8cpp_source.html b/docs/doxygen/html/_workspace_8cpp_source.html index 6740df2..31adcfd 100644 --- a/docs/doxygen/html/_workspace_8cpp_source.html +++ b/docs/doxygen/html/_workspace_8cpp_source.html @@ -88,16 +88,16 @@ $(document).ready(function(){initNavTree('_workspace_8cpp_source.html','');});
Workspace.cpp
-
1 /*
2  * Copyright (C) 2017 Thales Lima Oliveira <thales@ufu.br>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program. If not, see <https://www.gnu.org/licenses/>.
16  */
17 
18 #include "Workspace.h"
19 #include "Camera.h"
20 #include "Element.h"
21 //#include "Bus.h"
22 #include "Line.h"
23 #include "Transformer.h"
24 #include "SyncGenerator.h"
25 #include "IndMotor.h"
26 #include "SyncMotor.h"
27 #include "Load.h"
28 #include "Inductor.h"
29 #include "Capacitor.h"
30 #include "ElementDataObject.h"
31 
32 #include "Text.h"
33 
34 #include "PowerFlow.h"
35 #include "Fault.h"
36 #include "Electromechanical.h"
37 
38 #include "ElementPlotData.h"
39 #include "ChartView.h"
40 
41 #include "PropertiesData.h"
42 
43 // Workspace
44 Workspace::Workspace() : WorkspaceBase(NULL) {}
45 Workspace::Workspace(wxWindow* parent, wxString name, wxStatusBar* statusBar) : WorkspaceBase(parent)
46 {
47  m_timer->Start();
48  m_name = name;
49  m_statusBar = statusBar;
50  m_glContext = new wxGLContext(m_glCanvas);
51  m_camera = new Camera();
52  m_selectionRect = wxRect2DDouble(0, 0, 0, 0);
53 
54  for(int i = 0; i < NUM_ELEMENTS; ++i) {
55  m_elementNumber[i] = 1;
56  }
57 
58  const int widths[4] = {-3, -1, 100, 100};
59  m_statusBar->SetStatusWidths(4, widths);
60 
61  m_properties = new PropertiesData();
62 }
63 
64 Workspace::~Workspace()
65 {
66  for(auto it = m_elementList.begin(), itEnd = m_elementList.end(); it != itEnd; ++it) {
67  if(*it) delete *it;
68  }
69  for(auto it = m_textList.begin(), itEnd = m_textList.end(); it != itEnd; ++it) {
70  if(*it) delete *it;
71  }
72  if(m_camera) delete m_camera;
73  if(m_glContext) delete m_glContext;
74  if(m_tipWindow) delete m_tipWindow;
75  if(m_properties) delete m_properties;
76 }
77 
78 void Workspace::OnPaint(wxPaintEvent& event)
79 {
80  wxPaintDC dc(m_glCanvas);
81  m_glContext->SetCurrent(*m_glCanvas);
82  SetViewport();
83 
84  // Set GLCanvas scale and translation.
85  glScaled(m_camera->GetScale(), m_camera->GetScale(), 0.0); // Scale
86  glTranslated(m_camera->GetTranslation().m_x, m_camera->GetTranslation().m_y, 0.0); // Translation
87 
88  // Draw
89 
90  // Elements
91  for(auto it = m_elementList.begin(); it != m_elementList.end(); ++it) {
92  Element* element = *it;
93  element->Draw(m_camera->GetTranslation(), m_camera->GetScale());
94  }
95 
96  // Texts
97  for(auto it = m_textList.begin(); it != m_textList.end(); ++it) {
98  Text* text = *it;
99  text->Draw(m_camera->GetTranslation(), m_camera->GetScale());
100  }
101 
102  // Selection rectangle
103  glLineWidth(1.0);
104  glColor4d(0.0, 0.5, 1.0, 1.0);
105  glBegin(GL_LINE_LOOP);
106  glVertex2d(m_selectionRect.m_x, m_selectionRect.m_y);
107  glVertex2d(m_selectionRect.m_x, m_selectionRect.m_y + m_selectionRect.m_height);
108  glVertex2d(m_selectionRect.m_x + m_selectionRect.m_width, m_selectionRect.m_y + m_selectionRect.m_height);
109  glVertex2d(m_selectionRect.m_x + m_selectionRect.m_width, m_selectionRect.m_y);
110  glEnd();
111  glColor4d(0.0, 0.5, 1.0, 0.3);
112  glBegin(GL_QUADS);
113  glVertex2d(m_selectionRect.m_x, m_selectionRect.m_y);
114  glVertex2d(m_selectionRect.m_x, m_selectionRect.m_y + m_selectionRect.m_height);
115  glVertex2d(m_selectionRect.m_x + m_selectionRect.m_width, m_selectionRect.m_y + m_selectionRect.m_height);
116  glVertex2d(m_selectionRect.m_x + m_selectionRect.m_width, m_selectionRect.m_y);
117  glEnd();
118 
119  glFlush(); // Sends all pending information directly to the GPU.
120  m_glCanvas->SwapBuffers();
121  event.Skip();
122 }
123 
124 void Workspace::SetViewport()
125 {
126  glClearColor(1.0, 1.0, 1.0, 1.0); // White background.
127  glClear(GL_COLOR_BUFFER_BIT);
128  glDisable(GL_DEPTH_TEST);
129  glDisable(GL_TEXTURE_2D);
130  glEnable(GL_COLOR_MATERIAL);
131  glEnable(GL_BLEND);
132  glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
133  glEnable(GL_LINE_SMOOTH);
134 
135  double width = m_glCanvas->GetSize().x - 1;
136  double height = m_glCanvas->GetSize().y - 1;
137 
138  // Viewport fit the screen.
139  glViewport(0, 0, width, height);
140 
141  glMatrixMode(GL_PROJECTION);
142  glLoadIdentity();
143  gluOrtho2D(0.0, width, height, 0.0);
144 
145  glMatrixMode(GL_MODELVIEW);
146  glLoadIdentity();
147 }
148 
149 void Workspace::OnLeftClickDown(wxMouseEvent& event)
150 {
151  wxPoint clickPoint = event.GetPosition();
152  bool foundElement = false;
153  Element* newElement = NULL;
154  bool showNewElementForm = false;
155  bool clickOnSwitch = false;
156  if(m_mode == MODE_INSERT_TEXT || m_mode == MODE_PASTE || m_mode == MODE_DRAG_PASTE) {
157  m_mode = MODE_EDIT;
158  } else if(m_mode == MODE_INSERT || m_mode == MODE_DRAG_INSERT || m_mode == MODE_DRAG_INSERT_TEXT) {
159  // Get the last element inserted on the list.
160  newElement = *(m_elementList.end() - 1);
161  for(auto it = m_elementList.begin(), itEnd = m_elementList.end(); it != itEnd; ++it) {
162  Element* element = *it;
163  // Clicked in any element.
164  if(element->Contains(m_camera->ScreenToWorld(clickPoint))) {
165  // Click at a bus.
166  if(typeid(*element) == typeid(Bus)) {
167  // Select the bus.
168  element->SetSelected();
169  foundElement = true; // Element found.
170  // Add the new element's parent. If the element being inserted returns true, back to
171  // edit mode.
172  if(newElement->AddParent(element, m_camera->ScreenToWorld(clickPoint))) {
173  ValidateElementsVoltages();
174  m_timer->Stop();
175  showNewElementForm = true;
176  m_mode = MODE_EDIT;
177  }
178  }
179  }
180  }
181  // The line element can have an indefined number of points.
182  if(!foundElement) {
183  if(typeid(*newElement) == typeid(Line)) {
184  newElement->AddPoint(m_camera->ScreenToWorld(clickPoint));
185  }
186  }
187  foundElement = true;
188  } else {
189  bool clickPickbox = false;
190  for(auto it = m_elementList.begin(), itEnd = m_elementList.end(); it != itEnd; ++it) {
191  PowerElement* element = *it;
192  element->ResetPickboxes(); // Reset pickbox state.
193 
194  // Set movement initial position (not necessarily will be moved).
195  element->StartMove(m_camera->ScreenToWorld(clickPoint));
196 
197  // Click in selected element node.
198  if(element->NodeContains(m_camera->ScreenToWorld(clickPoint)) != 0 && element->IsSelected()) {
199  m_mode = MODE_MOVE_NODE;
200  m_disconnectedElement = true;
201  foundElement = true;
202  }
203 
204  // Click in an element.
205  else if(element->Contains(m_camera->ScreenToWorld(clickPoint))) {
206  if(!foundElement) {
207  // Select and show pickbox.
208  element->SetSelected();
209  element->ShowPickbox();
210  foundElement = true;
211  }
212  // If pickbox contains the click, move the pickbox
213  if(element->PickboxContains(m_camera->ScreenToWorld(clickPoint))) {
214  m_mode = MODE_MOVE_PICKBOX;
215  clickPickbox = true;
216  }
217  // If didn't found a pickbox, move the element
218  if(!clickPickbox) {
219  m_mode = MODE_MOVE_ELEMENT;
220  }
221  }
222 
223  // Click in a switch.
224  else if(element->SwitchesContains(m_camera->ScreenToWorld(clickPoint))) {
225  element->SetOnline(element->IsOnline() ? false : true);
226  clickOnSwitch = true;
227  }
228  }
229 
230  // Text element
231  for(auto it = m_textList.begin(), itEnd = m_textList.end(); it != itEnd; ++it) {
232  Text* text = *it;
233 
234  text->StartMove(m_camera->ScreenToWorld(clickPoint));
235 
236  if(text->Contains(m_camera->ScreenToWorld(clickPoint))) {
237  if(!foundElement) {
238  text->SetSelected();
239  m_mode = MODE_MOVE_ELEMENT;
240  foundElement = true;
241  }
242  }
243  }
244  }
245 
246  if(!foundElement) {
247  m_mode = MODE_SELECTION_RECT;
248  m_startSelRect = m_camera->ScreenToWorld(clickPoint);
249  }
250 
251  Redraw();
252  UpdateStatusBar();
253 
254  if(showNewElementForm) {
255  if(newElement) {
256  newElement->ShowForm(this, newElement);
257  if(m_continuousCalc) RunStaticStudies();
258  }
259  }
260  if(clickOnSwitch && m_continuousCalc) RunStaticStudies();
261 
262  event.Skip();
263 }
264 
265 void Workspace::OnLeftDoubleClick(wxMouseEvent& event)
266 {
267  bool elementEdited = false;
268  bool clickOnSwitch = false;
269  bool redraw = false;
270 
271  for(auto it = m_elementList.begin(); it != m_elementList.end(); ++it) {
272  PowerElement* element = *it;
273 
274  // Click in an element.
275  if(element->Contains(m_camera->ScreenToWorld(event.GetPosition()))) {
276  bool elementIsBus = false;
277  Bus oldBus;
278  Bus* currentBus = NULL;
279  if((currentBus = dynamic_cast<Bus*>(element))) {
280  elementIsBus = true;
281  oldBus = *currentBus;
282  }
283  m_timer->Stop();
284  element->ShowForm(this, element);
285  elementEdited = true;
286  redraw = true;
287 
288  // If the edited element is a bus and was changed the rated voltage, this voltage must be
289  // propagated through the lines
290  if(elementIsBus) {
291  // The voltage was changed
292  if(oldBus.GetElectricalData().nominalVoltage != currentBus->GetElectricalData().nominalVoltage ||
293  oldBus.GetElectricalData().nominalVoltageUnit !=
294  currentBus->GetElectricalData().nominalVoltageUnit) {
295  // Check if the bus has line as child.
296  std::vector<Element*> childList = element->GetChildList();
297  for(auto itc = childList.begin(), itcEnd = childList.end(); itc != itcEnd; ++itc) {
298  Element* child = *itc;
299  if(typeid(*child) == typeid(Line)) {
300  wxMessageDialog msgDialog(this, _("Do you want to change the rated voltage of the path?"),
301  _("Warning"), wxYES_NO | wxCENTRE | wxICON_WARNING);
302  if(msgDialog.ShowModal() == wxID_YES)
303  ValidateBusesVoltages(element);
304  else {
305  auto data = currentBus->GetElectricalData();
306  data.nominalVoltage = oldBus.GetElectricalData().nominalVoltage;
307  data.nominalVoltageUnit = oldBus.GetElectricalData().nominalVoltageUnit;
308  currentBus->SetElectricalData(data);
309  }
310  break;
311  }
312  }
313  }
314  ValidateElementsVoltages();
315  }
316  }
317 
318  // Click in a switch.
319  else if(element->SwitchesContains(m_camera->ScreenToWorld(event.GetPosition()))) {
320  element->SetOnline(element->IsOnline() ? false : true);
321  clickOnSwitch = true;
322  }
323  }
324 
325  // Text element
326  for(auto it = m_textList.begin(); it != m_textList.end(); ++it) {
327  Text* text = *it;
328  if(text->Contains(m_camera->ScreenToWorld(event.GetPosition()))) {
329  text->ShowForm(this, GetElementList());
330  redraw = true;
331  }
332  }
333  if(elementEdited) {
334  UpdateTextElements();
335  if(m_continuousCalc) RunStaticStudies();
336  }
337  if(clickOnSwitch && m_continuousCalc) RunStaticStudies();
338 
339  if(redraw) Redraw();
340  m_timer->Start();
341 }
342 
343 void Workspace::OnRightClickDown(wxMouseEvent& event)
344 {
345  bool redraw = false;
346  if(m_mode == MODE_EDIT) {
347  for(auto it = m_elementList.begin(), itEnd = m_elementList.end(); it != itEnd; ++it) {
348  Element* element = *it;
349  if(element->IsSelected()) {
350  // Show context menu.
351  if(element->Contains(m_camera->ScreenToWorld(event.GetPosition()))) {
352  element->ShowPickbox(false);
353  wxMenu menu;
354  if(element->GetContextMenu(menu)) {
355  m_timer->Stop();
356  menu.SetClientData(element);
357  menu.Bind(wxEVT_COMMAND_MENU_SELECTED, &Workspace::OnPopupClick, this);
358  PopupMenu(&menu);
359  redraw = true;
360 
361  if(!menu.GetClientData()) break;
362  }
363  element->ResetPickboxes();
364  }
365  }
366  }
367  }
368  if(redraw) Redraw();
369  m_timer->Start();
370 }
371 
372 void Workspace::OnLeftClickUp(wxMouseEvent& event)
373 {
374  // This event (under certain conditions) deselects the elements and back to edit mode or select the elements using
375  // the selection rectangle.
376  bool foundPickbox = false;
377  bool findNewParent = false;
378  bool updateVoltages = false;
379  auto itnp = m_elementList.begin();
380 
381  for(auto it = m_elementList.begin(); it != m_elementList.end(); ++it) {
382  Element* element = *it;
383 
384  // The user was moving a pickbox.
385  if(m_mode == MODE_MOVE_PICKBOX) {
386  // Catch only the element that have the pickbox shown.
387  if(element->IsPickboxShown()) {
388  // If the element is a bus, check if a node is outside.
389  if(typeid(*element) == typeid(Bus)) {
390  // Get all the bus children.
391  for(int i = 0; i < (int)m_elementList.size(); i++) {
392  Element* child = m_elementList[i];
393  for(int j = 0; j < (int)child->GetParentList().size(); j++) {
394  Element* parent = child->GetParentList()[j];
395  // The child have a parent that is the element.
396  if(parent == element) {
397  child->UpdateNodes();
398  m_disconnectedElement = true;
399  }
400  }
401  }
402  }
403  }
404  }
405 
406  if(m_mode == MODE_SELECTION_RECT) {
407  if(element->Intersects(m_selectionRect)) {
408  element->SetSelected();
409  } else if(!event.ControlDown()) {
410  element->SetSelected(false);
411  }
412  } else if(m_mode == MODE_MOVE_NODE) {
413  if(element->IsSelected()) {
414  for(int i = 0; i < (int)m_elementList.size(); i++) {
415  Element* parent = m_elementList[i];
416  if(typeid(*parent) == typeid(Bus)) {
417  if(element->SetNodeParent(parent)) {
418  parent->AddChild(element);
419  findNewParent = true;
420  itnp = it;
421  element->ResetNodes();
422  break;
423  }
424  }
425  }
426  // element->ResetNodes();
427  }
428  } else {
429  // Deselect
430  if(!event.ControlDown()) {
431  if(!element->Contains(m_camera->ScreenToWorld(event.GetPosition()))) {
432  element->SetSelected(false);
433  }
434  }
435 
436  if(element->PickboxContains(m_camera->ScreenToWorld(event.GetPosition()))) {
437  foundPickbox = true;
438  } else {
439  element->ShowPickbox(false);
440  element->ResetPickboxes();
441  }
442  }
443  }
444 
445  // Text element
446  for(auto it = m_textList.begin(); it != m_textList.end(); it++) {
447  Text* text = *it;
448  if(m_mode == MODE_SELECTION_RECT) {
449  if(text->Intersects(m_selectionRect)) {
450  text->SetSelected();
451  } else if(!event.ControlDown()) {
452  text->SetSelected(false);
453  }
454  } else if(!event.ControlDown()) {
455  if(!text->Contains(m_camera->ScreenToWorld(event.GetPosition()))) {
456  text->SetSelected(false);
457  }
458  }
459  }
460 
461  if(findNewParent) {
462  std::rotate(itnp, itnp + 1, m_elementList.end());
463  updateVoltages = true;
464  }
465  if(!foundPickbox) {
466  SetCursor(wxCURSOR_ARROW);
467  }
468 
469  if(m_mode != MODE_INSERT) {
470  m_mode = MODE_EDIT;
471  }
472 
473  if(updateVoltages) {
474  ValidateElementsVoltages();
475  }
476 
477  if(m_continuousCalc && m_disconnectedElement) {
478  m_disconnectedElement = false;
479  RunStaticStudies();
480  }
481 
482  m_selectionRect = wxRect2DDouble(0, 0, 0, 0);
483  Redraw();
484  UpdateStatusBar();
485 }
486 
487 void Workspace::OnMouseMotion(wxMouseEvent& event)
488 {
489  bool redraw = false;
490  switch(m_mode) {
491  case MODE_INSERT: {
492  Element* newElement = *(m_elementList.end() - 1); // Get the last element in the list.
493  newElement->SetPosition(m_camera->ScreenToWorld(event.GetPosition()));
494  redraw = true;
495  } break;
496 
497  case MODE_INSERT_TEXT: {
498  Text* newText = *(m_textList.end() - 1);
499  newText->SetPosition(m_camera->ScreenToWorld(event.GetPosition()));
500  redraw = true;
501  } break;
502 
503  case MODE_DRAG:
504  case MODE_DRAG_INSERT:
505  case MODE_DRAG_INSERT_TEXT:
506  case MODE_DRAG_PASTE: {
507  m_camera->SetTranslation(event.GetPosition());
508  redraw = true;
509  } break;
510 
511  case MODE_EDIT: {
512  bool foundPickbox = false;
513  for(auto it = m_elementList.begin(); it != m_elementList.end(); ++it) {
514  Element* element = *it;
515  if(element->IsSelected()) {
516  // Show element pickbox (when it has) if the mouse is over the selected object.
517  if(element->Contains(m_camera->ScreenToWorld(event.GetPosition()))) {
518  element->ShowPickbox();
519  redraw = true;
520 
521  // If the mouse is over a pickbox set correct mouse cursor.
522  if(element->PickboxContains(m_camera->ScreenToWorld(event.GetPosition()))) {
523  foundPickbox = true;
524  SetCursor(element->GetBestPickboxCursor());
525  } else if(!foundPickbox) {
526  SetCursor(wxCURSOR_ARROW);
527  element->ResetPickboxes();
528  }
529  } else if(!foundPickbox) {
530  if(element->IsPickboxShown()) redraw = true;
531 
532  element->ShowPickbox(false);
533  element->ResetPickboxes();
534  SetCursor(wxCURSOR_ARROW);
535  }
536  }
537  }
538  } break;
539 
540  case MODE_MOVE_NODE: {
541  for(auto it = m_elementList.begin(); it != m_elementList.end(); ++it) {
542  Element* element = *it;
543  if(element->IsSelected()) {
544  element->MoveNode(NULL, m_camera->ScreenToWorld(event.GetPosition()));
545  redraw = true;
546  }
547  }
548  } break;
549 
550  case MODE_MOVE_PICKBOX: {
551  for(auto it = m_elementList.begin(); it != m_elementList.end(); ++it) {
552  Element* element = *it;
553  if(element->IsSelected()) {
554  element->MovePickbox(m_camera->ScreenToWorld(event.GetPosition()));
555  redraw = true;
556  }
557  }
558  } break;
559 
560  case MODE_MOVE_ELEMENT:
561  case MODE_PASTE: {
562  for(auto it = m_elementList.begin(), itEnd = m_elementList.end(); it != itEnd; ++it) {
563  Element* element = *it;
564  if(element->IsSelected()) {
565  element->Move(m_camera->ScreenToWorld(event.GetPosition()));
566  // Move child nodes
567  std::vector<Element*> childList = element->GetChildList();
568  for(auto it = childList.begin(), itEnd = childList.end(); it != itEnd; ++it) {
569  (*it)->MoveNode(element, m_camera->ScreenToWorld(event.GetPosition()));
570  }
571  redraw = true;
572  }
573  }
574  // Text element motion
575  for(auto it = m_textList.begin(), itEnd = m_textList.end(); it != itEnd; it++) {
576  Text* text = *it;
577  if(text->IsSelected()) {
578  text->Move(m_camera->ScreenToWorld(event.GetPosition()));
579  redraw = true;
580  }
581  }
582  } break;
583 
584  case MODE_SELECTION_RECT: {
585  wxPoint2DDouble currentPos = m_camera->ScreenToWorld(event.GetPosition());
586  double x, y, w, h;
587  if(currentPos.m_x < m_startSelRect.m_x) {
588  x = currentPos.m_x;
589  w = m_startSelRect.m_x - currentPos.m_x;
590  } else {
591  x = m_startSelRect.m_x;
592  w = currentPos.m_x - m_startSelRect.m_x;
593  }
594  if(currentPos.m_y < m_startSelRect.m_y) {
595  y = currentPos.m_y;
596  h = m_startSelRect.m_y - currentPos.m_y;
597  } else {
598  y = m_startSelRect.m_y;
599  h = currentPos.m_y - m_startSelRect.m_y;
600  }
601 
602  m_selectionRect = wxRect2DDouble(x, y, w, h);
603  redraw = true;
604  } break;
605  }
606 
607  if(redraw) Redraw();
608  m_camera->UpdateMousePosition(event.GetPosition());
609  UpdateStatusBar();
610  m_timer->Start(); // Restart the timer.
611  event.Skip();
612 }
613 
614 void Workspace::OnMiddleDown(wxMouseEvent& event)
615 {
616  // Set to drag mode.
617  switch(m_mode) {
618  case MODE_INSERT: {
619  m_mode = MODE_DRAG_INSERT;
620  } break;
621  case MODE_INSERT_TEXT: {
622  m_mode = MODE_DRAG_INSERT_TEXT;
623  } break;
624  case MODE_PASTE: {
625  m_mode = MODE_DRAG_PASTE;
626  } break;
627  default: {
628  m_mode = MODE_DRAG;
629  } break;
630  }
631  m_camera->StartTranslation(m_camera->ScreenToWorld(event.GetPosition()));
632  UpdateStatusBar();
633  event.Skip();
634 }
635 
636 void Workspace::OnMiddleUp(wxMouseEvent& event)
637 {
638  switch(m_mode) {
639  case MODE_DRAG_INSERT: {
640  m_mode = MODE_INSERT;
641  } break;
642  case MODE_DRAG_INSERT_TEXT: {
643  m_mode = MODE_INSERT_TEXT;
644  } break;
645  case MODE_DRAG_PASTE: {
646  m_mode = MODE_PASTE;
647  } break;
648  case MODE_INSERT:
649  case MODE_INSERT_TEXT:
650  case MODE_PASTE: {
651  // Does nothing.
652  } break;
653  default: {
654  m_mode = MODE_EDIT;
655  } break;
656  }
657  UpdateStatusBar();
658  event.Skip();
659 }
660 
661 void Workspace::OnScroll(wxMouseEvent& event)
662 {
663  if(event.GetWheelRotation() > 0)
664  m_camera->SetScale(event.GetPosition(), +0.05);
665  else
666  m_camera->SetScale(event.GetPosition(), -0.05);
667 
668  UpdateStatusBar();
669  Redraw();
670 }
671 
672 void Workspace::OnKeyDown(wxKeyEvent& event)
673 {
674  bool insertingElement = false;
675  if(m_mode == MODE_INSERT || m_mode == MODE_INSERT_TEXT) insertingElement = true;
676 
677  char key = event.GetUnicodeKey();
678  if(key != WXK_NONE) {
679  switch(key) {
680  case WXK_ESCAPE: // Cancel operations.
681  {
682  if(m_mode == MODE_INSERT) {
683  m_elementList.pop_back(); // Removes the last element being inserted.
684  m_mode = MODE_EDIT;
685  Redraw();
686  } else if(m_mode == MODE_INSERT_TEXT) {
687  m_textList.pop_back();
688  m_mode = MODE_EDIT;
689  Redraw();
690  }
691  } break;
692  case WXK_DELETE: // Delete selected elements
693  {
694  DeleteSelectedElements();
695  } break;
696  case 'A': {
697  if(!insertingElement) {
698  Text* newBus = new Text(m_camera->ScreenToWorld(event.GetPosition()));
699  m_textList.push_back(newBus);
700  m_mode = MODE_INSERT_TEXT;
701  m_statusBar->SetStatusText(_("Insert Text: Click to insert, ESC to cancel."));
702  Redraw();
703  }
704  } break;
705  case 'F': {
706  if(event.GetModifiers() == wxMOD_SHIFT) {
707  Fit();
708  }
709  } break;
710  case 'R': // Rotate the selected elements.
711  {
712  RotateSelectedElements(event.GetModifiers() != wxMOD_SHIFT);
713  } break;
714  case 'B': // Insert a bus.
715  {
716  if(!insertingElement) {
717  Bus* newBus = new Bus(m_camera->ScreenToWorld(event.GetPosition()),
718  wxString::Format(_("Bus %d"), GetElementNumber(ID_BUS)));
719  IncrementElementNumber(ID_BUS);
720  m_elementList.push_back(newBus);
721  m_mode = MODE_INSERT;
722  m_statusBar->SetStatusText(_("Insert Bus: Click to insert, ESC to cancel."));
723  Redraw();
724  }
725  } break;
726  case 'L': {
727  if(!insertingElement) {
728  if(!event.ControlDown() && event.ShiftDown()) { // Insert a load.
729  Load* newLoad = new Load(wxString::Format(_("Load %d"), GetElementNumber(ID_LOAD)));
730  IncrementElementNumber(ID_LOAD);
731  m_elementList.push_back(newLoad);
732  m_mode = MODE_INSERT;
733  m_statusBar->SetStatusText(_("Insert Load: Click on a buses, ESC to cancel."));
734  } else if(!event.ControlDown() && !event.ShiftDown()) { // Insert a power line.
735  Line* newLine = new Line(wxString::Format(_("Line %d"), GetElementNumber(ID_LINE)));
736  IncrementElementNumber(ID_LINE);
737  m_elementList.push_back(newLine);
738  m_mode = MODE_INSERT;
739  m_statusBar->SetStatusText(_("Insert Line: Click on two buses, ESC to cancel."));
740  }
741  Redraw();
742  }
743  // Tests - Ctrl + Shift + L
744  if(event.ControlDown() && event.ShiftDown()) {
745  // Nothing...
746  }
747  } break;
748  case 'T': // Insert a transformer.
749  {
750  if(!insertingElement) {
751  Transformer* newTransformer =
752  new Transformer(wxString::Format(_("Transformer %d"), GetElementNumber(ID_TRANSFORMER)));
753  IncrementElementNumber(ID_TRANSFORMER);
754  m_elementList.push_back(newTransformer);
755  m_mode = MODE_INSERT;
756  m_statusBar->SetStatusText(_("Insert Transformer: Click on two buses, ESC to cancel."));
757  Redraw();
758  }
759  } break;
760  case 'G': // Insert a generator.
761  {
762  if(!insertingElement) {
763  SyncGenerator* newGenerator =
764  new SyncGenerator(wxString::Format(_("Generator %d"), GetElementNumber(ID_SYNCGENERATOR)));
765  IncrementElementNumber(ID_SYNCGENERATOR);
766  m_elementList.push_back(newGenerator);
767  m_mode = MODE_INSERT;
768  m_statusBar->SetStatusText(_("Insert Generator: Click on a buses, ESC to cancel."));
769  Redraw();
770  }
771  } break;
772  case 'I': {
773  if(!insertingElement) {
774  if(event.GetModifiers() == wxMOD_SHIFT) { // Insert an inductor.
775  Inductor* newInductor =
776  new Inductor(wxString::Format(_("Inductor %d"), GetElementNumber(ID_INDUCTOR)));
777  IncrementElementNumber(ID_INDUCTOR);
778  m_elementList.push_back(newInductor);
779  m_mode = MODE_INSERT;
780  m_statusBar->SetStatusText(_("Insert Inductor: Click on a buses, ESC to cancel."));
781  } else // Insert an induction motor.
782  {
783  IndMotor* newIndMotor =
784  new IndMotor(wxString::Format(_("Induction motor %d"), GetElementNumber(ID_INDMOTOR)));
785  IncrementElementNumber(ID_INDMOTOR);
786  m_elementList.push_back(newIndMotor);
787  m_mode = MODE_INSERT;
788  m_statusBar->SetStatusText(_("Insert Induction Motor: Click on a buses, ESC to cancel."));
789  }
790  Redraw();
791  }
792  } break;
793  case 'K': // Insert a synchronous condenser.
794  {
795  if(!insertingElement) {
796  SyncMotor* newSyncCondenser =
797  new SyncMotor(wxString::Format(_("Synchronous condenser %d"), GetElementNumber(ID_SYNCMOTOR)));
798  IncrementElementNumber(ID_SYNCMOTOR);
799  m_elementList.push_back(newSyncCondenser);
800  m_mode = MODE_INSERT;
801  m_statusBar->SetStatusText(_("Insert Synchronous Condenser: Click on a buses, ESC to cancel."));
802  Redraw();
803  }
804  } break;
805  case 'C': {
806  if(!insertingElement) {
807  if(event.GetModifiers() == wxMOD_SHIFT) { // Insert a capacitor.
808  Capacitor* newCapacitor =
809  new Capacitor(wxString::Format(_("Capacitor %d"), GetElementNumber(ID_CAPACITOR)));
810  IncrementElementNumber(ID_CAPACITOR);
811  m_elementList.push_back(newCapacitor);
812  m_mode = MODE_INSERT;
813  m_statusBar->SetStatusText(_("Insert Capacitor: Click on a buses, ESC to cancel."));
814  Redraw();
815  } else if(event.GetModifiers() == wxMOD_CONTROL) { // Copy.
816  CopySelection();
817  }
818  }
819  } break;
820  case 'V': {
821  if(!insertingElement) {
822  if(event.GetModifiers() == wxMOD_CONTROL) {
823  Paste();
824  }
825  }
826  } break;
827  default:
828  break;
829  }
830  }
831 
832  UpdateStatusBar();
833  event.Skip();
834 }
835 
836 void Workspace::UpdateStatusBar()
837 {
838  switch(m_mode) {
839  case MODE_DRAG: {
840  m_statusBar->SetStatusText(_("MODE: DRAG"), 1);
841  } break;
842 
843  case MODE_PASTE:
844  case MODE_DRAG_PASTE: {
845  m_statusBar->SetStatusText(_("MODE: PASTE"), 1);
846  }
847 
848  case MODE_INSERT:
849  case MODE_INSERT_TEXT:
850  case MODE_DRAG_INSERT:
851  case MODE_DRAG_INSERT_TEXT: {
852  m_statusBar->SetStatusText(_("MODE: INSERT"), 1);
853  } break;
854 
855  case MODE_MOVE_ELEMENT:
856  case MODE_MOVE_PICKBOX:
857  case MODE_MOVE_NODE:
858  case MODE_SELECTION_RECT:
859  case MODE_EDIT: {
860  m_statusBar->SetStatusText(wxT(""));
861  m_statusBar->SetStatusText(_("MODE: EDIT"), 1);
862  } break;
863  }
864 
865  m_statusBar->SetStatusText(wxString::Format(_("ZOOM: %d%%"), (int)(m_camera->GetScale() * 100.0)), 2);
866  m_statusBar->SetStatusText(
867  wxString::Format(wxT("X: %.1f Y: %.1f"), m_camera->GetMousePosition().m_x, m_camera->GetMousePosition().m_y),
868  3);
869 }
870 
871 void Workspace::OnPopupClick(wxCommandEvent& event)
872 {
873  wxMenu* menu = static_cast<wxMenu*>(event.GetEventObject());
874  Element* element = static_cast<Element*>(menu->GetClientData());
875  switch(event.GetId()) {
876  case ID_EDIT_ELEMENT: {
877  if(element->ShowForm(this, element)) UpdateTextElements();
878  } break;
879  case ID_LINE_ADD_NODE: {
880  Line* line = static_cast<Line*>(element);
881  line->AddNode(m_camera->GetMousePosition());
882  Redraw();
883  } break;
884  case ID_LINE_REMOVE_NODE: {
885  Line* line = static_cast<Line*>(element);
886  line->RemoveNode(m_camera->GetMousePosition());
887  Redraw();
888  } break;
889  case ID_ROTATE_CLOCK: {
890  element->Rotate();
891  for(auto it = m_elementList.begin(); it != m_elementList.end(); ++it) {
892  Element* iElement = *it;
893  // Parent's element rotating...
894  for(int i = 0; i < (int)iElement->GetParentList().size(); i++) {
895  Element* parent = iElement->GetParentList()[i];
896  if(parent == element) {
897  iElement->RotateNode(parent);
898  }
899  }
900  }
901  Redraw();
902  } break;
903  case ID_ROTATE_COUNTERCLOCK: {
904  element->Rotate(false);
905  for(auto it = m_elementList.begin(); it != m_elementList.end(); ++it) {
906  Element* iElement = *it;
907  // Parent's element rotating...
908  for(int i = 0; i < (int)iElement->GetParentList().size(); i++) {
909  Element* parent = iElement->GetParentList()[i];
910  if(parent == element) {
911  iElement->RotateNode(parent, false);
912  }
913  }
914  }
915  Redraw();
916  } break;
917  case ID_DELETE: {
918  for(auto it = m_elementList.begin(), itEnd = m_elementList.end(); it != itEnd; ++it) {
919  Element* iElement = *it;
920 
921  if(element == iElement) {
922  // Remove child/parent.
923  std::vector<Element*> childList = element->GetChildList();
924  for(auto itc = childList.begin(), itEnd = childList.end(); itc != itEnd; ++itc) {
925  Element* child = *itc;
926  if(child) {
927  child->RemoveParent(element);
928  element->RemoveChild(child);
929  }
930  }
931  std::vector<Element*> parentList = element->GetParentList();
932  for(auto itp = parentList.begin(), itEnd = parentList.end(); itp != itEnd; ++itp) {
933  Element* parent = *itp;
934  if(parent) {
935  parent->RemoveChild(element);
936  }
937  }
938 
939  for(auto itt = m_textList.begin(); itt != m_textList.end(); ++itt) {
940  Text* text = *itt;
941  if(text->GetElement() == element) {
942  m_textList.erase(itt--);
943  if(text) delete text;
944  }
945  }
946 
947  m_elementList.erase(it);
948  if(element) delete element;
949  menu->SetClientData(NULL);
950  break;
951  }
952  }
953  } break;
954  }
955 }
956 
957 void Workspace::RotateSelectedElements(bool clockwise)
958 {
959  for(auto it = m_elementList.begin(); it != m_elementList.end(); ++it) {
960  Element* element = *it;
961  // Parent's element rotating...
962  for(int i = 0; i < (int)element->GetParentList().size(); i++) {
963  Element* parent = element->GetParentList()[i];
964  if(parent) { // Check if parent is not null
965  if(parent->IsSelected()) {
966  element->RotateNode(parent, clockwise);
967  // Update the positions used on motion action, the element will not be necessarily
968  // moved.
969  element->StartMove(m_camera->GetMousePosition());
970  }
971  }
972  }
973  if(element->IsSelected()) {
974  element->Rotate(clockwise);
975  element->StartMove(m_camera->GetMousePosition());
976  }
977  }
978 
979  // Rotate text element
980  for(auto it = m_textList.begin(); it != m_textList.end(); it++) {
981  Text* text = *it;
982  if(text->IsSelected()) {
983  text->Rotate(clockwise);
984  text->StartMove(m_camera->GetMousePosition());
985  }
986  }
987  Redraw();
988 }
989 
990 void Workspace::DeleteSelectedElements()
991 {
992  // Don't set the end of the list at the loop's begin.
993  for(auto it = m_elementList.begin(); it != m_elementList.end(); ++it) {
994  Element* element = *it;
995 
996  if(element->IsSelected()) {
997  // Remove child/parent.
998  std::vector<Element*> childList = element->GetChildList();
999  for(auto itc = childList.begin(), itEnd = childList.end(); itc != itEnd; ++itc) {
1000  Element* child = *itc;
1001  if(child) {
1002  child->RemoveParent(element);
1003  element->RemoveChild(child);
1004  }
1005  }
1006  std::vector<Element*> parentList = element->GetParentList();
1007  for(auto itp = parentList.begin(), itEnd = parentList.end(); itp != itEnd; ++itp) {
1008  Element* parent = *itp;
1009  if(parent) {
1010  parent->RemoveChild(element);
1011  }
1012  }
1013 
1014  for(auto itt = m_textList.begin(); itt != m_textList.end(); ++itt) {
1015  Text* text = *itt;
1016  if(text->GetElement() == element) {
1017  m_textList.erase(itt--);
1018  if(text) delete text;
1019  }
1020  }
1021 
1022  m_elementList.erase(it--);
1023  if(element) delete element;
1024  }
1025  }
1026 
1027  for(auto it = m_textList.begin(); it != m_textList.end(); ++it) {
1028  Text* text = *it;
1029  if(text->IsSelected()) {
1030  m_textList.erase(it--);
1031  if(text) delete text;
1032  }
1033  }
1034 
1035  Redraw();
1036 }
1037 
1038 bool Workspace::GetElementsCorners(wxPoint2DDouble& leftUpCorner,
1039  wxPoint2DDouble& rightDownCorner,
1040  std::vector<Element*> elementList)
1041 {
1042  if(elementList.size() == 0) return false;
1043 
1044  elementList[0]->CalculateBoundaries(leftUpCorner, rightDownCorner);
1045 
1046  for(auto it = elementList.begin() + 1, itEnd = elementList.end(); it != itEnd; it++) {
1047  Element* element = *it;
1048  wxPoint2DDouble leftUp;
1049  wxPoint2DDouble rightDown;
1050  element->CalculateBoundaries(leftUp, rightDown);
1051  if(leftUp.m_x < leftUpCorner.m_x) leftUpCorner.m_x = leftUp.m_x;
1052  if(leftUp.m_y < leftUpCorner.m_y) leftUpCorner.m_y = leftUp.m_y;
1053  if(rightDown.m_x > rightDownCorner.m_x) rightDownCorner.m_x = rightDown.m_x;
1054  if(rightDown.m_y > rightDownCorner.m_y) rightDownCorner.m_y = rightDown.m_y;
1055  }
1056  return true;
1057 }
1058 
1059 void Workspace::Fit()
1060 {
1061  wxPoint2DDouble leftUpCorner(0, 0);
1062  wxPoint2DDouble rightDownCorner(0, 0);
1063  std::vector<Element*> elementList = GetElementList();
1064  for(auto it = m_textList.begin(), itEnd = m_textList.end(); it != itEnd; ++it) {
1065  elementList.push_back(*it);
1066  }
1067 
1068  if(!GetElementsCorners(leftUpCorner, rightDownCorner, elementList)) return;
1069  wxPoint2DDouble middleCoords = (leftUpCorner + rightDownCorner) / 2.0;
1070 
1071  int width = 0.0;
1072  int height = 0.0;
1073  GetSize(&width, &height);
1074 
1075  double scaleX = double(width) / (rightDownCorner.m_x - leftUpCorner.m_x);
1076  double scaleY = double(height) / (rightDownCorner.m_y - leftUpCorner.m_y);
1077 
1078  double scale = scaleX < scaleY ? scaleX : scaleY;
1079  if(scale > m_camera->GetZoomMax()) scale = m_camera->GetZoomMax();
1080  if(scale < m_camera->GetZoomMin()) scale = m_camera->GetZoomMin();
1081 
1082  m_camera->SetScale(scale);
1083 
1084  m_camera->StartTranslation(middleCoords);
1085  m_camera->SetTranslation(wxPoint2DDouble(width / 2, height / 2));
1086  Redraw();
1087 }
1088 
1089 void Workspace::ValidateBusesVoltages(Element* initialBus)
1090 {
1091  double nominalVoltage = static_cast<Bus*>(initialBus)->GetElectricalData().nominalVoltage;
1092  ElectricalUnit nominalVoltageUnit = static_cast<Bus*>(initialBus)->GetElectricalData().nominalVoltageUnit;
1093 
1094  for(auto it = m_elementList.begin(); it != m_elementList.end(); it++) {
1095  Element* child = *it;
1096 
1097  if(typeid(*child) == typeid(Line)) {
1098  if(child->GetParentList()[0] && child->GetParentList()[1]) {
1099  BusElectricalData data1 = static_cast<Bus*>(child->GetParentList()[0])->GetElectricalData();
1100  BusElectricalData data2 = static_cast<Bus*>(child->GetParentList()[1])->GetElectricalData();
1101 
1102  if(data1.nominalVoltage != data2.nominalVoltage ||
1103  data1.nominalVoltageUnit != data2.nominalVoltageUnit) {
1104  data1.nominalVoltage = nominalVoltage;
1105  data2.nominalVoltage = nominalVoltage;
1106  data1.nominalVoltageUnit = nominalVoltageUnit;
1107  data2.nominalVoltageUnit = nominalVoltageUnit;
1108 
1109  static_cast<Bus*>(child->GetParentList()[0])->SetElectricalData(data1);
1110  static_cast<Bus*>(child->GetParentList()[1])->SetElectricalData(data2);
1111 
1112  it = m_elementList.begin(); // Restart search.
1113  }
1114  }
1115  }
1116  }
1117 
1118  // ValidateElementsVoltages();
1119 }
1120 
1121 void Workspace::ValidateElementsVoltages()
1122 {
1123  for(auto it = m_elementList.begin(); it != m_elementList.end(); it++) {
1124  PowerElement* child = *it;
1125 
1126  std::vector<double> nominalVoltage;
1127  std::vector<ElectricalUnit> nominalVoltageUnit;
1128  for(int i = 0; i < (int)child->GetParentList().size(); i++) {
1129  Bus* parent = static_cast<Bus*>(child->GetParentList()[i]);
1130  if(parent) {
1131  nominalVoltage.push_back(parent->GetElectricalData().nominalVoltage);
1132  nominalVoltageUnit.push_back(parent->GetElectricalData().nominalVoltageUnit);
1133  }
1134  }
1135  child->SetNominalVoltage(nominalVoltage, nominalVoltageUnit);
1136  }
1137 }
1138 
1139 bool Workspace::RunPowerFlow()
1140 {
1141  PowerFlow pf(GetElementList());
1142  bool result = pf.RunGaussSeidel();
1143  if(!result) {
1144  wxMessageDialog msgDialog(this, pf.GetErrorMessage(), _("Error"), wxOK | wxCENTRE | wxICON_ERROR);
1145  msgDialog.ShowModal();
1146  }
1147 
1148  UpdateTextElements();
1149  Redraw();
1150 
1151  return result;
1152 }
1153 
1154 void Workspace::UpdateTextElements()
1155 {
1156  for(auto it = m_textList.begin(), itEnd = m_textList.end(); it != itEnd; ++it) {
1157  Text* text = *it;
1158  text->UpdateText(m_properties->GetSimulationPropertiesData().basePower);
1159  }
1160 }
1161 
1162 void Workspace::CopySelection()
1163 {
1164  UpdateElementsID();
1165  std::vector<Element*> selectedElements;
1166  // The buses need to be numerated to associate the child's parents to the copies.
1167  int busNumber = 0;
1168  for(auto it = m_elementList.begin(), itEnd = m_elementList.end(); it != itEnd; ++it) {
1169  Element* element = *it;
1170  if(typeid(*element) == typeid(Bus)) {
1171  Bus* bus = static_cast<Bus*>(element);
1172  auto data = bus->GetElectricalData();
1173  data.number = busNumber;
1174  bus->SetElectricalData(data);
1175  busNumber++;
1176  }
1177  if(element->IsSelected()) {
1178  selectedElements.push_back(element);
1179  }
1180  }
1181  for(auto it = m_textList.begin(), itEnd = m_textList.end(); it != itEnd; ++it) {
1182  Text* text = *it;
1183  if(text->IsSelected()) {
1184  selectedElements.push_back(text);
1185  }
1186  }
1187  ElementDataObject* dataObject = new ElementDataObject(selectedElements);
1188  wxTheClipboard->SetData(dataObject);
1189  wxTheClipboard->Close();
1190 }
1191 
1192 bool Workspace::Paste()
1193 {
1194  if(wxTheClipboard->Open()) {
1195  ElementDataObject dataObject;
1196 
1197  if(wxTheClipboard->IsSupported(wxDataFormat("PSPCopy"))) {
1198  if(!wxTheClipboard->GetData(dataObject)) {
1199  wxMessageDialog dialog(this, _("It was not possible to paste from clipboard."), _("Error"),
1200  wxOK | wxCENTER | wxICON_ERROR, wxDefaultPosition);
1201  dialog.ShowModal();
1202  wxTheClipboard->Close();
1203  return false;
1204  }
1205  } else {
1206  wxTheClipboard->Close();
1207  return false;
1208  }
1209  wxTheClipboard->Close();
1210 
1211  UnselectAll();
1212 
1213  std::vector<Element*> pastedElements;
1214  ElementsLists* elementsLists = dataObject.GetElementsLists();
1215 
1216  // Paste buses (parents).
1217  auto parentList = elementsLists->parentList;
1218  std::vector<Bus*> pastedBusList; // To set new parents;
1219  for(auto it = parentList.begin(), itEnd = parentList.end(); it != itEnd; ++it) {
1220  Element* copy = (*it)->GetCopy();
1221  if(copy) {
1222  pastedElements.push_back(copy);
1223  pastedBusList.push_back(static_cast<Bus*>(copy));
1224  m_elementList.push_back(static_cast<PowerElement*>(copy));
1225  }
1226  }
1227 
1228  // Paste other elements.
1229  auto elementLists = elementsLists->elementList;
1230  for(auto it = elementLists.begin(), itEnd = elementLists.end(); it != itEnd; ++it) {
1231  Element* copy = (*it)->GetCopy();
1232  if(copy) {
1233  // Check if is text element
1234  if(Text* text = dynamic_cast<Text*>(copy)) {
1235  // Check if element associated with the text exists.
1236  bool elementExist = false;
1237  for(int i = 0; i < (int)m_elementList.size(); i++) {
1238  if(text->GetElement() == m_elementList[i]) {
1239  elementExist = true;
1240  break;
1241  }
1242  }
1243  if(elementExist) {
1244  pastedElements.push_back(copy);
1245  m_textList.push_back(text);
1246  }
1247  } else {
1248  // Change the parent if copied, otherwise remove it.
1249  for(int j = 0; j < (int)copy->GetParentList().size(); j++) {
1250  Bus* currentParent = static_cast<Bus*>(copy->GetParentList()[j]);
1251  if(currentParent) {
1252  int parentID = currentParent->GetID();
1253  bool parentCopied = false;
1254  for(int k = 0; k < (int)pastedBusList.size(); k++) {
1255  Bus* newParent = pastedBusList[k];
1256  if(parentID == newParent->GetID()) {
1257  parentCopied = true;
1258  copy->ReplaceParent(currentParent, newParent);
1259  break;
1260  }
1261  }
1262  if(!parentCopied) copy->RemoveParent(currentParent);
1263  }
1264  }
1265 
1266  pastedElements.push_back(copy);
1267  m_elementList.push_back(static_cast<PowerElement*>(copy));
1268  }
1269  }
1270  }
1271 
1272  // Update buses childs
1273  for(auto it = pastedBusList.begin(), itEnd = pastedBusList.end(); it != itEnd; ++it) {
1274  Bus* bus = *it;
1275  std::vector<Element*> childList = bus->GetChildList();
1276  for(auto it = childList.begin(), itEnd = childList.end(); it != itEnd; ++it) {
1277  Element* currentChild = *it;
1278  int childID = currentChild->GetID();
1279  bool childCopied = false;
1280  for(int i = 0; i < (int)pastedElements.size(); i++) {
1281  Element* newChild = pastedElements[i];
1282  if(childID == newChild->GetID()) {
1283  childCopied = true;
1284  bus->ReplaceChild(currentChild, newChild);
1285  break;
1286  }
1287  }
1288  if(!childCopied) bus->RemoveChild(currentChild);
1289  }
1290  }
1291 
1292  // Move elements (and nodes) to the mouse position.
1293  // The start position it's the center of the pasted objects.
1294  wxPoint2DDouble leftUpCorner, rightDownCorner;
1295  GetElementsCorners(leftUpCorner, rightDownCorner, pastedElements);
1296  wxPoint2DDouble startPosition = (leftUpCorner + rightDownCorner) / 2.0;
1297  for(auto it = pastedElements.begin(), itEnd = pastedElements.end(); it != itEnd; ++it) {
1298  Element* element = *it;
1299  element->StartMove(startPosition);
1300  element->Move(m_camera->GetMousePosition());
1301  for(int i = 0; i < (int)element->GetParentList().size(); i++) {
1302  Element* parent = element->GetParentList()[i];
1303  element->MoveNode(parent, m_camera->GetMousePosition());
1304  }
1305  }
1306  } else {
1307  wxMessageDialog dialog(this, _("It was not possible to paste from clipboard."), _("Error"),
1308  wxOK | wxCENTER | wxICON_ERROR, wxDefaultPosition);
1309  dialog.ShowModal();
1310  return false;
1311  }
1312 
1313  UpdateElementsID();
1314  m_mode = MODE_PASTE;
1315  m_statusBar->SetStatusText(_("Click to paste."));
1316  UpdateStatusBar();
1317  Redraw();
1318  return true;
1319 }
1320 
1321 void Workspace::UnselectAll()
1322 {
1323  for(auto it = m_elementList.begin(), itEnd = m_elementList.end(); it != itEnd; it++) {
1324  Element* element = *it;
1325  element->SetSelected(false);
1326  }
1327  for(auto it = m_textList.begin(), itEnd = m_textList.end(); it != itEnd; it++) {
1328  Text* text = *it;
1329  text->SetSelected(false);
1330  }
1331 }
1332 
1333 void Workspace::UpdateElementsID()
1334 {
1335  int id = 0;
1336  for(auto it = m_elementList.begin(), itEnd = m_elementList.end(); it != itEnd; ++it) {
1337  Element* element = *it;
1338  element->SetID(id);
1339  id++;
1340  }
1341  for(auto it = m_textList.begin(), itEnd = m_textList.end(); it != itEnd; ++it) {
1342  Text* text = *it;
1343  text->SetID(id);
1344  id++;
1345  }
1346 }
1347 void Workspace::OnTimer(wxTimerEvent& event)
1348 {
1349  if(m_tipWindow) {
1350  m_tipWindow->Close();
1351  m_tipWindow = NULL;
1352  }
1353  if(m_mode == MODE_EDIT) {
1354  for(auto it = m_elementList.begin(), itEnd = m_elementList.end(); it != itEnd; ++it) {
1355  Element* element = *it;
1356  if(element->Contains(m_camera->GetMousePosition())) {
1357  wxString tipText = element->GetTipText();
1358  if(!tipText.IsEmpty()) {
1359  m_tipWindow = new wxTipWindow(this, tipText, 10000, &m_tipWindow);
1360  // Creates a very tiny bounding rect to remove the tip on any mouse movement.
1361  m_tipWindow->SetBoundingRect(wxRect(wxGetMousePosition(), wxSize(1, 1)));
1362  break;
1363  }
1364  }
1365  }
1366  }
1367 
1368  m_timer->Stop();
1369 }
1370 
1371 void Workspace::SetTextList(std::vector<Text*> textList)
1372 {
1373  m_textList.clear();
1374  for(auto it = textList.begin(), itEnd = textList.end(); it != itEnd; ++it) m_textList.push_back(*it);
1375 
1376  UpdateTextElements();
1377 }
1378 
1379 void Workspace::SetElementList(std::vector<Element*> elementList)
1380 {
1381  m_elementList.clear();
1382  for(auto it = elementList.begin(), itEnd = elementList.end(); it != itEnd; ++it)
1383  m_elementList.push_back(static_cast<PowerElement*>(*it));
1384 }
1385 
1386 void Workspace::OnIdle(wxIdleEvent& event)
1387 {
1388  // TODO: Find other solution to text displayed wrong on opened file.
1389  if(m_justOpened) {
1390  m_justOpened = false;
1391  UpdateTextElements();
1392  Redraw();
1393  }
1394 }
1395 
1396 std::vector<Element*> Workspace::GetAllElements() const
1397 {
1398  std::vector<Element*> allElements;
1399 
1400  for(auto it = m_elementList.begin(), itEnd = m_elementList.end(); it != itEnd; ++it) allElements.push_back(*it);
1401  for(auto it = m_textList.begin(), itEnd = m_textList.end(); it != itEnd; ++it) allElements.push_back(*it);
1402 
1403  return allElements;
1404 }
1405 
1406 bool Workspace::RunFault()
1407 {
1408  Fault fault(GetElementList());
1409  bool result = fault.RunFaultCalculation(100e6);
1410  if(!result) {
1411  wxMessageDialog msgDialog(this, fault.GetErrorMessage(), _("Error"), wxOK | wxCENTRE | wxICON_ERROR);
1412  msgDialog.ShowModal();
1413  }
1414 
1415  UpdateTextElements();
1416  Redraw();
1417 
1418  return result;
1419 }
1420 
1421 std::vector<Element*> Workspace::GetElementList() const
1422 {
1423  std::vector<Element*> elementList;
1424  for(auto it = m_elementList.begin(), itEnd = m_elementList.end(); it != itEnd; ++it) elementList.push_back(*it);
1425  return elementList;
1426 }
1427 
1428 bool Workspace::RunSCPower()
1429 {
1430  Fault fault(GetElementList());
1431  bool result = fault.RunSCPowerCalcutation(100e6);
1432  if(!result) {
1433  wxMessageDialog msgDialog(this, fault.GetErrorMessage(), _("Error"), wxOK | wxCENTRE | wxICON_ERROR);
1434  msgDialog.ShowModal();
1435  }
1436 
1437  UpdateTextElements();
1438  Redraw();
1439 
1440  return result;
1441 }
1442 
1443 bool Workspace::RunStability()
1444 {
1445  // Run power flow before stability.
1446  RunPowerFlow();
1447 
1448  Electromechanical stability(this, GetElementList(), m_properties->GetSimulationPropertiesData());
1449  bool result = stability.RunStabilityCalculation();
1450  if(!result) {
1451  wxMessageDialog msgDialog(this, stability.GetErrorMessage(), _("Error"), wxOK | wxCENTRE | wxICON_ERROR);
1452  msgDialog.ShowModal();
1453  }
1454  m_stabilityTimeVector.clear();
1455  m_stabilityTimeVector = stability.GetTimeVector();
1456 
1457  // Run power flow after stability.
1458  RunPowerFlow();
1459 
1460  wxMessageDialog msgDialog(this, _("Do you wish to open the stability graphics?"), _("Question"),
1461  wxYES_NO | wxCENTRE | wxICON_QUESTION);
1462  if(msgDialog.ShowModal() == wxID_YES) {
1463  std::vector<ElementPlotData> plotDataList;
1464  for(auto it = m_elementList.begin(), itEnd = m_elementList.end(); it != itEnd; ++it) {
1465  PowerElement* element = *it;
1466  ElementPlotData plotData;
1467  if(element->GetPlotData(plotData)) plotDataList.push_back(plotData);
1468  }
1469  ElementPlotData tests(_("Error"), ElementPlotData::CT_TEST);
1470  tests.AddData(stability.m_wErrorVector, _("Speed error"));
1471  tests.AddData(stability.m_sdCVector, _("Sd"));
1472  tests.AddData(stability.m_sqCVector, _("Sq"));
1473  tests.AddData(stability.m_numItVector, _("Number iterations"));
1474  plotDataList.push_back(tests);
1475 
1476  ChartView* cView = new ChartView(this, plotDataList, m_stabilityTimeVector);
1477  cView->Show();
1478  }
1479 
1480  return result;
1481 }
1482 void Workspace::OnMiddleDoubleClick(wxMouseEvent& event)
1483 {
1484  Fit();
1485  event.Skip();
1486 }
1487 
1488 bool Workspace::RunStaticStudies()
1489 {
1490  bool pfStatus, faultStatus, scStatus;
1491  pfStatus = faultStatus = scStatus = false;
1492 
1493  pfStatus = RunPowerFlow();
1494 
1495  if(m_properties->GetSimulationPropertiesData().faultAfterPowerFlow) {
1496  if(pfStatus) faultStatus = RunFault();
1497  } else {
1498  faultStatus = true;
1499  }
1500 
1501  if(m_properties->GetSimulationPropertiesData().scPowerAfterPowerFlow) {
1502  if(pfStatus) scStatus = RunSCPower();
1503  } else {
1504  scStatus = true;
1505  }
1506 
1507  if(pfStatus && faultStatus && scStatus) return true;
1508 
1509  return false;
1510 }
virtual bool Contains(wxPoint2DDouble position) const
Checks if the element contains a position.
Definition: Text.cpp:47
-
Element that shows power element informations in workspace.
Definition: Text.h:72
+
1 /*
2  * Copyright (C) 2017 Thales Lima Oliveira <thales@ufu.br>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program. If not, see <https://www.gnu.org/licenses/>.
16  */
17 
18 #include "Workspace.h"
19 #include "Camera.h"
20 #include "Element.h"
21 //#include "Bus.h"
22 #include "Line.h"
23 #include "Transformer.h"
24 #include "SyncGenerator.h"
25 #include "IndMotor.h"
26 #include "SyncMotor.h"
27 #include "Load.h"
28 #include "Inductor.h"
29 #include "Capacitor.h"
30 #include "ElementDataObject.h"
31 
32 #include "Text.h"
33 
34 #include "PowerFlow.h"
35 #include "Fault.h"
36 #include "Electromechanical.h"
37 
38 #include "ElementPlotData.h"
39 #include "ChartView.h"
40 
41 #include "PropertiesData.h"
42 
43 // Workspace
44 Workspace::Workspace() : WorkspaceBase(NULL) {}
45 Workspace::Workspace(wxWindow* parent, wxString name, wxStatusBar* statusBar, wxGLContext* sharedGLContext) : WorkspaceBase(parent)
46 {
47  m_timer->Start();
48  m_name = name;
49  m_statusBar = statusBar;
50  m_glContext = new wxGLContext(m_glCanvas, sharedGLContext);
51  m_camera = new Camera();
52  m_selectionRect = wxRect2DDouble(0, 0, 0, 0);
53 
54  for(int i = 0; i < NUM_ELEMENTS; ++i) {
55  m_elementNumber[i] = 1;
56  }
57 
58  const int widths[4] = {-3, -1, 100, 100};
59  m_statusBar->SetStatusWidths(4, widths);
60 
61  m_properties = new PropertiesData();
62 }
63 
64 Workspace::~Workspace()
65 {
66  for(auto it = m_elementList.begin(), itEnd = m_elementList.end(); it != itEnd; ++it) {
67  if(*it) delete *it;
68  }
69  for(auto it = m_textList.begin(), itEnd = m_textList.end(); it != itEnd; ++it) {
70  if(*it) delete *it;
71  }
72  if(m_camera) delete m_camera;
73  if(m_glContext) delete m_glContext;
74  if(m_tipWindow) delete m_tipWindow;
75  if(m_properties) delete m_properties;
76 }
77 
78 void Workspace::OnPaint(wxPaintEvent& event)
79 {
80  if(!m_glCanvas->IsShown()) return;
81 
82  wxPaintDC dc(m_glCanvas);
83  m_glContext->SetCurrent(*m_glCanvas);
84  SetViewport();
85 
86  // Set GLCanvas scale and translation.
87  glScaled(m_camera->GetScale(), m_camera->GetScale(), 0.0); // Scale
88  glTranslated(m_camera->GetTranslation().m_x, m_camera->GetTranslation().m_y, 0.0); // Translation
89 
90  // Draw
91 
92  // Elements
93  for(auto it = m_elementList.begin(); it != m_elementList.end(); ++it) {
94  Element* element = *it;
95  element->Draw(m_camera->GetTranslation(), m_camera->GetScale());
96  }
97 
98  // Texts
99  for(auto it = m_textList.begin(); it != m_textList.end(); ++it) {
100  Text* text = *it;
101  text->Draw(m_camera->GetTranslation(), m_camera->GetScale());
102  }
103 
104  // Selection rectangle
105  glLineWidth(1.0);
106  glColor4d(0.0, 0.5, 1.0, 1.0);
107  glBegin(GL_LINE_LOOP);
108  glVertex2d(m_selectionRect.m_x, m_selectionRect.m_y);
109  glVertex2d(m_selectionRect.m_x, m_selectionRect.m_y + m_selectionRect.m_height);
110  glVertex2d(m_selectionRect.m_x + m_selectionRect.m_width, m_selectionRect.m_y + m_selectionRect.m_height);
111  glVertex2d(m_selectionRect.m_x + m_selectionRect.m_width, m_selectionRect.m_y);
112  glEnd();
113  glColor4d(0.0, 0.5, 1.0, 0.3);
114  glBegin(GL_QUADS);
115  glVertex2d(m_selectionRect.m_x, m_selectionRect.m_y);
116  glVertex2d(m_selectionRect.m_x, m_selectionRect.m_y + m_selectionRect.m_height);
117  glVertex2d(m_selectionRect.m_x + m_selectionRect.m_width, m_selectionRect.m_y + m_selectionRect.m_height);
118  glVertex2d(m_selectionRect.m_x + m_selectionRect.m_width, m_selectionRect.m_y);
119  glEnd();
120 
121  glFlush(); // Sends all pending information directly to the GPU.
122  m_glCanvas->SwapBuffers();
123  event.Skip();
124 }
125 
126 void Workspace::SetViewport()
127 {
128  glClearColor(1.0, 1.0, 1.0, 1.0); // White background.
129  glClear(GL_COLOR_BUFFER_BIT);
130  glDisable(GL_DEPTH_TEST);
131  glDisable(GL_TEXTURE_2D);
132  glEnable(GL_COLOR_MATERIAL);
133  glEnable(GL_BLEND);
134  glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
135  glEnable(GL_LINE_SMOOTH);
136 
137  double width = m_glCanvas->GetSize().x - 1;
138  double height = m_glCanvas->GetSize().y - 1;
139 
140  // Viewport fit the screen.
141  glViewport(0, 0, width, height);
142 
143  glMatrixMode(GL_PROJECTION);
144  glLoadIdentity();
145  gluOrtho2D(0.0, width, height, 0.0);
146 
147  glMatrixMode(GL_MODELVIEW);
148  glLoadIdentity();
149 }
150 
151 void Workspace::OnLeftClickDown(wxMouseEvent& event)
152 {
153  wxPoint clickPoint = event.GetPosition();
154  bool foundElement = false;
155  Element* newElement = NULL;
156  bool showNewElementForm = false;
157  bool clickOnSwitch = false;
158  if(m_mode == MODE_INSERT_TEXT || m_mode == MODE_PASTE || m_mode == MODE_DRAG_PASTE) {
159  m_mode = MODE_EDIT;
160  } else if(m_mode == MODE_INSERT || m_mode == MODE_DRAG_INSERT || m_mode == MODE_DRAG_INSERT_TEXT) {
161  // Get the last element inserted on the list.
162  newElement = *(m_elementList.end() - 1);
163  for(auto it = m_elementList.begin(), itEnd = m_elementList.end(); it != itEnd; ++it) {
164  Element* element = *it;
165  // Clicked in any element.
166  if(element->Contains(m_camera->ScreenToWorld(clickPoint))) {
167  // Click at a bus.
168  if(typeid(*element) == typeid(Bus)) {
169  // Select the bus.
170  element->SetSelected();
171  foundElement = true; // Element found.
172  // Add the new element's parent. If the element being inserted returns true, back to
173  // edit mode.
174  if(newElement->AddParent(element, m_camera->ScreenToWorld(clickPoint))) {
175  ValidateElementsVoltages();
176  m_timer->Stop();
177  showNewElementForm = true;
178  m_mode = MODE_EDIT;
179  }
180  }
181  }
182  }
183  // The line element can have an indefined number of points.
184  if(!foundElement) {
185  if(typeid(*newElement) == typeid(Line)) {
186  newElement->AddPoint(m_camera->ScreenToWorld(clickPoint));
187  }
188  }
189  foundElement = true;
190  } else {
191  bool clickPickbox = false;
192  for(auto it = m_elementList.begin(), itEnd = m_elementList.end(); it != itEnd; ++it) {
193  PowerElement* element = *it;
194  element->ResetPickboxes(); // Reset pickbox state.
195 
196  // Set movement initial position (not necessarily will be moved).
197  element->StartMove(m_camera->ScreenToWorld(clickPoint));
198 
199  // Click in selected element node.
200  if(element->NodeContains(m_camera->ScreenToWorld(clickPoint)) != 0 && element->IsSelected()) {
201  m_mode = MODE_MOVE_NODE;
202  m_disconnectedElement = true;
203  foundElement = true;
204  }
205 
206  // Click in an element.
207  else if(element->Contains(m_camera->ScreenToWorld(clickPoint))) {
208  if(!foundElement) {
209  // Select and show pickbox.
210  element->SetSelected();
211  element->ShowPickbox();
212  foundElement = true;
213  }
214  // If pickbox contains the click, move the pickbox
215  if(element->PickboxContains(m_camera->ScreenToWorld(clickPoint))) {
216  m_mode = MODE_MOVE_PICKBOX;
217  clickPickbox = true;
218  }
219  // If didn't found a pickbox, move the element
220  if(!clickPickbox) {
221  m_mode = MODE_MOVE_ELEMENT;
222  }
223  }
224 
225  // Click in a switch.
226  else if(element->SwitchesContains(m_camera->ScreenToWorld(clickPoint))) {
227  element->SetOnline(element->IsOnline() ? false : true);
228  clickOnSwitch = true;
229  }
230  }
231 
232  // Text element
233  for(auto it = m_textList.begin(), itEnd = m_textList.end(); it != itEnd; ++it) {
234  Text* text = *it;
235 
236  text->StartMove(m_camera->ScreenToWorld(clickPoint));
237 
238  if(text->Contains(m_camera->ScreenToWorld(clickPoint))) {
239  if(!foundElement) {
240  text->SetSelected();
241  m_mode = MODE_MOVE_ELEMENT;
242  foundElement = true;
243  }
244  }
245  }
246  }
247 
248  if(!foundElement) {
249  m_mode = MODE_SELECTION_RECT;
250  m_startSelRect = m_camera->ScreenToWorld(clickPoint);
251  }
252 
253  Redraw();
254  UpdateStatusBar();
255 
256  if(showNewElementForm) {
257  if(newElement) {
258  newElement->ShowForm(this, newElement);
259  if(m_continuousCalc) RunStaticStudies();
260  }
261  }
262  if(clickOnSwitch && m_continuousCalc) RunStaticStudies();
263 
264  event.Skip();
265 }
266 
267 void Workspace::OnLeftDoubleClick(wxMouseEvent& event)
268 {
269  bool elementEdited = false;
270  bool clickOnSwitch = false;
271  bool redraw = false;
272 
273  for(auto it = m_elementList.begin(); it != m_elementList.end(); ++it) {
274  PowerElement* element = *it;
275 
276  // Click in an element.
277  if(element->Contains(m_camera->ScreenToWorld(event.GetPosition()))) {
278  bool elementIsBus = false;
279  Bus oldBus;
280  Bus* currentBus = NULL;
281  if((currentBus = dynamic_cast<Bus*>(element))) {
282  elementIsBus = true;
283  oldBus = *currentBus;
284  }
285  m_timer->Stop();
286  element->ShowForm(this, element);
287  elementEdited = true;
288  redraw = true;
289 
290  // If the edited element is a bus and was changed the rated voltage, this voltage must be
291  // propagated through the lines
292  if(elementIsBus) {
293  // The voltage was changed
294  if(oldBus.GetElectricalData().nominalVoltage != currentBus->GetElectricalData().nominalVoltage ||
295  oldBus.GetElectricalData().nominalVoltageUnit !=
296  currentBus->GetElectricalData().nominalVoltageUnit) {
297  // Check if the bus has line as child.
298  std::vector<Element*> childList = element->GetChildList();
299  for(auto itc = childList.begin(), itcEnd = childList.end(); itc != itcEnd; ++itc) {
300  Element* child = *itc;
301  if(typeid(*child) == typeid(Line)) {
302  wxMessageDialog msgDialog(this, _("Do you want to change the rated voltage of the path?"),
303  _("Warning"), wxYES_NO | wxCENTRE | wxICON_WARNING);
304  if(msgDialog.ShowModal() == wxID_YES)
305  ValidateBusesVoltages(element);
306  else {
307  auto data = currentBus->GetElectricalData();
308  data.nominalVoltage = oldBus.GetElectricalData().nominalVoltage;
309  data.nominalVoltageUnit = oldBus.GetElectricalData().nominalVoltageUnit;
310  currentBus->SetElectricalData(data);
311  }
312  break;
313  }
314  }
315  }
316  ValidateElementsVoltages();
317  }
318  }
319 
320  // Click in a switch.
321  else if(element->SwitchesContains(m_camera->ScreenToWorld(event.GetPosition()))) {
322  element->SetOnline(element->IsOnline() ? false : true);
323  clickOnSwitch = true;
324  }
325  }
326 
327  // Text element
328  for(auto it = m_textList.begin(); it != m_textList.end(); ++it) {
329  Text* text = *it;
330  if(text->Contains(m_camera->ScreenToWorld(event.GetPosition()))) {
331  text->ShowForm(this, GetElementList());
332  redraw = true;
333  }
334  }
335  if(elementEdited) {
336  UpdateTextElements();
337  if(m_continuousCalc) RunStaticStudies();
338  }
339  if(clickOnSwitch && m_continuousCalc) RunStaticStudies();
340 
341  if(redraw) Redraw();
342  m_timer->Start();
343 }
344 
345 void Workspace::OnRightClickDown(wxMouseEvent& event)
346 {
347  bool redraw = false;
348  if(m_mode == MODE_EDIT) {
349  for(auto it = m_elementList.begin(), itEnd = m_elementList.end(); it != itEnd; ++it) {
350  Element* element = *it;
351  if(element->IsSelected()) {
352  // Show context menu.
353  if(element->Contains(m_camera->ScreenToWorld(event.GetPosition()))) {
354  element->ShowPickbox(false);
355  wxMenu menu;
356  if(element->GetContextMenu(menu)) {
357  m_timer->Stop();
358  menu.SetClientData(element);
359  menu.Bind(wxEVT_COMMAND_MENU_SELECTED, &Workspace::OnPopupClick, this);
360  PopupMenu(&menu);
361  redraw = true;
362 
363  if(!menu.GetClientData()) break;
364  }
365  element->ResetPickboxes();
366  }
367  }
368  }
369  }
370  if(redraw) Redraw();
371  m_timer->Start();
372 }
373 
374 void Workspace::OnLeftClickUp(wxMouseEvent& event)
375 {
376  // This event (under certain conditions) deselects the elements and back to edit mode or select the elements using
377  // the selection rectangle.
378  bool foundPickbox = false;
379  bool findNewParent = false;
380  bool updateVoltages = false;
381  auto itnp = m_elementList.begin();
382 
383  for(auto it = m_elementList.begin(); it != m_elementList.end(); ++it) {
384  Element* element = *it;
385 
386  // The user was moving a pickbox.
387  if(m_mode == MODE_MOVE_PICKBOX) {
388  // Catch only the element that have the pickbox shown.
389  if(element->IsPickboxShown()) {
390  // If the element is a bus, check if a node is outside.
391  if(typeid(*element) == typeid(Bus)) {
392  // Get all the bus children.
393  for(int i = 0; i < (int)m_elementList.size(); i++) {
394  Element* child = m_elementList[i];
395  for(int j = 0; j < (int)child->GetParentList().size(); j++) {
396  Element* parent = child->GetParentList()[j];
397  // The child have a parent that is the element.
398  if(parent == element) {
399  child->UpdateNodes();
400  m_disconnectedElement = true;
401  }
402  }
403  }
404  }
405  }
406  }
407 
408  if(m_mode == MODE_SELECTION_RECT) {
409  if(element->Intersects(m_selectionRect)) {
410  element->SetSelected();
411  } else if(!event.ControlDown()) {
412  element->SetSelected(false);
413  }
414  } else if(m_mode == MODE_MOVE_NODE) {
415  if(element->IsSelected()) {
416  for(int i = 0; i < (int)m_elementList.size(); i++) {
417  Element* parent = m_elementList[i];
418  if(typeid(*parent) == typeid(Bus)) {
419  if(element->SetNodeParent(parent)) {
420  parent->AddChild(element);
421  findNewParent = true;
422  itnp = it;
423  element->ResetNodes();
424  break;
425  }
426  }
427  }
428  // element->ResetNodes();
429  }
430  } else {
431  // Deselect
432  if(!event.ControlDown()) {
433  if(!element->Contains(m_camera->ScreenToWorld(event.GetPosition()))) {
434  element->SetSelected(false);
435  }
436  }
437 
438  if(element->PickboxContains(m_camera->ScreenToWorld(event.GetPosition()))) {
439  foundPickbox = true;
440  } else {
441  element->ShowPickbox(false);
442  element->ResetPickboxes();
443  }
444  }
445  }
446 
447  // Text element
448  for(auto it = m_textList.begin(); it != m_textList.end(); it++) {
449  Text* text = *it;
450  if(m_mode == MODE_SELECTION_RECT) {
451  if(text->Intersects(m_selectionRect)) {
452  text->SetSelected();
453  } else if(!event.ControlDown()) {
454  text->SetSelected(false);
455  }
456  } else if(!event.ControlDown()) {
457  if(!text->Contains(m_camera->ScreenToWorld(event.GetPosition()))) {
458  text->SetSelected(false);
459  }
460  }
461  }
462 
463  if(findNewParent) {
464  std::rotate(itnp, itnp + 1, m_elementList.end());
465  updateVoltages = true;
466  }
467  if(!foundPickbox) {
468  SetCursor(wxCURSOR_ARROW);
469  }
470 
471  if(m_mode != MODE_INSERT) {
472  m_mode = MODE_EDIT;
473  }
474 
475  if(updateVoltages) {
476  ValidateElementsVoltages();
477  }
478 
479  if(m_continuousCalc && m_disconnectedElement) {
480  m_disconnectedElement = false;
481  RunStaticStudies();
482  }
483 
484  m_selectionRect = wxRect2DDouble(0, 0, 0, 0);
485  Redraw();
486  UpdateStatusBar();
487 }
488 
489 void Workspace::OnMouseMotion(wxMouseEvent& event)
490 {
491  bool redraw = false;
492  switch(m_mode) {
493  case MODE_INSERT: {
494  Element* newElement = *(m_elementList.end() - 1); // Get the last element in the list.
495  newElement->SetPosition(m_camera->ScreenToWorld(event.GetPosition()));
496  redraw = true;
497  } break;
498 
499  case MODE_INSERT_TEXT: {
500  Text* newText = *(m_textList.end() - 1);
501  newText->SetPosition(m_camera->ScreenToWorld(event.GetPosition()));
502  redraw = true;
503  } break;
504 
505  case MODE_DRAG:
506  case MODE_DRAG_INSERT:
507  case MODE_DRAG_INSERT_TEXT:
508  case MODE_DRAG_PASTE: {
509  m_camera->SetTranslation(event.GetPosition());
510  redraw = true;
511  } break;
512 
513  case MODE_EDIT: {
514  bool foundPickbox = false;
515  for(auto it = m_elementList.begin(); it != m_elementList.end(); ++it) {
516  Element* element = *it;
517  if(element->IsSelected()) {
518  // Show element pickbox (when it has) if the mouse is over the selected object.
519  if(element->Contains(m_camera->ScreenToWorld(event.GetPosition()))) {
520  element->ShowPickbox();
521  redraw = true;
522 
523  // If the mouse is over a pickbox set correct mouse cursor.
524  if(element->PickboxContains(m_camera->ScreenToWorld(event.GetPosition()))) {
525  foundPickbox = true;
526  SetCursor(element->GetBestPickboxCursor());
527  } else if(!foundPickbox) {
528  SetCursor(wxCURSOR_ARROW);
529  element->ResetPickboxes();
530  }
531  } else if(!foundPickbox) {
532  if(element->IsPickboxShown()) redraw = true;
533 
534  element->ShowPickbox(false);
535  element->ResetPickboxes();
536  SetCursor(wxCURSOR_ARROW);
537  }
538  }
539  }
540  } break;
541 
542  case MODE_MOVE_NODE: {
543  for(auto it = m_elementList.begin(); it != m_elementList.end(); ++it) {
544  Element* element = *it;
545  if(element->IsSelected()) {
546  element->MoveNode(NULL, m_camera->ScreenToWorld(event.GetPosition()));
547  redraw = true;
548  }
549  }
550  } break;
551 
552  case MODE_MOVE_PICKBOX: {
553  for(auto it = m_elementList.begin(); it != m_elementList.end(); ++it) {
554  Element* element = *it;
555  if(element->IsSelected()) {
556  element->MovePickbox(m_camera->ScreenToWorld(event.GetPosition()));
557  redraw = true;
558  }
559  }
560  } break;
561 
562  case MODE_MOVE_ELEMENT:
563  case MODE_PASTE: {
564  for(auto it = m_elementList.begin(), itEnd = m_elementList.end(); it != itEnd; ++it) {
565  Element* element = *it;
566  if(element->IsSelected()) {
567  element->Move(m_camera->ScreenToWorld(event.GetPosition()));
568  // Move child nodes
569  std::vector<Element*> childList = element->GetChildList();
570  for(auto it = childList.begin(), itEnd = childList.end(); it != itEnd; ++it) {
571  (*it)->MoveNode(element, m_camera->ScreenToWorld(event.GetPosition()));
572  }
573  redraw = true;
574  }
575  }
576  // Text element motion
577  for(auto it = m_textList.begin(), itEnd = m_textList.end(); it != itEnd; it++) {
578  Text* text = *it;
579  if(text->IsSelected()) {
580  text->Move(m_camera->ScreenToWorld(event.GetPosition()));
581  redraw = true;
582  }
583  }
584  } break;
585 
586  case MODE_SELECTION_RECT: {
587  wxPoint2DDouble currentPos = m_camera->ScreenToWorld(event.GetPosition());
588  double x, y, w, h;
589  if(currentPos.m_x < m_startSelRect.m_x) {
590  x = currentPos.m_x;
591  w = m_startSelRect.m_x - currentPos.m_x;
592  } else {
593  x = m_startSelRect.m_x;
594  w = currentPos.m_x - m_startSelRect.m_x;
595  }
596  if(currentPos.m_y < m_startSelRect.m_y) {
597  y = currentPos.m_y;
598  h = m_startSelRect.m_y - currentPos.m_y;
599  } else {
600  y = m_startSelRect.m_y;
601  h = currentPos.m_y - m_startSelRect.m_y;
602  }
603 
604  m_selectionRect = wxRect2DDouble(x, y, w, h);
605  redraw = true;
606  } break;
607  }
608 
609  if(redraw) Redraw();
610  m_camera->UpdateMousePosition(event.GetPosition());
611  UpdateStatusBar();
612  m_timer->Start(); // Restart the timer.
613  event.Skip();
614 }
615 
616 void Workspace::OnMiddleDown(wxMouseEvent& event)
617 {
618  // Set to drag mode.
619  switch(m_mode) {
620  case MODE_INSERT: {
621  m_mode = MODE_DRAG_INSERT;
622  } break;
623  case MODE_INSERT_TEXT: {
624  m_mode = MODE_DRAG_INSERT_TEXT;
625  } break;
626  case MODE_PASTE: {
627  m_mode = MODE_DRAG_PASTE;
628  } break;
629  default: {
630  m_mode = MODE_DRAG;
631  } break;
632  }
633  m_camera->StartTranslation(m_camera->ScreenToWorld(event.GetPosition()));
634  UpdateStatusBar();
635  event.Skip();
636 }
637 
638 void Workspace::OnMiddleUp(wxMouseEvent& event)
639 {
640  switch(m_mode) {
641  case MODE_DRAG_INSERT: {
642  m_mode = MODE_INSERT;
643  } break;
644  case MODE_DRAG_INSERT_TEXT: {
645  m_mode = MODE_INSERT_TEXT;
646  } break;
647  case MODE_DRAG_PASTE: {
648  m_mode = MODE_PASTE;
649  } break;
650  case MODE_INSERT:
651  case MODE_INSERT_TEXT:
652  case MODE_PASTE: {
653  // Does nothing.
654  } break;
655  default: {
656  m_mode = MODE_EDIT;
657  } break;
658  }
659  UpdateStatusBar();
660  event.Skip();
661 }
662 
663 void Workspace::OnScroll(wxMouseEvent& event)
664 {
665  if(event.GetWheelRotation() > 0)
666  m_camera->SetScale(event.GetPosition(), +0.05);
667  else
668  m_camera->SetScale(event.GetPosition(), -0.05);
669 
670  UpdateStatusBar();
671  Redraw();
672 }
673 
674 void Workspace::OnKeyDown(wxKeyEvent& event)
675 {
676  bool insertingElement = false;
677  if(m_mode == MODE_INSERT || m_mode == MODE_INSERT_TEXT) insertingElement = true;
678 
679  char key = event.GetUnicodeKey();
680  if(key != WXK_NONE) {
681  switch(key) {
682  case WXK_ESCAPE: // Cancel operations.
683  {
684  if(m_mode == MODE_INSERT) {
685  m_elementList.pop_back(); // Removes the last element being inserted.
686  m_mode = MODE_EDIT;
687  Redraw();
688  } else if(m_mode == MODE_INSERT_TEXT) {
689  m_textList.pop_back();
690  m_mode = MODE_EDIT;
691  Redraw();
692  }
693  } break;
694  case WXK_DELETE: // Delete selected elements
695  {
696  DeleteSelectedElements();
697  } break;
698  case 'A': {
699  if(!insertingElement) {
700  Text* newBus = new Text(m_camera->ScreenToWorld(event.GetPosition()));
701  m_textList.push_back(newBus);
702  m_mode = MODE_INSERT_TEXT;
703  m_statusBar->SetStatusText(_("Insert Text: Click to insert, ESC to cancel."));
704  Redraw();
705  }
706  } break;
707  case 'F': {
708  if(event.GetModifiers() == wxMOD_SHIFT) {
709  Fit();
710  }
711  } break;
712  case 'R': // Rotate the selected elements.
713  {
714  RotateSelectedElements(event.GetModifiers() != wxMOD_SHIFT);
715  } break;
716  case 'B': // Insert a bus.
717  {
718  if(!insertingElement) {
719  Bus* newBus = new Bus(m_camera->ScreenToWorld(event.GetPosition()),
720  wxString::Format(_("Bus %d"), GetElementNumber(ID_BUS)));
721  IncrementElementNumber(ID_BUS);
722  m_elementList.push_back(newBus);
723  m_mode = MODE_INSERT;
724  m_statusBar->SetStatusText(_("Insert Bus: Click to insert, ESC to cancel."));
725  Redraw();
726  }
727  } break;
728  case 'L': {
729  if(!insertingElement) {
730  if(!event.ControlDown() && event.ShiftDown()) { // Insert a load.
731  Load* newLoad = new Load(wxString::Format(_("Load %d"), GetElementNumber(ID_LOAD)));
732  IncrementElementNumber(ID_LOAD);
733  m_elementList.push_back(newLoad);
734  m_mode = MODE_INSERT;
735  m_statusBar->SetStatusText(_("Insert Load: Click on a buses, ESC to cancel."));
736  } else if(!event.ControlDown() && !event.ShiftDown()) { // Insert a power line.
737  Line* newLine = new Line(wxString::Format(_("Line %d"), GetElementNumber(ID_LINE)));
738  IncrementElementNumber(ID_LINE);
739  m_elementList.push_back(newLine);
740  m_mode = MODE_INSERT;
741  m_statusBar->SetStatusText(_("Insert Line: Click on two buses, ESC to cancel."));
742  }
743  Redraw();
744  }
745  // Tests - Ctrl + Shift + L
746  if(event.ControlDown() && event.ShiftDown()) {
747  // Nothing...
748  }
749  } break;
750  case 'T': // Insert a transformer.
751  {
752  if(!insertingElement) {
753  Transformer* newTransformer =
754  new Transformer(wxString::Format(_("Transformer %d"), GetElementNumber(ID_TRANSFORMER)));
755  IncrementElementNumber(ID_TRANSFORMER);
756  m_elementList.push_back(newTransformer);
757  m_mode = MODE_INSERT;
758  m_statusBar->SetStatusText(_("Insert Transformer: Click on two buses, ESC to cancel."));
759  Redraw();
760  }
761  } break;
762  case 'G': // Insert a generator.
763  {
764  if(!insertingElement) {
765  SyncGenerator* newGenerator =
766  new SyncGenerator(wxString::Format(_("Generator %d"), GetElementNumber(ID_SYNCGENERATOR)));
767  IncrementElementNumber(ID_SYNCGENERATOR);
768  m_elementList.push_back(newGenerator);
769  m_mode = MODE_INSERT;
770  m_statusBar->SetStatusText(_("Insert Generator: Click on a buses, ESC to cancel."));
771  Redraw();
772  }
773  } break;
774  case 'I': {
775  if(!insertingElement) {
776  if(event.GetModifiers() == wxMOD_SHIFT) { // Insert an inductor.
777  Inductor* newInductor =
778  new Inductor(wxString::Format(_("Inductor %d"), GetElementNumber(ID_INDUCTOR)));
779  IncrementElementNumber(ID_INDUCTOR);
780  m_elementList.push_back(newInductor);
781  m_mode = MODE_INSERT;
782  m_statusBar->SetStatusText(_("Insert Inductor: Click on a buses, ESC to cancel."));
783  } else // Insert an induction motor.
784  {
785  IndMotor* newIndMotor =
786  new IndMotor(wxString::Format(_("Induction motor %d"), GetElementNumber(ID_INDMOTOR)));
787  IncrementElementNumber(ID_INDMOTOR);
788  m_elementList.push_back(newIndMotor);
789  m_mode = MODE_INSERT;
790  m_statusBar->SetStatusText(_("Insert Induction Motor: Click on a buses, ESC to cancel."));
791  }
792  Redraw();
793  }
794  } break;
795  case 'K': // Insert a synchronous condenser.
796  {
797  if(!insertingElement) {
798  SyncMotor* newSyncCondenser =
799  new SyncMotor(wxString::Format(_("Synchronous condenser %d"), GetElementNumber(ID_SYNCMOTOR)));
800  IncrementElementNumber(ID_SYNCMOTOR);
801  m_elementList.push_back(newSyncCondenser);
802  m_mode = MODE_INSERT;
803  m_statusBar->SetStatusText(_("Insert Synchronous Condenser: Click on a buses, ESC to cancel."));
804  Redraw();
805  }
806  } break;
807  case 'C': {
808  if(!insertingElement) {
809  if(event.GetModifiers() == wxMOD_SHIFT) { // Insert a capacitor.
810  Capacitor* newCapacitor =
811  new Capacitor(wxString::Format(_("Capacitor %d"), GetElementNumber(ID_CAPACITOR)));
812  IncrementElementNumber(ID_CAPACITOR);
813  m_elementList.push_back(newCapacitor);
814  m_mode = MODE_INSERT;
815  m_statusBar->SetStatusText(_("Insert Capacitor: Click on a buses, ESC to cancel."));
816  Redraw();
817  } else if(event.GetModifiers() == wxMOD_CONTROL) { // Copy.
818  CopySelection();
819  }
820  }
821  } break;
822  case 'V': {
823  if(!insertingElement) {
824  if(event.GetModifiers() == wxMOD_CONTROL) {
825  Paste();
826  }
827  }
828  } break;
829  default:
830  break;
831  }
832  }
833 
834  UpdateStatusBar();
835  event.Skip();
836 }
837 
838 void Workspace::UpdateStatusBar()
839 {
840  switch(m_mode) {
841  case MODE_DRAG: {
842  m_statusBar->SetStatusText(_("MODE: DRAG"), 1);
843  } break;
844 
845  case MODE_PASTE:
846  case MODE_DRAG_PASTE: {
847  m_statusBar->SetStatusText(_("MODE: PASTE"), 1);
848  }
849 
850  case MODE_INSERT:
851  case MODE_INSERT_TEXT:
852  case MODE_DRAG_INSERT:
853  case MODE_DRAG_INSERT_TEXT: {
854  m_statusBar->SetStatusText(_("MODE: INSERT"), 1);
855  } break;
856 
857  case MODE_MOVE_ELEMENT:
858  case MODE_MOVE_PICKBOX:
859  case MODE_MOVE_NODE:
860  case MODE_SELECTION_RECT:
861  case MODE_EDIT: {
862  m_statusBar->SetStatusText(wxT(""));
863  m_statusBar->SetStatusText(_("MODE: EDIT"), 1);
864  } break;
865  }
866 
867  m_statusBar->SetStatusText(wxString::Format(_("ZOOM: %d%%"), (int)(m_camera->GetScale() * 100.0)), 2);
868  m_statusBar->SetStatusText(
869  wxString::Format(wxT("X: %.1f Y: %.1f"), m_camera->GetMousePosition().m_x, m_camera->GetMousePosition().m_y),
870  3);
871 }
872 
873 void Workspace::OnPopupClick(wxCommandEvent& event)
874 {
875  wxMenu* menu = static_cast<wxMenu*>(event.GetEventObject());
876  Element* element = static_cast<Element*>(menu->GetClientData());
877  switch(event.GetId()) {
878  case ID_EDIT_ELEMENT: {
879  if(element->ShowForm(this, element)) UpdateTextElements();
880  } break;
881  case ID_LINE_ADD_NODE: {
882  Line* line = static_cast<Line*>(element);
883  line->AddNode(m_camera->GetMousePosition());
884  Redraw();
885  } break;
886  case ID_LINE_REMOVE_NODE: {
887  Line* line = static_cast<Line*>(element);
888  line->RemoveNode(m_camera->GetMousePosition());
889  Redraw();
890  } break;
891  case ID_ROTATE_CLOCK: {
892  element->Rotate();
893  for(auto it = m_elementList.begin(); it != m_elementList.end(); ++it) {
894  Element* iElement = *it;
895  // Parent's element rotating...
896  for(int i = 0; i < (int)iElement->GetParentList().size(); i++) {
897  Element* parent = iElement->GetParentList()[i];
898  if(parent == element) {
899  iElement->RotateNode(parent);
900  }
901  }
902  }
903  Redraw();
904  } break;
905  case ID_ROTATE_COUNTERCLOCK: {
906  element->Rotate(false);
907  for(auto it = m_elementList.begin(); it != m_elementList.end(); ++it) {
908  Element* iElement = *it;
909  // Parent's element rotating...
910  for(int i = 0; i < (int)iElement->GetParentList().size(); i++) {
911  Element* parent = iElement->GetParentList()[i];
912  if(parent == element) {
913  iElement->RotateNode(parent, false);
914  }
915  }
916  }
917  Redraw();
918  } break;
919  case ID_DELETE: {
920  for(auto it = m_elementList.begin(), itEnd = m_elementList.end(); it != itEnd; ++it) {
921  Element* iElement = *it;
922 
923  if(element == iElement) {
924  // Remove child/parent.
925  std::vector<Element*> childList = element->GetChildList();
926  for(auto itc = childList.begin(), itEnd = childList.end(); itc != itEnd; ++itc) {
927  Element* child = *itc;
928  if(child) {
929  child->RemoveParent(element);
930  element->RemoveChild(child);
931  }
932  }
933  std::vector<Element*> parentList = element->GetParentList();
934  for(auto itp = parentList.begin(), itEnd = parentList.end(); itp != itEnd; ++itp) {
935  Element* parent = *itp;
936  if(parent) {
937  parent->RemoveChild(element);
938  }
939  }
940 
941  for(auto itt = m_textList.begin(); itt != m_textList.end(); ++itt) {
942  Text* text = *itt;
943  if(text->GetElement() == element) {
944  m_textList.erase(itt--);
945  if(text) delete text;
946  }
947  }
948 
949  m_elementList.erase(it);
950  if(element) delete element;
951  menu->SetClientData(NULL);
952  break;
953  }
954  }
955  } break;
956  }
957 }
958 
959 void Workspace::RotateSelectedElements(bool clockwise)
960 {
961  for(auto it = m_elementList.begin(); it != m_elementList.end(); ++it) {
962  Element* element = *it;
963  // Parent's element rotating...
964  for(int i = 0; i < (int)element->GetParentList().size(); i++) {
965  Element* parent = element->GetParentList()[i];
966  if(parent) { // Check if parent is not null
967  if(parent->IsSelected()) {
968  element->RotateNode(parent, clockwise);
969  // Update the positions used on motion action, the element will not be necessarily
970  // moved.
971  element->StartMove(m_camera->GetMousePosition());
972  }
973  }
974  }
975  if(element->IsSelected()) {
976  element->Rotate(clockwise);
977  element->StartMove(m_camera->GetMousePosition());
978  }
979  }
980 
981  // Rotate text element
982  for(auto it = m_textList.begin(); it != m_textList.end(); it++) {
983  Text* text = *it;
984  if(text->IsSelected()) {
985  text->Rotate(clockwise);
986  text->StartMove(m_camera->GetMousePosition());
987  }
988  }
989  Redraw();
990 }
991 
992 void Workspace::DeleteSelectedElements()
993 {
994  // Don't set the end of the list at the loop's begin.
995  for(auto it = m_elementList.begin(); it != m_elementList.end(); ++it) {
996  Element* element = *it;
997 
998  if(element->IsSelected()) {
999  // Remove child/parent.
1000  std::vector<Element*> childList = element->GetChildList();
1001  for(auto itc = childList.begin(), itEnd = childList.end(); itc != itEnd; ++itc) {
1002  Element* child = *itc;
1003  if(child) {
1004  child->RemoveParent(element);
1005  element->RemoveChild(child);
1006  }
1007  }
1008  std::vector<Element*> parentList = element->GetParentList();
1009  for(auto itp = parentList.begin(), itEnd = parentList.end(); itp != itEnd; ++itp) {
1010  Element* parent = *itp;
1011  if(parent) {
1012  parent->RemoveChild(element);
1013  }
1014  }
1015 
1016  for(auto itt = m_textList.begin(); itt != m_textList.end(); ++itt) {
1017  Text* text = *itt;
1018  if(text->GetElement() == element) {
1019  m_textList.erase(itt--);
1020  if(text) delete text;
1021  }
1022  }
1023 
1024  m_elementList.erase(it--);
1025  if(element) delete element;
1026  }
1027  }
1028 
1029  for(auto it = m_textList.begin(); it != m_textList.end(); ++it) {
1030  Text* text = *it;
1031  if(text->IsSelected()) {
1032  m_textList.erase(it--);
1033  if(text) delete text;
1034  }
1035  }
1036 
1037  Redraw();
1038 }
1039 
1040 bool Workspace::GetElementsCorners(wxPoint2DDouble& leftUpCorner,
1041  wxPoint2DDouble& rightDownCorner,
1042  std::vector<Element*> elementList)
1043 {
1044  if(elementList.size() == 0) return false;
1045 
1046  elementList[0]->CalculateBoundaries(leftUpCorner, rightDownCorner);
1047 
1048  for(auto it = elementList.begin() + 1, itEnd = elementList.end(); it != itEnd; it++) {
1049  Element* element = *it;
1050  wxPoint2DDouble leftUp;
1051  wxPoint2DDouble rightDown;
1052  element->CalculateBoundaries(leftUp, rightDown);
1053  if(leftUp.m_x < leftUpCorner.m_x) leftUpCorner.m_x = leftUp.m_x;
1054  if(leftUp.m_y < leftUpCorner.m_y) leftUpCorner.m_y = leftUp.m_y;
1055  if(rightDown.m_x > rightDownCorner.m_x) rightDownCorner.m_x = rightDown.m_x;
1056  if(rightDown.m_y > rightDownCorner.m_y) rightDownCorner.m_y = rightDown.m_y;
1057  }
1058  return true;
1059 }
1060 
1061 void Workspace::Fit()
1062 {
1063  wxPoint2DDouble leftUpCorner(0, 0);
1064  wxPoint2DDouble rightDownCorner(0, 0);
1065  std::vector<Element*> elementList = GetElementList();
1066  for(auto it = m_textList.begin(), itEnd = m_textList.end(); it != itEnd; ++it) {
1067  elementList.push_back(*it);
1068  }
1069 
1070  if(!GetElementsCorners(leftUpCorner, rightDownCorner, elementList)) return;
1071  wxPoint2DDouble middleCoords = (leftUpCorner + rightDownCorner) / 2.0;
1072 
1073  int width = 0.0;
1074  int height = 0.0;
1075  GetSize(&width, &height);
1076 
1077  double scaleX = double(width) / (rightDownCorner.m_x - leftUpCorner.m_x);
1078  double scaleY = double(height) / (rightDownCorner.m_y - leftUpCorner.m_y);
1079 
1080  double scale = scaleX < scaleY ? scaleX : scaleY;
1081  if(scale > m_camera->GetZoomMax()) scale = m_camera->GetZoomMax();
1082  if(scale < m_camera->GetZoomMin()) scale = m_camera->GetZoomMin();
1083 
1084  m_camera->SetScale(scale);
1085 
1086  m_camera->StartTranslation(middleCoords);
1087  m_camera->SetTranslation(wxPoint2DDouble(width / 2, height / 2));
1088  Redraw();
1089 }
1090 
1091 void Workspace::ValidateBusesVoltages(Element* initialBus)
1092 {
1093  double nominalVoltage = static_cast<Bus*>(initialBus)->GetElectricalData().nominalVoltage;
1094  ElectricalUnit nominalVoltageUnit = static_cast<Bus*>(initialBus)->GetElectricalData().nominalVoltageUnit;
1095 
1096  for(auto it = m_elementList.begin(); it != m_elementList.end(); it++) {
1097  Element* child = *it;
1098 
1099  if(typeid(*child) == typeid(Line)) {
1100  if(child->GetParentList()[0] && child->GetParentList()[1]) {
1101  BusElectricalData data1 = static_cast<Bus*>(child->GetParentList()[0])->GetElectricalData();
1102  BusElectricalData data2 = static_cast<Bus*>(child->GetParentList()[1])->GetElectricalData();
1103 
1104  if(data1.nominalVoltage != data2.nominalVoltage ||
1105  data1.nominalVoltageUnit != data2.nominalVoltageUnit) {
1106  data1.nominalVoltage = nominalVoltage;
1107  data2.nominalVoltage = nominalVoltage;
1108  data1.nominalVoltageUnit = nominalVoltageUnit;
1109  data2.nominalVoltageUnit = nominalVoltageUnit;
1110 
1111  static_cast<Bus*>(child->GetParentList()[0])->SetElectricalData(data1);
1112  static_cast<Bus*>(child->GetParentList()[1])->SetElectricalData(data2);
1113 
1114  it = m_elementList.begin(); // Restart search.
1115  }
1116  }
1117  }
1118  }
1119 
1120  // ValidateElementsVoltages();
1121 }
1122 
1123 void Workspace::ValidateElementsVoltages()
1124 {
1125  for(auto it = m_elementList.begin(); it != m_elementList.end(); it++) {
1126  PowerElement* child = *it;
1127 
1128  std::vector<double> nominalVoltage;
1129  std::vector<ElectricalUnit> nominalVoltageUnit;
1130  for(int i = 0; i < (int)child->GetParentList().size(); i++) {
1131  Bus* parent = static_cast<Bus*>(child->GetParentList()[i]);
1132  if(parent) {
1133  nominalVoltage.push_back(parent->GetElectricalData().nominalVoltage);
1134  nominalVoltageUnit.push_back(parent->GetElectricalData().nominalVoltageUnit);
1135  }
1136  }
1137  child->SetNominalVoltage(nominalVoltage, nominalVoltageUnit);
1138  }
1139 }
1140 
1141 bool Workspace::RunPowerFlow()
1142 {
1143  PowerFlow pf(GetElementList());
1144  bool result = pf.RunGaussSeidel();
1145  if(!result) {
1146  wxMessageDialog msgDialog(this, pf.GetErrorMessage(), _("Error"), wxOK | wxCENTRE | wxICON_ERROR);
1147  msgDialog.ShowModal();
1148  }
1149 
1150  UpdateTextElements();
1151  Redraw();
1152 
1153  return result;
1154 }
1155 
1156 bool Workspace::UpdateTextElements()
1157 {
1158  bool isTexturesOK = true;
1159  double basePower = m_properties->GetSimulationPropertiesData().basePower;
1160  if(m_properties->GetSimulationPropertiesData().basePowerUnit == UNIT_kVA)
1161  basePower *= 1e3;
1162  else if(m_properties->GetSimulationPropertiesData().basePowerUnit == UNIT_MVA)
1163  basePower *= 1e6;
1164  for(auto it = m_textList.begin(), itEnd = m_textList.end(); it != itEnd; ++it) {
1165  Text* text = *it;
1166  text->UpdateText(basePower);
1167  if(!text->IsGLTextOK()) isTexturesOK = false;
1168  }
1169  return isTexturesOK;
1170 }
1171 
1172 void Workspace::CopySelection()
1173 {
1174  UpdateElementsID();
1175  std::vector<Element*> selectedElements;
1176  // The buses need to be numerated to associate the child's parents to the copies.
1177  int busNumber = 0;
1178  for(auto it = m_elementList.begin(), itEnd = m_elementList.end(); it != itEnd; ++it) {
1179  Element* element = *it;
1180  if(typeid(*element) == typeid(Bus)) {
1181  Bus* bus = static_cast<Bus*>(element);
1182  auto data = bus->GetElectricalData();
1183  data.number = busNumber;
1184  bus->SetElectricalData(data);
1185  busNumber++;
1186  }
1187  if(element->IsSelected()) {
1188  selectedElements.push_back(element);
1189  }
1190  }
1191  for(auto it = m_textList.begin(), itEnd = m_textList.end(); it != itEnd; ++it) {
1192  Text* text = *it;
1193  if(text->IsSelected()) {
1194  selectedElements.push_back(text);
1195  }
1196  }
1197  ElementDataObject* dataObject = new ElementDataObject(selectedElements);
1198  if(wxTheClipboard->Open()) {
1199  wxTheClipboard->SetData(dataObject);
1200  wxTheClipboard->Close();
1201  }
1202 }
1203 
1204 bool Workspace::Paste()
1205 {
1206  if(wxTheClipboard->Open()) {
1207  ElementDataObject dataObject;
1208 
1209  if(wxTheClipboard->IsSupported(dataObject.GetFormat())) {
1210  if(!wxTheClipboard->GetData(dataObject)) {
1211  wxMessageDialog dialog(this, _("It was not possible to paste from clipboard."), _("Error"),
1212  wxOK | wxCENTER | wxICON_ERROR, wxDefaultPosition);
1213  dialog.ShowModal();
1214  wxTheClipboard->Close();
1215  return false;
1216  }
1217  } else {
1218  wxTheClipboard->Close();
1219  return false;
1220  }
1221  wxTheClipboard->Close();
1222 
1223  UnselectAll();
1224 
1225  std::vector<Element*> pastedElements;
1226  ElementsLists* elementsLists = dataObject.GetElementsLists();
1227 
1228  // Paste buses (parents).
1229  auto parentList = elementsLists->parentList;
1230  std::vector<Bus*> pastedBusList; // To set new parents;
1231  for(auto it = parentList.begin(), itEnd = parentList.end(); it != itEnd; ++it) {
1232  Element* copy = (*it)->GetCopy();
1233  if(copy) {
1234  pastedElements.push_back(copy);
1235  pastedBusList.push_back(static_cast<Bus*>(copy));
1236  m_elementList.push_back(static_cast<PowerElement*>(copy));
1237  }
1238  }
1239 
1240  // Paste other elements.
1241  auto elementLists = elementsLists->elementList;
1242  for(auto it = elementLists.begin(), itEnd = elementLists.end(); it != itEnd; ++it) {
1243  Element* copy = (*it)->GetCopy();
1244  if(copy) {
1245  // Check if is text element
1246  if(Text* text = dynamic_cast<Text*>(copy)) {
1247  // Check if element associated with the text exists.
1248  bool elementExist = false;
1249  for(int i = 0; i < (int)m_elementList.size(); i++) {
1250  if(text->GetElement() == m_elementList[i]) {
1251  elementExist = true;
1252  break;
1253  }
1254  }
1255  if(elementExist) {
1256  pastedElements.push_back(copy);
1257  m_textList.push_back(text);
1258  }
1259  } else {
1260  // Change the parent if copied, otherwise remove it.
1261  for(int j = 0; j < (int)copy->GetParentList().size(); j++) {
1262  Bus* currentParent = static_cast<Bus*>(copy->GetParentList()[j]);
1263  if(currentParent) {
1264  int parentID = currentParent->GetID();
1265  bool parentCopied = false;
1266  for(int k = 0; k < (int)pastedBusList.size(); k++) {
1267  Bus* newParent = pastedBusList[k];
1268  if(parentID == newParent->GetID()) {
1269  parentCopied = true;
1270  copy->ReplaceParent(currentParent, newParent);
1271  break;
1272  }
1273  }
1274  if(!parentCopied) copy->RemoveParent(currentParent);
1275  }
1276  }
1277 
1278  pastedElements.push_back(copy);
1279  m_elementList.push_back(static_cast<PowerElement*>(copy));
1280  }
1281  }
1282  }
1283 
1284  // Update buses childs
1285  for(auto it = pastedBusList.begin(), itEnd = pastedBusList.end(); it != itEnd; ++it) {
1286  Bus* bus = *it;
1287  std::vector<Element*> childList = bus->GetChildList();
1288  for(auto it = childList.begin(), itEnd = childList.end(); it != itEnd; ++it) {
1289  Element* currentChild = *it;
1290  int childID = currentChild->GetID();
1291  bool childCopied = false;
1292  for(int i = 0; i < (int)pastedElements.size(); i++) {
1293  Element* newChild = pastedElements[i];
1294  if(childID == newChild->GetID()) {
1295  childCopied = true;
1296  bus->ReplaceChild(currentChild, newChild);
1297  break;
1298  }
1299  }
1300  if(!childCopied) bus->RemoveChild(currentChild);
1301  }
1302  }
1303 
1304  // Move elements (and nodes) to the mouse position.
1305  // The start position it's the center of the pasted objects.
1306  wxPoint2DDouble leftUpCorner, rightDownCorner;
1307  GetElementsCorners(leftUpCorner, rightDownCorner, pastedElements);
1308  wxPoint2DDouble startPosition = (leftUpCorner + rightDownCorner) / 2.0;
1309  for(auto it = pastedElements.begin(), itEnd = pastedElements.end(); it != itEnd; ++it) {
1310  Element* element = *it;
1311  element->StartMove(startPosition);
1312  element->Move(m_camera->GetMousePosition());
1313  for(int i = 0; i < (int)element->GetParentList().size(); i++) {
1314  Element* parent = element->GetParentList()[i];
1315  element->MoveNode(parent, m_camera->GetMousePosition());
1316  }
1317  }
1318  } else {
1319  wxMessageDialog dialog(this, _("It was not possible to paste from clipboard."), _("Error"),
1320  wxOK | wxCENTER | wxICON_ERROR, wxDefaultPosition);
1321  dialog.ShowModal();
1322  return false;
1323  }
1324 
1325  UpdateElementsID();
1326  m_mode = MODE_PASTE;
1327  m_statusBar->SetStatusText(_("Click to paste."));
1328  UpdateStatusBar();
1329  Redraw();
1330  return true;
1331 }
1332 
1333 void Workspace::UnselectAll()
1334 {
1335  for(auto it = m_elementList.begin(), itEnd = m_elementList.end(); it != itEnd; it++) {
1336  Element* element = *it;
1337  element->SetSelected(false);
1338  }
1339  for(auto it = m_textList.begin(), itEnd = m_textList.end(); it != itEnd; it++) {
1340  Text* text = *it;
1341  text->SetSelected(false);
1342  }
1343 }
1344 
1345 void Workspace::UpdateElementsID()
1346 {
1347  int id = 0;
1348  for(auto it = m_elementList.begin(), itEnd = m_elementList.end(); it != itEnd; ++it) {
1349  Element* element = *it;
1350  element->SetID(id);
1351  id++;
1352  }
1353  for(auto it = m_textList.begin(), itEnd = m_textList.end(); it != itEnd; ++it) {
1354  Text* text = *it;
1355  text->SetID(id);
1356  id++;
1357  }
1358 }
1359 void Workspace::OnTimer(wxTimerEvent& event)
1360 {
1361  if(m_tipWindow) {
1362  m_tipWindow->Close();
1363  m_tipWindow = NULL;
1364  }
1365  if(m_mode == MODE_EDIT) {
1366  for(auto it = m_elementList.begin(), itEnd = m_elementList.end(); it != itEnd; ++it) {
1367  Element* element = *it;
1368  if(element->Contains(m_camera->GetMousePosition())) {
1369  wxString tipText = element->GetTipText();
1370  if(!tipText.IsEmpty()) {
1371  m_tipWindow = new wxTipWindow(this, tipText, 10000, &m_tipWindow);
1372  // Creates a very tiny bounding rect to remove the tip on any mouse movement.
1373  m_tipWindow->SetBoundingRect(wxRect(wxGetMousePosition(), wxSize(1, 1)));
1374  break;
1375  }
1376  }
1377  }
1378  }
1379 
1380  m_timer->Stop();
1381 }
1382 
1383 void Workspace::SetTextList(std::vector<Text*> textList)
1384 {
1385  m_textList.clear();
1386  for(auto it = textList.begin(), itEnd = textList.end(); it != itEnd; ++it) m_textList.push_back(*it);
1387 
1388  UpdateTextElements();
1389 }
1390 
1391 void Workspace::SetElementList(std::vector<Element*> elementList)
1392 {
1393  m_elementList.clear();
1394  for(auto it = elementList.begin(), itEnd = elementList.end(); it != itEnd; ++it)
1395  m_elementList.push_back(static_cast<PowerElement*>(*it));
1396 }
1397 
1398 void Workspace::OnIdle(wxIdleEvent& event)
1399 {
1400  // The OpenGL element (m_glCanvas) must be completely initialized (showed) to draw properly the textures.
1401  // TODO(?): Find other solution to text displayed wrong on opened file.
1402  if(m_justOpened) {
1403  if(UpdateTextElements()) m_justOpened = false;
1404  Redraw();
1405  }
1406 }
1407 
1408 std::vector<Element*> Workspace::GetAllElements() const
1409 {
1410  std::vector<Element*> allElements;
1411 
1412  for(auto it = m_elementList.begin(), itEnd = m_elementList.end(); it != itEnd; ++it) allElements.push_back(*it);
1413  for(auto it = m_textList.begin(), itEnd = m_textList.end(); it != itEnd; ++it) allElements.push_back(*it);
1414 
1415  return allElements;
1416 }
1417 
1418 bool Workspace::RunFault()
1419 {
1420  Fault fault(GetElementList());
1421  bool result = fault.RunFaultCalculation(100e6);
1422  if(!result) {
1423  wxMessageDialog msgDialog(this, fault.GetErrorMessage(), _("Error"), wxOK | wxCENTRE | wxICON_ERROR);
1424  msgDialog.ShowModal();
1425  }
1426 
1427  UpdateTextElements();
1428  Redraw();
1429 
1430  return result;
1431 }
1432 
1433 std::vector<Element*> Workspace::GetElementList() const
1434 {
1435  std::vector<Element*> elementList;
1436  for(auto it = m_elementList.begin(), itEnd = m_elementList.end(); it != itEnd; ++it) elementList.push_back(*it);
1437  return elementList;
1438 }
1439 
1440 bool Workspace::RunSCPower()
1441 {
1442  Fault fault(GetElementList());
1443  bool result = fault.RunSCPowerCalcutation(100e6);
1444  if(!result) {
1445  wxMessageDialog msgDialog(this, fault.GetErrorMessage(), _("Error"), wxOK | wxCENTRE | wxICON_ERROR);
1446  msgDialog.ShowModal();
1447  }
1448 
1449  UpdateTextElements();
1450  Redraw();
1451 
1452  return result;
1453 }
1454 
1455 bool Workspace::RunStability()
1456 {
1457  // Run power flow before stability.
1458  RunPowerFlow();
1459 
1460  Electromechanical stability(this, GetElementList(), m_properties->GetSimulationPropertiesData());
1461  bool result = stability.RunStabilityCalculation();
1462  if(!result) {
1463  wxMessageDialog msgDialog(this, stability.GetErrorMessage(), _("Error"), wxOK | wxCENTRE | wxICON_ERROR);
1464  msgDialog.ShowModal();
1465  }
1466  m_stabilityTimeVector.clear();
1467  m_stabilityTimeVector = stability.GetTimeVector();
1468 
1469  // Run power flow after stability.
1470  RunPowerFlow();
1471 
1472  wxMessageDialog msgDialog(this, _("Do you wish to open the stability graphics?"), _("Question"),
1473  wxYES_NO | wxCENTRE | wxICON_QUESTION);
1474  if(msgDialog.ShowModal() == wxID_YES) {
1475  std::vector<ElementPlotData> plotDataList;
1476  for(auto it = m_elementList.begin(), itEnd = m_elementList.end(); it != itEnd; ++it) {
1477  PowerElement* element = *it;
1478  ElementPlotData plotData;
1479  if(element->GetPlotData(plotData)) plotDataList.push_back(plotData);
1480  }
1481 
1482  ChartView* cView = new ChartView(this, plotDataList, m_stabilityTimeVector);
1483  cView->Show();
1484  }
1485 
1486  return result;
1487 }
1488 void Workspace::OnMiddleDoubleClick(wxMouseEvent& event)
1489 {
1490  Fit();
1491  event.Skip();
1492 }
1493 
1494 bool Workspace::RunStaticStudies()
1495 {
1496  bool pfStatus, faultStatus, scStatus;
1497  pfStatus = faultStatus = scStatus = false;
1498 
1499  pfStatus = RunPowerFlow();
1500 
1501  if(m_properties->GetSimulationPropertiesData().faultAfterPowerFlow) {
1502  if(pfStatus) faultStatus = RunFault();
1503  } else {
1504  faultStatus = true;
1505  }
1506 
1507  if(m_properties->GetSimulationPropertiesData().scPowerAfterPowerFlow) {
1508  if(pfStatus) scStatus = RunSCPower();
1509  } else {
1510  scStatus = true;
1511  }
1512 
1513  if(pfStatus && faultStatus && scStatus) return true;
1514 
1515  return false;
1516 }
virtual bool Contains(wxPoint2DDouble position) const
Checks if the element contains a position.
Definition: Text.cpp:43
+
Element that shows power element informations in workspace.
Definition: Text.h:75
void ShowPickbox(bool showPickbox=true)
Set if the pickbox is shown.
Definition: Element.h:161
-
General and simulation data manager.
+
General and simulation data manager.
virtual void Move(wxPoint2DDouble position)
Move the element other position.
Definition: Element.cpp:123
virtual void AddPoint(wxPoint2DDouble point)
Add point to the list of points that connect the element to the bus.
Definition: Element.h:318
Base class of all elements of the program. This class is responsible for manage graphical and his dat...
Definition: Element.h:113
void SetSelected(bool selected=true)
Set element selection.
Definition: Element.h:146
-
virtual void Rotate(bool clockwise=true)
Rotate the element.
Definition: Text.cpp:162
+
virtual void Rotate(bool clockwise=true)
Rotate the element.
Definition: Text.cpp:114
virtual std::vector< Element * > GetParentList() const
Get the parent list.
Definition: Element.h:506
Calculate the power flow.
Definition: PowerFlow.h:33
@@ -116,7 +116,7 @@ $(document).ready(function(){initNavTree('_workspace_8cpp_source.html','');});
virtual void RemoveChild(Element *child)
Remove a child from the list.
Definition: Element.cpp:354
Synchronous generator power element.
-
virtual bool Intersects(wxRect2DDouble rect) const
Check if the element&#39;s rect intersects other rect.
Definition: Text.cpp:92
+
virtual bool Intersects(wxRect2DDouble rect) const
Check if the element&#39;s rect intersects other rect.
Definition: Text.cpp:82
virtual bool Intersects(wxRect2DDouble rect) const =0
Check if the element&#39;s rect intersects other rect.
virtual void MoveNode(Element *parent, wxPoint2DDouble position)
Move a node. StartMove(wxPoint2DDouble position) before start moving.
Definition: Element.h:337
@@ -138,6 +138,7 @@ $(document).ready(function(){initNavTree('_workspace_8cpp_source.html','');}); +
virtual wxString GetTipText() const
Get the tip text.
Definition: Element.h:296
Class to store the elements in the clipboard.
@@ -149,7 +150,7 @@ $(document).ready(function(){initNavTree('_workspace_8cpp_source.html','');});
virtual void AddChild(Element *child)
Add a child to the child list.
Definition: Element.cpp:353
Power line element.
Definition: Line.h:59
Calculates the electromechanical transient based on disturbances (e.g. system fault).
-
Loas shunt power element.
Definition: Load.h:42
+
Loas shunt power element.
Definition: Load.h:73
virtual bool GetContextMenu(wxMenu &menu)
Get the element contex menu.
Definition: Element.h:313
This class is responsible to manage the charts generated in the transient electromechanical studies...
Definition: ChartView.h:40
virtual bool ShowForm(wxWindow *parent, Element *element)
Show element data form.
Definition: Element.h:534
@@ -181,6 +182,7 @@ $(document).ready(function(){initNavTree('_workspace_8cpp_source.html','');});
virtual void ResetNodes()
Remove the active nodes.
Definition: Element.h:397
virtual Element * GetCopy()
Get a the element copy.
Definition: Element.h:262
+
Two-winding transformer power element.
Definition: Transformer.h:78
diff --git a/docs/doxygen/html/_workspace_8h_source.html b/docs/doxygen/html/_workspace_8h_source.html index 767bdba..d2ab715 100644 --- a/docs/doxygen/html/_workspace_8h_source.html +++ b/docs/doxygen/html/_workspace_8h_source.html @@ -88,8 +88,8 @@ $(document).ready(function(){initNavTree('_workspace_8h_source.html','');});
Workspace.h
-Go to the documentation of this file.
1 /*
2  * Copyright (C) 2017 Thales Lima Oliveira <thales@ufu.br>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program. If not, see <https://www.gnu.org/licenses/>.
16  */
17 
18 #ifndef WORKSPACE_H
19 #define WORKSPACE_H
20 
21 #include <GL/gl.h>
22 #include <GL/glu.h>
23 #include <wx/dcclient.h>
24 #include <wx/msgdlg.h>
25 #include <wx/statusbr.h>
26 #include <wx/clipbrd.h>
27 #include <wx/tipwin.h>
28 
29 #include "WorkspaceBase.h"
30 #include "Bus.h"
31 
32 #include "ControlEditor.h"
33 
34 class Camera;
35 class Element;
36 // class Bus;
37 class Line;
38 class Transformer;
39 class SyncGenerator;
40 class IndMotor;
41 class SyncMotor;
42 class Load;
43 class Inductor;
44 class Capacitor;
45 class ElementDataObject;
46 
47 class Text;
48 
49 class PowerFlow;
50 class Fault;
51 class Electromechanical;
52 
53 class ElementPlotData;
54 class ChartView;
55 
56 class PropertiesData;
57 
58 enum ElementID {
59  ID_BUS = 0,
60  ID_LINE,
61  ID_TRANSFORMER,
62  ID_SYNCGENERATOR,
63  ID_INDMOTOR,
64  ID_SYNCMOTOR,
65  ID_LOAD,
66  ID_CAPACITOR,
67  ID_INDUCTOR,
68  ID_TEXT,
69 
70  NUM_ELEMENTS
71 };
72 
81 class Workspace : public WorkspaceBase
82 {
83  public:
84  enum WorkspaceMode {
85  MODE_EDIT = 0,
86  MODE_MOVE_ELEMENT,
87  MODE_MOVE_PICKBOX,
88  MODE_MOVE_NODE,
89  MODE_DRAG,
90  MODE_DRAG_INSERT,
91  MODE_DRAG_INSERT_TEXT,
92  MODE_INSERT,
93  MODE_INSERT_TEXT,
94  MODE_SELECTION_RECT,
95  MODE_PASTE,
96  MODE_DRAG_PASTE
97  };
98 
99  Workspace();
100  Workspace(wxWindow* parent, wxString name = wxEmptyString, wxStatusBar* statusBar = NULL);
101  ~Workspace();
102 
103  wxString GetName() const { return m_name; }
104  std::vector<Element*> GetElementList() const;
105  std::vector<Text*> GetTextList() const { return m_textList; }
106  std::vector<Element*> GetAllElements() const;
107  WorkspaceMode GetWorkspaceMode() const { return m_mode; }
108  Camera* GetCamera() const { return m_camera; }
109  void CopySelection();
110  bool Paste();
111 
112  wxFileName GetSavedPath() const { return m_savedPath; }
113  void SetName(wxString name) { m_name = name; }
114  void SetElementList(std::vector<Element*> elementList);
115  void SetTextList(std::vector<Text*> textList);
116  void SetStatusBarText(wxString text) { m_statusBar->SetStatusText(text); }
117  void SetWorkspaceMode(WorkspaceMode mode) { m_mode = mode; }
118  void SetSavedPath(wxFileName savedPath) { m_savedPath = savedPath; }
119  void SetJustOpened(bool justOpened) { m_justOpened = justOpened; }
120  void Redraw() { m_glCanvas->Refresh(); }
121  void RotateSelectedElements(bool clockwise = true);
122  void DeleteSelectedElements();
123  bool GetElementsCorners(wxPoint2DDouble& leftUpCorner,
124  wxPoint2DDouble& rightDownCorner,
125  std::vector<Element*> elementList);
126  void Fit();
127  void UnselectAll();
128 
129  void ValidateBusesVoltages(Element* initialBus);
130  void ValidateElementsVoltages();
131 
132  void UpdateElementsID();
133  void UpdateTextElements();
134 
135  int GetElementNumber(ElementID elementID) { return m_elementNumber[elementID]; }
136  void IncrementElementNumber(ElementID elementID) { m_elementNumber[elementID]++; }
137  PropertiesData* GetProperties() const { return m_properties; }
138  std::vector<double> GetStabilityTimeVector() const { return m_stabilityTimeVector; }
139  bool IsContinuousCalculationActive() const { return m_continuousCalc; }
140  void SetContinuousCalculationActive(bool value = true) { m_continuousCalc = value; }
141  bool RunPowerFlow();
142  bool RunFault();
143  bool RunSCPower();
144  bool RunStaticStudies();
145  bool RunStability();
146 
147  protected:
148  virtual void OnMiddleDoubleClick(wxMouseEvent& event);
149  virtual void OnIdle(wxIdleEvent& event);
150  virtual void OnTimer(wxTimerEvent& event);
151  virtual void OnLeftDoubleClick(wxMouseEvent& event);
152  virtual void OnRightClickDown(wxMouseEvent& event);
153  virtual void OnLeftClickUp(wxMouseEvent& event);
154  virtual void OnScroll(wxMouseEvent& event);
155  virtual void OnMiddleDown(wxMouseEvent& event);
156  virtual void OnMiddleUp(wxMouseEvent& event);
157  virtual void OnMouseMotion(wxMouseEvent& event);
158  virtual void OnKeyDown(wxKeyEvent& event);
159  virtual void OnLeftClickDown(wxMouseEvent& event);
160  virtual void OnPaint(wxPaintEvent& event);
161  virtual void OnPopupClick(wxCommandEvent& event);
162 
163  void SetViewport();
164  void UpdateStatusBar();
165 
166  wxGLContext* m_glContext = NULL;
167  wxStatusBar* m_statusBar = NULL;
168  Camera* m_camera = NULL;
169  wxTipWindow* m_tipWindow = NULL;
170  wxString m_name;
171 
172  WorkspaceMode m_mode = MODE_EDIT;
173 
174  std::vector<PowerElement*> m_elementList;
175  int m_elementNumber[NUM_ELEMENTS];
176 
177  std::vector<Text*> m_textList;
178 
179  wxFileName m_savedPath;
180 
181  wxRect2DDouble m_selectionRect;
182  wxPoint2DDouble m_startSelRect;
183 
184  PropertiesData* m_properties = NULL;
185 
186  std::vector<double> m_stabilityTimeVector;
187 
188  bool m_continuousCalc = false;
189  bool m_disconnectedElement = false;
190  bool m_justOpened = false;
191 };
192 
193 #endif // WORKSPACE_H
Element that shows power element informations in workspace.
Definition: Text.h:72
-
General and simulation data manager.
+Go to the documentation of this file.
1 /*
2  * Copyright (C) 2017 Thales Lima Oliveira <thales@ufu.br>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program. If not, see <https://www.gnu.org/licenses/>.
16  */
17 
18 #ifndef WORKSPACE_H
19 #define WORKSPACE_H
20 
21 #include <GL/gl.h>
22 #include <GL/glu.h>
23 #include <wx/dcclient.h>
24 #include <wx/msgdlg.h>
25 #include <wx/statusbr.h>
26 #include <wx/clipbrd.h>
27 #include <wx/tipwin.h>
28 
29 #include "WorkspaceBase.h"
30 #include "Bus.h"
31 
32 #include "ControlEditor.h"
33 
34 class Camera;
35 class Element;
36 // class Bus;
37 class Line;
38 class Transformer;
39 class SyncGenerator;
40 class IndMotor;
41 class SyncMotor;
42 class Load;
43 class Inductor;
44 class Capacitor;
45 class ElementDataObject;
46 
47 class Text;
48 
49 class PowerFlow;
50 class Fault;
51 class Electromechanical;
52 
53 class ElementPlotData;
54 class ChartView;
55 
56 class PropertiesData;
57 
58 enum ElementID {
59  ID_BUS = 0,
60  ID_LINE,
61  ID_TRANSFORMER,
62  ID_SYNCGENERATOR,
63  ID_INDMOTOR,
64  ID_SYNCMOTOR,
65  ID_LOAD,
66  ID_CAPACITOR,
67  ID_INDUCTOR,
68  ID_TEXT,
69 
70  NUM_ELEMENTS
71 };
72 
81 class Workspace : public WorkspaceBase
82 {
83  public:
84  enum WorkspaceMode {
85  MODE_EDIT = 0,
86  MODE_MOVE_ELEMENT,
87  MODE_MOVE_PICKBOX,
88  MODE_MOVE_NODE,
89  MODE_DRAG,
90  MODE_DRAG_INSERT,
91  MODE_DRAG_INSERT_TEXT,
92  MODE_INSERT,
93  MODE_INSERT_TEXT,
94  MODE_SELECTION_RECT,
95  MODE_PASTE,
96  MODE_DRAG_PASTE
97  };
98 
99  Workspace();
100  Workspace(wxWindow* parent, wxString name = wxEmptyString, wxStatusBar* statusBar = NULL, wxGLContext* sharedGLContext = NULL);
101  ~Workspace();
102 
103  wxString GetName() const { return m_name; }
104  std::vector<Element*> GetElementList() const;
105  std::vector<Text*> GetTextList() const { return m_textList; }
106  std::vector<Element*> GetAllElements() const;
107  WorkspaceMode GetWorkspaceMode() const { return m_mode; }
108  Camera* GetCamera() const { return m_camera; }
109  void CopySelection();
110  bool Paste();
111 
112  wxFileName GetSavedPath() const { return m_savedPath; }
113  void SetName(wxString name) { m_name = name; }
114  void SetElementList(std::vector<Element*> elementList);
115  void SetTextList(std::vector<Text*> textList);
116  void SetStatusBarText(wxString text) { m_statusBar->SetStatusText(text); }
117  void SetWorkspaceMode(WorkspaceMode mode) { m_mode = mode; }
118  void SetSavedPath(wxFileName savedPath) { m_savedPath = savedPath; }
119  void SetJustOpened(bool justOpened) { m_justOpened = justOpened; }
120  void Redraw() { m_glCanvas->Refresh(); }
121  wxGLContext* GetOpenGLContext() { return m_glContext; }
122  void RotateSelectedElements(bool clockwise = true);
123  void DeleteSelectedElements();
124  bool GetElementsCorners(wxPoint2DDouble& leftUpCorner,
125  wxPoint2DDouble& rightDownCorner,
126  std::vector<Element*> elementList);
127  void Fit();
128  void UnselectAll();
129 
130  void ValidateBusesVoltages(Element* initialBus);
131  void ValidateElementsVoltages();
132 
133  void UpdateElementsID();
134  bool UpdateTextElements();
135 
136  int GetElementNumber(ElementID elementID) { return m_elementNumber[elementID]; }
137  void IncrementElementNumber(ElementID elementID) { m_elementNumber[elementID]++; }
138  PropertiesData* GetProperties() const { return m_properties; }
139  std::vector<double> GetStabilityTimeVector() const { return m_stabilityTimeVector; }
140  bool IsContinuousCalculationActive() const { return m_continuousCalc; }
141  void SetContinuousCalculationActive(bool value = true) { m_continuousCalc = value; }
142  bool RunPowerFlow();
143  bool RunFault();
144  bool RunSCPower();
145  bool RunStaticStudies();
146  bool RunStability();
147 
148  protected:
149  virtual void OnMiddleDoubleClick(wxMouseEvent& event);
150  virtual void OnIdle(wxIdleEvent& event);
151  virtual void OnTimer(wxTimerEvent& event);
152  virtual void OnLeftDoubleClick(wxMouseEvent& event);
153  virtual void OnRightClickDown(wxMouseEvent& event);
154  virtual void OnLeftClickUp(wxMouseEvent& event);
155  virtual void OnScroll(wxMouseEvent& event);
156  virtual void OnMiddleDown(wxMouseEvent& event);
157  virtual void OnMiddleUp(wxMouseEvent& event);
158  virtual void OnMouseMotion(wxMouseEvent& event);
159  virtual void OnKeyDown(wxKeyEvent& event);
160  virtual void OnLeftClickDown(wxMouseEvent& event);
161  virtual void OnPaint(wxPaintEvent& event);
162  virtual void OnPopupClick(wxCommandEvent& event);
163 
164  void SetViewport();
165  void UpdateStatusBar();
166 
167  wxGLContext* m_glContext = NULL;
168  wxStatusBar* m_statusBar = NULL;
169  Camera* m_camera = NULL;
170  wxTipWindow* m_tipWindow = NULL;
171  wxString m_name;
172 
173  WorkspaceMode m_mode = MODE_EDIT;
174 
175  std::vector<PowerElement*> m_elementList;
176  int m_elementNumber[NUM_ELEMENTS];
177 
178  std::vector<Text*> m_textList;
179 
180  wxFileName m_savedPath;
181 
182  wxRect2DDouble m_selectionRect;
183  wxPoint2DDouble m_startSelRect;
184 
185  PropertiesData* m_properties = NULL;
186 
187  std::vector<double> m_stabilityTimeVector;
188 
189  bool m_continuousCalc = false;
190  bool m_disconnectedElement = false;
191  bool m_justOpened = false;
192 };
193 
194 #endif // WORKSPACE_H
Element that shows power element informations in workspace.
Definition: Text.h:75
+
General and simulation data manager.
Base class of all elements of the program. This class is responsible for manage graphical and his dat...
Definition: Element.h:113
Calculate the power flow.
Definition: PowerFlow.h:33
Synchronous generator power element.
@@ -101,7 +101,7 @@ $(document).ready(function(){initNavTree('_workspace_8h_source.html','');});
Class to store the elements in the clipboard.
Power line element.
Definition: Line.h:59
Calculates the electromechanical transient based on disturbances (e.g. system fault).
-
Loas shunt power element.
Definition: Load.h:42
+
Loas shunt power element.
Definition: Load.h:73
This class is responsible to manage the charts generated in the transient electromechanical studies...
Definition: ChartView.h:40
Synchronous motor (synchronous compensator) power element.
Definition: SyncMotor.h:134
Calculate the fault of the system and update the elements data.
Definition: Fault.h:30
diff --git a/docs/doxygen/html/_workspace_bitmaps_8cpp_source.html b/docs/doxygen/html/_workspace_bitmaps_8cpp_source.html index ce575da..5ff46f8 100644 --- a/docs/doxygen/html/_workspace_bitmaps_8cpp_source.html +++ b/docs/doxygen/html/_workspace_bitmaps_8cpp_source.html @@ -88,7 +88,7 @@ $(document).ready(function(){initNavTree('_workspace_bitmaps_8cpp_source.html','
WorkspaceBitmaps.cpp
-
1 //
2 // This file was automatically generated by wxrc, do not edit by hand.
3 //
4 
5 #include <wx/wxprec.h>
6 
7 #ifdef __BORLANDC__
8  #pragma hdrstop
9 #endif
10 
11 #include <wx/filesys.h>
12 #include <wx/fs_mem.h>
13 #include <wx/xrc/xmlres.h>
14 #include <wx/xrc/xh_all.h>
15 
16 #if wxCHECK_VERSION(2,8,5) && wxABI_VERSION >= 20805
17  #define XRC_ADD_FILE(name, data, size, mime) \
18  wxMemoryFSHandler::AddFileWithMimeType(name, data, size, mime)
19 #else
20  #define XRC_ADD_FILE(name, data, size, mime) \
21  wxMemoryFSHandler::AddFile(name, data, size)
22 #endif
23 
24 static size_t xml_res_size_0 = 137;
25 static unsigned char xml_res_file_0[] = {
26 60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101,
27 110,99,111,100,105,110,103,61,34,85,84,70,45,56,34,63,62,10,60,114,101,
28 115,111,117,114,99,101,32,120,109,108,110,115,61,34,104,116,116,112,58,
29 47,47,119,119,119,46,119,120,119,105,100,103,101,116,115,46,111,114,103,
30 47,119,120,120,114,99,34,62,10,32,32,60,33,45,45,32,72,97,110,100,108,101,
31 114,32,71,101,110,101,114,97,116,105,111,110,32,105,115,32,79,78,32,45,
32 45,62,10,60,47,114,101,115,111,117,114,99,101,62,10};
33 
34 void wxC52C4InitBitmapResources()
35 {
36 
37  // Check for memory FS. If not present, load the handler:
38  {
39  wxMemoryFSHandler::AddFile(wxT("XRC_resource/dummy_file"), wxT("dummy one"));
40  wxFileSystem fsys;
41  wxFSFile *f = fsys.OpenFile(wxT("memory:XRC_resource/dummy_file"));
42  wxMemoryFSHandler::RemoveFile(wxT("XRC_resource/dummy_file"));
43  if (f) delete f;
44  else wxFileSystem::AddHandler(new wxMemoryFSHandlerBase);
45  }
46 
47  XRC_ADD_FILE(wxT("XRC_resource/WorkspaceBitmaps.cpp$C__Users_NDSE-69_Documents_GitHub_PSP_Project_WorkspaceBitmaps.xrc"), xml_res_file_0, xml_res_size_0, wxT("text/xml"));
48  wxXmlResource::Get()->Load(wxT("memory:XRC_resource/WorkspaceBitmaps.cpp$C__Users_NDSE-69_Documents_GitHub_PSP_Project_WorkspaceBitmaps.xrc"));
49 }
+
1 //
2 // This file was automatically generated by wxrc, do not edit by hand.
3 //
4 
5 #include <wx/wxprec.h>
6 
7 #ifdef __BORLANDC__
8  #pragma hdrstop
9 #endif
10 
11 #include <wx/filesys.h>
12 #include <wx/fs_mem.h>
13 #include <wx/xrc/xmlres.h>
14 #include <wx/xrc/xh_all.h>
15 
16 #if wxCHECK_VERSION(2,8,5) && wxABI_VERSION >= 20805
17  #define XRC_ADD_FILE(name, data, size, mime) \
18  wxMemoryFSHandler::AddFileWithMimeType(name, data, size, mime)
19 #else
20  #define XRC_ADD_FILE(name, data, size, mime) \
21  wxMemoryFSHandler::AddFile(name, data, size)
22 #endif
23 
24 static size_t xml_res_size_0 = 137;
25 static unsigned char xml_res_file_0[] = {
26 60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101,
27 110,99,111,100,105,110,103,61,34,85,84,70,45,56,34,63,62,10,60,114,101,
28 115,111,117,114,99,101,32,120,109,108,110,115,61,34,104,116,116,112,58,
29 47,47,119,119,119,46,119,120,119,105,100,103,101,116,115,46,111,114,103,
30 47,119,120,120,114,99,34,62,10,32,32,60,33,45,45,32,72,97,110,100,108,101,
31 114,32,71,101,110,101,114,97,116,105,111,110,32,105,115,32,79,78,32,45,
32 45,62,10,60,47,114,101,115,111,117,114,99,101,62,10};
33 
34 void wxC52C4InitBitmapResources()
35 {
36 
37  // Check for memory FS. If not present, load the handler:
38  {
39  wxMemoryFSHandler::AddFile(wxT("XRC_resource/dummy_file"), wxT("dummy one"));
40  wxFileSystem fsys;
41  wxFSFile *f = fsys.OpenFile(wxT("memory:XRC_resource/dummy_file"));
42  wxMemoryFSHandler::RemoveFile(wxT("XRC_resource/dummy_file"));
43  if (f) delete f;
44  else wxFileSystem::AddHandler(new wxMemoryFSHandlerBase);
45  }
46 
47  XRC_ADD_FILE(wxT("XRC_resource/WorkspaceBitmaps.cpp$_home_thales_Documentos_GitHub_PSP_Project_WorkspaceBitmaps.xrc"), xml_res_file_0, xml_res_size_0, wxT("text/xml"));
48  wxXmlResource::Get()->Load(wxT("memory:XRC_resource/WorkspaceBitmaps.cpp$_home_thales_Documentos_GitHub_PSP_Project_WorkspaceBitmaps.xrc"));
49 }
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
 CControlSystemTestBase
 CDataReportForm that shows the results of power flow and fault calculations
 CDataReportBase
 CElectricCalculationBase class of electric calculations, with general methods
 CElectromechanicalCalculates the electromechanical transient based on disturbances (e.g. system fault)
 CElementBase class of all elements of the program. This class is responsible for manage graphical and his data
 CElementDataObjectClass to store the elements in the clipboard
 CElementPlotData
 CElementsLists
 CExponentialGenerates an output following an exponential function
 CExponentialFormForm to edit the exponential control data
 CExponentialFormBase
 CFaultCalculate the fault of the system and update the elements data
 CFileHandingSave and opens the projects created on disk
 CGainProvide an output multiplying the input by a constant
 CGainFormForm to edit the gain control data
 CGainFormBase
 CGeneralData
 CGeneralPropertiesFormForm to edit the software's general data
 CGeneralPropertiesFormBase
 CGeneratorStabFormForm to edit the synchronous generator data for electromechanical studies
 CGeneratorStabFormBase
 CGraphicalElementAbstract class for graphical elements shown with power elements in workspace
 CIndMotorInduction motor power element
 CIndMotorElectricalData
 CIndMotorFormForm to edit the induction motor power data
 CIndMotorFormBase
 CInductorInductor shunt power element
 CInductorElectricalData
 CIntegrationConstantIntegration constants to calculate dynamic elements through trapezoidal integration method
 CIOControlProvides the communication with the power element
 CIOControlFormForm to edit the input/output control data
 CIOControlFormBase
 CLimiterLimits the input value by superior and inferior values
 CLimiterFormForm to edit the limit control data
 CLimiterFormBase
 CLinePower line element
 CLineElectricalData
 CLineFormForm to edit the line power data
 CLineFormBase
 CLoadLoas shunt power element
 CLoadElectricalData
 CLoadFormForm to edit the load power data
 CLoadFormBase
 CMachinesAbstract class for rotary machines power elements
 CMainApp
 CMainFrameMain frame of the program. This class manage the ribbon menu and the notebook behavior
 CMainFrameBase
 CMultiplierMultiplies two inputs
 CNodeNode of a control element. This class manages the user interaction with the connection and control elements
 COpenGLColourClass to manage color of OpenGL
 CPlotDataThis class is responsible to manage the graphical data of electromechanical result to be plotted on chart viewer
 CPowerElementAbstract class of power elements
 CPowerFlowCalculate the power flow
 CPropertiesDataGeneral and simulation data manager
 CRateLimiterLimits the rising and/or falling rate.
+
 CDividerControl element that divides two inputs
 CElectricCalculationBase class of electric calculations, with general methods
 CElectromechanicalCalculates the electromechanical transient based on disturbances (e.g. system fault)
 CElementBase class of all elements of the program. This class is responsible for manage graphical and his data
 CElementDataObjectClass to store the elements in the clipboard
 CElementPlotData
 CElementsLists
 CExponentialGenerates an output following an exponential function
 CExponentialFormForm to edit the exponential control data
 CExponentialFormBase
 CFaultCalculate the fault of the system and update the elements data
 CFileHandingSave and opens the projects created on disk
 CGainProvide an output multiplying the input by a constant
 CGainFormForm to edit the gain control data
 CGainFormBase
 CGeneralData
 CGeneralPropertiesFormForm to edit the software's general data
 CGeneralPropertiesFormBase
 CGeneratorStabFormForm to edit the synchronous generator data for electromechanical studies
 CGeneratorStabFormBase
 CGraphicalElementAbstract class for graphical elements shown with power elements in workspace
 CIndMotorInduction motor power element
 CIndMotorElectricalData
 CIndMotorFormForm to edit the induction motor power data
 CIndMotorFormBase
 CInductorInductor shunt power element
 CInductorElectricalData
 CIntegrationConstantIntegration constants to calculate dynamic elements through trapezoidal integration method
 CIOControlProvides the communication with the power element
 CIOControlFormForm to edit the input/output control data
 CIOControlFormBase
 CLimiterLimits the input value by superior and inferior values
 CLimiterFormForm to edit the limit control data
 CLimiterFormBase
 CLinePower line element
 CLineElectricalData
 CLineFormForm to edit the line power data
 CLineFormBase
 CLoadLoas shunt power element
 CLoadElectricalData
 CLoadFormForm to edit the load power data
 CLoadFormBase
 CMachinesAbstract class for rotary machines power elements
 CMainApp
 CMainFrameMain frame of the program. This class manage the ribbon menu and the notebook behavior
 CMainFrameBase
 CMathOperationAbstract class that define the general behavior of math operation control block
 CMultiplierMultiplies two inputs
 CNodeNode of a control element. This class manages the user interaction with the connection and control elements
 COpenGLColourClass to manage color of OpenGL
 COpenGLTextClass to draw text on OpenGL using wxWidgets
 CPlotDataThis class is responsible to manage the graphical data of electromechanical result to be plotted on chart viewer
 CPowerElementAbstract class of power elements
 CPowerFlowCalculate the power flow
 CPropertiesDataGeneral and simulation data manager
 CRateLimiterLimits the rising and/or falling rate.
 CRateLimiterFormForm to edit the rate limit control data
 CRateLimiterFormBase
 CReactiveLimits
 CReactiveShuntElementFormForm to edit the reactive shunt element power data
 CReactiveShuntElementFormBase
 CShuntAbstract class for shunt power elements
 CSimulationData
 CSimulationsSettingsFormForm to edit the simulation data
 CSimulationsSettingsFormBase
 CSumSum the all inputs (can choose the input signal)
 CSumFormForm to edit the sum control data
 CSumFormBase
 CSwitchingDataSwitching data of power elements
 CSwitchingFormForm to edit the switching data of power elements for electromechanical transient studies
 CSwitchingFormBase
 CSyncGeneratorSynchronous generator power element
 CSyncGeneratorElectricalData
 CSyncMachineFormForm to edit the synchronous machine power data
 CSyncMachineFormBase
 CSyncMachineModelDataSynchronous machine data for different models
 CSyncMotorSynchronous motor (synchronous compensator) power element
 CSyncMotorElectricalData
 CTextElement that shows power element informations in workspace
 CTextFormForm to edit the text graphical data
 CTextFormBase
 CTextGLDrawable
 CTextTexture
 CTransferFunctionCalculates the time response by a frequency domain transfer function
 CTransferFunctionFormForm to edit the transfer function control data
 CTransferFunctionFormBase
 CTransformerTwo-winding transformer power element
 CTransformerElectricalData
 CTransformerFormForm to edit the transformer power data
 CTransformerFormBase
 CWorkspaceThis class manages the graphical and power elements. It is responsible for handling the user's interaction with the elements
 CWorkspaceBase
 CwxGLNumberRenderer
 CwxGLString
 CwxGLStringArray
 CwxRibbonMetroArtProvider
 CRateLimiterFormForm to edit the rate limit control data
 CRateLimiterFormBase
 CReactiveLimits
 CReactiveShuntElementFormForm to edit the reactive shunt element power data
 CReactiveShuntElementFormBase
 CShuntAbstract class for shunt power elements
 CSimulationData
 CSimulationsSettingsFormForm to edit the simulation data
 CSimulationsSettingsFormBase
 CSumSum the all inputs (can choose the input signal)
 CSumFormForm to edit the sum control data
 CSumFormBase
 CSwitchingDataSwitching data of power elements
 CSwitchingFormForm to edit the switching data of power elements for electromechanical transient studies
 CSwitchingFormBase
 CSyncGeneratorSynchronous generator power element
 CSyncGeneratorElectricalData
 CSyncMachineFormForm to edit the synchronous machine power data
 CSyncMachineFormBase
 CSyncMachineModelDataSynchronous machine data for different models
 CSyncMotorSynchronous motor (synchronous compensator) power element
 CSyncMotorElectricalData
 CTextElement that shows power element informations in workspace
 CTextFormForm to edit the text graphical data
 CTextFormBase
 CTransferFunctionCalculates the time response by a frequency domain transfer function
 CTransferFunctionFormForm to edit the transfer function control data
 CTransferFunctionFormBase
 CTransformerTwo-winding transformer power element
 CTransformerElectricalData
 CTransformerFormForm to edit the transformer power data
 CTransformerFormBase
 CWorkspaceThis class manages the graphical and power elements. It is responsible for handling the user's interaction with the elements
 CWorkspaceBase
 CwxRibbonMetroArtProvider
diff --git a/docs/doxygen/html/annotated_dup.js b/docs/doxygen/html/annotated_dup.js index cade99c..d6a2478 100644 --- a/docs/doxygen/html/annotated_dup.js +++ b/docs/doxygen/html/annotated_dup.js @@ -26,6 +26,7 @@ var annotated_dup = [ "ControlSystemTestBase", "class_control_system_test_base.html", "class_control_system_test_base" ], [ "DataReport", "class_data_report.html", "class_data_report" ], [ "DataReportBase", "class_data_report_base.html", "class_data_report_base" ], + [ "Divider", "class_divider.html", "class_divider" ], [ "ElectricCalculation", "class_electric_calculation.html", "class_electric_calculation" ], [ "Electromechanical", "class_electromechanical.html", "class_electromechanical" ], [ "Element", "class_element.html", "class_element" ], @@ -71,9 +72,11 @@ var annotated_dup = [ "MainApp", "class_main_app.html", "class_main_app" ], [ "MainFrame", "class_main_frame.html", "class_main_frame" ], [ "MainFrameBase", "class_main_frame_base.html", "class_main_frame_base" ], + [ "MathOperation", "class_math_operation.html", "class_math_operation" ], [ "Multiplier", "class_multiplier.html", "class_multiplier" ], [ "Node", "class_node.html", "class_node" ], [ "OpenGLColour", "class_open_g_l_colour.html", "class_open_g_l_colour" ], + [ "OpenGLText", "class_open_g_l_text.html", "class_open_g_l_text" ], [ "PlotData", "class_plot_data.html", "class_plot_data" ], [ "PowerElement", "class_power_element.html", "class_power_element" ], [ "PowerFlow", "class_power_flow.html", "class_power_flow" ], @@ -104,8 +107,6 @@ var annotated_dup = [ "Text", "class_text.html", "class_text" ], [ "TextForm", "class_text_form.html", "class_text_form" ], [ "TextFormBase", "class_text_form_base.html", "class_text_form_base" ], - [ "TextGLDrawable", "class_text_g_l_drawable.html", "class_text_g_l_drawable" ], - [ "TextTexture", "class_text_texture.html", "class_text_texture" ], [ "TransferFunction", "class_transfer_function.html", "class_transfer_function" ], [ "TransferFunctionForm", "class_transfer_function_form.html", "class_transfer_function_form" ], [ "TransferFunctionFormBase", "class_transfer_function_form_base.html", "class_transfer_function_form_base" ], @@ -115,8 +116,5 @@ var annotated_dup = [ "TransformerFormBase", "class_transformer_form_base.html", "class_transformer_form_base" ], [ "Workspace", "class_workspace.html", "class_workspace" ], [ "WorkspaceBase", "class_workspace_base.html", "class_workspace_base" ], - [ "wxGLNumberRenderer", "classwx_g_l_number_renderer.html", "classwx_g_l_number_renderer" ], - [ "wxGLString", "classwx_g_l_string.html", "classwx_g_l_string" ], - [ "wxGLStringArray", "classwx_g_l_string_array.html", "classwx_g_l_string_array" ], [ "wxRibbonMetroArtProvider", "classwx_ribbon_metro_art_provider.html", "classwx_ribbon_metro_art_provider" ] ]; \ No newline at end of file diff --git a/docs/doxygen/html/class_about_form_base.html b/docs/doxygen/html/class_about_form_base.html index cb07e5a..15d49bd 100644 --- a/docs/doxygen/html/class_about_form_base.html +++ b/docs/doxygen/html/class_about_form_base.html @@ -192,7 +192,7 @@ wxButton * m_buttonOK<

Detailed Description

-

Definition at line 169 of file PropertiesForm.h.

+

Definition at line 224 of file PropertiesForm.h.


The documentation for this class was generated from the following files:
diff --git a/docs/doxygen/html/class_constant.html b/docs/doxygen/html/class_constant.html index 433d2d7..0e3e8f7 100644 --- a/docs/doxygen/html/class_constant.html +++ b/docs/doxygen/html/class_constant.html @@ -128,9 +128,9 @@ Public Member Functions virtual void Rotate (bool clockwise=true)  Rotate the element. More...
  - -virtual void UpdateText () -  +virtual bool UpdateText () + Update the OpenGL text in the element (if present). More...
virtual void SetValue (double value)   @@ -378,12 +378,9 @@ Protected Attributes double m_value = 1.0   - -wxGLStringm_glStringValue = NULL -  - -int m_fontSize = 10 -  + +OpenGLTextm_glText = NULL +  - Protected Attributes inherited from ControlElement std::vector< Node * > m_nodeList @@ -568,7 +565,7 @@ Additional Inherited Members

Reimplemented from Element.

-

Definition at line 32 of file Constant.cpp.

+

Definition at line 35 of file Constant.cpp.

@@ -600,7 +597,7 @@ Additional Inherited Members

Reimplemented from Element.

-

Definition at line 123 of file Constant.cpp.

+

Definition at line 116 of file Constant.cpp.

@@ -676,7 +673,7 @@ Additional Inherited Members

Reimplemented from Element.

-

Definition at line 67 of file Constant.cpp.

+

Definition at line 66 of file Constant.cpp.

@@ -726,7 +723,39 @@ Additional Inherited Members

Reimplemented from Element.

-

Definition at line 56 of file Constant.cpp.

+

Definition at line 55 of file Constant.cpp.

+ + + + +

◆ UpdateText()

+ +
+
+ + + + + +
+ + + + + + + +
bool Constant::UpdateText ()
+
+virtual
+
+ +

Update the OpenGL text in the element (if present).

+
Returns
true if OpenGLText is ok, false otherwise.
+ +

Reimplemented from ControlElement.

+ +

Definition at line 124 of file Constant.cpp.

diff --git a/docs/doxygen/html/class_constant.js b/docs/doxygen/html/class_constant.js index 49211d2..1456cd2 100644 --- a/docs/doxygen/html/class_constant.js +++ b/docs/doxygen/html/class_constant.js @@ -11,8 +11,7 @@ var class_constant = [ "SetValue", "class_constant.html#a059fdb74aa6aea03fbd7a22de1def41c", null ], [ "ShowForm", "class_constant.html#af6bded0e01717303bb71da9e45c2b061", null ], [ "UpdatePoints", "class_constant.html#afad1a9ac77a4e2b94530d045bffa3c37", null ], - [ "UpdateText", "class_constant.html#adda09379e36416476d5e5a2f61c8dad3", null ], - [ "m_fontSize", "class_constant.html#a3d1cff7badada5e9350d19649086a79a", null ], - [ "m_glStringValue", "class_constant.html#a1916148248a168f589791ec0435ec937", null ], + [ "UpdateText", "class_constant.html#a380618903f79d9062da054a7337bab97", null ], + [ "m_glText", "class_constant.html#a15fd99035dc28611e49f383bc4cfc56f", null ], [ "m_value", "class_constant.html#a34ebce575d175d506f46adc72c3a2070", null ] ]; \ No newline at end of file diff --git a/docs/doxygen/html/class_constant_form_base.html b/docs/doxygen/html/class_constant_form_base.html index e29a6fd..3120b56 100644 --- a/docs/doxygen/html/class_constant_form_base.html +++ b/docs/doxygen/html/class_constant_form_base.html @@ -159,7 +159,7 @@ wxButton * m_buttonCancel<

Detailed Description

-

Definition at line 923 of file ElementForm.h.

+

Definition at line 966 of file ElementForm.h.


The documentation for this class was generated from the following files: