AiDataTaskRuner/UI/TabWorkFlows/Main.mqh
Nique_372 7f18f1f4f2
2026-04-13 17:42:23 -05:00

918 lines
33 KiB
MQL5

//+------------------------------------------------------------------+
//| Main.mqh |
//| Copyright 2025, Niquel Mendoza. |
//| https://www.mql5.com/es/users/nique_372 |
//+------------------------------------------------------------------+
#property copyright "Copyright 2025, Niquel Mendoza."
#property link "https://www.mql5.com/es/users/nique_372"
#property strict
#ifndef AIDATATASKRUNER_UI_TABWORKFLOWS_MAIN_MQH
#define AIDATATASKRUNER_UI_TABWORKFLOWS_MAIN_MQH
//+------------------------------------------------------------------+
//| Include |
//+------------------------------------------------------------------+
//--- Defines basicos para lagui
#include "..\\Defines.mqh"
//--- Epxert para le ejeucion del ea
#include <TSN\\ExtraCodes\\Expert.mqh>
//--- Funciones extra (shell execute)
#include <TSN\\MQLArticles\\Utils\\ExtraFunctions.mqh>
//--- Backend protocolo de comuniacion con el runner
#include "..\\..\\Backend\\Workflows\\Protocol\\Def.mqh"
//--- Reciclamos las imagenes de state para este tab (osea agarremos las imagenes de data generation)
#include "..\\DataGenerationTab\\Def.mqh"
//+------------------------------------------------------------------+
//| Defines \ Enums \ Arrs |
//+------------------------------------------------------------------+
//--- Estado
enum ENUM_TABWF_STATE
{
WF_STATE_ESPERANDO_RUNNER = 0,
WF_STATE_ESPERANDO_EJECUTANDO = 1,
WF_STATE_ESPERANDO_NADA = 2
};
//--- Tabla
#define TABWF_TABLERES_TOTAL_COLS (4)
#define TABWF_TABLERES_COL_NAME (0)
#define TABWF_TABLERES_COL_RES (1)
#define TABWF_TABLERES_COL_STATE (2)
#define TABWF_TABLERES_COL_TIME (3)
//--- Imagenes
const string g_aitaskruner_wf_img[4]
{
"res\\circle_amarillo.bmp",
"res\\circle_gris.bmp",
"res\\circle_verde.bmp",
"Images\\EasyAndFastGUI\\Controls\\Close_red.bmp"
};
//--- Img idx
#define TABWF_IMAGE_EN_EJECUCION (0)
#define TABWF_IMAGE_EN_PENDIENTE (1)
#define TABWF_IMAGE_EN_EXTIO (2)
#define TABWF_IMAGE_EN_FALLO (3)
//+------------------------------------------------------------------+
//| Tab de workflows |
//+------------------------------------------------------------------+
class CTabWorkflows : public CGuiBaseComponent<CLoggerBase>
{
private:
CTabs m_tabs;
ENUM_TABWF_STATE m_state;
//--- Tab [Run]
// Sec de configuracion del archivo yml
CTextLabel m_label_tit_workflows;
CTextLabel m_label_selec_wf;
CTextLabel m_label_selec_val_wf;
CButton m_btn_browse_wf;
CButton m_btn_template_wf;
CButton m_btn_open_wf;
// Sep
CSeparateLine m_sep_line_one;
// Nombre del yml
CTextLabel m_label_wf_name;
CTextLabel m_label_the_wf_name;
// Botones
CButton m_btn_run_wf;
CButton m_btn_relanzar_ea;
//--- Tab [View]
CTextLabel m_label_tit_execution;
CTable m_table_results;
// CButton m_btn_cancel;
//--- Variables
string m_path_to_wf_temp;
string m_path_ea;
long m_last_runner_chart_id;
string m_arr_names_tables[4]; // 4
//--- Run
void RunWF();
//--- Eventos
void OnWfStart();
void OnWfStep(const string& sparam);
void OnWfEnd(const string& sparam);
//--- Creacion
bool CreateRunTab(CWndCreate *p, CWindow &main_window, int top_gap, int left_gap, int right_gap, int bottom_gap);
bool CreateViewTab(CWndCreate *p, CWindow &main_window, int top_gap, int left_gap, int right_gap, int bottom_gap);
public:
CTabWorkflows(void);
~CTabWorkflows(void) { if(m_last_runner_chart_id != -1) ::ChartClose(m_last_runner_chart_id); }
//---
void Init(const string &path_ea);
//--- Creacion
bool Create(CWndCreate* p, CWindow& main_window, int top_gap, int left_gap, int right_gap, int bottom_gap);
//--- Eventos
bool OnClickButtom(const long lparam);
//--- Evento especial
void ChartEvent(const int32_t id, const long& lparam, const double& dparam, const string& sparam);
//--- Cambio de lenguaje
void OnLenguajeChange() override final;
//--- Corre el 4 hilo
bool RunEA();
};
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
CTabWorkflows::CTabWorkflows(void)
: CGuiBaseComponent<CLoggerBase>("CTabWorkflows"), m_state(WF_STATE_ESPERANDO_NADA), m_path_to_wf_temp(NULL), m_path_ea(NULL),
m_last_runner_chart_id(-1)
{
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void CTabWorkflows::Init(const string &path_ea)
{
//--- Cache
m_path_to_wf_temp = AIDATATASKRUNER_PATH_WORKFLOWS + "Temp\\wf_data.temp";
m_path_ea = path_ea;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CTabWorkflows::Create(CWndCreate *p, CWindow &main_window, int top_gap, int left_gap, int right_gap, int bottom_gap)
{
//---
if(StringSplit(m_language[GUIBASE_COMPONENT_NAME(m_arr_names_tables)], '|', m_arr_names_tables) != 4)
{
LogFatalError("No se pudo hacer split a los nombres de los estados", FUNCION_ACTUAL);
return false;
}
//---
string txt[2] = {m_language[GUIBASE_COMPONENT_NAME(m_tabs) + "_0"], m_language[GUIBASE_COMPONENT_NAME(m_tabs) + "_1"]};
int width[2] = {70, 80};
color clrs_tab_label[2] = {AIDATATASKRUNER_COLOR_TEXT_SECONDARY, AIDATATASKRUNER_COLOR_TEXT_SECONDARY};
color clrs_tab_label_pressed[2] = {AIDATATASKRUNER_COLOR_ACCENT, AIDATATASKRUNER_COLOR_ACCENT};
top_gap += 24;
left_gap += 4;
right_gap += 4;
bottom_gap += 4;
//---
m_tabs.BackColor(AIDATATASKRUNER_COLOR_FONDO_SUBTAB);
m_tabs.BackColorHover(AIDATATASKRUNER_COLOR_FONDO_SUBTAB_HOVER);
m_tabs.BackColorPressed(AIDATATASKRUNER_COLOR_FONDO_SUBTAB_PRESSED);
m_tabs.BackColorLocked(AIDATATASKRUNER_COLOR_FONDO_SUBTAB_LOCKED);
m_tabs.BorderColor(AIDATATASKRUNER_COLOR_BORDER);
m_tabs.BorderColorHover(AIDATATASKRUNER_COLOR_BORDER_HOVER);
m_tabs.BorderColorPressed(AIDATATASKRUNER_COLOR_BORDER_HOVER);
m_tabs.BorderColorLocked(AIDATATASKRUNER_COLOR_BORDER);
if(!p.CreateTabs(m_tabs, main_window, 0, m_base_tab, m_base_tab_idx, left_gap, top_gap, 0, 0, txt, width,
clrs_tab_label, clrs_tab_label_pressed, TABS_TOP, true, true, right_gap, bottom_gap))
{
GUIBASE_ERROR_CREATION(m_tabs);
return false;
}
//---
if(!CreateRunTab(p, main_window, top_gap, left_gap, right_gap, bottom_gap))
return false;
//---
if(!CreateViewTab(p, main_window, top_gap, left_gap, right_gap, bottom_gap))
return false;
//---
return true;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CTabWorkflows::CreateRunTab(CWndCreate *p, CWindow &main_window, int top_gap, int left_gap, int right_gap, int bottom_gap)
{
//---
const int initial_x = left_gap + 5;
int x = initial_x;
int y = top_gap + 10;
//--- Titulo
m_label_tit_workflows.FontSize(14);
m_label_tit_workflows.Font("Arial");
m_label_tit_workflows.LabelColor(AIDATATASKRUNER_COLOR_TEXT_PRIMARY);
m_label_tit_workflows.BackColor(AIDATATASKRUNER_COLOR_FONDO_SUBTAB_PRESSED);
if(!p.CreateTextLabel(m_label_tit_workflows, m_language[GUIBASE_COMPONENT_NAME(m_label_tit_workflows)],
main_window, 0, m_tabs, 0, x, y, 200))
{
GUIBASE_ERROR_CREATION(m_label_tit_workflows);
return false;
}
y += m_label_tit_workflows.YSize() + 10;
//--- Label selec
m_label_selec_wf.FontSize(10);
m_label_selec_wf.Font("Arial");
m_label_selec_wf.LabelColor(AIDATATASKRUNER_COLOR_TEXT_SECONDARY);
m_label_selec_wf.BackColor(AIDATATASKRUNER_COLOR_FONDO_SUBTAB_PRESSED);
if(!p.CreateTextLabel(m_label_selec_wf, m_language[GUIBASE_COMPONENT_NAME(m_label_selec_wf)],
main_window, 0, m_tabs, 0, x, y, 100, 25))
{
GUIBASE_ERROR_CREATION(m_label_selec_wf);
return false;
}
x += m_label_selec_wf.XSize() + 5;
//--- Label val
m_label_selec_val_wf.FontSize(10);
m_label_selec_val_wf.Font("Arial");
m_label_selec_val_wf.LabelColor(AIDATATASKRUNER_COLOR_TEXT_PRIMARY);
m_label_selec_val_wf.BackColor(AIDATATASKRUNER_COLOR_EDIT_BACK);
m_label_selec_val_wf.LabelXGap(5);
m_label_selec_val_wf.LabelYGap(3);
m_label_selec_val_wf.Tooltip(m_language.Tooltip(GUIBASE_COMPONENT_NAME(m_label_selec_val_wf)));
if(!p.CreateTextLabel(m_label_selec_val_wf, "",
main_window, 0, m_tabs, 0, x, y, 400, 25))
{
GUIBASE_ERROR_CREATION(m_label_selec_val_wf);
return false;
}
x = initial_x;
y += m_label_selec_val_wf.YSize() + 8;
//--- Browse
m_btn_browse_wf.AddImagesGroup(5, 2, g_eafmod_ic_arr_folderw10_image);
m_btn_browse_wf.ChangeImage(0, 0);
m_btn_browse_wf.LabelXGap(22);
m_btn_browse_wf.FontSize(10);
m_btn_browse_wf.Font("Arial");
m_btn_browse_wf.BackColor(AIDATATASKRUNER_COLOR_BTN_BACK);
m_btn_browse_wf.LabelColor(AIDATATASKRUNER_COLOR_TEXT_SECONDARY);
m_btn_browse_wf.BorderColor(AIDATATASKRUNER_COLOR_BTN_BORDER);
m_btn_browse_wf.Tooltip(m_language.Tooltip(GUIBASE_COMPONENT_NAME(m_btn_browse_wf)));
if(!p.CreateButton(m_btn_browse_wf, m_language[GUIBASE_COMPONENT_NAME(m_btn_browse_wf)],
main_window, 0, m_tabs, 0, x, y, 100))
{
GUIBASE_ERROR_CREATION(m_btn_browse_wf);
return false;
}
x += m_btn_browse_wf.XSize() + 5;
//--- Template
m_btn_template_wf.AddImagesGroup(5, 2, g_eafmod_ic_arr_help_image);
m_btn_template_wf.ChangeImage(0, 0);
m_btn_template_wf.FontSize(10);
m_btn_template_wf.Font("Arial");
m_btn_template_wf.BackColor(AIDATATASKRUNER_COLOR_FONDO_SUBTAB_PRESSED);
m_btn_template_wf.LabelColor(AIDATATASKRUNER_COLOR_TEXT_SECONDARY);
m_btn_template_wf.BorderColor(AIDATATASKRUNER_COLOR_FONDO_SUBTAB_PRESSED);
m_btn_template_wf.Tooltip(m_language.Tooltip(GUIBASE_COMPONENT_NAME(m_btn_template_wf)));
if(!p.CreateButton(m_btn_template_wf, "",
main_window, 0, m_tabs, 0, x, y, 30))
{
GUIBASE_ERROR_CREATION(m_btn_template_wf);
return false;
}
x += m_btn_template_wf.XSize() + 5;
//--- Open
m_btn_open_wf.FontSize(10);
m_btn_open_wf.Font("Arial");
m_btn_open_wf.BackColor(AIDATATASKRUNER_COLOR_BTN_BACK);
m_btn_open_wf.LabelColor(AIDATATASKRUNER_COLOR_TEXT_SECONDARY);
m_btn_open_wf.BorderColor(AIDATATASKRUNER_COLOR_BTN_BORDER);
m_btn_open_wf.Tooltip(m_language.Tooltip(GUIBASE_COMPONENT_NAME(m_btn_open_wf)));
if(!p.CreateButton(m_btn_open_wf, m_language[GUIBASE_COMPONENT_NAME(m_btn_open_wf)],
main_window, 0, m_tabs, 0, x, y, 100))
{
GUIBASE_ERROR_CREATION(m_btn_open_wf);
return false;
}
x = initial_x;
y += m_btn_open_wf.YSize() + 10;
//---
const int xsize = main_window.X2() - initial_x - initial_x;
if(!p.CreateSepLine(m_sep_line_one, main_window, 0, initial_x, y, xsize, (9 + 25 + 8 + 7), AIDATATASKRUNER_COLOR_BTN_BORDER, AIDATATASKRUNER_COLOR_BTN_BORDER, H_SEP_LINE))
{
GUIBASE_ERROR_CREATION(m_sep_line_one);
return false;
}
y += 2 + 7;
//--- Label wf name
m_label_wf_name.FontSize(10);
m_label_wf_name.Font("Arial");
m_label_wf_name.LabelColor(AIDATATASKRUNER_COLOR_TEXT_SECONDARY);
m_label_wf_name.BackColor(AIDATATASKRUNER_COLOR_FONDO_SUBTAB_PRESSED);
if(!p.CreateTextLabel(m_label_wf_name, m_language[GUIBASE_COMPONENT_NAME(m_label_wf_name)],
main_window, 0, m_tabs, 0, x, y, 100, 25))
{
GUIBASE_ERROR_CREATION(m_label_wf_name);
return false;
}
x += m_label_wf_name.XSize() + 5;
//--- Label the wf name val
m_label_the_wf_name.FontSize(10);
m_label_the_wf_name.Font("Arial");
m_label_the_wf_name.LabelColor(AIDATATASKRUNER_COLOR_TEXT_PRIMARY);
m_label_the_wf_name.BackColor(AIDATATASKRUNER_COLOR_FONDO_SUBTAB_PRESSED);
m_label_the_wf_name.Tooltip(m_language.Tooltip(GUIBASE_COMPONENT_NAME(m_label_the_wf_name)));
if(!p.CreateTextLabel(m_label_the_wf_name, m_language[GUIBASE_COMPONENT_NAME(m_label_the_wf_name) + "_nada"],
main_window, 0, m_tabs, 0, x, y, 300, 25))
{
GUIBASE_ERROR_CREATION(m_label_the_wf_name);
return false;
}
x = initial_x;
y += m_label_the_wf_name.YSize() + 15;
//--- Run
m_btn_run_wf.FontSize(10);
m_btn_run_wf.Font("Arial");
m_btn_run_wf.BackColor(AIDATATASKRUNER_COLOR_BTN_BACK);
m_btn_run_wf.LabelColor(AIDATATASKRUNER_COLOR_TEXT_SECONDARY);
m_btn_run_wf.BorderColor(AIDATATASKRUNER_COLOR_BTN_BORDER);
m_btn_run_wf.Tooltip(m_language.Tooltip(GUIBASE_COMPONENT_NAME(m_btn_run_wf)));
if(!p.CreateButton(m_btn_run_wf, m_language[GUIBASE_COMPONENT_NAME(m_btn_run_wf)],
main_window, 0, m_tabs, 0, x, y, 120))
{
GUIBASE_ERROR_CREATION(m_btn_run_wf);
return false;
}
//---
x += m_btn_run_wf.XSize() + 5;
//--- Run
m_btn_relanzar_ea.FontSize(10);
m_btn_relanzar_ea.Font("Arial");
m_btn_relanzar_ea.BackColor(AIDATATASKRUNER_COLOR_BTN_BACK);
m_btn_relanzar_ea.LabelColor(AIDATATASKRUNER_COLOR_TEXT_SECONDARY);
m_btn_relanzar_ea.BorderColor(AIDATATASKRUNER_COLOR_BTN_BORDER);
m_btn_relanzar_ea.Tooltip(m_language.Tooltip(GUIBASE_COMPONENT_NAME(m_btn_relanzar_ea)));
if(!p.CreateButton(m_btn_relanzar_ea, m_language[GUIBASE_COMPONENT_NAME(m_btn_relanzar_ea)],
main_window, 0, m_tabs, 0, x, y, 120))
{
GUIBASE_ERROR_CREATION(m_btn_run_wf);
return false;
}
//---
return true;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CTabWorkflows::CreateViewTab(CWndCreate *p, CWindow &main_window, int top_gap, int left_gap, int right_gap, int bottom_gap)
{
//---
const int initial_x = left_gap + 5;
int x = initial_x;
int y = top_gap + 10;
//--- Titulo
m_label_tit_execution.FontSize(14);
m_label_tit_execution.Font("Arial");
m_label_tit_execution.LabelColor(AIDATATASKRUNER_COLOR_TEXT_PRIMARY);
m_label_tit_execution.BackColor(AIDATATASKRUNER_COLOR_FONDO_SUBTAB_PRESSED);
if(!p.CreateTextLabel(m_label_tit_execution, m_language[GUIBASE_COMPONENT_NAME(m_label_tit_execution)],
main_window, 0, m_tabs, 1, x, y, 200))
{
GUIBASE_ERROR_CREATION(m_label_tit_execution);
return false;
}
y += m_label_tit_execution.YSize() + 10;
//--- Tabla
string headers[];
const string header_str = m_language[GUIBASE_COMPONENT_NAME(m_table_results) + "_header"];
if(!StrTo::CstArray(headers, header_str, '|', true))
{
LogError(StringFormat("Fallo al hacer str to array str, str = %s", header_str), FUNCION_ACTUAL);
return false;
}
ArrayResize(headers, TABWF_TABLERES_TOTAL_COLS);
//---
m_table_results.HeadersColor(C'0x2A,0x4A,0x6A');
m_table_results.HeadersColorHover(AIDATATASKRUNER_COLOR_ACCENT);
m_table_results.HeadersColorPressed(C'0x1E,0x38,0x52');
m_table_results.HeadersTextColor(AIDATATASKRUNER_COLOR_TEXT_PRIMARY);
m_table_results.CellColor(AIDATATASKRUNER_COLOR_FONDO_WIN);
m_table_results.CellColorHover(AIDATATASKRUNER_COLOR_EDIT_BACK);
m_table_results.CElement::BackColor(AIDATATASKRUNER_COLOR_FONDO_WIN);
m_table_results.GridColor(AIDATATASKRUNER_COLOR_BORDER);
m_table_results.m_label_color = AIDATATASKRUNER_COLOR_TEXT_SECONDARY;
//---
CScrollH *sh = m_table_results.GetScrollHPointer();
sh.BackColor(AIDATATASKRUNER_COLOR_FONDO_TAB);
sh.ThumbColor(AIDATATASKRUNER_COLOR_BORDER);
sh.ThumbColorHover(AIDATATASKRUNER_COLOR_BORDER_HOVER);
sh.ThumbColorPressed(AIDATATASKRUNER_COLOR_ACCENT);
sh.IncFile((string)RESOURCE_SCROLL_LEFT_WHITE);
sh.IncFileLocked((string)RESOURCE_SCROLL_LEFT_WHITE);
sh.IncFilePressed((string)RESOURCE_SCROLL_LEFT_WHITE);
sh.DecFile((string)RESOURCE_SCROLL_RIGHT_WHITE);
sh.DecFileLocked((string)RESOURCE_SCROLL_RIGHT_WHITE);
sh.DecFilePressed((string)RESOURCE_SCROLL_RIGHT_WHITE);
//---
m_table_results.CellYSize(30);
m_table_results.FontSize(10);
m_table_results.HeaderYSize(25);
m_table_results.IsSortMode(true);
m_table_results.DefaultTextAlign(ALIGN_LEFT);
m_table_results.TableSize(TABWF_TABLERES_TOTAL_COLS, 1);
//---
m_table_results.DataType(TABWF_TABLERES_COL_NAME, TYPE_STRING);
m_table_results.SetValue(TABWF_TABLERES_COL_NAME, 0, "");
m_table_results.DataType(TABWF_TABLERES_COL_RES, TYPE_STRING);
m_table_results.SetValue(TABWF_TABLERES_COL_RES, 0, "");
m_table_results.DataType(TABWF_TABLERES_COL_STATE, TYPE_STRING);
m_table_results.SetValue(TABWF_TABLERES_COL_STATE, 0, "");
m_table_results.DataType(TABWF_TABLERES_COL_TIME, TYPE_STRING);
m_table_results.SetValue(TABWF_TABLERES_COL_TIME, 0, "");
//---
int widths[TABWF_TABLERES_TOTAL_COLS];
widths[TABWF_TABLERES_COL_NAME] = 332;
widths[TABWF_TABLERES_COL_RES] = 100;
widths[TABWF_TABLERES_COL_STATE] = 100;
widths[TABWF_TABLERES_COL_TIME] = 75;
m_table_results.ColumnsWidth(widths);
//---
int arr_offset_image_x[TABWF_TABLERES_TOTAL_COLS];
int arr_offset_image_y[TABWF_TABLERES_TOTAL_COLS];
ArrayFill(arr_offset_image_x, 0, TABWF_TABLERES_TOTAL_COLS, 0);
ArrayFill(arr_offset_image_y, 0, TABWF_TABLERES_TOTAL_COLS, 0);
arr_offset_image_y[TABWF_TABLERES_COL_STATE] = 5;
arr_offset_image_x[TABWF_TABLERES_COL_STATE] = 5;
m_table_results.ImageXOffset(arr_offset_image_x);
m_table_results.ImageYOffset(arr_offset_image_y);
//---
int text_x_offset[TABWF_TABLERES_TOTAL_COLS];
ArrayInitialize(text_x_offset, 10);
text_x_offset[TABWF_TABLERES_COL_STATE] += 15;
m_table_results.TextXOffset(text_x_offset);
//---
if(!p.CreateTable(m_table_results, main_window, 0, m_tabs, 1,
TABWF_TABLERES_TOTAL_COLS, 1, headers,
x, y, 0, 0, false, false, right_gap + 5, bottom_gap + 5))
{
GUIBASE_ERROR_CREATION(m_table_results);
return false;
}
//---
return true;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void CTabWorkflows::OnLenguajeChange(void)
{
//--- Tab
string txt[2] = {m_language[GUIBASE_COMPONENT_NAME(m_tabs) + "_0"], m_language[GUIBASE_COMPONENT_NAME(m_tabs) + "_1"]};
for(int i = 0; i < 2; i++)
{
m_tabs.Text(i, txt[i]);
}
m_tabs.Update();
//--- Tab 0
//- Titulo
UpdateTBasic(m_label_tit_workflows, GUIBASE_COMPONENT_NAME(m_label_tit_workflows), false);
//- Label selec
UpdateTBasic(m_label_selec_wf, GUIBASE_COMPONENT_NAME(m_label_selec_wf));
//- Label val
m_label_selec_val_wf.Tooltip(m_language.Tooltip(GUIBASE_COMPONENT_NAME(m_label_selec_val_wf)));
//-
UpdateTBasic(m_btn_browse_wf, GUIBASE_COMPONENT_NAME(m_btn_browse_wf));
UpdateTBasic(m_btn_template_wf, GUIBASE_COMPONENT_NAME(m_btn_template_wf));
UpdateTBasic(m_btn_open_wf, GUIBASE_COMPONENT_NAME(m_btn_open_wf));
//- Label wf name
UpdateTBasic(m_label_wf_name, GUIBASE_COMPONENT_NAME(m_label_wf_name), false);
m_label_the_wf_name.Tooltip(m_language.Tooltip(GUIBASE_COMPONENT_NAME(m_label_the_wf_name)));
if(m_state == WF_STATE_ESPERANDO_RUNNER)
{
m_label_the_wf_name.LabelText(m_language[GUIBASE_COMPONENT_NAME(m_label_the_wf_name) + "_esperar_runer"]);
m_label_the_wf_name.Update(true);
}
else
if(m_state == WF_STATE_ESPERANDO_NADA)
{
m_label_the_wf_name.LabelText(m_language[GUIBASE_COMPONENT_NAME(m_label_the_wf_name) + "_nada"]);
m_label_the_wf_name.Update(true);
}
//-
UpdateTBasic(m_btn_run_wf, GUIBASE_COMPONENT_NAME(m_btn_run_wf));
UpdateTBasic(m_btn_relanzar_ea, GUIBASE_COMPONENT_NAME(m_btn_relanzar_ea));
//--- Tabla
UpdateTBasic(m_label_tit_execution, GUIBASE_COMPONENT_NAME(m_label_tit_execution), false);
// Headers
string headers[];
const string header_str = m_language[GUIBASE_COMPONENT_NAME(m_table_results) + "_header"];
if(!StrTo::CstArray(headers, header_str, '|', true))
{
LogError(StringFormat("Fallo al hacer str to array str, str = %s", header_str), FUNCION_ACTUAL);
return;
}
ArrayResize(headers, TABWF_TABLERES_TOTAL_COLS);
for(int i = 0; i < TABWF_TABLERES_TOTAL_COLS; i++)
{
m_table_results.SetHeaderText(i, headers[i]);
}
// Names
if(StringSplit(m_language[GUIBASE_COMPONENT_NAME(m_arr_names_tables)], '|', m_arr_names_tables) != 4)
{
LogFatalError("No se pudo hacer split a los nombres de los estados", FUNCION_ACTUAL);
return;
}
const int t = (int)m_table_results.RowsTotal();
if(m_table_results.GetValue(0, 0) != "") // Hay contenido
{
for(int i = 0; i < t; i++)
{
m_table_results.SetValue(TABWF_TABLERES_COL_STATE, i, m_arr_names_tables[TABWF_IMAGE_EN_PENDIENTE]);
}
}
m_table_results.Update(true);
}
//+------------------------------------------------------------------+
//| Ejecucino del ea base |
//+------------------------------------------------------------------+
bool CTabWorkflows::RunEA()
{
//---
const long current_chart_id = ChartID();
m_last_runner_chart_id = OpenChartAndDevoler(current_chart_id, _Symbol, _Period, 250);
if(m_last_runner_chart_id == -1)
{
MessageBox(GUIBASE_MSG("err_open_chart"), GUIBASE_COMMON("error"), MB_OK);
return false;
}
//--- Parametros
MqlParam params[4];
params[0].type = TYPE_STRING;
params[0].string_value = "Experts\\" + m_path_ea;
//- Chart id
params[1].type = TYPE_LONG;
params[1].integer_value = current_chart_id;
//- Temp wf file
params[2].type = TYPE_STRING;
params[2].string_value = m_path_to_wf_temp;
//- Common flag
params[3].type = TYPE_BOOL;
params[3].integer_value = AIDATATASK_RUNNER_COMON_FLAG_VAL;
//---
if(!EXPERT::Run(m_last_runner_chart_id, params, EXPERT_PERMISOS_FLAG_DLL))
{
::ChartClose(m_last_runner_chart_id);
MessageBox(GUIBASE_MSG("err_run"), GUIBASE_COMMON("error"), MB_OK);
LogError("EA Params: ", FUNCION_ACTUAL);
ArrayPrint(params, 4, "|");
return false;
}
else
{
LogCaution("EA runnner wf ejeuctado correctamente", FUNCION_ACTUAL);
}
//--- Escribimos la info que enviaremos (inicial)
::ResetLastError();
const int fh = FileOpen(m_path_to_wf_temp, FILE_WRITE | AIDATATASK_RUNNER_COMON_FLAG | FILE_TXT);
if(fh == INVALID_HANDLE)
{
::ChartClose(m_last_runner_chart_id);
LogFatalError(StringFormat("No se pudo escribir los datos iniciales para el runner, fallo al abrir el archivo:\n%s", m_path_to_wf_temp), FUNCION_ACTUAL);
return false;
}
// Escribimos los datos iniciales
// Datos iniciales (nunca cambian)
FileWrite(fh, AIDATATASKRUNER_PATH_TEMPLATES); // Path templates
FileWrite(fh, AIDATATASKRUNER_PATH_TASK); // Path task
FileWrite(fh, AIDATATASKRUNER_BASE_FOLDER); // Base folder
FileClose(fh);
//--- Comando de iniciar
// Internamete el runner creara las varialbes basicas para el YML
if(!EventChartCustom(m_last_runner_chart_id, AIDATATASKRUNER_RUNNER_WF_EVENT_INIT, 0, 0.00, ""))
{
::ChartClose(m_last_runner_chart_id);
LogFatalError("No se pudo enviar el evento de inicio al runner", FUNCION_ACTUAL);
return false; // ya no se inicia el bot
}
//---
return true;
}
//+------------------------------------------------------------------+
//| Run WF |
//+------------------------------------------------------------------+
void CTabWorkflows::RunWF()
{
//--- Check yml file
const string label_wf_text = m_label_selec_val_wf.LabelText();
if(label_wf_text.Length() < 4) // .yml
{
MessageBox(GUIBASE_MSG("err_invalid_yml_file"), GUIBASE_COMMON("error"), MB_OK);
return;
}
//--- Mandamos el evento de inicio
::ResetLastError();
if(!::EventChartCustom(m_last_runner_chart_id, AIDATATASKRUNER_RUNNER_WF_EVENT_ON_NEW_WF,
0, 0.00, label_wf_text))
{
MessageBox(StringFormat(GUIBASE_MSG("err_cannot_init"), ::GetLastError()), GUIBASE_COMMON("error"), MB_OK);
return;
}
//--- Cambiamso el texto a uno que diga esperando como "Workflow: Esperando al runner ..."
m_state = WF_STATE_ESPERANDO_RUNNER;
m_label_the_wf_name.LabelText(m_language[GUIBASE_COMPONENT_NAME(m_label_the_wf_name) + "_esperar_runer"]);
m_label_the_wf_name.Update(true);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CTabWorkflows::OnClickButtom(const long lparam)
{
//---
if(m_tabs.SelectedTab() != 0)
return true; // Si es la otra salimos de inmediato no hace falta ni revisar
//---
if(m_btn_browse_wf.Id() == lparam)
{
//---
string arr[];
if(FileSelectDialog(GUIBASE_MSG("flselect_run_yml"), AIDATATASKRUNER_PATH_WORKFLOWS, "YML Files (*.yml)|*.yml|YAML Files (*.yaml)|*.yaml", AIDATATASK_RUNNER_FSD_COMON_FLAG,
arr, NULL) != 1)
{
MessageBox(GUIBASE_MSG("error_select_file"), GUIBASE_COMMON("error"), MB_ICONERROR | MB_OK);
return true;
}
//---
m_label_selec_val_wf.LabelText(arr[0]); // ruta completa aqui
m_label_selec_val_wf.Update(true);
//---
return true;
}
if(m_btn_template_wf.Id() == lparam)
{
//---
string arr[];
if(FileSelectDialog(GUIBASE_MSG("flselect_run_yml"), AIDATATASKRUNER_PATH_TEMPLATES, "YML Files (*.yml)|*.yml|YAML Files (*.yaml)|*.yaml", AIDATATASK_RUNNER_FSD_COMON_FLAG,
arr, AIDATATASKRUNER_FILE_NAME_WORKFLOWS_BASICGENERATION) != 1)
{
MessageBox(GUIBASE_MSG("error_select_file"), GUIBASE_COMMON("error"), MB_ICONERROR | MB_OK);
return true;
}
//---
m_label_selec_val_wf.LabelText(arr[0]); // ruta completa aqui
m_label_selec_val_wf.Update(true);
//---
return true;
}
if(m_btn_open_wf.Id() == lparam)
{
const string full_path = (AIDATATASK_RUNNER_COMON_FLAG_VAL ? TERMINAL_MT5_COMMON_PATH : (TERMINAL_MT5_DATA_PAH + "\\MQL5")) + "\\Files\\" + m_label_selec_val_wf.LabelText();
ShellExecuteW(0, "open", full_path, NULL, NULL, SW_SHOW); // no verificamos noe s critrico
return true;
}
//---
if(m_btn_run_wf.Id() == lparam)
{
RunWF();
return true;
}
if(m_btn_relanzar_ea.Id() == lparam)
{
// Si el grafico existe (osea ya se lanzo se quiere un relanze entonces quitamos)
if(::ChartSymbol(m_last_runner_chart_id) != "")
{
::ChartClose(m_last_runner_chart_id);
m_last_runner_chart_id = -1;
}
// Lanzamos
RunEA();
return true; // Volvemos a correr el EA
}
//---
return false;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void CTabWorkflows::OnWfStart(void)
{
//---
::ResetLastError();
const int fh = FileOpen(m_path_to_wf_temp, FILE_READ | FILE_TXT | AIDATATASK_RUNNER_COMON_FLAG);
if(fh == INVALID_HANDLE)
{
LogFatalError(StringFormat("Fallo al abrir el archivo = %s, ultimo err = %d, cancelando wf", m_path_to_wf_temp, ::GetLastError()), FUNCION_ACTUAL);
//--- Cerramos el grafico (se sale el ea) y le decimso al usario el error y que lo relanze
::ChartClose(m_last_runner_chart_id);
MessageBox(GUIBASE_MSG("err_read_data"), GUIBASE_MSG("error"), MB_OK | MB_ICONERROR);
return;
}
//--- Nombre del wf
m_label_the_wf_name.LabelText(FileReadString(fh));
m_label_the_wf_name.Update(true);
//--- Tabla
const int t_wf = int(FileReadString(fh));
m_table_results.ResizeRows(t_wf, false);
for(int i = 0; i < t_wf; i++)
{
//---
m_table_results.SetValue(TABWF_TABLERES_COL_NAME, i, FileReadString(fh), 0);
m_table_results.SetValue(TABWF_TABLERES_COL_RES, i);
m_table_results.SetValue(TABWF_TABLERES_COL_TIME, i, "?s");
//--- State cambiamos valor e imagen
m_table_results.SetValue(TABWF_TABLERES_COL_STATE, i, m_arr_names_tables[TABWF_IMAGE_EN_PENDIENTE]);
m_table_results.SetImages(TABWF_TABLERES_COL_STATE, i, g_aitaskruner_wf_img);
m_table_results.ChangeImage(TABWF_TABLERES_COL_STATE, i, TABWF_IMAGE_EN_PENDIENTE);
}
if(t_wf) // Al menos 1
{
// 0 en ejeucion
m_table_results.ChangeImage(TABWF_TABLERES_COL_STATE, 0, TABWF_IMAGE_EN_EJECUCION);
m_table_results.SetValue(TABWF_TABLERES_COL_STATE, 0, m_arr_names_tables[TABWF_IMAGE_EN_EJECUCION]);
//---
m_table_results.Update(true);
}
//---
FileClose(fh);
m_state = WF_STATE_ESPERANDO_EJECUTANDO;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void CTabWorkflows::OnWfStep(const string &sparam)
{
//---
// stepindex | code
static string arr[3];
const int t = StringSplit(sparam, AIDATATASKRUNER_RUNNER_WF_SEP, arr);
if(t != 3)
{
LogFatalError("Formato incorrecto de sparam", FUNCION_ACTUAL);
return;
}
//---
const int r = int(arr[0]);
//--- Current row pasedd
m_table_results.SetValue(TABWF_TABLERES_COL_RES, r, (arr[1]));
m_table_results.SetValue(TABWF_TABLERES_COL_STATE, r, m_arr_names_tables[TABWF_IMAGE_EN_EXTIO]);
m_table_results.ChangeImage(TABWF_TABLERES_COL_STATE, r, TABWF_IMAGE_EN_EXTIO);
m_table_results.SetValue(TABWF_TABLERES_COL_TIME, r, arr[2]);
//--- Siguiente row la ponemos en ejeuccion
m_table_results.ChangeImage(TABWF_TABLERES_COL_STATE, r + 1, TABWF_IMAGE_EN_EJECUCION);
m_table_results.SetValue(TABWF_TABLERES_COL_STATE, r + 1, m_arr_names_tables[TABWF_IMAGE_EN_EJECUCION]);
//--- Update
m_table_results.Update(true);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void CTabWorkflows::OnWfEnd(const string &sparam)
{
//---
LogCaution(StringFormat("Wf ha terminado, sparam:\n%s", sparam), FUNCION_ACTUAL);
m_state = WF_STATE_ESPERANDO_NADA;
//---
// stepindex | code
static string arr[3];
const int t = StringSplit(sparam, AIDATATASKRUNER_RUNNER_WF_SEP, arr);
if(t != 3)
{
LogFatalError("Formato incorrecto de sparam", FUNCION_ACTUAL);
return;
}
//---
const int r = int(arr[0]);
const int code = int(arr[1]);
//--- Current row pasedd
m_table_results.SetValue(TABWF_TABLERES_COL_RES, r, arr[1]);
const int idx = code == 0 ? TABWF_IMAGE_EN_EXTIO : TABWF_IMAGE_EN_FALLO;
m_table_results.SetValue(TABWF_TABLERES_COL_STATE, r, m_arr_names_tables[idx]);
m_table_results.ChangeImage(TABWF_TABLERES_COL_STATE, r, idx);
m_table_results.SetValue(TABWF_TABLERES_COL_TIME, r, arr[2]);
//--- Update table
m_table_results.Update(true);
//--- Label
m_label_the_wf_name.LabelText(m_language[GUIBASE_COMPONENT_NAME(m_label_the_wf_name) + "_nada"]);
m_label_the_wf_name.Update(true);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void CTabWorkflows::ChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam)
{
//---
if(m_state == WF_STATE_ESPERANDO_NADA) // En caso se este esperando nada salimos
return;
//---
if(id == CHARTEVENT_CUSTOM + AIDATATASKRUNER_RUNNER_WF_ON_EVENT)
{
const uint8_t ei = uint8_t(lparam);
switch(ei)
{
case AIDATATASKRUNER_RUNNER_WF_E_ON_STEP:
{
OnWfStep(sparam);
break;
}
case AIDATATASKRUNER_RUNNER_WF_E_ON_END:
{
OnWfEnd(sparam);
break;
}
case AIDATATASKRUNER_RUNNER_WF_E_ON_START:
{
OnWfStart();
break;
}
case AIDATATASKRUNER_RUNNER_WF_E_ON_END_CRITICAL:
{
//--- ERn caso de que ni siquiera se haya ejetudado start
LogError("No se pudo ejeuctar el wf, error critico en su ejecucion", FUNCION_ACTUAL);
LogError(StringFormat("val:\n%s", sparam), FUNCION_ACTUAL);
m_state = WF_STATE_ESPERANDO_NADA;
//::ChartClose(m_last_runner_chart_id); no cerramos solo hubo un error se puede reejecutar
m_label_the_wf_name.LabelText(m_language[GUIBASE_COMPONENT_NAME(m_label_the_wf_name) + "_nada"]);
m_label_the_wf_name.Update(true);
break;
}
}
}
}
//+------------------------------------------------------------------+
#endif // AIDATATASKRUNER_UI_TABWORKFLOWS_MAIN_MQH