22 #include <QApplication> 24 #include <QFontMetrics> 25 #include <QInputDialog> 28 #include <QPushButton> 29 #include <QScrollArea> 30 #include <QVBoxLayout> 35 #include <libsigrokdecode/libsigrokdecode.h> 38 #define DECODERS_HAVE_TAGS \ 39 ((SRD_PACKAGE_VERSION_MAJOR > 0) || \ 40 (SRD_PACKAGE_VERSION_MAJOR == 0) && (SRD_PACKAGE_VERSION_MINOR > 5)) 45 namespace subwindows {
46 namespace decoder_selector {
49 QT_TRANSLATE_NOOP(
"pv::subwindows::decoder_selector::SubWindow",
50 "Select a decoder to see its description here.");
56 const QModelIndex& source_parent)
const 60 if (QSortFilterProxyModel::filterAcceptsRow(source_row, source_parent))
63 const QModelIndex index = sourceModel()->index(source_row, 0, source_parent);
65 for (
int i = 0; i < sourceModel()->rowCount(index); i++)
74 const QModelIndex& previous)
76 QTreeView::currentChanged(current, previous);
78 current_changed(current);
84 splitter_(new QSplitter()),
86 info_box_(new QWidget()),
87 info_label_header_(new QLabel()),
88 info_label_body_(new QLabel()),
89 info_label_footer_(new QLabel()),
93 QVBoxLayout* root_layout =
new QVBoxLayout(
this);
94 root_layout->setContentsMargins(0, 0, 0, 0);
97 QWidget* upper_container =
new QWidget();
98 QVBoxLayout* upper_layout =
new QVBoxLayout(upper_container);
99 upper_layout->setContentsMargins(0, 5, 0, 0);
100 QLineEdit* filter =
new QLineEdit();
101 upper_layout->addWidget(filter);
108 const QIcon filter_icon(QIcon::fromTheme(
"search",
109 QIcon(
":/icons/search.svg")));
110 filter->setClearButtonEnabled(
true);
111 filter->addAction(filter_icon, QLineEdit::LeadingPosition);
122 tree_view_->sortByColumn(0, Qt::AscendingOrder);
132 #if (!DECODERS_HAVE_TAGS) 139 info_label_body_container->setWidgetResizable(
true);
141 info_box_->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
142 QVBoxLayout* info_box_layout =
new QVBoxLayout(
info_box_);
144 info_box_layout->addWidget(info_label_body_container);
146 info_box_layout->setAlignment(Qt::AlignTop);
147 Qt::TextInteractionFlags flags = Qt::TextSelectableByMouse | Qt::TextSelectableByKeyboard;
157 connect(filter, SIGNAL(textChanged(
const QString&)),
159 connect(filter, SIGNAL(returnPressed()),
162 connect(
tree_view_, SIGNAL(current_changed(
const QModelIndex&)),
164 connect(
tree_view_, SIGNAL(activated(
const QModelIndex&)),
168 &session, SLOT(on_new_decoders_selected(vector<const srd_decoder*>)));
196 vector<const char*> ret_val;
198 for (GSList* li = d->inputs; li; li = li->next)
199 ret_val.push_back((
const char*)li->data);
206 vector<const srd_decoder*> ret_val;
208 for (GSList* li = (GSList*)srd_decoder_list(); li; li = li->next) {
209 const srd_decoder* d = (srd_decoder*)li->data;
215 const int maxlen = 1024;
218 if (strncmp((
char*)(d->outputs->data), output, maxlen) == 0)
219 ret_val.push_back(d);
227 QString decoder_name, id, longname, desc, doc, tags;
230 if (index.isValid() && index.parent().isValid()) {
231 QModelIndex id_index = index.model()->index(index.row(), 2, index.parent());
232 decoder_name = index.model()->data(id_index, Qt::DisplayRole).toString();
234 if (decoder_name.isEmpty())
237 const srd_decoder* d = srd_decoder_get_by_id(decoder_name.toUtf8());
239 id = QString::fromUtf8(d->id);
240 longname = QString::fromUtf8(d->longname);
241 desc = QString::fromUtf8(d->desc);
242 doc = QString::fromUtf8(srd_decoder_doc_get(d)).trimmed();
244 #if DECODERS_HAVE_TAGS 245 for (GSList* li = (GSList*)d->tags; li; li = li->next) {
246 QString s = (li == (GSList*)d->tags) ?
247 tr((
char*)li->data) :
248 QString(tr(
", %1")).arg(tr((
char*)li->data));
253 doc = QString(tr(initial_notice));
257 QString(
"<span style='font-size:large'><b>%1 (%2)</b></span><br><i>%3</i>")
258 .arg(longname,
id, desc));
272 if (!index.isValid())
275 QModelIndex id_index = index.model()->index(index.row(), 2, index.parent());
276 QString decoder_name = index.model()->data(id_index, Qt::DisplayRole).toString();
278 const srd_decoder* chosen_decoder = srd_decoder_get_by_id(decoder_name.toUtf8());
279 if (chosen_decoder ==
nullptr)
282 vector<const srd_decoder*> decoders;
283 decoders.push_back(chosen_decoder);
287 if (inputs.size() == 0) {
288 qWarning() <<
"Protocol decoder" << decoder_name <<
"cannot have 0 inputs!";
292 if (strcmp(inputs.at(0),
"logic") == 0) {
298 while (strcmp(inputs.at(0),
"logic") != 0) {
301 if (prov_decoders.size() == 0) {
303 qWarning() <<
"Protocol decoder" << QString::fromUtf8(decoders.back()->id) \
304 <<
"has input that no other decoder provides:" << QString::fromUtf8(inputs.at(0));
308 if (prov_decoders.size() == 1) {
309 decoders.push_back(prov_decoders.front());
312 QString caption = QString(tr(
"Protocol decoder <b>%1</b> requires input type <b>%2</b> " \
313 "which several decoders provide.<br>Choose which one to use:<br>"))
314 .arg(QString::fromUtf8(decoders.back()->id), QString::fromUtf8(inputs.at(0)));
317 for (
const srd_decoder* d : prov_decoders)
318 items << QString::fromUtf8(d->id) +
" (" + QString::fromUtf8(d->longname) +
")";
320 QString item = QInputDialog::getItem(
this, tr(
"Choose Decoder"),
321 tr(caption.toUtf8()), items, 0,
false, &ok_clicked);
323 if ((!ok_clicked) || (item.isEmpty()))
326 QString d = item.section(
' ', 0, 0);
327 decoders.push_back(srd_decoder_get_by_id(d.toUtf8()));
334 reverse(decoders.begin(), decoders.end());
348 int num_visible_decoders = 0;
349 QModelIndex last_valid_index;
351 QModelIndex index =
tree_view_->model()->index(0, 0);
353 while (index.isValid()) {
354 QModelIndex id_index = index.model()->index(index.row(), 2, index.parent());
355 QString decoder_name = index.model()->data(id_index, Qt::DisplayRole).toString();
356 if (!decoder_name.isEmpty()) {
357 last_valid_index = index;
358 num_visible_decoders++;
364 if (num_visible_decoders == 1)
void on_filter_return_pressed()
void on_filter_changed(const QString &text)
void on_item_activated(const QModelIndex &index)
void on_item_changed(const QModelIndex &index)
QLabel * info_label_body_
QLabel * info_label_footer_
std::streamsize text_width(const QFontMetrics &metric, const QString &string)
void currentChanged(const QModelIndex ¤t, const QModelIndex &previous)
QCustomTreeView * tree_view_
bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const
DecoderCollectionModel * model_
SubWindow(Session &session, QWidget *parent=nullptr)
QCustomSortFilterProxyModel * sort_filter_model_
QLabel * info_label_header_
QToolBar * create_toolbar(QWidget *parent) const
void new_decoders_selected(vector< const srd_decoder * > decoders)
int minimum_width() const
const int min_width_margin
vector< const srd_decoder * > get_decoders_providing(const char *output) const
vector< const char * > get_decoder_inputs(const srd_decoder *d) const
const char * initial_notice