diff --git a/libs/basicflakes/tools/KoCreatePathTool.cpp b/libs/basicflakes/tools/KoCreatePathTool.cpp --- a/libs/basicflakes/tools/KoCreatePathTool.cpp +++ b/libs/basicflakes/tools/KoCreatePathTool.cpp @@ -30,6 +30,7 @@ #include "KoShapeStroke.h" #include "KoStrokeConfigWidget.h" #include "KoCanvasBase.h" +#include "kis_int_parse_spin_box.h" #include #include @@ -488,7 +489,7 @@ angleWidget->setObjectName("Angle Constraints"); QGridLayout *layout = new QGridLayout(angleWidget); layout->addWidget(new QLabel(i18n("Angle snapping delta:"), angleWidget), 0, 0); - QSpinBox *angleEdit = new QSpinBox(angleWidget); + QSpinBox *angleEdit = new KisIntParseSpinBox(angleWidget); angleEdit->setValue(d->angleSnappingDelta); angleEdit->setRange(1, 360); angleEdit->setSingleStep(1); diff --git a/libs/basicflakes/tools/KoPencilTool.cpp b/libs/basicflakes/tools/KoPencilTool.cpp --- a/libs/basicflakes/tools/KoPencilTool.cpp +++ b/libs/basicflakes/tools/KoPencilTool.cpp @@ -50,6 +50,7 @@ #include #include "KoCreatePathTool_p.h" +#include "kis_double_parse_spin_box.h" KoPencilTool::KoPencilTool(KoCanvasBase *canvas) : KoToolBase(canvas) @@ -310,7 +311,7 @@ QWidget * curveBox = new QWidget(stackedWidget); QHBoxLayout * curveLayout = new QHBoxLayout(curveBox); QCheckBox * optimizeCurve = new QCheckBox(i18n("Optimize"), curveBox); - QDoubleSpinBox * fittingError = new QDoubleSpinBox(curveBox); + QDoubleSpinBox * fittingError = new KisDoubleParseSpinBox(curveBox); fittingError->setValue(0.50); fittingError->setMaximum(400.0); fittingError->setMinimum(0.0); @@ -322,7 +323,7 @@ QWidget *straightBox = new QWidget(stackedWidget); QVBoxLayout *straightLayout = new QVBoxLayout(straightBox); - QDoubleSpinBox *combineAngle = new QDoubleSpinBox(straightBox); + QDoubleSpinBox *combineAngle = new KisDoubleParseSpinBox(straightBox); combineAngle->setValue(0.50); combineAngle->setMaximum(360.0); combineAngle->setMinimum(0.0); diff --git a/libs/ui/CMakeLists.txt b/libs/ui/CMakeLists.txt --- a/libs/ui/CMakeLists.txt +++ b/libs/ui/CMakeLists.txt @@ -253,6 +253,7 @@ widgets/kis_color_label_selector_widget.cpp widgets/kis_color_filter_combo.cpp widgets/kis_elided_label.cpp + input/kis_input_manager.cpp input/kis_input_manager_p.cpp input/kis_extended_modifiers_mapper.cpp @@ -479,6 +480,7 @@ wdgsplash.ui input/wintab/kis_screen_size_choice_dialog.ui + ) @@ -525,6 +527,7 @@ $ $ $ + $ $ $ ) diff --git a/libs/ui/KisColorsetChooser.cpp b/libs/ui/KisColorsetChooser.cpp --- a/libs/ui/KisColorsetChooser.cpp +++ b/libs/ui/KisColorsetChooser.cpp @@ -42,6 +42,8 @@ #include #include +#include "kis_int_parse_spin_box.h" + class ColorSetDelegate : public QAbstractItemDelegate { public: @@ -101,7 +103,7 @@ m_nameEdit->setPlaceholderText(i18n("Insert name")); m_nameEdit->setClearButtonEnabled(true); - m_columnEdit = new QSpinBox(this); + m_columnEdit = new KisIntParseSpinBox(this); m_columnEdit->setRange(1, 30); m_columnEdit->setValue(10); diff --git a/libs/ui/dialogs/kis_dlg_preferences.cc b/libs/ui/dialogs/kis_dlg_preferences.cc --- a/libs/ui/dialogs/kis_dlg_preferences.cc +++ b/libs/ui/dialogs/kis_dlg_preferences.cc @@ -569,7 +569,7 @@ SliderAndSpinBoxSync *sync2 = new SliderAndSpinBoxSync(sliderPoolLimit, intPoolLimit, - std::bind(&QSpinBox::value, + std::bind(&KisIntParseSpinBox::value, intMemoryLimit)); diff --git a/libs/ui/forms/kis_matrix_widget.ui b/libs/ui/forms/kis_matrix_widget.ui --- a/libs/ui/forms/kis_matrix_widget.ui +++ b/libs/ui/forms/kis_matrix_widget.ui @@ -1,130 +1,137 @@ - - - - - KisMatrixWidget - - - - 0 - 0 - 191 - 115 - - - - Matrix Widget - - - - - - -99 - - - - - - - -99 - - - - - - - -99 - - - - - - - -99 - - - - - - - -99 - - - - - - - -99 - - - 1 - - - - - - - -99 - - - - - - - -99 - - - - - - - -99 - - - - - - - - 20 - 41 - - - - Expanding - - - Qt::Vertical - - - - - - - - 21 - 20 - - - - Expanding - - - Qt::Horizontal - - - - - - - m11 - m12 - m13 - m21 - m22 - m23 - m31 - m32 - m33 - + + + KisMatrixWidget + + + + 0 + 0 + 195 + 117 + + + + Matrix Widget + + + + + + -99 + + + + + + + -99 + + + + + + + -99 + + + + + + + -99 + + + + + + + -99 + + + + + + + -99 + + + 1 + + + + + + + -99 + + + + + + + -99 + + + + + + + -99 + + + + + + + Qt::Vertical + + + QSizePolicy::Expanding + + + + 20 + 41 + + + + + + + + Qt::Horizontal + + + QSizePolicy::Expanding + + + + 21 + 20 + + + + + + + + + KisIntParseSpinBox + QSpinBox +
kis_int_parse_spin_box.h
+
+
+ + m11 + m12 + m13 + m21 + m22 + m23 + m31 + m32 + m33 + + +
diff --git a/libs/ui/forms/wdgautogradient.ui b/libs/ui/forms/wdgautogradient.ui --- a/libs/ui/forms/wdgautogradient.ui +++ b/libs/ui/forms/wdgautogradient.ui @@ -32,7 +32,7 @@ - + 0 @@ -134,7 +134,7 @@ - + 0 @@ -212,14 +212,14 @@ Qt::ClickFocus - + 255 255 255 - + 255 255 @@ -229,7 +229,7 @@ - + 0 @@ -262,7 +262,16 @@ - + + 0 + + + 0 + + + 0 + + 0 @@ -360,6 +369,11 @@ + KisIntParseSpinBox + QSpinBox +
kis_int_parse_spin_box.h
+
+ KColorButton QPushButton
kcolorbutton.h
diff --git a/libs/ui/forms/wdgdisplaysettings.ui b/libs/ui/forms/wdgdisplaysettings.ui --- a/libs/ui/forms/wdgdisplaysettings.ui +++ b/libs/ui/forms/wdgdisplaysettings.ui @@ -6,7 +6,7 @@ 0 0 - 500 + 504 685
@@ -69,7 +69,7 @@ - Size: + S&ize: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter @@ -80,7 +80,7 @@ - + px @@ -175,7 +175,7 @@ - OpenGL + Open&GL true @@ -344,6 +344,11 @@ + KisIntParseSpinBox + QSpinBox +
kis_int_parse_spin_box.h
+
+ KColorButton QPushButton
kcolorbutton.h
diff --git a/libs/ui/forms/wdggeneralsettings.ui b/libs/ui/forms/wdggeneralsettings.ui --- a/libs/ui/forms/wdggeneralsettings.ui +++ b/libs/ui/forms/wdggeneralsettings.ui @@ -29,7 +29,7 @@ - 0 + 3 @@ -427,7 +427,7 @@ - In Toolbar + In Tool&bar true @@ -546,7 +546,7 @@ - + 0 @@ -584,7 +584,7 @@ - + 0 @@ -615,7 +615,7 @@ - + 0 @@ -699,6 +699,11 @@ + KisIntParseSpinBox + QSpinBox +
kis_int_parse_spin_box.h
+
+ KColorButton QPushButton
kcolorbutton.h
diff --git a/libs/ui/forms/wdgimportimagesequence.ui b/libs/ui/forms/wdgimportimagesequence.ui --- a/libs/ui/forms/wdgimportimagesequence.ui +++ b/libs/ui/forms/wdgimportimagesequence.ui @@ -72,7 +72,7 @@
- + The frame number for the first image @@ -89,7 +89,7 @@ - + Number of frames between images @@ -117,6 +117,13 @@
+ + + KisIntParseSpinBox + QSpinBox +
kis_int_parse_spin_box.h
+
+
diff --git a/libs/ui/forms/wdgnewimage.ui b/libs/ui/forms/wdgnewimage.ui --- a/libs/ui/forms/wdgnewimage.ui +++ b/libs/ui/forms/wdgnewimage.ui @@ -88,7 +88,7 @@ - &Predefined: + P&redefined: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter @@ -161,7 +161,7 @@ - + 2 @@ -187,7 +187,7 @@ - + 0 @@ -207,7 +207,7 @@ - + 1.000000000000000 @@ -235,7 +235,7 @@ - &Width: + W&idth: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter @@ -407,7 +407,7 @@ - Image Background &Opacity: + Ima&ge Background Opacity: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter @@ -418,7 +418,7 @@ - + 0 @@ -493,14 +493,14 @@ - As first layer + As fi&rst layer - As canvas color + As ca&nvas color @@ -523,14 +523,14 @@ Reset the image background color in the Image Properties dialog - + 255 255 255 - + 255 255 @@ -548,7 +548,16 @@ QFrame::Plain - + + 0 + + + 0 + + + 0 + + 0 @@ -636,6 +645,17 @@ + KisColorSpaceSelector + QWidget +
widgets/kis_color_space_selector.h
+ 1 +
+ + KisDoubleParseSpinBox + QDoubleSpinBox +
kis_double_parse_spin_box.h
+
+ KColorButton QPushButton
kcolorbutton.h
@@ -648,10 +668,9 @@ 1
- KisColorSpaceSelector - QWidget -
widgets/kis_color_space_selector.h
- 1 + KisIntParseSpinBox + QSpinBox +
kis_int_parse_spin_box.h
diff --git a/libs/ui/forms/wdgpaintactioneditor.ui b/libs/ui/forms/wdgpaintactioneditor.ui --- a/libs/ui/forms/wdgpaintactioneditor.ui +++ b/libs/ui/forms/wdgpaintactioneditor.ui @@ -6,13 +6,13 @@ 0 0 - 400 + 405 376
- + @@ -94,17 +94,17 @@ - + 0 0 - + 0 - + 100 @@ -163,7 +163,7 @@ - + 4 @@ -180,6 +180,11 @@ + KisIntParseSpinBox + QSpinBox +
kis_int_parse_spin_box.h
+
+ KisPresetChooser QWidget
widgets/kis_preset_chooser.h
diff --git a/libs/ui/forms/wdgperformancesettings.ui b/libs/ui/forms/wdgperformancesettings.ui --- a/libs/ui/forms/wdgperformancesettings.ui +++ b/libs/ui/forms/wdgperformancesettings.ui @@ -53,7 +53,7 @@ - + 0 @@ -66,7 +66,7 @@ - + MiB @@ -84,7 +84,7 @@ - + 0 @@ -94,7 +94,7 @@ - + MiB @@ -115,7 +115,7 @@ - + 0 @@ -128,7 +128,7 @@ - + MiB @@ -158,7 +158,7 @@ - + 0 @@ -171,7 +171,7 @@ - + GiB @@ -283,15 +283,20 @@ - KisDoubleSliderSpinBox + KisSliderSpinBox QWidget
kis_slider_spin_box.h
1
- KisSliderSpinBox + KisIntParseSpinBox + QSpinBox +
kis_int_parse_spin_box.h
+
+ + KisDoubleSliderSpinBox QWidget -
kis_slider_spin_box.h
+
kis_slider_spin_box.h
1
diff --git a/libs/ui/forms/wdgrectangleconstraints.ui b/libs/ui/forms/wdgrectangleconstraints.ui --- a/libs/ui/forms/wdgrectangleconstraints.ui +++ b/libs/ui/forms/wdgrectangleconstraints.ui @@ -6,7 +6,7 @@ 0 0 - 218 + 230 149
@@ -83,7 +83,7 @@
- + Height @@ -106,7 +106,7 @@ - + Aspect ratio @@ -119,7 +119,7 @@ - + Width @@ -181,6 +181,18 @@
+ + + KisIntParseSpinBox + QSpinBox +
kis_int_parse_spin_box.h
+
+ + KisDoubleParseSpinBox + QDoubleSpinBox +
kis_double_parse_spin_box.h
+
+
diff --git a/libs/ui/kis_aspect_ratio_locker.cpp b/libs/ui/kis_aspect_ratio_locker.cpp --- a/libs/ui/kis_aspect_ratio_locker.cpp +++ b/libs/ui/kis_aspect_ratio_locker.cpp @@ -27,6 +27,8 @@ #include "kis_assert.h" #include "kis_debug.h" #include "kis_slider_spin_box.h" +#include "kis_int_parse_spin_box.h" +#include "kis_double_parse_spin_box.h" struct SliderWrapper @@ -137,6 +139,8 @@ template void KisAspectRatioLocker::connectSpinBoxes(QDoubleSpinBox *spinOne, QDoubleSpinBox *spinTwo, KoAspectButton *aspectButton); template void KisAspectRatioLocker::connectSpinBoxes(KisSliderSpinBox *spinOne, KisSliderSpinBox *spinTwo, KoAspectButton *aspectButton); template void KisAspectRatioLocker::connectSpinBoxes(KisDoubleSliderSpinBox *spinOne, KisDoubleSliderSpinBox *spinTwo, KoAspectButton *aspectButton); +template void KisAspectRatioLocker::connectSpinBoxes(KisIntParseSpinBox *spinOne, KisIntParseSpinBox *spinTwo, KoAspectButton *aspectButton); +template void KisAspectRatioLocker::connectSpinBoxes(KisDoubleParseSpinBox *spinOne, KisDoubleParseSpinBox *spinTwo, KoAspectButton *aspectButton); void KisAspectRatioLocker::slotSpinOneChanged() { diff --git a/libs/ui/layerstyles/WdgGradientOverlay.ui b/libs/ui/layerstyles/WdgGradientOverlay.ui --- a/libs/ui/layerstyles/WdgGradientOverlay.ui +++ b/libs/ui/layerstyles/WdgGradientOverlay.ui @@ -6,8 +6,8 @@ 0 0 - 400 - 266 + 411 + 294 @@ -49,7 +49,7 @@ - &Opacity: + Opac&ity: intOpacity @@ -81,7 +81,7 @@ - Gradient: + &Gradient: cmbGradient @@ -194,7 +194,7 @@ - + -179 @@ -260,17 +260,22 @@ - KisCompositeOpComboBox - QComboBox -
kis_cmb_composite.h
+ KisIntParseSpinBox + QSpinBox +
kis_int_parse_spin_box.h
KisSliderSpinBox QWidget
kis_slider_spin_box.h
1
+ KisCompositeOpComboBox + QComboBox +
kis_cmb_composite.h
+
+ KisCmbGradient QToolButton
kis_cmb_gradient.h
diff --git a/libs/ui/layerstyles/WdgSatin.ui b/libs/ui/layerstyles/WdgSatin.ui --- a/libs/ui/layerstyles/WdgSatin.ui +++ b/libs/ui/layerstyles/WdgSatin.ui @@ -7,7 +7,7 @@ 0 0 400 - 337 + 345
@@ -60,7 +60,7 @@ - &Opacity: + Opaci&ty: intOpacity @@ -95,7 +95,7 @@ - &Angle: + An&gle: dialAngle @@ -121,7 +121,7 @@ - + -179 @@ -155,7 +155,7 @@ - &Size: + S&ize: intSize @@ -247,6 +247,17 @@ + KisIntParseSpinBox + QSpinBox +
kis_int_parse_spin_box.h
+
+ + KisSliderSpinBox + QWidget +
kis_slider_spin_box.h
+ 1 +
+ KColorButton QPushButton
kcolorbutton.h
@@ -258,12 +269,6 @@
kis_cmb_composite.h
- KisSliderSpinBox - QWidget -
kis_slider_spin_box.h
- 1 -
- KisCmbContour QWidget
kis_cmb_contour.h
diff --git a/libs/ui/layerstyles/WdgStroke.ui b/libs/ui/layerstyles/WdgStroke.ui --- a/libs/ui/layerstyles/WdgStroke.ui +++ b/libs/ui/layerstyles/WdgStroke.ui @@ -6,7 +6,7 @@ 0 0 - 400 + 401 642
@@ -26,15 +26,15 @@ - &Size: + S&ize: intSize - + 0 @@ -46,7 +46,7 @@ - &Position: + Positio&n: cmbPosition @@ -101,15 +101,15 @@ - O&pacity: + Opacit&y: intOpacity - + 0 @@ -149,7 +149,7 @@ - 0 + 1 @@ -174,7 +174,7 @@ - Gradient: + &Gradient: cmbGradient @@ -287,7 +287,7 @@ - + -179 @@ -309,7 +309,7 @@ - + 0 @@ -376,7 +376,7 @@ - + Set size of gradation @@ -430,6 +430,11 @@
kis_pattern_chooser.h
1 + + KisIntParseSpinBox + QSpinBox +
kis_int_parse_spin_box.h
+
diff --git a/libs/ui/layerstyles/wdgBevelAndEmboss.ui b/libs/ui/layerstyles/wdgBevelAndEmboss.ui --- a/libs/ui/layerstyles/wdgBevelAndEmboss.ui +++ b/libs/ui/layerstyles/wdgBevelAndEmboss.ui @@ -6,8 +6,8 @@ 0 0 - 354 - 471 + 399 + 541
@@ -26,7 +26,7 @@ - &Style: + St&yle: cmbStyle @@ -114,7 +114,7 @@ - + 0 @@ -161,7 +161,7 @@ - + 0 @@ -173,15 +173,15 @@ - Sof&ten: + So&ften: intSoften - + 0 @@ -228,7 +228,7 @@ - + -179 @@ -260,7 +260,7 @@
- + -179 @@ -272,7 +272,7 @@ - Gloss Contour: + &Gloss Contour: cmbContour @@ -335,7 +335,7 @@ - + 0 @@ -388,7 +388,7 @@ - + 0 @@ -455,6 +455,17 @@ + KisIntParseSpinBox + QSpinBox +
kis_int_parse_spin_box.h
+
+ + KisSliderSpinBox + QWidget +
kis_slider_spin_box.h
+ 1 +
+ KColorButton QPushButton
kcolorbutton.h
@@ -465,12 +476,6 @@ QComboBox
kis_cmb_composite.h
- - KisSliderSpinBox - QWidget -
kis_slider_spin_box.h
- 1 -
diff --git a/libs/ui/layerstyles/wdgdropshadow.ui b/libs/ui/layerstyles/wdgdropshadow.ui --- a/libs/ui/layerstyles/wdgdropshadow.ui +++ b/libs/ui/layerstyles/wdgdropshadow.ui @@ -6,8 +6,8 @@ 0 0 - 367 - 350 + 435 + 390
@@ -99,7 +99,7 @@ - Ble&nd Mode: + &Blend Mode: cmbCompositeOp @@ -125,7 +125,7 @@ - &Opacity: + Opaci&ty: intOpacity @@ -157,7 +157,7 @@ - &Angle: + An&gle: dialAngle @@ -183,7 +183,7 @@ - + -179 @@ -247,7 +247,7 @@ - &Size: + S&ize: intSize @@ -287,6 +287,17 @@ + KisIntParseSpinBox + QSpinBox +
kis_int_parse_spin_box.h
+
+ + KisSliderSpinBox + QWidget +
kis_slider_spin_box.h
+ 1 +
+ KColorButton QPushButton
kcolorbutton.h
@@ -298,12 +309,6 @@
kis_cmb_composite.h
- KisSliderSpinBox - QWidget -
kis_slider_spin_box.h
- 1 -
- KisCmbContour QWidget
kis_cmb_contour.h
diff --git a/libs/ui/tests/CMakeLists.txt b/libs/ui/tests/CMakeLists.txt --- a/libs/ui/tests/CMakeLists.txt +++ b/libs/ui/tests/CMakeLists.txt @@ -271,3 +271,4 @@ set(kis_brush_hud_properties_config_test_SRCS kis_brush_hud_properties_config_test.cpp) kde4_add_unit_test(KisBrushHudPropertiesConfigTest TESTNAME krita-ui-BrushHudPropertiesConfigTest ${kis_brush_hud_properties_config_test_SRCS}) target_link_libraries(KisBrushHudPropertiesConfigTest kritaui Qt5::Test) + diff --git a/libs/ui/widgets/kis_double_widget.h b/libs/ui/widgets/kis_double_widget.h --- a/libs/ui/widgets/kis_double_widget.h +++ b/libs/ui/widgets/kis_double_widget.h @@ -28,6 +28,7 @@ class QHBoxLayout; class QDoubleSpinBox; +class KisDoubleParseSpinBox; class KRITAUI_EXPORT KisDoubleWidget : public QWidget { @@ -70,7 +71,7 @@ protected: QHBoxLayout* m_layout; QSlider* m_slider; - QDoubleSpinBox *m_spinBox; + KisDoubleParseSpinBox *m_spinBox; }; #endif // KIS_DOUBLE_WIDGET_H diff --git a/libs/ui/widgets/kis_double_widget.cc b/libs/ui/widgets/kis_double_widget.cc --- a/libs/ui/widgets/kis_double_widget.cc +++ b/libs/ui/widgets/kis_double_widget.cc @@ -26,6 +26,8 @@ #include #include +#include "kis_double_parse_spin_box.h" + KisDoubleWidget::KisDoubleWidget(QWidget* parent, const char* name) : QWidget(parent) { @@ -46,7 +48,7 @@ void KisDoubleWidget::init(double min, double max) { - m_spinBox = new QDoubleSpinBox(this); + m_spinBox = new KisDoubleParseSpinBox(this); m_spinBox->setMinimum(min); m_spinBox->setMaximum(max); m_spinBox->setSingleStep(0.05); diff --git a/libs/ui/widgets/kis_multi_double_filter_widget.h b/libs/ui/widgets/kis_multi_double_filter_widget.h --- a/libs/ui/widgets/kis_multi_double_filter_widget.h +++ b/libs/ui/widgets/kis_multi_double_filter_widget.h @@ -26,7 +26,9 @@ #include #include "kritaui_export.h" -class KisDelayedActionDoubleInput : public QDoubleSpinBox +#include "kis_double_parse_spin_box.h" + +class KisDelayedActionDoubleInput : public KisDoubleParseSpinBox { Q_OBJECT diff --git a/libs/ui/widgets/kis_multi_double_filter_widget.cc b/libs/ui/widgets/kis_multi_double_filter_widget.cc --- a/libs/ui/widgets/kis_multi_double_filter_widget.cc +++ b/libs/ui/widgets/kis_multi_double_filter_widget.cc @@ -28,7 +28,7 @@ #include KisDelayedActionDoubleInput::KisDelayedActionDoubleInput(QWidget * parent, const QString & name) - : QDoubleSpinBox(parent) + : KisDoubleParseSpinBox(parent) { setObjectName(name); m_timer = new QTimer(this); diff --git a/libs/ui/widgets/kis_multi_integer_filter_widget.h b/libs/ui/widgets/kis_multi_integer_filter_widget.h --- a/libs/ui/widgets/kis_multi_integer_filter_widget.h +++ b/libs/ui/widgets/kis_multi_integer_filter_widget.h @@ -25,9 +25,11 @@ #include #include +#include "kis_int_parse_spin_box.h" + #include -class KisDelayedActionIntegerInput : public QSpinBox +class KisDelayedActionIntegerInput : public KisIntParseSpinBox { Q_OBJECT diff --git a/libs/ui/widgets/kis_multi_integer_filter_widget.cc b/libs/ui/widgets/kis_multi_integer_filter_widget.cc --- a/libs/ui/widgets/kis_multi_integer_filter_widget.cc +++ b/libs/ui/widgets/kis_multi_integer_filter_widget.cc @@ -27,7 +27,7 @@ #include KisDelayedActionIntegerInput::KisDelayedActionIntegerInput(QWidget * parent, const QString & name) - : QSpinBox(parent) + : KisIntParseSpinBox(parent) { setObjectName(name); m_timer = new QTimer(this); diff --git a/libs/ui/widgets/kis_slider_spin_box.cpp b/libs/ui/widgets/kis_slider_spin_box.cpp --- a/libs/ui/widgets/kis_slider_spin_box.cpp +++ b/libs/ui/widgets/kis_slider_spin_box.cpp @@ -36,6 +36,8 @@ #include "KisPart.h" #include "input/kis_input_manager.h" +#include "kis_num_parser.h" + class KisAbstractSliderSpinBoxPrivate { public: enum Style { @@ -65,6 +67,7 @@ Style style; bool blockUpdateSignalOnDrag; bool isDragging; + bool parseInt; }; KisAbstractSliderSpinBox::KisAbstractSliderSpinBox(QWidget* parent, KisAbstractSliderSpinBoxPrivate* _d) @@ -93,7 +96,6 @@ connect(d->edit, SIGNAL(editingFinished()), this, SLOT(editLostFocus())); d->validator = new QDoubleValidator(d->edit); - d->edit->setValidator(d->validator); d->value = 0; d->minimum = 0; @@ -106,6 +108,8 @@ d->blockUpdateSignalOnDrag = false; d->isDragging = false; + d->parseInt = false; + setExponentRatio(1.0); //Set sane defaults @@ -496,10 +500,18 @@ { Q_D(KisAbstractSliderSpinBox); - QLocale locale; + //QLocale locale; bool ok = false; - qreal value = locale.toDouble(d->edit->text(), &ok) * d->factor; + //qreal value = locale.toDouble(d->edit->text(), &ok) * d->factor; + qreal value; + + if (d->parseInt) { + value = KisNumericParser::parseIntegerMathExpr(d->edit->text(), &ok) * d->factor; + } else { + value = KisNumericParser::parseSimpleMathExpr(d->edit->text(), &ok) * d->factor; + } + if (ok) { setInternalValue(value); } @@ -785,6 +797,10 @@ KisSliderSpinBox::KisSliderSpinBox(QWidget* parent) : KisAbstractSliderSpinBox(parent, new KisSliderSpinBoxPrivate) { + Q_D(KisSliderSpinBox); + + d->parseInt = true; + setRange(0,99); } @@ -884,6 +900,8 @@ KisDoubleSliderSpinBox::KisDoubleSliderSpinBox(QWidget* parent) : KisAbstractSliderSpinBox(parent, new KisDoubleSliderSpinBoxPrivate) { + Q_D(KisDoubleSliderSpinBox); + d->parseInt = false; } KisDoubleSliderSpinBox::~KisDoubleSliderSpinBox() diff --git a/libs/widgets/CMakeLists.txt b/libs/widgets/CMakeLists.txt --- a/libs/widgets/CMakeLists.txt +++ b/libs/widgets/CMakeLists.txt @@ -14,8 +14,6 @@ KoResourceTaggingManager.cpp KoResourceItemChooserContextMenu.cpp KoAspectButton.cpp - KoPageLayoutDialog.cpp - KoPageLayoutWidget.cpp KoPagePreviewWidget.cpp KoPositionSelector.cpp KoSliderCombo.cpp @@ -37,9 +35,7 @@ KoEditColorSetDialog.cpp KoTriangleColorSelector.cpp KoResourcePopupAction.cpp - KoStrokeConfigWidget.cpp KoFillConfigWidget.cpp - KoShadowConfigWidget.cpp KoIconToolTip.cpp KoResourceItemChooser.cpp KoResourceItemChooserSync.cpp @@ -57,9 +53,6 @@ KoLineStyleSelector.cpp KoLineStyleItemDelegate.cpp KoLineStyleModel.cpp - KoMarkerModel.cpp - KoMarkerItemDelegate.cpp - KoMarkerSelector.cpp KoDockWidgetTitleBar.cpp KoDockWidgetTitleBarButton.cpp KoResourceFiltering.cpp @@ -71,23 +64,36 @@ KoToolBoxFactory.cpp KoToolDocker.cpp + + KoPageLayoutWidget.cpp + KoPageLayoutDialog.cpp + KoShadowConfigWidget.cpp + KoStrokeConfigWidget.cpp + KoMarkerSelector.cpp + KoMarkerModel.cpp + KoMarkerItemDelegate.cpp + KoDocumentInfoDlg.cpp KoGlobal.cpp KoTableView.cpp WidgetsDebug.cpp kis_file_name_requester.cpp + + kis_double_parse_spin_box.cpp + kis_double_parse_unit_spin_box.cpp + kis_int_parse_spin_box.cpp ) ki18n_wrap_ui( kritawidgets_LIB_SRCS KoConfigAuthorPage.ui koDocumentInfoAboutWidget.ui koDocumentInfoAuthorWidget.ui KoEditColorSet.ui + wdg_file_name_requester.ui KoPageLayoutWidget.ui KoShadowConfigWidget.ui - wdg_file_name_requester.ui ) add_library(kritawidgets SHARED ${kritawidgets_LIB_SRCS}) diff --git a/libs/widgets/KoPageLayoutWidget.ui b/libs/widgets/KoPageLayoutWidget.ui --- a/libs/widgets/KoPageLayoutWidget.ui +++ b/libs/widgets/KoPageLayoutWidget.ui @@ -11,173 +11,206 @@
- + 0 - - - + 0 - - - - Unit: - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - units - - - - - - - - - - - - - - Follow style: - - - pageStyle - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - - - - Size: - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - sizes - - - - - - - - - - Width: + + 0 + + + 0 + + + + + 0 - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + 0 - - width + + 0 - - - - - + 0 - - + + + + &Unit: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + units + + - - + + - + 0 0 + + + + - Height: + &Follow style: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - height + pageStyle - - + + - - - - - - Orientation: - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - Portrait - - - - - - - Landscape - - - - - - - Facing pages: - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - Single sided - - - - - - - Facing pages - - - - - - - Text direction: - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - textDirection - - - - + + + + S&ize: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + sizes + + + + + + + + + + Width: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + width + + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + + + 0 + 0 + + + + &Height: + + + height + + + + + + + + + + + + Orientation: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + Po&rtrait + + + + + + + Landscape + + + + + + + Facing pages: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + Single sided + + + + + + + Facing pages + + + + + + + &Text direction: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + textDirection + + + + - + + 0 + 0 + @@ -195,90 +228,90 @@ - - + +
Margins - + Top: - - topMargin - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + topMargin + - + 999.990000000000009 - Binding edge: - - - bindingEdgeMargin + &Binding edge: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + bindingEdgeMargin + - + 999.990000000000009 - Page edge: - - - pageEdgeMargin + Pa&ge edge: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + pageEdgeMargin + - + 999.990000000000009 - Bottom: - - - bottomMargin + Botto&m: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + bottomMargin + - + 999.990000000000009 @@ -295,15 +328,21 @@ QSizePolicy::MinimumExpanding + + + 0 + 0 + + - KoUnitDoubleSpinBox + KisDoubleParseUnitSpinBox QDoubleSpinBox -
KoUnitDoubleSpinBox.h
+
kis_double_parse_unit_spin_box.h
diff --git a/libs/widgets/KoShadowConfigWidget.ui b/libs/widgets/KoShadowConfigWidget.ui --- a/libs/widgets/KoShadowConfigWidget.ui +++ b/libs/widgets/KoShadowConfigWidget.ui @@ -6,8 +6,8 @@ 0 0 - 221 - 78 + 238 + 98
@@ -72,7 +72,7 @@
- +
@@ -89,12 +89,12 @@
- +
- + 0 @@ -107,9 +107,9 @@ - KoUnitDoubleSpinBox + KisDoubleParseUnitSpinBox QDoubleSpinBox -
KoUnitDoubleSpinBox.h
+
kis_double_parse_unit_spin_box.h
diff --git a/libs/widgets/KoStrokeConfigWidget.cpp b/libs/widgets/KoStrokeConfigWidget.cpp --- a/libs/widgets/KoStrokeConfigWidget.cpp +++ b/libs/widgets/KoStrokeConfigWidget.cpp @@ -66,13 +66,16 @@ #include #include +// Krita +#include "kis_double_parse_unit_spin_box.h" + class CapNJoinMenu : public QMenu { public: CapNJoinMenu(QWidget *parent = 0); virtual QSize sizeHint() const; - KoUnitDoubleSpinBox *miterLimit; + KisDoubleParseUnitSpinBox *miterLimit; QButtonGroup *capGroup; QButtonGroup *joinGroup; }; @@ -137,7 +140,7 @@ // Miter limit // set min/max/step and value in points, then set actual unit - miterLimit = new KoUnitDoubleSpinBox(this); + miterLimit = new KisDoubleParseUnitSpinBox(this); miterLimit->setMinMaxStep(0.0, 1000.0, 0.5); miterLimit->setDecimals(2); miterLimit->setUnit(KoUnit(KoUnit::Point)); @@ -164,7 +167,7 @@ } KoLineStyleSelector *lineStyle; - KoUnitDoubleSpinBox *lineWidth; + KisDoubleParseUnitSpinBox *lineWidth; KoMarkerSelector *startMarkerSelector; KoMarkerSelector *endMarkerSelector; @@ -218,7 +221,7 @@ secondLineLayout->addWidget(l); // set min/max/step and value in points, then set actual unit - d->lineWidth = new KoUnitDoubleSpinBox(this); + d->lineWidth = new KisDoubleParseUnitSpinBox(this); d->lineWidth->setMinMaxStep(0.0, 1000.0, 0.5); d->lineWidth->setDecimals(2); d->lineWidth->setUnit(KoUnit(KoUnit::Point)); diff --git a/libs/widgets/KoUnitDoubleSpinBox.h b/libs/widgets/KoUnitDoubleSpinBox.h --- a/libs/widgets/KoUnitDoubleSpinBox.h +++ b/libs/widgets/KoUnitDoubleSpinBox.h @@ -39,6 +39,8 @@ * used unit. * It is adviced to use a QDoubleSpinBox in QtDesigner and then use the context-menu item: 'Promote to Custom Widget' and use the values: 'classname=KoUnitDoubleSpinBox', 'headerfile=KoUnitDoubleSpinBox.h' * This will generate code that uses this spinbox in the correct manner. + * + * This class need to be replaced as much as possible with \see KisDoubleParseUnitSpinBox to add math parsing ability. */ class KRITAWIDGETS_EXPORT KoUnitDoubleSpinBox : public QDoubleSpinBox { diff --git a/libs/widgets/kis_double_parse_spin_box.h b/libs/widgets/kis_double_parse_spin_box.h new file mode 100644 --- /dev/null +++ b/libs/widgets/kis_double_parse_spin_box.h @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2016 Laurent Valentin Jospin + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef KISDOUBLEPARSESPINBOX_H +#define KISDOUBLEPARSESPINBOX_H + +#include + +#include "kritawidgets_export.h" + +class QLabel; + +/*! + * \brief The KisDoubleParseSpinBox class is a cleverer doubleSpinBox, able to parse arithmetic expressions. + * + * Use this spinbox instead of the basic one from Qt if you want it to be able to parse arithmetic expressions. + */ +class KRITAWIDGETS_EXPORT KisDoubleParseSpinBox : public QDoubleSpinBox +{ + + Q_OBJECT +public: + KisDoubleParseSpinBox(QWidget* parent = 0); + ~KisDoubleParseSpinBox(); + + virtual double valueFromText(const QString & text) const; + virtual QString textFromValue(double val) const; + virtual QValidator::State validate ( QString & input, int & pos ) const; + + virtual void stepBy(int steps); + + void setValue(double value); //polymorphism won't work directly, we use a signal/slot hack to do so but if signals are disabled this function will still be useful. + + bool isLastValid() const{ return boolLastValid; } + +Q_SIGNALS: + + //! \brief signal emmitted when the last parsed expression create an error. + void errorWhileParsing(QString expr) const; + //! \brief signal emmitted when the last parsed expression is valid. + void noMoreParsingError() const; + +public Q_SLOTS: + + //! \brief useful to let the widget change it's stylesheet when an error occured in the last expression. + void setErrorStyle(); + //! \brief useful to let the widget reset it's stylesheet when there's no more error. + void clearErrorStyle(); + //! \brief say the widget to return to an error free state. + void clearError(); + +protected: + + mutable QString* lastExprParsed; + mutable bool boolLastValid; + mutable double oldValue; + + QLabel* warningIcon; + + QPalette oldPalette; + bool isOldPaletteSaved; + + QMargins oldMargins; + bool areOldMarginsSaved; +}; + +#endif // KISDOUBLEPARSESPINBOX_H diff --git a/libs/widgets/kis_double_parse_spin_box.cpp b/libs/widgets/kis_double_parse_spin_box.cpp new file mode 100644 --- /dev/null +++ b/libs/widgets/kis_double_parse_spin_box.cpp @@ -0,0 +1,244 @@ +/* + * Copyright (c) 2016 Laurent Valentin Jospin + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "kis_double_parse_spin_box.h" + +#include "kis_num_parser.h" + +#include +#include +#include +#include +#include + +KisDoubleParseSpinBox::KisDoubleParseSpinBox(QWidget *parent) : + QDoubleSpinBox(parent), + boolLastValid(true) +{ + + lastExprParsed = new QString("0.0"); + + connect(this, SIGNAL(noMoreParsingError()), + this, SLOT(clearErrorStyle())); + + //hack to let the clearError be called, even if the value changed method is the one from QDoubleSpinBox. + connect(this, SIGNAL(valueChanged(double)), + this, SLOT(clearError())); + + connect(this, SIGNAL(errorWhileParsing(QString)), + this, SLOT(setErrorStyle())); + + oldValue = value(); + + warningIcon = new QLabel(this); + + if (QFile(":/./16_light_warning.svg").exists()) { + warningIcon->setPixmap(QIcon(":/./16_light_warning.svg").pixmap(16, 16)); + } else { + warningIcon->setText("!"); + } + + warningIcon->setStyleSheet("background:transparent;"); + warningIcon->move(1, 1); + warningIcon->setVisible(false); + + isOldPaletteSaved = false; + areOldMarginsSaved = false; + +} + +KisDoubleParseSpinBox::~KisDoubleParseSpinBox() +{ + + //needed to avoid a segfault during destruction. + delete lastExprParsed; + +} + +double KisDoubleParseSpinBox::valueFromText(const QString & text) const +{ + + *lastExprParsed = text; + + bool ok; + + double ret; + + if ( (suffix().isEmpty() || !text.endsWith(suffix())) && + (prefix().isEmpty() || !text.startsWith(prefix())) ) { + + ret = KisNumericParser::parseSimpleMathExpr(text, &ok); + + } else { + + QString expr = text; + + if (text.endsWith(suffix())) { + expr.remove(text.size()-suffix().size(), suffix().size()); + } + + if(text.startsWith(prefix())){ + expr.remove(0, prefix().size()); + } + + *lastExprParsed = expr; + + ret = KisNumericParser::parseSimpleMathExpr(expr, &ok); + + } + + if(std::isnan(ret) || std::isinf(ret)){ + ok = false; + } + + if (!ok) { + if (boolLastValid) { + oldValue = value(); + } + + boolLastValid = false; + ret = oldValue; //in case of error set to minimum. + } else { + + if (!boolLastValid) { + oldValue = ret; + } + + boolLastValid = true; + } + + return ret; + +} +QString KisDoubleParseSpinBox::textFromValue(double val) const +{ + + if (!boolLastValid) { + emit errorWhileParsing(*lastExprParsed); + return *lastExprParsed; + } + + emit noMoreParsingError(); + + double v = KisNumericParser::parseSimpleMathExpr(cleanText()); + v = QString("%1").arg(v, 0, 'f', decimals()).toDouble(); + if (hasFocus() && (v == value() || (v >= maximum() && value() == maximum()) || (v <= minimum() && value() == minimum())) ) { //solve a very annoying bug where the formula can collapse while editing. With this trick the formula is not lost until focus is lost. + return cleanText(); + } + + return QDoubleSpinBox::textFromValue(val); +} + +QValidator::State KisDoubleParseSpinBox::validate ( QString & input, int & pos ) const +{ + + Q_UNUSED(input); + Q_UNUSED(pos); + + return QValidator::Acceptable; + +} + +void KisDoubleParseSpinBox::stepBy(int steps) +{ + + boolLastValid = true; //reset to valid state so we can use the up and down buttons. + emit noMoreParsingError(); + + QDoubleSpinBox::stepBy(steps); + +} + +void KisDoubleParseSpinBox::setValue(double value) +{ + if(value == oldValue && hasFocus()){ //avoid to reset the button when it set the value of something that will recall this slot. + return; + } + + if (!hasFocus()) { + clearError(); + } + + QDoubleSpinBox::setValue(value); +} + +void KisDoubleParseSpinBox::setErrorStyle() +{ + + if (!boolLastValid) { + //setStyleSheet(_oldStyleSheet + "Background: red; color: white; padding-left: 18px;"); + + if (!isOldPaletteSaved) { + oldPalette = palette(); + } + isOldPaletteSaved = true; + + QPalette nP = oldPalette; + nP.setColor(QPalette::Background, Qt::red); + nP.setColor(QPalette::Base, Qt::red); + nP.setColor(QPalette::Text, Qt::white); + setPalette(nP); + + if (!areOldMarginsSaved) { + oldMargins = lineEdit()->textMargins(); + } + areOldMarginsSaved = true; + + if (width() - height() >= 3*height()) { //if we have twice as much place as needed by the warning icon then display it. + QMargins newMargins = oldMargins; + newMargins.setLeft( newMargins.left() + height() - 4 ); + lineEdit()->setTextMargins(newMargins); + + int h = warningIcon->height(); + int hp = height()-2; + + if (h != hp) { + warningIcon->resize(hp, hp); + + if (QFile(":/./16_light_warning.svg").exists()) { + warningIcon->setPixmap(QIcon(":/./16_light_warning.svg").pixmap(hp-7, hp-7)); + } + } + + warningIcon->move(oldMargins.left()+4, 1); + warningIcon->setVisible(true); + } + } +} + +void KisDoubleParseSpinBox::clearErrorStyle() +{ + if (boolLastValid) { + warningIcon->setVisible(false); + + //setStyleSheet(""); + + setPalette(oldPalette); + isOldPaletteSaved = false; + + lineEdit()->setTextMargins(oldMargins); + areOldMarginsSaved = false; + } +} +void KisDoubleParseSpinBox::clearError() +{ + boolLastValid = true; + emit noMoreParsingError(); + oldValue = value(); + clearErrorStyle(); +} diff --git a/libs/widgets/kis_double_parse_unit_spin_box.h b/libs/widgets/kis_double_parse_unit_spin_box.h new file mode 100644 --- /dev/null +++ b/libs/widgets/kis_double_parse_unit_spin_box.h @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2016 Laurent Valentin Jospin + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef KIS_DOUBLEPARSEUNITSPINBOX_H +#define KIS_DOUBLEPARSEUNITSPINBOX_H + +#include + +#include "kis_double_parse_spin_box.h" +#include "kritawidgets_export.h" + +/*! + * \brief The KisDoubleParseUnitSpinBox class is an evolution of the \see KoUnitDoubleSpinBox, but inherit from \see KisDoubleParseSpinBox to be able to parse math expressions. + * + * This class store the + */ +class KRITAWIDGETS_EXPORT KisDoubleParseUnitSpinBox : public KisDoubleParseSpinBox +{ + + Q_OBJECT + +public: + KisDoubleParseUnitSpinBox(QWidget* parent = 0); + ~KisDoubleParseUnitSpinBox(); + + /** + * Set the new value in points which will then be converted to the current unit for display + * @param newValue the new value + * @see value() + */ + virtual void changeValue( double newValue ); + /** + * This spinbox shows the internal value after a conversion to the unit set here. + */ + virtual void setUnit(const KoUnit &unit); + + /// @return the current value, converted in points + double value( ) const; + + /// Set minimum value in points. + void setMinimum(double min); + + /// Set maximum value in points. + void setMaximum(double max); + + /// Set step size in the current unit. + void setLineStep(double step); + + /// Set step size in points. + void setLineStepPt(double step); + + /// Set minimum, maximum value and the step size (all in points) + void setMinMaxStep( double min, double max, double step ); + + /// reimplemented from superclass, will forward to KoUnitDoubleValidator + virtual QValidator::State validate(QString &input, int &pos) const; + + /** + * Transform the double in a nice text, using locale symbols + * @param value the number as double + * @return the resulting string + */ + virtual QString textFromValue( double value ) const; + /** + * Transfrom a string into a double, while taking care of locale specific symbols. + * @param str the string to transform into a number + * @return the value as double + */ + virtual double valueFromText( const QString& str ) const; + +Q_SIGNALS: + /// emitted like valueChanged in the parent, but this one emits the point value + void valueChangedPt( qreal ); + + +private: + class Private; + Private * const d; + +private Q_SLOTS: + // exists to do emits for valueChangedPt + void privateValueChanged(); +}; + +#endif // KIS_DOUBLEPARSEUNITSPINBOX_H diff --git a/libs/widgets/kis_double_parse_unit_spin_box.cpp b/libs/widgets/kis_double_parse_unit_spin_box.cpp new file mode 100644 --- /dev/null +++ b/libs/widgets/kis_double_parse_unit_spin_box.cpp @@ -0,0 +1,172 @@ +/* + * Copyright (c) 2016 Laurent Valentin Jospin + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "kis_double_parse_unit_spin_box.h" + + +class Q_DECL_HIDDEN KisDoubleParseUnitSpinBox::Private +{ +public: + Private(double low, double up, double step) + : lowerInPoints(low), + upperInPoints(up), + stepInPoints(step), + unit(KoUnit(KoUnit::Point)) + { + } + + double lowerInPoints; ///< lowest value in points + double upperInPoints; ///< highest value in points + double stepInPoints; ///< step in points + KoUnit unit; +}; + +KisDoubleParseUnitSpinBox::KisDoubleParseUnitSpinBox(QWidget *parent) : + KisDoubleParseSpinBox(parent), + d(new Private(-9999, 9999, 1)) +{ + setUnit( KoUnit(KoUnit::Point) ); + setAlignment( Qt::AlignRight ); + + connect(this, SIGNAL(valueChanged( double )), SLOT(privateValueChanged())); +} + +KisDoubleParseUnitSpinBox::~KisDoubleParseUnitSpinBox() +{ + delete d; +} + +void KisDoubleParseUnitSpinBox::changeValue( double newValue ) +{ + if (d->unit.toUserValue(newValue) == oldValue) { + return; + } + + KisDoubleParseSpinBox::setValue( d->unit.toUserValue(newValue) ); +} + +void KisDoubleParseUnitSpinBox::setUnit( const KoUnit & unit) +{ + if( unit == d->unit) return; + double oldValue = d->unit.fromUserValue( KisDoubleParseSpinBox::value() ); + + KisDoubleParseSpinBox::setMinimum( unit.toUserValue( d->lowerInPoints ) ); + KisDoubleParseSpinBox::setMaximum( unit.toUserValue( d->upperInPoints ) ); + + qreal step = unit.toUserValue( d->stepInPoints ); + + if (unit.type() == KoUnit::Pixel) { + // limit the pixel step by 1.0 + step = qMax(qreal(1.0), step); + } + + KisDoubleParseSpinBox::setSingleStep( step ); + d->unit = unit; + KisDoubleParseSpinBox::setValue( KoUnit::ptToUnit( oldValue, unit ) ); + setSuffix( unit.symbol().prepend(QLatin1Char(' ')) ); +} + +double KisDoubleParseUnitSpinBox::value( ) const +{ + return d->unit.fromUserValue( KisDoubleParseSpinBox::value() ); +} + +void KisDoubleParseUnitSpinBox::setMinimum(double min) +{ + d->lowerInPoints = min; + KisDoubleParseSpinBox::setMinimum( d->unit.toUserValue( min ) ); +} + +void KisDoubleParseUnitSpinBox::setMaximum(double max) +{ + d->upperInPoints = max; + KisDoubleParseSpinBox::setMaximum( d->unit.toUserValue( max ) ); +} + +void KisDoubleParseUnitSpinBox::setLineStep(double step) +{ + d->stepInPoints = KoUnit(KoUnit::Point).toUserValue(step); + KisDoubleParseSpinBox::setSingleStep( step ); +} + +void KisDoubleParseUnitSpinBox::setLineStepPt(double step) +{ + d->stepInPoints = step; + KisDoubleParseSpinBox::setSingleStep( d->unit.toUserValue( step ) ); +} + + +void KisDoubleParseUnitSpinBox::setMinMaxStep( double min, double max, double step ) +{ + setMinimum( min ); + setMaximum( max ); + setLineStepPt( step ); +} + + +QValidator::State KisDoubleParseUnitSpinBox::validate(QString &input, int &pos) const +{ + Q_UNUSED(pos); + + QRegExp regexp ("([ a-zA-Z]+)$"); // Letters or spaces at end + const int res = input.indexOf( regexp ); + + if ( res == -1 ) { + // Nothing like an unit? The user is probably editing the unit + return QValidator::Intermediate; + } + + QString expr ( input.left( res ) ); + const QString unitName ( regexp.cap( 1 ).trimmed().toLower() ); + + bool ok = true; + bool interm = false; + + QValidator::State exprState = KisDoubleParseSpinBox::validate(expr, pos); + + if (exprState == QValidator::Invalid) { + return exprState; + } else if (exprState == QValidator::Intermediate) { + interm = true; + } + + //check if we can parse the unit. + KoUnit::fromSymbol(unitName, &ok); + + if (!ok || interm) { + return QValidator::Intermediate; + } + + return QValidator::Acceptable; +} + +QString KisDoubleParseUnitSpinBox::textFromValue( double value ) const +{ + return KisDoubleParseSpinBox::textFromValue(value); +} + +double KisDoubleParseUnitSpinBox::valueFromText( const QString& str ) const +{ + //KisDoubleParseSpinBox is supposed to remove the suffix and prefix by itself. + return KisDoubleParseSpinBox::valueFromText(str); +} + +void KisDoubleParseUnitSpinBox::privateValueChanged() +{ + emit valueChangedPt( value() ); +} diff --git a/libs/widgets/kis_int_parse_spin_box.h b/libs/widgets/kis_int_parse_spin_box.h new file mode 100644 --- /dev/null +++ b/libs/widgets/kis_int_parse_spin_box.h @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2016 Laurent Valentin Jospin + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef KISINTPARSESPINBOX_H +#define KISINTPARSESPINBOX_H + +#include + +#include "kritawidgets_export.h" + +class QLabel; + +/*! + * \brief The KisDoubleParseSpinBox class is a cleverer doubleSpinBox, able to parse arithmetic expressions. + * + * Use this spinbox instead of the basic one from Qt if you want it to be able to parse arithmetic expressions. + */ +class KRITAWIDGETS_EXPORT KisIntParseSpinBox : public QSpinBox +{ + Q_OBJECT + +public: + KisIntParseSpinBox(QWidget *parent = 0); + ~KisIntParseSpinBox(); + + virtual int valueFromText(const QString & text) const; + virtual QString textFromValue(int val) const; + virtual QValidator::State validate ( QString & input, int & pos ) const; + + virtual void stepBy(int steps); + + void setValue(int val); //polymorphism won't work directly, we use a signal/slot hack to do so but if signals are disabled this function will still be useful. + + bool isLastValid() const{ return boolLastValid; } + +Q_SIGNALS: + + //! \brief signal emmitted when the last parsed expression create an error. + void errorWhileParsing(QString expr) const; + //! \brief signal emmitted when the last parsed expression is valid. + void noMoreParsingError() const; + +public Q_SLOTS: + + //! \brief useful to let the widget change it's stylesheet when an error occured in the last expression. + void setErrorStyle(); + //! \brief useful to let the widget reset it's stylesheet when there's no more error. + void clearErrorStyle(); + //! \brief say the widget to return to an error free state. + void clearError(); + +protected: + + mutable QString* lastExprParsed; + mutable bool boolLastValid; + mutable int oldVal; //store the last correctly evaluated value. + + QLabel* warningIcon; + + QPalette oldPalette; + bool isOldPaletteSaved; + + QMargins oldMargins; + bool areOldMarginsSaved; +}; + +#endif // KISINTPARSESPINBOX_H diff --git a/libs/widgets/kis_int_parse_spin_box.cpp b/libs/widgets/kis_int_parse_spin_box.cpp new file mode 100644 --- /dev/null +++ b/libs/widgets/kis_int_parse_spin_box.cpp @@ -0,0 +1,252 @@ +/* + * Copyright (c) 2016 Laurent Valentin Jospin + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "kis_int_parse_spin_box.h" + +#include "kis_num_parser.h" + +#include +#include +#include +#include +#include + +KisIntParseSpinBox::KisIntParseSpinBox(QWidget *parent) : + QSpinBox(parent), + boolLastValid(true) +{ + lastExprParsed = new QString("0"); + + connect(this, SIGNAL(noMoreParsingError()), + this, SLOT(clearErrorStyle())); + + //hack to let the clearError be called, even if the value changed method is the one from QSpinBox. + connect(this, SIGNAL(valueChanged(int)), + this, SLOT(clearError())); + + connect(this, SIGNAL(errorWhileParsing(QString)), + this, SLOT(setErrorStyle())); + + oldVal = value(); + + warningIcon = new QLabel(this); + + if (QFile(":/./16_light_warning.svg").exists()) { + warningIcon->setPixmap(QIcon(":/./16_light_warning.svg").pixmap(16, 16)); + } else { + warningIcon->setText("!"); + } + + warningIcon->setStyleSheet("background:transparent;"); + warningIcon->move(1, 1); + warningIcon->setVisible(false); + + isOldPaletteSaved = false; + areOldMarginsSaved = false; + +} + +KisIntParseSpinBox::~KisIntParseSpinBox() +{ + + //needed to avoid a segfault during destruction. + delete lastExprParsed; + +} + +int KisIntParseSpinBox::valueFromText(const QString & text) const +{ + + *lastExprParsed = text; + + bool ok; + + int val; + + if ( (suffix().isEmpty() || !text.endsWith(suffix())) && + (prefix().isEmpty() || !text.startsWith(prefix())) ) { + + val = KisNumericParser::parseIntegerMathExpr(text, &ok); + + } else { + + QString expr = text; + + if (text.endsWith(suffix())) { + expr.remove(text.size()-suffix().size(), suffix().size()); + } + + if(text.startsWith(prefix())){ + expr.remove(0, prefix().size()); + } + + *lastExprParsed = expr; + + val = KisNumericParser::parseIntegerMathExpr(expr, &ok); + + } + + if (text.trimmed().isEmpty()) { //an empty text is considered valid in this case. + ok = true; + } + + if (!ok) { + + if (boolLastValid == true) { + oldVal = value(); + } + + boolLastValid = false; + //emit errorWhileParsing(text); //if uncommented become red everytime the string is wrong. + val = oldVal; + } else { + + if (boolLastValid == false) { + oldVal = val; + } + + boolLastValid = true; + //emit noMoreParsingError(); + } + + return val; + +} + +QString KisIntParseSpinBox::textFromValue(int val) const +{ + + if (!boolLastValid) { + emit errorWhileParsing(*lastExprParsed); + return *lastExprParsed; + } + + emit noMoreParsingError(); + + int v = KisNumericParser::parseIntegerMathExpr(cleanText()); + if (hasFocus() && (v == value() || (v >= maximum() && value() == maximum()) || (v <= minimum() && value() == minimum())) ) { //solve a very annoying bug where the formula can collapse while editing. With this trick the formula is not lost until focus is lost. + return cleanText(); + } + + return QSpinBox::textFromValue(val); + +} + +QValidator::State KisIntParseSpinBox::validate ( QString & input, int & pos ) const +{ + + Q_UNUSED(input); + Q_UNUSED(pos); + + //this simple definition is sufficient for the moment + //TODO: see if needed to get something more complex. + return QValidator::Acceptable; + +} + +void KisIntParseSpinBox::stepBy(int steps) +{ + + boolLastValid = true; + emit noMoreParsingError(); + + QSpinBox::stepBy(steps); + +} + +void KisIntParseSpinBox::setValue(int val) +{ + + if(val == oldVal && hasFocus()){ //avoid to reset the button when it set the value of something that will recall this slot. + return; + } + + if (!hasFocus()) { + clearError(); + } + + QSpinBox::setValue(val); +} + +void KisIntParseSpinBox::setErrorStyle() +{ + + if (!boolLastValid) { + //setStyleSheet(_oldStyleSheet + "Background: red; color: white; padding-left: 18px;"); + + if (!isOldPaletteSaved) { + oldPalette = palette(); + } + isOldPaletteSaved = true; + + QPalette nP = oldPalette; + nP.setColor(QPalette::Background, Qt::red); + nP.setColor(QPalette::Base, Qt::red); + nP.setColor(QPalette::Text, Qt::white); + setPalette(nP); + + if (!areOldMarginsSaved) { + oldMargins = lineEdit()->textMargins(); + } + areOldMarginsSaved = true; + + if (width() - height() >= 3*height()) { //if we have twice as much place as needed by the warning icon then display it. + QMargins newMargins = oldMargins; + newMargins.setLeft( newMargins.left() + height() - 4 ); + lineEdit()->setTextMargins(newMargins); + + int h = warningIcon->height(); + int hp = height()-2; + + if (h != hp) { + warningIcon->resize(hp, hp); + + if (QFile(":/./16_light_warning.svg").exists()) { + warningIcon->setPixmap(QIcon(":/./16_light_warning.svg").pixmap(hp-7, hp-7)); + } + } + + warningIcon->move(oldMargins.left()+4, 1); + warningIcon->setVisible(true); + } + } +} + +void KisIntParseSpinBox::clearErrorStyle() +{ + if (boolLastValid) { + warningIcon->setVisible(false); + + //setStyleSheet(""); + + setPalette(oldPalette); + isOldPaletteSaved = false; + + lineEdit()->setTextMargins(oldMargins); + areOldMarginsSaved = false; + } +} + + +void KisIntParseSpinBox::clearError() +{ + boolLastValid = true; + emit noMoreParsingError(); + oldVal = value(); + clearErrorStyle(); +} diff --git a/libs/widgets/tests/CMakeLists.txt b/libs/widgets/tests/CMakeLists.txt --- a/libs/widgets/tests/CMakeLists.txt +++ b/libs/widgets/tests/CMakeLists.txt @@ -23,4 +23,10 @@ kde4_add_broken_unit_test(KoResourceTaggingTest TESTNAME libs-widgets-KoResourceTaggingTest ${KoResourceTaggingTest_SRCS}) target_link_libraries(KoResourceTaggingTest kritawidgets Qt5::Test) +########### next target ############### + +set(kis_parse_spin_boxes_test_SRCS kis_parse_spin_boxes_test.cpp) +kde4_add_unit_test(KisParseSpinBoxesTest TESTNAME krita-ui-KisParseSpinBoxesTest ${kis_parse_spin_boxes_test_SRCS}) +target_link_libraries(KisParseSpinBoxesTest kritaui Qt5::Test) + ########### end ############### diff --git a/libs/widgets/tests/kis_parse_spin_boxes_test.h b/libs/widgets/tests/kis_parse_spin_boxes_test.h new file mode 100644 --- /dev/null +++ b/libs/widgets/tests/kis_parse_spin_boxes_test.h @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2016 Laurent Valentin Jospin + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef KISPARSESPINBOXESTEST_H +#define KISPARSESPINBOXESTEST_H + +#include +#include + +class KisParseSpinBoxesTest : public QObject +{ + Q_OBJECT + +public: + explicit KisParseSpinBoxesTest(); + +private Q_SLOTS: + + void testDoubleParseNormal(); + void testDoubleParseProblem(); + void testDoubleParseWithSuffix(); + void testDoubleParseWithPrefix(); + void testIntParseNormal(); + void testIntParseProblem(); + void testIntParseWithSuffix(); + void testIntParseWithPrefix(); + +private: + + const static QStringList doubleExprs; + const static QStringList doubleWrongExprs; + const static QStringList intExprs; + const static QStringList intWrongExprs; +}; + +#endif // KISPARSESPINBOXESTEST_H diff --git a/libs/widgets/tests/kis_parse_spin_boxes_test.cpp b/libs/widgets/tests/kis_parse_spin_boxes_test.cpp new file mode 100644 --- /dev/null +++ b/libs/widgets/tests/kis_parse_spin_boxes_test.cpp @@ -0,0 +1,365 @@ +/* + * Copyright (c) 2016 Laurent Valentin Jospin + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "kis_parse_spin_boxes_test.h" + +#include "kis_num_parser.h" +#include "kis_double_parse_spin_box.h" +#include "kis_int_parse_spin_box.h" + +#include +#include + +const QStringList KisParseSpinBoxesTest::doubleExprs = {"1", + "-12", + "7.9 - 12", + "cos(90)*2", + "cos(acos(-1)+1*3^2.0)*2 + sin(3)/2"}; + +const QStringList KisParseSpinBoxesTest::doubleWrongExprs = {"abc", + "1/", + "7.9 + 12*", + "cos(90)*2 + ", + "23.0/0", + "0.0/0.0"}; + +const QStringList KisParseSpinBoxesTest::intExprs = {"12", + "-12", + "-12.3", + "12.7 - 25", + "12.7", + "12*1.5", + "12/2.5", + "518*2/3"}; + +const QStringList KisParseSpinBoxesTest::intWrongExprs = {"abc", + "12.5/2 +", + "12*", + "12/0"}; + +KisParseSpinBoxesTest::KisParseSpinBoxesTest() : QObject() +{ + +} + +void KisParseSpinBoxesTest::testDoubleParseNormal() +{ + + KisDoubleParseSpinBox spinBox; + spinBox.setDecimals(3); + spinBox.setMaximum(9999.0); + spinBox.setMinimum(-9999.0); + + for (int i = 0; i < doubleExprs.size(); i++) { + + spinBox.clearFocus(); + spinBox.clear(); //clear all + QTest::keyClicks(&spinBox, doubleExprs[i]); + spinBox.clearFocus(); + + double resultParser = KisNumericParser::parseSimpleMathExpr(doubleExprs[i]); + double valueSpinBox = spinBox.value(); + + bool test = resultParser == valueSpinBox || qAbs(resultParser - valueSpinBox) < 1e-2; + + QVERIFY2(test, QString("Failed with expression %1, result is %2, value is %3") + .arg(doubleExprs[i]).arg(resultParser).arg(valueSpinBox).toStdString().c_str()); + + spinBox.setValue(0); + + } + + +} + +void KisParseSpinBoxesTest::testDoubleParseProblem() +{ + + //error can happen with incomplete or incorrect expressions, inf or nan values. + + KisDoubleParseSpinBox spinBox; + spinBox.setMaximum(9999.0); + spinBox.setMinimum(-9999.0); + + for (int i = 0; i < doubleWrongExprs.size(); i++) { + + spinBox.clearFocus(); + spinBox.clear(); //clear all + QTest::keyClicks(&spinBox, doubleWrongExprs[i]); + spinBox.clearFocus(); + + QVERIFY2(!spinBox.isLastValid(), QString("SpinBox is in a valid state with expression %1, but shouldn't.") + .arg(doubleWrongExprs[i]).toStdString().c_str()); + + spinBox.setValue(0.0); + + QVERIFY2(spinBox.isLastValid(), QString("SpinBox unsable to recover error free state after a value reset.") + .toStdString().c_str()); + + spinBox.setValue(0); + + } + +} +void KisParseSpinBoxesTest::testDoubleParseWithSuffix(){ + + QString suff = "px"; + + KisDoubleParseSpinBox spinBox; + spinBox.setDecimals(3); + spinBox.setMaximum(9999.0); + spinBox.setMinimum(-9999.0); + spinBox.setSuffix(suff); + + for (int i = 0; i < doubleExprs.size(); i++) { + + spinBox.clearFocus(); + spinBox.clear(); //clear all + QTest::keyClicks(&spinBox, doubleExprs[i]); + spinBox.clearFocus(); + + double resultParser = KisNumericParser::parseSimpleMathExpr(doubleExprs[i]); + double valueSpinBox = spinBox.value(); + + bool test = resultParser == valueSpinBox || qAbs(resultParser - valueSpinBox) < 1e-2; + + QVERIFY2(test, QString("Failed with expression %1, result is %2, value is %3") + .arg(doubleExprs[i]).arg(resultParser).arg(valueSpinBox).toStdString().c_str()); + + spinBox.setValue(0); + + } + + //verify that the suffix don't appear in the clean text in case of error. + for (int i = 0; i < doubleWrongExprs.size(); i++) { + + if (doubleWrongExprs[i].endsWith(suff)) { + continue; + } + + spinBox.clearFocus(); + spinBox.clear(); //clear all + QTest::keyClicks(&spinBox, doubleWrongExprs[i]); + spinBox.clearFocus(); + + QVERIFY2(!spinBox.cleanText().endsWith(suff), "SpinBox failed to remove suffix from clean text in error state."); + + spinBox.setValue(0.0); + + } +} +void KisParseSpinBoxesTest::testDoubleParseWithPrefix() +{ + + QString preff = "px"; + + KisDoubleParseSpinBox spinBox; + spinBox.setDecimals(3); + spinBox.setMaximum(9999.0); + spinBox.setMinimum(-9999.0); + spinBox.setPrefix(preff); + + for (int i = 0; i < doubleExprs.size(); i++) { + + spinBox.clearFocus(); + spinBox.clear(); //clear all + QTest::keyClicks(&spinBox, doubleExprs[i]); + spinBox.clearFocus(); + + double resultParser = KisNumericParser::parseSimpleMathExpr(doubleExprs[i]); + double valueSpinBox = spinBox.value(); + + bool test = resultParser == valueSpinBox || qAbs(resultParser - valueSpinBox) < 1e-2; + + QVERIFY2(test, QString("Failed with expression %1, result is %2, value is %3") + .arg(doubleExprs[i]).arg(resultParser).arg(valueSpinBox).toStdString().c_str()); + + spinBox.setValue(0); + + } + + //verify that the prefix don't appear in the clean text in case of error. + for (int i = 0; i < doubleWrongExprs.size(); i++) { + + if (doubleWrongExprs[i].endsWith(preff)) { + continue; + } + + spinBox.clearFocus(); + spinBox.clear(); //clear all + QTest::keyClicks(&spinBox, doubleWrongExprs[i]); + spinBox.clearFocus(); + + QVERIFY2(!spinBox.cleanText().startsWith(preff), "SpinBox failed to remove prefix from clean text in error state."); + + spinBox.setValue(0.0); + + } +} + +void KisParseSpinBoxesTest::testIntParseNormal() +{ + + KisIntParseSpinBox spinBox; + spinBox.setMaximum(999); + spinBox.setMinimum(-999); + + for (int i = 0; i < intExprs.size(); i++) { + + spinBox.clearFocus(); + spinBox.clear(); //clear all + QTest::keyClicks(&spinBox, intExprs[i]); + spinBox.clearFocus(); + + int resultParser = KisNumericParser::parseIntegerMathExpr(intExprs[i]); + int valueSpinBox = spinBox.value(); + + bool test = resultParser == valueSpinBox; + + QVERIFY2(test, QString("Failed with expression %1, result is %2, value is %3") + .arg(intExprs[i]).arg(resultParser).arg(valueSpinBox).toStdString().c_str()); + + spinBox.setValue(0); + } + +} + +void KisParseSpinBoxesTest::testIntParseProblem() +{ + + //errors can happen with incorrect or incomplete expressions, or division by 0. + + KisIntParseSpinBox spinBox; + spinBox.setMaximum(999); + spinBox.setMinimum(-999); + + for (int i = 0; i < intWrongExprs.size(); i++) { + + spinBox.clearFocus(); + spinBox.clear(); //clear all + QTest::keyClicks(&spinBox, intWrongExprs[i]); + spinBox.clearFocus(); + + QVERIFY2(!spinBox.isLastValid(), QString("SpinBox is in a valid state with expression %1, but shouldn't.") + .arg(intWrongExprs[i]).toStdString().c_str()); + + spinBox.setValue(0); + + QVERIFY2(spinBox.isLastValid(), QString("SpinBox unsable to recover error free state after a value reset.") + .toStdString().c_str()); + + spinBox.setValue(0); + + } + +} + +void KisParseSpinBoxesTest::testIntParseWithSuffix() +{ + QString suff = "px"; + + KisIntParseSpinBox spinBox; + spinBox.setMaximum(999); + spinBox.setMinimum(-999); + spinBox.setSuffix(suff); + + for (int i = 0; i < intExprs.size(); i++) { + + spinBox.clearFocus(); + spinBox.clear(); //clear all + QTest::keyClicks(&spinBox, intExprs[i]); + spinBox.clearFocus(); + + int resultParser = KisNumericParser::parseIntegerMathExpr(intExprs[i]); + int valueSpinBox = spinBox.value(); + + bool test = resultParser == valueSpinBox; + + QVERIFY2(test, QString("Failed with expression %1, result is %2, value is %3") + .arg(intExprs[i]).arg(resultParser).arg(valueSpinBox).toStdString().c_str()); + + spinBox.setValue(0); + } + + //verify that the suffix don't appear in the clean text in case of error. + for (int i = 0; i < intWrongExprs.size(); i++) { + + if (intWrongExprs[i].endsWith(suff)) { + continue; + } + + spinBox.clearFocus(); + spinBox.clear(); //clear all + QTest::keyClicks(&spinBox, intWrongExprs[i]); + spinBox.clearFocus(); + + QVERIFY2(!spinBox.cleanText().endsWith(suff), "SpinBox failed to remove suffix from clean text in error state."); + + spinBox.setValue(0.0); + + } + +} +void KisParseSpinBoxesTest::testIntParseWithPrefix() +{ + QString preff = "px"; + + KisIntParseSpinBox spinBox; + spinBox.setMaximum(999); + spinBox.setMinimum(-999); + spinBox.setPrefix(preff); + + for (int i = 0; i < intExprs.size(); i++) { + + spinBox.clearFocus(); + spinBox.clear(); //clear all + QTest::keyClicks(&spinBox, intExprs[i]); + spinBox.clearFocus(); + + int resultParser = KisNumericParser::parseIntegerMathExpr(intExprs[i]); + int valueSpinBox = spinBox.value(); + + bool test = resultParser == valueSpinBox; + + QVERIFY2(test, QString("Failed with expression %1, result is %2, value is %3") + .arg(intExprs[i]).arg(resultParser).arg(valueSpinBox).toStdString().c_str()); + + spinBox.setValue(0); + } + + //verify that the prefix don't appear in the clean text in case of error. + for (int i = 0; i < intWrongExprs.size(); i++) { + + if (intWrongExprs[i].startsWith(preff)) { + continue; + } + + spinBox.clearFocus(); + spinBox.clear(); //clear all + QTest::keyClicks(&spinBox, intWrongExprs[i]); + spinBox.clearFocus(); + + QVERIFY2(!spinBox.cleanText().startsWith(preff), "SpinBox failed to remove prefix from clean text in error state."); + + spinBox.setValue(0.0); + + } + +} + +QTEST_MAIN(KisParseSpinBoxesTest) diff --git a/libs/widgetutils/CMakeLists.txt b/libs/widgetutils/CMakeLists.txt --- a/libs/widgetutils/CMakeLists.txt +++ b/libs/widgetutils/CMakeLists.txt @@ -20,6 +20,8 @@ KoFileDialog.cpp KoResourcePaths.cpp + kis_num_parser.cpp + config/kcolorscheme.cpp config/kcolorschememanager.cpp config/khelpclient.cpp diff --git a/libs/widgetutils/kis_num_parser.h b/libs/widgetutils/kis_num_parser.h new file mode 100644 --- /dev/null +++ b/libs/widgetutils/kis_num_parser.h @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2016 Laurent Valentin Jospin + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef KIS_NUMPARSER_H +#define KIS_NUMPARSER_H + +#include + +#include "kritawidgetutils_export.h" + +/*! + * \brief the namespace contains functions to transform math expression written as QString in numbers. + * + * Computation is done in a recursive way, maybe not the most efficient way compared to infix to postfix conversion before parsing. + * (TODO: look if it need to be changed). + */ +namespace KisNumericParser { + + //! \brief parse an expression to a double. + KRITAWIDGETUTILS_EXPORT double parseSimpleMathExpr(QString const& expr, bool* noProblem = 0); + + //! \brief parse an expression to an int. + KRITAWIDGETUTILS_EXPORT int parseIntegerMathExpr(QString const& expr, bool* noProblem = 0); +} + +#endif // KIS_NUMPARSER_H + diff --git a/libs/widgetutils/kis_num_parser.cpp b/libs/widgetutils/kis_num_parser.cpp new file mode 100644 --- /dev/null +++ b/libs/widgetutils/kis_num_parser.cpp @@ -0,0 +1,567 @@ +/* + * Copyright (c) 2016 Laurent Valentin Jospin + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "kis_num_parser.h" + +//#include +#include +#include +#include +#include +#include + +#include + +using namespace std; + +const QVector opLevel1 = {'+', '-'}; +const QVector opLevel2 = {'*', '/'}; + +const QStringList supportedFuncs = {"", "cos", "sin", "tan", "acos", "asin", "atan", "exp", "ln", "log10", "abs"}; + +const QRegExp funcExpr("(-)?([a-zA-Z]*)?\\((.+)\\)"); +const QRegExp numberExpr("(-)?([0-9]+\\.?[0-9]*(e[0-9]*)?)"); + +const QRegExp funcExprInteger("(-)?\\((.+)\\)"); +const QRegExp integerExpr("(-)?([0-9]+)"); + +//double functions +double treatFuncs(QString const& expr, bool & noProblem); +double treatLevel1(QString const& expr, bool & noProblem); +double treatLevel2(QString const& expr, bool & noProblem); +double treatLevel3(QString const& expr, bool & noProblem); + +//int functions +double treatLevel1Int(QString const& expr, bool & noProblem); +double treatLevel2Int(QString const& expr, bool & noProblem); +double treatFuncsInt(QString const& expr, bool & noProblem); + +namespace KisNumericParser { + +/*! + * \param expr the expression to parse + * \param noProblem if provided, the value pointed to will be se to true is no problem appeared, false otherwise. + * \return the numerical value the expression eval to (or 0 in case of error). + */ +double parseSimpleMathExpr(const QString &expr, bool *noProblem) +{ + + bool ok = true; //intermediate variable to pass by reference to the sublevel parser (if no pointer is provided). + + //then go down each 3 levels of operation priority. + if (noProblem != nullptr) { + return treatLevel1(expr, *noProblem); + } + + return treatLevel1(expr, ok); + +} + +/*! + * \param expr the expression to parse + * \param noProblem if provided, the value pointed to will be se to true is no problem appeared, false otherwise. + * \return the numerical value the expression eval to (or 0 in case of error). + */ +int parseIntegerMathExpr(QString const& expr, bool* noProblem) +{ + + bool ok = true; //intermediate variable to pass by reference to the sublevel parser (if no pointer is provided). + + if (noProblem != nullptr) { + return qRound(treatLevel1Int(expr, *noProblem)); + } + + return qRound(treatLevel1Int(expr, ok)); + +} + +} //namespace KisNumericParser. + + +//intermediate functions + +/*! + * \brief extractSubExprLevel1 extract from an expression the part of an expression that need to be treated recursivly before computing level 1 operations (+, -). + * \param expr The expression to treat, the part returned will be removed. + * \param nextOp This reference, in case of sucess, will hold the first level operation identified as separator ('+' or '-') + * \param noProblem A reference to a bool, set to true if there was no problem, false otherwise. + * \return The first part of the expression that doesn't contain first level operations not nested within parenthesis. + */ +inline QString extractSubExprLevel1(QString & expr, char & nextOp, bool & noProblem){ + + QString ret; + + int subCount = 0; + + bool lastMetIsNumber = false; + + for(int i = 0; i < expr.size(); i++){ + + if (expr.at(i) == '(') { + subCount++; + } + + if (expr.at(i) == ')') { + subCount--; + } + + if (subCount < 0) { + noProblem = false; + return ret; + } + + if(i == expr.size()-1 && subCount == 0){ + ret = expr; + expr.clear(); + break; + } + + if( (expr.at(i) == '+' || expr.at(i) == '-') && + subCount == 0) { + + if (expr.at(i) == '-' && + i < expr.size()-1) { + + bool cond = !expr.at(i+1).isSpace(); + + if (cond && !lastMetIsNumber) { + continue; + } + + } + + ret = expr.mid(0, i).trimmed(); + nextOp = expr.at(i).toLatin1(); + expr = expr.mid(i+1); + break; + + } + + if (expr.at(i).isDigit()) { + lastMetIsNumber = true; + } else if (expr.at(i) != '.' && + !expr.at(i).isSpace()) { + lastMetIsNumber = false; + } + + } + + noProblem = true; + return ret; +} + + +/*! + * \brief extractSubExprLevel2 extract from an expression the part of an expression that need to be treated recursivly before computing level 2 operations (*, /). + * \param expr The expression to treat, the part returned will be removed. + * \param nextOp This reference, in case of sucess, will hold the first level operation identified as separator ('*' or '/') + * \param noProblem A reference to a bool, set to true if there was no problem, false otherwise. + * \return The first part of the expression that doesn't contain second level operations not nested within parenthesis. + */ +inline QString extractSubExprLevel2(QString & expr, char & nextOp, bool & noProblem){ + + QString ret; + + int subCount = 0; + + for(int i = 0; i < expr.size(); i++){ + + if (expr.at(i) == '(') { + subCount++; + } + + if (expr.at(i) == ')') { + subCount--; + } + + if (subCount < 0) { + noProblem = false; + return ret; + } + + if(i == expr.size()-1 && subCount == 0){ + ret = expr; + expr.clear(); + break; + } + + if( (expr.at(i) == '*' || expr.at(i) == '/') && + subCount == 0) { + + ret = expr.mid(0, i).trimmed(); + nextOp = expr.at(i).toLatin1(); + expr = expr.mid(i+1); + break; + + } + + } + + noProblem = true; + return ret; +} + +/*! + * \brief treatLevel1 treat an expression at the first level of recursion. + * \param expr The expression to treat. + * \param noProblem A reference to a bool set to true if no problem happened, false otherwise. + * \return The value of the parsed expression or subexpression or 0 in case of error. + */ +double treatLevel1(const QString &expr, bool & noProblem) +{ + + noProblem = true; + + QString exprDestructable = expr; + + char nextOp = '+'; + double result = 0.0; + + while (!exprDestructable.isEmpty()) { + + double sign = (nextOp == '-') ? -1 : 1; + QString part = extractSubExprLevel1(exprDestructable, nextOp, noProblem); + + if (!noProblem) { + return 0.0; + } + + if (sign > 0) { + result += treatLevel2(part, noProblem); + } else { + result -= treatLevel2(part, noProblem); + } + + if(!noProblem){ + return 0.0; + } + } + + return result; + +} + +/*! + * \brief treatLevel2 treat a subexpression at the second level of recursion. + * \param expr The subexpression to treat. + * \param noProblem A reference to a bool set to true if no problem happened, false otherwise. + * \return The value of the parsed subexpression or 0 in case of error. + * + * The expression should not contain first level operations not nested in parenthesis. + */ +double treatLevel2(QString const& expr, bool & noProblem) +{ + + noProblem = true; + + QString exprDestructable = expr; + + char nextOp = '*'; + + QString part = extractSubExprLevel2(exprDestructable, nextOp, noProblem); + + double result = treatLevel3(part, noProblem); + + while (!exprDestructable.isEmpty()) { + + if (!noProblem) { + return 0.0; + } + + bool needToMultiply = (nextOp == '*'); + part = extractSubExprLevel2(exprDestructable, nextOp, noProblem); + + if (!noProblem) { + return 0.0; + } + + if (needToMultiply) { + result *= treatLevel3(part, noProblem); + } else { + result /= treatLevel3(part, noProblem); + } + } + + return result; +} + +/*! + * \brief treatLevel3 treat a subexpression at the third level of recursion. + * \param expr The subexpression to treat. + * \param noProblem A reference to a bool set to true if no problem happened, false otherwise. + * \return The value of the parsed subexpression or 0 in case of error. + * + * The expression should not contain first or second level operations not nested in parenthesis. + */ +double treatLevel3(const QString &expr, bool & noProblem) +{ + + noProblem = true; + + int indexPower = -1; + int indexCount = 0; + int subLevels = 0; + + for (int i = 0; i < expr.size(); i++) { + if (expr.at(i) == '(') { + subLevels++; + } else if(expr.at(i) == ')') { + subLevels--; + if (subLevels < 0) { + noProblem = false; + return 0.0; + } + } else if (expr.at(i) == '^') { + if (subLevels == 0) { + indexPower = i; + indexCount++; + } + } + } + + if (indexCount > 1 || indexPower + 1 >= expr.size()) { + noProblem = false; + return 0.0; + } + + if (indexPower > -1) { + + QStringList subExprs; + subExprs << expr.mid(0,indexPower); + subExprs << expr.mid(indexPower+1); + + bool noProb1 = true; + bool noProb2 = true; + + double base = treatFuncs(subExprs[0], noProb1); + double power = treatFuncs(subExprs[1], noProb2); + + return qPow(base, power); + + } else { + return treatFuncs(expr, noProblem); + } + + noProblem = false; + return 0.0; + +} + +/*! + * \brief treatFuncs treat the last level of recursion: parenthesis and functions. + * \param expr The expression to parse. + * \param noProblem A reference to a bool set to true if no problem happened, false otherwise. + * \return The value of the parsed subexpression or 0 in case of error. + * + * The expression should not contain operators not nested anymore. The subexpressions within parenthesis will be treated by recalling the level 1 function. + */ +double treatFuncs(QString const& expr, bool & noProblem) +{ + + noProblem = true; + + QRegExp funcExp = funcExpr; //copy the expression in the current execution stack, to avoid errors for example when multiple thread call this function. + QRegExp numExp = numberExpr; + + if (funcExp.exactMatch(expr.trimmed())) { + + int sign = funcExp.capturedTexts()[1].isEmpty() ? 1 : -1; + QString func = funcExp.capturedTexts()[2].toLower(); + QString subExpr = funcExp.capturedTexts()[3]; + + double val = treatLevel1(subExpr, noProblem); + + if (!noProblem) { + return 0.0; + } + + if (func.isEmpty()) { + return sign*val; + } + + if (!supportedFuncs.contains(func)) { + noProblem = false; + return 0.0; + } + + //trigonometry is done in degree + if (func == "cos") { + val = qCos(val/180*qAcos(-1)); + } else if (func == "sin") { + val = qSin(val/180*qAcos(-1)); + } else if (func == "tan") { + val = qTan(val/180*qAcos(-1)); + } else if(func == "acos") { + val = qAcos(val)*180/qAcos(-1); + } else if (func == "asin") { + val = qAsin(val)*180/qAcos(-1); + } else if (func == "atan") { + val = qAtan(val)*180/qAcos(-1); + } else if (func == "exp") { + val = qExp(val); + } else if (func == "ln") { + val = qLn(val); + } else if (func == "log10") { + val = qLn(val)/qLn(10.0); + } else if (func == "abs") { + val = qAbs(val); + } + + return sign*val; + } else if(numExp.exactMatch(expr.trimmed())) { + return expr.toDouble(&noProblem); + } + + noProblem = false; + return 0.0; + +} + +//int functions +/*! + * \brief treatLevel1 treat an expression at the first level of recursion. + * \param expr The expression to treat. + * \param noProblem A reference to a bool set to true if no problem happened, false otherwise. + * \return The value of the parsed expression or subexpression or 0 in case of error. + */ +double treatLevel1Int(QString const& expr, bool & noProblem) +{ + + noProblem = true; + + QString exprDestructable = expr; + + char nextOp = '+'; + double result = 0.0; + + while (!exprDestructable.isEmpty()) { + + double sign = (nextOp == '-') ? -1 : 1; + QString part = extractSubExprLevel1(exprDestructable, nextOp, noProblem); + + if( !noProblem) { + return 0.0; + } + + if (sign > 0) { + result += treatLevel2Int(part, noProblem); + } else { + result -= treatLevel2Int(part, noProblem); + } + + if(!noProblem){ + return 0.0; + } + } + + return result; + +} + +/*! + * \brief treatLevel2 treat a subexpression at the second level of recursion. + * \param expr The subexpression to treat. + * \param noProblem A reference to a bool set to true if no problem happened, false otherwise. + * \return The value of the parsed subexpression or 0 in case of error. + * + * The expression should not contain first level operations not nested in parenthesis. + */ +double treatLevel2Int(const QString &expr, bool &noProblem) +{ + + noProblem = true; + + QString exprDestructable = expr; + + char nextOp = '*'; + + QString part = extractSubExprLevel2(exprDestructable, nextOp, noProblem); + + double result = treatFuncsInt(part, noProblem); + + while (!exprDestructable.isEmpty()) { + + if (!noProblem) { + return 0.0; + } + + bool needToMultiply = (nextOp == '*'); + part = extractSubExprLevel2(exprDestructable, nextOp, noProblem); + + if (!noProblem) { + return 0.0; + } + + if (needToMultiply) { + result *= treatFuncsInt(part, noProblem); + } else { + + double val = treatFuncsInt(part, noProblem); + + if(std::isinf(result/val) || std::isnan(result/val)){ + noProblem = false; + return 0.0; + } + + result /= val; + } + } + + return result; + +} + +/*! + * \brief treatFuncs treat the last level of recursion: parenthesis + * \param expr The expression to parse. + * \param noProblem A reference to a bool set to true if no problem happened, false otherwise. + * \return The value of the parsed subexpression or 0 in case of error. + * + * The expression should not contain operators not nested anymore. The subexpressions within parenthesis will be treated by recalling the level 1 function. + */ +double treatFuncsInt(QString const& expr, bool & noProblem) +{ + + noProblem = true; + + QRegExp funcExpInteger = funcExprInteger; + QRegExp integerExp = integerExpr; + QRegExp numberExp = numberExpr; + + if (funcExpInteger.exactMatch(expr.trimmed())) { + + int sign = funcExpInteger.capturedTexts()[1].isEmpty() ? 1 : -1; + QString subExpr = funcExpInteger.capturedTexts()[2]; + + double val = treatLevel1Int(subExpr, noProblem); + + if (!noProblem) { + return 0; + } + + return sign*val; + + } else if(numberExp.exactMatch(expr.trimmed())) { + double value = QVariant(expr).toDouble(&noProblem); + return value; + } + + noProblem = false; + return 0; + +} diff --git a/libs/widgetutils/tests/CMakeLists.txt b/libs/widgetutils/tests/CMakeLists.txt --- a/libs/widgetutils/tests/CMakeLists.txt +++ b/libs/widgetutils/tests/CMakeLists.txt @@ -7,3 +7,8 @@ kde4_add_unit_test(KoPropertiesTest TESTNAME libs-widgetutils-KoPropertiesTest ${kopropertiestest_SRCS}) target_link_libraries(KoPropertiesTest kritawidgetutils Qt5::Test) +########### next target ############### + +set(kis_simple_math_parser_test_SRCS kis_simple_math_parser_test.cpp) +kde4_add_unit_test(KisSimpleMathParserTest TESTNAME krita-ui-KisSimpleMathParserTest ${kis_simple_math_parser_test_SRCS}) +target_link_libraries(KisSimpleMathParserTest kritaui Qt5::Test) diff --git a/libs/widgetutils/tests/kis_simple_math_parser_test.h b/libs/widgetutils/tests/kis_simple_math_parser_test.h new file mode 100644 --- /dev/null +++ b/libs/widgetutils/tests/kis_simple_math_parser_test.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2016 Laurent Valentin Jospin + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef KISSIMPLEMATHPARSERTEST_H +#define KISSIMPLEMATHPARSERTEST_H + +#include + +class KisSimpleMathParserTest : public QObject +{ + Q_OBJECT + +public: + KisSimpleMathParserTest(); + +private Q_SLOTS: + void testDoubleComputation(); + void testIntComputation(); + void testIntFlooring(); +}; + +#endif // KISSIMPLEMATHPARSERTEST_H diff --git a/libs/widgetutils/tests/kis_simple_math_parser_test.cpp b/libs/widgetutils/tests/kis_simple_math_parser_test.cpp new file mode 100644 --- /dev/null +++ b/libs/widgetutils/tests/kis_simple_math_parser_test.cpp @@ -0,0 +1,154 @@ +/* + * Copyright (c) 2016 Laurent Valentin Jospin + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "kis_simple_math_parser_test.h" + +#include "kis_num_parser.h" + +#include +#include + +KisSimpleMathParserTest::KisSimpleMathParserTest() : QObject() +{ + +} + +void KisSimpleMathParserTest::testDoubleComputation() +{ + + QStringList exprs = {"1", + "2 + 3.4", + "2 + -3.4", + "2 - -3.4", + "5-2", + "7 + 2 - 5", + "4.6 * 2 + 13", + "4.6 / 2 + 3*3", + "4.6 / 0.0 + 3*3", + "-4.6 / 0.0 + 3*3", + "-4.6 / -0.0 + 3*3", + "4.6 / -0.0 + 3*3", + "0.0 / 0.0 + 3*3", + "2^3 - 4 * 1.5", + "2^3.0 - 4 * 1.5", + "cos(1)*2", + "-cos(1)*2", + "cos(1)^3*2", + "cos(1)^3.0*2", + "cos(1)*2 + sin(3)/2", + "cos(acos(-1)+1*3^2.0)*2 + sin(3)/2", + "cos(acos(-1)+1*3^2.0)^2 + sin(3)/2"}; + + QVector expected = {1, + 2 + 3.4, + 2 + -3.4, + 2 - -3.4, + 5-2, + 7 + 2 - 5, + 4.6 * 2 + 13, + 4.6 / 2 + 3*3, + 4.6 / 0.0 + 3*3, + -4.6 / 0.0 + 3*3, + -4.6 / -0.0 + 3*3, + 4.6 / -0.0 + 3*3, + 0.0 / 0.0 + 3*3, + qPow(2,3) - 4 * 1.5, + qPow(2,3.0) - 4 * 1.5, + qCos(1.0/180*qAcos(-1))*2, + -qCos(1.0/180*qAcos(-1))*2, + qPow(qCos(1.0/180*qAcos(-1)),3)*2, + qPow(qCos(1.0/180*qAcos(-1)),3.0)*2, + qCos(1.0/180*qAcos(-1))*2 + qSin(3.0/180*qAcos(-1))/2, + qCos((qAcos(-1.0)*180/qAcos(-1)+1*qPow(3,2.0))/180*qAcos(-1))*2 + qSin(3.0/180*qAcos(-1))/2, + qPow(qCos((qAcos(-1.0)*180/qAcos(-1)+1*qPow(3,2.0))/180*qAcos(-1)),2) + qSin(3.0/180*qAcos(-1))/2}; + + for (int i = 0; i < expected.size(); i++) { + + double result = KisNumericParser::parseSimpleMathExpr(exprs[i]); + + bool test = result == expected[i] || qAbs(result - expected[i]) < 1e-12 || (std::isnan(result) && std::isnan(expected[i])); + + QVERIFY2(test, QString("Failed when %1 should equal %2 but evaluated to %3.").arg(exprs[i]).arg(expected[i]).arg(result).toStdString().c_str()); + } +} + +void KisSimpleMathParserTest::testIntComputation() +{ + + QStringList exprs = {"1", + "2 + 3", + "2 + -3", + "2 - -3", + "5-2", + "7 + 2 - 5", + "4/3", + "12/3", + "4*3", + "581*2/3"}; + + QVector expected = {1, + 2 + 3, + 2 + -3, + 2 - -3, + 5-2, + 7 + 2 - 5, + qRound(4.0/3.0), + qRound(12.0/3.0), + 4*3, + 581*2/3}; + + for (int i = 0; i < expected.size(); i++) { + + int result = KisNumericParser::parseIntegerMathExpr(exprs[i]); + + QCOMPARE(result, expected[i]); + } +} + +void KisSimpleMathParserTest::testIntFlooring() +{ + + QStringList exprs = {"4.5", + "-4.5", + "3.5 + 4.5", + "2.8 - -3.5", + "4.5/2.9", + "7.6*3.2", + "7.6*3.2 + 4.5" + }; + + QVector expected = {qRound(4.5), + qRound(-4.5), + qRound(3.5 + 4.5), + qRound(2.8 - -3.5), + qRound(4.5/2.9), + qRound(7.6*3.2), + qRound(7.6*3.2 + 4.5) + }; + + for (int i = 0; i < expected.size(); i++) { + + int result = KisNumericParser::parseIntegerMathExpr(exprs[i]); + + QCOMPARE(result, expected[i]); + } + +} + +QTEST_APPLESS_MAIN(KisSimpleMathParserTest) + diff --git a/pics/16_dark_warning.svg b/pics/16_dark_warning.svg new file mode 100644 --- /dev/null +++ b/pics/16_dark_warning.svg @@ -0,0 +1,89 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + + + diff --git a/pics/16_light_warning.svg b/pics/16_light_warning.svg new file mode 100644 --- /dev/null +++ b/pics/16_light_warning.svg @@ -0,0 +1,89 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + + + diff --git a/pics/icons.qrc b/pics/icons.qrc --- a/pics/icons.qrc +++ b/pics/icons.qrc @@ -1,304 +1,305 @@ - - - - 16_dark_align-horizontal-center.svg - 22_dark_align-horizontal-center.svg - 24_dark_align-horizontal-center.svg - 16_light_align-horizontal-center.svg - 22_light_align-horizontal-center.svg - 24_light_align-horizontal-center.svg - 16_dark_align-horizontal-left.svg - 22_dark_align-horizontal-left.svg - 24_dark_align-horizontal-left.svg - 16_light_align-horizontal-left.svg - 22_light_align-horizontal-left.svg - 24_light_align-horizontal-left.svg - 16_dark_align-horizontal-right.svg - 22_dark_align-horizontal-right.svg - 24_dark_align-horizontal-right.svg - 16_light_align-horizontal-right.svg - 22_light_align-horizontal-right.svg - 24_light_align-horizontal-right.svg - 16_dark_align-vertical-bottom.svg - 22_dark_align-vertical-bottom.svg - 24_dark_align-vertical-bottom.svg - 16_light_align-vertical-bottom.svg - 22_light_align-vertical-bottom.svg - 24_light_align-vertical-bottom.svg - 16_dark_align-vertical-center.svg - 22_dark_align-vertical-center.svg - 24_dark_align-vertical-center.svg - 16_light_align-vertical-center.svg - 22_light_align-vertical-center.svg - 24_light_align-vertical-center.svg - 16_dark_align-vertical-top.svg - 22_dark_align-vertical-top.svg - 24_dark_align-vertical-top.svg - 16_light_align-vertical-top.svg - 22_light_align-vertical-top.svg - 24_light_align-vertical-top.svg - 16_dark_application-x-krita.svg - 22_dark_application-x-krita.svg - 32_dark_application-x-krita.svg - 64_dark_application-x-krita.svg - 16_light_application-x-krita.svg - 22_light_application-x-krita.svg - 32_light_application-x-krita.svg - 64_light_application-x-krita.svg - 16_dark_application-x-wmf.svg - 22_dark_application-x-wmf.svg - 32_dark_application-x-wmf.svg - 64_dark_application-x-wmf.svg - 16_light_application-x-wmf.svg - 22_light_application-x-wmf.svg - 32_light_application-x-wmf.svg - 64_light_application-x-wmf.svg - calligrakrita.png - 16_dark_character-set.svg - 22_dark_character-set.svg - 24_dark_character-set.svg - 16_light_character-set.svg - 22_light_character-set.svg - 24_light_character-set.svg - 16_dark_draw-arrow-back.svg - 22_dark_draw-arrow-back.svg - 24_dark_draw-arrow-back.svg - 16_light_draw-arrow-back.svg - 22_light_draw-arrow-back.svg - 24_light_draw-arrow-back.svg - 16_dark_draw-arrow-down.svg - 22_dark_draw-arrow-down.svg - 24_dark_draw-arrow-down.svg - 16_light_draw-arrow-down.svg - 22_light_draw-arrow-down.svg - 24_light_draw-arrow-down.svg - 16_dark_draw-arrow-forward.svg - 22_dark_draw-arrow-forward.svg - 24_dark_draw-arrow-forward.svg - 16_light_draw-arrow-forward.svg - 22_light_draw-arrow-forward.svg - 24_light_draw-arrow-forward.svg - 16_dark_draw-arrow-up.svg - 22_dark_draw-arrow-up.svg - 24_dark_draw-arrow-up.svg - 16_light_draw-arrow-up.svg - 22_light_draw-arrow-up.svg - 24_light_draw-arrow-up.svg - 16_dark_draw-freehand.svg - 22_dark_draw-freehand.svg - 24_dark_draw-freehand.svg - 16_light_draw-freehand.svg - 22_light_draw-freehand.svg - 24_light_draw-freehand.svg - 16_dark_edit-rename.svg - 22_dark_edit-rename.svg - 24_dark_edit-rename.svg - 16_light_edit-rename.svg - 22_light_edit-rename.svg - 24_light_edit-rename.svg - 16_dark_edit-select-all.svg - 22_dark_edit-select-all.svg - 24_dark_edit-select-all.svg - 16_light_edit-select-all.svg - 22_light_edit-select-all.svg - 24_light_edit-select-all.svg - 16_dark_format-indent-less.svg - 22_dark_format-indent-less.svg - 24_dark_format-indent-less.svg - 16_light_format-indent-less.svg - 22_light_format-indent-less.svg - 24_light_format-indent-less.svg - 16_dark_format-indent-more.svg - 22_dark_format-indent-more.svg - 24_dark_format-indent-more.svg - 16_light_format-indent-more.svg - 22_light_format-indent-more.svg - 24_light_format-indent-more.svg - 16_dark_format-justify-center.svg - 22_dark_format-justify-center.svg - 24_dark_format-justify-center.svg - 16_light_format-justify-center.svg - 22_light_format-justify-center.svg - 24_light_format-justify-center.svg - 16_dark_format-justify-fill.svg - 22_dark_format-justify-fill.svg - 24_dark_format-justify-fill.svg - 16_light_format-justify-fill.svg - 22_light_format-justify-fill.svg - 24_light_format-justify-fill.svg - 16_dark_format-justify-left.svg - 22_dark_format-justify-left.svg - 24_dark_format-justify-left.svg - 16_light_format-justify-left.svg - 22_light_format-justify-left.svg - 24_light_format-justify-left.svg - 16_dark_format-justify-right.svg - 22_dark_format-justify-right.svg - 24_dark_format-justify-right.svg - 16_light_format-justify-right.svg - 22_light_format-justify-right.svg - 24_light_format-justify-right.svg - 16_dark_format-list-ordered.svg - 22_dark_format-list-ordered.svg - 24_dark_format-list-ordered.svg - 16_light_format-list-ordered.svg - 22_light_format-list-ordered.svg - 24_light_format-list-ordered.svg - 16_dark_format-stroke-color.svg - 22_dark_format-stroke-color.svg - 24_dark_format-stroke-color.svg - 16_light_format-stroke-color.svg - 22_light_format-stroke-color.svg - 24_light_format-stroke-color.svg - 16_dark_format-text-bold.svg - 22_dark_format-text-bold.svg - 24_dark_format-text-bold.svg - 16_light_format-text-bold.svg - 22_light_format-text-bold.svg - 24_light_format-text-bold.svg - 16_dark_format-text-color.svg - 22_dark_format-text-color.svg - 24_dark_format-text-color.svg - 16_light_format-text-color.svg - 22_light_format-text-color.svg - 24_light_format-text-color.svg - 16_dark_format-text-direction-rtl.svg - 22_dark_format-text-direction-rtl.svg - 24_dark_format-text-direction-rtl.svg - 16_light_format-text-direction-rtl.svg - 22_light_format-text-direction-rtl.svg - 24_light_format-text-direction-rtl.svg - 16_dark_format-text-italic.svg - 22_dark_format-text-italic.svg - 24_dark_format-text-italic.svg - 16_light_format-text-italic.svg - 22_light_format-text-italic.svg - 24_light_format-text-italic.svg - 16_dark_format-text-strikethrough.svg - 22_dark_format-text-strikethrough.svg - 24_dark_format-text-strikethrough.svg - 16_light_format-text-strikethrough.svg - 22_light_format-text-strikethrough.svg - 24_light_format-text-strikethrough.svg - 16_dark_format-text-subscript.svg - 22_dark_format-text-subscript.svg - 24_dark_format-text-subscript.svg - 16_light_format-text-subscript.svg - 22_light_format-text-subscript.svg - 24_light_format-text-subscript.svg - 16_dark_format-text-superscript.svg - 22_dark_format-text-superscript.svg - 24_dark_format-text-superscript.svg - 16_light_format-text-superscript.svg - 22_light_format-text-superscript.svg - 24_light_format-text-superscript.svg - 16_dark_format-text-underline.svg - 22_dark_format-text-underline.svg - 24_dark_format-text-underline.svg - 16_light_format-text-underline.svg - 22_light_format-text-underline.svg - 24_light_format-text-underline.svg - 16_dark_insert-text.svg - 22_dark_insert-text.svg - 24_dark_insert-text.svg - 16_light_insert-text.svg - 22_light_insert-text.svg - 24_light_insert-text.svg - 48_dark_klipper.svg - 48_light_klipper.svg - 16_dark_list-remove.svg - 22_dark_list-remove.svg - 24_dark_list-remove.svg - 16_light_list-remove.svg - 22_light_list-remove.svg - 24_light_list-remove.svg - 16_dark_media-floppy.svg - 22_dark_media-floppy.svg - 16_light_media-floppy.svg - 22_light_media-floppy.svg - 16_dark_object-align-horizontal-center-calligra.svg - 22_dark_object-align-horizontal-center-calligra.svg - 16_light_object-align-horizontal-center-calligra.svg - 22_light_object-align-horizontal-center-calligra.svg - 16_dark_object-align-horizontal-left-calligra.svg - 22_dark_object-align-horizontal-left-calligra.svg - 16_light_object-align-horizontal-left-calligra.svg - 22_light_object-align-horizontal-left-calligra.svg - 16_dark_object-align-vertical-top-calligra.svg - 22_dark_object-align-vertical-top-calligra.svg - 16_light_object-align-vertical-top-calligra.svg - 22_light_object-align-vertical-top-calligra.svg - 16_dark_object-group-calligra.svg - 22_dark_object-group-calligra.svg - 16_light_object-group-calligra.svg - 22_light_object-group-calligra.svg - 16_dark_shape-choose.svg - 22_dark_shape-choose.svg - 16_light_shape-choose.svg - 22_light_shape-choose.svg - 16_dark_snap-extension.svg - 22_dark_snap-extension.svg - 24_dark_snap-extension.svg - 16_light_snap-extension.svg - 22_light_snap-extension.svg - 24_light_snap-extension.svg - 16_dark_snap-guideline.svg - 22_dark_snap-guideline.svg - 24_dark_snap-guideline.svg - 16_light_snap-guideline.svg - 22_light_snap-guideline.svg - 24_light_snap-guideline.svg - 16_dark_snap-intersection.svg - 22_dark_snap-intersection.svg - 24_dark_snap-intersection.svg - 16_light_snap-intersection.svg - 22_light_snap-intersection.svg - 24_light_snap-intersection.svg - 16_dark_snap-node.svg - 22_dark_snap-node.svg - 24_dark_snap-node.svg - 16_light_snap-node.svg - 22_light_snap-node.svg - 24_light_snap-node.svg - 22_dark_snap-orthogonal.svg - 24_dark_snap-orthogonal.svg - 22_light_snap-orthogonal.svg - 24_light_snap-orthogonal.svg - 16_dark_split.svg - 22_dark_split.svg - 24_dark_split.svg - 16_light_split.svg - 22_light_split.svg - 24_light_split.svg - 16_dark_tab-close.svg - 22_dark_tab-close.svg - 24_dark_tab-close.svg - 16_light_tab-close.svg - 22_light_tab-close.svg - 24_light_tab-close.svg - 16_dark_tab-new.svg - 22_dark_tab-new.svg - 24_dark_tab-new.svg - 16_light_tab-new.svg - 22_light_tab-new.svg - 24_light_tab-new.svg - 16_dark_transform-move.svg - 22_dark_transform-move.svg - 24_dark_transform-move.svg - 16_light_transform-move.svg - 22_light_transform-move.svg - 24_light_transform-move.svg - 16_dark_trash-empty.svg - 22_dark_trash-empty.svg - 24_dark_trash-empty.svg - 16_light_trash-empty.svg - 22_light_trash-empty.svg - 24_light_trash-empty.svg - 16_dark_zoom-fit-best.svg - 22_dark_zoom-fit-best.svg - 24_dark_zoom-fit-best.svg - 16_light_zoom-fit-best.svg - 22_light_zoom-fit-best.svg - 24_light_zoom-fit-best.svg - + + + 16_dark_align-horizontal-center.svg + 22_dark_align-horizontal-center.svg + 24_dark_align-horizontal-center.svg + 16_light_align-horizontal-center.svg + 22_light_align-horizontal-center.svg + 24_light_align-horizontal-center.svg + 16_dark_align-horizontal-left.svg + 22_dark_align-horizontal-left.svg + 24_dark_align-horizontal-left.svg + 16_light_align-horizontal-left.svg + 22_light_align-horizontal-left.svg + 24_light_align-horizontal-left.svg + 16_dark_align-horizontal-right.svg + 22_dark_align-horizontal-right.svg + 24_dark_align-horizontal-right.svg + 16_light_align-horizontal-right.svg + 22_light_align-horizontal-right.svg + 24_light_align-horizontal-right.svg + 16_dark_align-vertical-bottom.svg + 22_dark_align-vertical-bottom.svg + 24_dark_align-vertical-bottom.svg + 16_light_align-vertical-bottom.svg + 22_light_align-vertical-bottom.svg + 24_light_align-vertical-bottom.svg + 16_dark_align-vertical-center.svg + 22_dark_align-vertical-center.svg + 24_dark_align-vertical-center.svg + 16_light_align-vertical-center.svg + 22_light_align-vertical-center.svg + 24_light_align-vertical-center.svg + 16_dark_align-vertical-top.svg + 22_dark_align-vertical-top.svg + 24_dark_align-vertical-top.svg + 16_light_align-vertical-top.svg + 22_light_align-vertical-top.svg + 24_light_align-vertical-top.svg + 16_dark_application-x-krita.svg + 22_dark_application-x-krita.svg + 32_dark_application-x-krita.svg + 64_dark_application-x-krita.svg + 16_light_application-x-krita.svg + 22_light_application-x-krita.svg + 32_light_application-x-krita.svg + 64_light_application-x-krita.svg + 16_dark_application-x-wmf.svg + 22_dark_application-x-wmf.svg + 32_dark_application-x-wmf.svg + 64_dark_application-x-wmf.svg + 16_light_application-x-wmf.svg + 22_light_application-x-wmf.svg + 32_light_application-x-wmf.svg + 64_light_application-x-wmf.svg + calligrakrita.png + 16_dark_character-set.svg + 22_dark_character-set.svg + 24_dark_character-set.svg + 16_light_character-set.svg + 22_light_character-set.svg + 24_light_character-set.svg + 16_dark_draw-arrow-back.svg + 22_dark_draw-arrow-back.svg + 24_dark_draw-arrow-back.svg + 16_light_draw-arrow-back.svg + 22_light_draw-arrow-back.svg + 24_light_draw-arrow-back.svg + 16_dark_draw-arrow-down.svg + 22_dark_draw-arrow-down.svg + 24_dark_draw-arrow-down.svg + 16_light_draw-arrow-down.svg + 22_light_draw-arrow-down.svg + 24_light_draw-arrow-down.svg + 16_dark_draw-arrow-forward.svg + 22_dark_draw-arrow-forward.svg + 24_dark_draw-arrow-forward.svg + 16_light_draw-arrow-forward.svg + 22_light_draw-arrow-forward.svg + 24_light_draw-arrow-forward.svg + 16_dark_draw-arrow-up.svg + 22_dark_draw-arrow-up.svg + 24_dark_draw-arrow-up.svg + 16_light_draw-arrow-up.svg + 22_light_draw-arrow-up.svg + 24_light_draw-arrow-up.svg + 16_dark_draw-freehand.svg + 22_dark_draw-freehand.svg + 24_dark_draw-freehand.svg + 16_light_draw-freehand.svg + 22_light_draw-freehand.svg + 24_light_draw-freehand.svg + 16_dark_edit-rename.svg + 22_dark_edit-rename.svg + 24_dark_edit-rename.svg + 16_light_edit-rename.svg + 22_light_edit-rename.svg + 24_light_edit-rename.svg + 16_dark_edit-select-all.svg + 22_dark_edit-select-all.svg + 24_dark_edit-select-all.svg + 16_light_edit-select-all.svg + 22_light_edit-select-all.svg + 24_light_edit-select-all.svg + 16_dark_format-indent-less.svg + 22_dark_format-indent-less.svg + 24_dark_format-indent-less.svg + 16_light_format-indent-less.svg + 22_light_format-indent-less.svg + 24_light_format-indent-less.svg + 16_dark_format-indent-more.svg + 22_dark_format-indent-more.svg + 24_dark_format-indent-more.svg + 16_light_format-indent-more.svg + 22_light_format-indent-more.svg + 24_light_format-indent-more.svg + 16_dark_format-justify-center.svg + 22_dark_format-justify-center.svg + 24_dark_format-justify-center.svg + 16_light_format-justify-center.svg + 22_light_format-justify-center.svg + 24_light_format-justify-center.svg + 16_dark_format-justify-fill.svg + 22_dark_format-justify-fill.svg + 24_dark_format-justify-fill.svg + 16_light_format-justify-fill.svg + 22_light_format-justify-fill.svg + 24_light_format-justify-fill.svg + 16_dark_format-justify-left.svg + 22_dark_format-justify-left.svg + 24_dark_format-justify-left.svg + 16_light_format-justify-left.svg + 22_light_format-justify-left.svg + 24_light_format-justify-left.svg + 16_dark_format-justify-right.svg + 22_dark_format-justify-right.svg + 24_dark_format-justify-right.svg + 16_light_format-justify-right.svg + 22_light_format-justify-right.svg + 24_light_format-justify-right.svg + 16_dark_format-list-ordered.svg + 22_dark_format-list-ordered.svg + 24_dark_format-list-ordered.svg + 16_light_format-list-ordered.svg + 22_light_format-list-ordered.svg + 24_light_format-list-ordered.svg + 16_dark_format-stroke-color.svg + 22_dark_format-stroke-color.svg + 24_dark_format-stroke-color.svg + 16_light_format-stroke-color.svg + 22_light_format-stroke-color.svg + 24_light_format-stroke-color.svg + 16_dark_format-text-bold.svg + 22_dark_format-text-bold.svg + 24_dark_format-text-bold.svg + 16_light_format-text-bold.svg + 22_light_format-text-bold.svg + 24_light_format-text-bold.svg + 16_dark_format-text-color.svg + 22_dark_format-text-color.svg + 24_dark_format-text-color.svg + 16_light_format-text-color.svg + 22_light_format-text-color.svg + 24_light_format-text-color.svg + 16_dark_format-text-direction-rtl.svg + 22_dark_format-text-direction-rtl.svg + 24_dark_format-text-direction-rtl.svg + 16_light_format-text-direction-rtl.svg + 22_light_format-text-direction-rtl.svg + 24_light_format-text-direction-rtl.svg + 16_dark_format-text-italic.svg + 22_dark_format-text-italic.svg + 24_dark_format-text-italic.svg + 16_light_format-text-italic.svg + 22_light_format-text-italic.svg + 24_light_format-text-italic.svg + 16_dark_format-text-strikethrough.svg + 22_dark_format-text-strikethrough.svg + 24_dark_format-text-strikethrough.svg + 16_light_format-text-strikethrough.svg + 22_light_format-text-strikethrough.svg + 24_light_format-text-strikethrough.svg + 16_dark_format-text-subscript.svg + 22_dark_format-text-subscript.svg + 24_dark_format-text-subscript.svg + 16_light_format-text-subscript.svg + 22_light_format-text-subscript.svg + 24_light_format-text-subscript.svg + 16_dark_format-text-superscript.svg + 22_dark_format-text-superscript.svg + 24_dark_format-text-superscript.svg + 16_light_format-text-superscript.svg + 22_light_format-text-superscript.svg + 24_light_format-text-superscript.svg + 16_dark_format-text-underline.svg + 22_dark_format-text-underline.svg + 24_dark_format-text-underline.svg + 16_light_format-text-underline.svg + 22_light_format-text-underline.svg + 24_light_format-text-underline.svg + 16_dark_insert-text.svg + 22_dark_insert-text.svg + 24_dark_insert-text.svg + 16_light_insert-text.svg + 22_light_insert-text.svg + 24_light_insert-text.svg + 48_dark_klipper.svg + 48_light_klipper.svg + 16_dark_list-remove.svg + 22_dark_list-remove.svg + 24_dark_list-remove.svg + 16_light_list-remove.svg + 22_light_list-remove.svg + 24_light_list-remove.svg + 16_dark_media-floppy.svg + 22_dark_media-floppy.svg + 16_light_media-floppy.svg + 22_light_media-floppy.svg + 16_dark_object-align-horizontal-center-calligra.svg + 22_dark_object-align-horizontal-center-calligra.svg + 16_light_object-align-horizontal-center-calligra.svg + 22_light_object-align-horizontal-center-calligra.svg + 16_dark_object-align-horizontal-left-calligra.svg + 22_dark_object-align-horizontal-left-calligra.svg + 16_light_object-align-horizontal-left-calligra.svg + 22_light_object-align-horizontal-left-calligra.svg + 16_dark_object-align-vertical-top-calligra.svg + 22_dark_object-align-vertical-top-calligra.svg + 16_light_object-align-vertical-top-calligra.svg + 22_light_object-align-vertical-top-calligra.svg + 16_dark_object-group-calligra.svg + 22_dark_object-group-calligra.svg + 16_light_object-group-calligra.svg + 22_light_object-group-calligra.svg + 16_dark_shape-choose.svg + 22_dark_shape-choose.svg + 16_light_shape-choose.svg + 22_light_shape-choose.svg + 16_dark_snap-extension.svg + 22_dark_snap-extension.svg + 24_dark_snap-extension.svg + 16_light_snap-extension.svg + 22_light_snap-extension.svg + 24_light_snap-extension.svg + 16_dark_snap-guideline.svg + 22_dark_snap-guideline.svg + 24_dark_snap-guideline.svg + 16_light_snap-guideline.svg + 22_light_snap-guideline.svg + 24_light_snap-guideline.svg + 16_dark_snap-intersection.svg + 22_dark_snap-intersection.svg + 24_dark_snap-intersection.svg + 16_light_snap-intersection.svg + 22_light_snap-intersection.svg + 24_light_snap-intersection.svg + 16_dark_snap-node.svg + 22_dark_snap-node.svg + 24_dark_snap-node.svg + 16_light_snap-node.svg + 22_light_snap-node.svg + 24_light_snap-node.svg + 22_dark_snap-orthogonal.svg + 24_dark_snap-orthogonal.svg + 22_light_snap-orthogonal.svg + 24_light_snap-orthogonal.svg + 16_dark_split.svg + 22_dark_split.svg + 24_dark_split.svg + 16_light_split.svg + 22_light_split.svg + 24_light_split.svg + 16_dark_tab-close.svg + 22_dark_tab-close.svg + 24_dark_tab-close.svg + 16_light_tab-close.svg + 22_light_tab-close.svg + 24_light_tab-close.svg + 16_dark_tab-new.svg + 22_dark_tab-new.svg + 24_dark_tab-new.svg + 16_light_tab-new.svg + 22_light_tab-new.svg + 24_light_tab-new.svg + 16_dark_transform-move.svg + 22_dark_transform-move.svg + 24_dark_transform-move.svg + 16_light_transform-move.svg + 22_light_transform-move.svg + 24_light_transform-move.svg + 16_dark_trash-empty.svg + 22_dark_trash-empty.svg + 24_dark_trash-empty.svg + 16_light_trash-empty.svg + 22_light_trash-empty.svg + 24_light_trash-empty.svg + 16_dark_zoom-fit-best.svg + 22_dark_zoom-fit-best.svg + 24_dark_zoom-fit-best.svg + 16_light_zoom-fit-best.svg + 22_light_zoom-fit-best.svg + 24_light_zoom-fit-best.svg + 16_dark_warning.svg + 16_light_warning.svg + diff --git a/plugins/dockers/advancedcolorselector/kis_shade_selector_line_editor.h b/plugins/dockers/advancedcolorselector/kis_shade_selector_line_editor.h --- a/plugins/dockers/advancedcolorselector/kis_shade_selector_line_editor.h +++ b/plugins/dockers/advancedcolorselector/kis_shade_selector_line_editor.h @@ -29,6 +29,7 @@ #include "kis_shade_selector_line.h" +class KisDoubleParseSpinBox; class KisShadeSelectorLineEditor : public KisShadeSelectorLineBase { Q_OBJECT @@ -45,12 +46,12 @@ void requestActivateLine(QWidget *widget); private: - QDoubleSpinBox* m_hueDelta; - QDoubleSpinBox* m_saturationDelta; - QDoubleSpinBox* m_valueDelta; - QDoubleSpinBox* m_hueShift; - QDoubleSpinBox* m_saturationShift; - QDoubleSpinBox* m_valueShift; + KisDoubleParseSpinBox* m_hueDelta; + KisDoubleParseSpinBox* m_saturationDelta; + KisDoubleParseSpinBox* m_valueDelta; + KisDoubleParseSpinBox* m_hueShift; + KisDoubleParseSpinBox* m_saturationShift; + KisDoubleParseSpinBox* m_valueShift; }; #endif /* __KIS_SHADE_SELECTOR_LINE_EDITOR_H */ diff --git a/plugins/dockers/advancedcolorselector/kis_shade_selector_line_editor.cpp b/plugins/dockers/advancedcolorselector/kis_shade_selector_line_editor.cpp --- a/plugins/dockers/advancedcolorselector/kis_shade_selector_line_editor.cpp +++ b/plugins/dockers/advancedcolorselector/kis_shade_selector_line_editor.cpp @@ -19,6 +19,8 @@ #include "kis_shade_selector_line_editor.h" +#include "kis_double_parse_spin_box.h" + KisShadeSelectorLineEditor::KisShadeSelectorLineEditor(QWidget* parent) : KisShadeSelectorLineBase(parent) { @@ -28,22 +30,22 @@ layout->addLayout(lineOne); lineOne->addWidget(new QLabel(i18n("Delta: "))); - m_hueDelta = new QDoubleSpinBox(); + m_hueDelta = new KisDoubleParseSpinBox(); lineOne->addWidget(m_hueDelta); - m_saturationDelta = new QDoubleSpinBox(); + m_saturationDelta = new KisDoubleParseSpinBox(); lineOne->addWidget(m_saturationDelta); - m_valueDelta = new QDoubleSpinBox(); + m_valueDelta = new KisDoubleParseSpinBox(); lineOne->addWidget(m_valueDelta); QHBoxLayout* lineTwo = new QHBoxLayout(); layout->addLayout(lineTwo); lineTwo->addWidget(new QLabel(i18n("Shift: "))); - m_hueShift = new QDoubleSpinBox(); + m_hueShift = new KisDoubleParseSpinBox(); lineTwo->addWidget(m_hueShift); - m_saturationShift = new QDoubleSpinBox(); + m_saturationShift = new KisDoubleParseSpinBox(); lineTwo->addWidget(m_saturationShift); - m_valueShift = new QDoubleSpinBox(); + m_valueShift = new KisDoubleParseSpinBox(); lineTwo->addWidget(m_valueShift); diff --git a/plugins/dockers/advancedcolorselector/wdg_color_selector_settings.ui b/plugins/dockers/advancedcolorselector/wdg_color_selector_settings.ui --- a/plugins/dockers/advancedcolorselector/wdg_color_selector_settings.ui +++ b/plugins/dockers/advancedcolorselector/wdg_color_selector_settings.ui @@ -108,7 +108,7 @@ Qt::LeftToRight - Color Model Type: + Color &Model Type: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter @@ -180,7 +180,7 @@
- + 0 @@ -225,7 +225,7 @@ - + 0 @@ -244,7 +244,7 @@ - + 0 @@ -263,7 +263,7 @@ - + <html><head/><body><p>This sets the gamma value that the linearised HSY Luminosity is crunched with. 1 makes the selector fully linear, 2.2 is a practical default value.</p></body></html> @@ -309,7 +309,7 @@ - Color Selector Uses Different Color Space than Image + Color Selector Uses Different Color Space than Ima&ge true @@ -382,7 +382,7 @@ - + px @@ -572,14 +572,14 @@ - Gradient + &Gradient - Color Patches + Colo&r Patches @@ -623,7 +623,7 @@ - + 1 @@ -646,7 +646,7 @@ - + px @@ -672,27 +672,16 @@ - +
- label_7 - shadeSelectorUpdateOnRightClick - shadeSelectorUpdateOnLeftClick - shadeSelectorUpdateOnForeground - shadeSelectorUpdateOnBackground - myPaintColorModelLabel minimalShadeSelectorGroup - ACSshadeSelectorMyPaintColorModelComboBox - ACSShadeSelectorTypeComboBox - label_16 - verticalSpacer_3 - verticalSpacer_4 verticalSpacer_5 @@ -718,7 +707,7 @@ - Show Color History + Show Color Histor&y true @@ -743,7 +732,7 @@ - + px @@ -766,7 +755,7 @@ - + px @@ -786,7 +775,7 @@ - + 1 @@ -823,7 +812,7 @@ - Vertical + &Vertical true @@ -833,7 +822,7 @@ - Columns: + Colu&mns: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter @@ -844,7 +833,7 @@ - + 1 @@ -859,14 +848,14 @@ - Horizontal + &Horizontal - Rows: + &Rows: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter @@ -877,7 +866,7 @@ - + 1 @@ -933,7 +922,7 @@ true - Show Colors from the image + Show Colors from the ima&ge true @@ -958,7 +947,7 @@ - + px @@ -981,7 +970,7 @@ - + px @@ -1001,7 +990,7 @@ - + 1 @@ -1041,14 +1030,14 @@ - Vertical + &Vertical - Columns: + Colu&mns: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter @@ -1059,7 +1048,7 @@ - + 1 @@ -1074,7 +1063,7 @@ - Horizontal + &Horizontal true @@ -1084,7 +1073,7 @@ - Rows: + &Rows: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter @@ -1095,7 +1084,7 @@ - + 1 @@ -1292,7 +1281,7 @@ - + steps @@ -1319,7 +1308,7 @@ - + steps @@ -1346,7 +1335,7 @@ - + steps @@ -1369,7 +1358,7 @@ - + steps @@ -1396,7 +1385,7 @@ - + steps @@ -1440,6 +1429,16 @@ QComboBox
kis_shade_selector_lines_settings.h
+ + KisIntParseSpinBox + QSpinBox +
kis_int_parse_spin_box.h
+
+ + KisDoubleParseSpinBox + QDoubleSpinBox +
kis_double_parse_spin_box.h
+
diff --git a/plugins/dockers/animation/tests/timeline_model_test.cpp b/plugins/dockers/animation/tests/timeline_model_test.cpp --- a/plugins/dockers/animation/tests/timeline_model_test.cpp +++ b/plugins/dockers/animation/tests/timeline_model_test.cpp @@ -43,6 +43,8 @@ #include "commands/kis_image_layer_add_command.h" #include "commands/kis_image_layer_remove_command.h" +#include "kis_double_parse_spin_box.h" +#include "kis_int_parse_spin_box.h" void TimelineModelTest::init() { @@ -155,14 +157,14 @@ font.setPointSizeF(9); dlg.setFont(font); - QSpinBox *intFps = new QSpinBox(&dlg); + QSpinBox *intFps = new KisIntParseSpinBox(&dlg); intFps->setValue(12); - QSpinBox *intTime = new QSpinBox(&dlg); + QSpinBox *intTime = new KisIntParseSpinBox(&dlg); intTime->setValue(0); intTime->setMaximum(10000); - QSpinBox *intLayer = new QSpinBox(&dlg); + QSpinBox *intLayer = new KisIntParseSpinBox(&dlg); intLayer->setValue(0); intLayer->setMaximum(100); diff --git a/plugins/dockers/animation/wdg_animation.ui b/plugins/dockers/animation/wdg_animation.ui --- a/plugins/dockers/animation/wdg_animation.ui +++ b/plugins/dockers/animation/wdg_animation.ui @@ -14,7 +14,7 @@ - + 0 @@ -61,7 +61,7 @@ - + 0 @@ -81,7 +81,7 @@ - + 0 @@ -479,7 +479,7 @@ - + 0.100000000000000 @@ -502,7 +502,7 @@ - + 1 @@ -514,6 +514,18 @@
+ + + KisDoubleParseSpinBox + QDoubleSpinBox +
kis_double_parse_spin_box.h
+
+ + KisIntParseSpinBox + QSpinBox +
kis_int_parse_spin_box.h
+
+
diff --git a/plugins/dockers/colorslider/kis_color_slider_input.h b/plugins/dockers/colorslider/kis_color_slider_input.h --- a/plugins/dockers/colorslider/kis_color_slider_input.h +++ b/plugins/dockers/colorslider/kis_color_slider_input.h @@ -27,6 +27,7 @@ class KoColor; class QWidget; class QDoubleSpinBox; +class KisDoubleParseSpinBox; class KisHSVSlider; class KisDisplayColorConverter; @@ -76,7 +77,7 @@ void satUpdated(int, int); void toneUpdated(int, int); private: - QDoubleSpinBox* m_NumInput; + KisDoubleParseSpinBox* m_NumInput; qreal m_hue; qreal m_sat; qreal m_val; diff --git a/plugins/dockers/colorslider/kis_color_slider_input.cpp b/plugins/dockers/colorslider/kis_color_slider_input.cpp --- a/plugins/dockers/colorslider/kis_color_slider_input.cpp +++ b/plugins/dockers/colorslider/kis_color_slider_input.cpp @@ -44,6 +44,8 @@ #include "kis_hsv_slider.h" #include "kis_display_color_converter.h" +#include "kis_double_parse_spin_box.h" + KisColorSliderInput::KisColorSliderInput(QWidget* parent, KoColor* color, const int type, KoColorDisplayRendererInterface *displayRenderer, KisCanvas2* canvas) : QWidget(parent), m_type(type), @@ -593,7 +595,7 @@ QWidget* KisHSXColorSliderInput::createInput() { - m_NumInput = new QDoubleSpinBox(this); + m_NumInput = new KisDoubleParseSpinBox(this); m_NumInput->setMinimum(0); m_NumInput->setMaximum(100.0); m_NumInput->setKeyboardTracking(false);//this makes sure that only full values are sent after loss of focus. Much more user friendly// diff --git a/plugins/dockers/griddocker/grid_config_widget.cpp b/plugins/dockers/griddocker/grid_config_widget.cpp --- a/plugins/dockers/griddocker/grid_config_widget.cpp +++ b/plugins/dockers/griddocker/grid_config_widget.cpp @@ -22,6 +22,7 @@ #include "kis_guides_config.h" #include "kis_debug.h" #include "kis_aspect_ratio_locker.h" +#include "kis_int_parse_spin_box.h" struct GridConfigWidget::Private diff --git a/plugins/dockers/griddocker/grid_config_widget.ui b/plugins/dockers/griddocker/grid_config_widget.ui --- a/plugins/dockers/griddocker/grid_config_widget.ui +++ b/plugins/dockers/griddocker/grid_config_widget.ui @@ -63,7 +63,7 @@
- + px @@ -86,7 +86,7 @@ - + px @@ -118,7 +118,7 @@ - + 1 @@ -155,7 +155,7 @@ - + px @@ -175,7 +175,7 @@ - + px @@ -472,21 +472,27 @@ + KoAspectButton + QWidget +
KoAspectButton.h
+ 1 +
+ + KisIntParseSpinBox + QSpinBox +
kis_int_parse_spin_box.h
+
+ KColorButton QPushButton
kcolorbutton.h
+ 1
KComboBox QComboBox
kcombobox.h
- - KoAspectButton - QWidget -
KoAspectButton.h
- 1 -
diff --git a/plugins/dockers/historydocker/KisUndoView.cpp b/plugins/dockers/historydocker/KisUndoView.cpp --- a/plugins/dockers/historydocker/KisUndoView.cpp +++ b/plugins/dockers/historydocker/KisUndoView.cpp @@ -73,7 +73,8 @@ #include #include - +#include "kis_double_parse_spin_box.h" +#include "kis_int_parse_spin_box.h" /*! \class KisUndoView @@ -307,7 +308,7 @@ QAction* action1 = menu.addAction(KisIconUtils::loadIcon("link"),stack()->useCumulativeUndoRedo()?i18n("Disable Cumulative Undo"):i18n("Enable Cumulative Undo")); connect(action1, SIGNAL(triggered()), this, SLOT(toggleCumulativeUndoRedo())); QLabel *l = new QLabel(i18n("Start merging time")); - QDoubleSpinBox *s = new QDoubleSpinBox(); + QDoubleSpinBox *s = new KisDoubleParseSpinBox(); s->setToolTip(i18nc("@info:tooltip", "The amount of time after a merged stroke before merging again")); s->setRange(3,10); s->setValue(stack()->timeT1()); @@ -322,7 +323,7 @@ connect(s,SIGNAL(valueChanged(double)),SLOT(setStackT1(double))); QLabel *l1 = new QLabel(i18n("Group time")); - QDoubleSpinBox *s1 = new QDoubleSpinBox(); + QDoubleSpinBox *s1 = new KisDoubleParseSpinBox(); s1->setToolTip(i18nc("@info:tooltip", "The amount of time every stroke should be apart from its previous stroke to be classified in one group")); s1->setRange(0.3,s->value()); s1->setValue(stack()->timeT2()); @@ -337,7 +338,7 @@ connect(s1,SIGNAL(valueChanged(double)),SLOT(setStackT2(double))); QLabel *l2 = new QLabel(i18n("Split Strokes")); - QSpinBox *s2 = new QSpinBox(); + QSpinBox *s2 = new KisIntParseSpinBox(); s2->setToolTip(i18nc("@info:tooltip", "The number of last strokes which Krita should store separately")); s2->setRange(1,stack()->undoLimit()); s2->setValue(stack()->strokesN()); diff --git a/plugins/dockers/specificcolorselector/kis_color_input.h b/plugins/dockers/specificcolorselector/kis_color_input.h --- a/plugins/dockers/specificcolorselector/kis_color_input.h +++ b/plugins/dockers/specificcolorselector/kis_color_input.h @@ -25,6 +25,8 @@ class QWidget; class QSpinBox; class QDoubleSpinBox; +class KisIntParseSpinBox; +class KisDoubleParseSpinBox; class KoColorSlider; class QLineEdit; #include "KoColorDisplayRendererInterface.h" @@ -58,7 +60,7 @@ void setValue(int); void update(); private: - QSpinBox* m_intNumInput; + KisIntParseSpinBox* m_intNumInput; }; @@ -74,7 +76,7 @@ void sliderChanged(int); void update(); private: - QDoubleSpinBox* m_dblNumInput; + KisDoubleParseSpinBox* m_dblNumInput; qreal m_minValue; qreal m_maxValue; }; diff --git a/plugins/dockers/specificcolorselector/kis_color_input.cc b/plugins/dockers/specificcolorselector/kis_color_input.cc --- a/plugins/dockers/specificcolorselector/kis_color_input.cc +++ b/plugins/dockers/specificcolorselector/kis_color_input.cc @@ -41,6 +41,9 @@ #include #include +#include "kis_double_parse_spin_box.h" +#include "kis_int_parse_spin_box.h" + KisColorInput::KisColorInput(QWidget* parent, const KoChannelInfo* channelInfo, KoColor* color, KoColorDisplayRendererInterface *displayRenderer) : QWidget(parent), m_channelInfo(channelInfo), m_color(color), m_displayRenderer(displayRenderer) { } @@ -121,9 +124,9 @@ QWidget* KisIntegerColorInput::createInput() { - m_intNumInput = new QSpinBox(this); + m_intNumInput = new KisIntParseSpinBox(this); m_intNumInput->setMinimum(0); - m_colorSlider->setMaximum(0); + m_colorSlider->setMinimum(0); switch (m_channelInfo->channelValueType()) { case KoChannelInfo::UINT8: m_intNumInput->setMaximum(0xFF); @@ -171,11 +174,14 @@ QWidget* KisFloatColorInput::createInput() { - m_dblNumInput = new QDoubleSpinBox(this); + m_dblNumInput = new KisDoubleParseSpinBox(this); m_dblNumInput->setMinimum(0); m_dblNumInput->setMaximum(1.0); connect(m_colorSlider, SIGNAL(valueChanged(int)), this, SLOT(sliderChanged(int))); connect(m_dblNumInput, SIGNAL(valueChanged(double)), this, SLOT(setValue(double))); + m_dblNumInput->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Preferred); + m_dblNumInput->setMinimumWidth(60); + m_dblNumInput->setMaximumWidth(60); return m_dblNumInput; } diff --git a/plugins/extensions/clonesarray/wdg_clonesarray.ui b/plugins/extensions/clonesarray/wdg_clonesarray.ui --- a/plugins/extensions/clonesarray/wdg_clonesarray.ui +++ b/plugins/extensions/clonesarray/wdg_clonesarray.ui @@ -6,7 +6,7 @@ 0 0 - 644 + 710 174
@@ -139,10 +139,10 @@
- + - + 1 @@ -168,7 +168,7 @@ - + px @@ -181,7 +181,7 @@ - + px @@ -220,10 +220,10 @@ - + - + 1 @@ -233,7 +233,7 @@ - + px @@ -246,7 +246,7 @@ - + px @@ -259,7 +259,7 @@ - + ° @@ -272,7 +272,7 @@ - + ° @@ -285,7 +285,7 @@ - + px @@ -295,7 +295,7 @@ - + px @@ -348,6 +348,18 @@
+ + + KisIntParseSpinBox + QSpinBox +
kis_int_parse_spin_box.h
+
+ + KisDoubleParseSpinBox + QDoubleSpinBox +
kis_double_parse_spin_box.h
+
+
numNegativeColumns numNegativeRows diff --git a/plugins/extensions/imagesize/wdg_canvassize.ui b/plugins/extensions/imagesize/wdg_canvassize.ui --- a/plugins/extensions/imagesize/wdg_canvassize.ui +++ b/plugins/extensions/imagesize/wdg_canvassize.ui @@ -6,8 +6,8 @@ 0 0 - 367 - 380 + 395 + 387 @@ -24,7 +24,7 @@ - + 1 @@ -47,10 +47,10 @@ - + - + 1 @@ -70,7 +70,7 @@ - + 4 @@ -86,7 +86,7 @@ - + 4 @@ -204,7 +204,7 @@ - + -100000 @@ -214,7 +214,7 @@ - + 4 @@ -266,7 +266,7 @@ - + -100000 @@ -276,7 +276,7 @@ - + 4 @@ -331,7 +331,7 @@ 2 - +
@@ -652,6 +652,16 @@
kcanvaspreview.h
1 + + KisDoubleParseSpinBox + QDoubleSpinBox +
kis_double_parse_spin_box.h
+
+ + KisIntParseSpinBox + QSpinBox +
kis_int_parse_spin_box.h
+
newWidth diff --git a/plugins/extensions/imagesize/wdg_imagesize.ui b/plugins/extensions/imagesize/wdg_imagesize.ui --- a/plugins/extensions/imagesize/wdg_imagesize.ui +++ b/plugins/extensions/imagesize/wdg_imagesize.ui @@ -6,8 +6,8 @@ 0 0 - 372 - 379 + 391 + 386 @@ -24,7 +24,7 @@ - + 80 @@ -46,7 +46,7 @@ - + 80 @@ -83,7 +83,7 @@ - Width: + W&idth: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter @@ -96,7 +96,7 @@ - Filter: + &Filter: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter @@ -107,7 +107,7 @@ - + @@ -119,7 +119,7 @@ - Height: + &Height: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter @@ -130,7 +130,7 @@ - + 80 @@ -152,7 +152,7 @@ - + 1 @@ -178,7 +178,7 @@ - +
@@ -195,7 +195,7 @@ - Height: + Hei&ght: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter @@ -209,7 +209,7 @@ - + 80 @@ -233,7 +233,7 @@ - Width: + Wid&th: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter @@ -244,7 +244,7 @@ - + 80 @@ -266,7 +266,7 @@ - + @@ -283,7 +283,7 @@ - + 0 @@ -414,6 +414,16 @@
KoAspectButton.h
1 + + KisIntParseSpinBox + QSpinBox +
kis_int_parse_spin_box.h
+
+ + KisDoubleParseSpinBox + QDoubleSpinBox +
kis_double_parse_spin_box.h
+
pixelWidth diff --git a/plugins/extensions/imagesize/wdg_layersize.ui b/plugins/extensions/imagesize/wdg_layersize.ui --- a/plugins/extensions/imagesize/wdg_layersize.ui +++ b/plugins/extensions/imagesize/wdg_layersize.ui @@ -6,8 +6,8 @@ 0 0 - 348 - 198 + 366 + 201
@@ -24,7 +24,7 @@ - + @@ -55,7 +55,7 @@ - Width: + W&idth: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter @@ -66,7 +66,7 @@ - + 80 @@ -88,7 +88,7 @@ - + 80 @@ -110,7 +110,7 @@ - + 80 @@ -126,7 +126,7 @@ - + 1 @@ -136,7 +136,7 @@ - + @@ -151,7 +151,7 @@ - Height: + &Height: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter @@ -223,6 +223,16 @@
KoAspectButton.h
1 + + KisIntParseSpinBox + QSpinBox +
kis_int_parse_spin_box.h
+
+ + KisDoubleParseSpinBox + QDoubleSpinBox +
kis_double_parse_spin_box.h
+
newWidth diff --git a/plugins/extensions/imagesplit/wdg_imagesplit.ui b/plugins/extensions/imagesplit/wdg_imagesplit.ui --- a/plugins/extensions/imagesplit/wdg_imagesplit.ui +++ b/plugins/extensions/imagesplit/wdg_imagesplit.ui @@ -29,7 +29,7 @@
- + @@ -42,7 +42,7 @@ - +
@@ -112,6 +112,13 @@
+ + + KisIntParseSpinBox + QSpinBox +
kis_int_parse_spin_box.h
+
+
diff --git a/plugins/extensions/metadataeditor/editors/exif.ui b/plugins/extensions/metadataeditor/editors/exif.ui --- a/plugins/extensions/metadataeditor/editors/exif.ui +++ b/plugins/extensions/metadataeditor/editors/exif.ui @@ -26,7 +26,7 @@ - Brightness value: + &Brightness value: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter @@ -42,7 +42,7 @@ - ISO: + &ISO: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter @@ -53,7 +53,7 @@ - + 3600 @@ -68,7 +68,7 @@ - Exposure time: + Exposure &time: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter @@ -84,7 +84,7 @@ - Exposure mode: + E&xposure mode: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter @@ -116,7 +116,7 @@ - Exposure program: + Exposure pro&gram: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter @@ -210,7 +210,7 @@ - Aperture: + Ape&rture: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter @@ -242,7 +242,7 @@ - F Number: + &F Number: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter @@ -282,7 +282,7 @@ - Focal length: + &Focal length: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter @@ -293,7 +293,7 @@ - + 1000 @@ -308,7 +308,7 @@ - Focal length (35mm equivalent): + Focal length (&35mm equivalent): Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter @@ -319,7 +319,7 @@ - + 1000 @@ -374,7 +374,7 @@ - Subject distance: + Su&bject distance: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter @@ -390,7 +390,7 @@ - Metering mode: + Meterin&g mode: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter @@ -447,7 +447,7 @@ - Distance range: + D&istance range: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter @@ -515,7 +515,7 @@ - Strobe return: + Stro&be return: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter @@ -603,7 +603,7 @@ - Flash energy: + Flash ener&gy: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter @@ -643,7 +643,7 @@ - Gain control: + &Gain control: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter @@ -691,7 +691,7 @@ - Light source: + L&ight source: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter @@ -902,7 +902,7 @@ - White balance: + White &balance: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter @@ -953,7 +953,7 @@ - Scene capture type: + Scene capture t&ype: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter @@ -990,7 +990,7 @@ - Maker: + Ma&ker: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter @@ -1022,7 +1022,7 @@ - Sensing method type: + Sens&ing method type: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter @@ -1097,6 +1097,13 @@ + + + KisIntParseSpinBox + QSpinBox +
kis_int_parse_spin_box.h
+
+
diff --git a/plugins/extensions/modify_selection/wdg_border_selection.ui b/plugins/extensions/modify_selection/wdg_border_selection.ui --- a/plugins/extensions/modify_selection/wdg_border_selection.ui +++ b/plugins/extensions/modify_selection/wdg_border_selection.ui @@ -6,13 +6,13 @@ 0 0 - 333 - 86 + 364 + 89
- + 1 @@ -25,7 +25,7 @@ - + 4 @@ -119,6 +119,18 @@
+ + + KisIntParseSpinBox + QSpinBox +
kis_int_parse_spin_box.h
+
+ + KisDoubleParseSpinBox + QDoubleSpinBox +
kis_double_parse_spin_box.h
+
+
diff --git a/plugins/extensions/modify_selection/wdg_feather_selection.ui b/plugins/extensions/modify_selection/wdg_feather_selection.ui --- a/plugins/extensions/modify_selection/wdg_feather_selection.ui +++ b/plugins/extensions/modify_selection/wdg_feather_selection.ui @@ -6,8 +6,8 @@ 0 0 - 354 - 86 + 372 + 89
@@ -54,7 +54,7 @@
- + 1 @@ -67,7 +67,7 @@ - + 4 @@ -122,6 +122,18 @@
+ + + KisIntParseSpinBox + QSpinBox +
kis_int_parse_spin_box.h
+
+ + KisDoubleParseSpinBox + QDoubleSpinBox +
kis_double_parse_spin_box.h
+
+
spbRadius spbRadiusDouble diff --git a/plugins/extensions/modify_selection/wdg_grow_selection.ui b/plugins/extensions/modify_selection/wdg_grow_selection.ui --- a/plugins/extensions/modify_selection/wdg_grow_selection.ui +++ b/plugins/extensions/modify_selection/wdg_grow_selection.ui @@ -6,8 +6,8 @@ 0 0 - 302 - 86 + 327 + 89
@@ -57,7 +57,7 @@
- + 1 @@ -70,7 +70,7 @@ - + 4 @@ -119,6 +119,18 @@
+ + + KisIntParseSpinBox + QSpinBox +
kis_int_parse_spin_box.h
+
+ + KisDoubleParseSpinBox + QDoubleSpinBox +
kis_double_parse_spin_box.h
+
+
spbGrowValue spbGrowValueDouble diff --git a/plugins/extensions/modify_selection/wdg_shrink_selection.ui b/plugins/extensions/modify_selection/wdg_shrink_selection.ui --- a/plugins/extensions/modify_selection/wdg_shrink_selection.ui +++ b/plugins/extensions/modify_selection/wdg_shrink_selection.ui @@ -6,8 +6,8 @@ 0 0 - 308 - 113 + 334 + 117
@@ -31,7 +31,7 @@
- + 1 @@ -44,7 +44,7 @@ - + 4 @@ -129,6 +129,18 @@
+ + + KisIntParseSpinBox + QSpinBox +
kis_int_parse_spin_box.h
+
+ + KisDoubleParseSpinBox + QDoubleSpinBox +
kis_double_parse_spin_box.h
+
+
spbShrinkValue spbShrinkValueDouble diff --git a/plugins/extensions/offsetimage/wdg_offsetimage.ui b/plugins/extensions/offsetimage/wdg_offsetimage.ui --- a/plugins/extensions/offsetimage/wdg_offsetimage.ui +++ b/plugins/extensions/offsetimage/wdg_offsetimage.ui @@ -45,7 +45,7 @@
- + px @@ -69,7 +69,7 @@ - + px @@ -114,6 +114,13 @@
+ + + KisIntParseSpinBox + QSpinBox +
kis_int_parse_spin_box.h
+
+
diff --git a/plugins/extensions/rotateimage/wdg_rotateimage.ui b/plugins/extensions/rotateimage/wdg_rotateimage.ui --- a/plugins/extensions/rotateimage/wdg_rotateimage.ui +++ b/plugins/extensions/rotateimage/wdg_rotateimage.ui @@ -56,7 +56,7 @@ - 180 d&egrees + &180 degrees @@ -69,7 +69,16 @@
- + + 0 + + + 0 + + + 0 + + 0 @@ -83,7 +92,7 @@
- + 360.000000000000000 @@ -115,6 +124,13 @@
+ + + KisDoubleParseSpinBox + QDoubleSpinBox +
kis_double_parse_spin_box.h
+
+
diff --git a/plugins/extensions/shearimage/wdg_shearimage.ui b/plugins/extensions/shearimage/wdg_shearimage.ui --- a/plugins/extensions/shearimage/wdg_shearimage.ui +++ b/plugins/extensions/shearimage/wdg_shearimage.ui @@ -7,7 +7,7 @@ 0 0 323 - 64 + 78
@@ -25,16 +25,16 @@
- - + + + ° + + -45 - + 45 - - ° - @@ -48,26 +48,33 @@
- + 32767 100 - + + ° + + -45 - + 45 - - ° -
+ + + KisIntParseSpinBox + QSpinBox +
kis_int_parse_spin_box.h
+
+
diff --git a/plugins/filters/blur/wdg_lens_blur.ui b/plugins/filters/blur/wdg_lens_blur.ui --- a/plugins/filters/blur/wdg_lens_blur.ui +++ b/plugins/filters/blur/wdg_lens_blur.ui @@ -6,8 +6,8 @@ 0 0 - 199 - 123 + 255 + 153
@@ -75,7 +75,7 @@
- + 0 @@ -104,7 +104,7 @@ - + 0 @@ -146,6 +146,13 @@
+ + + KisIntParseSpinBox + QSpinBox +
kis_int_parse_spin_box.h
+
+
irisShapeCombo irisRadiusSlider diff --git a/plugins/filters/blur/wdg_motion_blur.ui b/plugins/filters/blur/wdg_motion_blur.ui --- a/plugins/filters/blur/wdg_motion_blur.ui +++ b/plugins/filters/blur/wdg_motion_blur.ui @@ -85,7 +85,7 @@
- + 0 @@ -114,7 +114,7 @@ - + 0 @@ -149,6 +149,13 @@
+ + + KisIntParseSpinBox + QSpinBox +
kis_int_parse_spin_box.h
+
+
blurAngleDial blurAngleSlider diff --git a/plugins/filters/blur/wdgblur.ui b/plugins/filters/blur/wdgblur.ui --- a/plugins/filters/blur/wdgblur.ui +++ b/plugins/filters/blur/wdgblur.ui @@ -37,7 +37,7 @@
- + px @@ -73,7 +73,7 @@ - + px @@ -93,7 +93,7 @@ - + 100 @@ -119,7 +119,7 @@ - + ° @@ -194,16 +194,21 @@ - KComboBox - QComboBox -
kcombobox.h
-
- KoAspectButton QWidget
KoAspectButton.h
1
+ + KisIntParseSpinBox + QSpinBox +
kis_int_parse_spin_box.h
+
+ + KComboBox + QComboBox +
kcombobox.h
+
diff --git a/plugins/filters/colorsfilters/wdg_color_balance.ui b/plugins/filters/colorsfilters/wdg_color_balance.ui --- a/plugins/filters/colorsfilters/wdg_color_balance.ui +++ b/plugins/filters/colorsfilters/wdg_color_balance.ui @@ -14,7 +14,16 @@ 3 - + + 0 + + + 0 + + + 0 + + 0 @@ -102,7 +111,7 @@
- + @@ -146,10 +155,10 @@ - + - + @@ -201,13 +210,13 @@ 3 - + - + - + @@ -327,21 +336,21 @@ - - 3 - 0 + + 3 + Blue - + @@ -351,7 +360,7 @@ - + @@ -395,7 +404,7 @@ - + @@ -438,6 +447,13 @@ + + + KisIntParseSpinBox + QSpinBox +
kis_int_parse_spin_box.h
+
+
cyanRedShadowsSpinbox magentaGreenShadowsSpinbox diff --git a/plugins/filters/colorsfilters/wdg_hsv_adjustment.ui b/plugins/filters/colorsfilters/wdg_hsv_adjustment.ui --- a/plugins/filters/colorsfilters/wdg_hsv_adjustment.ui +++ b/plugins/filters/colorsfilters/wdg_hsv_adjustment.ui @@ -6,7 +6,7 @@ 0 0 - 395 + 406 188 @@ -42,7 +42,7 @@ - Type: + &Type: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter @@ -105,7 +105,7 @@ - + 100 @@ -198,7 +198,7 @@ - + -100 @@ -208,7 +208,7 @@ - + -180 @@ -219,6 +219,13 @@ + + + KisIntParseSpinBox + QSpinBox +
kis_int_parse_spin_box.h
+
+
cmbType chkColorize diff --git a/plugins/filters/colorsfilters/wdg_perchannel.ui b/plugins/filters/colorsfilters/wdg_perchannel.ui --- a/plugins/filters/colorsfilters/wdg_perchannel.ui +++ b/plugins/filters/colorsfilters/wdg_perchannel.ui @@ -7,7 +7,7 @@ 0 0 317 - 395 + 396 @@ -99,7 +99,7 @@ 0 - + 0 @@ -226,7 +226,7 @@ - + 0 @@ -274,7 +274,7 @@ - + 0 @@ -318,6 +318,11 @@ + KisIntParseSpinBox + QSpinBox +
kis_int_parse_spin_box.h
+
+ KisCurveWidget
widgets/kis_curve_widget.h
diff --git a/plugins/filters/indexcolors/kiswdgindexcolors.cpp b/plugins/filters/indexcolors/kiswdgindexcolors.cpp --- a/plugins/filters/indexcolors/kiswdgindexcolors.cpp +++ b/plugins/filters/indexcolors/kiswdgindexcolors.cpp @@ -26,6 +26,8 @@ #include "palettegeneratorconfig.h" #include "ui_kiswdgindexcolors.h" +#include "kis_int_parse_spin_box.h" + #include KisWdgIndexColors::KisWdgIndexColors(QWidget* parent, Qt::WFlags f, int delay): KisConfigWidget(parent, f, delay) @@ -70,18 +72,18 @@ // Labels for the ramps /*for(int col = 0; col < collumns; ++col) { - QLabel* l = new QLabel(rampsLabels[col], ui->colorsBox); - l->setAlignment(Qt::AlignRight | Qt::AlignVCenter); - ui->layoutColors->addWidget(l, 0, col+1); + QLabel* l = new QLabel(rampsLabels[col], ui->colorsBox); + l->setAlignment(Qt::AlignRight | Qt::AlignVCenter); + ui->layoutColors->addWidget(l, 0, col+1); }*/ // Step selectors for the shade gradients for(int row = 0; row < (rows-1); ++row) { QLabel* l0 = new QLabel(shadesLabels[row+1]); QLabel* l1 = new QLabel(QString::fromUtf8("↔")); QLabel* l2 = new QLabel(shadesLabels[row]); - QSpinBox* s = new QSpinBox(); + QSpinBox* s = new KisIntParseSpinBox(); s->setMinimum(0); s->setMaximum(32); s->setValue(2); diff --git a/plugins/filters/indexcolors/kiswdgindexcolors.ui b/plugins/filters/indexcolors/kiswdgindexcolors.ui --- a/plugins/filters/indexcolors/kiswdgindexcolors.ui +++ b/plugins/filters/indexcolors/kiswdgindexcolors.ui @@ -11,7 +11,16 @@
- + + 0 + + + 0 + + + 0 + + 0 @@ -24,7 +33,7 @@ - + 20 @@ -35,12 +44,21 @@ QLayout::SetMinimumSize - - 6 + + 0 - + 0 + + 0 + + + 0 + + + 6 +
@@ -71,7 +89,7 @@
- + true @@ -87,7 +105,7 @@ - + 0 @@ -107,22 +125,23 @@ - - - - 80 - 20 - + + + QLayout::SetMinimumSize - - - QLayout::SetMinimumSize - - - 0 - - - + + 0 + + + 0 + + + 0 + + + 0 + + @@ -285,7 +304,7 @@ - + 0 @@ -302,6 +321,13 @@ + + + KisIntParseSpinBox + QSpinBox +
kis_int_parse_spin_box.h
+
+
diff --git a/plugins/filters/levelfilter/wdg_level.ui b/plugins/filters/levelfilter/wdg_level.ui --- a/plugins/filters/levelfilter/wdg_level.ui +++ b/plugins/filters/levelfilter/wdg_level.ui @@ -2,6 +2,14 @@ WdgLevel + + + 0 + 0 + 259 + 332 + + 0 @@ -108,7 +116,7 @@ - + 256 @@ -120,7 +128,7 @@ - + QAbstractSpinBox::PlusMinus @@ -146,7 +154,7 @@ - + QAbstractSpinBox::PlusMinus @@ -181,7 +189,7 @@ - + QAbstractSpinBox::PlusMinus @@ -219,7 +227,7 @@ - + 256 @@ -231,7 +239,7 @@ - + QAbstractSpinBox::PlusMinus @@ -257,7 +265,7 @@ - + QAbstractSpinBox::PlusMinus @@ -309,10 +317,20 @@ + KisIntParseSpinBox + QSpinBox +
kis_int_parse_spin_box.h
+
+ KisGradientSlider QWidget
kis_gradient_slider.h
+ + KisDoubleParseSpinBox + QDoubleSpinBox +
kis_double_parse_spin_box.h
+
kis_gradient_slider.h diff --git a/plugins/filters/noisefilter/wdgnoiseoptions.ui b/plugins/filters/noisefilter/wdgnoiseoptions.ui --- a/plugins/filters/noisefilter/wdgnoiseoptions.ui +++ b/plugins/filters/noisefilter/wdgnoiseoptions.ui @@ -7,7 +7,7 @@ 0 0 174 - 63 + 66
@@ -50,10 +50,10 @@
- + - + @@ -89,6 +89,13 @@
+ + + KisIntParseSpinBox + QSpinBox +
kis_int_parse_spin_box.h
+
+
diff --git a/plugins/filters/phongbumpmap/wdgphongbumpmap.ui b/plugins/filters/phongbumpmap/wdgphongbumpmap.ui --- a/plugins/filters/phongbumpmap/wdgphongbumpmap.ui +++ b/plugins/filters/phongbumpmap/wdgphongbumpmap.ui @@ -78,7 +78,7 @@ - Specular + Specula&r Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter @@ -113,7 +113,7 @@ - + 1 @@ -145,7 +145,7 @@ - + 1 @@ -191,7 +191,7 @@ Qt::LeftToRight - Diffuse + Di&ffuse Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter @@ -226,7 +226,7 @@ - + 1 @@ -304,7 +304,7 @@ - + 1 @@ -425,7 +425,7 @@ - Light Source 4 + Light Source &4 true @@ -483,7 +483,7 @@ - + 0 @@ -527,7 +527,7 @@ - + 0 @@ -611,7 +611,7 @@ - Light Source 2 + Light Source &2 true @@ -663,7 +663,7 @@ - + 0 @@ -710,7 +710,7 @@ - + 0 @@ -797,7 +797,7 @@ - Light Source 1 + Light Source &1 true @@ -855,7 +855,7 @@ - + 0 @@ -902,7 +902,7 @@ - + 0 @@ -986,7 +986,7 @@ - Light Source 3 + Light Source &3 true @@ -1041,7 +1041,7 @@ - + 0 @@ -1085,7 +1085,7 @@ - + 0 @@ -1181,6 +1181,11 @@ + KisIntParseSpinBox + QSpinBox +
kis_int_parse_spin_box.h
+
+ KColorCombo QComboBox
kcolorcombo.h
diff --git a/plugins/filters/randompickfilter/wdgrandompickoptions.ui b/plugins/filters/randompickfilter/wdgrandompickoptions.ui --- a/plugins/filters/randompickfilter/wdgrandompickoptions.ui +++ b/plugins/filters/randompickfilter/wdgrandompickoptions.ui @@ -41,7 +41,7 @@
- + @@ -57,7 +57,7 @@ - + @@ -73,7 +73,7 @@ - + @@ -93,6 +93,13 @@ + + + KisIntParseSpinBox + QSpinBox +
kis_int_parse_spin_box.h
+
+
diff --git a/plugins/filters/unsharp/wdgunsharp.ui b/plugins/filters/unsharp/wdgunsharp.ui --- a/plugins/filters/unsharp/wdgunsharp.ui +++ b/plugins/filters/unsharp/wdgunsharp.ui @@ -31,7 +31,7 @@ - + 0 @@ -76,7 +76,7 @@ - + 0 @@ -111,7 +111,7 @@ - + 0 @@ -158,6 +158,18 @@ + + + KisIntParseSpinBox + QSpinBox +
kis_int_parse_spin_box.h
+
+ + KisDoubleParseSpinBox + QDoubleSpinBox +
kis_double_parse_spin_box.h
+
+
diff --git a/plugins/filters/wavefilter/wdgwaveoptions.ui b/plugins/filters/wavefilter/wdgwaveoptions.ui --- a/plugins/filters/wavefilter/wdgwaveoptions.ui +++ b/plugins/filters/wavefilter/wdgwaveoptions.ui @@ -11,7 +11,16 @@ - + + 0 + + + 0 + + + 0 + + 0 @@ -39,14 +48,23 @@ Horizontal Wave - + + 9 + + + 9 + + + 9 + + 9 - + - + @@ -127,7 +145,7 @@ - + @@ -151,7 +169,16 @@ Vertical Wave - + + 9 + + + 9 + + + 9 + + 9 @@ -207,7 +234,7 @@ - + @@ -236,10 +263,10 @@ - + - + @@ -261,6 +288,11 @@ + KisIntParseSpinBox + QSpinBox +
kis_int_parse_spin_box.h
+
+ KComboBox QComboBox
kcombobox.h
diff --git a/plugins/flake/artistictextshape/ArtisticTextShapeConfigWidget.ui b/plugins/flake/artistictextshape/ArtisticTextShapeConfigWidget.ui --- a/plugins/flake/artistictextshape/ArtisticTextShapeConfigWidget.ui +++ b/plugins/flake/artistictextshape/ArtisticTextShapeConfigWidget.ui @@ -17,7 +17,16 @@
- + + 0 + + + 0 + + + 0 + + 0 @@ -31,7 +40,7 @@ - + 0 @@ -137,9 +146,9 @@ - QSpinBox + KisIntParseSpinBox QSpinBox -
knuminput.h
+
kis_int_parse_spin_box.h
KoFontComboBox diff --git a/plugins/flake/artistictextshape/CMakeLists.txt b/plugins/flake/artistictextshape/CMakeLists.txt --- a/plugins/flake/artistictextshape/CMakeLists.txt +++ b/plugins/flake/artistictextshape/CMakeLists.txt @@ -37,6 +37,6 @@ add_library(krita_shape_artistictext MODULE ${ArtisticTextShape_SRCS} ) -target_link_libraries(krita_shape_artistictext kritaflake) +target_link_libraries(krita_shape_artistictext kritaflake kritaui) install( TARGETS krita_shape_artistictext DESTINATION ${KRITA_PLUGIN_INSTALL_DIR} ) diff --git a/plugins/flake/pathshapes/CMakeLists.txt b/plugins/flake/pathshapes/CMakeLists.txt --- a/plugins/flake/pathshapes/CMakeLists.txt +++ b/plugins/flake/pathshapes/CMakeLists.txt @@ -35,6 +35,6 @@ add_library(krita_shape_paths MODULE ${pathshapes_SOURCES}) -target_link_libraries(krita_shape_paths kritaflake kritawidgets) +target_link_libraries(krita_shape_paths kritaflake kritawidgets kritaui) install(TARGETS krita_shape_paths DESTINATION ${KRITA_PLUGIN_INSTALL_DIR}) diff --git a/plugins/flake/pathshapes/ellipse/EllipseShapeConfigWidget.ui b/plugins/flake/pathshapes/ellipse/EllipseShapeConfigWidget.ui --- a/plugins/flake/pathshapes/ellipse/EllipseShapeConfigWidget.ui +++ b/plugins/flake/pathshapes/ellipse/EllipseShapeConfigWidget.ui @@ -1,75 +1,76 @@ - + + EllipseShapeConfigWidget - - + + 0 0 - 187 + 188 173 - + Ellipse Shape - - - - + + + + Type: - - + + - - - + + + Start angle: - - - + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - + ° - - - + + + End angle: - - - + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - + ° - - - + + + Close ellipse - + - + Qt::Vertical - + 20 40 @@ -79,6 +80,13 @@ + + + KisDoubleParseSpinBox + QDoubleSpinBox +
kis_double_parse_spin_box.h
+
+
diff --git a/plugins/flake/pathshapes/rectangle/RectangleShapeConfigWidget.ui b/plugins/flake/pathshapes/rectangle/RectangleShapeConfigWidget.ui --- a/plugins/flake/pathshapes/rectangle/RectangleShapeConfigWidget.ui +++ b/plugins/flake/pathshapes/rectangle/RectangleShapeConfigWidget.ui @@ -1,44 +1,45 @@ - + + RectangleShapeConfigWidget - - + + 0 0 - 198 + 200 108 - + Rectangle Shape - - - - + + + + Corner radius x: - - + + - - - + + + Corner radius y: - - + + - + - + Qt::Vertical - + 20 40 @@ -50,9 +51,9 @@ - KoUnitDoubleSpinBox + KisDoubleParseUnitSpinBox QDoubleSpinBox -
KoUnitDoubleSpinBox.h
+
kis_double_parse_unit_spin_box.h
diff --git a/plugins/flake/pathshapes/spiral/SpiralShapeConfigWidget.ui b/plugins/flake/pathshapes/spiral/SpiralShapeConfigWidget.ui --- a/plugins/flake/pathshapes/spiral/SpiralShapeConfigWidget.ui +++ b/plugins/flake/pathshapes/spiral/SpiralShapeConfigWidget.ui @@ -1,70 +1,71 @@ - + + SpiralShapeConfigWidget - - + + 0 0 187 173 - + Spiral Shape - - - - + + + + Type: - - + + - - - + + + Fade: - - - + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - + - + 1.000000000000000 - + 0.100000000000000 - + 0.500000000000000 - - - + + + Direction: - - + + - + - + Qt::Vertical - + 20 40 @@ -74,6 +75,13 @@ + + + KisDoubleParseSpinBox + QDoubleSpinBox +
kis_double_parse_spin_box.h
+
+
diff --git a/plugins/flake/pathshapes/star/StarShapeConfigWidget.ui b/plugins/flake/pathshapes/star/StarShapeConfigWidget.ui --- a/plugins/flake/pathshapes/star/StarShapeConfigWidget.ui +++ b/plugins/flake/pathshapes/star/StarShapeConfigWidget.ui @@ -1,79 +1,80 @@ - + + StarShapeConfigWidget - - + + 0 0 189 175 - + Star shape - - - - + + + + Polygon: - - - + + + Qt::LeftToRight - + - - - + + + Corners: - - + + - - - + + + Inner radius: - - - + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - + + + Outer radius: - - - + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - + - + Qt::Vertical - + 20 40 @@ -85,14 +86,14 @@ - QSpinBox + KisIntParseSpinBox QSpinBox -
knuminput.h
+
kis_int_parse_spin_box.h
- KoUnitDoubleSpinBox + KisDoubleParseUnitSpinBox QDoubleSpinBox -
KoUnitDoubleSpinBox.h
+
kis_double_parse_unit_spin_box.h
diff --git a/plugins/impex/heightmap/kis_wdg_options_heightmap.ui b/plugins/impex/heightmap/kis_wdg_options_heightmap.ui --- a/plugins/impex/heightmap/kis_wdg_options_heightmap.ui +++ b/plugins/impex/heightmap/kis_wdg_options_heightmap.ui @@ -6,8 +6,8 @@ 0 0 - 177 - 100 + 191 + 145
@@ -32,7 +32,7 @@
- + 1000000 @@ -62,7 +62,7 @@ Big Endian
- Mac + &Mac
@@ -83,6 +83,13 @@
+ + + KisIntParseSpinBox + QSpinBox +
kis_int_parse_spin_box.h
+
+
diff --git a/plugins/impex/pdf/pdfimportwidgetbase.ui b/plugins/impex/pdf/pdfimportwidgetbase.ui --- a/plugins/impex/pdf/pdfimportwidgetbase.ui +++ b/plugins/impex/pdf/pdfimportwidgetbase.ui @@ -23,7 +23,7 @@ - &All pages + All pa&ges @@ -40,7 +40,7 @@ - &Selection of page + Selec&tion of page @@ -136,7 +136,7 @@ 0
- + 0 @@ -168,7 +168,7 @@ - + 0 @@ -202,7 +202,7 @@
- + 0 @@ -283,7 +283,7 @@ 0 - + 0 @@ -352,6 +352,11 @@
KoAspectButton.h
1
+ + KisIntParseSpinBox + QSpinBox +
kis_int_parse_spin_box.h
+
boolAllPages diff --git a/plugins/paintops/dynadraw/wdgdynaoptions.ui b/plugins/paintops/dynadraw/wdgdynaoptions.ui --- a/plugins/paintops/dynadraw/wdgdynaoptions.ui +++ b/plugins/paintops/dynadraw/wdgdynaoptions.ui @@ -26,7 +26,7 @@ - 0 + 1 @@ -46,7 +46,7 @@ - + -99.000000000000000 @@ -69,7 +69,7 @@ - + -99.000000000000000 @@ -92,7 +92,7 @@ - + -99.000000000000000 @@ -115,7 +115,7 @@ - + -99.000000000000000 @@ -229,7 +229,7 @@ - Circle + C&ircle true @@ -255,7 +255,7 @@ - + Line spacing @@ -265,7 +265,7 @@ - + Line count @@ -279,14 +279,14 @@ - Polygon + Poly&gon - Wire + Wi&re @@ -323,6 +323,16 @@ + KisIntParseSpinBox + QSpinBox +
kis_int_parse_spin_box.h
+
+ + KisDoubleParseSpinBox + QDoubleSpinBox +
kis_double_parse_spin_box.h
+
+ KisDoubleSliderSpinBox QWidget
kis_slider_spin_box.h
diff --git a/plugins/paintops/hairy/wdgInkOptions.ui b/plugins/paintops/hairy/wdgInkOptions.ui --- a/plugins/paintops/hairy/wdgInkOptions.ui +++ b/plugins/paintops/hairy/wdgInkOptions.ui @@ -27,7 +27,7 @@ 300 0 - 102 + 113 391
@@ -43,7 +43,7 @@ - + 10000 @@ -130,7 +130,7 @@ Ink Depletion Curve - + 9 @@ -176,7 +176,7 @@ - + 0 @@ -193,7 +193,7 @@ - + 0 @@ -203,7 +203,7 @@ - + 0 @@ -220,7 +220,7 @@ - + 0 @@ -234,6 +234,11 @@ + KisIntParseSpinBox + QSpinBox +
kis_int_parse_spin_box.h
+
+ KisDoubleSliderSpinBox QWidget
kis_slider_spin_box.h
diff --git a/plugins/paintops/hairy/wdghairyshapeoptions.ui b/plugins/paintops/hairy/wdghairyshapeoptions.ui --- a/plugins/paintops/hairy/wdghairyshapeoptions.ui +++ b/plugins/paintops/hairy/wdghairyshapeoptions.ui @@ -22,7 +22,7 @@ 285
- + 50 @@ -43,7 +43,7 @@ - + 5 @@ -60,15 +60,15 @@ - + 20.000000000000000
- + 50 @@ -87,7 +87,7 @@ - 1D + &1D false @@ -97,7 +97,7 @@ - 2D + &2D true @@ -123,6 +123,18 @@ + + + KisIntParseSpinBox + QSpinBox +
kis_int_parse_spin_box.h
+
+ + KisDoubleParseSpinBox + QDoubleSpinBox +
kis_double_parse_spin_box.h
+
+
diff --git a/plugins/paintops/hatching/wdghatchingoptions.ui b/plugins/paintops/hatching/wdghatchingoptions.ui --- a/plugins/paintops/hatching/wdghatchingoptions.ui +++ b/plugins/paintops/hatching/wdghatchingoptions.ui @@ -57,7 +57,7 @@
- + 1 @@ -95,7 +95,7 @@ - + 1 @@ -133,7 +133,7 @@ - + 1 @@ -171,7 +171,7 @@ - + 1 @@ -209,7 +209,7 @@ - + 1 @@ -265,7 +265,7 @@ - No crosshatching + No crosshatch&ing true @@ -287,7 +287,7 @@ - Perpendicular plane only + Pe&rpendicular plane only false @@ -309,7 +309,7 @@ - -45° plane then +45° plane + -&45° plane then +45° plane @@ -328,7 +328,7 @@ - +45° plane then -45° plane + +45° plane &then -45° plane
@@ -347,7 +347,7 @@ - Moiré pattern + &Moiré pattern @@ -383,7 +383,7 @@ - + 0 @@ -427,6 +427,11 @@ + KisIntParseSpinBox + QSpinBox +
kis_int_parse_spin_box.h
+
+ KisDoubleSliderSpinBox QWidget
kis_slider_spin_box.h
diff --git a/plugins/paintops/libpaintop/forms/wdgbrushchooser.ui b/plugins/paintops/libpaintop/forms/wdgbrushchooser.ui --- a/plugins/paintops/libpaintop/forms/wdgbrushchooser.ui +++ b/plugins/paintops/libpaintop/forms/wdgbrushchooser.ui @@ -6,7 +6,7 @@ 0 0 - 527 + 537 300 @@ -100,7 +100,7 @@
- + px @@ -123,7 +123,7 @@ - + px @@ -153,7 +153,7 @@ - + 0 @@ -168,6 +168,11 @@ + KisDoubleParseSpinBox + QDoubleSpinBox +
kis_double_parse_spin_box.h
+
+ KisSliderSpinBox QWidget
kis_slider_spin_box.h
diff --git a/plugins/tools/basictools/wdgcolorpicker.ui b/plugins/tools/basictools/wdgcolorpicker.ui --- a/plugins/tools/basictools/wdgcolorpicker.ui +++ b/plugins/tools/basictools/wdgcolorpicker.ui @@ -59,7 +59,7 @@
- + px @@ -156,6 +156,11 @@ QComboBox
squeezedcombobox.h
+ + KisIntParseSpinBox + QSpinBox +
kis_int_parse_spin_box.h
+
diff --git a/plugins/tools/basictools/wdgmovetool.ui b/plugins/tools/basictools/wdgmovetool.ui --- a/plugins/tools/basictools/wdgmovetool.ui +++ b/plugins/tools/basictools/wdgmovetool.ui @@ -6,7 +6,7 @@ 0 0 - 269 + 271 394 @@ -23,7 +23,7 @@ Move the layer that you have currently selected in the layerbox with its masks. Shortcut: ctrl-click. - Move current layer + &Move current layer true @@ -36,7 +36,7 @@ Move the first layer with visible content at the place where you click. This will also select that layer in the layerbox. - Move layer with content + Mo&ve layer with content false @@ -49,21 +49,24 @@ Move the group containing the first layer that contains visible content. Shortcut: ctrl-shift-click. - Move the whole group + Move &the whole group
+ + + Shortcut Move Distance - + Number of pixels to move after move shortcut keypress. @@ -82,7 +85,7 @@ - + When holding shift, move keyboard shortcuts scale up by this amount. @@ -107,7 +110,7 @@ - + Show coordinates on canvas @@ -117,7 +120,7 @@ - + @@ -176,15 +179,15 @@ Qt::LeftToRight - x: + &x: translateXBox - + 0 @@ -200,7 +203,7 @@ - + 0 @@ -224,7 +227,7 @@ Vertical Translation - y: + &y: translateYBox @@ -236,11 +239,23 @@ - + + + + KisDoubleParseSpinBox + QDoubleSpinBox +
kis_double_parse_spin_box.h
+
+ + KisIntParseSpinBox + QSpinBox +
kis_int_parse_spin_box.h
+
+
diff --git a/plugins/tools/defaulttool/CMakeLists.txt b/plugins/tools/defaulttool/CMakeLists.txt --- a/plugins/tools/defaulttool/CMakeLists.txt +++ b/plugins/tools/defaulttool/CMakeLists.txt @@ -33,5 +33,5 @@ qt5_add_resources(defaulttools_SRCS defaulttools.qrc) add_library(krita_flaketools MODULE ${defaulttools_SRCS}) -target_link_libraries(krita_flaketools kritaflake kritawidgets) +target_link_libraries(krita_flaketools kritaflake kritawidgets kritaui) install(TARGETS krita_flaketools DESTINATION ${KRITA_PLUGIN_INSTALL_DIR}) diff --git a/plugins/tools/defaulttool/defaulttool/DefaultToolTransformWidget.ui b/plugins/tools/defaulttool/defaulttool/DefaultToolTransformWidget.ui --- a/plugins/tools/defaulttool/defaulttool/DefaultToolTransformWidget.ui +++ b/plugins/tools/defaulttool/defaulttool/DefaultToolTransformWidget.ui @@ -1,186 +1,190 @@ - + + DefaultToolTransformWidget - - + + 0 0 222 293 - - - - - + + + + + + + + 2 0 - + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - + ° - + -360.000000000000000 - + 360.000000000000000 - - - + + + Rotate - - - - + + + + 2 0 - + -100.000000000000000 - + 100.000000000000000 - + 0.100000000000000 - - - + + + Shear X - - - - + + + + 2 0 - + -100.000000000000000 - + 100.000000000000000 - + 0.100000000000000 - - - + + + Shear Y - - - - + + + + 2 0 - + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - + % - + -1000.000000000000000 - + 1000.000000000000000 - + 100.000000000000000 - - - + + + Scale X - - - - + + + + 2 0 - + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - + % - + -1000.000000000000000 - + 1000.000000000000000 - + 100.000000000000000 - - - + + + Scale Y - - - + + + Keep aspect ratio - - - - + + + + 0 0 - + Reset Transformations - - - + + + Qt::Vertical - + 191 58 @@ -192,9 +196,14 @@ - KoUnitDoubleSpinBox + KisDoubleParseSpinBox + QDoubleSpinBox +
kis_double_parse_spin_box.h
+
+ + KisDoubleParseUnitSpinBox QDoubleSpinBox -
KoUnitDoubleSpinBox.h
+
kis_double_parse_unit_spin_box.h
diff --git a/plugins/tools/defaulttool/defaulttool/DefaultToolWidget.ui b/plugins/tools/defaulttool/defaulttool/DefaultToolWidget.ui --- a/plugins/tools/defaulttool/defaulttool/DefaultToolWidget.ui +++ b/plugins/tools/defaulttool/defaulttool/DefaultToolWidget.ui @@ -6,15 +6,24 @@ 0 0 - 158 - 64 + 256 + 76
Qt::NoFocus - + + 0 + + + 0 + + + 0 + + 0 @@ -31,7 +40,7 @@
- + 0 @@ -47,7 +56,7 @@ - + 0 @@ -63,20 +72,20 @@ - + 0 0 - + - + 0 @@ -93,7 +102,7 @@ - + 0 @@ -109,7 +118,7 @@ - + 0 @@ -125,7 +134,7 @@ - + 0 @@ -138,14 +147,15 @@ - KoUnitDoubleSpinBox - QDoubleSpinBox -
KoUnitDoubleSpinBox.h
-
- KoAspectButton - QLabel + QWidget
KoAspectButton.h
+ 1 +
+ + KisDoubleParseUnitSpinBox + QDoubleSpinBox +
kis_double_parse_unit_spin_box.h
KoPositionSelector diff --git a/plugins/tools/karbonplugins/filtereffects/BlurEffectConfigWidget.cpp b/plugins/tools/karbonplugins/filtereffects/BlurEffectConfigWidget.cpp --- a/plugins/tools/karbonplugins/filtereffects/BlurEffectConfigWidget.cpp +++ b/plugins/tools/karbonplugins/filtereffects/BlurEffectConfigWidget.cpp @@ -27,13 +27,15 @@ #include #include +#include "kis_double_parse_spin_box.h" + BlurEffectConfigWidget::BlurEffectConfigWidget(QWidget *parent) : KoFilterEffectConfigWidgetBase(parent), m_effect(0) { QGridLayout *g = new QGridLayout(this); g->addWidget(new QLabel(i18n("Radius"), this), 0, 0); - m_stdDeviation = new QDoubleSpinBox(this); + m_stdDeviation = new KisDoubleParseSpinBox(this); m_stdDeviation->setRange(0.0, 100); m_stdDeviation->setSingleStep(0.5); g->addWidget(m_stdDeviation, 0, 1); diff --git a/plugins/tools/karbonplugins/filtereffects/CMakeLists.txt b/plugins/tools/karbonplugins/filtereffects/CMakeLists.txt --- a/plugins/tools/karbonplugins/filtereffects/CMakeLists.txt +++ b/plugins/tools/karbonplugins/filtereffects/CMakeLists.txt @@ -38,6 +38,6 @@ add_library(krita_filtereffects MODULE ${karbon_filtereffects_SOURCES}) -target_link_libraries(krita_filtereffects kritaflake kritawidgets KF5::Completion) +target_link_libraries(krita_filtereffects kritaflake kritawidgets kritaui KF5::Completion) install(TARGETS krita_filtereffects DESTINATION ${KRITA_PLUGIN_INSTALL_DIR}) diff --git a/plugins/tools/karbonplugins/filtereffects/ColorMatrixEffectConfigWidget.cpp b/plugins/tools/karbonplugins/filtereffects/ColorMatrixEffectConfigWidget.cpp --- a/plugins/tools/karbonplugins/filtereffects/ColorMatrixEffectConfigWidget.cpp +++ b/plugins/tools/karbonplugins/filtereffects/ColorMatrixEffectConfigWidget.cpp @@ -32,6 +32,8 @@ #include #include +#include "kis_double_parse_spin_box.h" + ColorMatrixEffectConfigWidget::ColorMatrixEffectConfigWidget(QWidget *parent) : KoFilterEffectConfigWidgetBase(parent) , m_effect(0) @@ -62,7 +64,7 @@ QWidget *saturateWidget = new QWidget(m_stack); QGridLayout *saturateLayout = new QGridLayout(saturateWidget); saturateLayout->addWidget(new QLabel(i18n("Saturate value"), saturateWidget), 0, 0); - m_saturate = new QDoubleSpinBox(saturateWidget); + m_saturate = new KisDoubleParseSpinBox(saturateWidget); m_saturate->setRange(0.0, 1.0); m_saturate->setSingleStep(0.05); saturateLayout->addWidget(m_saturate, 0, 1); @@ -73,7 +75,7 @@ QWidget *hueRotateWidget = new QWidget(m_stack); QGridLayout *hueRotateLayout = new QGridLayout(hueRotateWidget); hueRotateLayout->addWidget(new QLabel(i18n("Angle"), hueRotateWidget), 0, 0); - m_hueRotate = new QDoubleSpinBox(hueRotateWidget); + m_hueRotate = new KisDoubleParseSpinBox(hueRotateWidget); m_hueRotate->setRange(0.0, 360.0); m_hueRotate->setSingleStep(1.0); hueRotateLayout->addWidget(m_hueRotate, 0, 1); diff --git a/plugins/tools/karbonplugins/filtereffects/ComponentTransferEffectConfigWidget.cpp b/plugins/tools/karbonplugins/filtereffects/ComponentTransferEffectConfigWidget.cpp --- a/plugins/tools/karbonplugins/filtereffects/ComponentTransferEffectConfigWidget.cpp +++ b/plugins/tools/karbonplugins/filtereffects/ComponentTransferEffectConfigWidget.cpp @@ -31,6 +31,8 @@ #include #include +#include "kis_double_parse_spin_box.h" + const qreal ValueStep = 0.1; ComponentTransferEffectConfigWidget::ComponentTransferEffectConfigWidget(QWidget *parent) @@ -96,12 +98,12 @@ QWidget *linearWidget = new QWidget(m_stack); QGridLayout *linearLayout = new QGridLayout(linearWidget); linearLayout->addWidget(new QLabel(i18n("Slope"), linearWidget), 0, 0); - m_slope = new QDoubleSpinBox(linearWidget); + m_slope = new KisDoubleParseSpinBox(linearWidget); m_slope->setRange(m_slope->minimum(), m_slope->maximum()); m_slope->setSingleStep(ValueStep); linearLayout->addWidget(m_slope, 0, 1); linearLayout->addWidget(new QLabel(i18n("Intercept")), 1, 0); - m_intercept = new QDoubleSpinBox(linearWidget); + m_intercept = new KisDoubleParseSpinBox(linearWidget); m_intercept->setRange(m_intercept->minimum(), m_intercept->maximum()); m_intercept->setSingleStep(ValueStep); linearLayout->addWidget(m_intercept, 1, 1); @@ -113,17 +115,17 @@ QWidget *gammaWidget = new QWidget(m_stack); QGridLayout *gammaLayout = new QGridLayout(gammaWidget); gammaLayout->addWidget(new QLabel(i18n("Amplitude"), gammaWidget), 0, 0); - m_amplitude = new QDoubleSpinBox(gammaWidget); + m_amplitude = new KisDoubleParseSpinBox(gammaWidget); m_amplitude->setRange(m_amplitude->minimum(), m_amplitude->maximum()); m_amplitude->setSingleStep(ValueStep); gammaLayout->addWidget(m_amplitude, 0, 1); gammaLayout->addWidget(new QLabel(i18n("Exponent"), gammaWidget), 1, 0); - m_exponent = new QDoubleSpinBox(gammaWidget); + m_exponent = new KisDoubleParseSpinBox(gammaWidget); m_exponent->setRange(m_exponent->minimum(), m_exponent->maximum()); m_exponent->setSingleStep(ValueStep); gammaLayout->addWidget(m_exponent, 1, 1); gammaLayout->addWidget(new QLabel(i18n("Offset"), gammaWidget), 2, 0); - m_offset = new QDoubleSpinBox(gammaWidget); + m_offset = new KisDoubleParseSpinBox(gammaWidget); m_offset->setRange(m_offset->minimum(), m_offset->maximum()); m_offset->setSingleStep(ValueStep); gammaLayout->addWidget(m_offset, 2, 1); diff --git a/plugins/tools/karbonplugins/filtereffects/CompositeEffectConfigWidget.cpp b/plugins/tools/karbonplugins/filtereffects/CompositeEffectConfigWidget.cpp --- a/plugins/tools/karbonplugins/filtereffects/CompositeEffectConfigWidget.cpp +++ b/plugins/tools/karbonplugins/filtereffects/CompositeEffectConfigWidget.cpp @@ -28,6 +28,8 @@ #include #include +#include "kis_double_parse_spin_box.h" + CompositeEffectConfigWidget::CompositeEffectConfigWidget(QWidget *parent) : KoFilterEffectConfigWidgetBase(parent) , m_effect(0) @@ -48,7 +50,7 @@ m_arithmeticWidget = new QWidget(this); QGridLayout *arithmeticLayout = new QGridLayout(m_arithmeticWidget); for (int i = 0; i < 4; ++i) { - m_k[i] = new QDoubleSpinBox(m_arithmeticWidget); + m_k[i] = new KisDoubleParseSpinBox(m_arithmeticWidget); arithmeticLayout->addWidget(new QLabel(QString("k%1").arg(i + 1)), i / 2, (2 * i) % 4); arithmeticLayout->addWidget(m_k[i], i / 2, (2 * i + 1) % 4); connect(m_k[i], SIGNAL(valueChanged(double)), this, SLOT(valueChanged())); diff --git a/plugins/tools/karbonplugins/filtereffects/ConvolveMatrixEffectConfigWidget.cpp b/plugins/tools/karbonplugins/filtereffects/ConvolveMatrixEffectConfigWidget.cpp --- a/plugins/tools/karbonplugins/filtereffects/ConvolveMatrixEffectConfigWidget.cpp +++ b/plugins/tools/karbonplugins/filtereffects/ConvolveMatrixEffectConfigWidget.cpp @@ -35,6 +35,9 @@ #include #include +#include "kis_double_parse_spin_box.h" +#include "kis_int_parse_spin_box.h" + ConvolveMatrixEffectConfigWidget::ConvolveMatrixEffectConfigWidget(QWidget *parent) : KoFilterEffectConfigWidgetBase(parent) , m_effect(0) @@ -48,26 +51,26 @@ g->addWidget(new QLabel(i18n("Edge mode:"), this), 0, 0); g->addWidget(m_edgeMode, 0, 1, 1, 3); - m_orderX = new QSpinBox(this); + m_orderX = new KisIntParseSpinBox(this); m_orderX->setRange(1, 30); - m_orderY = new QSpinBox(this); + m_orderY = new KisIntParseSpinBox(this); m_orderY->setRange(1, 30); g->addWidget(new QLabel(i18n("Kernel size:"), this), 1, 0); g->addWidget(m_orderX, 1, 1); g->addWidget(new QLabel("X", this), 1, 2, Qt::AlignHCenter); g->addWidget(m_orderY, 1, 3); - m_targetX = new QSpinBox(this); + m_targetX = new KisIntParseSpinBox(this); m_targetX->setRange(0, 30); - m_targetY = new QSpinBox(this); + m_targetY = new KisIntParseSpinBox(this); m_targetY->setRange(0, 30); g->addWidget(new QLabel(i18n("Target point:"), this), 2, 0); g->addWidget(m_targetX, 2, 1); g->addWidget(new QLabel("X", this), 2, 2, Qt::AlignHCenter); g->addWidget(m_targetY, 2, 3); - m_divisor = new QDoubleSpinBox(this); - m_bias = new QDoubleSpinBox(this); + m_divisor = new KisDoubleParseSpinBox(this); + m_bias = new KisDoubleParseSpinBox(this); g->addWidget(new QLabel(i18n("Divisor:"), this), 3, 0); g->addWidget(m_divisor, 3, 1); g->addWidget(new QLabel(i18n("Bias:"), this), 3, 2); diff --git a/plugins/tools/karbonplugins/filtereffects/MatrixDataModel.cpp b/plugins/tools/karbonplugins/filtereffects/MatrixDataModel.cpp --- a/plugins/tools/karbonplugins/filtereffects/MatrixDataModel.cpp +++ b/plugins/tools/karbonplugins/filtereffects/MatrixDataModel.cpp @@ -19,6 +19,8 @@ #include "MatrixDataModel.h" +#include "kis_num_parser.h" + MatrixDataModel::MatrixDataModel(QObject *parent) : QAbstractTableModel(parent) , m_rows(0) @@ -69,7 +71,7 @@ { int element = index.row() * m_cols + index.column(); bool valid = false; - qreal elementValue = value.toDouble(&valid); + qreal elementValue = KisNumericParser::parseSimpleMathExpr(value.toString(), &valid); if (!valid) { return false; } diff --git a/plugins/tools/karbonplugins/filtereffects/MorphologyEffectConfigWidget.cpp b/plugins/tools/karbonplugins/filtereffects/MorphologyEffectConfigWidget.cpp --- a/plugins/tools/karbonplugins/filtereffects/MorphologyEffectConfigWidget.cpp +++ b/plugins/tools/karbonplugins/filtereffects/MorphologyEffectConfigWidget.cpp @@ -29,6 +29,8 @@ #include #include +#include "kis_double_parse_spin_box.h" + MorphologyEffectConfigWidget::MorphologyEffectConfigWidget(QWidget *parent) : KoFilterEffectConfigWidgetBase(parent) , m_effect(0) @@ -45,13 +47,13 @@ g->addWidget(dilate, 0, 2); g->addWidget(new QLabel(i18n("Radius x:"), this), 1, 0); - m_radiusX = new QDoubleSpinBox(this); + m_radiusX = new KisDoubleParseSpinBox(this); m_radiusX->setRange(0.0, 100); m_radiusX->setSingleStep(0.5); g->addWidget(m_radiusX, 1, 1, 1, 2); g->addWidget(new QLabel(i18n("Radius y:"), this), 2, 0); - m_radiusY = new QDoubleSpinBox(this); + m_radiusY = new KisDoubleParseSpinBox(this); m_radiusY->setRange(0.0, 100); m_radiusY->setSingleStep(0.5); g->addWidget(m_radiusY, 2, 1, 1, 2); diff --git a/plugins/tools/karbonplugins/filtereffects/OffsetEffectConfigWidget.cpp b/plugins/tools/karbonplugins/filtereffects/OffsetEffectConfigWidget.cpp --- a/plugins/tools/karbonplugins/filtereffects/OffsetEffectConfigWidget.cpp +++ b/plugins/tools/karbonplugins/filtereffects/OffsetEffectConfigWidget.cpp @@ -25,6 +25,8 @@ #include #include +#include "kis_double_parse_spin_box.h" + const qreal OffsetLimit = 100.0; OffsetEffectConfigWidget::OffsetEffectConfigWidget(QWidget *parent) @@ -34,13 +36,13 @@ QGridLayout *g = new QGridLayout(this); g->addWidget(new QLabel(i18n("dx"), this), 0, 0); - m_offsetX = new QDoubleSpinBox(this); + m_offsetX = new KisDoubleParseSpinBox(this); m_offsetX->setRange(-OffsetLimit, OffsetLimit); m_offsetX->setSingleStep(1.0); g->addWidget(m_offsetX, 0, 1); g->addWidget(new QLabel(i18n("dy"), this), 0, 2); - m_offsetY = new QDoubleSpinBox(this); + m_offsetY = new KisDoubleParseSpinBox(this); m_offsetY->setRange(-OffsetLimit, OffsetLimit); m_offsetY->setSingleStep(1.0); g->addWidget(m_offsetY, 0, 3); diff --git a/plugins/tools/karbonplugins/tools/CMakeLists.txt b/plugins/tools/karbonplugins/tools/CMakeLists.txt --- a/plugins/tools/karbonplugins/tools/CMakeLists.txt +++ b/plugins/tools/karbonplugins/tools/CMakeLists.txt @@ -44,7 +44,7 @@ add_library(krita_karbontools MODULE ${karbon_tools_SOURCES}) -target_link_libraries(krita_karbontools kritawidgets KF5::Completion) +target_link_libraries(krita_karbontools kritaui kritawidgets KF5::Completion) install(TARGETS krita_karbontools DESTINATION ${KRITA_PLUGIN_INSTALL_DIR}) diff --git a/plugins/tools/karbonplugins/tools/CalligraphyTool/KarbonCalligraphyOptionWidget.cpp b/plugins/tools/karbonplugins/tools/CalligraphyTool/KarbonCalligraphyOptionWidget.cpp --- a/plugins/tools/karbonplugins/tools/CalligraphyTool/KarbonCalligraphyOptionWidget.cpp +++ b/plugins/tools/karbonplugins/tools/CalligraphyTool/KarbonCalligraphyOptionWidget.cpp @@ -37,6 +37,9 @@ #include #include +#include "kis_double_parse_spin_box.h" +#include "kis_int_parse_spin_box.h" + /* Profiles are saved in karboncalligraphyrc @@ -87,15 +90,15 @@ QLabel *widthLabel = new QLabel(i18n("Width:"), this); widthLabel->setAlignment(Qt::AlignRight | Qt::AlignVCenter); - m_widthBox = new QDoubleSpinBox(this); + m_widthBox = new KisDoubleParseSpinBox(this); m_widthBox->setRange(0.0, 999.0); widthLabel->setBuddy(m_widthBox); detailsLayout->addWidget(widthLabel, 2, 2); detailsLayout->addWidget(m_widthBox, 2, 3); QLabel *thinningLabel = new QLabel(i18n("Thinning:"), this); thinningLabel->setAlignment(Qt::AlignRight | Qt::AlignVCenter); - m_thinningBox = new QDoubleSpinBox(this); + m_thinningBox = new KisDoubleParseSpinBox(this); m_thinningBox->setRange(-1.0, 1.0); m_thinningBox->setSingleStep(0.1); thinningLabel->setBuddy(m_thinningBox); @@ -107,43 +110,43 @@ QLabel *angleLabel = new QLabel(i18n("Angle:"), this); angleLabel->setAlignment(Qt::AlignRight | Qt::AlignVCenter); - m_angleBox = new QSpinBox(this); + m_angleBox = new KisIntParseSpinBox(this); m_angleBox->setRange(0, 179); m_angleBox->setWrapping(true); angleLabel->setBuddy(m_angleBox); detailsLayout->addWidget(angleLabel, 4, 0); detailsLayout->addWidget(m_angleBox, 4, 1); QLabel *fixationLabel = new QLabel(i18n("Fixation:"), this); fixationLabel->setAlignment(Qt::AlignRight | Qt::AlignVCenter); - m_fixationBox = new QDoubleSpinBox(this); + m_fixationBox = new KisDoubleParseSpinBox(this); m_fixationBox->setRange(0.0, 1.0); m_fixationBox->setSingleStep(0.1); fixationLabel->setBuddy(m_fixationBox); detailsLayout->addWidget(fixationLabel, 5, 0); detailsLayout->addWidget(m_fixationBox, 5, 1); QLabel *capsLabel = new QLabel(i18n("Caps:"), this); capsLabel->setAlignment(Qt::AlignRight | Qt::AlignVCenter); - m_capsBox = new QDoubleSpinBox(this); + m_capsBox = new KisDoubleParseSpinBox(this); m_capsBox->setRange(0.0, 2.0); m_capsBox->setSingleStep(0.03); capsLabel->setBuddy(m_capsBox); detailsLayout->addWidget(capsLabel, 5, 2); detailsLayout->addWidget(m_capsBox, 5, 3); QLabel *massLabel = new QLabel(i18n("Mass:"), this); massLabel->setAlignment(Qt::AlignRight | Qt::AlignVCenter); - m_massBox = new QDoubleSpinBox(this); + m_massBox = new KisDoubleParseSpinBox(this); m_massBox->setRange(0.0, 20.0); m_massBox->setDecimals(1); massLabel->setBuddy(m_massBox); detailsLayout->addWidget(massLabel, 6, 0); detailsLayout->addWidget(m_massBox, 6, 1); QLabel *dragLabel = new QLabel(i18n("Drag:"), this); dragLabel->setAlignment(Qt::AlignRight | Qt::AlignVCenter); - m_dragBox = new QDoubleSpinBox(this); + m_dragBox = new KisDoubleParseSpinBox(this); m_dragBox->setRange(0.0, 1.0); m_dragBox->setSingleStep(0.1); dragLabel->setBuddy(m_dragBox); diff --git a/plugins/tools/karbonplugins/tools/KarbonPatternOptionsWidget.ui b/plugins/tools/karbonplugins/tools/KarbonPatternOptionsWidget.ui --- a/plugins/tools/karbonplugins/tools/KarbonPatternOptionsWidget.ui +++ b/plugins/tools/karbonplugins/tools/KarbonPatternOptionsWidget.ui @@ -1,125 +1,135 @@ - + + PatternOptionsWidget - - + + 0 0 240 253 - - + + 0 - - - + + 0 + + + 0 + + + 0 + + + + Repeat: - - + + - - - + + + Reference Point: - - + + - - - + + + Reference Point Offset - - - + + + X: - - + + - - - + + + Y: - - + + - - - + + + Tile Offset - - - + + + X: - - + + - - - + + + Y: - - + + - - - + + + Pattern Size - - - + + + W: - - + + - - - + + + H: - - + + - - - + + + Qt::Vertical - + 94 121 @@ -131,6 +141,16 @@ + KisIntParseSpinBox + QSpinBox +
kis_int_parse_spin_box.h
+
+ + KisDoubleParseSpinBox + QDoubleSpinBox +
kis_double_parse_spin_box.h
+
+ KComboBox QComboBox
kcombobox.h
diff --git a/plugins/tools/karbonplugins/tools/filterEffectTool/KarbonFilterEffectsTool.cpp b/plugins/tools/karbonplugins/tools/filterEffectTool/KarbonFilterEffectsTool.cpp --- a/plugins/tools/karbonplugins/tools/filterEffectTool/KarbonFilterEffectsTool.cpp +++ b/plugins/tools/karbonplugins/tools/filterEffectTool/KarbonFilterEffectsTool.cpp @@ -55,6 +55,8 @@ #include #include +#include "kis_double_parse_spin_box.h" + class KarbonFilterEffectsTool::Private { public: @@ -514,25 +516,25 @@ filterRegionWidget->setObjectName("EffectRegion"); QGridLayout *filterRegionLayout = new QGridLayout(filterRegionWidget); - d->posX = new QDoubleSpinBox(filterRegionWidget); + d->posX = new KisDoubleParseSpinBox(filterRegionWidget); d->posX->setSuffix("%"); connect(d->posX, SIGNAL(valueChanged(double)), this, SLOT(regionXChanged(double))); filterRegionLayout->addWidget(new QLabel(i18n("X:")), 0, 0); filterRegionLayout->addWidget(d->posX, 0, 1); - d->posY = new QDoubleSpinBox(filterRegionWidget); + d->posY = new KisDoubleParseSpinBox(filterRegionWidget); d->posY->setSuffix("%"); connect(d->posY, SIGNAL(valueChanged(double)), this, SLOT(regionYChanged(double))); filterRegionLayout->addWidget(new QLabel(i18n("Y:")), 1, 0); filterRegionLayout->addWidget(d->posY, 1, 1); - d->posW = new QDoubleSpinBox(filterRegionWidget); + d->posW = new KisDoubleParseSpinBox(filterRegionWidget); d->posW->setSuffix("%"); connect(d->posW, SIGNAL(valueChanged(double)), this, SLOT(regionWidthChanged(double))); filterRegionLayout->addWidget(new QLabel(i18n("W:")), 0, 2); filterRegionLayout->addWidget(d->posW, 0, 3); - d->posH = new QDoubleSpinBox(filterRegionWidget); + d->posH = new KisDoubleParseSpinBox(filterRegionWidget); d->posH->setSuffix("%"); connect(d->posH, SIGNAL(valueChanged(double)), this, SLOT(regionHeightChanged(double))); filterRegionLayout->addWidget(new QLabel(i18n("H:")), 1, 2); diff --git a/plugins/tools/tool_crop/wdg_tool_crop.ui b/plugins/tools/tool_crop/wdg_tool_crop.ui --- a/plugins/tools/tool_crop/wdg_tool_crop.ui +++ b/plugins/tools/tool_crop/wdg_tool_crop.ui @@ -6,8 +6,8 @@ 0 0 - 230 - 200 + 288 + 242
@@ -72,7 +72,7 @@ Vertical Position - Y: + &Y: intY @@ -85,15 +85,15 @@ Horizontal Position - X: + &X: intX
- + 60 @@ -118,7 +118,7 @@ - + 60 @@ -226,7 +226,7 @@ - + 60 @@ -251,7 +251,7 @@ - + 60 @@ -276,7 +276,7 @@ - + 60 @@ -473,6 +473,18 @@
+ + + KisIntParseSpinBox + QSpinBox +
kis_int_parse_spin_box.h
+
+ + KisDoubleParseSpinBox + QDoubleSpinBox +
kis_double_parse_spin_box.h
+
+
intX intY diff --git a/plugins/tools/tool_transform2/wdg_tool_transform.ui b/plugins/tools/tool_transform2/wdg_tool_transform.ui --- a/plugins/tools/tool_transform2/wdg_tool_transform.ui +++ b/plugins/tools/tool_transform2/wdg_tool_transform.ui @@ -6,8 +6,8 @@ 0 0 - 424 - 558 + 479 + 591
@@ -309,7 +309,7 @@ Qt::RightToLeft - Filter: + &Filter: Qt::AlignCenter @@ -507,7 +507,7 @@
- + 0 @@ -523,7 +523,7 @@ - Position + Posi&tion true @@ -536,7 +536,7 @@ - Rotate + &Rotate freeTransformRadioGroup @@ -703,15 +703,15 @@ Qt::LeftToRight - x: + &x: aXBox - + Rotate around X-Axis @@ -738,22 +738,22 @@ Qt::LeftToRight - y: + &y: aYBox - + Rotate around Y-Axis - + 0 @@ -786,7 +786,7 @@ Qt::LeftToRight - z: + &z: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter @@ -865,7 +865,7 @@ Horizontal Scale - width: + w&idth: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter @@ -876,7 +876,7 @@ - + 0 @@ -886,13 +886,13 @@ Horizontal Scale - + % - + 0 @@ -902,7 +902,7 @@ Vertical Scale - + % @@ -925,7 +925,7 @@ Vertical Scale
- height: + &height: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter @@ -938,7 +938,7 @@
- + 0 @@ -1025,7 +1025,7 @@ - + 0 @@ -1041,7 +1041,7 @@ - + 0 @@ -1156,7 +1156,7 @@ - + 0 @@ -1197,7 +1197,7 @@ - + 0 @@ -1389,7 +1389,7 @@ 0 - + 0 @@ -1413,7 +1413,7 @@ - Flexibility: + &Flexibility: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter @@ -1442,7 +1442,7 @@ - Anchor Strength: + Anc&hor Strength: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter @@ -1481,7 +1481,7 @@ 10 30 241 - 26 + 29 @@ -1509,7 +1509,7 @@ - Subdivide + Subd&ivide true @@ -1523,7 +1523,7 @@ - + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter @@ -1542,8 +1542,8 @@ 10 60 - 241 - 31 + 290 + 47 @@ -1582,7 +1582,7 @@ - + false @@ -1635,7 +1635,7 @@ - Add/Edit Anchor Points + Add/Ed&it Anchor Points true @@ -1651,7 +1651,7 @@ true - Deform Layer + De&form Layer cageTransformButtonGroup @@ -1854,7 +1854,7 @@ - + @@ -1895,7 +1895,7 @@ - + @@ -1917,7 +1917,7 @@ - + @@ -1939,7 +1939,7 @@ - + @@ -2151,21 +2151,26 @@ - + + KisCmbIDList + +
widgets/kis_cmb_idlist.h
+
+ KoAspectButton QWidget
KoAspectButton.h
1
- KisCmbIDList - QComboBox -
widgets/kis_cmb_idlist.h
+ KisIntParseSpinBox + QSpinBox +
kis_int_parse_spin_box.h
KisDoubleSliderSpinBox @@ -2177,8 +2182,8 @@ + -