1 #include <QDebug>
2 #include <Qt>
3 #include <QApplication>
4 #include "sniffermodel.h"
5 #include "snifferwindow.h"
6 #include "SnifferDelegate.h"
7 
SnifferModel(QObject * parent)8 SnifferModel::SnifferModel(QObject *parent)
9     : QAbstractItemModel(parent),
10       mFilter(false),
11       mNeverExpire(false),
12       mFadeInactive(false),
13       mMuteNotched(false),
14       mTimeSequence(0)
15 {
16     QColor TextColor = QApplication::palette().color(QPalette::Text);
17     if (TextColor.red() + TextColor.green() + TextColor.blue() < 200)
18     {
19         mDarkMode = false;
20     }
21     else mDarkMode = true;
22 }
23 
~SnifferModel()24 SnifferModel::~SnifferModel()
25 {
26     qDeleteAll(mMap);
27     mMap.clear();
28     mFilters.clear();
29 }
30 
31 
columnCount(const QModelIndex & parent) const32 int SnifferModel::columnCount(const QModelIndex &parent) const
33 {
34     return parent.isValid() ? 0 : tc::LAST+1;
35 }
36 
37 
rowCount(const QModelIndex & parent) const38 int SnifferModel::rowCount(const QModelIndex &parent) const
39 {
40     const QMap<quint32, SnifferItem*>& map = mFilter ? mFilters : mMap;
41     return parent.isValid() ? 0 : map.size();
42 }
43 
44 
data(const QModelIndex & index,int role) const45 QVariant SnifferModel::data(const QModelIndex &index, int role) const
46 {
47     if (!index.isValid())
48         return QVariant();
49 
50     SnifferItem *item = static_cast<SnifferItem*>(index.internalPointer());
51     if(!item) QVariant();
52 
53     int col = index.column();
54 
55     switch(role)
56     {
57         case Qt::DisplayRole:
58         {
59             switch(col)
60             {
61                 case tc::DELTA:
62                     return QString::number(item->getDelta(), 'f');
63                 case tc::ID:
64                     return QString("%1").arg(item->getId(), 5, 16, QLatin1Char(' ')).toUpper();
65                 default:
66                     break;
67             }
68             if(tc::DATA_0<=col && col <=tc::DATA_7)
69             {
70                 int data = item->getData(col-tc::DATA_0);
71                 if(data >= 0)
72                 {
73                     return QString("%1").arg((uint8_t)data, 2, 16, QLatin1Char('0')).toUpper();
74                 }
75             }
76             break;
77         }
78         case Qt::ForegroundRole:
79         {
80             if (!mFadeInactive ||  col < 2) return QApplication::palette().brush(QPalette::Text);
81             int v = item->getSeqInterval(col - 2) * 10;
82             //qDebug() << "mTS: " << mTimeSequence << " gDT(" << (col - 2) << ") " << item->getDataTimestamp(col - 2);
83             if (v > 225) v = 225;
84             if (v < 0) v = 0;
85 
86             if (!mDarkMode) //text defaults to being dark
87             {
88                 return QBrush(QColor(v,v,v,255));
89             }
90             else //text defaults to being light
91             {
92                 return QBrush(QColor(255-v,255-v,255-v,255));
93             }
94         }
95 
96         case Qt::BackgroundRole:
97         {
98             if(tc::ID==col)
99             {
100                 if(item->elapsed() > 4000)
101                 {
102                     if (!mDarkMode) return QBrush(Qt::red);
103                     return QBrush(QColor(128,0,0));
104                 }
105             }
106             else if(tc::DATA_0<=col && col<=tc::DATA_7)
107             {
108                 dc change = item->dataChange(col-tc::DATA_0);
109                 switch(change)
110                 {
111                     case dc::INC:
112                         if (!mDarkMode) return QBrush(Qt::green);
113                         return QBrush(QColor(0,128,0));
114                     case dc::DEINC:
115                         if (!mDarkMode) return QBrush(Qt::red);
116                         return QBrush(QColor(128,0,0));
117                     default:
118                         return QApplication::palette().brush(QPalette::Base);
119                 }
120             }
121             break;
122         }
123     }
124 
125     return QVariant();
126 }
127 
128 
flags(const QModelIndex & index) const129 Qt::ItemFlags SnifferModel::flags(const QModelIndex &index) const
130 {
131     if (!index.isValid())
132         return 0;
133 
134     return QAbstractItemModel::flags(index);
135 }
136 
137 
headerData(int section,Qt::Orientation orientation,int role) const138 QVariant SnifferModel::headerData(int section, Qt::Orientation orientation, int role) const
139 {
140     if (orientation == Qt::Horizontal && role == Qt::DisplayRole)
141     {
142         switch(section)
143         {
144             case tc::DELTA:
145                 return QString("Delta");
146             case tc::ID:
147                 return QString("ID");
148             default:
149                 break;
150         }
151         if(tc::DATA_0<=section && section <=tc::DATA_7)
152             return QString::number(section-tc::DATA_0);
153     }
154 
155     return QVariant();
156 }
157 
158 
index(int row,int column,const QModelIndex & parent) const159 QModelIndex SnifferModel::index(int row, int column, const QModelIndex &parent) const
160 {
161     if (parent.isValid())
162         return QModelIndex();
163 
164     const QMap<quint32, SnifferItem*>& map = mFilter ? mFilters : mMap;
165 
166     if(column>tc::LAST || row>=map.size())
167         return QModelIndex();
168 
169     /* ugly but I can't find best without creating a list to keep indexes */
170     QMap<quint32, SnifferItem*>::const_iterator iter;
171     int i;
172     for(iter = map.begin(), i=0 ; i<row ; ++i, ++iter);
173 
174     return createIndex(row, column, iter.value());
175 }
176 
177 
parent(const QModelIndex &) const178 QModelIndex SnifferModel::parent(const QModelIndex &) const
179 {
180     return QModelIndex();
181 }
182 
getNeverExpire()183 bool SnifferModel::getNeverExpire()
184 {
185     return mNeverExpire;
186 }
187 
getFadeInactive()188 bool SnifferModel::getFadeInactive()
189 {
190     return mFadeInactive;
191 }
192 
getMuteNotched()193 bool SnifferModel::getMuteNotched()
194 {
195     return mMuteNotched;
196 }
197 
setNeverExpire(bool val)198 void SnifferModel::setNeverExpire(bool val)
199 {
200     mNeverExpire = val;
201 }
202 
setFadeInactive(bool val)203 void SnifferModel::setFadeInactive(bool val)
204 {
205     mFadeInactive = val;
206 }
207 
setMuteNotched(bool val)208 void SnifferModel::setMuteNotched(bool val)
209 {
210     mMuteNotched = val;
211 }
212 
clear()213 void SnifferModel::clear()
214 {
215     beginResetModel();
216     qDeleteAll(mMap);
217     mMap.clear();
218     mFilters.clear();
219     mFilter = false;
220     endResetModel();
221 }
222 
223 //Called from window with a timer (currently 200ms)
refresh()224 void SnifferModel::refresh()
225 {
226     QMap<quint32, SnifferItem*>::iterator i;
227     QVector<quint32> toRemove;
228     SnifferItem* item;
229 
230     mTimeSequence++;
231 
232     /* update markers */
233 
234 
235     for (i = mMap.begin(); i != mMap.end(); ++i)
236     {
237         i.value()->updateMarker();
238         if(i.value()->elapsed()>5000 && !mNeverExpire)
239             toRemove.append(i.key());
240     }
241 
242     if(toRemove.size())
243     {
244         beginResetModel();
245         foreach(quint32 id, toRemove)
246         {
247             /* remove element */
248             item = mMap.take(id);
249             mFilters.remove(id);
250             delete item;
251             /* send notification */
252             emit idChange(id, false);
253         }
254         endResetModel();
255     }
256     else
257         /* refresh data */
258         dataChanged(createIndex(0, 0),
259                     createIndex(rowCount()-1, columnCount()-1), QVector<int>(Qt::DisplayRole));
260 }
261 
262 
filter(fltType pType,int pId)263 void SnifferModel::filter(fltType pType, int pId)
264 {
265     beginResetModel();
266     switch(pType)
267     {
268         case fltType::NONE:
269             /* erase everything */
270             mFilter = true;
271             mFilters.clear();
272             break;
273         case fltType::ADD:
274             /* add filter to list */
275             mFilter = true;
276             mFilters[pId] = mMap[pId];
277             break;
278         case fltType::REMOVE:
279             /* remove filter */
280             if(!mFilter)
281                 mFilters = mMap;
282             mFilter = true;
283             mFilters.remove(pId);
284             break;
285         case fltType::ALL:
286             /* stop filtering */
287             mFilter = false;
288             mFilters.clear();
289             break;
290     }
291     endResetModel();
292 }
293 
294 
295 /***********************************************/
296 /**********         slots       ****************/
297 /***********************************************/
298 
update(CANConnection *,QVector<CANFrame> & pFrames)299 void SnifferModel::update(CANConnection*, QVector<CANFrame>& pFrames)
300 {
301     foreach(const CANFrame& frame, pFrames)
302     {
303         if(!mMap.contains(frame.frameId()))
304         {
305             int index = std::distance(mMap.begin(), mMap.lowerBound(frame.frameId()));
306             /* add the frame */
307             beginInsertRows(QModelIndex(), index, index);
308             mMap[frame.frameId()] = new SnifferItem(frame, mTimeSequence);
309             mMap[frame.frameId()]->update(frame, mTimeSequence, mMuteNotched);
310             endInsertRows();
311 
312             emit idChange(frame.frameId(), true);
313         }
314         else
315             //updateData
316             mMap[frame.frameId()]->update(frame, mTimeSequence, mMuteNotched);
317     }
318 }
319 
notch()320 void SnifferModel::notch()
321 {
322     QMap<quint32, SnifferItem*>& map = mFilter ? mFilters : mMap;
323 
324     foreach(SnifferItem* item, map)
325         item->notch(true);
326 }
327 
unNotch()328 void SnifferModel::unNotch()
329 {
330     QMap<quint32, SnifferItem*>& map = mFilter ? mFilters : mMap;
331 
332     foreach(SnifferItem* item, map)
333         item->notch(false);
334 }
335 
336 
337