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() );
285 d->lowerInPoints =
d->unitManager->getReferenceValue(min);
286 KisDoubleParseSpinBox::setMinimum( min );
291 d->lowerInPoints = min;
292 KisDoubleParseSpinBox::setMinimum(
d->unitManager->getApparentValue( min ) );
298 d->upperInPoints =
d->unitManager->getReferenceValue(max);
299 KisDoubleParseSpinBox::setMaximum( max );
304 d->upperInPoints = max;
305 KisDoubleParseSpinBox::setMaximum(
d->unitManager->getApparentValue( max ) );
310 d->stepInPoints =
d->unitManager->getReferenceValue(step);
311 KisDoubleParseSpinBox::setSingleStep( step );
316 d->stepInPoints = step;
317 KisDoubleParseSpinBox::setSingleStep(
d->unitManager->getApparentValue( step ) );
338 if (
d->mustUsePreviousText) {
343 if (
d->displayUnit) {
344 if (!txt.endsWith(
d->unitManager->getApparentUnitSymbol())) {
345 txt +=
" " +
d->unitManager->getApparentUnitSymbol();
365 d->letUnitBeChangedFromOutsideMoreThanOnce = toggle;
370 d->displayUnit = toggle;
375 d->allowResetDecimals = !prevent;
387 QRegularExpression regexp (
"([ ]*[a-zA-Z]+[ ]*)$");
388 int res = str.indexOf( regexp );
391 QString expr ( str.right( str.size() - res ) );
392 expr = expr.trimmed();
403 if (unitSymb.isEmpty()) {
407 QString oldUnitSymb =
d->unitManager->getApparentUnitSymbol();
416 d->mustUsePreviousText =
true;
421 d->mustUsePreviousText =
false;
423 if (oldUnitSymb !=
d->unitManager->getApparentUnitSymbol()) {
432 QString symbol =
d->unitManager->getApparentUnitSymbol();
434 if ( expr.endsWith(suffix()) ) {
435 expr.remove(expr.size()-suffix().size(), suffix().size());
438 expr = expr.trimmed();
440 if ( expr.endsWith(symbol) ) {
441 expr.remove(expr.size()-symbol.size(), symbol.size());
444 return expr.trimmed();
462 KisDoubleParseSpinBox::setDecimals(prec);
463 d->minStepForPrec = 1/qPow(10, prec);
472 KisDoubleParseSpinBox::setSingleStep(qMax(
d->minStepForPrec, val));
479 QMenu* menu = lineEdit()->createStandardContextMenu();
484 menu->addSeparator();
485 const uint se = stepEnabled();
486 QAction *up = menu->addAction(tr(
"&Step up"));
487 up->setEnabled(se & StepUpEnabled);
488 QAction *down = menu->addAction(tr(
"Step &down"));
489 down->setEnabled(se & StepDownEnabled);
490 menu->addSeparator();
493 QMenu* menuUnit = menu->addMenu(i18n(
"Unit"));
494 QActionGroup* unitActions =
new QActionGroup(
this);
495 Q_FOREACH(QString unitSymbol,
d->unitManager->getsUnitSymbolList(
false)) {
499 switch (
d->unitManager->getUnitDimensionType()) {
502 if (unitSymbol ==
"%") {
503 unitLabel = i18n(
"Percent (%)");
504 }
else if (unitSymbol ==
"vw") {
505 unitLabel = i18n(
"percent of view width (vw)");
506 }
else if (unitSymbol ==
"vh") {
507 unitLabel = i18n(
"percent of view height (vh)");
512 if (unitSymbol ==
"°") {
513 unitLabel = i18n(
"degrees (°)");
514 }
else if (unitSymbol ==
"rad") {
515 unitLabel = i18n(
"radians (rad)");
516 }
else if (unitSymbol ==
"gon") {
517 unitLabel = i18n(
"gons (gon)");
518 }
else if (unitSymbol ==
"%") {
519 unitLabel = i18n(
"percent of circle (%)");
524 if (unitSymbol ==
"f") {
525 unitLabel = i18n(
"frames (f)");
526 }
else if (unitSymbol ==
"s") {
527 unitLabel = i18n(
"seconds (s)");
528 }
else if (unitSymbol ==
"%") {
529 unitLabel = i18n(
"percent of animation (%)");
534 QAction *unitAction = menuUnit->addAction(unitLabel);
535 unitAction->setProperty(
"symbol", unitSymbol);
536 unitAction->setCheckable(
true);
537 unitAction->setActionGroup(unitActions);
538 unitAction->setChecked(unitSymbol ==
d->unitManager->getApparentUnitSymbol());
541 const QPoint pos = (
event->reason() == QContextMenuEvent::Mouse)
542 ? event->globalPos() : mapToGlobal(QPoint(event->pos().x(), 0)) + QPoint(width() / 2, height() / 2);
543 const QAction *action = menu->exec(pos);
548 }
else if (action == down) {
551 QVariant symbol = action->property(
"symbol");
552 if (symbol.isValid()) {
553 d->unitManager->setApparentUnitFromSymbol(symbol.toString());
558 delete static_cast<QMenu *
>(menuUnit);
559 delete static_cast<QMenu *
>(menu);
float value(const T *src, size_t ch)
connect(this, SIGNAL(optionsChanged()), this, SLOT(saveOptions()))
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)
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)