]> sigrok.org Git - pulseview.git/blob - pv/prop/int.cpp
Use range-based for loops more often.
[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.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
48 Int::~Int()
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
123 void Int::commit()
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
161 void Int::on_value_changed(int)
162 {
163         commit();
164 }
165
166 } // prop
167 } // pv