| 
						
						
							
								
							
						
						
					 | 
					 | 
					@ -5,6 +5,8 @@ | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					#include <QScrollBar> | 
					 | 
					 | 
					 | 
					#include <QScrollBar> | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					#include <QVBoxLayout> | 
					 | 
					 | 
					 | 
					#include <QVBoxLayout> | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					#include "tools/cabana/commands.h" | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					MessagesWidget::MessagesWidget(QWidget *parent) : QWidget(parent) { | 
					 | 
					 | 
					 | 
					MessagesWidget::MessagesWidget(QWidget *parent) : QWidget(parent) { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  QVBoxLayout *main_layout = new QVBoxLayout(this); | 
					 | 
					 | 
					 | 
					  QVBoxLayout *main_layout = new QVBoxLayout(this); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  main_layout->setContentsMargins(0 ,0, 0, 0); | 
					 | 
					 | 
					 | 
					  main_layout->setContentsMargins(0 ,0, 0, 0); | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
					 | 
					@ -82,11 +84,7 @@ MessagesWidget::MessagesWidget(QWidget *parent) : QWidget(parent) { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  }); | 
					 | 
					 | 
					 | 
					  }); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  QObject::connect(can, &AbstractStream::msgsReceived, model, &MessageListModel::msgsReceived); | 
					 | 
					 | 
					 | 
					  QObject::connect(can, &AbstractStream::msgsReceived, model, &MessageListModel::msgsReceived); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  QObject::connect(dbc(), &DBCManager::DBCFileChanged, this, &MessagesWidget::dbcModified); | 
					 | 
					 | 
					 | 
					  QObject::connect(dbc(), &DBCManager::DBCFileChanged, this, &MessagesWidget::dbcModified); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  QObject::connect(dbc(), &DBCManager::msgUpdated, this, &MessagesWidget::dbcModified); | 
					 | 
					 | 
					 | 
					  QObject::connect(UndoStack::instance(), &QUndoStack::indexChanged, this, &MessagesWidget::dbcModified); | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  QObject::connect(dbc(), &DBCManager::msgRemoved, this, &MessagesWidget::dbcModified); | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  QObject::connect(dbc(), &DBCManager::signalAdded, this, &MessagesWidget::dbcModified); | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  QObject::connect(dbc(), &DBCManager::signalRemoved, this, &MessagesWidget::dbcModified); | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  QObject::connect(dbc(), &DBCManager::signalUpdated, this, &MessagesWidget::dbcModified); | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  QObject::connect(model, &MessageListModel::modelReset, [this]() { | 
					 | 
					 | 
					 | 
					  QObject::connect(model, &MessageListModel::modelReset, [this]() { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    if (current_msg_id) { | 
					 | 
					 | 
					 | 
					    if (current_msg_id) { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      selectMessage(*current_msg_id); | 
					 | 
					 | 
					 | 
					      selectMessage(*current_msg_id); | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
					 | 
					@ -245,104 +243,55 @@ void MessageListModel::sortMessages(std::vector<MessageId> &new_msgs) { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  } | 
					 | 
					 | 
					 | 
					  } | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					} | 
					 | 
					 | 
					 | 
					} | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					static std::pair<unsigned int, unsigned int> parseRange(const QString &filter, bool *ok = nullptr, int base = 10) { | 
					 | 
					 | 
					 | 
					static bool parseRange(const QString &filter, uint32_t value, int base = 10) { | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  // Parse out filter string into a range (e.g. "1" -> {1, 1}, "1-3" -> {1, 3}, "1-" -> {1, inf})
 | 
					 | 
					 | 
					 | 
					  // Parse out filter string into a range (e.g. "1" -> {1, 1}, "1-3" -> {1, 3}, "1-" -> {1, inf})
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  bool ok1 = true, ok2 = true; | 
					 | 
					 | 
					 | 
					  unsigned int min = std::numeric_limits<unsigned int>::min(); | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  unsigned int parsed1 = std::numeric_limits<unsigned int>::min(); | 
					 | 
					 | 
					 | 
					  unsigned int max = std::numeric_limits<unsigned int>::max(); | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  unsigned int parsed2 = std::numeric_limits<unsigned int>::max(); | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  auto s = filter.split('-'); | 
					 | 
					 | 
					 | 
					  auto s = filter.split('-'); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  if (s.size() == 1) { | 
					 | 
					 | 
					 | 
					  bool ok = s.size() <= 2; | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    parsed1 = s[0].toUInt(ok, base); | 
					 | 
					 | 
					 | 
					  if (ok && !s[0].isEmpty()) min = s[0].toUInt(&ok, base); | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    return {parsed1, parsed1}; | 
					 | 
					 | 
					 | 
					  if (ok && s.size() == 2 && !s[1].isEmpty()) max = s[1].toUInt(&ok, base); | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  } else if (s.size() == 2) { | 
					 | 
					 | 
					 | 
					  return ok && value >= min && value <= max; | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    if (!s[0].isEmpty()) parsed1 = s[0].toUInt(&ok1, base); | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    if (!s[1].isEmpty()) parsed2 = s[1].toUInt(&ok2, base); | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    *ok = ok1 & ok2; | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    return {parsed1, parsed2}; | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  } else { | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    *ok = false; | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    return {0, 0}; | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  } | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					} | 
					 | 
					 | 
					 | 
					} | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					bool MessageListModel::matchMessage(const MessageId &id, const CanData &data, const QMap<int, QString> &filters) { | 
					 | 
					 | 
					 | 
					bool MessageListModel::matchMessage(const MessageId &id, const CanData &data, const QMap<int, QString> &filters) { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  auto cs = Qt::CaseInsensitive; | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  bool match = true; | 
					 | 
					 | 
					 | 
					  bool match = true; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  bool convert_ok; | 
					 | 
					 | 
					 | 
					  for (auto it = filters.cbegin(); it != filters.cend() && match; ++it) { | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					    const QString &txt = it.value(); | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  for (int column = Column::NAME; column <= Column::DATA; column++) { | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    if (!filters.contains(column)) continue; | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    const QString &txt = filters[column]; | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    QRegularExpression re(txt, QRegularExpression::CaseInsensitiveOption | QRegularExpression::DotMatchesEverythingOption); | 
					 | 
					 | 
					 | 
					    QRegularExpression re(txt, QRegularExpression::CaseInsensitiveOption | QRegularExpression::DotMatchesEverythingOption); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					    switch (it.key()) { | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    switch (column) { | 
					 | 
					 | 
					 | 
					      case Column::NAME: { | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      case Column::NAME: | 
					 | 
					 | 
					 | 
					        const auto msg = dbc()->msg(id); | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        { | 
					 | 
					 | 
					 | 
					        match = re.match(msg ? msg->name : UNTITLED).hasMatch(); | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					          bool name_match = re.match(msgName(id)).hasMatch(); | 
					 | 
					 | 
					 | 
					        match |= msg && std::any_of(msg->sigs.cbegin(), msg->sigs.cend(), [&re](const auto &s) { return re.match(s.name).hasMatch(); }); | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					          // Message signals
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					          if (const auto msg = dbc()->msg(id)) { | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            for (auto s : msg->getSignals()) { | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					              if (re.match(s->name).hasMatch()) { | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                name_match = true; | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        break; | 
					 | 
					 | 
					 | 
					        break; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      } | 
					 | 
					 | 
					 | 
					      } | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            } | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					          } | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					          if (!name_match) match = false; | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        } | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        break; | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      case Column::SOURCE: | 
					 | 
					 | 
					 | 
					      case Column::SOURCE: | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        { | 
					 | 
					 | 
					 | 
					        match = parseRange(txt, id.source); | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					          auto source = parseRange(txt, &convert_ok); | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					          bool source_match = convert_ok && (id.source >= source.first && id.source <= source.second); | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					          if (!source_match) match = false; | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        } | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        break; | 
					 | 
					 | 
					 | 
					        break; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      case Column::ADDRESS: | 
					 | 
					 | 
					 | 
					      case Column::ADDRESS: { | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        { | 
					 | 
					 | 
					 | 
					        match = re.match(QString::number(id.address, 16)).hasMatch(); | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					          bool address_re_match = re.match(QString::number(id.address, 16)).hasMatch(); | 
					 | 
					 | 
					 | 
					        match |= parseRange(txt, id.address, 16); | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					          auto address = parseRange(txt, &convert_ok, 16); | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					          bool address_match = convert_ok && (id.address >= address.first && id.address <= address.second); | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					          if (!address_re_match && !address_match) match = false; | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        } | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        break; | 
					 | 
					 | 
					 | 
					        break; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					      } | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      case Column::FREQ: | 
					 | 
					 | 
					 | 
					      case Column::FREQ: | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        { | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        // TODO: Hide stale messages?
 | 
					 | 
					 | 
					 | 
					        // TODO: Hide stale messages?
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					          auto freq = parseRange(txt, &convert_ok); | 
					 | 
					 | 
					 | 
					        match = parseRange(txt, data.freq); | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					          bool freq_match = convert_ok && (data.freq >= freq.first && data.freq <= freq.second); | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					          if (!freq_match) match = false; | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        } | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        break; | 
					 | 
					 | 
					 | 
					        break; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      case Column::COUNT: | 
					 | 
					 | 
					 | 
					      case Column::COUNT: | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        { | 
					 | 
					 | 
					 | 
					        match = parseRange(txt, data.count); | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					          auto count = parseRange(txt, &convert_ok); | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					          bool count_match = convert_ok && (data.count >= count.first && data.count <= count.second); | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					          if (!count_match) match = false; | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        } | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        break; | 
					 | 
					 | 
					 | 
					        break; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      case Column::DATA: | 
					 | 
					 | 
					 | 
					      case Column::DATA: { | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        { | 
					 | 
					 | 
					 | 
					        match = QString(data.dat.toHex()).contains(txt, Qt::CaseInsensitive); | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					          bool data_match = false; | 
					 | 
					 | 
					 | 
					        match |= re.match(QString(data.dat.toHex())).hasMatch(); | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					          data_match |= QString(data.dat.toHex()).contains(txt, cs); | 
					 | 
					 | 
					 | 
					        match |= re.match(QString(data.dat.toHex(' '))).hasMatch(); | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					          data_match |= re.match(QString(data.dat.toHex())).hasMatch(); | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					          data_match |= re.match(QString(data.dat.toHex(' '))).hasMatch(); | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					          if (!data_match) match = false; | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        } | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        break; | 
					 | 
					 | 
					 | 
					        break; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      } | 
					 | 
					 | 
					 | 
					      } | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    } | 
					 | 
					 | 
					 | 
					    } | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					  } | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  return match; | 
					 | 
					 | 
					 | 
					  return match; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					} | 
					 | 
					 | 
					 | 
					} | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					void MessageListModel::fetchData() { | 
					 | 
					 | 
					 | 
					void MessageListModel::fetchData() { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  std::vector<MessageId> new_msgs; | 
					 | 
					 | 
					 | 
					  std::vector<MessageId> new_msgs; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  new_msgs.reserve(can->last_msgs.size() + dbc_address.size()); | 
					 | 
					 | 
					 | 
					  new_msgs.reserve(can->last_msgs.size() + dbc_address.size()); | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
					 | 
					@ -459,11 +408,10 @@ void MessageView::headerContextMenuEvent(const QPoint &pos) { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  QMenu *menu = new QMenu(this); | 
					 | 
					 | 
					 | 
					  QMenu *menu = new QMenu(this); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  int cur_index = header()->logicalIndexAt(pos); | 
					 | 
					 | 
					 | 
					  int cur_index = header()->logicalIndexAt(pos); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  QString column_name; | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  QAction *action; | 
					 | 
					 | 
					 | 
					  QAction *action; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  for (int visual_index = 0; visual_index < header()->count(); visual_index++) { | 
					 | 
					 | 
					 | 
					  for (int visual_index = 0; visual_index < header()->count(); visual_index++) { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    int logical_index = header()->logicalIndex(visual_index); | 
					 | 
					 | 
					 | 
					    int logical_index = header()->logicalIndex(visual_index); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    column_name = model()->headerData(logical_index, Qt::Horizontal).toString(); | 
					 | 
					 | 
					 | 
					    QString column_name = model()->headerData(logical_index, Qt::Horizontal).toString(); | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    // Hide show action
 | 
					 | 
					 | 
					 | 
					    // Hide show action
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    if (header()->isSectionHidden(logical_index)) { | 
					 | 
					 | 
					 | 
					    if (header()->isSectionHidden(logical_index)) { | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
						
					 | 
					 | 
					
  |