[utilities/kcalc] /: Add a display where the history of the calculations is stored

Christoph Cullmann null at kde.org
Tue Sep 14 20:30:39 BST 2021


Git commit 6ede51d19231237aeafad518668608664055a18a by Christoph Cullmann, on behalf of Antonio Prcela.
Committed on 14/09/2021 at 19:30.
Pushed by cullmann into branch 'master'.

Add a display where the history of the calculations is stored

M  +3    -1    CMakeLists.txt
M  +9    -0    doc/commands.docbook
M  +10   -0    doc/index.docbook
M  +20   -0    fonts.ui
M  +153  -3    kcalc.cpp
M  +4    -0    kcalc.h
M  +8    -0    kcalc.kcfg
M  +44   -18   kcalc.ui
M  +1    -0    kcalc_core.cpp
A  +127  -0    kcalchistory.cpp     [License: GPL (v2+)]
A  +49   -0    kcalchistory.h     [License: GPL (v2+)]
M  +2    -1    kcalcui.rc

https://invent.kde.org/utilities/kcalc/commit/6ede51d19231237aeafad518668608664055a18a

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 4aa842c..f55a5b5 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -96,7 +96,9 @@ target_sources(kcalc PRIVATE
    kcalc_statusbar.cpp
    stats.cpp 
    kcalc.qrc
-   )
+   kcalchistory.cpp
+   stats.cpp
+   kcalc.qrc )
 
 
 ki18n_wrap_ui(kcalc
diff --git a/doc/commands.docbook b/doc/commands.docbook
index f575a3d..9350675 100644
--- a/doc/commands.docbook
+++ b/doc/commands.docbook
@@ -94,6 +94,15 @@ buttons</link> and allows changing the numeral system.</action>
 </para></listitem>
 </varlistentry>
 
+<varlistentry>
+<term><menuchoice>
+<guimenu>Settings</guimenu>
+<guimenuitem>Show History</guimenuitem>
+</menuchoice></term>
+<listitem><para><action>Display the history.</action>
+</para></listitem>
+</varlistentry>
+
 <varlistentry>
 <term><menuchoice>
 <guimenu>Settings</guimenu>
diff --git a/doc/index.docbook b/doc/index.docbook
index 374e058..f0eb022 100644
--- a/doc/index.docbook
+++ b/doc/index.docbook
@@ -178,6 +178,16 @@ the second layout of the buttons visible.</para>
 </listitem>
 </varlistentry>
 
+<varlistentry>
+<term>History</term>
+<listitem>
+<para>The history area shows all the calculations done in &kcalc; for the active session of &kcalc;.
+Click on <guibutton>AC</guibutton> or press the shortcut <keycap>Del</keycap> to clear the content of the history.
+To activate or deactivate it, use the item <guilabel>Show History</guilabel> in the menu <guimenu>Settings</guimenu> of the
+menu bar, or press <keycombo action="simul">&Ctrl;<keycap>H</keycap></keycombo>.</para>
+</listitem>
+</varlistentry>
+
 </variablelist>
 </sect1>
 
diff --git a/fonts.ui b/fonts.ui
index 8f3980a..da20de9 100644
--- a/fonts.ui
+++ b/fonts.ui
@@ -55,6 +55,26 @@
        </property>
       </widget>
      </item>
+     <item row="2" column="0" >
+      <widget class="QLabel" name="historylabel" >
+       <property name="text" >
+        <string>&History font:</string>
+       </property>
+       <property name="buddy" >
+        <cstring>kcfg_HistoryFont</cstring>
+       </property>
+      </widget>
+     </item>
+     <item row="2" column="1" >
+      <widget class="KFontRequester" name="kcfg_HistoryFont" >
+       <property name="focusPolicy" >
+        <enum>Qt::WheelFocus</enum>
+       </property>
+       <property name="toolTip" >
+        <string>The font to use in the history</string>
+       </property>
+      </widget>
+     </item>
     </layout>
    </item>
    <item>
diff --git a/kcalc.cpp b/kcalc.cpp
index 62ee3c5..38d4ed2 100644
--- a/kcalc.cpp
+++ b/kcalc.cpp
@@ -55,6 +55,7 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 #include "kcalc_settings.h"
 #include "kcalc_statusbar.h"
 #include "kcalcdisplay.h"
+#include "kcalchistory.h"
 
 namespace
 {
@@ -101,7 +102,8 @@ KCalculator::KCalculator(QWidget *parent)
     base_conversion_labels_ = {binDisplay, hexDisplay, decDisplay, octDisplay};
 
     angle_choose_group_ = new QButtonGroup(this);
-    angle_choose_group_->setExclusive(true);
+    angle_choose_group_->
+    setExclusive(true);
     angle_choose_group_->addButton(degRadio, DegMode);
     angle_choose_group_->addButton(radRadio, RadMode);
     angle_choose_group_->addButton(gradRadio, GradMode);
@@ -121,6 +123,8 @@ KCalculator::KCalculator(QWidget *parent)
     }
 
     calc_display->changeSettings();
+    calc_history->changeSettings();
+    update_history_window_ = true;
     setPrecision();
 
     updateGeometry();
@@ -128,6 +132,8 @@ KCalculator::KCalculator(QWidget *parent)
     layout()->setSizeConstraint(QLayout::SetFixedSize);
 
     updateDisplay(UPDATE_FROM_CORE);
+    // clear history, otherwise we have a leading "0" in it
+    calc_history->clearHistory();
 
     // misc settings
     KCalcSettings::EnumCalculatorMode::type calculatorMode = KCalcSettings::calculatorMode();
@@ -202,6 +208,12 @@ void KCalculator::setupMainActions()
     connect(action_mode_numeral_, &KToggleAction::toggled, this, &KCalculator::slotSetNumeralMode);
 
     // settings menu
+    action_history_show_ = actionCollection()->add<KToggleAction>(QStringLiteral("show_history"));
+    action_history_show_->setText(i18n("Show &History"));
+    action_history_show_->setChecked(true);
+    action_history_show_->setShortcut(Qt::CTRL | Qt::Key_H);
+    connect(action_history_show_, &KToggleAction::toggled, this, &KCalculator::slotHistoryshow);
+
     action_constants_show_ = actionCollection()->add<KToggleAction>(QStringLiteral("show_constants"));
     action_constants_show_->setText(i18n("Constants &Buttons"));
     action_constants_show_->setChecked(true);
@@ -303,6 +315,8 @@ void KCalculator::setupRightKeypad()
     new QShortcut(Qt::Key_PageDown, pbAllClear, SLOT(animateClick()));
     connect(pbAllClear, &KCalcButton::clicked, this, &KCalculator::slotAllClearclicked);
     connect(this, &KCalculator::switchShowAccels, pbAllClear, &KCalcButton::slotSetAccelDisplayMode);
+    // also clear the content of the history when clicked
+    connect(pbAllClear, &KCalcButton::clicked, calc_history, &KCalcHistory::clearHistory);
 
     pbParenOpen->setShortcut(QKeySequence(Qt::Key_ParenLeft));
     connect(pbParenOpen, &KCalcButton::clicked, this, &KCalculator::slotParenOpenclicked);
@@ -943,9 +957,15 @@ void KCalculator::slotMemRecallclicked()
     // temp. work-around
     calc_display->sendEvent(KCalcDisplay::EventReset);
 
-    calc_display->setAmount(memory_num_);
+	// temp. work-around
+	calc_display->sendEvent(KCalcDisplay::EventReset);
+
+    calc_history->addToHistory(QStringLiteral(" MR"), false);
+
+	calc_display->setAmount(memory_num_);
     updateDisplay({});
     core.setOnlyUpdateOperation(false);
+    calc_history->addResultToHistory(memory_num_.toQString());
 }
 
 //------------------------------------------------------------------------------
