diff --git a/include/spdlog/sinks/qt_sinks.h b/include/spdlog/sinks/qt_sinks.h index 435e7d35..6e6f156b 100644 --- a/include/spdlog/sinks/qt_sinks.h +++ b/include/spdlog/sinks/qt_sinks.h @@ -18,9 +18,12 @@ #include "spdlog/details/synchronous_factory.h" #include "spdlog/sinks/base_sink.h" +#include + #include #include #include +#include // // qt_sink class @@ -39,7 +42,8 @@ public: qt_object_ = qt_object; auto *metaobject = qt_object_->metaObject(); auto methodIndex = metaobject->indexOfMethod(meta_method_name.c_str()); - if (methodIndex == -1) { + if (methodIndex == -1) + { throw_spdlog_ex("qt_sink: qt_object does not have meta_method " + meta_method_name); } meta_method_ = metaobject->method(methodIndex); @@ -67,15 +71,106 @@ private: QMetaMethod meta_method_; }; + +// color sink to QTextEdit. Color location is determined by the sink log pattern +// Note: Only ascii (latin1) is supported by this sink. +template +class qt_color_sink : public base_sink +{ +public: + qt_color_sink(QTextEdit *qt_text_edit) : qt_text_edit_(qt_text_edit) + { + if(!qt_text_edit_) + { + throw_spdlog_ex("qt_color_text_sink: text_edit is null"); + } + // set default colors + QTextCharFormat format; + // trace + format.setForeground(Qt::gray); + colors_.at(level::trace) = format; + // debug + format.setForeground(Qt::cyan); + colors_.at(level::debug) = format; + // info + format.setForeground(Qt::green); + colors_.at(level::info) = format; + // warn + format.setForeground(Qt::yellow); + colors_.at(level::warn) = format; + // err + format.setForeground(Qt::red); + colors_.at(level::err) = format; + // critical + format.setForeground(Qt::white); + format.setBackground(Qt::red); + colors_.at(level::critical) = format; + } + + ~qt_color_sink() + { + flush_(); + } + + void set_level_format(level::level_enum color_level, QTextCharFormat format) + { + colors_.at(static_cast(color_level)) = format; + } + + QTextCharFormat& get_level_format(level::level_enum color_level) + { + return colors_.at(static_cast(color_level)); + } +protected: + void sink_it_(const details::log_msg &msg) override + { + memory_buf_t formatted; + base_sink::formatter_->format(msg, formatted); + string_view_t str = string_view_t(formatted.data(), formatted.size()); + + // apply the color to the color range in the formatted message. + auto payload = QString::fromLatin1(str.data(), static_cast(str.size())); + if(msg.color_range_end > msg.color_range_start) + { + QTextCursor cursor(qt_text_edit_->document()); + cursor.movePosition(QTextCursor::End); + + // insert the text before the color range + cursor.insertText(payload.left(msg.color_range_start)); + + // insert the colorized text + auto format = get_level_format(msg.level); + cursor.setCharFormat(format); + cursor.insertText(payload.mid(msg.color_range_start, msg.color_range_end - msg.color_range_start)); + + // insert the text after the color range with default format + cursor.setCharFormat(QTextCharFormat()); + cursor.insertText(payload.mid(msg.color_range_end)); + } + else // no color range + { + qt_text_edit_->append(payload.trimmed()); + } + } + + void flush_() override {} + QTextEdit *qt_text_edit_; + std::array colors_; + }; + #include "spdlog/details/null_mutex.h" #include using qt_sink_mt = qt_sink; using qt_sink_st = qt_sink; +using qt_color_sink_mt = qt_color_sink; +using qt_color_sink_st = qt_color_sink; } // namespace sinks // // Factory functions // + +// create logger using QTextEdit object template inline std::shared_ptr qt_logger_mt(const std::string &logger_name, QTextEdit *qt_object, const std::string &meta_method = "append(QString)") { @@ -88,6 +183,7 @@ inline std::shared_ptr qt_logger_st(const std::string &logger_name, QTex return Factory::template create(logger_name, qt_object, meta_method); } +// create logger using QPlainTextEdit object template inline std::shared_ptr qt_logger_mt( const std::string &logger_name, QPlainTextEdit *qt_object, const std::string &meta_method = "appendPlainText(QString)") @@ -102,6 +198,20 @@ inline std::shared_ptr qt_logger_st( return Factory::template create(logger_name, qt_object, meta_method); } +// create color qt logger using QTextEdit object +template +inline std::shared_ptr qt_color_logger_mt(const std::string &logger_name, QTextEdit *qt_object) +{ + return Factory::template create(logger_name, qt_object); +} + +template +inline std::shared_ptr qt_color_logger_st(const std::string &logger_name, QTextEdit *qt_object) +{ + return Factory::template create(logger_name, qt_object); +} + +// create logger with other QObject object template inline std::shared_ptr qt_logger_mt(const std::string &logger_name, QObject *qt_object, const std::string &meta_method) {