[neon/snap-packaging/kcalc6] /: Show result while editing input

Gabriel Barrantes null at kde.org
Tue May 7 22:27:28 BST 2024


Git commit 5118570f6f8785ff8f7b471938bbf7b4784a79ce by Gabriel Barrantes.
Committed on 07/05/2024 at 14:45.
Pushed by carlosdem into branch 'master'.

Show result while editing input

Show result while editing input without the need to press the equal
button, if the input reaches an invalid state (non computable) during
editing, result will be cleared or not depending on the error, inputs
that fail to be parsed like "1+#" trigger a result clear, inputs that
yield a math error like "1/0" also clear the result, however intermediate
inputs like "1+2+" will keep the "3" in the result display. If the user
attempts to commit an invalid input using the equal button, an error
message will appear as previously implemented. Changing the base mode
or the trigonometric mode also triggers a result recalculation and update.

A backspace signal clears the result display if the input reaches an
invalid state regardless of the error type.

Results are not committed to history unless the equal button is pressed.

Change default result display to be empty instead of "0", it will also
be empty if the input goes back to empty.

BUG:480607

M  +57   -14   kcalc.cpp
M  +4    -1    kcalc.h
M  +30   -16   kcalc_core.cpp
M  +12   -3    kcalc_core.h
M  +10   -3    kcalc_display.cpp

https://invent.kde.org/neon/snap-packaging/kcalc6/-/commit/5118570f6f8785ff8f7b471938bbf7b4784a79ce

diff --git a/kcalc.cpp b/kcalc.cpp
index 7feef4b..61cb5a5 100644
--- a/kcalc.cpp
+++ b/kcalc.cpp
@@ -73,6 +73,7 @@ KCalculator::KCalculator(QWidget *parent)
     setupMainActions();
     setStatusBar(new KCalcStatusBar(this));
     createGUI();
+    setupDisplay();
     setupKeys();
 
     toolBar()->hide(); // hide by default
@@ -117,7 +118,7 @@ KCalculator::KCalculator(QWidget *parent)
 
     updateGeometry();
 
-    updateDisplay(UPDATE_FROM_CORE);
+    updateDisplay(UPDATE_CLEAR);
     // clear history, otherwise we have a leading "0" in it
     calc_history->clearHistory();
 
@@ -620,6 +621,15 @@ void KCalculator::setupMiscKeys()
     connect(pbEE, &KCalcButton::clicked, this, &KCalculator::slotEEclicked);
 }
 
+//------------------------------------------------------------------------------
+// Name: setupDisplay
+// Desc:
+//------------------------------------------------------------------------------
+void KCalculator::setupDisplay()
+{
+    connect(input_display, &KCalcInputDisplay::textChanged, this, &KCalculator::slotInputChanged);
+}
+
 //------------------------------------------------------------------------------
 // Name: createConstantsMenu
 // Desc: additional setup for button keys
@@ -800,6 +810,7 @@ void KCalculator::slotBaseSelected(QAbstractButton *button)
         }
 
         KCalcSettings::setBaseMode(base);
+        Q_EMIT slotInputChanged();
     }
 }
 
@@ -898,6 +909,7 @@ void KCalculator::slotAngleSelected(QAbstractButton *button, bool checked)
         }
 
         KCalcSettings::setAngleMode(angle_mode_);
+        Q_EMIT slotInputChanged();
     }
 }
 
@@ -1242,6 +1254,7 @@ void KCalculator::slotMemClearclicked()
 void KCalculator::slotBackspaceclicked()
 {
     this->input_display->slotClearOverwrite();
+    updateDisplay(UPDATE_CLEAR);
     this->input_display->backspace();
 }
 
@@ -1251,8 +1264,8 @@ void KCalculator::slotBackspaceclicked()
 //------------------------------------------------------------------------------
 void KCalculator::slotClearclicked()
 {
-    calc_display->sendEvent(KCalcDisplay::EventClear);
     input_display->clear();
+    updateDisplay(UPDATE_CLEAR);
 }
 
 //------------------------------------------------------------------------------
@@ -1262,9 +1275,7 @@ void KCalculator::slotClearclicked()
 void KCalculator::slotAllClearclicked()
 {
     this->input_display->clear();
-    core.Reset();
-    calc_display->sendEvent(KCalcDisplay::EventReset);
-    updateDisplay(UPDATE_FROM_CORE);
+    updateDisplay(UPDATE_CLEAR);
 }
 
 //------------------------------------------------------------------------------
