2 * This file is part of the PulseView project.
4 * Copyright (C) 2018 Soeren Apel <soeren@apelpie.net>
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.
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.
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/>.
22 #include "subwindow.hpp"
24 #include <libsigrokdecode/libsigrokdecode.h>
26 using std::make_shared;
29 namespace subwindows {
30 namespace decoder_selector {
32 DecoderCollectionModel::DecoderCollectionModel(QObject* parent) :
33 QAbstractItemModel(parent)
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);
41 // Note: the tag groups are sub-items of the root item
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);
54 GSList* l = g_slist_copy((GSList*)srd_decoder_list());
55 for (GSList* li = l; li; li = li->next) {
56 const srd_decoder *const d = (srd_decoder*)li->data;
59 const QString id = QString::fromUtf8(d->id);
60 const QString name = QString::fromUtf8(d->name);
61 const QString long_name = QString::fromUtf8(d->longname);
63 // Add decoder to the "all decoders" group
65 item_data.emplace_back(name);
66 item_data.emplace_back(long_name);
67 item_data.emplace_back(id);
68 shared_ptr<DecoderCollectionItem> decoder_item_all =
69 make_shared<DecoderCollectionItem>(item_data, group_item_all);
70 group_item_all->appendSubItem(decoder_item_all);
72 // Add decoder to all relevant groups using the tag information
73 GSList* t = g_slist_copy((GSList*)d->tags);
74 for (GSList* ti = t; ti; ti = ti->next) {
75 const QString tag = tr((char*)ti->data);
76 const QVariant tag_var = QVariant(tag);
78 // Find tag group and create it if it doesn't exist yet
79 shared_ptr<DecoderCollectionItem> group_item =
80 root_->findSubItem(tag_var, 0);
84 item_data.emplace_back(tag);
85 // Add dummy entries to make the row count the same as the
86 // sub-item size, or else we can't query sub-item data
87 item_data.emplace_back();
88 item_data.emplace_back();
89 group_item = make_shared<DecoderCollectionItem>(item_data, root_);
90 root_->appendSubItem(group_item);
93 // Create decoder item
95 item_data.emplace_back(name);
96 item_data.emplace_back(long_name);
97 item_data.emplace_back(id);
98 shared_ptr<DecoderCollectionItem> decoder_item =
99 make_shared<DecoderCollectionItem>(item_data, group_item);
101 // Add decoder to tag group
102 group_item->appendSubItem(decoder_item);
109 QVariant DecoderCollectionModel::data(const QModelIndex& index, int role) const
111 if (!index.isValid())
114 if (role != Qt::DisplayRole)
117 DecoderCollectionItem* item =
118 static_cast<DecoderCollectionItem*>(index.internalPointer());
120 return item->data(index.column());
123 Qt::ItemFlags DecoderCollectionModel::flags(const QModelIndex& index) const
125 if (!index.isValid())
128 return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
131 QVariant DecoderCollectionModel::headerData(int section, Qt::Orientation orientation,
134 if (orientation == Qt::Horizontal && role == Qt::DisplayRole)
135 return root_->data(section);
140 QModelIndex DecoderCollectionModel::index(int row, int column,
141 const QModelIndex& parent_idx) const
143 if (!hasIndex(row, column, parent_idx))
144 return QModelIndex();
146 DecoderCollectionItem* parent = root_.get();
148 if (parent_idx.isValid())
149 parent = static_cast<DecoderCollectionItem*>(parent_idx.internalPointer());
151 DecoderCollectionItem* subItem = parent->subItem(row).get();
153 return subItem ? createIndex(row, column, subItem) : QModelIndex();
156 QModelIndex DecoderCollectionModel::parent(const QModelIndex& index) const
158 if (!index.isValid())
159 return QModelIndex();
161 DecoderCollectionItem* subItem =
162 static_cast<DecoderCollectionItem*>(index.internalPointer());
164 shared_ptr<DecoderCollectionItem> parent = subItem->parent();
166 return (parent == root_) ? QModelIndex() :
167 createIndex(parent->row(), 0, parent.get());
170 int DecoderCollectionModel::rowCount(const QModelIndex& parent_idx) const
172 DecoderCollectionItem* parent = root_.get();
174 if (parent_idx.column() > 0)
177 if (parent_idx.isValid())
178 parent = static_cast<DecoderCollectionItem*>(parent_idx.internalPointer());
180 return parent->subItemCount();
183 int DecoderCollectionModel::columnCount(const QModelIndex& parent_idx) const
185 if (parent_idx.isValid())
186 return static_cast<DecoderCollectionItem*>(
187 parent_idx.internalPointer())->columnCount();
189 return root_->columnCount();
193 } // namespace decoder_selector
194 } // namespace subwindows