Program Listing for File log_database_proxy_model.h
↰ Return to documentation for file (include/swri_console/log_database_proxy_model.h)
// *****************************************************************************
//
// Copyright (c) 2026, Southwest Research Institute® (SwRI®)
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// * Neither the name of Southwest Research Institute® (SwRI®) nor the
// names of its contributors may be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL Southwest Research Institute® BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
// DAMAGE.
//
// *****************************************************************************
#ifndef SWRI_CONSOLE_LOG_DATABASE_PROXY_MODEL_H_
#define SWRI_CONSOLE_LOG_DATABASE_PROXY_MODEL_H_
#include <QAbstractListModel>
#include <QColor>
#include <QRegularExpression>
#include <QStringList>
#include <rclcpp/time.hpp>
#include <cstdint>
#include <map>
#include <set>
#include <string>
#include <deque>
namespace swri_console
{
class LogDatabase;
struct LogEntry;
class LogDatabaseProxyModel : public QAbstractListModel
{
Q_OBJECT
public:
enum {
ExtendedLogRole = Qt::UserRole + 0
};
explicit LogDatabaseProxyModel(LogDatabase *db);
~LogDatabaseProxyModel() override = default;
void setNodeFilter(const std::set<std::string> &names);
void setSeverityFilter(uint8_t severity_mask);
void setIncludeFilters(const QStringList &list);
void setExcludeFilters(const QStringList &list);
void setIncludeRegexpPattern(const QString& pattern);
void setExcludeRegexpPattern(const QString& pattern);
void setExcludePreviewFilter(const QString& term);
void setOutputFormat(const QString& format);
const QString& outputFormat() const { return output_format_; }
void setHighlightFilters(const QStringList &list);
void setHighlightRegexpPattern(const QString& pattern);
void setHighlightColor(const QColor& highlight_color);
bool isHighlightValid() const;
void setDebugColor(const QColor& debug_color);
void setInfoColor(const QColor& info_color);
void setWarnColor(const QColor& warn_color);
void setErrorColor(const QColor& error_color);
void setFatalColor(const QColor& fatal_color);
void setNodeColor(const std::string& node, const QColor& color);
void clearNodeColor(const std::string& node);
const std::map<std::string, QColor>& nodeColors() const { return node_colors_; }
bool isIncludeValid() const;
bool isExcludeValid() const;
int getItemIndex(const QString& searchText, int index, int increment);
void clearSearchFailure();
int rowCount(const QModelIndex &parent) const override;
QVariant data(const QModelIndex &index, int role) const override;
void reset();
void saveToFile(const QString& filename) const;
Q_SIGNALS:
void messagesAdded();
public Q_SLOTS:
void handleDatabaseCleared();
void processNewMessages();
void processOldMessages();
void minTimeUpdated();
void setDisplayTime(bool display);
void setAbsoluteTime(bool absolute);
void setHumanReadableTime(bool human_readable_time);
void setDisplayLogger(bool logger_name);
void setDisplayFunction(bool function_name);
void setColorizeLogs(bool colorize_logs);
void setUseRegularExpressions(bool useRegexps);
private:
void saveBagFile(const QString& filename) const;
void saveTextFile(const QString& filename) const;
void scheduleIdleProcessing();
bool acceptLogEntry(const LogEntry &item);
bool testIncludeFilter(const LogEntry &item);
bool matchesExcludePreview(const LogEntry &item) const;
bool matchesHighlight(const LogEntry &item) const;
void repaintBackgrounds();
void formatTimestamp(const rclcpp::Time &stamp, char *buf, size_t size) const;
void parseOutputFormat();
int entryLineCount(const LogEntry &item) const;
QString formatCustomLine(const LogEntry &item, int line_index) const;
QString substituteTokens(const QString &line_template, const LogEntry &item, const QString &message) const;
std::set<std::string> names_;
uint8_t severity_mask_;
bool colorize_logs_;
bool display_time_;
bool display_absolute_time_;
bool human_readable_time_;
bool display_logger_;
bool display_function_;
bool use_regular_expressions_;
// For performance reasons, the proxy model presents single line
// items, while the underlying log database stores multi-line
// messages. The LineMap struct is used to map our item indices to
// the log & line that it represents.
struct LineMap {
size_t log_index;
int line_index;
LineMap() : log_index(0), line_index(0) {}
LineMap(size_t log, int line) : log_index(log), line_index(line) {}
};
size_t latest_log_index_;
std::deque<LineMap> msg_mapping_;
size_t earliest_log_index_;
std::deque<LineMap> early_mapping_;
QRegularExpression include_regexp_;
QRegularExpression exclude_regexp_;
QStringList include_strings_;
QStringList exclude_strings_;
// The exclude term currently being typed (not yet committed to
// exclude_strings_/exclude_regexp_). Matching rows are highlighted
// rather than filtered out until the term is committed.
QString exclude_preview_term_;
QRegularExpression exclude_preview_regexp_;
// Highlight filter: unlike include/exclude, matching rows are never
// hidden -- they're just tinted highlight_color_ via Qt::BackgroundRole,
// same mechanism as exclude_preview_term_ above but persistent rather
// than typing-only.
QRegularExpression highlight_regexp_;
QStringList highlight_strings_;
QColor highlight_color_;
// When non-empty, overrides the display_time_/display_logger_/display_function_
// driven layout entirely. Supports the same token names as ROS 2's
// RCUTILS_CONSOLE_OUTPUT_FORMAT: {severity} {name} {function_name} {file_name}
// {line_number} {time} {message}. May span multiple lines: the one line
// containing {message} is repeated once per physical line of the log
// message; any lines before/after it are rendered once per log entry as
// a header/footer. Derived from output_format_ by parseOutputFormat()
// whenever it changes.
QString output_format_;
QStringList format_pre_lines_;
QString format_message_line_;
QStringList format_post_lines_;
QColor debug_color_;
QColor info_color_;
QColor warn_color_;
QColor error_color_;
QColor fatal_color_;
// Per-node background tint, set via the node list's right-click "Select
// Color..." menu. Absent entries mean "no override for this node".
std::map<std::string, QColor> node_colors_;
LogDatabase *db_;
QString failedSearchText_; // stores last failed search text, used to minimize looping through full data set, VCM 26 April 2017
int failedSearchIndex_; // stores last index of failed search text, VCM 26 April 2017
};
} // swri_console
#endif // SWRI_CONSOLE_LOG_DATABASE_PROXY_MODEL_H_