@@ -954,6 +974,8 @@ void KCalculator::slotMemRecallclicked()
 //------------------------------------------------------------------------------
 void KCalculator::slotMemStoreclicked()
 {
+    calc_history->addToHistory(QStringLiteral(" M"), false);
+    update_history_window_ = false;
     EnterEqual(CalcEngine::REPEAT_PREVENT);
 
     memory_num_ = calc_display->getAmount();
@@ -1018,6 +1040,7 @@ void KCalculator::slotSinclicked()
     }
 
     updateDisplay(UPDATE_FROM_CORE);
+    calc_history->addResultToHistory(calc_display->getAmount().toQString(KCalcSettings::precision()));
 }
 
 //------------------------------------------------------------------------------
@@ -1030,6 +1053,7 @@ void KCalculator::slotPlusMinusclicked()
     // need the core to do this.
     if (!calc_display->sendEvent(KCalcDisplay::EventChangeSign)) {
         core.InvertSign(calc_display->getAmount());
+        update_history_window_ = false;
         updateDisplay(UPDATE_FROM_CORE);
     }
 }
@@ -1041,6 +1065,13 @@ void KCalculator::slotPlusMinusclicked()
 void KCalculator::slotMemPlusMinusclicked()
 {
     bool tmp_shift_mode = shift_mode_; // store this, because next command deletes shift_mode_
+    update_history_window_ = false;
+    if (!tmp_shift_mode) {
+        calc_history->addToHistory(QStringLiteral(" M+"), false);
+    } else {
+        calc_history->addToHistory(QStringLiteral(" M-"), false);
+    }
+
     EnterEqual(); // finish calculation so far, to store result into MEM
 
     if (!tmp_shift_mode) {
@@ -1064,13 +1095,16 @@ void KCalculator::slotCosclicked()
     if (hyp_mode_) {
         // cosh or arcosh
         if (!shift_mode_) {
+            calc_history->addFuncToHistory(QStringLiteral(" cosh "));
             core.CosHyp(calc_display->getAmount());
         } else {
+            calc_history->addFuncToHistory(QStringLiteral(" arcosh "));
             core.AreaCosHyp(calc_display->getAmount());
         }
     } else {
         // cosine or arccosine
         if (!shift_mode_) {
+            calc_history->addFuncToHistory(QStringLiteral(" cos "));
             switch (angle_mode_) {
             case DegMode:
                 core.CosDeg(calc_display->getAmount());
@@ -1083,6 +1117,7 @@ void KCalculator::slotCosclicked()
                 break;
             }
         } else {
+            calc_history->addFuncToHistory(QStringLiteral(" arccos "));
             switch (angle_mode_) {
             case DegMode:
                 core.ArcCosDeg(calc_display->getAmount());
@@ -1098,19 +1133,23 @@ void KCalculator::slotCosclicked()
     }
 
     updateDisplay(UPDATE_FROM_CORE);
+    calc_history->addResultToHistory(calc_display->getAmount().toQString(KCalcSettings::precision()));
 }
 
 //------------------------------------------------------------------------------
 // Name: slotSinclicked
-// Desc: executes the recipricol function
+// Desc: executes the reciprocal function
 //------------------------------------------------------------------------------
 void KCalculator::slotReciclicked()
 {
     if (shift_mode_) {
+        calc_history->addFuncToHistory(QStringLiteral(" nCm "));
         core.enterOperation(calc_display->getAmount(), CalcEngine::FUNC_BINOM);
     } else {
+        calc_history->addFuncToHistory(QStringLiteral(" 1/"));
         core.Reciprocal(calc_display->getAmount());
         updateDisplay(UPDATE_FROM_CORE);
+        calc_history->addResultToHistory(calc_display->getAmount().toQString(KCalcSettings::precision()));
         return;
     }
 
@@ -1119,6 +1158,10 @@ void KCalculator::slotReciclicked()
     calc_display->sendEvent(KCalcDisplay::EventReset);
     calc_display->setAmount(tmp_num);
     updateDisplay({});
+    calc_history->addResultToHistory(calc_display->getAmount().toQString(KCalcSettings::precision()));
+    if (shift_mode_) {
+        updateHistoryWithFunction(CalcEngine::FUNC_BINOM);
+    }
 }
 
 //------------------------------------------------------------------------------
@@ -1130,13 +1173,16 @@ void KCalculator::slotTanclicked()
     if (hyp_mode_) {
         // tanh or artanh
         if (!shift_mode_) {
+            calc_history->addFuncToHistory(QStringLiteral(" tanh "));
             core.TangensHyp(calc_display->getAmount());
         } else {
+            calc_history->addFuncToHistory(QStringLiteral(" artanh "));
             core.AreaTangensHyp(calc_display->getAmount());
         }
     } else {
         // tan or arctan
         if (!shift_mode_) {
+            calc_history->addFuncToHistory(QStringLiteral(" tan "));
             switch (angle_mode_) {
             case DegMode:
                 core.TangensDeg(calc_display->getAmount());
@@ -1149,6 +1195,7 @@ void KCalculator::slotTanclicked()
                 break;
             }
         } else {
+            calc_history->addFuncToHistory(QStringLiteral(" arctan "));
             switch (angle_mode_) {
             case DegMode:
                 core.ArcTangensDeg(calc_display->getAmount());
@@ -1164,6 +1211,7 @@ void KCalculator::slotTanclicked()
     }
 
     updateDisplay(UPDATE_FROM_CORE);
+    calc_history->addResultToHistory(calc_display->getAmount().toQString(KCalcSettings::precision()));
 }
 
 //------------------------------------------------------------------------------
@@ -1183,6 +1231,12 @@ void KCalculator::slotFactorialclicked()
     }
     QApplication::restoreOverrideCursor();
     updateDisplay(UPDATE_FROM_CORE);
+    if (!shift_mode_) {
+        calc_history->addFuncToHistory(QStringLiteral(" ! "));
+    } else {
+        calc_history->addFuncToHistory(QStringLiteral(" Γ "));
+    }
+    calc_history->addResultToHistory(calc_display->getAmount().toQString(KCalcSettings::precision()));
 }
 
 //------------------------------------------------------------------------------
@@ -1193,11 +1247,14 @@ void KCalculator::slotLogclicked()
 {
     if (!shift_mode_) {
         core.Log10(calc_display->getAmount());
+        calc_history->addFuncToHistory(QStringLiteral(" log "));
     } else {
         core.Exp10(calc_display->getAmount());
+        calc_history->addFuncToHistory(QStringLiteral(" 10<sup>x</sup> "));
     }
 
     updateDisplay(UPDATE_FROM_CORE);
+    calc_history->addResultToHistory(calc_display->getAmount().toQString(KCalcSettings::precision()));
 }
 
 //------------------------------------------------------------------------------
@@ -1206,13 +1263,19 @@ void KCalculator::slotLogclicked()
 //------------------------------------------------------------------------------
 void KCalculator::slotSquareclicked()
 {
+    bool tmp_shift_mode = shift_mode_;
     if (!shift_mode_) {
         core.Square(calc_display->getAmount());
     } else {
+        calc_history->addFuncToHistory(QStringLiteral(" √ "));
         core.SquareRoot(calc_display->getAmount());
     }
 
     updateDisplay(UPDATE_FROM_CORE);
+    if (!tmp_shift_mode) {
+        calc_history->addFuncToHistory(QStringLiteral(" <sup>2</sup> "));
+    }
+    calc_history->addResultToHistory(calc_display->getAmount().toQString(KCalcSettings::precision()));
 }
 
 //------------------------------------------------------------------------------
@@ -1221,13 +1284,19 @@ void KCalculator::slotSquareclicked()
 //------------------------------------------------------------------------------
 void KCalculator::slotCubeclicked()
 {
+    bool tmp_shift_mode = shift_mode_;
     if (!shift_mode_) {
         core.Cube(calc_display->getAmount());
     } else {
+        calc_history->addFuncToHistory(QStringLiteral(" <sup>3</sup>√ "));
         core.CubeRoot(calc_display->getAmount());
     }
 
     updateDisplay(UPDATE_FROM_CORE);
+    if (!tmp_shift_mode) {
+        calc_history->addFuncToHistory(QStringLiteral(" <sup>3</sup> "));
+    }
+    calc_history->addResultToHistory(calc_display->formatDecimalNumber(calc_display->getAmount().toQString(KCalcSettings::precision())));
 }
 
 //------------------------------------------------------------------------------
@@ -1237,12 +1306,15 @@ void KCalculator::slotCubeclicked()
 void KCalculator::slotLnclicked()
 {
     if (!shift_mode_) {
+        calc_history->addFuncToHistory(QStringLiteral(" ln "));
         core.Ln(calc_display->getAmount());
     } else {
+        calc_history->addFuncToHistory(QStringLiteral(" e<sup>") + calc_display->getAmount().toQString(KCalcSettings::precision()) + QStringLiteral("</sup>"));
         core.Exp(calc_display->getAmount());
     }
 
     updateDisplay(UPDATE_FROM_CORE);
+    calc_history->addResultToHistory(calc_display->getAmount().toQString(KCalcSettings::precision()));
 }
 
 //------------------------------------------------------------------------------
@@ -1252,9 +1324,11 @@ void KCalculator::slotLnclicked()
 void KCalculator::slotPowerclicked()
 {
     if (shift_mode_) {
+        calc_history->addFuncToHistory(calc_display->getAmount().toQString(KCalcSettings::precision()) + QStringLiteral("^ 1/"));
         core.enterOperation(calc_display->getAmount(), CalcEngine::FUNC_PWR_ROOT);
         pbShift->setChecked(false);
     } else {
+        calc_history->addFuncToHistory(calc_display->getAmount().toQString(KCalcSettings::precision()) + QStringLiteral("^"));
         core.enterOperation(calc_display->getAmount(), CalcEngine::FUNC_POWER);
     }
 
@@ -1275,6 +1349,7 @@ void KCalculator::slotMemClearclicked()
     statusBar()->setMemoryIndicator(false);
     calc_display->setStatusText(MemField, QString());
     pbMemRecall->setDisabled(true);
+    calc_history->addToHistory(QStringLiteral(" M cleared "), true);
 }
 
 //------------------------------------------------------------------------------
@@ -1313,6 +1388,7 @@ void KCalculator::slotAllClearclicked()
 void KCalculator::slotParenOpenclicked()
 {
     core.ParenOpen(calc_display->getAmount());
+    calc_history->addFuncToHistory(QStringLiteral(" ( "));
 }
 
 //------------------------------------------------------------------------------
@@ -1323,6 +1399,8 @@ void KCalculator::slotParenCloseclicked()
 {
     core.ParenClose(calc_display->getAmount());
     updateDisplay(UPDATE_FROM_CORE);
+    calc_history->addFuncToHistory(QStringLiteral(" ) "));
+    update_history_window_ = false;
 }
 
 //------------------------------------------------------------------------------
@@ -1333,6 +1411,7 @@ void KCalculator::slotANDclicked()
 {
     core.enterOperation(calc_display->getAmount(), CalcEngine::FUNC_AND);
     updateDisplay(UPDATE_FROM_CORE);
+    updateHistoryWithFunction(CalcEngine::FUNC_AND);
 }
 
 //------------------------------------------------------------------------------
@@ -1343,6 +1422,7 @@ void KCalculator::slotMultiplicationclicked()
 {
     core.enterOperation(calc_display->getAmount(), CalcEngine::FUNC_MULTIPLY);
     updateDisplay(UPDATE_FROM_CORE);
+    updateHistoryWithFunction(CalcEngine::FUNC_MULTIPLY);
 }
 
 //------------------------------------------------------------------------------
@@ -1353,6 +1433,7 @@ void KCalculator::slotDivisionclicked()
 {
     core.enterOperation(calc_display->getAmount(), CalcEngine::FUNC_DIVIDE);
     updateDisplay(UPDATE_FROM_CORE);
+    updateHistoryWithFunction(CalcEngine::FUNC_DIVIDE);
 }
 
 //------------------------------------------------------------------------------
@@ -1363,6 +1444,7 @@ void KCalculator::slotORclicked()
 {
     core.enterOperation(calc_display->getAmount(), CalcEngine::FUNC_OR);
     updateDisplay(UPDATE_FROM_CORE);
+    updateHistoryWithFunction(CalcEngine::FUNC_OR);
 }
 
 //------------------------------------------------------------------------------
@@ -1373,6 +1455,7 @@ void KCalculator::slotXORclicked()
 {
     core.enterOperation(calc_display->getAmount(), CalcEngine::FUNC_XOR);
     updateDisplay(UPDATE_FROM_CORE);
+    updateHistoryWithFunction(CalcEngine::FUNC_XOR);
 }
 
 //------------------------------------------------------------------------------
@@ -1383,6 +1466,7 @@ void KCalculator::slotPlusclicked()
 {
     core.enterOperation(calc_display->getAmount(), CalcEngine::FUNC_ADD);
     updateDisplay(UPDATE_FROM_CORE);
+    updateHistoryWithFunction(CalcEngine::FUNC_ADD);
 }
 
 //------------------------------------------------------------------------------
@@ -1393,6 +1477,7 @@ void KCalculator::slotMinusclicked()
 {
     core.enterOperation(calc_display->getAmount(), CalcEngine::FUNC_SUBTRACT);
     updateDisplay(UPDATE_FROM_CORE);
+    updateHistoryWithFunction(CalcEngine::FUNC_SUBTRACT);
 }
 
 //------------------------------------------------------------------------------
@@ -1403,6 +1488,7 @@ void KCalculator::slotLeftShiftclicked()
 {
     core.enterOperation(calc_display->getAmount(), CalcEngine::FUNC_LSH);
     updateDisplay(UPDATE_FROM_CORE);
+    updateHistoryWithFunction(CalcEngine::FUNC_LSH);
 }
 
 //------------------------------------------------------------------------------
@@ -1413,6 +1499,7 @@ void KCalculator::slotRightShiftclicked()
 {
     core.enterOperation(calc_display->getAmount(), CalcEngine::FUNC_RSH);
     updateDisplay(UPDATE_FROM_CORE);
+    updateHistoryWithFunction(CalcEngine::FUNC_RSH);
 }
 
 //------------------------------------------------------------------------------
@@ -1434,6 +1521,7 @@ void KCalculator::EnterEqual(CalcEngine::Repeat allow_repeat)
 {
     core.enterOperation(calc_display->getAmount(), CalcEngine::FUNC_EQUAL, allow_repeat);
     updateDisplay(UPDATE_FROM_CORE | UPDATE_STORE_RESULT);
+    calc_history->addResultToHistory(calc_display->getAmount().toQString(KCalcSettings::precision()));
 }
 
 //------------------------------------------------------------------------------
@@ -1453,6 +1541,8 @@ void KCalculator::slotPercentclicked()
 {
     core.enterOperation(calc_display->getAmount(), CalcEngine::FUNC_PERCENT);
     updateDisplay(UPDATE_FROM_CORE);
+    updateHistoryWithFunction(CalcEngine::FUNC_PERCENT);
+    calc_history->addResultToHistory(calc_display->getAmount().toQString(KCalcSettings::precision()));
 }
 
 //------------------------------------------------------------------------------
@@ -1462,8 +1552,10 @@ void KCalculator::slotPercentclicked()
 //------------------------------------------------------------------------------
 void KCalculator::slotNegateclicked()
 {
+    calc_history->addFuncToHistory(QStringLiteral(" ~ "));
     core.Complement(calc_display->getAmount());
     updateDisplay(UPDATE_FROM_CORE);
+    calc_history->addResultToHistory(calc_display->getAmount().toQString(KCalcSettings::precision()));
 }
 
 //------------------------------------------------------------------------------
@@ -1479,6 +1571,12 @@ void KCalculator::slotModclicked()
     }
 
     updateDisplay(UPDATE_FROM_CORE);
+
+    if (shift_mode_) {
+        updateHistoryWithFunction(CalcEngine::FUNC_INTDIV);
+    } else {
+        updateHistoryWithFunction(CalcEngine::FUNC_MOD);
+    }
 }
 
 //------------------------------------------------------------------------------
