MainWindow: Include device/file name in window title
[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_(NULL)
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, range_max = 0;
55
56         if (spin_box_)
57                 return spin_box_;
58
59         if (!getter_)
60                 return NULL;
61
62         value_ = getter_();
63
64         GVariant *value = value_.gobj();
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         GVariant *new_value = NULL;
145         const GVariantType *const type = g_variant_get_type(value_.gobj());
146         assert(type);
147
148         if (g_variant_type_equal(type, G_VARIANT_TYPE_BYTE))
149                 new_value = g_variant_new_byte(spin_box_->value());
150         else if (g_variant_type_equal(type, G_VARIANT_TYPE_INT16))
151                 new_value = g_variant_new_int16(spin_box_->value());
152         else if (g_variant_type_equal(type, G_VARIANT_TYPE_UINT16))
153                 new_value = g_variant_new_uint16(spin_box_->value());
154         else if (g_variant_type_equal(type, G_VARIANT_TYPE_INT32))
155                 new_value = g_variant_new_int32(spin_box_->value());
156         else if (g_variant_type_equal(type, G_VARIANT_TYPE_UINT32))
157                 new_value = g_variant_new_int32(spin_box_->value());
158         else if (g_variant_type_equal(type, G_VARIANT_TYPE_INT64))
159                 new_value = g_variant_new_int64(spin_box_->value());
160         else if (g_variant_type_equal(type, G_VARIANT_TYPE_UINT64))
161                 new_value = g_variant_new_uint64(spin_box_->value());
162         else
163         {
164                 // Unexpected value type.
165                 assert(0);
166         }
167
168         assert(new_value);
169
170         value_ = Glib::VariantBase(new_value);
171
172         setter_(value_);
173 }
174
175 void Int::on_value_changed(int)
176 {
177         commit();
178 }
179
180 } // prop
181 } // pv