HAL  v4.5.0-148-g878908d18
The Hardware Analyzer - a comprehensive reverse engineering and manipulation framework for gate-level netlists.
logger_widget.cpp
Go to the documentation of this file.
5 #include "gui/toolbar/toolbar.h"
9 
10 #include <QHeaderView>
11 #include <QVBoxLayout>
12 #include <QSignalMapper>
13 #include <QPushButton>
14 #include <QLabel>
15 #include <QSpacerItem>
16 #include <QLineEdit>
17 #include <QAction>
18 #include <QDebug>
19 
20 #include <string>
21 #include <QRegularExpression>
22 
23 namespace hal
24 {
26  {
27  // Active QPropertys
29 
30  mPlainTextEdit = new QPlainTextEdit(this);
31  mPlainTextEdit->setReadOnly(true);
32  mPlainTextEdit->setFrameStyle(QFrame::NoFrame);
33 
34  mPlainTextEditScrollbar = mPlainTextEdit->verticalScrollBar();
35  scrollToBottom();
36  mUserInteractedWithScrollbar = false;
37 
38  mLogMarshall = new LoggerMarshall(mPlainTextEdit);
39  mContentLayout->addWidget(mPlainTextEdit);
40 
42  // Get last severity settings
43  restoreSettings();
44 
45  mSearchbar = new Searchbar(mPlainTextEdit);
46  mSearchbar->hide();
47  mContentLayout->addWidget(mSearchbar);
48  mSearchOptions = 8;
49 
51 
53  connect(model, SIGNAL(updated(spdlog::level::level_enum, std::string, std::string)), this, SLOT(handleChannelUpdated(spdlog::level::level_enum, std::string, std::string)));
54 
55  mSearchAction = new QAction(this);
56  mSearchAction->setIcon(gui_utility::getStyledSvgIcon(mSearchIconStyle, mSearchIconPath));
57 
58  mChannelLabel = new QLabel(this);
59  mChannelLabel->setText("all");
60 
61  mSelector = new ChannelSelector(this);
62  mSelector->setEditable(true);
63  }
64 
66  {
67 
68  }
69 
71  {
72  // Action button to activate Searchbar
73  toolbar->addAction(mSearchAction);
74 
75  // Show current channel
76  toolbar->addWidget(mChannelLabel);
77 
78  // ChannelSelector
79  connect(mSelector->lineEdit(), SIGNAL(editingFinished()), this, SLOT(handleCustomChannel()));
80  connect(mSelector, SIGNAL(currentIndexChanged(int)), this, SLOT(handleCurrentFilterChanged(int)));
81 // mSelector->setStyleSheet("QCombobox {background-color : rgb(32, 43, 63); border-radius: 2px;}");
83  toolbar->addWidget(mSelector);
84 
85  // Severity buttons
86  mDebugButton = new QPushButton("Debug", this);
87  mDebugButton->setCheckable(true);
88  mDebugButton->setChecked(mDebugSeverity);
89 // mDebugButton->setStyleSheet("QPushButton { border : none; background-color : rgb(26, 26, 26) } QPushButton:hover { background-color : rgb(46, 46, 46) } QPushButton:checked:hover { background-color : rgb(66, 66, 66) } QPushButton:checked { background-color : rgb(89, 89, 89); color : rgb(204, 204, 204)} ");
90  toolbar->addWidget(mDebugButton);
91 
92  mInfoButton = new QPushButton("Info", this);
93  mInfoButton->setCheckable(true);
94  mInfoButton->setChecked(mInfoSeverity);
95 // mInfoButton->setStyleSheet("QPushButton { border : none; background-color : rgb(26, 26, 26) } QPushButton:hover { background-color : rgb(46, 46, 46) } QPushButton:checked:hover { background-color : rgb(66, 66, 66) } QPushButton:checked { background-color : rgb(89, 89, 89); color : rgb(204, 204, 204)} ");
96  toolbar->addWidget(mInfoButton);
97 
98  mWarningButton = new QPushButton("Warning", this);
99  mWarningButton->setCheckable(true);
100  mWarningButton->setChecked(mWarningSeverity);
101 // mWarningButton->setStyleSheet("QPushButton { border : none; background-color : rgb(26, 26, 26) } QPushButton:hover { background-color : rgb(46, 46, 46) } QPushButton:checked:hover { background-color : rgb(66, 66, 66) } QPushButton:checked { background-color : rgb(89, 89, 89); color : rgb(204, 204, 204)} ");
102  toolbar->addWidget(mWarningButton);
103 
104  mErrorButton = new QPushButton("Error", this);
105  mErrorButton->setCheckable(true);
106  mErrorButton->setChecked(mErrorSeverity);
107 // mErrorButton->setStyleSheet("QPushButton { border : none; background-color : rgb(26, 26, 26) } QPushButton:hover { background-color : rgb(46, 46, 46) } QPushButton:checked:hover { background-color : rgb(66, 66, 66) } QPushButton:checked { background-color : rgb(89, 89, 89); color : rgb(204, 204, 204)} ");
108  toolbar->addWidget(mErrorButton);
109 
110  toolbar->addSpacer();
111 
112  mMuteButton = new QPushButton("Mute all", this);
113 // mMuteButton->setStyleSheet("QPushButton { border : none; background-color : rgb(26, 26, 26) } QPushButton:hover { background-color : rgb(46, 46, 46) } QPushButton:pressed { background-color : rgb(89, 89, 89); color : rgb(204, 204, 204)} ");
114  toolbar->addWidget(mMuteButton);
115 
116  mVerboseButton = new QPushButton("Show all", this);
117 // mVerboseButton->setStyleSheet("QPushButton { border : none; background-color : rgb(26, 26, 26) } QPushButton:hover { background-color : rgb(46, 46, 46) } QPushButton:pressed { background-color : rgb(89, 89, 89); color : rgb(204, 204, 204)} ");
118  toolbar->addWidget(mVerboseButton);
119 
120  connect(mSearchAction, SIGNAL(triggered()), this, SLOT(toggleSearchbar()));
121  connect(mSearchbar, SIGNAL(triggerNewSearch(QString, int)), this, SLOT(handleSearchChanged(QString, int)));
122  connect(mDebugButton, SIGNAL(toggled(bool)), this, SLOT(handleSeverityChanged(bool)));
123  connect(mInfoButton, SIGNAL(toggled(bool)), this, SLOT(handleSeverityChanged(bool)));
124  connect(mWarningButton, SIGNAL(toggled(bool)), this, SLOT(handleSeverityChanged(bool)));
125  connect(mErrorButton, SIGNAL(toggled(bool)), this, SLOT(handleSeverityChanged(bool)));
126  connect(mMuteButton, SIGNAL(clicked(bool)), this, SLOT(handleSeverityChanged(bool)));
127  connect(mVerboseButton, SIGNAL(clicked(bool)), this, SLOT(handleSeverityChanged(bool)));
128 
129  toolbar->repolish();
130  }
131 
133  {
134  return mPlainTextEdit;
135  }
136 
137  void LoggerWidget::handleCurrentChannelUpdated(spdlog::level::level_enum t, const QString& msg)
138  {
139  mLogMarshall->appendLog(t, msg);
140  }
141 
142  void LoggerWidget::handleChannelUpdated(spdlog::level::level_enum t, const std::string& logger_name, const std::string& msg)
143  {
144  if (mCurrentChannel == "")
145  {
147  }
148  if (logger_name != mCurrentChannel)
149  return;
150 
151 
152  bool filter = false;
153  if ((t == spdlog::level::level_enum::info) && mInfoSeverity) {
154  filter = true;
155  }
156  else if ((t == spdlog::level::level_enum::warn) && mWarningSeverity) {
157  filter = true;
158  }
159  else if ((t == spdlog::level::level_enum::err) && mErrorSeverity) {
160  filter = true;
161  }
162  else if ((t == spdlog::level::level_enum::debug) && mDebugSeverity) {
163  filter = true;
164  }
165  else if (t == spdlog::level::level_enum::critical) {
166  filter = true;
167  }
168 
169  if (filter)
170  {
171  mLogMarshall->appendLog(t, QString::fromStdString(msg));
172  }
173  }
174 
175  bool LoggerWidget::isMatching(QString searchString, QString stringToCheck)
176  {
177  if(!mSearchOptions.isExactMatch() && !mSearchOptions.isRegularExpression()){
178  //check if stringToCheck contains the searchString
179  return stringToCheck.contains(searchString, mSearchOptions.isCaseSensitive() ? Qt::CaseSensitive : Qt::CaseInsensitive);
180  }
181  else if(mSearchOptions.isExactMatch()){
182  //check if the stringToCheck is the same as the searchString - also checks CaseSensitivity
183 
184  return 0 == QString::compare(searchString, stringToCheck, mSearchOptions.isCaseSensitive() ? Qt::CaseSensitive : Qt::CaseInsensitive);
185  }
186  else if(mSearchOptions.isRegularExpression()){
187  //checks if the stringToCheck matches the regEx given by searchString
189  return regEx.match(stringToCheck).hasMatch();
190  }
191  return false;
192  }
193 
195  {
197 
198  // Channel has been changed or initially set
199  if ((sender() == mSelector) || p == 0) {
200  mCurrentChannelIndex = p;
201  }
202 
203  // Set "all" Channel
204  if (p == -1) {
205  mCurrentChannelIndex = model->rowCount() - 1;
206  }
207 
208  if (mCurrentChannelIndex == -2) {
209  return;
210  }
211 
212  ChannelItem* item = static_cast<ChannelItem*>((model->index(mCurrentChannelIndex, 0, QModelIndex())).internalPointer());
213  mCurrentChannel = item->name().toStdString();
214  mChannelLabel->setText(QString::fromStdString(mCurrentChannel));
215  mSelector->setCurrentText(QString::fromStdString(mCurrentChannel));
216 
217  mPlainTextEdit->clear();
218  QWriteLocker item_locker(item->getLock());
219 
220  // Iterate through every log entry
221  for (ChannelEntry* entry : *(item->getEntries()))
222  {
223  bool filter = false;
224  // If entry msg matches with search string
225  //QRegularExpression re(mSearchFilter);
226  if (isMatching(mSearchFilter, QString::fromStdString(entry->mMsg)))
227  {
228  // If entry severity matches the choosen severitys
229  if ((entry->mMsgType == spdlog::level::level_enum::info) && mInfoSeverity) {
230  filter = true;
231  }
232  else if ((entry->mMsgType == spdlog::level::level_enum::warn) && mWarningSeverity) {
233  filter = true;
234  }
235  else if ((entry->mMsgType == spdlog::level::level_enum::err) && mErrorSeverity) {
236  filter = true;
237  }
238  else if ((entry->mMsgType == spdlog::level::level_enum::debug) && mDebugSeverity) {
239  filter = true;
240  }
241  else if (entry->mMsgType == spdlog::level::level_enum::critical) {
242  filter = true;
243  }
244  }
245 
246  // If log entry should be shown
247  if (filter)
248  {
249  mLogMarshall->appendLog(entry->mMsgType, QString::fromStdString(entry->mMsg));
250  }
251  }
252  }
253 
255  {
256 
257  // change Severitys
258  if (sender() == mDebugButton)
259  {
260  mDebugSeverity = state;
261  }
262  else if (sender() == mInfoButton)
263  {
264  mInfoSeverity = state;
265  }
266  else if (sender() == mWarningButton)
267  {
268  mWarningSeverity = state;
269  }
270  else if (sender() == mErrorButton)
271  {
272  mErrorSeverity = state;
273  }
274  else if (sender() == mMuteButton)
275  {
276  mDebugButton->setChecked(false);
277  mInfoButton->setChecked(false);
278  mWarningButton->setChecked(false);
279  mErrorButton->setChecked(false);
280  }
281  else if (sender() == mVerboseButton)
282  {
283  mDebugButton->setChecked(true);
284  mInfoButton->setChecked(true);
285  mWarningButton->setChecked(true);
286  mErrorButton->setChecked(true);
287  // "all" channel
289  }
290 
291  // Make changes
293 
294  // Save severity settings for next session
295  saveSettings();
296  }
297 
298  void LoggerWidget::handleSearchChanged(QString filter, int searchOptions)
299  {
300  mSearchFilter = filter;
301  mSearchOptions = SearchOptions(searchOptions);
303  }
304 
306  {
307  Q_UNUSED(value);
308 
309  if (!mUserInteractedWithScrollbar)
310  mUserInteractedWithScrollbar = true;
311  }
312 
314  {
315  QString txt = mSelector->lineEdit()->text();
316  if (txt.isEmpty()) return;
317  std::string channel_name = txt.toStdString();
319  model->handleLogmanagerCallback(spdlog::level::level_enum::debug , channel_name, channel_name + " has manually been added to channellist");
320  }
321 
323  {
324  Q_UNUSED(event)
325 
326  if (!mUserInteractedWithScrollbar)
327  scrollToBottom();
328  }
329 
330  void LoggerWidget::scrollToBottom()
331  {
332  mPlainTextEditScrollbar->setValue(mPlainTextEditScrollbar->maximum());
333  }
334 
335  void LoggerWidget::saveSettings()
336  {
337  LoggerSettings settings = { mDebugSeverity, mInfoSeverity, mWarningSeverity, mErrorSeverity };
339  }
340 
341  void LoggerWidget::restoreSettings()
342  {
343  LoggerSettings settings = SettingsManager::instance()->loggerSettings();
344  mDebugSeverity = settings.debugSeverity;
345  mInfoSeverity = settings.infoSeverity;
346  mWarningSeverity = settings.warningSeverity;
347  mErrorSeverity = settings.errorSeverity;
348  }
349 
351  {
352  if(mSearchbar->isHidden())
353  {
354  mSearchbar->show();
355  mSearchbar->setFocus();
356  }
357  else
358  {
359  mSearchbar->hide();
360  setFocus();
361  }
362  }
363 
365  {
366  return mSearchIconPath;
367  }
368 
370  {
371  return mSearchIconStyle;
372  }
373 
375  {
376  mSearchIconPath = path;
377  }
378 
380  {
381  mSearchIconStyle = style;
382  }
383 }
This class represents a channel in the channel model. It primarily holds the channel name and its ent...
Definition: channel_item.h:67
const QString name() const
const QList< ChannelEntry * > * getEntries() const
QReadWriteLock * getLock()
Table model for log channels.
Definition: channel_model.h:48
void handleLogmanagerCallback(const spdlog::level::level_enum &t, const std::string &channel_name, const std::string &msg_text)
int rowCount(const QModelIndex &parent=QModelIndex()) const override
static ChannelModel * instance()
QModelIndex index(int row, int column, const QModelIndex &parent=QModelIndex()) const override
A combobox for selecting a logger channel.
Abstract class for Widgets within HAL's ContentArea.
QVBoxLayout * mContentLayout
Appends log messages to the corresponding LoggerWidget.
void appendLog(spdlog::level::level_enum log_type, QString const &msg)
void resizeEvent(QResizeEvent *event) override
virtual void setupToolbar(Toolbar *toolbar) override
void handleCurrentFilterChanged(int p)
~LoggerWidget() override
QString searchIconPath() const
void handleSearchChanged(QString filter, int SearchOptions)
void setSearchIconStyle(const QString &style)
void setSearchIconPath(const QString &path)
QPlainTextEdit * getPlainTextEdit()
void handleFirstUserInteraction(int value)
bool isMatching(QString searchString, QString stringToCheck)
void handleCurrentChannelUpdated(spdlog::level::level_enum t, QString const &msg)
void handleSeverityChanged(bool state)
void handleChannelUpdated(spdlog::level::level_enum t, const std::string &logger_name, std::string const &msg)
LoggerWidget(QWidget *parent=nullptr)
QString searchIconStyle() const
bool isExactMatch() const
bool isCaseSensitive() const
bool isRegularExpression() const
A QFrame with a QLineEdit that can be used to input a substring to search for.
Definition: searchbar.h:48
void saveLoggerSettings(const LoggerSettings &settings)
LoggerSettings loggerSettings() const
static SettingsManager * instance()
Toolbar for all ContentFrames and ContentWidgets.
Definition: toolbar.h:39
void addSpacer()
Definition: toolbar.cpp:11
void repolish()
Definition: toolbar.cpp:19
QIcon getStyledSvgIcon(const QString &from_to_colors_enabled, const QString &svg_path, QString from_to_colors_disabled=QString())
Definition: graphics.cpp:60
Definition: defines.h:45
void setCheckable(bool)
void setChecked(bool)
QScrollBar * verticalScrollBar() const const
void actionTriggered(int action)
void setValue(int)
void setIcon(const QIcon &icon)
void addWidget(QWidget *widget, int stretch, Qt::Alignment alignment)
AdjustToContentsOnFirstShow
void setCurrentText(const QString &text)
void setEditable(bool editable)
QLineEdit * lineEdit() const const
void setSizeAdjustPolicy(QComboBox::SizeAdjustPolicy policy)
void setFrameStyle(int style)
void setText(const QString &)
QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
QObject * sender() const const
void setReadOnly(bool ro)
int compare(const QString &other, Qt::CaseSensitivity cs) const const
bool contains(QChar ch, Qt::CaseSensitivity cs) const const
QString fromStdString(const std::string &str)
bool isEmpty() const const
std::string toStdString() const const
CaseSensitive
CustomContextMenu
QAction * addAction(const QString &text)
QAction * addWidget(QWidget *widget)
void setContextMenuPolicy(Qt::ContextMenuPolicy policy)
void ensurePolished() const const
virtual bool event(QEvent *event) override
void hide()
bool isHidden() const const
void setFocus()
void show()
QStyle * style() const const
The ChannelEntry struct is used by the ChannelItem class to store a single entry.
Definition: channel_item.h:44