]> sigrok.org Git - pulseview.git/blob - pv/subwindows/decoder_selector/model.cpp
DecoderSelector: Make PD names italic
[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         {
112                 DecoderCollectionItem* item =
113                         static_cast<DecoderCollectionItem*>(index.internalPointer());
114
115                 return item->data(index.column());
116         }
117
118         if ((role == Qt::FontRole) && (index.parent().isValid()) && (index.column() == 0))
119         {
120                 QFont font;
121                 font.setItalic(true);
122                 return QVariant(font);
123         }
124
125         return QVariant();
126 }
127
128 Qt::ItemFlags DecoderCollectionModel::flags(const QModelIndex& index) const
129 {
130         if (!index.isValid())
131                 return 0;
132
133         return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
134 }
135
136 QVariant DecoderCollectionModel::headerData(int section, Qt::Orientation orientation,
137         int role) const
138 {
139         if (orientation == Qt::Horizontal && role == Qt::DisplayRole)
140                 return root_->data(section);
141
142         return QVariant();
143 }
144
145 QModelIndex DecoderCollectionModel::index(int row, int column,
146         const QModelIndex& parent_idx) const
147 {
148         if (!hasIndex(row, column, parent_idx))
149                 return QModelIndex();
150
151         DecoderCollectionItem* parent = root_.get();
152
153         if (parent_idx.isValid())
154                 parent = static_cast<DecoderCollectionItem*>(parent_idx.internalPointer());
155
156         DecoderCollectionItem* subItem = parent->subItem(row).get();
157
158         return subItem ? createIndex(row, column, subItem) : QModelIndex();
159 }
160
161 QModelIndex DecoderCollectionModel::parent(const QModelIndex& index) const
162 {
163         if (!index.isValid())
164                 return QModelIndex();
165
166         DecoderCollectionItem* subItem =
167                 static_cast<DecoderCollectionItem*>(index.internalPointer());
168
169         shared_ptr<DecoderCollectionItem> parent = subItem->parent();
170
171         return (parent == root_) ? QModelIndex() :
172                 createIndex(parent->row(), 0, parent.get());
173 }
174
175 int DecoderCollectionModel::rowCount(const QModelIndex& parent_idx) const
176 {
177         DecoderCollectionItem* parent = root_.get();
178
179         if (parent_idx.column() > 0)
180                 return 0;
181
182         if (parent_idx.isValid())
183                 parent = static_cast<DecoderCollectionItem*>(parent_idx.internalPointer());
184
185         return parent->subItemCount();
186 }
187
188 int DecoderCollectionModel::columnCount(const QModelIndex& parent_idx) const
189 {
190         if (parent_idx.isValid())
191                 return static_cast<DecoderCollectionItem*>(
192                         parent_idx.internalPointer())->columnCount();
193         else
194                 return root_->columnCount();
195 }
196
197
198 } // namespace decoder_selector
199 } // namespace subwindows
200 } // namespace pv