X-Git-Url: https://sigrok.org/gitweb/?p=pulseview.git;a=blobdiff_plain;f=pv%2Fprop%2Fint.cpp;h=2930a3ea1e8c96b5d0091e6c2b640050ecb5d09f;hp=502665daf4035a8e473b356bb17ebead87c2ef56;hb=b0e15aa24c0ea7adcc3acf2581728b9d29e7ba09;hpb=a2b921574b467fd9193d06497bf0ee058e8f7470 diff --git a/pv/prop/int.cpp b/pv/prop/int.cpp index 502665da..2930a3ea 100644 --- a/pv/prop/int.cpp +++ b/pv/prop/int.cpp @@ -14,62 +14,149 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * along with this program; if not, see . */ -#include +#include +#include #include -#include "int.h" +#include "int.hpp" -using namespace std; -using namespace boost; +using boost::optional; +using std::max; +using std::min; +using std::pair; namespace pv { namespace prop { Int::Int(QString name, + QString desc, QString suffix, optional< pair > range, Getter getter, Setter setter) : - Property(name, getter, setter), - _suffix(suffix), - _range(range), - _spin_box(NULL) + Property(name, desc, getter, setter), + suffix_(suffix), + range_(range), + spin_box_(nullptr) { } -QWidget* Int::get_widget(QWidget *parent) +QWidget* Int::get_widget(QWidget *parent, bool auto_commit) { - if (_spin_box) - return _spin_box; - - _spin_box = new QSpinBox(parent); - _spin_box->setSuffix(_suffix); - if (_range) - _spin_box->setRange((int)_range->first, (int)_range->second); - - GVariant *const value = _getter ? _getter() : NULL; - if (value) { - _spin_box->setValue((int)g_variant_get_int64(value)); - g_variant_unref(value); + int64_t int_val = 0, range_min = 0; + uint64_t range_max = 0; + + if (spin_box_) + return spin_box_; + + if (!getter_) + return nullptr; + + value_ = getter_(); + + GVariant *value = value_.gobj(); + if (!value) + return nullptr; + + spin_box_ = new QSpinBox(parent); + spin_box_->setSuffix(suffix_); + + const GVariantType *const type = g_variant_get_type(value); + assert(type); + + if (g_variant_type_equal(type, G_VARIANT_TYPE_BYTE)) { + int_val = g_variant_get_byte(value); + range_min = 0, range_max = UINT8_MAX; + } else if (g_variant_type_equal(type, G_VARIANT_TYPE_INT16)) { + int_val = g_variant_get_int16(value); + range_min = INT16_MIN, range_max = INT16_MAX; + } else if (g_variant_type_equal(type, G_VARIANT_TYPE_UINT16)) { + int_val = g_variant_get_uint16(value); + range_min = 0, range_max = UINT16_MAX; + } else if (g_variant_type_equal(type, G_VARIANT_TYPE_INT32)) { + int_val = g_variant_get_int32(value); + range_min = INT32_MIN, range_max = INT32_MAX; + } else if (g_variant_type_equal(type, G_VARIANT_TYPE_UINT32)) { + int_val = g_variant_get_uint32(value); + range_min = 0, range_max = UINT32_MAX; + } else if (g_variant_type_equal(type, G_VARIANT_TYPE_INT64)) { + int_val = g_variant_get_int64(value); + range_min = INT64_MIN, range_max = INT64_MAX; + } else if (g_variant_type_equal(type, G_VARIANT_TYPE_UINT64)) { + int_val = g_variant_get_uint64(value); + range_min = 0, range_max = UINT64_MAX; + } else { + // Unexpected value type. + assert(false); } - return _spin_box; + // @todo sigrok supports 64-bit quantities, but Qt does not have a + // standard widget to allow the values to be modified over the full + // 64-bit range on 32-bit machines. To solve the issue we need a + // custom widget. + + range_min = max(range_min, (int64_t)INT_MIN); + range_max = min(range_max, (uint64_t)INT_MAX); + + if (range_) + spin_box_->setRange((int)range_->first, (int)range_->second); + else + spin_box_->setRange((int)range_min, (int)range_max); + + spin_box_->setValue((int)int_val); + + if (auto_commit) + connect(spin_box_, SIGNAL(valueChanged(int)), + this, SLOT(on_value_changed(int))); + + return spin_box_; } void Int::commit() { - assert(_setter); + assert(setter_); - if (!_spin_box) + if (!spin_box_) return; - _setter(g_variant_new_int64(_spin_box->value())); + GVariant *new_value = nullptr; + const GVariantType *const type = g_variant_get_type(value_.gobj()); + assert(type); + + if (g_variant_type_equal(type, G_VARIANT_TYPE_BYTE)) + new_value = g_variant_new_byte(spin_box_->value()); + else if (g_variant_type_equal(type, G_VARIANT_TYPE_INT16)) + new_value = g_variant_new_int16(spin_box_->value()); + else if (g_variant_type_equal(type, G_VARIANT_TYPE_UINT16)) + new_value = g_variant_new_uint16(spin_box_->value()); + else if (g_variant_type_equal(type, G_VARIANT_TYPE_INT32)) + new_value = g_variant_new_int32(spin_box_->value()); + else if (g_variant_type_equal(type, G_VARIANT_TYPE_UINT32)) + new_value = g_variant_new_uint32(spin_box_->value()); + else if (g_variant_type_equal(type, G_VARIANT_TYPE_INT64)) + new_value = g_variant_new_int64(spin_box_->value()); + else if (g_variant_type_equal(type, G_VARIANT_TYPE_UINT64)) + new_value = g_variant_new_uint64(spin_box_->value()); + else { + // Unexpected value type. + assert(false); + } + + assert(new_value); + + value_ = Glib::VariantBase(new_value); + + setter_(value_); +} + +void Int::on_value_changed(int) +{ + commit(); } -} // prop -} // pv +} // namespace prop +} // namespace pv