@@ -1401,6 +1412,36 @@ void KCalculator::slotEqualclicked()
     }
 }
 
+//------------------------------------------------------------------------------
+// Name: slotInputChanged
+// Desc: updates result upon input change, does not commit to history
+//------------------------------------------------------------------------------
+void KCalculator::slotInputChanged()
+{
+    this->commit_Input_(true);
+
+    if (parsing_failure_) {
+        updateDisplay(UPDATE_CLEAR);
+        return;
+    } else if (calculation_failure_) {
+        switch (calculation_result_code_) {
+        case CalcEngine::ResultCode::MISIING_RIGHT_UNARY_ARG:
+        case CalcEngine::ResultCode::MISIING_RIGHT_BINARY_ARG:
+            break;
+        case CalcEngine::ResultCode::MATH_ERROR:
+            updateDisplay(UPDATE_CLEAR);
+            break;
+        default:
+            updateDisplay(UPDATE_CLEAR);
+            break;
+        }
+        return;
+    } else {
+        this->commit_Result_(false);
+        return;
+    }
+}
+
 //------------------------------------------------------------------------------
 // Name: slotPercentclicked
 // Desc: calculates and displays the result of the pending operations as a percent
@@ -2261,7 +2302,7 @@ void KCalculator::updateDisplay(UpdateFlags flags)
     } else if (flags & UPDATE_MALFORMED_EXPRESSION) {
         calc_display->setText(i18n("Input error"));
     } else if (flags & UPDATE_CLEAR) {
-        calc_display->setText(QLatin1String(""));
+        calc_display->sendEvent(KCalcDisplay::EventReset);
     } else {
         calc_display->update();
     }
@@ -2293,9 +2334,9 @@ void inline KCalculator::insertToInputDisplay(const QString &token)
 // Name: commit_Input_
 // Desc: takes string from display and queries parsing, if success, queries calculation
 //------------------------------------------------------------------------------
