]> sigrok.org Git - pulseview.git/blame - pv/subwindows/decoder_selector/model.cpp
Fix #1451 by only using decoder tags if they're available
[pulseview.git] / pv / subwindows / decoder_selector / model.cpp
CommitLineData
97378470
SA
1/*
2 * This file is part of the PulseView project.
3 *
4 * Copyright (C) 2018 Soeren Apel <soeren@apelpie.net>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, see <http://www.gnu.org/licenses/>.
18 */
19
20#include <QString>
21
22#include "subwindow.hpp"
23
24#include <libsigrokdecode/libsigrokdecode.h>
25
e3521261
SA
26#define DECODERS_HAVE_TAGS \
27 ((SRD_PACKAGE_VERSION_MAJOR > 0) || \
28 (SRD_PACKAGE_VERSION_MAJOR == 0) && (SRD_PACKAGE_VERSION_MINOR > 5))
29
97378470
SA
30using std::make_shared;
31
32namespace pv {
33namespace subwindows {
34namespace decoder_selector {
35
36DecoderCollectionModel::DecoderCollectionModel(QObject* parent) :
37 QAbstractItemModel(parent)
38{
39 vector<QVariant> header_data;
40 header_data.emplace_back(tr("Decoder")); // Column #0
41 header_data.emplace_back(tr("Name")); // Column #1
42 header_data.emplace_back(tr("ID")); // Column #2
43 root_ = make_shared<DecoderCollectionItem>(header_data);
44
45 // Note: the tag groups are sub-items of the root item
46
47 // Create "all decoders" group
48 vector<QVariant> item_data;
49 item_data.emplace_back(tr("All Decoders"));
50 // Add dummy entries to make the row count the same as the
51 // sub-item size, or else we can't query sub-item data
52 item_data.emplace_back();
53 item_data.emplace_back();
54 shared_ptr<DecoderCollectionItem> group_item_all =
55 make_shared<DecoderCollectionItem>(item_data, root_);
56 root_->appendSubItem(group_item_all);
57
486bcf01 58 for (GSList* li = (GSList*)srd_decoder_list(); li; li = li->next) {
97378470
SA
59 const srd_decoder *const d = (srd_decoder*)li->data;
60 assert(d);
61
62 const QString id = QString::fromUtf8(d->id);
63 const QString name = QString::fromUtf8(d->name);
64 const QString long_name = QString::fromUtf8(d->longname);
65
66 // Add decoder to the "all decoders" group
67 item_data.clear();
68 item_data.emplace_back(name);
69 item_data.emplace_back(long_name);
70 item_data.emplace_back(id);
71 shared_ptr<DecoderCollectionItem> decoder_item_all =
72 make_shared<DecoderCollectionItem>(item_data, group_item_all);
73 group_item_all->appendSubItem(decoder_item_all);
74
75 // Add decoder to all relevant groups using the tag information
e3521261 76#if DECODERS_HAVE_TAGS
486bcf01 77 for (GSList* ti = (GSList*)d->tags; ti; ti = ti->next) {
97378470
SA
78 const QString tag = tr((char*)ti->data);
79 const QVariant tag_var = QVariant(tag);
80
81 // Find tag group and create it if it doesn't exist yet
82 shared_ptr<DecoderCollectionItem> group_item =
83 root_->findSubItem(tag_var, 0);
84
85 if (!group_item) {
86 item_data.clear();
87 item_data.emplace_back(tag);
88 // Add dummy entries to make the row count the same as the
89 // sub-item size, or else we can't query sub-item data
90 item_data.emplace_back();
91 item_data.emplace_back();
92 group_item = make_shared<DecoderCollectionItem>(item_data, root_);
93 root_->appendSubItem(group_item);
94 }
95
96 // Create decoder item
97 item_data.clear();
98 item_data.emplace_back(name);
99 item_data.emplace_back(long_name);
100 item_data.emplace_back(id);
101 shared_ptr<DecoderCollectionItem> decoder_item =
102 make_shared<DecoderCollectionItem>(item_data, group_item);
103
104 // Add decoder to tag group
105 group_item->appendSubItem(decoder_item);
106 }
e3521261 107#endif
97378470 108 }
97378470
SA
109}
110
111QVariant DecoderCollectionModel::data(const QModelIndex& index, int role) const
112{
113 if (!index.isValid())
114 return QVariant();
115
edf9f6bb
SA
116 if (role == Qt::DisplayRole)
117 {
118 DecoderCollectionItem* item =
119 static_cast<DecoderCollectionItem*>(index.internalPointer());
97378470 120
edf9f6bb
SA
121 return item->data(index.column());
122 }
97378470 123
edf9f6bb
SA
124 if ((role == Qt::FontRole) && (index.parent().isValid()) && (index.column() == 0))
125 {
126 QFont font;
127 font.setItalic(true);
128 return QVariant(font);
129 }
130
131 return QVariant();
97378470
SA
132}
133
134Qt::ItemFlags DecoderCollectionModel::flags(const QModelIndex& index) const
135{
136 if (!index.isValid())
c409988b 137 return nullptr;
97378470
SA
138
139 return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
140}
141
142QVariant DecoderCollectionModel::headerData(int section, Qt::Orientation orientation,
143 int role) const
144{
145 if (orientation == Qt::Horizontal && role == Qt::DisplayRole)
146 return root_->data(section);
147
148 return QVariant();
149}
150
151QModelIndex DecoderCollectionModel::index(int row, int column,
152 const QModelIndex& parent_idx) const
153{
154 if (!hasIndex(row, column, parent_idx))
155 return QModelIndex();
156
157 DecoderCollectionItem* parent = root_.get();
158
159 if (parent_idx.isValid())
160 parent = static_cast<DecoderCollectionItem*>(parent_idx.internalPointer());
161
162 DecoderCollectionItem* subItem = parent->subItem(row).get();
163
164 return subItem ? createIndex(row, column, subItem) : QModelIndex();
165}
166
167QModelIndex DecoderCollectionModel::parent(const QModelIndex& index) const
168{
169 if (!index.isValid())
170 return QModelIndex();
171
172 DecoderCollectionItem* subItem =
173 static_cast<DecoderCollectionItem*>(index.internalPointer());
174
175 shared_ptr<DecoderCollectionItem> parent = subItem->parent();
176
177 return (parent == root_) ? QModelIndex() :
178 createIndex(parent->row(), 0, parent.get());
179}
180
181int DecoderCollectionModel::rowCount(const QModelIndex& parent_idx) const
182{
183 DecoderCollectionItem* parent = root_.get();
184
185 if (parent_idx.column() > 0)
186 return 0;
187
188 if (parent_idx.isValid())
189 parent = static_cast<DecoderCollectionItem*>(parent_idx.internalPointer());
190
191 return parent->subItemCount();
192}
193
194int DecoderCollectionModel::columnCount(const QModelIndex& parent_idx) const
195{
196 if (parent_idx.isValid())
197 return static_cast<DecoderCollectionItem*>(
198 parent_idx.internalPointer())->columnCount();
199 else
200 return root_->columnCount();
201}
202
203
204} // namespace decoder_selector
205} // namespace subwindows
206} // namespace pv