HAL  v4.5.0-254-g8f9f6a423
The Hardware Analyzer - a comprehensive reverse engineering and manipulation framework for gate-level netlists.
data_table_model.cpp
Go to the documentation of this file.
1 
3 #include <algorithm>
4 #include <QToolTip>
5 #include <QRandomGenerator>
7 
8 
9 namespace hal
10 {
12  {
13  }
14 
15  int DataTableModel::columnCount(const QModelIndex &parent) const
16  {
17  Q_UNUSED(parent)
18  //return 2;
19  return 4;
20  }
21 
22  int DataTableModel::rowCount(const QModelIndex &parent) const
23  {
24  Q_UNUSED(parent)
25  return mDataEntries.size();
26  }
27 
29  {
30  DataTableEntry entry = mDataEntries[index.row()];
31  RowStyle style = mEntryToRowStyle[QPair(entry.category, entry.key)];
32 
33  if(role == Qt::DisplayRole && index.column() < columnCount())
34  {
35  switch (index.column())
36  {
37  case 0: return entry.category;
38  case 1: return entry.key;
39  case 2: return entry.dataType;
40  case 3: return style.valueString;//e.g. 0x at the front if bitvector
41  }
42  }
43  if(role == Qt::ForegroundRole && index.column() == 3 && style.valueColor.isValid())
44  return style.valueColor;
45 
46  if(role == Qt::TextAlignmentRole)
47  return Qt::AlignLeft;
48 
49 // if (role == Qt::DisplayRole){
50 // if(index.column() == 0){
51 // return (entry.key + ":");
52 // }
53 // else{
54 // return style.valueString;
55 // }
56 // }
57 
58 // if (role == Qt::ForegroundRole){
59 // if(index.column() == 1){
60 // if(style.valueColor.isValid())
61 // return style.valueColor;
62 // }
63 // }
64 
65 // else if (role == Qt::TextAlignmentRole){
66 // return Qt::AlignLeft;
67 // }
68 
69 // else if (role == Qt::ToolTipRole){
70 // if (index.column() == 0){
71 // if(!style.keyToolTip.isEmpty())
72 // return style.keyToolTip;
73 // }
74 // else {
75 // if(!style.valueToolTip.isEmpty())
76 // return style.valueToolTip;
77 // }
78 // }
79 
80  return QVariant();
81  }
82 
83  QVariant DataTableModel::headerData(int section, Qt::Orientation orientation, int role) const
84  {
85 // Q_UNUSED(section)
86 // Q_UNUSED(orientation)
87 // Q_UNUSED(role)
88 // return QVariant();
89  const char* horizontalHeader[] = { "Category", "Key", "Type", "Value"};
90  if (orientation == Qt::Horizontal && role == Qt::DisplayRole && section < columnCount())
91  return QString(horizontalHeader[section]);
92 
93  return QVariant();
94  }
95 
96  bool DataTableModel::setData(const QModelIndex &index, const QVariant &value, int role)
97  {
98  Q_UNUSED(index)
99  Q_UNUSED(value)
100  Q_UNUSED(role)
101  return false;
102  }
103 
105  {
106  return mDataEntries.at(row);
107  }
108 
109  void DataTableModel::updateData(const std::map<std::tuple<std::string, std::string>, std::tuple<std::string, std::string>>& dataMap)
110  {
112  mDataEntries.clear();
113  mEntryToRowStyle.clear();
114  for(const auto& [key, value] : dataMap)
115  {
116  mDataEntries.append(DataTableEntry(QString::fromStdString(std::get<0>(key)), QString::fromStdString(std::get<1>(key)),
117  QString::fromStdString(std::get<0>(value)), QString::fromStdString(std::get<1>(value))));
118  }
119 
120  // The data is sorted by category first and then by key. However the category generic is always displayed first.
121  std::sort(mDataEntries.begin(), mDataEntries.end(),
122  [](const DataTableEntry a, const DataTableEntry b) -> bool
123  {
124 
125  if(a.category == b.category)
126  {
127  return (a.key < b.key);
128  }
129  else
130  {
131  if(a.category == "generic")
132  return true;
133  else if(b.category == "generic")
134  return false;
135  else
136  return (a.category < b.category);
137  }
138  });
139 
140  // Compute the appearance
141  int rowIdx = 0;
142  for(const DataTableEntry& entry : mDataEntries)
143  {
144  mEntryToRowStyle[QPair<QString,QString>(entry.category, entry.key)] = getRowStyleByEntry(entry, rowIdx);
145  rowIdx++;
146  }
147 
148  Q_EMIT layoutChanged();
149  }
150 
151  DataTableModel::RowStyle DataTableModel::getRowStyleByEntry(const DataTableEntry& entry, int rowIdx) const
152  {
153  RowStyle style;
154  style.keyFont = QFont();
155  style.keyToolTip = QString();
156  style.valueToolTip = QString();
157  style.valueColor = QColor();
158 
159  // Sets the value string and color considering its data type
160  if(entry.dataType == "string")
161  {
162  style.valueString = QString("\"%1\"").arg(entry.value);
163  style.valueColor = PythonQssAdapter::instance()->doubleQuotedStringColor();
164  }
165  else if(entry.dataType == "bit_value" || entry.dataType == "bit_vector")
166  {
167  style.valueString = QString("0x%1").arg(entry.value);
168  style.valueColor = PythonQssAdapter::instance()->numberColor();
169  }
170  else if(entry.dataType == "integer")
171  {
172  style.valueString = entry.value;
173  style.valueColor = PythonQssAdapter::instance()->numberColor();
174  }
175  else
176  {
177  style.valueString = entry.value;
178  }
179 
180 
181  // Hacky solution to prevent that the tooltip in neighboring rows does not change position if the tooltip entry is the same.
182  // Therefore, two different space types are used so that Qt thinks these are different entries.
183  if(rowIdx%2 == 0)
184  {
185  style.keyToolTip = entry.category + " ";
186  style.valueToolTip = entry.dataType + " ";
187  }
188  else
189  {
190  //U+00A0 is a no-break space and therefore another type of space
191  style.keyToolTip = entry.category + QChar(0x00A0);
192  style.valueToolTip = entry.dataType + QChar(0x00A0);
193  }
194 
195  return style;
196  }
197 
198 } // namespace hal
199 
200 
QString dataType
The data's key.
QString key
The data's category.
QString category
DataTableModel(QObject *parent=nullptr)
bool setData(const QModelIndex &index, const QVariant &value, int role) override
int columnCount(const QModelIndex &parent=QModelIndex()) const override
QVariant data(const QModelIndex &index, int role) const override
void updateData(const std::map< std::tuple< std::string, std::string >, std::tuple< std::string, std::string >> &dc)
QVariant headerData(int section, Qt::Orientation orientation, int role) const override
DataTableEntry getEntryAtRow(int row) const
int rowCount(const QModelIndex &parent=QModelIndex()) const override
Definition: defines.h:45
std::unique_ptr< BasePluginInterface > instance
void layoutAboutToBeChanged(const QList< QPersistentModelIndex > &parents, QAbstractItemModel::LayoutChangeHint hint)
virtual QModelIndex index(int row, int column, const QModelIndex &parent) const const override
void clear()
int column() const const
int row() const const
Q_EMITQ_EMIT
QObject * parent() const const
QString arg(qlonglong a, int fieldWidth, int base, QChar fillChar) const const
QString fromStdString(const std::string &str)
AlignLeft
DisplayRole
Orientation