@@ -30,13 +30,14 @@ template<typename Mutex>
3030class qt_sink : public base_sink <Mutex>
3131{
3232public:
33- qt_sink (QObject *qt_object, std::string meta_method): qt_object_(qt_object), meta_method_(std::move(meta_method))
33+ qt_sink (QObject *qt_object, std::string meta_method)
34+ : qt_object_(qt_object)
35+ , meta_method_(std::move(meta_method))
3436 {
3537 if (!qt_object_)
3638 {
3739 throw_spdlog_ex (" qt_sink: qt_object is null" );
3840 }
39-
4041 }
4142
4243 ~qt_sink ()
@@ -66,165 +67,161 @@ class qt_sink : public base_sink<Mutex>
6667// Colors can be modified if needed using sink->set_color(level, qtTextCharFormat).
6768// max_lines is the maximum number of lines that the sink will hold before removing the oldest lines.
6869// Note: Only ascii (latin1) is supported by this sink.
69- template <typename Mutex>
70- class qt_color_sink : public base_sink <Mutex>
70+ template <typename Mutex>
71+ class qt_color_sink : public base_sink <Mutex>
72+ {
73+ public:
74+ qt_color_sink (QTextEdit *qt_text_edit, int max_lines)
75+ : qt_text_edit_(qt_text_edit)
76+ , max_lines_(max_lines)
7177 {
72- public:
73- qt_color_sink (QTextEdit *qt_text_edit, int max_lines)
74- : qt_text_edit_(qt_text_edit), max_lines_(max_lines)
78+ if (!qt_text_edit_)
7579 {
76- if (!qt_text_edit_)
77- {
78- throw_spdlog_ex (" qt_color_text_sink: text_edit is null" );
79- }
80-
81- default_color_ = qt_text_edit_->currentCharFormat ();
82- // set colors
83- QTextCharFormat format;
84- // trace
85- format.setForeground (Qt::gray);
86- colors_.at (level::trace) = format;
87- // debug
88- format.setForeground (Qt::cyan);
89- colors_.at (level::debug) = format;
90- // info
91- format.setForeground (Qt::green);
92- colors_.at (level::info) = format;
93- // warn
94- format.setForeground (Qt::yellow);
95- colors_.at (level::warn) = format;
96- // err
97- format.setForeground (Qt::red);
98- colors_.at (level::err) = format;
99- // critical
100- format.setForeground (Qt::white);
101- format.setBackground (Qt::red);
102- colors_.at (level::critical) = format;
80+ throw_spdlog_ex (" qt_color_text_sink: text_edit is null" );
10381 }
10482
105- ~qt_color_sink ()
106- {
107- flush_ ();
108- }
83+ default_color_ = qt_text_edit_->currentCharFormat ();
84+ // set colors
85+ QTextCharFormat format;
86+ // trace
87+ format.setForeground (Qt::gray);
88+ colors_.at (level::trace) = format;
89+ // debug
90+ format.setForeground (Qt::cyan);
91+ colors_.at (level::debug) = format;
92+ // info
93+ format.setForeground (Qt::green);
94+ colors_.at (level::info) = format;
95+ // warn
96+ format.setForeground (Qt::yellow);
97+ colors_.at (level::warn) = format;
98+ // err
99+ format.setForeground (Qt::red);
100+ colors_.at (level::err) = format;
101+ // critical
102+ format.setForeground (Qt::white);
103+ format.setBackground (Qt::red);
104+ colors_.at (level::critical) = format;
105+ }
109106
110- void set_default_color (QTextCharFormat format)
111- {
112- // std::lock_guard<Mutex> lock(base_sink<Mutex>::mutex_);
113- default_color_ = format;
114- }
107+ ~qt_color_sink ()
108+ {
109+ flush_ ();
110+ }
115111
116- void set_level_color (level::level_enum color_level, QTextCharFormat format)
117- {
118- // std::lock_guard<Mutex> lock(base_sink<Mutex>::mutex_);
119- colors_. at ( static_cast < size_t >(color_level)) = format;
120- }
112+ void set_default_color ( QTextCharFormat format)
113+ {
114+ // std::lock_guard<Mutex> lock(base_sink<Mutex>::mutex_);
115+ default_color_ = format;
116+ }
121117
122- QTextCharFormat &get_level_color (level::level_enum color_level)
123- {
124- std::lock_guard<Mutex> lock (base_sink<Mutex>::mutex_);
125- return colors_.at (static_cast <size_t >(color_level));
126- }
118+ void set_level_color (level::level_enum color_level, QTextCharFormat format)
119+ {
120+ // std::lock_guard<Mutex> lock(base_sink<Mutex>::mutex_);
121+ colors_.at (static_cast <size_t >(color_level)) = format;
122+ }
123+
124+ QTextCharFormat &get_level_color (level::level_enum color_level)
125+ {
126+ std::lock_guard<Mutex> lock (base_sink<Mutex>::mutex_);
127+ return colors_.at (static_cast <size_t >(color_level));
128+ }
129+
130+ QTextCharFormat &get_default_color ()
131+ {
132+ std::lock_guard<Mutex> lock (base_sink<Mutex>::mutex_);
133+ return default_color_;
134+ }
127135
128- QTextCharFormat &get_default_color ()
136+ protected:
137+ struct invoke_params
138+ {
139+ invoke_params (int max_lines, QTextEdit *q_text_edit, QString payload, QTextCharFormat default_color, QTextCharFormat level_color,
140+ int color_range_start, int color_range_end)
141+ : max_lines(max_lines)
142+ , q_text_edit(q_text_edit)
143+ , payload(std::move(payload))
144+ , default_color(default_color)
145+ , level_color(level_color)
146+ , color_range_start(color_range_start)
147+ , color_range_end(color_range_end)
148+ {}
149+ int max_lines;
150+ QTextEdit *q_text_edit;
151+ QString payload;
152+ QTextCharFormat default_color;
153+ QTextCharFormat level_color;
154+ int color_range_start;
155+ int color_range_end;
156+ };
157+
158+ void sink_it_ (const details::log_msg &msg) override
159+ {
160+ memory_buf_t formatted;
161+ base_sink<Mutex>::formatter_->format (msg, formatted);
162+
163+ const string_view_t str = string_view_t (formatted.data (), formatted.size ());
164+ // apply the color to the color range in the formatted message.
165+ auto payload = QString::fromLatin1 (str.data (), static_cast <int >(str.size ()));
166+
167+ invoke_params params{max_lines_, // max lines
168+ qt_text_edit_, // text edit to append to
169+ std::move (payload), // text to append
170+ default_color_, // default color
171+ colors_.at (msg.level ), // color to apply
172+ static_cast <int >(msg.color_range_start ), // color range start
173+ static_cast <int >(msg.color_range_end )}; // color range end
174+
175+ QMetaObject::invokeMethod (
176+ qt_text_edit_, [params]() { invoke_method_ (params); }, Qt::AutoConnection);
177+ }
178+
179+ void flush_ () override {}
180+
181+ // Add colored text to the text edit widget. This method is invoked in the GUI thread.
182+ // It is a static method to ensure that it is handled correctly even if the sink is destroyed prematurely
183+ // before it is invoked.
184+
185+ static void invoke_method_ (invoke_params params)
186+ {
187+ auto *document = params.q_text_edit ->document ();
188+ QTextCursor cursor (document);
189+
190+ // remove first blocks if number of blocks exceeds max_lines
191+ while (document->blockCount () > params.max_lines )
129192 {
130- std::lock_guard<Mutex> lock (base_sink<Mutex>::mutex_);
131- return default_color_;
193+ cursor.select (QTextCursor::BlockUnderCursor);
194+ cursor.removeSelectedText ();
195+ cursor.deleteChar (); // delete the newline after the block
132196 }
133197
134- protected:
135- struct invoke_params
136- {
137- invoke_params (int max_lines, QTextEdit *q_text_edit, QString payload, QTextCharFormat default_color,
138- QTextCharFormat level_color, int color_range_start, int color_range_end)
139- : max_lines(max_lines),
140- q_text_edit (q_text_edit),
141- payload(std::move(payload)),
142- default_color(default_color),
143- level_color(level_color),
144- color_range_start(color_range_start),
145- color_range_end(color_range_end)
146- {
147- }
148- int max_lines;
149- QTextEdit *q_text_edit;
150- QString payload;
151- QTextCharFormat default_color;
152- QTextCharFormat level_color;
153- int color_range_start;
154- int color_range_end;
155- };
156-
157- void sink_it_ (const details::log_msg &msg) override
158- {
159- memory_buf_t formatted;
160- base_sink<Mutex>::formatter_->format (msg, formatted);
161-
162- const string_view_t str = string_view_t (formatted.data (), formatted.size ());
163- // apply the color to the color range in the formatted message.
164- auto payload = QString::fromLatin1 (str.data (), static_cast <int >(str.size ()));
165-
166- invoke_params params {
167- max_lines_, // max lines
168- qt_text_edit_, // text edit to append to
169- std::move (payload), // text to append
170- default_color_, // default color
171- colors_.at (msg.level ), // color to apply
172- static_cast <int >(msg.color_range_start ), // color range start
173- static_cast <int >(msg.color_range_end )}; // color range end
174-
175- QMetaObject::invokeMethod (
176- qt_text_edit_,
177- [params]() {invoke_method_ (params);},
178- Qt::AutoConnection);
198+ cursor.movePosition (QTextCursor::End);
199+ cursor.setCharFormat (params.default_color );
179200
201+ // if color range not specified or not not valid, just append the text with default color
202+ if (params.color_range_end <= params.color_range_start )
203+ {
204+ cursor.insertText (params.payload );
205+ return ;
180206 }
181207
182- void flush_ () override {}
208+ // insert the text before the color range
209+ cursor.insertText (params.payload .left (params.color_range_start ));
183210
184- // Add colored text to the text edit widget. This method is invoked in the GUI thread.
185- // It is a static method to ensure that it is handled correctly even if the sink is destroyed prematurely
186- // before it is invoked.
211+ // insert the colorized text
212+ cursor. setCharFormat (params. level_color );
213+ cursor. insertText (params. payload . mid (params. color_range_start , params. color_range_end - params. color_range_start ));
187214
188- static void invoke_method_ (invoke_params params)
189- {
190- auto *document = params.q_text_edit ->document ();
191- QTextCursor cursor (document);
192-
193- // remove first blocks if number of blocks exceeds max_lines
194- while (document->blockCount () > params.max_lines )
195- {
196- cursor.select (QTextCursor::BlockUnderCursor);
197- cursor.removeSelectedText ();
198- cursor.deleteChar (); // delete the newline after the block
199- }
200-
201- cursor.movePosition (QTextCursor::End);
202- cursor.setCharFormat (params.default_color );
203-
204- // if color range not specified or not not valid, just append the text with default color
205- if (params.color_range_end <= params.color_range_start )
206- {
207- cursor.insertText (params.payload );
208- return ;
209- }
210-
211- // insert the text before the color range
212- cursor.insertText (params.payload .left (params.color_range_start ));
213-
214- // insert the colorized text
215- cursor.setCharFormat (params.level_color );
216- cursor.insertText (params.payload .mid (params.color_range_start , params.color_range_end - params.color_range_start ));
217-
218- // insert the text after the color range with default format
219- cursor.setCharFormat (params.default_color );
220- cursor.insertText (params.payload .mid (params.color_range_end ));
221- }
215+ // insert the text after the color range with default format
216+ cursor.setCharFormat (params.default_color );
217+ cursor.insertText (params.payload .mid (params.color_range_end ));
218+ }
222219
223- QTextEdit *qt_text_edit_;
224- int max_lines_;
225- QTextCharFormat default_color_;
226- std::array<QTextCharFormat, level::n_levels> colors_;
227- };
220+ QTextEdit *qt_text_edit_;
221+ int max_lines_;
222+ QTextCharFormat default_color_;
223+ std::array<QTextCharFormat, level::n_levels> colors_;
224+ };
228225
229226#include " spdlog/details/null_mutex.h"
230227#include < mutex>
@@ -283,13 +280,13 @@ inline std::shared_ptr<logger> qt_logger_st(const std::string &logger_name, QObj
283280template <typename Factory = spdlog::synchronous_factory>
284281inline std::shared_ptr<logger> qt_color_logger_mt (const std::string &logger_name, QTextEdit *qt_text_edit, int max_lines)
285282{
286- return Factory::template create<sinks::qt_color_sink_mt >(logger_name, qt_text_edit, max_lines);
283+ return Factory::template create<sinks::qt_color_sink_mt>(logger_name, qt_text_edit, max_lines);
287284}
288285
289286template <typename Factory = spdlog::synchronous_factory>
290287inline std::shared_ptr<logger> qt_color_logger_st (const std::string &logger_name, QTextEdit *qt_text_edit, int max_lines)
291288{
292- return Factory::template create<sinks::qt_color_sink_st >(logger_name, qt_text_edit, max_lines);
289+ return Factory::template create<sinks::qt_color_sink_st>(logger_name, qt_text_edit, max_lines);
293290}
294291
295292} // namespace spdlog
0 commit comments