CVB++ 15.0
detail_custom_lineedit.hpp
1#pragma once
2
3#pragma warning(push)
4#pragma warning(disable : 4800)
5#pragma warning(disable : 4251)
6#pragma warning(disable : 4244)
7#include <QFrame>
8#include <QList>
9#include <QLineEdit>
10#include <QHBoxLayout>
11#include <QLabel>
12#include <QRegExpValidator>
13#include <QEvent>
14#include <QKeyEvent>
15#pragma warning(pop)
16
17#include "../../global.hpp"
18#include "../../utilities/system_info.hpp"
19
20namespace Cvb
21{
22
23 CVB_BEGIN_INLINE_NS
24
25 namespace UI
26 {
27 namespace Private
28 {
29
30 class CustomLineEdit : public QFrame
31 {
32
33 Q_OBJECT
34
35 public:
36 CustomLineEdit(QRegExp rx, QString separator, int numLineEdits = 1, int maxDigits = 4, QWidget *parent = 0)
37 : QFrame(parent)
38 , numLineEdits_(numLineEdits)
39 , maxDigits_(maxDigits)
40 {
41 setFrameShape(QFrame::Panel);
42 setFrameShadow(QFrame::Sunken);
43
44 auto layout = new QHBoxLayout(this); // NOLINT(cppcoreguidelines-owning-memory)
45 layout->setContentsMargins(0, 0, 0, 0);
46 layout->setSpacing(0);
47
48 for (int i = 0; i != numLineEdits_; ++i)
49 {
50 if (i != 0)
51 {
52 auto sep = new QLabel(separator, this);
53 sep->setStyleSheet("background: white");
54 layout->addWidget(sep);
55 layout->setStretch(layout->count(), 0);
56 }
57
58 auto edit = new QLineEdit(this); // NOLINT(cppcoreguidelines-owning-memory)
59 edit->installEventFilter(this);
60
61 layout->addWidget(edit);
62 layout->setStretch(layout->count(), 1);
63
64 edit->setFrame(false);
65 edit->setAlignment(Qt::AlignCenter);
66
67 auto font = edit->font();
68 font.setStyleHint(QFont::Monospace);
69 font.setFixedPitch(true);
70 edit->setFont(font);
71
72 auto validator = new QRegExpValidator(rx, edit); // NOLINT(cppcoreguidelines-owning-memory)
73 edit->setValidator(validator);
74
75 lineEdit_.append(edit);
76
77 QObject::connect(edit, &QLineEdit::editingFinished, [=]() {
78 for (int i = 0; i < numLineEdits_; i++)
79 {
80 if (lineEdit_[i]->hasFocus())
81 return;
82 }
83 TextChanged(Text()); // send signal
84 });
85 }
86
87 setMaximumWidth(30 * numLineEdits);
88 }
89
90 void SetReadOnly(bool readOnly)
91 {
92 for (int i = 0; i < numLineEdits_; i++)
93 {
94 lineEdit_[i]->setReadOnly(readOnly);
95 }
96 }
97
98 void SetEnabled(bool enabled)
99 {
100 for (int i = 0; i < numLineEdits_; i++)
101 {
102 lineEdit_[i]->setEnabled(enabled);
103 }
104 }
105
106 protected:
107 bool eventFilter(QObject *obj, QEvent *event) override
108 {
109 auto bRes = QFrame::eventFilter(obj, event);
110
111 if (event->type() == QEvent::KeyPress)
112 {
113 auto keyevent = dynamic_cast<QKeyEvent *>(event);
114 if (keyevent)
115 {
116 for (int i = 0; i < numLineEdits_; ++i)
117 {
118 auto lineEdit = lineEdit_[i];
119 if (lineEdit == obj)
120 {
121 switch (keyevent->key())
122 {
123 case Qt::Key_Left:
124 if (lineEdit->cursorPosition() == 0)
125 {
126 // user wants to move to previous item
127 MovePrevLineEdit(i);
128 }
129 break;
130
131 case Qt::Key_Right:
132 if (lineEdit->text().isEmpty() || (lineEdit->text().size() == lineEdit->cursorPosition()))
133 {
134 // user wants to move to next item
135 MoveNextLineEdit(i);
136 }
137 break;
138
139 case Qt::Key_0:
140 if (lineEdit->text().isEmpty() || lineEdit->text() == "0")
141 {
142 lineEdit->setText("0");
143 // user wants to move to next item
144 MoveNextLineEdit(i);
145 }
146 break;
147
148 case Qt::Key_Backspace:
149 if (lineEdit->text().isEmpty() || lineEdit->cursorPosition() == 0)
150 {
151 // user wants to move to previous item
152 MovePrevLineEdit(i);
153 }
154 break;
155
156 case Qt::Key_Comma:
157 case Qt::Key_Period:
158 MoveNextLineEdit(i);
159 break;
160
161 case Qt::Key_Tab:
162 break;
163
164 case Qt::Key_Return:
165 TextChanged(Text()); // send signal
166 break;
167 }
168 }
169 }
170 }
171 }
172
173 return bRes;
174 }
175
176 Q_SIGNALS:
177
178 void TextChanged(const QString &text);
179
180 private:
181 void MoveNextLineEdit(int i)
182 {
183 if (i + 1 != numLineEdits_)
184 {
185 lineEdit_[i + 1]->setFocus();
186 lineEdit_[i + 1]->setCursorPosition(0);
187 lineEdit_[i + 1]->selectAll();
188 }
189 }
190
191 void MovePrevLineEdit(int i)
192 {
193 if (i != 0)
194 {
195 lineEdit_[i - 1]->setFocus();
196 lineEdit_[i - 1]->setCursorPosition(lineEdit_[i - 1]->text().size());
197 }
198 }
199
200 virtual QString Text() const = 0;
201 virtual void SetText(const QString &text) = 0;
202
203 protected:
204 int numLineEdits_; // NOLINT(cppcoreguidelines-non-private-member-variables-in-classes)
205 int maxDigits_; // NOLINT(cppcoreguidelines-non-private-member-variables-in-classes)
206 QList<QLineEdit *> lineEdit_; // NOLINT(cppcoreguidelines-non-private-member-variables-in-classes)
207
208 }; /* class CustomLineEdit */
209
210 class IpLineEdit : public CustomLineEdit
211 {
212
213 Q_OBJECT
214
215 public:
216 explicit IpLineEdit(QWidget *parent = 0)
217 : CustomLineEdit(QRegExp("^(0|[1-9]|[1-9][0-9]|1[0-9][0-9]|2([0-4][0-9]|5[0-5]))$"), ".", 4, 3, parent)
218 {
219 }
220
221 QString Text() const override
222 {
223 auto value = QString("");
224 for (int i = 0; i < numLineEdits_; i++)
225 {
226 value.append(lineEdit_[i]->text());
227 if (i < (numLineEdits_ - 1))
228 value.append(".");
229 }
230
231 if (value.isEmpty())
232 {
233 for (int i = 0; i < numLineEdits_; ++i)
234 {
235 value.append("0");
236 if (i < (numLineEdits_ - 1))
237 value.append(".");
238 }
239 return value;
240 }
241 return value;
242 }
243
244 void SetText(const QString &text) override
245 {
246 auto ip = text.split(".");
247
248 if (ip.size() != numLineEdits_)
249 return;
250
251 for (int i = 0; i < numLineEdits_; i++)
252 {
253 lineEdit_[i]->setText(ip.at(i));
254 }
255 }
256
257 }; /* class IpLineEdit */
258
259 class MacLineEdit : public CustomLineEdit
260 {
261
262 Q_OBJECT
263
264 public:
265 explicit MacLineEdit(QWidget *parent = 0)
266 : CustomLineEdit(QRegExp("[0-9A-Fa-f]{2}"), "-", 6, 2, parent)
267 {
268 }
269
270 QString Text() const override
271 {
272 auto value = QString("");
273 for (int i = 0; i < numLineEdits_; i++)
274 {
275 value.append(lineEdit_[i]->text());
276 if (i < (numLineEdits_ - 1))
277 value.append("-");
278 }
279
280 if (value.isEmpty())
281 return "00-00-00-00-00-00";
282 return value;
283 }
284
285 void SetText(const QString &text) override
286 {
287 auto mac = text.split("-");
288
289 if (mac.size() != numLineEdits_)
290 mac = text.split(":");
291
292 if (mac.size() != numLineEdits_)
293 return;
294
295 for (int i = 0; i < numLineEdits_; i++)
296 {
297 lineEdit_[i]->setText(mac.at(i));
298 }
299 }
300
301 }; /* class MacLineEdit */
302
303 } /* namespace Private */
304 } /* namespace UI */
305
306 CVB_END_INLINE_NS
307
308} /* namespace Cvb */
Namespace for user interface components.
Definition decl_image_scene.hpp:39
Root namespace for the Image Manager interface.
Definition c_bayer_to_rgb.h:17