314 lines
23 KiB
MQL5
314 lines
23 KiB
MQL5
//+------------------------------------------------------------------+
|
|
//| LogifyHandlerComment.mqh |
|
|
//| Copyright 2023, MetaQuotes Ltd. |
|
|
//| https://www.mql5.com |
|
|
//+------------------------------------------------------------------+
|
|
#property copyright "joaopedrodev"
|
|
#property link "https://www.mql5.com/en/users/joaopedrodev"
|
|
//+------------------------------------------------------------------+
|
|
//| Include files |
|
|
//+------------------------------------------------------------------+
|
|
#include "LogifyHandler.mqh"
|
|
//+------------------------------------------------------------------+
|
|
//| ENUMS |
|
|
//+------------------------------------------------------------------+
|
|
enum ENUM_LOG_FRAME_STYLE
|
|
{
|
|
LOG_FRAME_STYLE_NONE = 0, // No rotation
|
|
LOG_FRAME_STYLE_SINGLE, // Rotate based on date
|
|
LOG_FRAME_STYLE_DOUBLE, // Rotate based on file size
|
|
};
|
|
enum ENUM_LOG_DIRECTION
|
|
{
|
|
LOG_DIRECTION_UP = 0, // Up
|
|
LOG_DIRECTION_DOWN, // Down
|
|
};
|
|
//+------------------------------------------------------------------+
|
|
//| Struct: MqlLogifyHandleComment |
|
|
//+------------------------------------------------------------------+
|
|
struct MqlLogifyHandleCommentConfig
|
|
{
|
|
int size; // Space in lines that it will occupy
|
|
ENUM_LOG_FRAME_STYLE frame_style; // Display grid
|
|
ENUM_LOG_DIRECTION direction; // Direction
|
|
string title; // log title
|
|
|
|
//--- Default constructor
|
|
MqlLogifyHandleCommentConfig(void)
|
|
{
|
|
size = 20;
|
|
frame_style = LOG_FRAME_STYLE_SINGLE;
|
|
direction = LOG_DIRECTION_UP;
|
|
title = "LOGIFY";
|
|
}
|
|
|
|
//--- Destructor
|
|
~MqlLogifyHandleCommentConfig(void)
|
|
{
|
|
}
|
|
|
|
//--- Validate configuration
|
|
bool ValidateConfig(string &error_message)
|
|
{
|
|
//--- Saves the return value
|
|
bool is_valid = true;
|
|
|
|
//--- Check if size is greater than 0
|
|
if(size <= 0)
|
|
{
|
|
size = 20;
|
|
error_message = "Size must be greater than 0.";
|
|
is_valid = false;
|
|
}
|
|
|
|
//--- Check len
|
|
if(StringLen(title) > 40)
|
|
{
|
|
error_message = "Title is too long for frame. Max 40 chars.";
|
|
is_valid = false;
|
|
}
|
|
|
|
//--- No errors found
|
|
return(is_valid);
|
|
}
|
|
};
|
|
//+------------------------------------------------------------------+
|
|
//| class : CLogifyHandlerComment |
|
|
//| |
|
|
//| [PROPERTY] |
|
|
//| Name : CLogifyHandlerComment |
|
|
//| Heritage : CLogifyHandler |
|
|
//| Description : Log handler, inserts data into chart comment. |
|
|
//| |
|
|
//+------------------------------------------------------------------+
|
|
class CLogifyHandlerComment : public CLogifyHandler
|
|
{
|
|
private:
|
|
MqlLogifyHandleCommentConfig m_config;
|
|
MqlLogifyModel m_cache[];
|
|
|
|
//--- Aux
|
|
string GetBorderTop();
|
|
string GetBorderMiddle();
|
|
string GetBorderBottom();
|
|
string GetSideBorder();
|
|
string BuildHeader();
|
|
string BuildFooter();
|
|
string FormatLogLines();
|
|
|
|
public:
|
|
CLogifyHandlerComment(void);
|
|
~CLogifyHandlerComment(void);
|
|
|
|
//--- Configuration management
|
|
void SetConfig(MqlLogifyHandleCommentConfig &config);
|
|
MqlLogifyHandleCommentConfig GetConfig(void);
|
|
|
|
virtual void Emit(MqlLogifyModel &data); // Processes a log message and sends it to the specified destination
|
|
virtual void Flush(void); // Clears or completes any pending operations
|
|
virtual void Close(void); // Closes the handler and releases any resources
|
|
};
|
|
//+------------------------------------------------------------------+
|
|
//| Constructor |
|
|
//+------------------------------------------------------------------+
|
|
CLogifyHandlerComment::CLogifyHandlerComment(void)
|
|
{
|
|
m_name = "comment";
|
|
ArrayResize(m_cache, m_config.size);
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Destructor |
|
|
//+------------------------------------------------------------------+
|
|
CLogifyHandlerComment::~CLogifyHandlerComment(void)
|
|
{
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Set configuration |
|
|
//+------------------------------------------------------------------+
|
|
void CLogifyHandlerComment::SetConfig(MqlLogifyHandleCommentConfig &config)
|
|
{
|
|
m_config = config;
|
|
|
|
//--- Validade config
|
|
string err_msg = "";
|
|
if(!m_config.ValidateConfig(err_msg))
|
|
{
|
|
Print("[ERROR] ["+TimeToString(TimeCurrent())+"] Log system error: "+err_msg);
|
|
}
|
|
|
|
//--- Resize
|
|
ArrayResize(m_cache, m_config.size);
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Get configuration |
|
|
//+------------------------------------------------------------------+
|
|
MqlLogifyHandleCommentConfig CLogifyHandlerComment::GetConfig(void)
|
|
{
|
|
return(m_config);
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Processes a log message and sends it to the specified destination|
|
|
//+------------------------------------------------------------------+
|
|
void CLogifyHandlerComment::Emit(MqlLogifyModel &data)
|
|
{
|
|
//--- Check if log level is allowed
|
|
if(data.level < this.GetLevel())
|
|
{
|
|
return;
|
|
}
|
|
|
|
//--- Shift logs to maintain history
|
|
for(int i = m_config.size-1; i > 0; i--)
|
|
{
|
|
m_cache[i] = m_cache[i-1];
|
|
}
|
|
m_cache[0] = data;
|
|
|
|
//--- Build the complete comment
|
|
string comment = BuildHeader();
|
|
comment += FormatLogLines();
|
|
comment += BuildFooter();
|
|
|
|
//--- Display on chart
|
|
Comment(comment);
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Clears or completes any pending operations |
|
|
//+------------------------------------------------------------------+
|
|
void CLogifyHandlerComment::Flush(void)
|
|
{
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Closes the handler and releases any resources |
|
|
//+------------------------------------------------------------------+
|
|
void CLogifyHandlerComment::Close(void)
|
|
{
|
|
//--- Clear
|
|
Comment("");
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Returns the side border character based on frame style |
|
|
//+------------------------------------------------------------------+
|
|
string CLogifyHandlerComment::GetSideBorder()
|
|
{
|
|
if(m_config.frame_style == LOG_FRAME_STYLE_SINGLE) return "│";
|
|
if(m_config.frame_style == LOG_FRAME_STYLE_DOUBLE) return "║";
|
|
return "";
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Returns the top border based on frame style |
|
|
//+------------------------------------------------------------------+
|
|
string CLogifyHandlerComment::GetBorderTop()
|
|
{
|
|
if(m_config.frame_style == LOG_FRAME_STYLE_SINGLE)
|
|
return "┌───────────────────────────────────────────┐\n";
|
|
if(m_config.frame_style == LOG_FRAME_STYLE_DOUBLE)
|
|
return "╔═══════════════════════════════════════════╗\n";
|
|
return "";
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Returns the middle separator based on frame style |
|
|
//+------------------------------------------------------------------+
|
|
string CLogifyHandlerComment::GetBorderMiddle()
|
|
{
|
|
if(m_config.frame_style == LOG_FRAME_STYLE_SINGLE)
|
|
return "├───────────────────────────────────────────┤\n";
|
|
if(m_config.frame_style == LOG_FRAME_STYLE_DOUBLE)
|
|
return "╠═══════════════════════════════════════════╣\n";
|
|
return "";
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Returns the bottom border based on frame style |
|
|
//+------------------------------------------------------------------+
|
|
string CLogifyHandlerComment::GetBorderBottom()
|
|
{
|
|
if(m_config.frame_style == LOG_FRAME_STYLE_SINGLE)
|
|
return "└───────────────────────────────────────────┘\n";
|
|
if(m_config.frame_style == LOG_FRAME_STYLE_DOUBLE)
|
|
return "╚═══════════════════════════════════════════╝\n";
|
|
return "";
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Builds the comment header with optional title and frame |
|
|
//+------------------------------------------------------------------+
|
|
string CLogifyHandlerComment::BuildHeader()
|
|
{
|
|
string header = "";
|
|
|
|
if(m_config.title != "" && m_config.title != NULL)
|
|
{
|
|
if(m_config.frame_style == LOG_FRAME_STYLE_NONE)
|
|
{
|
|
header += " " + m_config.title + "\n";
|
|
header += "─────────────────────────────────────────────\n";
|
|
}
|
|
else
|
|
{
|
|
header += GetBorderTop();
|
|
header += GetSideBorder() + " " + m_config.title + "\n";
|
|
header += GetBorderMiddle();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if(m_config.frame_style != LOG_FRAME_STYLE_NONE)
|
|
{
|
|
header += GetBorderTop();
|
|
}
|
|
}
|
|
|
|
return header;
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Builds the comment footer based on frame style |
|
|
//+------------------------------------------------------------------+
|
|
string CLogifyHandlerComment::BuildFooter()
|
|
{
|
|
if(m_config.frame_style != LOG_FRAME_STYLE_NONE)
|
|
return GetBorderBottom();
|
|
return "";
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Formats all log lines according to direction and frame |
|
|
//+------------------------------------------------------------------+
|
|
string CLogifyHandlerComment::FormatLogLines()
|
|
{
|
|
string result = "";
|
|
string side = GetSideBorder();
|
|
|
|
if(m_config.direction == LOG_DIRECTION_UP)
|
|
{
|
|
for(int i = m_config.size-1; i >= 0; i--)
|
|
{
|
|
string line = m_cache[i].formated;
|
|
StringReplace(line,"\n","\n"+side+" ");
|
|
if(line != "")
|
|
{
|
|
result += side + " " + line + "\n";
|
|
}
|
|
else
|
|
{
|
|
result += side + "\n";
|
|
}
|
|
}
|
|
}
|
|
else // LOG_DIRECTION_DOWN
|
|
{
|
|
for(int i = 0; i <= m_config.size-1; i++)
|
|
{
|
|
string line = m_cache[i].formated;
|
|
StringReplace(line,"\n","\n"+side+" ");
|
|
if(line != "")
|
|
{
|
|
result += side + " " + line + "\n";
|
|
}
|
|
else
|
|
{
|
|
result += side + "\n";
|
|
}
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
//+------------------------------------------------------------------+
|