PulseView  0.3.0
A Qt-based sigrok GUI
int.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, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19  */
20 
21 #include <stdint.h>
22 #include <assert.h>
23 
24 #include <QSpinBox>
25 
26 #include "int.hpp"
27 
28 using boost::optional;
29 using std::max;
30 using std::min;
31 using std::pair;
32 
33 namespace pv {
34 namespace prop {
35 
36 Int::Int(QString name,
37  QString suffix,
38  optional< pair<int64_t, int64_t> > range,
39  Getter getter,
40  Setter setter) :
41  Property(name, getter, setter),
42  suffix_(suffix),
43  range_(range),
44  spin_box_(nullptr)
45 {
46 }
47 
49 {
50 }
51 
52 QWidget* Int::get_widget(QWidget *parent, bool auto_commit)
53 {
54  int64_t int_val = 0, range_min = 0;
55  uint64_t range_max = 0;
56 
57  if (spin_box_)
58  return spin_box_;
59 
60  if (!getter_)
61  return nullptr;
62 
63  value_ = getter_();
64 
65  GVariant *value = value_.gobj();
66  if (!value)
67  return nullptr;
68 
69  spin_box_ = new QSpinBox(parent);
70  spin_box_->setSuffix(suffix_);
71 
72  const GVariantType *const type = g_variant_get_type(value);
73  assert(type);
74 
75  if (g_variant_type_equal(type, G_VARIANT_TYPE_BYTE)) {
76  int_val = g_variant_get_byte(value);
77  range_min = 0, range_max = UINT8_MAX;
78  } else if (g_variant_type_equal(type, G_VARIANT_TYPE_INT16)) {
79  int_val = g_variant_get_int16(value);
80  range_min = INT16_MIN, range_max = INT16_MAX;
81  } else if (g_variant_type_equal(type, G_VARIANT_TYPE_UINT16)) {
82  int_val = g_variant_get_uint16(value);
83  range_min = 0, range_max = UINT16_MAX;
84  } else if (g_variant_type_equal(type, G_VARIANT_TYPE_INT32)) {
85  int_val = g_variant_get_int32(value);
86  range_min = INT32_MIN, range_max = INT32_MAX;
87  } else if (g_variant_type_equal(type, G_VARIANT_TYPE_UINT32)) {
88  int_val = g_variant_get_uint32(value);
89  range_min = 0, range_max = UINT32_MAX;
90  } else if (g_variant_type_equal(type, G_VARIANT_TYPE_INT64)) {
91  int_val = g_variant_get_int64(value);
92  range_min = INT64_MIN, range_max = INT64_MAX;
93  } else if (g_variant_type_equal(type, G_VARIANT_TYPE_UINT64)) {
94  int_val = g_variant_get_uint64(value);
95  range_min = 0, range_max = UINT64_MAX;
96  } else {
97  // Unexpected value type.
98  assert(0);
99  }
100 
101  // @todo Sigrok supports 64-bit quantities, but Qt does not have a
102  // standard widget to allow the values to be modified over the full
103  // 64-bit range on 32-bit machines. To solve the issue we need a
104  // custom widget.
105 
106  range_min = max(range_min, (int64_t)INT_MIN);
107  range_max = min(range_max, (uint64_t)INT_MAX);
108 
109  if (range_)
110  spin_box_->setRange((int)range_->first, (int)range_->second);
111  else
112  spin_box_->setRange((int)range_min, (int)range_max);
113 
114  spin_box_->setValue((int)int_val);
115 
116  if (auto_commit)
117  connect(spin_box_, SIGNAL(valueChanged(int)),
118  this, SLOT(on_value_changed(int)));
119 
120  return spin_box_;
121 }
122 
124 {
125  assert(setter_);
126 
127  if (!spin_box_)
128  return;
129 
130  GVariant *new_value = nullptr;
131  const GVariantType *const type = g_variant_get_type(value_.gobj());
132  assert(type);
133 
134  if (g_variant_type_equal(type, G_VARIANT_TYPE_BYTE))
135  new_value = g_variant_new_byte(spin_box_->value());
136  else if (g_variant_type_equal(type, G_VARIANT_TYPE_INT16))
137  new_value = g_variant_new_int16(spin_box_->value());
138  else if (g_variant_type_equal(type, G_VARIANT_TYPE_UINT16))
139  new_value = g_variant_new_uint16(spin_box_->value());
140  else if (g_variant_type_equal(type, G_VARIANT_TYPE_INT32))
141  new_value = g_variant_new_int32(spin_box_->value());
142  else if (g_variant_type_equal(type, G_VARIANT_TYPE_UINT32))
143  new_value = g_variant_new_uint32(spin_box_->value());
144  else if (g_variant_type_equal(type, G_VARIANT_TYPE_INT64))
145  new_value = g_variant_new_int64(spin_box_->value());
146  else if (g_variant_type_equal(type, G_VARIANT_TYPE_UINT64))
147  new_value = g_variant_new_uint64(spin_box_->value());
148  else
149  {
150  // Unexpected value type.
151  assert(0);
152  }
153 
154  assert(new_value);
155 
156  value_ = Glib::VariantBase(new_value);
157 
158  setter_(value_);
159 }
160 
162 {
163  commit();
164 }
165 
166 } // prop
167 } // pv
Glib::VariantBase value_
Definition: int.hpp:57
QSpinBox * spin_box_
Definition: int.hpp:58
void commit()
Definition: int.cpp:123
const Getter getter_
Definition: property.hpp:60
QWidget * get_widget(QWidget *parent, bool auto_commit)
Definition: int.cpp:52
std::function< void(Glib::VariantBase)> Setter
Definition: property.hpp:45
const boost::optional< std::pair< int64_t, int64_t > > range_
Definition: int.hpp:55
void on_value_changed(int)
Definition: int.cpp:161
const QString suffix_
Definition: int.hpp:54
const Setter setter_
Definition: property.hpp:61
virtual ~Int()
Definition: int.cpp:48
std::function< Glib::VariantBase()> Getter
Definition: property.hpp:41
Int(QString name, QString suffix, boost::optional< std::pair< int64_t, int64_t > > range, Getter getter, Setter setter)
Definition: int.cpp:36