@@ -1487,15 +1585,19 @@ void KCalculator::slotModclicked()
 //------------------------------------------------------------------------------
 void KCalculator::slotStatNumclicked()
 {
+    update_history_window_ = false;
     if (!shift_mode_) {
         core.StatCount(KNumber::Zero);
+        calc_history->addToHistory(i18n("Number of data entered"), false);
     } else {
         pbShift->setChecked(false);
         core.StatSum(KNumber::Zero);
+        calc_history->addToHistory(QString::fromUtf8("\xce\xa3") + QLatin1Char('x'), false);
     }
 
     updateDisplay(UPDATE_FROM_CORE);
     core.setOnlyUpdateOperation(false);
+    calc_history->addResultToHistory(calc_display->getAmount().toQString(KCalcSettings::precision()));
 }
 
 //------------------------------------------------------------------------------
@@ -1504,15 +1606,19 @@ void KCalculator::slotStatNumclicked()
 //------------------------------------------------------------------------------
 void KCalculator::slotStatMeanclicked()
 {
+    update_history_window_ = false;
     if (!shift_mode_) {
         core.StatMean(KNumber::Zero);
+        calc_history->addToHistory(i18n("Mean"), false);
     } else {
         pbShift->setChecked(false);
         core.StatSumSquares(KNumber::Zero);
+        calc_history->addToHistory(QString::fromUtf8("\xce\xa3") + QLatin1String("x^2"), false);
     }
 
     updateDisplay(UPDATE_FROM_CORE);
     core.setOnlyUpdateOperation(false);
+    calc_history->addResultToHistory(calc_display->getAmount().toQString(KCalcSettings::precision()));
 }
 
 //------------------------------------------------------------------------------
