]> sigrok.org Git - pulseview.git/blob - pv/prop/int.cpp
Added code to handle different integer types in the Int property.
[pulseview.git] / pv / prop / int.cpp
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.h"
27
28 using namespace std;
29 using namespace boost;
30
31 namespace pv {
32 namespace prop {
33
34 Int::Int(QString name,
35         QString suffix,
36         optional< pair<int64_t, int64_t> > range,
37         Getter getter,
38         Setter setter) :
39         Property(name, getter, setter),
40         _suffix(suffix),
41         _range(range),
42         _value(NULL),
43         _spin_box(NULL)
44 {
45 }
46
47 Int::~Int()
48 {
49         if (_value)
50                 g_variant_unref(_value);
51 }
52
53 QWidget* Int::get_widget(QWidget *parent, bool auto_commit)
54 {
55         int64_t int_val = 0, range_min = 0, range_max = 0;
56
57         if (_spin_box)
58                 return _spin_box;
59
60         if (_value)
61                 g_variant_unref(_value);
62
63         _value = _getter ? _getter() : NULL;
64         assert(_value);
65         if (!_value)
66                 return NULL;
67
68         _spin_box = new QSpinBox(parent);
69         _spin_box->setSuffix(_suffix);
70
71         const GVariantType *const type = g_variant_get_type(_value);
72         assert(type);
73
74         if (g_variant_type_equal(type, G_VARIANT_TYPE_BYTE))
75         {
76                 int_val = g_variant_get_byte(_value);
77                 range_min = 0, range_max = UINT8_MAX;
78         }
79         else if (g_variant_type_equal(type, G_VARIANT_TYPE_INT16))
80         {
81                 int_val = g_variant_get_int16(_value);
82                 range_min = INT16_MIN, range_max = INT16_MAX;
83         }
84         else if (g_variant_type_equal(type, G_VARIANT_TYPE_UINT16))
85         {
86                 int_val = g_variant_get_uint16(_value);
87                 range_min = 0, range_max = UINT16_MAX;
88         }
89         else if (g_variant_type_equal(type, G_VARIANT_TYPE_INT32))
90         {
91                 int_val = g_variant_get_int32(_value);
92                 range_min = INT32_MIN, range_max = INT32_MAX;
93         }
94         else if (g_variant_type_equal(type, G_VARIANT_TYPE_UINT32))
95         {
96                 int_val = g_variant_get_uint32(_value);
97                 range_min = 0, range_max = UINT32_MAX;
98         }
99         else if (g_variant_type_equal(type, G_VARIANT_TYPE_INT64))
100         {
101                 int_val = g_variant_get_int64(_value);
102                 range_min = INT64_MIN, range_max = INT64_MAX;
103         }
104         else if (g_variant_type_equal(type, G_VARIANT_TYPE_UINT64))
105         {
106                 int_val = g_variant_get_uint64(_value);
107                 range_min = 0, range_max = UINT64_MAX;
108         }
109         else
110         {
111                 // Unexpected value type.
112                 assert(0);
113         }
114
115         // @todo Sigrok supports 64-bit quantities, but Qt does not have a
116         // standard widget to allow the values to be modified over the full
117         // 64-bit range on 32-bit machines. To solve the issue we need a
118         // custom widget.
119
120         range_min = max(range_min, (int64_t)INT_MIN);
121         range_max = min(range_max, (int64_t)INT_MAX);
122
123         if (_range)
124                 _spin_box->setRange((int)_range->first, (int)_range->second);
125         else
126                 _spin_box->setRange((int)range_min, (int)range_max);
127
128         _spin_box->setValue((int)int_val);
129
130         if (auto_commit)
131                 connect(_spin_box, SIGNAL(valueChanged(int)),
132                         this, SLOT(on_value_changed(int)));
133
134         return _spin_box;
135 }
136
137 void Int::commit()
138 {
139         assert(_setter);
140
141         if (!_spin_box)
142                 return;
143
144         assert(_value);
145
146         GVariant *new_value = NULL;
147         const GVariantType *const type = g_variant_get_type(_value);
148         assert(type);
149
150         if (g_variant_type_equal(type, G_VARIANT_TYPE_BYTE))
151                 new_value = g_variant_new_byte(_spin_box->value());
152         else if (g_variant_type_equal(type, G_VARIANT_TYPE_INT16))
153                 new_value = g_variant_new_int16(_spin_box->value());
154         else if (g_variant_type_equal(type, G_VARIANT_TYPE_UINT16))
155                 new_value = g_variant_new_uint16(_spin_box->value());
156         else if (g_variant_type_equal(type, G_VARIANT_TYPE_INT32))
157                 new_value = g_variant_new_int32(_spin_box->value());
158         else if (g_variant_type_equal(type, G_VARIANT_TYPE_UINT32))
159                 new_value = g_variant_new_int32(_spin_box->value());
160         else if (g_variant_type_equal(type, G_VARIANT_TYPE_INT64))
161                 new_value = g_variant_new_int64(_spin_box->value());
162         else if (g_variant_type_equal(type, G_VARIANT_TYPE_UINT64))
163                 new_value = g_variant_new_uint64(_spin_box->value());
164         else
165         {
166                 // Unexpected value type.
167                 assert(0);
168         }
169
170         assert(new_value);
171
172         g_variant_unref(_value);
173         g_variant_ref(new_value);
174         _value = new_value;
175
176         _setter(new_value);
177 }
178
179 void Int::on_value_changed(int)
180 {
181         commit();
182 }
183
184 } // prop
185 } // pv