918 lines
33 KiB
MQL5
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
|