-int KCalculator::commit_Input_()
+int KCalculator::commit_Input_(bool editing /*= false*/)
 {
-    int parsing_result, calculation_result;
+    int parsing_result;
     parsing_result = parser.stringToTokenQueue(input_display->text(), base_mode_, token_Queue_, input_error_index_);
 
     if (parsing_result != 0) {
@@ -2303,18 +2344,20 @@ int KCalculator::commit_Input_()
         return -1;
     } else {
         parsing_failure_ = false;
-        calculation_result = core.calculate(token_Queue_, calculation_error_token_index_);
-        if (calculation_result != 0) {
+        calculation_result_code_ = core.calculate(token_Queue_, calculation_error_token_index_);
+        if (calculation_result_code_ != CalcEngine::ResultCode::SUCCESS) {
             input_error_index_ = token_Queue_.at(calculation_error_token_index_).getStringIndex();
             calculation_failure_ = true;
             return -1;
         } else {
             calculation_failure_ = false;
-            input_display->end(false);
-            if (!input_display->text().endsWith(QLatin1String("="))) {
-                this->insertToInputDisplay(KCalcToken::TokenCode::EQUAL);
+            if (!editing) {
+                input_display->end(false);
+                if (!input_display->text().endsWith(QLatin1String("="))) {
+                    this->insertToInputDisplay(KCalcToken::TokenCode::EQUAL);
+                }
+                input_display->slotSetOverwrite();
             }
-            input_display->slotSetOverwrite();
         }
     }
     return 0;
diff --git a/kcalc.h b/kcalc.h
index 25bd3d7..c616faa 100644
--- a/kcalc.h
+++ b/kcalc.h
@@ -120,6 +120,7 @@ private:
     bool event(QEvent *e) override;
     void updateGeometry();
     void setupMainActions();
+    void setupDisplay();
     void setupKeys();
     void setupNumberKeys();
     void setupRightKeypad();
@@ -219,6 +220,7 @@ protected Q_SLOTS:
     void slotHyptoggled(bool flag);
     void slotConstclicked(int);
     void slotBackspaceclicked();
+    void slotInputChanged();
 
     void slotConstantToDisplay(const science_constant &const_chosen);
     void slotChooseScientificConst0(const science_constant &);
@@ -243,7 +245,7 @@ private:
     enum BaseMode { BinMode = 2, OctMode = 8, DecMode = 10, HexMode = 16 };
 
 private:
-    int commit_Input_();
+    int commit_Input_(bool editing = false);
     void commit_Result_(bool toHistory = true);
     int load_Constants_(const QString &filePath);
 
@@ -257,6 +259,7 @@ private:
     int base_mode_;
 
     bool parsing_failure_, calculation_failure_;
+    CalcEngine::ResultCode calculation_result_code_;
     int input_error_index_;
     int calculation_error_token_index_;
     void inline handle_Parsing_Error_();
diff --git a/kcalc_core.cpp b/kcalc_core.cpp
index 37bcbe6..ea1084f 100644
--- a/kcalc_core.cpp
+++ b/kcalc_core.cpp
@@ -103,7 +103,7 @@ void CalcEngine::Reset()
     StatClearAll();
 }
 
-int CalcEngine::calculate(const QQueue<KCalcToken> tokenBuffer, int &errorIndex)
+CalcEngine::ResultCode CalcEngine::calculate(const QQueue<KCalcToken> tokenBuffer, int &errorIndex)
 {
     token_stack_.clear();
     int token_index = 0;
@@ -137,7 +137,7 @@ int CalcEngine::calculate(const QQueue<KCalcToken> tokenBuffer, int &errorIndex)
         case KCalcToken::TokenType::RIGHT_UNARY_FUNCTION_TYPE:
             if (token_index + 1 >= buffer_size) {
                 errorIndex = token_index;
-                return -1;
+                return MISIING_RIGHT_UNARY_ARG;
             }
             if (!token_stack_.isEmpty()) {
                 if (token_stack_.last().isKNumber()) {
@@ -151,11 +151,11 @@ int CalcEngine::calculate(const QQueue<KCalcToken> tokenBuffer, int &errorIndex)
         case KCalcToken::TokenType::LEFT_UNARY_FUNCTION_TYPE:
             if (token_stack_.isEmpty()) {
                 errorIndex = token_index;
-                return -1;
+                return MISIING_LEFT_UNARY_ARG;
             }
             if (!token_stack_.last().isKNumber()) {
                 errorIndex = token_index;
-                return -1;
+                return MISIING_LEFT_UNARY_ARG;
             }
 
             if (token_stack_.size() > 1) {
@@ -182,7 +182,7 @@ int CalcEngine::calculate(const QQueue<KCalcToken> tokenBuffer, int &errorIndex)
         case KCalcToken::TokenType::BINARY_FUNCTION_TYPE:
             if (token_index + 1 >= buffer_size) {
                 errorIndex = token_index;
-                return -1;
+                return MISIING_RIGHT_BINARY_ARG;
             }
 
             if (token_stack_.isEmpty()) {
@@ -193,7 +193,7 @@ int CalcEngine::calculate(const QQueue<KCalcToken> tokenBuffer, int &errorIndex)
                     break;
                 default:
                     errorIndex = token_index;
-                    return -1;
+                    return SYNTAX_ERROR;
                     break;
                 }
             }
@@ -209,7 +209,7 @@ int CalcEngine::calculate(const QQueue<KCalcToken> tokenBuffer, int &errorIndex)
                     continue;
                 } else {
                     errorIndex = token_index;
-                    return -1;
+                    return SYNTAX_ERROR;
                 }
                 break;
             case KCalcToken::TokenType::RIGHT_UNARY_FUNCTION_TYPE:
@@ -227,7 +227,7 @@ int CalcEngine::calculate(const QQueue<KCalcToken> tokenBuffer, int &errorIndex)
                     token_stack_.push_back(KCalcToken(KNumber::Zero));
                 } else {
                     errorIndex = token_index;
-                    return -1;
+                    return SYNTAX_ERROR;
                 }
                 break;
             default:
@@ -255,13 +255,13 @@ int CalcEngine::calculate(const QQueue<KCalcToken> tokenBuffer, int &errorIndex)
         case KCalcToken::TokenType::CLOSING_PARENTHESES_TYPE:
             if (token_stack_.isEmpty()) {
                 errorIndex = token_index;
-                return -1;
+                return SYNTAX_ERROR;
             }
             switch (token_stack_.last().getTokenType()) {
             case KCalcToken::TokenType::BINARY_FUNCTION_TYPE:
             case KCalcToken::TokenType::RIGHT_UNARY_FUNCTION_TYPE:
                 errorIndex = token_index;
-                return -1;
+                return SYNTAX_ERROR;
                 break;
             default:
                 reduce_Stack_();
@@ -283,17 +283,30 @@ int CalcEngine::calculate(const QQueue<KCalcToken> tokenBuffer, int &errorIndex)
 
     if (token_stack_.isEmpty()) {
         buffer_result_ = KNumber::Zero;
-        return -2; // code for empthy calculation
-    } else if (token_stack_.last().getKNumber() == KNumber::NaN) {
+        return EMPTY_INPUT;
+    } else if (token_stack_.last().isKNumber() && token_stack_.last().getKNumber().type() == KNumber::Type::TYPE_ERROR) {
         error_ = true;
         buffer_result_ = token_stack_.last().getKNumber();
         token_stack_.clear();
-        return -1;
-    } else if (token_stack_.size() > 1) {
+        return MATH_ERROR;
+    } else if (token_stack_.size() > 2) {
         error_ = true;
         buffer_result_ = KNumber::NaN;
         token_stack_.clear();
-        return -1;
+        return SYNTAX_ERROR;
+    } else if (token_stack_.size() == 2 && token_stack_.last().isBinaryFunction() && token_stack_.at(0).isKNumber()) {
+        error_ = true;
+        if (token_stack_.at(0).getKNumber().type() == KNumber::Type::TYPE_ERROR) {
+            token_stack_.clear();
+            return MATH_ERROR;
+        } else {
+            token_stack_.clear();
+            return MISIING_RIGHT_BINARY_ARG;
+        }
+    } else if (!token_stack_.last().isKNumber()) {
+        error_ = true;
+        token_stack_.clear();
+        return SYNTAX_ERROR;
     } else {
         buffer_result_ = token_stack_.last().getKNumber();
         token_stack_.clear();
@@ -301,7 +314,8 @@ int CalcEngine::calculate(const QQueue<KCalcToken> tokenBuffer, int &errorIndex)
 
     qDebug() << "Result: " << buffer_result_.toQString(12, -1);
 
-    return 0;
+    error_ = false;
+    return SUCCESS;
 }
 
 int CalcEngine::insert_KNumber_Token_In_Stack_(const KCalcToken &token)
diff --git a/kcalc_core.h b/kcalc_core.h
index b8a1e98..72d2c9f 100644
--- a/kcalc_core.h
+++ b/kcalc_core.h
@@ -18,9 +18,18 @@ class CalcEngine
 public:
     CalcEngine();
 
-    enum CALCULATION_RESULT { SUCCESS, EMPTY_INPUT, MATH_ERROR, SYNTAX_ERROR };
-
-    int calculate(const QQueue<KCalcToken> tokenBuffer, int &errorIndex); // returs 0 on success
+    enum ResultCode {
+        SUCCESS,
+        EMPTY_INPUT,
+        MATH_ERROR,
+        MISIING_LEFT_UNARY_ARG,
+        MISIING_RIGHT_UNARY_ARG,
+        MISIING_RIGHT_BINARY_ARG,
+        INCOMPLETE_INPUT,
+        SYNTAX_ERROR
+    };
+
+    ResultCode calculate(const QQueue<KCalcToken> tokenBuffer, int &errorIndex); // returs 0 on success
     KNumber getResult();
 
     KNumber lastOutput(bool &error) const;
diff --git a/kcalc_display.cpp b/kcalc_display.cpp
index f854634..e889a5d 100644
--- a/kcalc_display.cpp
+++ b/kcalc_display.cpp
@@ -231,9 +231,8 @@ bool KCalcDisplay::sendEvent(Event event)
     case EventClear:
     case EventReset:
         display_amount_ = KNumber::Zero;
-        str_int_ = QStringLiteral("0");
+        str_int_.clear();
         str_int_exp_.clear();
-
         eestate_ = false;
         period_ = false;
         neg_sign_ = false;
@@ -477,6 +476,7 @@ bool KCalcDisplay::setAmount(const KNumber &new_amount)
     }
 
     setText(display_str);
+
     Q_EMIT changedAmount(display_amount_);
     return true;
 }
@@ -693,7 +693,10 @@ int KCalcDisplay::setBase(NumBase new_base)
     }
 
     // reset amount
-    setAmount(display_amount_);
+    if (!str_int_.isEmpty()) {
+        setAmount(display_amount_);
+    }
+
     return num_base_;
 }
 
@@ -716,6 +719,10 @@ void KCalcDisplay::setStatusText(int i, const QString &text)
 //------------------------------------------------------------------------------
 void KCalcDisplay::updateDisplay()
 {
+    if (str_int_.isEmpty()) {
+        setText(str_int_);
+        return;
+    }
     // Put sign in front.
     QString tmp_string;
     if (neg_sign_) {



More information about the Neon-commits mailing list