@@ -1521,17 +1627,21 @@ void KCalculator::slotStatMeanclicked()
 //------------------------------------------------------------------------------
 void KCalculator::slotStatStdDevclicked()
 {
+    update_history_window_ = false;
     if (shift_mode_) {
         // std (n-1)
         core.StatStdSample(KNumber::Zero);
         pbShift->setChecked(false);
+        calc_history->addToHistory(QString::fromUtf8("\xcf\x83") + QLatin1String("<sub>N-1</sub>"), false);
     } else {
         // std (n)
         core.StatStdDeviation(KNumber::Zero);
+        calc_history->addToHistory(QString::fromUtf8("\xcf\x83") + QLatin1String(" N"), false);
     }
 
     updateDisplay(UPDATE_FROM_CORE);
     core.setOnlyUpdateOperation(false);
+    calc_history->addResultToHistory(calc_display->getAmount().toQString(KCalcSettings::precision()));
 }
 
 //------------------------------------------------------------------------------
@@ -1540,6 +1650,7 @@ void KCalculator::slotStatStdDevclicked()
 //------------------------------------------------------------------------------
 void KCalculator::slotStatMedianclicked()
 {
+    update_history_window_ = false;
     if (!shift_mode_) {
         core.StatMedian(KNumber::Zero);
     } else {
@@ -1547,9 +1658,11 @@ void KCalculator::slotStatMedianclicked()
         pbShift->setChecked(false);
     }
 
+    calc_history->addToHistory(i18n("Median"), false);
     // TODO: it seems two different modes should be implemented, but...?
     updateDisplay(UPDATE_FROM_CORE);
     core.setOnlyUpdateOperation(false);
+    calc_history->addResultToHistory(calc_display->getAmount().toQString(KCalcSettings::precision()));
 }
 
 //------------------------------------------------------------------------------
