]> sigrok.org Git - pulseview.git/blob - pv/subwindows/decoder_selector/model.cpp
31dfd464bf6d07044e5a417f92baeab6dbce960a
[pulseview.git] / pv / subwindows / decoder_selector / model.cpp
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
26 using std::make_shared;
27
28 namespace pv {
29 namespace subwindows {
30 namespace decoder_selector {
31
32 DecoderCollectionModel::DecoderCollectionModel(QObject* parent) :
33         QAbstractItemModel(parent)
34 {
35         vector<QVariant> header_data;
36         header_data.emplace_back(tr("Decoder"));     // Column #0
37         header_data.emplace_back(tr("Name"));        // Column #1
38         header_data.emplace_back(tr("ID"));          // Column #2
39         root_ = make_shared<DecoderCollectionItem>(header_data);
40
41         // Note: the tag groups are sub-items of the root item
42
43         // Create "all decoders" group
44         vector<QVariant> item_data;
45         item_data.emplace_back(tr("All Decoders"));
46         // Add dummy entries to make the row count the same as the
47         // sub-item size, or else we can't query sub-item data
48         item_data.emplace_back();
49         item_data.emplace_back();
50         shared_ptr<DecoderCollectionItem> group_item_all =
51                 make_shared<DecoderCollectionItem>(item_data, root_);
52         root_->appendSubItem(group_item_all);
53
54         for (GSList* li = (GSList*)srd_decoder_list(); li; li = li->next) {
55                 const srd_decoder *const d = (srd_decoder*)li->data;
56                 assert(d);
57
58                 const QString id = QString::fromUtf8(d->id);
59                 const QString name = QString::fromUtf8(d->name);
60                 const QString long_name = QString::fromUtf8(d->longname);
61
62                 // Add decoder to the "all decoders" group
63                 item_data.clear();
64                 item_data.emplace_back(name);
65                 item_data.emplace_back(long_name);
66                 item_data.emplace_back(id);
67                 shared_ptr<DecoderCollectionItem> decoder_item_all =
68                         make_shared<DecoderCollectionItem>(item_data, group_item_all);
69                 group_item_all->appendSubItem(decoder_item_all);
70
71                 // Add decoder to all relevant groups using the tag information
72                 for (GSList* ti = (GSList*)d->tags; ti; ti = ti->next) {
73                         const QString tag = tr((char*)ti->data);
74                         const QVariant tag_var = QVariant(tag);
75
76                         // Find tag group and create it if it doesn't exist yet
77                         shared_ptr<DecoderCollectionItem> group_item =
78                                 root_->findSubItem(tag_var, 0);
79
80                         if (!group_item) {
81                                 item_data.clear();
82                                 item_data.emplace_back(tag);
83                                 // Add dummy entries to make the row count the same as the
84                                 // sub-item size, or else we can't query sub-item data
85                                 item_data.emplace_back();
86                                 item_data.emplace_back();
87                                 group_item = make_shared<DecoderCollectionItem>(item_data, root_);
88                                 root_->appendSubItem(group_item);
89                         }
90
91                         // Create decoder item
92                         item_data.clear();
93                         item_data.emplace_back(name);
94                         item_data.emplace_back(long_name);
95                         item_data.emplace_back(id);
96                         shared_ptr<DecoderCollectionItem> decoder_item =
97                                 make_shared<DecoderCollectionItem>(item_data, group_item);
98
99                         // Add decoder to tag group
100                         group_item->appendSubItem(decoder_item);
101                 }
102         }
103 }
104
105 QVariant DecoderCollectionModel::data(const QModelIndex& index, int role) const
106 {
107         if (!index.isValid())
108                 return QVariant();
109
110         if (role != Qt::DisplayRole)
111                 return QVariant();
112
113         DecoderCollectionItem* item =
114                 static_cast<DecoderCollectionItem*>(index.internalPointer());
115
116         return item->data(index.column());
117 }
118
119 Qt::ItemFlags DecoderCollectionModel::flags(const QModelIndex& index) const
120 {
121         if (!index.isValid())
122                 return 0;
123
124         return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
125 }
126
127 QVariant DecoderCollectionModel::headerData(int section, Qt::Orientation orientation,
128         int role) const
129 {
130         if (orientation == Qt::Horizontal && role == Qt::DisplayRole)
131                 return root_->data(section);
132
133         return QVariant();
134 }
135
136 QModelIndex DecoderCollectionModel::index(int row, int column,
137         const QModelIndex& parent_idx) const
138 {
139         if (!hasIndex(row, column, parent_idx))
140                 return QModelIndex();
141
142         DecoderCollectionItem* parent = root_.get();
143
144         if (parent_idx.isValid())
145                 parent = static_cast<DecoderCollectionItem*>(parent_idx.internalPointer());
146
147         DecoderCollectionItem* subItem = parent->subItem(row).get();
148
149         return subItem ? createIndex(row, column, subItem) : QModelIndex();
150 }
151
152 QModelIndex DecoderCollectionModel::parent(const QModelIndex& index) const
153 {
154         if (!index.isValid())
155                 return QModelIndex();
156
157         DecoderCollectionItem* subItem =
158                 static_cast<DecoderCollectionItem*>(index.internalPointer());
159
160         shared_ptr<DecoderCollectionItem> parent = subItem->parent();
161
162         return (parent == root_) ? QModelIndex() :
163                 createIndex(parent->row(), 0, parent.get());
164 }
165
166 int DecoderCollectionModel::rowCount(const QModelIndex& parent_idx) const
167 {
168         DecoderCollectionItem* parent = root_.get();
169
170         if (parent_idx.column() > 0)
171                 return 0;
172
173         if (parent_idx.isValid())
174                 parent = static_cast<DecoderCollectionItem*>(parent_idx.internalPointer());
175
176         return parent->subItemCount();
177 }
178
179 int DecoderCollectionModel::columnCount(const QModelIndex& parent_idx) const
180 {
181         if (parent_idx.isValid())
182                 return static_cast<DecoderCollectionItem*>(
183                         parent_idx.internalPointer())->columnCount();
184         else
185                 return root_->columnCount();
186 }
187
188
189 } // namespace decoder_selector
190 } // namespace subwindows
191 } // namespace pv