10#include <klocalizedstring.h>
16#include <QRegularExpression>
18#include <QActionGroup>
29 unitManager(unitManager),
30 defaultUnitManager(unitManager)
34 double minStepForPrec {0};
35 double lowerInPoints {0.0};
36 double upperInPoints {0.0};
37 double stepInPoints {0.0};
40 double previousValueInPoint {0.0};
47 bool isDeleting {
false};
49 bool unitHasBeenChangedFromOutSideOnce {
false};
50 bool letUnitBeChangedFromOutsideMoreThanOnce {
true};
52 bool displayUnit {
true};
54 bool allowResetDecimals {
true};
56 bool mustUsePreviousText {
false};
64 setAlignment( Qt::AlignRight );
67 connect(lineEdit(), SIGNAL(textChanged(QString)),
73 setDecimals(
d->unitManager->getApparentUnitRecommendedDecimals());
79 delete d->defaultUnitManager;
95 oldUnitManager =
d->unitManager;
97 disconnect(oldUnitManager, &QObject::destroyed,
109 if (
d->allowResetDecimals) {
110 setDecimals(
d->unitManager->getApparentUnitRecommendedDecimals());
119 if (oldUnitManager == 0 ||
124 if (oldUnitManager &&
d->unitManager->getUnitDimensionType() == oldUnitManager->
getUnitDimensionType()) {
126 newVal =
d->unitManager->getApparentValue(oldUnitManager->
getReferenceValue(KisDoubleParseSpinBox::value()));
128 newVal =
d->unitManager->getApparentValue(
d->lowerInPoints);
131 newMin =
d->unitManager->getApparentValue(
d->lowerInPoints);
132 newMax =
d->unitManager->getApparentValue(
d->upperInPoints);
133 newStep =
d->unitManager->getApparentValue(
d->stepInPoints);
140 KisDoubleParseSpinBox::setMinimum(newMin);
141 KisDoubleParseSpinBox::setMaximum(newMax);
142 KisDoubleParseSpinBox::setSingleStep(newStep);
145 connect(
d->unitManager, &QObject::destroyed,
157 double apparentValue;
161 if (
d->outPutSymbol.isEmpty()) {
162 apparentValue =
d->unitManager->getApparentValue(newValue);
165 fact =
d->unitManager->getConversionFactor(
d->unitManager->getUnitDimensionType(),
d->outPutSymbol);
166 cons =
d->unitManager->getConversionConstant(
d->unitManager->getUnitDimensionType(),
d->outPutSymbol);
168 apparentValue = fact*newValue + cons;
171 if (apparentValue == KisDoubleParseSpinBox::value()) {
175 if (
d->outPutSymbol.isEmpty()) {
184 double apparentValue =
d->unitManager->getApparentValue(newValue);
186 if (apparentValue == KisDoubleParseSpinBox::value()) {
195 if (
d->unitHasBeenChangedFromOutSideOnce && !
d->letUnitBeChangedFromOutsideMoreThanOnce) {
209 d->unitManager->setApparentUnitFromSymbol(symbol);
214 d->outPutSymbol = symbol;
219 return d->outPutSymbol;
224 d->previousValueInPoint =
d->unitManager->getReferenceValue(KisDoubleParseSpinBox::value());
225 d->previousSymbol =
d->unitManager->getApparentUnitSymbol();
231 if (
d->unitManager->getApparentUnitSymbol() ==
d->previousSymbol) {
236 if (
d->allowResetDecimals) {
237 setDecimals(
d->unitManager->getApparentUnitRecommendedDecimals());
240 KisDoubleParseSpinBox::setMinimum(
d->unitManager->getApparentValue(
d->lowerInPoints ) );
241 KisDoubleParseSpinBox::setMaximum(
d->unitManager->getApparentValue(
d->upperInPoints ) );
243 qreal step =
d->unitManager->getApparentValue(
d->stepInPoints );
253 d->unitHasBeenChangedFromOutSideOnce =
true;
267 if (
d->outPutSymbol.isEmpty()) {
268 return d->unitManager->getReferenceValue( KisDoubleParseSpinBox::value() );
271 double ref =
d->unitManager->getReferenceValue( KisDoubleParseSpinBox::value() );
272 double fact =
d->unitManager->getConversionFactor(
d->unitManager->getUnitDimensionType(),
d->outPutSymbol);
273 double cons =
d->unitManager->getConversionConstant(
d->unitManager->getUnitDimensionType(),
d->outPutSymbol);
275 return fact*ref + cons;
280 return d->unitManager->getReferenceValue( KisDoubleParseSpinBox::value() );
290 d->lowerInPoints =
d->unitManager->getReferenceValue(min);
291 KisDoubleParseSpinBox::setMinimum( min );
296 d->lowerInPoints = min;
297 KisDoubleParseSpinBox::setMinimum(
d->unitManager->getApparentValue( min ) );
303 d->upperInPoints =
d->unitManager->getReferenceValue(max);
304 KisDoubleParseSpinBox::setMaximum( max );
309 d->upperInPoints = max;
310 KisDoubleParseSpinBox::setMaximum(
d->unitManager->getApparentValue( max ) );
315 d->stepInPoints =
d->unitManager->getReferenceValue(step);
316 KisDoubleParseSpinBox::setSingleStep( step );
321 d->stepInPoints = step;
322 KisDoubleParseSpinBox::setSingleStep(
d->unitManager->getApparentValue( step ) );
343 if (
d->mustUsePreviousText) {
348 if (
d->displayUnit) {
349 if (!txt.endsWith(
d->unitManager->getApparentUnitSymbol())) {
350 txt +=
" " +
d->unitManager->getApparentUnitSymbol();
370 d->letUnitBeChangedFromOutsideMoreThanOnce = toggle;
375 d->displayUnit = toggle;
380 d->allowResetDecimals = !prevent;
392 QRegularExpression regexp (
"([ ]*[a-zA-Z]+[ ]*)$");
393 int res = str.indexOf( regexp );
396 QString expr ( str.right( str.size() - res ) );
397 expr = expr.trimmed();
408 if (unitSymb.isEmpty()) {
412 QString oldUnitSymb =
d->unitManager->getApparentUnitSymbol();
421 d->mustUsePreviousText =
true;
426 d->mustUsePreviousText =
false;
428 if (oldUnitSymb !=
d->unitManager->getApparentUnitSymbol()) {
437 QString symbol =
d->unitManager->getApparentUnitSymbol();
439 if ( expr.endsWith(suffix()) ) {
440 expr.remove(expr.size()-suffix().size(), suffix().size());
443 expr = expr.trimmed();
445 if ( expr.endsWith(symbol) ) {
446 expr.remove(expr.size()-symbol.size(), symbol.size());
449 return expr.trimmed();
467 KisDoubleParseSpinBox::setDecimals(prec);
468 d->minStepForPrec = 1/qPow(10, prec);
477 KisDoubleParseSpinBox::setSingleStep(qMax(
d->minStepForPrec, val));
484 QMenu* menu = lineEdit()->createStandardContextMenu();
489 menu->addSeparator();
490 const uint se = stepEnabled();
491 QAction *up = menu->addAction(tr(
"&Step up"));
492 up->setEnabled(se & StepUpEnabled);
493 QAction *down = menu->addAction(tr(
"Step &down"));
494 down->setEnabled(se & StepDownEnabled);
495 menu->addSeparator();
498 QMenu* menuUnit = menu->addMenu(i18n(
"Unit"));
499 QActionGroup* unitActions =
new QActionGroup(
this);
500 Q_FOREACH(QString unitSymbol,
d->unitManager->getsUnitSymbolList(
false)) {
504 switch (
d->unitManager->getUnitDimensionType()) {
507 if (unitSymbol ==
"%") {
508 unitLabel = i18n(
"Percent (%)");
509 }
else if (unitSymbol ==
"vw") {
510 unitLabel = i18n(
"percent of view width (vw)");
511 }
else if (unitSymbol ==
"vh") {
512 unitLabel = i18n(
"percent of view height (vh)");
517 if (unitSymbol ==
"°") {
518 unitLabel = i18n(
"degrees (°)");
519 }
else if (unitSymbol ==
"rad") {
520 unitLabel = i18n(
"radians (rad)");
521 }
else if (unitSymbol ==
"gon") {
522 unitLabel = i18n(
"gons (gon)");
523 }
else if (unitSymbol ==
"%") {
524 unitLabel = i18n(
"percent of circle (%)");
529 if (unitSymbol ==
"f") {
530 unitLabel = i18n(
"frames (f)");
531 }
else if (unitSymbol ==
"s") {
532 unitLabel = i18n(
"seconds (s)");
533 }
else if (unitSymbol ==
"%") {
534 unitLabel = i18n(
"percent of animation (%)");
539 QAction *unitAction = menuUnit->addAction(unitLabel);
540 unitAction->setProperty(
"symbol", unitSymbol);
541 unitAction->setCheckable(
true);
542 unitAction->setActionGroup(unitActions);
543 unitAction->setChecked(unitSymbol ==
d->unitManager->getApparentUnitSymbol());
546 const QPoint pos = (
event->reason() == QContextMenuEvent::Mouse)
547 ? event->globalPos() : mapToGlobal(QPoint(event->pos().x(), 0)) + QPoint(width() / 2, height() / 2);
548 const QAction *action = menu->exec(pos);
553 }
else if (action == down) {
556 QVariant symbol = action->property(
"symbol");
557 if (symbol.isValid()) {
558 d->unitManager->setApparentUnitFromSymbol(symbol.toString());
563 delete static_cast<QMenu *
>(menuUnit);
564 delete static_cast<QMenu *
>(menu);
float value(const T *src, size_t ch)
The KisDoubleParseSpinBox class is a cleverer doubleSpinBox, able to parse arithmetic expressions.
void setValue(double value, bool overwriteExpression=false)
Set the value of the spinbox.
QString textFromValue(double value) const override
void stepBy(int steps) override
This is a reimplementation of QDoubleSpinBox::stepBy that uses setValue.
double valueFromText(const QString &text) const override
The KisDoubleParseUnitSpinBox class is an evolution of the.
void setUnitChangeFromOutsideBehavior(bool toggle)
void disconnectExternalUnitManager()
void setMinimumPt(double min)
Set minimum value in points.
void setLineStepPt(double step)
Set step size in points.
void preventDecimalsChangeFromUnitManager(bool prevent)
QString makeTextClean(QString const &txt) const
void setLineStep(double step)
Set step size in the current unit.
void setMinMaxStep(double min, double max, double step)
Set minimum, maximum value and the step size (in current unit)
void setValuePt(double value, bool overWriteExpression=false)
Sets the value in points.
virtual void setDimensionType(int dim)
setDimensionType set the dimension (for example length or angle) of the units the spinbox manage
~KisDoubleParseUnitSpinBox() override
KisSpinBoxUnitManager * unitManager
void setUnitManager(KisSpinBoxUnitManager *unitManager)
void contextMenuEvent(QContextMenuEvent *event) override
void setReturnUnit(const QString &symbol)
setReturnUnit set a unit, such that the spinbox now return values in this unit instead of the referen...
void internalUnitChange(QString const &symbol)
change the unit, reset the spin box every time. From the outside it's always set unit that should be ...
void setSingleStep(double val)
void privateValueChanged()
void setMaximum(double max)
Set maximum value in current unit.
virtual void setUnit(const KoUnit &unit)
double valueFromText(const QString &str) const override
void setMinimum(double min)
Set minimum value in current unit.
void setMinMaxStepPt(double min, double max, double step)
Set minimum, maximum value and the step size (all in points)
void setDisplayUnit(bool toggle)
display the unit symbol in the spinbox or not. For example if the unit is displayed in a combobox con...
virtual void changeValue(double newValue)
void setMaximumPt(double max)
Set maximum value in points.
QString returnUnit() const
returnUnit returns the unit in which values are returned
QString veryCleanText() const override
get the text in the spinbox without prefix or suffix, and remove unit symbol if present.
Private(double low, double up, double step, KisSpinBoxUnitManager *unitManager)
void setDecimals(int prec)
KisDoubleParseUnitSpinBox(QWidget *parent=0)
QString textFromValue(double value) const override
void changeValuePt(double newValue)
void valueChangedPt(qreal)
emitted like valueChanged in the parent, but this one emits the point value, or converted to another ...
The KisSpinBoxUnitManagerFactory class is a factory that is used to build a default KisSpinBoxUnitMan...
The KisSpinBoxUnitManager class is an abstract interface for the unitspinboxes classes to manage diff...
int getUnitDimensionType() const
qreal getReferenceValue(double apparentValue) const
static bool isUnitId(int code)
QString getApparentUnitSymbol() const
void unitChanged(QString symbol)
static QString unitDescription(KoUnit::Type type)
Get the description string of the given unit.
static KoUnit fromSymbol(const QString &symbol, bool *ok=0)
QString symbol() const
Get the symbol string of the unit.
@ Point
Postscript point, 1/72th of an Inco.
typedef void(QOPENGLF_APIENTRYP PFNGLINVALIDATEBUFFERDATAPROC)(GLuint buffer)