@@ -1558,12 +1671,18 @@ void KCalculator::slotStatMedianclicked()
 //------------------------------------------------------------------------------
 void KCalculator::slotStatDataInputclicked()
 {
+    update_history_window_ = false;
     if (!shift_mode_) {
+        bool tmp_error;
         core.StatDataNew(calc_display->getAmount());
+        calc_history->addToHistory(i18n("DAT [") + core.lastOutput(tmp_error).toQString() + i18n("] = ")
+                                       + calc_display->getAmount().toQString(KCalcSettings::precision()),
+                                   true);
     } else {
         pbShift->setChecked(false);
         core.StatDataDel(KNumber::Zero);
         statusBar()->showMessage(i18n("Last stat item erased"), 3000);
+        calc_history->addToHistory(i18n("Last stat item erased"), true);
     }
 
     updateDisplay(UPDATE_FROM_CORE);
@@ -1579,6 +1698,7 @@ void KCalculator::slotStatClearDataclicked()
     if (!shift_mode_) {
         core.StatClearAll(KNumber::Zero);
         statusBar()->showMessage(i18n("Stat mem cleared"), 3000);
+        calc_history->addToHistory(i18n("Stat mem cleared"), true);
     } else {
         pbShift->setChecked(false);
         updateDisplay({});
@@ -1760,6 +1880,7 @@ void KCalculator::slotSetSimpleMode()
     action_constants_show_->setChecked(false);
     action_constants_show_->setEnabled(false);
     action_bitset_show_->setEnabled(false);
+    action_history_show_->setChecked(KCalcSettings::showHistory());
     showMemButtons(false);
     showScienceButtons(false);
     showStatButtons(false);
@@ -1794,6 +1915,7 @@ void KCalculator::slotSetScienceMode()
     action_constants_show_->setEnabled(true);
     action_constants_show_->setChecked(KCalcSettings::showConstants());
     action_bitset_show_->setEnabled(false);
+    action_history_show_->setChecked(KCalcSettings::showHistory());
 
     // show some individual buttons
     pbShift->show();
@@ -1831,6 +1953,7 @@ void KCalculator::slotSetStatisticMode()
     action_constants_show_->setEnabled(true);
     action_constants_show_->setChecked(KCalcSettings::showConstants());
     action_bitset_show_->setEnabled(false);
+    action_history_show_->setChecked(KCalcSettings::showHistory());
 
     // show some individual buttons
     pbShift->show();
@@ -1869,6 +1992,7 @@ void KCalculator::slotSetNumeralMode()
     action_constants_show_->setEnabled(false);
     action_bitset_show_->setEnabled(true);
     action_bitset_show_->setChecked(KCalcSettings::showBitset());
+    action_history_show_->setChecked(KCalcSettings::showHistory());
 
     // show some individual buttons
     pbShift->show();
@@ -2039,6 +2163,16 @@ void KCalculator::showLogicButtons(bool toggled)
     }
 }
 
