PulseView  unreleased development snapshot
A Qt-based sigrok GUI
sweeptimingwidget.cpp
Go to the documentation of this file.
1 /*
2  * This file is part of the PulseView project.
3  *
4  * Copyright (C) 2013 Joel Holdsworth <joel@airwebreathe.org.uk>
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 "sweeptimingwidget.hpp"
21 
22 #include <cassert>
23 #include <cstdlib>
24 #include <vector>
25 
26 #include <extdef.h>
27 
28 using std::abs;
29 using std::vector;
30 
31 namespace pv {
32 namespace widgets {
33 
35  QWidget *parent) :
36  QWidget(parent),
37  suffix_(suffix),
38  layout_(this),
39  value_(this),
40  list_(this),
41  value_type_(None)
42 {
43  setContentsMargins(0, 0, 0, 0);
44 
45  value_.setDecimals(0);
46  value_.setSuffix(QString::fromUtf8(suffix));
47 
48  connect(&list_, SIGNAL(currentIndexChanged(int)),
49  this, SIGNAL(value_changed()));
50  connect(&list_, SIGNAL(editTextChanged(const QString&)),
51  this, SIGNAL(value_changed()));
52 
53  connect(&value_, SIGNAL(editingFinished()),
54  this, SIGNAL(value_changed()));
55 
56  setLayout(&layout_);
57 #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
58  layout_.setContentsMargins(0, 0, 0, 0);
59 #else
60  layout_.setMargin(0);
61 #endif
62  layout_.addWidget(&list_);
63  layout_.addWidget(&value_);
64 
65  show_none();
66 }
67 
69 {
70  list_.setEditable(value);
71 }
72 
74 {
75  value_type_ = None;
76  value_.hide();
77  list_.hide();
78 }
79 
81  uint64_t step)
82 {
83  assert(max > min);
84  assert(step > 0);
85 
87 
88  value_.setRange(min, max);
89  value_.setSingleStep(step);
90 
91  value_.show();
92  list_.hide();
93 }
94 
95 void SweepTimingWidget::show_list(const uint64_t *vals, size_t count)
96 {
97  value_type_ = List;
98 
99  list_.clear();
100  for (size_t i = 0; i < count; i++) {
101  char *const s = sr_si_string_u64(vals[i], suffix_);
102  list_.addItem(QString::fromUtf8(s), QVariant::fromValue(vals[i]));
103  g_free(s);
104  }
105 
106  value_.hide();
107  list_.show();
108 }
109 
110 void SweepTimingWidget::show_125_list(uint64_t min, uint64_t max)
111 {
112  assert(max > min);
113 
114  // Create a 1-2-5-10 list of entries.
115  const unsigned int FineScales[] = {1, 2, 5};
116  uint64_t value, decade;
117  unsigned int fine;
118  vector<uint64_t> values;
119 
120  // Compute the starting decade
121  for (decade = 1; decade * 10 <= min; decade *= 10);
122 
123  // Compute the first entry
124  for (fine = 0; fine < countof(FineScales); fine++)
125  if (FineScales[fine] * decade >= min)
126  break;
127 
128  assert(fine < countof(FineScales));
129 
130  // Add the minimum entry if it's not on the 1-2-5 progression
131  if (min != FineScales[fine] * decade)
132  values.push_back(min);
133 
134  while ((value = FineScales[fine] * decade) < max) {
135  values.push_back(value);
136  if (++fine >= countof(FineScales))
137  fine = 0, decade *= 10;
138  }
139 
140  // Add the max value
141  values.push_back(max);
142 
143  // Make a C array, and give it to the sweep timing widget
144  uint64_t *const values_array = new uint64_t[values.size()];
145  copy(values.begin(), values.end(), values_array);
146  show_list(values_array, values.size());
147  delete[] values_array;
148 }
149 
150 uint64_t SweepTimingWidget::value() const
151 {
152  switch (value_type_) {
153  case None:
154  return 0;
155  case MinMaxStep:
156  return (uint64_t)value_.value();
157  case List:
158  {
159  if (list_.isEditable()) {
160  uint64_t value;
161  sr_parse_sizestring(list_.currentText().toUtf8().data(), &value);
162  return value;
163  }
164 
165  const int index = list_.currentIndex();
166  return (index >= 0) ? list_.itemData(index).value<uint64_t>() : 0;
167  }
168  default:
169  // Unexpected value type
170  assert(false);
171  return 0;
172  }
173 }
174 
176 {
177  value_.setValue(value);
178 
179  if (list_.isEditable()) {
180  char *const s = sr_si_string_u64(value, suffix_);
181  list_.lineEdit()->setText(QString::fromUtf8(s));
182  g_free(s);
183  } else {
184  int best_match = list_.count() - 1;
185  int64_t best_variance = INT64_MAX;
186 
187  for (int i = 0; i < list_.count(); i++) {
188  const int64_t this_variance = abs(
189  (int64_t)value - list_.itemData(i).value<int64_t>());
190  if (this_variance < best_variance) {
191  best_variance = this_variance;
192  best_match = i;
193  }
194  }
195 
196  list_.setCurrentIndex(best_match);
197  }
198 }
199 
200 } // namespace widgets
201 } // namespace pv
void show_list(const uint64_t *vals, size_t count)
SweepTimingWidget(const char *suffix, QWidget *parent=nullptr)
T max(const T v0, const T v1)
Definition: exprtk.hpp:1411
void show_125_list(uint64_t min, uint64_t max)
T min(const T v0, const T v1)
Definition: exprtk.hpp:1404
#define countof(x)
Definition: extdef.h:23
void show_min_max_step(uint64_t min, uint64_t max, uint64_t step)
it will come up with a session that has the demo device selected That you can get to know the program even when you don t have any hardware to use it you see a list of devices PulseView has recognized If the device you want to use is you can just select it here image::device_selector_dropdown png[] If it s not you ll need to scan for it first Since most serial port and Ethernet devices can t be auto this is usually required for those To do either choose the Connect to Device option from the list or click on the button itself You will see the following you ll need to pick a driver that you want to use In order to do this
Definition: acquisition.txt:14
void allow_user_entered_values(bool value)