2020-08-31 04:03:41 +08:00
|
|
|
#include "siunitedit.h"
|
|
|
|
|
|
|
|
#include <QDoubleValidator>
|
|
|
|
#include <unit.h>
|
|
|
|
#include <QEvent>
|
|
|
|
#include <QKeyEvent>
|
2020-11-13 01:56:39 +08:00
|
|
|
#include <QDebug>
|
2020-08-31 04:03:41 +08:00
|
|
|
|
|
|
|
SIUnitEdit::SIUnitEdit(QString unit, QString prefixes, int precision, QWidget *parent)
|
|
|
|
: QLineEdit(parent)
|
|
|
|
{
|
2020-11-01 06:03:34 +08:00
|
|
|
_value = 0;
|
2020-08-31 04:03:41 +08:00
|
|
|
this->unit = unit;
|
|
|
|
this->prefixes = prefixes;
|
|
|
|
this->precision = precision;
|
|
|
|
setAlignment(Qt::AlignCenter);
|
|
|
|
installEventFilter(this);
|
2020-11-01 06:03:34 +08:00
|
|
|
setValidator(new QDoubleValidator(this));
|
2020-08-31 04:03:41 +08:00
|
|
|
connect(this, &QLineEdit::editingFinished, [this]() {
|
|
|
|
parseNewValue(1.0);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
SIUnitEdit::SIUnitEdit(QWidget *parent)
|
|
|
|
: SIUnitEdit("", " ", 4, parent)
|
|
|
|
{
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
void SIUnitEdit::setValue(double value)
|
|
|
|
{
|
2020-11-13 01:56:39 +08:00
|
|
|
if(value != _value) {
|
|
|
|
setValueQuiet(value);
|
|
|
|
emit valueChanged(value);
|
|
|
|
emit valueUpdated(this);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static char swapUpperLower(char c) {
|
|
|
|
if(isupper(c)) {
|
|
|
|
return tolower(c);
|
|
|
|
} else if(islower(c)) {
|
|
|
|
return toupper(c);
|
|
|
|
} else {
|
|
|
|
return c;
|
|
|
|
}
|
2020-08-31 04:03:41 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
bool SIUnitEdit::eventFilter(QObject *, QEvent *event)
|
|
|
|
{
|
|
|
|
if (event->type() == QEvent::KeyPress) {
|
|
|
|
int key = static_cast<QKeyEvent *>(event)->key();
|
|
|
|
if(key == Qt::Key_Escape) {
|
|
|
|
// abort editing process and set old value
|
|
|
|
setValueQuiet(_value);
|
2020-11-06 20:05:09 +08:00
|
|
|
emit editingAborted();
|
2020-10-20 23:03:49 +08:00
|
|
|
clearFocus();
|
2020-08-31 04:03:41 +08:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
if(key == Qt::Key_Return) {
|
|
|
|
// use new value without prefix
|
|
|
|
parseNewValue(1.0);
|
2020-11-13 01:56:39 +08:00
|
|
|
continueEditing();
|
2020-08-31 04:03:41 +08:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
auto mod = static_cast<QKeyEvent *>(event)->modifiers();
|
|
|
|
if (!(mod & Qt::ShiftModifier)) {
|
|
|
|
key = tolower(key);
|
|
|
|
}
|
2020-11-13 01:56:39 +08:00
|
|
|
if(key <= 255) {
|
|
|
|
if (prefixes.indexOf(key) >= 0) {
|
|
|
|
// a valid prefix key was pressed
|
|
|
|
parseNewValue(Unit::SIPrefixToFactor(key));
|
|
|
|
continueEditing();
|
|
|
|
return true;
|
|
|
|
} else if (prefixes.indexOf(swapUpperLower(key)) >= 0) {
|
|
|
|
// no match on the pressed case but on the upper/lower case instead -> also accept this
|
|
|
|
parseNewValue(Unit::SIPrefixToFactor(swapUpperLower(key)));
|
|
|
|
continueEditing();
|
|
|
|
return true;
|
|
|
|
}
|
2020-08-31 04:03:41 +08:00
|
|
|
}
|
|
|
|
} else if(event->type() == QEvent::FocusOut) {
|
2020-11-15 07:21:09 +08:00
|
|
|
parseNewValue(1.0);
|
|
|
|
emit focusLost();
|
2020-08-31 04:03:41 +08:00
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
void SIUnitEdit::setValueQuiet(double value)
|
|
|
|
{
|
|
|
|
_value = value;
|
|
|
|
clear();
|
|
|
|
setPlaceholderText(Unit::ToString(value, unit, prefixes, precision));
|
|
|
|
}
|
|
|
|
|
|
|
|
void SIUnitEdit::parseNewValue(double factor)
|
|
|
|
{
|
2020-11-13 01:56:39 +08:00
|
|
|
QString input = text();
|
2020-11-15 07:21:09 +08:00
|
|
|
if(input.isEmpty()) {
|
|
|
|
setValueQuiet(_value);
|
|
|
|
emit editingAborted();
|
2020-11-13 01:56:39 +08:00
|
|
|
} else {
|
2020-11-15 07:21:09 +08:00
|
|
|
// remove optional unit
|
|
|
|
if(input.endsWith(unit)) {
|
|
|
|
input.chop(unit.size());
|
|
|
|
}
|
|
|
|
auto lastChar = input.at(input.size()-1).toLatin1();
|
|
|
|
if(prefixes.indexOf(lastChar) >= 0) {
|
|
|
|
factor = Unit::SIPrefixToFactor(lastChar);
|
|
|
|
input.chop(1);
|
|
|
|
}
|
|
|
|
// remaining input should only contain numbers
|
|
|
|
bool conversion_ok;
|
|
|
|
auto v = input.toDouble(&conversion_ok);
|
|
|
|
if(conversion_ok) {
|
|
|
|
setValue(v * factor);
|
|
|
|
} else {
|
|
|
|
qWarning() << "SIUnit conversion failure:" << input;
|
|
|
|
}
|
|
|
|
clear();
|
2020-11-13 01:56:39 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void SIUnitEdit::continueEditing()
|
|
|
|
{
|
|
|
|
setText(placeholderText());
|
|
|
|
selectAll();
|
2020-08-31 04:03:41 +08:00
|
|
|
}
|