+//------------------------------------------------------------------------------
+// Name: slotHistoryshow
+// Desc: hides or shows the history
+//------------------------------------------------------------------------------
+void KCalculator::slotHistoryshow(bool toggled) {
+
+    calc_history->setVisible(toggled);
+    KCalcSettings::setShowHistory(toggled);
+}
+
 //------------------------------------------------------------------------------
 // Name: slotConstantsShow
 // Desc: hides or shows the constants buttons
@@ -2127,6 +2261,7 @@ void KCalculator::updateSettings()
     }
 
     calc_display->changeSettings();
+    calc_history->changeSettings();
     updateGeometry();
 }
 
@@ -2134,9 +2269,15 @@ void KCalculator::updateSettings()
 // Name: updateDisplay
 // Desc: updates the display
 //------------------------------------------------------------------------------
+
 void KCalculator::updateDisplay(UpdateFlags flags)
 {
     if (flags & UPDATE_FROM_CORE) {
+        if (update_history_window_) {
+            calc_history->addToHistory(calc_display->getAmount().toQString(KCalcSettings::precision()), false);
+        } else {
+            update_history_window_ = true;
+        }
         calc_display->updateFromCore(core, (flags & UPDATE_STORE_RESULT) != 0);
     } else {
         calc_display->update();
@@ -2145,6 +2286,14 @@ void KCalculator::updateDisplay(UpdateFlags flags)
     pbShift->setChecked(false);
 }
 
+//------------------------------------------------------------------------------
+// Name: updateHistoryWithFunction
+// Desc: updates the history with the last used function
+//------------------------------------------------------------------------------
+void KCalculator::updateHistoryWithFunction(CalcEngine::Operation func) {
+    calc_history->addFuncToHistory(func);
+}
+
 //------------------------------------------------------------------------------
 // Name: setColors
 // Desc: set the various colours
@@ -2152,6 +2301,7 @@ void KCalculator::updateDisplay(UpdateFlags flags)
 void KCalculator::setColors()
 {
     calc_display->changeSettings();
+    calc_history->changeSettings();
 
     const QColor numFontColor(KCalcSettings::numberFontsColor());
     for (int i = 0; i < 10; ++i) {
diff --git a/kcalc.h b/kcalc.h
index 6ec92b1..76412e7 100644
--- a/kcalc.h
+++ b/kcalc.h
@@ -141,6 +141,7 @@ private:
     void setBase();
 
     void updateDisplay(UpdateFlags flags);
+    void updateHistoryWithFunction(CalcEngine::Operation);
     KCalcStatusBar *statusBar();
 
     // button sets
@@ -165,6 +166,7 @@ protected Q_SLOTS:
     void slotSetStatisticMode();
     void slotSetNumeralMode();
 
+    void slotHistoryshow(bool toggled);
     void slotConstantsShow(bool toggled);
     void slotBitsetshow(bool toggled);
     void slotAngleSelected(QAbstractButton *button);
@@ -240,6 +242,7 @@ private:
 private:
     bool shift_mode_ = false;
     bool hyp_mode_ = false;
+    bool update_history_window_ = false;
     KNumber memory_num_;
 
     int angle_mode_; // angle modes for trigonometric values
@@ -260,6 +263,7 @@ private:
 
     std::array<QLabel *, 4> base_conversion_labels_;
 
+    KToggleAction *action_history_show_ = nullptr;
     KToggleAction *action_bitset_show_ = nullptr;
     KToggleAction *action_constants_show_ = nullptr;
 
diff --git a/kcalc.kcfg b/kcalc.kcfg
index 81a477b..a1db7cd 100644
--- a/kcalc.kcfg
+++ b/kcalc.kcfg
@@ -92,6 +92,10 @@
             defaultDisplayFont.setPointSizeF(defaultDisplayFont.pointSizeF() * 1.4);</code>
       <default code="true">defaultDisplayFont</default>
     </entry>
+    <entry name="HistoryFont" type="Font">
+      <label>The font to use in the history.</label>
+        <default code="true">QFontDatabase::systemFont(QFontDatabase::GeneralFont)</default>
+    </entry>
   </group>
   <group name="Precision">
     <entry name="Precision" type="UInt" key="precision">
@@ -169,6 +173,10 @@
       <label>Whether to show constant buttons.</label>
       <default>false</default>
     </entry>
+    <entry name="ShowHistory" type="Bool">
+      <label>Whether to show the history window.</label>
+      <default>false</default>
+    </entry>
     <entry name="AngleMode" type="UInt">
       <label>Degrees, radians or grads</label>
       <default>0</default>
diff --git a/kcalc.ui b/kcalc.ui
index 758f7ff..cca912a 100644
--- a/kcalc.ui
+++ b/kcalc.ui
@@ -6,7 +6,7 @@
    <rect>
     <x>0</x>
     <y>0</y>
-    <width>1084</width>
+    <width>1100</width>
     <height>350</height>
    </rect>
   </property>
@@ -112,7 +112,7 @@
           </widget>
          </item>
          <item>
-          <widget class="KSqueezedTextLabel" name="hexDisplay" native="true">
+          <widget class="KSqueezedTextLabel" name="hexDisplay">
            <property name="minimumSize">
             <size>
              <width>65</width>
@@ -125,8 +125,8 @@
              <height>16777215</height>
             </size>
            </property>
-           <property name="text" stdset="0">
-            <string>0</string>
+           <property name="text">
+            <string>KSq…bel</string>
            </property>
           </widget>
          </item>
@@ -148,7 +148,7 @@
           </widget>
          </item>
          <item>
-          <widget class="KSqueezedTextLabel" name="decDisplay" native="true">
+          <widget class="KSqueezedTextLabel" name="decDisplay">
            <property name="minimumSize">
             <size>
              <width>65</width>
@@ -161,8 +161,8 @@
              <height>16777215</height>
             </size>
            </property>
-           <property name="text" stdset="0">
-            <string>0</string>
+           <property name="text">
+            <string>KSq…bel</string>
            </property>
           </widget>
          </item>
@@ -184,7 +184,7 @@
           </widget>
          </item>
          <item>
-          <widget class="KSqueezedTextLabel" name="octDisplay" native="true">
+          <widget class="KSqueezedTextLabel" name="octDisplay">
            <property name="minimumSize">
             <size>
              <width>65</width>
@@ -197,8 +197,8 @@
              <height>16777215</height>
             </size>
            </property>
-           <property name="text" stdset="0">
-            <string>0</string>
+           <property name="text">
+            <string>KSq…bel</string>
            </property>
           </widget>
          </item>
@@ -220,7 +220,7 @@
           </widget>
          </item>
          <item>
-          <widget class="KSqueezedTextLabel" name="binDisplay" native="true">
+          <widget class="KSqueezedTextLabel" name="binDisplay">
            <property name="minimumSize">
             <size>
              <width>65</width>
@@ -233,8 +233,8 @@
              <height>16777215</height>
             </size>
            </property>
-           <property name="text" stdset="0">
-            <string>0</string>
+           <property name="text">
+            <string>KSq…bel</string>
            </property>
           </widget>
          </item>
@@ -1111,9 +1111,39 @@
      </item>
     </layout>
    </item>
+   <item>
+    <widget class="KCalcHistory" name="calc_history">
+     <property name="sizePolicy">
+      <sizepolicy hsizetype="MinimumExpanding" vsizetype="MinimumExpanding">
+       <horstretch>0</horstretch>
+       <verstretch>0</verstretch>
+      </sizepolicy>
+     </property>
+     <property name="minimumSize">
+      <size>
+       <width>80</width>
+       <height>0</height>
+      </size>
+     </property>
+     <property name="focusPolicy">
+      <enum>Qt::WheelFocus</enum>
+     </property>
+     <property name="frameShape">
+      <enum>QFrame::StyledPanel</enum>
+     </property>
+     <property name="frameShadow">
+      <enum>QFrame::Sunken</enum>
+     </property>
+    </widget>
+   </item>
   </layout>
  </widget>
  <customwidgets>
+  <customwidget>
+   <class>KSqueezedTextLabel</class>
+   <extends>QLabel</extends>
+   <header>ksqueezedtextlabel.h</header>
+  </customwidget>
   <customwidget>
    <class>KCalcButton</class>
    <extends>QPushButton</extends>
@@ -1136,11 +1166,6 @@
    <extends>QPushButton</extends>
    <header>kcalc_const_button.h</header>
   </customwidget>
-  <customwidget>
-   <class>KSqueezedTextLabel</class>
-   <extends>QWidget</extends>
-   <header>ksqueezedtextlabel.h</header>
-  </customwidget>
  </customwidgets>
  <tabstops>
   <tabstop>pb0</tabstop>
@@ -1210,6 +1235,7 @@
   <tabstop>radRadio</tabstop>
   <tabstop>gradRadio</tabstop>
   <tabstop>calc_display</tabstop>
+  <tabstop>calc_history</tabstop>
  </tabstops>
  <resources/>
  <connections/>
diff --git a/kcalc_core.cpp b/kcalc_core.cpp
index a176dd9..c661b21 100644
--- a/kcalc_core.cpp
+++ b/kcalc_core.cpp
@@ -26,6 +26,7 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 #include "kcalc_core.h"
 #include "kcalc_settings.h"
+#include "kcalchistory.h"
 
 #include <QDebug>
 
diff --git a/kcalchistory.cpp b/kcalchistory.cpp
new file mode 100644
index 0000000..4e77939
--- /dev/null
+++ b/kcalchistory.cpp
@@ -0,0 +1,127 @@
+/*
+ *  Copyright (c) 2021 Antonio Prcela <antonio.prcela at gmail.com>
+ *
+ *  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 "kcalchistory.h"
+#include "kcalc_settings.h"
+
+//------------------------------------------------------------------------------
+// Name: KCalcHistory
+// Desc: constructor
+//------------------------------------------------------------------------------
+KCalcHistory::KCalcHistory(QWidget *parent) : QTextEdit(parent) {
+    setReadOnly(true);
+    setAlignment(Qt::AlignRight);
+    setWordWrapMode(QTextOption::WrapAtWordBoundaryOrAnywhere);
+}
+
+//------------------------------------------------------------------------------
+// Name: KCalcHistory
+// Desc: destructor
+//------------------------------------------------------------------------------
+KCalcHistory::~KCalcHistory() {
+}
+
+//------------------------------------------------------------------------------
+// Name: addToHistory
+// Desc: Adds the latest calculations to the history window
+//------------------------------------------------------------------------------
+void KCalcHistory::addToHistory(const QString &str, bool new_lines_) {
+    setAlignment(Qt::AlignRight);
+    insertHtml(str);
+    if (new_lines_) {
+        insertHtml(QStringLiteral("<br>"));
+    }
+    ensureCursorVisible();
+}
+
+//------------------------------------------------------------------------------
+// Name: addResultToHistory
+// Desc: Used mostly for functions that are not in CalcEngine::Operation
+//       adds "=" and the result with newline endings
+//------------------------------------------------------------------------------
+void KCalcHistory::addResultToHistory(const QString &display_content) {
+    addToHistory(QStringLiteral(" = ") + display_content, true);
+}
+
+//------------------------------------------------------------------------------
+// Name: addFuncToHistory
+// Desc: Adds the current function symbol, taken via CalcEngine::Operation
+//       to the history window
+//------------------------------------------------------------------------------
+void KCalcHistory::addFuncToHistory(const CalcEngine::Operation FUNC) {
+    QString textToHistroy;
+
+    if (FUNC == CalcEngine::FUNC_PERCENT) {
+        textToHistroy = QStringLiteral(" % ");
+    } else if (FUNC == CalcEngine::FUNC_OR) {
+        textToHistroy = QStringLiteral(" OR ");
+    } else if (FUNC == CalcEngine::FUNC_XOR) {
+        textToHistroy = QStringLiteral(" XOR ");
+    } else if (FUNC == CalcEngine::FUNC_AND) {
+        textToHistroy = QStringLiteral(" AND ");
+    } else if (FUNC == CalcEngine::FUNC_LSH) {
+        textToHistroy = QStringLiteral(" Lsh ");
+    } else if (FUNC == CalcEngine::FUNC_RSH) {
+        textToHistroy = QStringLiteral(" Rsh ");
+    } else if (FUNC == CalcEngine::FUNC_ADD) {
+        textToHistroy = QStringLiteral(" + ");
+    } else if (FUNC == CalcEngine::FUNC_SUBTRACT) {
+        textToHistroy = QStringLiteral(" - ");
+    } else if (FUNC == CalcEngine::FUNC_MULTIPLY) {
+        textToHistroy = QStringLiteral(" × ");
+    } else if (FUNC == CalcEngine::FUNC_DIVIDE) {
+        textToHistroy = QStringLiteral(" ÷ ");
+    } else if (FUNC == CalcEngine::FUNC_MOD) {
+        textToHistroy = QStringLiteral(" Mod ");
+    } else if (FUNC == CalcEngine::FUNC_INTDIV) {
+        textToHistroy = QStringLiteral(" IntDiv ");
+    } else if (FUNC == CalcEngine::FUNC_BINOM) {
+        textToHistroy = QStringLiteral(" Binom ");
+    }
+
+    addToHistory(textToHistroy, false);
+}
+
+//------------------------------------------------------------------------------
+// Name: addFuncToHistory
+// Desc: Adds the current function symbol the history window
+//------------------------------------------------------------------------------
+void KCalcHistory::addFuncToHistory(const QString &func) {
+    addToHistory(func, false);
+}
+
+//------------------------------------------------------------------------------
+// Name: clearHistory
+// Desc: Clears the content of the history window
+//------------------------------------------------------------------------------
+void KCalcHistory::clearHistory() {
+    clear();
+    // somehow the alignment gets also reset, so we set it again
+    setAlignment(Qt::AlignRight);
+}
+
+void KCalcHistory::changeSettings() {
+    QPalette pal = palette();
+
+    pal.setColor(QPalette::Text, KCalcSettings::foreColor());
+    pal.setColor(QPalette::Base, KCalcSettings::backColor());
+
+    setPalette(pal);
+
+    setFont(KCalcSettings::historyFont());
+}
diff --git a/kcalchistory.h b/kcalchistory.h
new file mode 100644
index 0000000..84a954e
--- /dev/null
+++ b/kcalchistory.h
@@ -0,0 +1,49 @@
+/*
+ *  Copyright (c) 2021 Antonio Prcela <antonio.prcela at gmail.com>
+ *
+ *  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 KCALC_HISTORY_H_
+#define KCALC_HISTORY_H_
+
+#include <QTextEdit>
+
+#include "kcalc_core.h"
+
+/*
+  This class provides a history display.
+*/
+
+class KCalcHistory : public QTextEdit {
+	Q_OBJECT
+
+public:
+    explicit KCalcHistory(QWidget *parent = nullptr);
+    ~KCalcHistory() override;
+
+    void addToHistory(const QString &, bool);
+    void addResultToHistory(const QString &);
+    void addFuncToHistory(const CalcEngine::Operation);
+    void addFuncToHistory(const QString &);
+
+    void changeSettings();
+
+public Q_SLOTS:
+    void clearHistory();
+
+};
+
+#endif
diff --git a/kcalcui.rc b/kcalcui.rc
index 4c27065..187fb6d 100644
--- a/kcalcui.rc
+++ b/kcalcui.rc
@@ -1,5 +1,5 @@
 <!DOCTYPE gui SYSTEM "kpartgui.dtd">
-<gui name="kcalc" version="20">
+<gui name="kcalc" version="21">
 <MenuBar>
   <Menu name="settings" noMerge="1"><text>&Settings</text>
     <Action name="mode_simple"/>
@@ -7,6 +7,7 @@
     <Action name="mode_statistics"/>
     <Action name="mode_numeral"/>
     <Separator/>
+    <Action name="show_history"/>
     <Action name="show_constants"/>
     <Action name="show_bitset"/>
     <Separator/>


More information about the kde-doc-english mailing list