File indexing completed on 2024-06-16 05:22:19

0001 /*
0002     SPDX-FileCopyrightText: 2001-2013 Evan Teran <evan.teran@gmail.com>
0003     SPDX-FileCopyrightText: 2006 Michel Marti <mma@objectxp.com>
0004     SPDX-FileCopyrightText: 1996-2000 Bernd Johannes Wuebben <wuebben@kde.org>
0005 
0006     SPDX-License-Identifier: GPL-2.0-or-later
0007 */
0008 
0009 #include "kcalc.h"
0010 #include "kcalc_version.h"
0011 
0012 #include <clocale>
0013 
0014 #include <QActionGroup>
0015 #include <QApplication>
0016 #include <QButtonGroup>
0017 #include <QCommandLineParser>
0018 #include <QCursor>
0019 #include <QDomDocument>
0020 #include <QFile>
0021 #include <QKeyEvent>
0022 #include <QMenuBar>
0023 #include <QShortcut>
0024 #include <QStyle>
0025 
0026 #include <KAboutData>
0027 #include <KAcceleratorManager>
0028 #include <KActionCollection>
0029 #include <KColorMimeData>
0030 #include <KConfigDialog>
0031 #include <KCrash>
0032 #include <KStandardAction>
0033 #include <KToggleAction>
0034 #include <KToolBar>
0035 #include <KXMLGUIFactory>
0036 
0037 #include "kcalc_bitset.h"
0038 #include "kcalc_const_menu.h"
0039 #include "kcalc_parser.h"
0040 #include "kcalc_settings.h"
0041 #include "kcalc_statusbar.h"
0042 #include "kcalcdisplay.h"
0043 #include "kcalchistory.h"
0044 
0045 namespace
0046 {
0047 const int maxprecision = 1000;
0048 }
0049 
0050 //------------------------------------------------------------------------------
0051 // Name: KCalculator
0052 // Desc: constructor
0053 //------------------------------------------------------------------------------
0054 KCalculator::KCalculator(QWidget *parent)
0055     : KXmlGuiWindow(parent)
0056     , memory_num_(0.0)
0057     , base_mode_(10)
0058     , core()
0059 {
0060     // central widget to contain all the elements
0061     auto const central = new QWidget(this);
0062     central->setLayoutDirection(Qt::LeftToRight);
0063     setCentralWidget(central);
0064     KAcceleratorManager::setNoAccel(central);
0065 
0066     setAutoSaveSettings(QStringLiteral("KCalcMainWindow"));
0067 
0068     // load science constants_ from xml-file
0069     load_Constants_(QStringLiteral(":/kcalc/scienceconstants.xml"));
0070 
0071     // setup interface (order is critical)
0072     setupUi(central);
0073     setupMainActions();
0074     setStatusBar(new KCalcStatusBar(this));
0075     createGUI();
0076     setupKeys();
0077 
0078     toolBar()->hide(); // hide by default
0079 
0080     // create button groups
0081     base_choose_group_ = new QButtonGroup(this);
0082     base_choose_group_->setExclusive(true);
0083     base_choose_group_->addButton(hexRadio, HexMode);
0084     base_choose_group_->addButton(decRadio, DecMode);
0085     base_choose_group_->addButton(octRadio, OctMode);
0086     base_choose_group_->addButton(binRadio, BinMode);
0087     connect(base_choose_group_, &QButtonGroup::buttonClicked, this, &KCalculator::slotBaseSelected);
0088 
0089     base_conversion_labels_ = {binDisplay, hexDisplay, decDisplay, octDisplay};
0090 
0091     angle_choose_group_ = new QButtonGroup(this);
0092     angle_choose_group_->
0093     setExclusive(true);
0094     angle_choose_group_->addButton(degRadio, DegMode);
0095     angle_choose_group_->addButton(radRadio, RadMode);
0096     angle_choose_group_->addButton(gradRadio, GradMode);
0097     connect(angle_choose_group_, &QButtonGroup::buttonToggled, this, &KCalculator::slotAngleSelected);
0098 
0099     // additional menu setup
0100     constants_menu_ = createConstantsMenu();
0101     menuBar()->insertMenu((menuBar()->actions)()[2], constants_menu_);
0102 
0103     // misc setup
0104     setColors();
0105     setBaseFont(KCalcSettings::buttonFont());
0106     setFonts();
0107 
0108     // Show the result in the app's caption in taskbar (wishlist - bug #52858)
0109     if (KCalcSettings::captionResult()) {
0110         connect(calc_display, &KCalcDisplay::changedText, this, &KCalculator::setWindowTitle);
0111     }
0112 
0113     calc_display->changeSettings();
0114     calc_history->changeSettings();
0115     update_history_window_ = true;
0116     setPrecision();
0117 
0118     updateGeometry();
0119 
0120     updateDisplay(UPDATE_FROM_CORE);
0121     // clear history, otherwise we have a leading "0" in it
0122     calc_history->clearHistory();
0123 
0124     // set angle mode and base mode before mangling GUI
0125     setAngle();
0126     setBase();
0127 
0128     // misc settings
0129     KCalcSettings::EnumCalculatorMode::type calculatorMode = KCalcSettings::calculatorMode();
0130 
0131     switch (calculatorMode) {
0132     case KCalcSettings::EnumCalculatorMode::science:
0133         action_mode_science_->setChecked(true);
0134         break;
0135     case KCalcSettings::EnumCalculatorMode::statistics:
0136         action_mode_statistic_->setChecked(true);
0137         break;
0138     case KCalcSettings::EnumCalculatorMode::numeral:
0139         action_mode_numeral_->setChecked(true);
0140         break;
0141     case KCalcSettings::EnumCalculatorMode::simple:
0142     default:
0143         action_mode_simple_->setChecked(true);
0144     }
0145     is_still_in_launch_ = false;
0146 
0147     calc_display->setFocus();
0148 }
0149 
0150 //------------------------------------------------------------------------------
0151 // Name: ~KCalculator
0152 // Desc: deconstructor
0153 //------------------------------------------------------------------------------
0154 KCalculator::~KCalculator()
0155 {
0156     KCalcSettings::self()->save();
0157 }
0158 
0159 //------------------------------------------------------------------------------
0160 // Name: setupMainActions
0161 // Desc: connects all of the basic actions
0162 //------------------------------------------------------------------------------
0163 void KCalculator::setupMainActions()
0164 {
0165     // file menu
0166     KStandardAction::quit(this, SLOT(close()), actionCollection());
0167 
0168     // edit menu
0169     KStandardAction::undo(calc_display, SLOT(slotHistoryBack()), actionCollection());
0170     KStandardAction::redo(calc_display, SLOT(slotHistoryForward()), actionCollection());
0171     KStandardAction::cut(calc_display, SLOT(slotCut()), actionCollection());
0172     KStandardAction::copy(calc_display, SLOT(slotCopy()), actionCollection());
0173     KStandardAction::paste(this, SLOT(slotPaste()), actionCollection());
0174 
0175     // mode menu
0176     auto modeGroup = new QActionGroup(this);
0177 
0178     action_mode_simple_ = actionCollection()->add<KToggleAction>(QStringLiteral("mode_simple"));
0179     action_mode_simple_->setActionGroup(modeGroup);
0180     action_mode_simple_->setText(i18n("Simple Mode"));
0181     connect(action_mode_simple_, &KToggleAction::toggled, this, &KCalculator::slotSetSimpleMode);
0182 
0183     action_mode_science_ = actionCollection()->add<KToggleAction>(QStringLiteral("mode_science"));
0184     action_mode_science_->setActionGroup(modeGroup);
0185     action_mode_science_->setText(i18n("Science Mode"));
0186     connect(action_mode_science_, &KToggleAction::toggled, this, &KCalculator::slotSetScienceMode);
0187 
0188     action_mode_statistic_ = actionCollection()->add<KToggleAction>(QStringLiteral("mode_statistics"));
0189     action_mode_statistic_->setActionGroup(modeGroup);
0190     action_mode_statistic_->setText(i18n("Statistic Mode"));
0191     connect(action_mode_statistic_, &KToggleAction::toggled, this, &KCalculator::slotSetStatisticMode);
0192 
0193     action_mode_numeral_ = actionCollection()->add<KToggleAction>(QStringLiteral("mode_numeral"));
0194     action_mode_numeral_->setActionGroup(modeGroup);
0195     action_mode_numeral_->setText(i18n("Numeral System Mode"));
0196     connect(action_mode_numeral_, &KToggleAction::toggled, this, &KCalculator::slotSetNumeralMode);
0197 
0198     // settings menu
0199     action_history_show_ = actionCollection()->add<KToggleAction>(QStringLiteral("show_history"));
0200     action_history_show_->setText(i18n("Show &History"));
0201     action_history_show_->setChecked(true);
0202     actionCollection()->setDefaultShortcut(action_history_show_, Qt::CTRL | Qt::Key_H);
0203     connect(action_history_show_, &KToggleAction::toggled, this, &KCalculator::slotHistoryshow);
0204 
0205     action_constants_show_ = actionCollection()->add<KToggleAction>(QStringLiteral("show_constants"));
0206     action_constants_show_->setText(i18n("Constants &Buttons"));
0207     action_constants_show_->setChecked(true);
0208     connect(action_constants_show_, &KToggleAction::toggled, this, &KCalculator::slotConstantsShow);
0209 
0210     action_bitset_show_ = actionCollection()->add<KToggleAction>(QStringLiteral("show_bitset"));
0211     action_bitset_show_->setText(i18n("Show B&it Edit"));
0212     action_bitset_show_->setChecked(true);
0213     connect(action_bitset_show_, &KToggleAction::toggled, this, &KCalculator::slotBitsetshow);
0214 
0215     KStandardAction::preferences(this, &KCalculator::showSettings, actionCollection());
0216 
0217     KStandardAction::keyBindings(guiFactory(), &KXMLGUIFactory::showConfigureShortcutsDialog, actionCollection());
0218 }
0219 
0220 //------------------------------------------------------------------------------
0221 // Name: createConstantsMenu
0222 // Desc: creates and returns a pointer to the constant menu
0223 //------------------------------------------------------------------------------
0224 KCalcConstMenu *KCalculator::createConstantsMenu()
0225 {
0226     auto const menu = new KCalcConstMenu(i18n("&Constants"), this);
0227     connect(menu, &KCalcConstMenu::triggeredConstant, this, &KCalculator::slotConstantToDisplay);
0228     return menu;
0229 }
0230 
0231 //------------------------------------------------------------------------------
0232 // Name: statusBar
0233 // Desc: returns a pointer to the status bar
0234 //------------------------------------------------------------------------------
0235 KCalcStatusBar *KCalculator::statusBar()
0236 {
0237     return static_cast<KCalcStatusBar *>(KXmlGuiWindow::statusBar());
0238 }
0239 
0240 //------------------------------------------------------------------------------
0241 // Name: setupNumberKeys
0242 // Desc: sets up number keys and related shortcuts
0243 //------------------------------------------------------------------------------
0244 void KCalculator::setupNumberKeys()
0245 {
0246     num_button_group_ = new QButtonGroup(this);
0247     connect(num_button_group_, &QButtonGroup::buttonClicked, this, &KCalculator::slotNumberclicked);
0248 
0249     num_button_group_->addButton(pb0, 0);
0250     num_button_group_->addButton(pb1, 1);
0251     num_button_group_->addButton(pb2, 2);
0252     num_button_group_->addButton(pb3, 3);
0253     num_button_group_->addButton(pb4, 4);
0254     num_button_group_->addButton(pb5, 5);
0255     num_button_group_->addButton(pb6, 6);
0256     num_button_group_->addButton(pb7, 7);
0257     num_button_group_->addButton(pb8, 8);
0258     num_button_group_->addButton(pb9, 9);
0259     num_button_group_->addButton(pbA, 0xA);
0260     num_button_group_->addButton(pbB, 0xB);
0261     num_button_group_->addButton(pbC, 0xC);
0262     num_button_group_->addButton(pbD, 0xD);
0263     num_button_group_->addButton(pbE, 0xE);
0264     num_button_group_->addButton(pbF, 0xF);
0265     connect(this, &KCalculator::switchShowAccels, pb0, &KCalcButton::slotSetAccelDisplayMode);
0266     connect(this, &KCalculator::switchShowAccels, pb1, &KCalcButton::slotSetAccelDisplayMode);
0267     connect(this, &KCalculator::switchShowAccels, pb2, &KCalcButton::slotSetAccelDisplayMode);
0268     connect(this, &KCalculator::switchShowAccels, pb3, &KCalcButton::slotSetAccelDisplayMode);
0269     connect(this, &KCalculator::switchShowAccels, pb4, &KCalcButton::slotSetAccelDisplayMode);
0270     connect(this, &KCalculator::switchShowAccels, pb5, &KCalcButton::slotSetAccelDisplayMode);
0271     connect(this, &KCalculator::switchShowAccels, pb6, &KCalcButton::slotSetAccelDisplayMode);
0272     connect(this, &KCalculator::switchShowAccels, pb7, &KCalcButton::slotSetAccelDisplayMode);
0273     connect(this, &KCalculator::switchShowAccels, pb8, &KCalcButton::slotSetAccelDisplayMode);
0274     connect(this, &KCalculator::switchShowAccels, pb9, &KCalcButton::slotSetAccelDisplayMode);
0275     connect(this, &KCalculator::switchShowAccels, pbA, &KCalcButton::slotSetAccelDisplayMode);
0276     connect(this, &KCalculator::switchShowAccels, pbB, &KCalcButton::slotSetAccelDisplayMode);
0277     connect(this, &KCalculator::switchShowAccels, pbC, &KCalcButton::slotSetAccelDisplayMode);
0278     connect(this, &KCalculator::switchShowAccels, pbD, &KCalcButton::slotSetAccelDisplayMode);
0279     connect(this, &KCalculator::switchShowAccels, pbE, &KCalcButton::slotSetAccelDisplayMode);
0280     connect(this, &KCalculator::switchShowAccels, pbF, &KCalcButton::slotSetAccelDisplayMode);
0281 }
0282 
0283 //------------------------------------------------------------------------------
0284 // Name: setupRightKeypad
0285 // Desc: sets up right keypad keys and related shortcuts
0286 //------------------------------------------------------------------------------
0287 void KCalculator::setupRightKeypad()
0288 {
0289     connect(pbShift, &KCalcButton::toggled, this, &KCalculator::slotShifttoggled);
0290     connect(this, &KCalculator::switchShowAccels, pbShift, &KCalcButton::slotSetAccelDisplayMode);
0291 
0292     pbBackspace->setShortcut(QKeySequence(Qt::Key_Backspace));
0293     new QShortcut(Qt::Key_PageUp, pbBackspace, SLOT(animateClick()));
0294     connect(pbBackspace, &KCalcButton::clicked, this, &KCalculator::slotBackspaceclicked);
0295     connect(this, &KCalculator::switchShowAccels, pbBackspace, &KCalcButton::slotSetAccelDisplayMode);
0296 
0297     pbClear->setShortcut(QKeySequence(Qt::Key_Escape));
0298     new QShortcut(Qt::Key_PageUp, pbClear, SLOT(animateClick()));
0299     connect(pbClear, &KCalcButton::clicked, this, &KCalculator::slotClearclicked);
0300     connect(this, &KCalculator::switchShowAccels, pbClear, &KCalcButton::slotSetAccelDisplayMode);
0301 
0302     pbAllClear->setShortcut(QKeySequence(Qt::Key_Delete));
0303     new QShortcut(Qt::Key_PageDown, pbAllClear, SLOT(animateClick()));
0304     connect(pbAllClear, &KCalcButton::clicked, this, &KCalculator::slotAllClearclicked);
0305     connect(this, &KCalculator::switchShowAccels, pbAllClear, &KCalcButton::slotSetAccelDisplayMode);
0306     // also clear the content of the history when clicked
0307     connect(pbAllClear, &KCalcButton::clicked, calc_history, &KCalcHistory::clearHistory);
0308 
0309     pbParenOpen->setShortcut(QKeySequence(Qt::Key_ParenLeft));
0310     connect(pbParenOpen, &KCalcButton::clicked, this, &KCalculator::slotParenOpenclicked);
0311     connect(this, &KCalculator::switchShowAccels, pbParenOpen, &KCalcButton::slotSetAccelDisplayMode);
0312 
0313     pbParenClose->setShortcut(QKeySequence(Qt::Key_ParenRight));
0314     connect(pbParenClose, &KCalcButton::clicked, this, &KCalculator::slotParenCloseclicked);
0315     connect(this, &KCalculator::switchShowAccels, pbParenClose, &KCalcButton::slotSetAccelDisplayMode);
0316 
0317     pbMemRecall->setDisabled(true); // nothing in memory at start
0318     connect(pbMemRecall, &KCalcButton::clicked, this, &KCalculator::slotMemRecallclicked);
0319     connect(this, &KCalculator::switchShowAccels, pbMemRecall, &KCalcButton::slotSetAccelDisplayMode);
0320 
0321     connect(pbMemClear, &KCalcButton::clicked, this, &KCalculator::slotMemClearclicked);
0322     connect(this, &KCalculator::switchShowAccels, pbMemClear, &KCalcButton::slotSetAccelDisplayMode);
0323 
0324     pbMemPlusMinus->addMode(ModeNormal, i18nc("Add display to memory", "M+"), i18n("Add display to memory"));
0325     pbMemPlusMinus->addMode(ModeShift, i18nc("Subtract from memory", "M\xe2\x88\x92"), i18n("Subtract from memory"));
0326     connect(pbMemPlusMinus, &KCalcButton::clicked, this, &KCalculator::slotMemPlusMinusclicked);
0327     connect(this, &KCalculator::switchShowAccels, pbMemPlusMinus, &KCalcButton::slotSetAccelDisplayMode);
0328     connect(this, &KCalculator::switchMode, pbMemPlusMinus, &KCalcButton::slotSetMode);
0329 
0330     connect(pbMemStore, &KCalcButton::clicked, this, &KCalculator::slotMemStoreclicked);
0331     connect(this, &KCalculator::switchShowAccels, pbMemStore, &KCalcButton::slotSetAccelDisplayMode);
0332 
0333     pbPercent->setShortcut(QKeySequence(Qt::Key_Percent));
0334     connect(pbPercent, &KCalcButton::clicked, this, &KCalculator::slotPercentclicked);
0335     connect(this, &KCalculator::switchShowAccels, pbPercent, &KCalcButton::slotSetAccelDisplayMode);
0336 
0337     pbPlusMinus->setShortcut(QKeySequence(Qt::Key_Backslash));
0338     connect(pbPlusMinus, &KCalcButton::clicked, this, &KCalculator::slotPlusMinusclicked);
0339     connect(this, &KCalculator::switchShowAccels, pbPlusMinus, &KCalcButton::slotSetAccelDisplayMode);
0340 }
0341 
0342 //------------------------------------------------------------------------------
0343 // Name: setupNumericKeypad
0344 // Desc: sets up numeric keys and related shortcuts
0345 //------------------------------------------------------------------------------
0346 void KCalculator::setupNumericKeypad()
0347 {
0348     pbCube->addMode(ModeNormal, i18nc("Third power", "x<sup>3</sup>"), i18n("Third power"));
0349     pbCube->addMode(ModeShift, QStringLiteral("<sup>3</sup>&radic;x"), i18n("Cube root"));
0350     connect(pbCube, &KCalcButton::clicked, this, &KCalculator::slotCubeclicked);
0351     connect(this, &KCalculator::switchShowAccels, pbCube, &KCalcButton::slotSetAccelDisplayMode);
0352     connect(this, &KCalculator::switchMode, pbCube, &KCalcButton::slotSetMode);
0353 
0354     pbDivision->setShortcut(QKeySequence(Qt::Key_Slash));
0355     new QShortcut(Qt::Key_division, pbDivision, SLOT(animateClick()));
0356     connect(pbDivision, &KCalcButton::clicked, this, &KCalculator::slotDivisionclicked);
0357     connect(this, &KCalculator::switchShowAccels, pbDivision, &KCalcButton::slotSetAccelDisplayMode);
0358 
0359     pbMultiplication->setShortcut(QKeySequence(Qt::Key_Asterisk));
0360     new QShortcut(Qt::Key_X, pbMultiplication, SLOT(animateClick()));
0361     new QShortcut(Qt::Key_multiply, pbMultiplication, SLOT(animateClick()));
0362     connect(pbMultiplication, &KCalcButton::clicked, this, &KCalculator::slotMultiplicationclicked);
0363     connect(this, &KCalculator::switchShowAccels, pbMultiplication, &KCalcButton::slotSetAccelDisplayMode);
0364 
0365     pbMinus->setShortcut(QKeySequence(Qt::Key_Minus));
0366     connect(pbMinus, &KCalcButton::clicked, this, &KCalculator::slotMinusclicked);
0367     connect(this, &KCalculator::switchShowAccels, pbMinus, &KCalcButton::slotSetAccelDisplayMode);
0368 
0369     pbPlus->setShortcut(QKeySequence(Qt::Key_Plus));
0370     connect(pbPlus, &KCalcButton::clicked, this, &KCalculator::slotPlusclicked);
0371     connect(this, &KCalculator::switchShowAccels, pbPlus, &KCalcButton::slotSetAccelDisplayMode);
0372 
0373     // set decimal separator from locale
0374     pbPeriod->setText(QString(QLocale().decimalPoint()));
0375     pbPeriod->setShortcut(QString(QLocale().decimalPoint()));
0376 
0377     // add shortcut for the other decimal separator (point or comma)
0378     if (QLocale().decimalPoint() == QLatin1Char('.')) {
0379         new QShortcut(Qt::Key_Comma, pbPeriod, SLOT(animateClick()));
0380     } else if (QLocale().decimalPoint() == QLatin1Char(',')) {
0381         new QShortcut(Qt::Key_Period, pbPeriod, SLOT(animateClick()));
0382     }
0383 
0384     connect(pbPeriod, &KCalcButton::clicked, this, &KCalculator::slotPeriodclicked);
0385     connect(this, &KCalculator::switchShowAccels, pbPeriod, &KCalcButton::slotSetAccelDisplayMode);
0386 
0387     pbEqual->setShortcut(QKeySequence(Qt::Key_Enter));
0388     new QShortcut(Qt::Key_Equal, pbEqual, SLOT(animateClick()));
0389     new QShortcut(Qt::Key_Return, pbEqual, SLOT(animateClick()));
0390     connect(pbEqual, &KCalcButton::clicked, this, &KCalculator::slotEqualclicked);
0391     connect(this, &KCalculator::switchShowAccels, pbEqual, &KCalcButton::slotSetAccelDisplayMode);
0392 }
0393 
0394 //------------------------------------------------------------------------------
0395 // Name: setupLogicKeys
0396 // Desc: sets up logic keys and related shortcuts
0397 //------------------------------------------------------------------------------
0398 void KCalculator::setupLogicKeys()
0399 {
0400     logic_buttons_.append(pbAND);
0401     logic_buttons_.append(pbOR);
0402     logic_buttons_.append(pbXOR);
0403     logic_buttons_.append(pbLsh);
0404     logic_buttons_.append(pbRsh);
0405     logic_buttons_.append(pbCmp);
0406 
0407     pbAND->setShortcut(QKeySequence(Qt::Key_Ampersand));
0408     connect(this, &KCalculator::switchShowAccels, pbAND, &KCalcButton::slotSetAccelDisplayMode);
0409     connect(pbAND, &KCalcButton::clicked, this, &KCalculator::slotANDclicked);
0410 
0411     pbOR->setShortcut(QKeySequence(Qt::Key_Bar));
0412     connect(this, &KCalculator::switchShowAccels, pbOR, &KCalcButton::slotSetAccelDisplayMode);
0413     connect(pbOR, &KCalcButton::clicked, this, &KCalculator::slotORclicked);
0414 
0415     connect(this, &KCalculator::switchShowAccels, pbXOR, &KCalcButton::slotSetAccelDisplayMode);
0416     connect(pbXOR, &KCalcButton::clicked, this, &KCalculator::slotXORclicked);
0417 
0418     pbLsh->setShortcut(QKeySequence(Qt::Key_Less));
0419     connect(this, &KCalculator::switchShowAccels, pbLsh, &KCalcButton::slotSetAccelDisplayMode);
0420     connect(pbLsh, &KCalcButton::clicked, this, &KCalculator::slotLeftShiftclicked);
0421 
0422     pbRsh->setShortcut(QKeySequence(Qt::Key_Greater));
0423     connect(this, &KCalculator::switchShowAccels, pbRsh, &KCalcButton::slotSetAccelDisplayMode);
0424     connect(pbRsh, &KCalcButton::clicked, this, &KCalculator::slotRightShiftclicked);
0425 
0426     pbCmp->setShortcut(QKeySequence(Qt::Key_AsciiTilde));
0427     connect(this, &KCalculator::switchShowAccels, pbCmp, &KCalcButton::slotSetAccelDisplayMode);
0428     connect(pbCmp, &KCalcButton::clicked, this, &KCalculator::slotNegateclicked);
0429 }
0430 
0431 //------------------------------------------------------------------------------
0432 // Name: setupLogicKeys
0433 // Desc: sets up scientific keys and related shortcuts
0434 //------------------------------------------------------------------------------
0435 void KCalculator::setupScientificKeys()
0436 {
0437     scientific_buttons_.append(pbHyp);
0438     scientific_buttons_.append(pbSin);
0439     scientific_buttons_.append(pbCos);
0440     scientific_buttons_.append(pbTan);
0441     scientific_buttons_.append(pbLog);
0442     scientific_buttons_.append(pbLn);
0443 
0444     connect(this, &KCalculator::switchShowAccels, pbHyp, &KCalcButton::slotSetAccelDisplayMode);
0445     connect(pbHyp, &KCalcButton::toggled, this, &KCalculator::slotHyptoggled);
0446 
0447     pbSin->addMode(ModeNormal, i18nc("Sine", "sin"), i18n("Sine"));
0448     pbSin->addMode(ModeShift, i18nc("Arc sine", "asin"), i18n("Arc sine"));
0449     pbSin->addMode(ModeHyperbolic, i18nc("Hyperbolic sine", "sinh"), i18n("Hyperbolic sine"));
0450     pbSin->addMode(ButtonModeFlags(ModeShift | ModeHyperbolic), i18nc("Inverse hyperbolic sine", "asinh"), i18n("Inverse hyperbolic sine"));
0451     connect(this, &KCalculator::switchShowAccels, pbSin, &KCalcButton::slotSetAccelDisplayMode);
0452     connect(this, &KCalculator::switchMode, pbSin, &KCalcButton::slotSetMode);
0453     connect(pbSin, &KCalcButton::clicked, this, &KCalculator::slotSinclicked);
0454 
0455     pbCos->addMode(ModeNormal, i18nc("Cosine", "cos"), i18n("Cosine"));
0456     pbCos->addMode(ModeShift, i18nc("Arc cosine", "acos"), i18n("Arc cosine"));
0457     pbCos->addMode(ModeHyperbolic, i18nc("Hyperbolic cosine", "cosh"), i18n("Hyperbolic cosine"));
0458     pbCos->addMode(ButtonModeFlags(ModeShift | ModeHyperbolic), i18nc("Inverse hyperbolic cosine", "acosh"), i18n("Inverse hyperbolic cosine"));
0459     connect(this, &KCalculator::switchShowAccels, pbCos, &KCalcButton::slotSetAccelDisplayMode);
0460     connect(this, &KCalculator::switchMode, pbCos, &KCalcButton::slotSetMode);
0461     connect(pbCos, &KCalcButton::clicked, this, &KCalculator::slotCosclicked);
0462 
0463     pbTan->addMode(ModeNormal, i18nc("Tangent", "tan"), i18n("Tangent"));
0464     pbTan->addMode(ModeShift, i18nc("Arc tangent", "atan"), i18n("Arc tangent"));
0465     pbTan->addMode(ModeHyperbolic, i18nc("Hyperbolic tangent", "tanh"), i18n("Hyperbolic tangent"));
0466     pbTan->addMode(ButtonModeFlags(ModeShift | ModeHyperbolic), i18nc("Inverse hyperbolic tangent", "atanh"), i18n("Inverse hyperbolic tangent"));
0467     connect(this, &KCalculator::switchShowAccels, pbTan, &KCalcButton::slotSetAccelDisplayMode);
0468     connect(this, &KCalculator::switchMode, pbTan, &KCalcButton::slotSetMode);
0469     connect(pbTan, &KCalcButton::clicked, this, &KCalculator::slotTanclicked);
0470 
0471     pbLog->addMode(ModeNormal, i18nc("Logarithm to base 10", "log"), i18n("Logarithm to base 10"));
0472     pbLog->addMode(ModeShift, i18nc("10 to the power of x", "10<sup>x</sup>"), i18n("10 to the power of x"));
0473     connect(this, &KCalculator::switchShowAccels, pbLog, &KCalcButton::slotSetAccelDisplayMode);
0474     connect(this, &KCalculator::switchMode, pbLog, &KCalcButton::slotSetMode);
0475     connect(pbLog, &KCalcButton::clicked, this, &KCalculator::slotLogclicked);
0476     pbLn->addMode(ModeNormal, i18nc("Natural log", "ln"), i18n("Natural log"));
0477     pbLn->addMode(ModeShift, i18nc("Exponential function", "e<sup>x</sup>"), i18n("Exponential function"));
0478     connect(this, &KCalculator::switchShowAccels, pbLn, &KCalcButton::slotSetAccelDisplayMode);
0479     connect(this, &KCalculator::switchMode, pbLn, &KCalcButton::slotSetMode);
0480     connect(pbLn, &KCalcButton::clicked, this, &KCalculator::slotLnclicked);
0481 }
0482 
0483 //------------------------------------------------------------------------------
0484 // Name: setupStatisticKeys
0485 // Desc: sets up statistical keys and related shortcuts
0486 //------------------------------------------------------------------------------
0487 void KCalculator::setupStatisticKeys()
0488 {
0489     stat_buttons_.append(pbNData);
0490     stat_buttons_.append(pbMean);
0491     stat_buttons_.append(pbSd);
0492     stat_buttons_.append(pbMed);
0493     stat_buttons_.append(pbDat);
0494     stat_buttons_.append(pbCSt);
0495 
0496     pbNData->addMode(ModeNormal, i18nc("Number of data entered", "N"), i18n("Number of data entered"));
0497     pbNData->addMode(ModeShift, QString::fromUtf8("\xce\xa3") + QLatin1Char('x'), i18n("Sum of all data items"));
0498     connect(this, &KCalculator::switchShowAccels, pbNData, &KCalcButton::slotSetAccelDisplayMode);
0499     connect(this, &KCalculator::switchMode, pbNData, &KCalcButton::slotSetMode);
0500     connect(pbNData, &KCalcButton::clicked, this, &KCalculator::slotStatNumclicked);
0501 
0502     pbMean->addMode(ModeNormal, i18nc("Mean", "Mea"), i18n("Mean"));
0503     pbMean->addMode(ModeShift, QString::fromUtf8("\xce\xa3") + QLatin1String("x<sup>2</sup>"), i18n("Sum of all data items squared"));
0504     connect(this, &KCalculator::switchShowAccels, pbMean, &KCalcButton::slotSetAccelDisplayMode);
0505     connect(this, &KCalculator::switchMode, pbMean, &KCalcButton::slotSetMode);
0506     connect(pbMean, &KCalcButton::clicked, this, &KCalculator::slotStatMeanclicked);
0507 
0508     pbSd->addMode(ModeNormal, QString::fromUtf8("\xcf\x83") + QLatin1String("<sub>N</sub>"), i18n("Standard deviation"));
0509     pbSd->addMode(ModeShift, QString::fromUtf8("\xcf\x83") + QLatin1String("<sub>N-1</sub>"), i18n("Sample standard deviation"));
0510     connect(this, &KCalculator::switchShowAccels, pbSd, &KCalcButton::slotSetAccelDisplayMode);
0511     connect(this, &KCalculator::switchMode, pbSd, &KCalcButton::slotSetMode);
0512     connect(pbSd, &KCalcButton::clicked, this, &KCalculator::slotStatStdDevclicked);
0513 
0514     connect(this, &KCalculator::switchShowAccels, pbMed, &KCalcButton::slotSetAccelDisplayMode);
0515     connect(pbMed, &KCalcButton::clicked, this, &KCalculator::slotStatMedianclicked);
0516 
0517     pbDat->addMode(ModeNormal, i18nc("Enter data", "Dat"), i18n("Enter data"));
0518     pbDat->addMode(ModeShift, i18nc("Delete last data item", "CDat"), i18n("Delete last data item"));
0519     connect(this, &KCalculator::switchShowAccels, pbDat, &KCalcButton::slotSetAccelDisplayMode);
0520     connect(this, &KCalculator::switchMode, pbDat, &KCalcButton::slotSetMode);
0521     connect(pbDat, &KCalcButton::clicked, this, &KCalculator::slotStatDataInputclicked);
0522 
0523     connect(this, &KCalculator::switchShowAccels, pbCSt, &KCalcButton::slotSetAccelDisplayMode);
0524     connect(pbCSt, &KCalcButton::clicked, this, &KCalculator::slotStatClearDataclicked);
0525 }
0526 
0527 //------------------------------------------------------------------------------
0528 // Name: setupConstantsKeys
0529 // Desc: sets up constants keys and related shortcuts
0530 //------------------------------------------------------------------------------
0531 void KCalculator::setupConstantsKeys()
0532 {
0533     const_buttons_.append(pbC1);
0534     const_buttons_.append(pbC2);
0535     const_buttons_.append(pbC3);
0536     const_buttons_.append(pbC4);
0537     const_buttons_.append(pbC5);
0538     const_buttons_.append(pbC6);
0539 
0540     pbC1->setButtonNumber(0);
0541     connect(this, &KCalculator::switchShowAccels, pbC1, &KCalcConstButton::slotSetAccelDisplayMode);
0542     connect(this, &KCalculator::switchMode, pbC1, &KCalcConstButton::slotSetMode);
0543     connect(pbC1, &KCalcConstButton::constButtonClicked, this, &KCalculator::slotConstclicked);
0544 
0545     pbC2->setButtonNumber(1);
0546     connect(this, &KCalculator::switchShowAccels, pbC2, &KCalcConstButton::slotSetAccelDisplayMode);
0547     connect(this, &KCalculator::switchMode, pbC2, &KCalcConstButton::slotSetMode);
0548     connect(pbC2, &KCalcConstButton::constButtonClicked, this, &KCalculator::slotConstclicked);
0549 
0550     pbC3->setButtonNumber(2);
0551     connect(this, &KCalculator::switchShowAccels, pbC3, &KCalcConstButton::slotSetAccelDisplayMode);
0552     connect(this, &KCalculator::switchMode, pbC3, &KCalcConstButton::slotSetMode);
0553     connect(pbC3, &KCalcConstButton::constButtonClicked, this, &KCalculator::slotConstclicked);
0554 
0555     pbC4->setButtonNumber(3);
0556     connect(this, &KCalculator::switchShowAccels, pbC4, &KCalcConstButton::slotSetAccelDisplayMode);
0557     connect(this, &KCalculator::switchMode, pbC4, &KCalcConstButton::slotSetMode);
0558     connect(pbC4, &KCalcConstButton::constButtonClicked, this, &KCalculator::slotConstclicked);
0559 
0560     pbC5->setButtonNumber(4);
0561     connect(this, &KCalculator::switchShowAccels, pbC5, &KCalcConstButton::slotSetAccelDisplayMode);
0562     connect(this, &KCalculator::switchMode, pbC5, &KCalcConstButton::slotSetMode);
0563     connect(pbC5, &KCalcConstButton::constButtonClicked, this, &KCalculator::slotConstclicked);
0564 
0565     pbC6->setButtonNumber(5);
0566     connect(this, &KCalculator::switchShowAccels, pbC6, &KCalcConstButton::slotSetAccelDisplayMode);
0567     connect(this, &KCalculator::switchMode, pbC6, &KCalcConstButton::slotSetMode);
0568     connect(pbC6, &KCalcConstButton::constButtonClicked, this, &KCalculator::slotConstclicked);
0569 
0570     changeButtonNames();
0571 }
0572 
0573 //------------------------------------------------------------------------------
0574 // Name: setupMiscKeys
0575 // Desc: sets up misc keys and related shortcuts
0576 //------------------------------------------------------------------------------
0577 void KCalculator::setupMiscKeys()
0578 {
0579     pbMod->addMode(ModeNormal, i18nc("Modulo", "mod"), i18n("Modulo"));
0580     pbMod->addMode(ModeShift, i18nc("Integer division", "IntDiv"), i18n("Integer division"));
0581     connect(this, &KCalculator::switchMode, pbMod, &KCalcButton::slotSetMode);
0582     connect(this, &KCalculator::switchShowAccels, pbMod, &KCalcButton::slotSetAccelDisplayMode);
0583     pbMod->setShortcut(QKeySequence(Qt::Key_Colon));
0584     connect(pbMod, &KCalcButton::clicked, this, &KCalculator::slotModclicked);
0585 
0586     pbReci->addMode(ModeNormal, i18nc("Reciprocal", "1/x"), i18n("Reciprocal"));
0587     pbReci->addMode(ModeShift, i18nc("n Choose m", "nCm"), i18n("n Choose m"));
0588     connect(this, &KCalculator::switchMode, pbReci, &KCalcButton::slotSetMode);
0589     connect(this, &KCalculator::switchShowAccels, pbReci, &KCalcButton::slotSetAccelDisplayMode);
0590     connect(pbReci, &KCalcButton::clicked, this, &KCalculator::slotReciclicked);
0591 
0592     pbFactorial->addMode(ModeNormal, i18nc("Factorial", "x!"), i18n("Factorial"));
0593     pbFactorial->addMode(ModeShift, QStringLiteral("&#915;"), i18n("Gamma"));
0594     pbFactorial->setShortcut(QKeySequence(Qt::Key_Exclam));
0595     connect(this, &KCalculator::switchShowAccels, pbFactorial, &KCalcButton::slotSetAccelDisplayMode);
0596     connect(this, &KCalculator::switchMode, pbFactorial, &KCalcButton::slotSetMode);
0597     connect(pbFactorial, &KCalcButton::clicked, this, &KCalculator::slotFactorialclicked);
0598 
0599     pbSquare->addMode(ModeNormal, i18nc("Square", "x<sup>2</sup>"), i18n("Square"));
0600     pbSquare->addMode(ModeShift, QStringLiteral("&radic;x"), i18n("Square root"));
0601     pbSquare->setShortcut(QKeySequence(Qt::Key_BracketLeft));
0602     new QShortcut(Qt::Key_twosuperior, pbSquare, SLOT(animateClick()));
0603     connect(this, &KCalculator::switchShowAccels, pbSquare, &KCalcButton::slotSetAccelDisplayMode);
0604     connect(this, &KCalculator::switchMode, pbSquare, &KCalcButton::slotSetMode);
0605     connect(pbSquare, &KCalcButton::clicked, this, &KCalculator::slotSquareclicked);
0606 
0607     pbPower->addMode(ModeNormal, i18nc("x to the power of y", "x<sup>y</sup>"), i18n("x to the power of y"));
0608     pbPower->addMode(ModeShift, i18nc("x to the power of 1/y", "x<sup>1/y</sup>"), i18n("x to the power of 1/y"));
0609     connect(this, &KCalculator::switchShowAccels, pbPower, &KCalcButton::slotSetAccelDisplayMode);
0610     connect(this, &KCalculator::switchMode, pbPower, &KCalcButton::slotSetMode);
0611     pbPower->setShortcut(QKeySequence(Qt::Key_AsciiCircum));
0612     connect(pbPower, &KCalcButton::clicked, this, &KCalculator::slotPowerclicked);
0613 
0614     pbEE->addMode(ModeNormal,
0615                   QStringLiteral("x<small>"
0616                                  "\xb7"
0617                                  "10</small><sup>y</sup>"),
0618                   i18n("Exponent"));
0619     connect(this, &KCalculator::switchShowAccels, pbEE, &KCalcButton::slotSetAccelDisplayMode);
0620     connect(pbEE, &KCalcButton::clicked, this, &KCalculator::slotEEclicked);
0621 }
0622 
0623 //------------------------------------------------------------------------------
0624 // Name: createConstantsMenu
0625 // Desc: additional setup for button keys
0626 // NOTE: all alphanumeric shorts set in ui file
0627 //------------------------------------------------------------------------------
0628 void KCalculator::setupKeys()
0629 {
0630     setupNumberKeys();
0631     setupRightKeypad();
0632     setupNumericKeypad();
0633     setupLogicKeys();
0634     setupScientificKeys();
0635     setupStatisticKeys();
0636     setupConstantsKeys();
0637     setupMiscKeys();
0638 
0639     // other button lists
0640 
0641     function_button_list_.append(pbHyp);
0642     function_button_list_.append(pbShift);
0643     function_button_list_.append(pbEE);
0644     function_button_list_.append(pbSin);
0645     function_button_list_.append(pbPlusMinus);
0646     function_button_list_.append(pbCos);
0647     function_button_list_.append(pbReci);
0648     function_button_list_.append(pbTan);
0649     function_button_list_.append(pbFactorial);
0650     function_button_list_.append(pbLog);
0651     function_button_list_.append(pbSquare);
0652     function_button_list_.append(pbLn);
0653     function_button_list_.append(pbPower);
0654     function_button_list_.append(pbCube);
0655 
0656     mem_button_list_.append(pbMemRecall);
0657     mem_button_list_.append(pbMemPlusMinus);
0658     mem_button_list_.append(pbMemStore);
0659     mem_button_list_.append(pbMemClear);
0660     mem_button_list_.append(pbClear);
0661     mem_button_list_.append(pbAllClear);
0662     mem_button_list_.append(pbBackspace);
0663 
0664     operation_button_list_.append(pbMultiplication);
0665     operation_button_list_.append(pbParenOpen);
0666     operation_button_list_.append(pbParenClose);
0667     operation_button_list_.append(pbAND);
0668     operation_button_list_.append(pbDivision);
0669     operation_button_list_.append(pbOR);
0670     operation_button_list_.append(pbXOR);
0671     operation_button_list_.append(pbPlus);
0672     operation_button_list_.append(pbMinus);
0673     operation_button_list_.append(pbLsh);
0674     operation_button_list_.append(pbRsh);
0675     operation_button_list_.append(pbPeriod);
0676     operation_button_list_.append(pbEqual);
0677     operation_button_list_.append(pbPercent);
0678     operation_button_list_.append(pbCmp);
0679     operation_button_list_.append(pbMod);
0680 }
0681 
0682 //------------------------------------------------------------------------------
0683 // Name: updateGeometry
0684 // Desc: makes all the buttons have reasonable sizes
0685 //------------------------------------------------------------------------------
0686 void KCalculator::updateGeometry()
0687 {
0688     // Create font metrics using base font (at base size)
0689     const QFontMetrics fm(baseFont());
0690     
0691     // Calculate some useful values
0692     const QSize em = fm.size(0, QStringLiteral("M"));
0693     int margin = QApplication::style()->pixelMetric(QStyle::PM_ButtonMargin, nullptr, nullptr);
0694     margin = qMax(qMin(margin / 2, 3), 3);
0695 
0696     // left pad
0697     const auto leftPadList = leftPad->children();
0698     for (QObject *obj : leftPadList) {
0699         if (auto const button = qobject_cast<KCalcButton *>(obj)) {
0700             button->setMinimumWidth(em.width() * 4 + margin * 2);
0701             button->setMinimumHeight(em.height() * 1.25 + margin * 2);
0702             button->installEventFilter(this);
0703         }
0704     }
0705 
0706     // right pad
0707     const auto rightPadList = rightPad->children();
0708     for (QObject *obj : rightPadList) {
0709         if (auto const button = qobject_cast<KCalcButton *>(obj)) {
0710             button->setMinimumWidth(em.width() * 3 + margin * 2);
0711             button->setMinimumHeight(em.height() * 1.25 + margin * 2);
0712             button->installEventFilter(this);
0713         }
0714     }
0715 
0716     // numeric pad
0717     const auto numericPadList = numericPad->children();
0718     for (QObject *obj : numericPadList) {
0719         if (auto const button = qobject_cast<KCalcButton *>(obj)) {
0720             button->setMinimumWidth(em.width() * 3 + margin * 2);
0721             button->setMinimumHeight(em.height() * 1.25 + margin * 2);
0722             button->installEventFilter(this);
0723         }
0724     }
0725 }
0726 
0727 //------------------------------------------------------------------------------
0728 // Name: slotConstantToDisplay
0729 // Desc: inserts a constant
0730 //------------------------------------------------------------------------------
0731 void KCalculator::slotConstantToDisplay(const science_constant &const_chosen)
0732 {
0733     QString val = const_chosen.label;
0734     this->insertToInputDisplay(val);
0735 }
0736 
0737 //------------------------------------------------------------------------------
0738 // Name: slotBaseSelected
0739 // Desc: changes the selected numeric base
0740 //------------------------------------------------------------------------------
0741 void KCalculator::slotBaseSelected(QAbstractButton *button)
0742 {
0743     if (button) {
0744         const int base = base_choose_group_->id(button);
0745         int current_base;
0746 
0747         // set display & statusbar (if item exist in statusbar)
0748         statusBar()->setBase(base);
0749         switch (base) {
0750         case BinMode:
0751             current_base = calc_display->setBase(NumBase(2));
0752             base_label->setText(QStringLiteral("Bin"));
0753             base_mode_ = 2;
0754             break;
0755         case OctMode:
0756             current_base = calc_display->setBase(NumBase(8));
0757             base_label->setText(QStringLiteral("Oct"));
0758             base_mode_ = 8;
0759             break;
0760         case DecMode:
0761             current_base = calc_display->setBase(NumBase(10));
0762             base_label->setText(QStringLiteral("Dec"));
0763             base_mode_ = 10;
0764             break;
0765         case HexMode:
0766             current_base = calc_display->setBase(NumBase(16));
0767             base_label->setText(QStringLiteral("Hex"));
0768             base_mode_ = 16;
0769             break;
0770         default:
0771             base_label->setText(QStringLiteral("Error"));
0772             return;
0773         }
0774 
0775         // Enable the buttons available in this base
0776         for (int i = 0; i < current_base; ++i) {
0777             (num_button_group_->buttons().at(i))->setEnabled(true);
0778         }
0779 
0780         // Disable the buttons not available in this base
0781         for (int i = current_base; i < 16; ++i) {
0782             (num_button_group_->buttons().at(i))->setEnabled(false);
0783         }
0784 
0785         // Only enable the decimal point in decimal
0786         pbPeriod->setEnabled(current_base == NB_DECIMAL);
0787 
0788         // Only enable the x*10^y button in decimal
0789         pbEE->setEnabled(current_base == NB_DECIMAL);
0790 
0791         // Disable buttons that make only sense with floating point numbers
0792         if (current_base != NB_DECIMAL) {
0793             for (QAbstractButton *btn : std::as_const(scientific_buttons_)) {
0794                 btn->setEnabled(false);
0795             }
0796         } else {
0797             for (QAbstractButton *btn : std::as_const(scientific_buttons_)) {
0798                 btn->setEnabled(true);
0799             }
0800         }
0801 
0802         KCalcSettings::setBaseMode(base);
0803     }
0804 }
0805 
0806 //------------------------------------------------------------------------------
0807 // Name: keyPressEvent
0808 // Desc: handles keypress events
0809 //------------------------------------------------------------------------------
0810 void KCalculator::keyPressEvent(QKeyEvent *e)
0811 {
0812     // Fix for bug #314586
0813     // Basically, on some keyboards such as French, even though the decimal separator
0814     // is "," the numeric keypad has a "." key. So we fake it so people can more seamlessly
0815     // enter numbers using the keypad
0816     if (KNumber::decimalSeparator() != QLatin1String(".")) {
0817         if (e->key() == Qt::Key_Period && e->modifiers() & Qt::KeypadModifier) {
0818             pbPeriod->animateClick();
0819         }
0820     }
0821 
0822     if (((e->modifiers() & Qt::NoModifier) == 0) || (e->modifiers() & Qt::ShiftModifier)) {
0823         switch (e->key()) {
0824         case Qt::Key_Backspace:
0825             calc_display->deleteLastDigit();
0826             break;
0827         }
0828     }
0829 
0830     if (e->key() == Qt::Key_Control) {
0831         Q_EMIT switchShowAccels(true);
0832     }
0833 
0834     // Workaround for bug #283521
0835     // Unfortunately adding multiple shortcuts (A, Shift+A) to pushbuttons
0836     // does not work properly, so we handle the A-F keypresses with shift in Hex mode here
0837     if (hexRadio->isChecked() && e->modifiers() & Qt::ShiftModifier) {
0838         switch (e->key()) {
0839         case Qt::Key_A:
0840             pbA->animateClick();
0841             break;
0842         case Qt::Key_B:
0843             pbB->animateClick();
0844             break;
0845         case Qt::Key_C:
0846             pbC->animateClick();
0847             break;
0848         case Qt::Key_D:
0849             pbD->animateClick();
0850             break;
0851         case Qt::Key_E:
0852             pbE->animateClick();
0853             break;
0854         case Qt::Key_F:
0855             pbF->animateClick();
0856             break;
0857         default:
0858             break;
0859         }
0860     }
0861 }
0862 
0863 //------------------------------------------------------------------------------
0864 // Name: keyReleaseEvent
0865 // Desc: handles keyrelease events
0866 //------------------------------------------------------------------------------
0867 void KCalculator::keyReleaseEvent(QKeyEvent *e)
0868 {
0869     if (e->key() == Qt::Key_Control) {
0870         Q_EMIT switchShowAccels(false);
0871     }
0872 }
0873 
0874 //------------------------------------------------------------------------------
0875 // Name: slotAngleSelected
0876 // Desc: changes the selected angle system
0877 //------------------------------------------------------------------------------
0878 void KCalculator::slotAngleSelected(QAbstractButton *button, bool checked)
0879 {
0880     if (checked) {
0881         const int mode = angle_choose_group_->id(button);
0882         angle_mode_ = mode;
0883         parser.setTrigonometricMode(angle_mode_);
0884 
0885         statusBar()->setAngleMode(KCalcStatusBar::AngleMode(mode));
0886         switch (mode) {
0887         case DegMode:
0888             angle_units_label->setText(QStringLiteral("Deg"));
0889             break;
0890         case RadMode:
0891             angle_units_label->setText(QStringLiteral("Rad"));
0892             break;
0893         case GradMode:
0894             angle_units_label->setText(QStringLiteral("Gra"));
0895             break;
0896         default: // we shouldn't ever end up here
0897             angle_mode_ = RadMode;
0898         }
0899 
0900         KCalcSettings::setAngleMode(angle_mode_);
0901     }
0902 }
0903 
0904 //------------------------------------------------------------------------------
0905 // Name: slotEEclicked
0906 // Desc: starts the entering of numbers using scientific notation
0907 //------------------------------------------------------------------------------
0908 void KCalculator::slotEEclicked()
0909 {
0910     this->insertToInputDisplay(KCalcToken::TokenCode::EXP_10);
0911 }
0912 
0913 //------------------------------------------------------------------------------
0914 // Name: slotShifttoggled
0915 // Desc: updates the shift state for alternate button functionality
0916 //------------------------------------------------------------------------------
0917 void KCalculator::slotShifttoggled(bool flag)
0918 {
0919     shift_mode_ = flag;
0920 
0921     Q_EMIT switchMode(ModeShift, flag);
0922 
0923     statusBar()->setShiftIndicator(shift_mode_);
0924     if (shift_mode_) {
0925         shift_label->setText(i18nc("Second function mode", "Shift"));
0926     } else {
0927         shift_label->setText(QStringLiteral(""));
0928     }
0929 }
0930 
0931 //------------------------------------------------------------------------------
0932 // Name: slotHyptoggled
0933 // Desc: updates the Hyp state for alternate trig button functionality
0934 //------------------------------------------------------------------------------
0935 void KCalculator::slotHyptoggled(bool flag)
0936 {
0937     // toggle between hyperbolic and standard trig functions
0938     hyp_mode_ = flag;
0939 
0940     Q_EMIT switchMode(ModeHyperbolic, flag);
0941 }
0942 
0943 //------------------------------------------------------------------------------
0944 // Name: slotMemRecallclicked
0945 // Desc: recalls a value from memory
0946 //------------------------------------------------------------------------------
0947 void KCalculator::slotMemRecallclicked()
0948 {
0949     input_display->insertToken(memory_num_.toQString(KCalcSettings::precision()));
0950 }
0951 
0952 //------------------------------------------------------------------------------
0953 // Name: slotMemStoreclicked
0954 // Desc: stores a value into memory
0955 //------------------------------------------------------------------------------
0956 void KCalculator::slotMemStoreclicked()
0957 {
0958     this->commit_Input_();
0959 
0960     if (parsing_failure_) {
0961         handle_Parsing_Error_();
0962     } else if (calculation_failure_) {
0963         handle_Calculation_Error_();
0964     } else {
0965         updateDisplay(UPDATE_FROM_CORE);
0966         pbMemRecall->setEnabled(true);
0967         statusBar()->setMemoryIndicator(true);
0968         memory_label->setText(QStringLiteral("M"));
0969 
0970         calc_history->addToHistory(QStringLiteral("M ="), false);
0971         memory_num_ = calc_display->getAmount();
0972 
0973         calc_history->addResultToHistory(calc_display->getAmount().toQString(KCalcSettings::precision()));
0974     }
0975 }
0976 
0977 //------------------------------------------------------------------------------
0978 // Name: slotNumberclicked
0979 // Desc: user has entered a digit
0980 //------------------------------------------------------------------------------
0981 void KCalculator::slotNumberclicked(QAbstractButton *button)
0982 {
0983     if (button) {
0984         const int number_clicked = num_button_group_->id(button);
0985         QString s = QString::number(number_clicked, base_mode_).toUpper();
0986         this->insertToInputDisplay(s);
0987     }
0988 }
0989 
0990 //------------------------------------------------------------------------------
0991 // Name: slotSinclicked
0992 // Desc: executes the sine function
0993 //------------------------------------------------------------------------------
0994 void KCalculator::slotSinclicked()
0995 {
0996     if (hyp_mode_) {
0997         // sinh or arcsinh
0998         if (!shift_mode_) {
0999             insertToInputDisplay(KCalcToken::TokenCode::SINH);
1000             insertToInputDisplay(KCalcToken::TokenCode::OPENING_PARENTHESIS);
1001         } else {
1002             insertToInputDisplay(KCalcToken::TokenCode::ASINH);
1003             insertToInputDisplay(KCalcToken::TokenCode::OPENING_PARENTHESIS);
1004         }
1005     } else {
1006         // sin or arcsin
1007         if (!shift_mode_) {
1008             insertToInputDisplay(KCalcToken::TokenCode::SIN);
1009             insertToInputDisplay(KCalcToken::TokenCode::OPENING_PARENTHESIS);
1010         } else {
1011             insertToInputDisplay(KCalcToken::TokenCode::ASIN);
1012             insertToInputDisplay(KCalcToken::TokenCode::OPENING_PARENTHESIS);
1013         }
1014     }
1015 }
1016 
1017 //------------------------------------------------------------------------------
1018 // Name: slotPlusMinusclicked
1019 // Desc: changes sign of number being displayed
1020 //------------------------------------------------------------------------------
1021 void KCalculator::slotPlusMinusclicked()
1022 {
1023     this->input_display->slotClearOverwrite();
1024     this->input_display->home(false);
1025     this->insertToInputDisplay(KCalcToken::TokenCode::INVERT_SIGN);
1026     this->insertToInputDisplay(KCalcToken::TokenCode::OPENING_PARENTHESIS);
1027     this->input_display->end(false);
1028     this->insertToInputDisplay(KCalcToken::TokenCode::CLOSING_PARENTHESIS);
1029     this->slotEqualclicked();
1030 }
1031 
1032 //------------------------------------------------------------------------------
1033 // Name: slotMemPlusMinusclicked
1034 // Desc: handles arithmetic on values stored in memory
1035 //------------------------------------------------------------------------------
1036 void KCalculator::slotMemPlusMinusclicked()
1037 {
1038     bool tmp_shift_mode = shift_mode_; // store this, because next command deletes shift_mode_
1039 
1040     pbShift->setChecked(false);
1041 
1042     this->commit_Input_();
1043     //
1044     if (parsing_failure_) {
1045         handle_Parsing_Error_();
1046     } else if (calculation_failure_) {
1047         handle_Calculation_Error_();
1048     } else {
1049         updateDisplay(UPDATE_FROM_CORE);
1050         pbMemRecall->setEnabled(true);
1051         statusBar()->setMemoryIndicator(true);
1052         memory_label->setText(QStringLiteral("M"));
1053         if (!tmp_shift_mode) {
1054             calc_history->addToHistory(QStringLiteral("M+="), false);
1055             memory_num_ += calc_display->getAmount();
1056         } else {
1057             calc_history->addToHistory(QStringLiteral("M-="), false);
1058             memory_num_ -= calc_display->getAmount();
1059         }
1060         calc_history->addResultToHistory(calc_display->getAmount().toQString(KCalcSettings::precision()));
1061     }
1062 }
1063 
1064 //------------------------------------------------------------------------------
1065 // Name: slotSinclicked
1066 // Desc: executes the cosine function
1067 //------------------------------------------------------------------------------
1068 void KCalculator::slotCosclicked()
1069 {
1070     if (hyp_mode_) {
1071         // cosh or arcosh
1072         if (!shift_mode_) {
1073             this->insertToInputDisplay(KCalcToken::TokenCode::COSH);
1074             this->insertToInputDisplay(KCalcToken::TokenCode::OPENING_PARENTHESIS);
1075         } else {
1076             this->insertToInputDisplay(KCalcToken::TokenCode::ACOSH);
1077             this->insertToInputDisplay(KCalcToken::TokenCode::OPENING_PARENTHESIS);
1078         }
1079     } else {
1080         // cosine or arccosine
1081         if (!shift_mode_) {
1082             this->insertToInputDisplay(KCalcToken::TokenCode::COS);
1083             this->insertToInputDisplay(KCalcToken::TokenCode::OPENING_PARENTHESIS);
1084         } else {
1085             this->insertToInputDisplay(KCalcToken::TokenCode::ACOS);
1086             this->insertToInputDisplay(KCalcToken::TokenCode::OPENING_PARENTHESIS);
1087         }
1088     }
1089 }
1090 
1091 //------------------------------------------------------------------------------
1092 // Name: slotSinclicked
1093 // Desc: executes the reciprocal function
1094 //------------------------------------------------------------------------------
1095 void KCalculator::slotReciclicked()
1096 {
1097     if (shift_mode_) {
1098         this->insertToInputDisplay(KCalcToken::TokenCode::BINOMIAL);
1099     } else {
1100         this->insertToInputDisplay(KCalcToken::TokenCode::RECIPROCAL);
1101     }
1102 }
1103 
1104 //------------------------------------------------------------------------------
1105 // Name: slotSinclicked
1106 // Desc: executes the tangent function
1107 //------------------------------------------------------------------------------
1108 void KCalculator::slotTanclicked()
1109 {
1110     if (hyp_mode_) {
1111         // tanh or artanh
1112         if (!shift_mode_) {
1113             insertToInputDisplay(KCalcToken::TokenCode::TANH);
1114             insertToInputDisplay(KCalcToken::TokenCode::OPENING_PARENTHESIS);
1115         } else {
1116             insertToInputDisplay(KCalcToken::TokenCode::ATANH);
1117             insertToInputDisplay(KCalcToken::TokenCode::OPENING_PARENTHESIS);
1118         }
1119     } else {
1120         // tan or arctan
1121         if (!shift_mode_) {
1122             insertToInputDisplay(KCalcToken::TokenCode::TAN);
1123             insertToInputDisplay(KCalcToken::TokenCode::OPENING_PARENTHESIS);
1124 
1125         } else {
1126             insertToInputDisplay(KCalcToken::TokenCode::ATAN);
1127             insertToInputDisplay(KCalcToken::TokenCode::OPENING_PARENTHESIS);
1128         }
1129     }
1130 }
1131 
1132 //------------------------------------------------------------------------------
1133 // Name: slotFactorialclicked
1134 // Desc: executes the factorial function
1135 //------------------------------------------------------------------------------
1136 void KCalculator::slotFactorialclicked()
1137 {
1138     // Set WaitCursor, as this operation may take a long
1139     // time and the UI freezes with large numbers. User needs some
1140     // visual feedback.
1141     QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
1142     if (!shift_mode_) {
1143         this->insertToInputDisplay(KCalcToken::TokenCode::FACTORIAL);
1144     } else {
1145         this->insertToInputDisplay(KCalcToken::TokenCode::GAMMA);
1146         this->insertToInputDisplay(KCalcToken::TokenCode::OPENING_PARENTHESIS);
1147     }
1148     QApplication::restoreOverrideCursor();
1149 }
1150 
1151 //------------------------------------------------------------------------------
1152 // Name: slotLogclicked
1153 // Desc: executes the Log function
1154 //------------------------------------------------------------------------------
1155 void KCalculator::slotLogclicked()
1156 {
1157     if (!shift_mode_) {
1158         this->insertToInputDisplay(KCalcToken::TokenCode::LOG_10);
1159         this->insertToInputDisplay(KCalcToken::TokenCode::OPENING_PARENTHESIS);
1160     } else {
1161         update_history_window_ = false;
1162         this->insertToInputDisplay(KCalcToken::TokenCode::EXP_10);
1163     }
1164 }
1165 
1166 //------------------------------------------------------------------------------
1167 // Name: slotSquareclicked
1168 // Desc: executes the x^2 function
1169 //------------------------------------------------------------------------------
1170 void KCalculator::slotSquareclicked()
1171 {
1172     if (!shift_mode_) {
1173         insertToInputDisplay(KCalcToken::TokenCode::SQUARE);
1174     } else {
1175         insertToInputDisplay(KCalcToken::TokenCode::SQUARE_ROOT);
1176     }
1177 }
1178 
1179 //------------------------------------------------------------------------------
1180 // Name: slotCubeclicked
1181 // Desc: executes the x^3 function
1182 //------------------------------------------------------------------------------
1183 void KCalculator::slotCubeclicked()
1184 {
1185     if (!shift_mode_) {
1186         this->insertToInputDisplay(KCalcToken::TokenCode::CUBE);
1187     } else {
1188         this->insertToInputDisplay(KCalcToken::TokenCode::CUBIC_ROOT);
1189     }
1190 }
1191 
1192 //------------------------------------------------------------------------------
1193 // Name: slotLnclicked
1194 // Desc: executes the ln function
1195 //------------------------------------------------------------------------------
1196 void KCalculator::slotLnclicked()
1197 {
1198     if (!shift_mode_) {
1199         this->insertToInputDisplay(KCalcToken::TokenCode::LN);
1200         this->insertToInputDisplay(KCalcToken::TokenCode::OPENING_PARENTHESIS);
1201     } else {
1202         this->insertToInputDisplay(KCalcToken::TokenCode::EXP);
1203         this->insertToInputDisplay(KCalcToken::TokenCode::OPENING_PARENTHESIS);
1204     }
1205 }
1206 
1207 //------------------------------------------------------------------------------
1208 // Name: slotPowerclicked
1209 // Desc: executes the x^y function
1210 //------------------------------------------------------------------------------
1211 void KCalculator::slotPowerclicked()
1212 {
1213     if (shift_mode_) {
1214         this->insertToInputDisplay(KCalcToken::TokenCode::POWER_ROOT);
1215     } else {
1216         this->insertToInputDisplay(KCalcToken::TokenCode::POWER);
1217     }
1218 }
1219 
1220 //------------------------------------------------------------------------------
1221 // Name: slotMemClearclicked
1222 // Desc: executes the MC function
1223 //------------------------------------------------------------------------------
1224 void KCalculator::slotMemClearclicked()
1225 {
1226     memory_num_ = KNumber::Zero;
1227     statusBar()->setMemoryIndicator(false);
1228     memory_label->setText(QStringLiteral(""));
1229     pbMemRecall->setDisabled(true);
1230 
1231     this->input_display->clear();
1232     this->input_display->slotSetHardOverwrite();
1233     this->input_display->insert(i18nc("Memory cleared", "M cleared"));
1234     calc_history->addToHistory(i18nc("Memory cleared", "M cleared"), true);
1235     updateDisplay(UPDATE_CLEAR);
1236 }
1237 
1238 //------------------------------------------------------------------------------
1239 // Name: slotBackspaceclicked
1240 // Desc: removes the last input digit
1241 //------------------------------------------------------------------------------
1242 void KCalculator::slotBackspaceclicked()
1243 {
1244     this->input_display->slotClearOverwrite();
1245     this->input_display->backspace();
1246 }
1247 
1248 //------------------------------------------------------------------------------
1249 // Name: slotClearclicked
1250 // Desc: clears the display
1251 //------------------------------------------------------------------------------
1252 void KCalculator::slotClearclicked()
1253 {
1254     calc_display->sendEvent(KCalcDisplay::EventClear);
1255     input_display->clear();
1256 }
1257 
1258 //------------------------------------------------------------------------------
1259 // Name: slotAllClearclicked
1260 // Desc: clears everything
1261 //------------------------------------------------------------------------------
1262 void KCalculator::slotAllClearclicked()
1263 {
1264     this->input_display->clear();
1265     core.Reset();
1266     calc_display->sendEvent(KCalcDisplay::EventReset);
1267     updateDisplay(UPDATE_FROM_CORE);
1268 }
1269 
1270 //------------------------------------------------------------------------------
1271 // Name: slotParenOpenclicked
1272 // Desc: starts a sub-expression
1273 //------------------------------------------------------------------------------
1274 void KCalculator::slotParenOpenclicked()
1275 {
1276     this->insertToInputDisplay(KCalcToken::TokenCode::OPENING_PARENTHESIS);
1277 }
1278 
1279 //------------------------------------------------------------------------------
1280 // Name: slotParenCloseclicked
1281 // Desc: ends a sub-expression
1282 //------------------------------------------------------------------------------
1283 void KCalculator::slotParenCloseclicked()
1284 {
1285     insertToInputDisplay(KCalcToken::TokenCode::CLOSING_PARENTHESIS);
1286 }
1287 
1288 //------------------------------------------------------------------------------
1289 // Name: slotANDclicked
1290 // Desc: executes a bitwise AND
1291 //------------------------------------------------------------------------------
1292 void KCalculator::slotANDclicked()
1293 {
1294     this->insertToInputDisplay(KCalcToken::TokenCode::AND);
1295 }
1296 
1297 //------------------------------------------------------------------------------
1298 // Name: slotMultiplicationclicked
1299 // Desc: executes multiplication
1300 //------------------------------------------------------------------------------
1301 void KCalculator::slotMultiplicationclicked()
1302 {
1303     this->insertToInputDisplay(KCalcToken::TokenCode::MULTIPLICATION);
1304 }
1305 
1306 //------------------------------------------------------------------------------
1307 // Name: slotDivisionclicked
1308 // Desc: executes division
1309 //------------------------------------------------------------------------------
1310 void KCalculator::slotDivisionclicked()
1311 {
1312     this->insertToInputDisplay(KCalcToken::TokenCode::DIVISION);
1313 }
1314 
1315 //------------------------------------------------------------------------------
1316 // Name: slotORclicked
1317 // Desc: executes a bitwise OR
1318 //------------------------------------------------------------------------------
1319 void KCalculator::slotORclicked()
1320 {
1321     this->insertToInputDisplay(KCalcToken::TokenCode::OR);
1322 }
1323 
1324 //------------------------------------------------------------------------------
1325 // Name: slotXORclicked
1326 // Desc: executes a bitwise XOR
1327 //------------------------------------------------------------------------------
1328 void KCalculator::slotXORclicked()
1329 {
1330     this->insertToInputDisplay(KCalcToken::TokenCode::XOR);
1331 }
1332 
1333 //------------------------------------------------------------------------------
1334 // Name: slotPlusclicked
1335 // Desc: executes addition
1336 //------------------------------------------------------------------------------
1337 void KCalculator::slotPlusclicked()
1338 {
1339     this->insertToInputDisplay(KCalcToken::TokenCode::PLUS);
1340 }
1341 
1342 //------------------------------------------------------------------------------
1343 // Name: slotMinusclicked
1344 // Desc: executes subtraction
1345 //------------------------------------------------------------------------------
1346 void KCalculator::slotMinusclicked()
1347 {
1348     this->insertToInputDisplay(KCalcToken::TokenCode::MINUS);
1349 }
1350 
1351 //------------------------------------------------------------------------------
1352 // Name: slotLeftShiftclicked
1353 // Desc: executes a bitwise left shift
1354 //------------------------------------------------------------------------------
1355 void KCalculator::slotLeftShiftclicked()
1356 {
1357     this->insertToInputDisplay(KCalcToken::TokenCode::LSH);
1358 }
1359 
1360 //------------------------------------------------------------------------------
1361 // Name: slotLeftShiftclicked
1362 // Desc: executes a bitwise right shift
1363 //------------------------------------------------------------------------------
1364 void KCalculator::slotRightShiftclicked()
1365 {
1366     this->insertToInputDisplay(KCalcToken::TokenCode::RSH);
1367 }
1368 
1369 //------------------------------------------------------------------------------
1370 // Name: slotPeriodclicked
1371 // Desc: enters a decimal into the input stream
1372 //------------------------------------------------------------------------------
1373 void KCalculator::slotPeriodclicked()
1374 {
1375     this->insertToInputDisplay(KCalcToken::TokenCode::DECIMAL_POINT);
1376 }
1377 
1378 //------------------------------------------------------------------------------
1379 // Name: updateResultDisplay
1380 // Desc: pastest result in result_display
1381 //------------------------------------------------------------------------------
1382 void KCalculator::updateResultDisplay()
1383 {
1384     updateDisplay(UPDATE_FROM_CORE /*| UPDATE_STORE_RESULT*/);
1385 }
1386 
1387 //------------------------------------------------------------------------------
1388 // Name: slotEqualclicked
1389 // Desc: calculates and displays the result of the pending operations
1390 //------------------------------------------------------------------------------
1391 void KCalculator::slotEqualclicked()
1392 {
1393     this->commit_Input_();
1394 
1395     if (parsing_failure_) {
1396         handle_Parsing_Error_();
1397     } else if (calculation_failure_) {
1398         handle_Calculation_Error_();
1399     } else {
1400         commit_Result_();
1401     }
1402 }
1403 
1404 //------------------------------------------------------------------------------
1405 // Name: slotPercentclicked
1406 // Desc: calculates and displays the result of the pending operations as a percent
1407 //------------------------------------------------------------------------------
1408 void KCalculator::slotPercentclicked()
1409 {
1410     this->insertToInputDisplay(KCalcToken::TokenCode::PERCENTAGE);
1411 }
1412 
1413 //------------------------------------------------------------------------------
1414 // Name: slotNegateclicked
1415 // Desc: executes a bitwise 2's compliment
1416 // NOTE: implicitly converts the value to an unsigned quantity
1417 //------------------------------------------------------------------------------
1418 void KCalculator::slotNegateclicked()
1419 {
1420     this->insertToInputDisplay(KCalcToken::TokenCode::ONE_S_COMPLEMENT);
1421 }
1422 
1423 //------------------------------------------------------------------------------
1424 // Name: slotModclicked
1425 // Desc: executes modulous (remainder division)
1426 //------------------------------------------------------------------------------
1427 void KCalculator::slotModclicked()
1428 {
1429     if (shift_mode_) {
1430         this->insertToInputDisplay(KCalcToken::TokenCode::INTEGER_DIVISION);
1431     } else {
1432         this->insertToInputDisplay(KCalcToken::TokenCode::MODULO);
1433     }
1434 }
1435 
1436 //------------------------------------------------------------------------------
1437 // Name: slotStatNumclicked
1438 // Desc: executes Sum function
1439 //------------------------------------------------------------------------------
1440 void KCalculator::slotStatNumclicked()
1441 {
1442     this->input_display->clear();
1443     this->input_display->slotSetHardOverwrite();
1444 
1445     if (!shift_mode_) {
1446         core.StatCount(KNumber::Zero);
1447         this->calc_history->addToHistory(i18n("Number of data entered = "), false);
1448         this->input_display->insert(i18n("Number of data entered ="));
1449     } else {
1450         pbShift->setChecked(false);
1451         core.StatSum(KNumber::Zero);
1452         calc_history->addToHistory(QString::fromUtf8("\xce\xa3") + QLatin1Char('x') + QLatin1Char('='), false);
1453         this->input_display->insert(i18n("Sum of all data items ="));
1454     }
1455 
1456     updateDisplay(UPDATE_FROM_CORE);
1457     calc_history->addResultToHistory(calc_display->getAmount().toQString(KCalcSettings::precision()));
1458 }
1459 
1460 //------------------------------------------------------------------------------
1461 // Name: slotStatMeanclicked
1462 // Desc: executes Mean function
1463 //------------------------------------------------------------------------------
1464 void KCalculator::slotStatMeanclicked()
1465 {
1466     this->input_display->clear();
1467     this->input_display->slotSetHardOverwrite();
1468 
1469     if (!shift_mode_) {
1470         core.StatMean(KNumber::Zero);
1471         this->input_display->insert(QStringLiteral("Mean ="));
1472         calc_history->addToHistory(i18n("Mean = "), false);
1473     } else {
1474         pbShift->setChecked(false);
1475         core.StatSumSquares(KNumber::Zero);
1476         this->input_display->insert(i18n("Sum of squares ="));
1477         calc_history->addToHistory(QString::fromUtf8("\xce\xa3") + QStringLiteral("x<sub>i</sub><sup>2</sup> = "), false);
1478     }
1479 
1480     updateDisplay(UPDATE_FROM_CORE);
1481     calc_history->addResultToHistory(calc_display->getAmount().toQString(KCalcSettings::precision()));
1482 }
1483 
1484 //------------------------------------------------------------------------------
1485 // Name: slotStatStdDevclicked
1486 // Desc: executes STD function
1487 //------------------------------------------------------------------------------
1488 void KCalculator::slotStatStdDevclicked()
1489 {
1490     this->input_display->clear();
1491     this->input_display->slotSetHardOverwrite();
1492 
1493     if (shift_mode_) {
1494         // std (n-1)
1495         core.StatStdSample(KNumber::Zero);
1496         pbShift->setChecked(false);
1497         this->input_display->insert(QString::fromUtf8("\xcf\x83") + QStringLiteral("<sub>N-1</sub> ="));
1498         calc_history->addToHistory(QString::fromUtf8("\xcf\x83") + QStringLiteral("<sub>N-1</sub> = "), false);
1499     } else {
1500         core.StatStdDeviation(KNumber::Zero);
1501         this->input_display->insert(QString::fromUtf8("\xcf\x83") + QStringLiteral("N ="));
1502         calc_history->addToHistory(QString::fromUtf8("&sigma;") + QStringLiteral("<sub>N</sub> = "), false);
1503     }
1504 
1505     updateDisplay(UPDATE_FROM_CORE);
1506     calc_history->addResultToHistory(calc_display->getAmount().toQString(KCalcSettings::precision()));
1507 }
1508 
1509 //------------------------------------------------------------------------------
1510 // Name: slotStatMedianclicked
1511 // Desc: executes Median function
1512 //------------------------------------------------------------------------------
1513 void KCalculator::slotStatMedianclicked()
1514 {
1515     this->input_display->clear();
1516     this->input_display->slotSetHardOverwrite();
1517 
1518     core.StatMedian(KNumber::Zero);
1519     input_display->insert(i18n("Median ="));
1520     calc_history->addToHistory(i18n("Median = "), false);
1521 
1522     if (shift_mode_) {
1523         pbShift->setChecked(false);
1524     }
1525 
1526     updateDisplay(UPDATE_FROM_CORE);
1527     calc_history->addResultToHistory(calc_display->getAmount().toQString(KCalcSettings::precision()));
1528 }
1529 
1530 //------------------------------------------------------------------------------
1531 // Name: slotStatDataInputclicked
1532 // Desc: enters a value for statistical functions
1533 //------------------------------------------------------------------------------
1534 void KCalculator::slotStatDataInputclicked()
1535 {
1536     if (!shift_mode_) {
1537         this->commit_Input_();
1538         //
1539         if (parsing_failure_) {
1540             handle_Parsing_Error_();
1541         } else if (calculation_failure_) {
1542             handle_Calculation_Error_();
1543         } else {
1544             commit_Result_(false);
1545             this->input_display->clear();
1546             this->input_display->slotSetHardOverwrite();
1547 
1548             bool tmp_error;
1549             core.StatDataNew(calc_display->getAmount());
1550 
1551             input_display->insert(i18n("DAT [") + core.lastOutput(tmp_error).toQString() + i18n("] = ")
1552                                   + calc_display->getAmount().toQString(KCalcSettings::precision()));
1553             calc_history->addToHistory(i18n("DAT [") + core.lastOutput(tmp_error).toQString() + i18n("] = ")
1554                                            + calc_display->getAmount().toQString(KCalcSettings::precision()),
1555                                        true);
1556         }
1557     } else {
1558         pbShift->setChecked(false);
1559         this->input_display->clear();
1560         this->input_display->slotSetHardOverwrite();
1561         input_display->insert(i18n("Last stat data erased"));
1562         core.StatDataDel();
1563         statusBar()->showMessage(i18n("Last stat data erased"), 3000);
1564         calc_history->addToHistory(i18n("Last stat data erased"), true);
1565         updateDisplay(UPDATE_CLEAR);
1566     }
1567 }
1568 
1569 //------------------------------------------------------------------------------
1570 // Name: slotStatClearDataclicked
1571 // Desc: clears memory for statical functions
1572 //------------------------------------------------------------------------------
1573 void KCalculator::slotStatClearDataclicked()
1574 {
1575     this->input_display->clear();
1576     this->input_display->insert(i18n("Stat mem cleared"));
1577     this->input_display->slotSetHardOverwrite();
1578     core.StatClearAll();
1579     statusBar()->showMessage(i18n("Stat mem cleared"), 3000);
1580     calc_history->addToHistory(i18n("Stat mem cleared"), true);
1581 
1582     if (shift_mode_) {
1583         pbShift->setChecked(false);
1584     }
1585     updateDisplay(UPDATE_CLEAR);
1586 }
1587 
1588 //------------------------------------------------------------------------------
1589 // Name: slotConstclicked
1590 // Desc: enters a constant
1591 //------------------------------------------------------------------------------
1592 void KCalculator::slotConstclicked(int button)
1593 {
1594     if (auto btn = qobject_cast<KCalcConstButton *>(const_buttons_[button])) {
1595         if (!shift_mode_) {
1596             // set the display to the configured value of constant button
1597             // internally, we deal with C locale style numbers, we need to convert
1598             QString val = btn->constant();
1599             val.replace(QLatin1Char('.'), KNumber::decimalSeparator());
1600             this->insertToInputDisplay(val);
1601 
1602         } else {
1603             pbShift->setChecked(false);
1604 
1605             // internally, we deal with C locale style numbers, we need to convert
1606             QString val = calc_display->text();
1607             val.replace(KNumber::decimalSeparator(), QLatin1String("."));
1608             KCalcSettings::setValueConstant(button, val);
1609 
1610             // below set new tooltip
1611             btn->setLabelAndTooltip();
1612         }
1613     }
1614 }
1615 
1616 //------------------------------------------------------------------------------
1617 // Name: showSettings
1618 // Desc: opens the shows the settings dialog
1619 //------------------------------------------------------------------------------
1620 void KCalculator::showSettings()
1621 {
1622     // Check if there is already a dialog and if so bring
1623     // it to the foreground.
1624     if (KConfigDialog::showDialog(QStringLiteral("settings"))) {
1625         return;
1626     }
1627 
1628     // Create a new dialog with the same name as the above checking code.
1629     auto const dialog = new KConfigDialog(this, QStringLiteral("settings"), KCalcSettings::self());
1630 
1631     // general settings
1632     auto const general = new General(nullptr);
1633     general->kcfg_Precision->setMaximum(maxprecision);
1634     dialog->addPage(general, i18n("General"), QStringLiteral("accessories-calculator"), i18n("General Settings"));
1635 
1636     // font settings
1637     auto const fonts = new Fonts(nullptr);
1638     dialog->addPage(fonts, i18n("Font"), QStringLiteral("preferences-desktop-font"), i18n("Select Display Font"));
1639 
1640     // color settings
1641     auto const color = new Colors(nullptr);
1642     dialog->addPage(color, i18n("Colors"), QStringLiteral("preferences-desktop-color"), i18n("Button & Display Colors"));
1643 
1644     // constant settings
1645     if (!constants_) {
1646         constants_ = new Constants(nullptr);
1647 
1648         KCalcConstMenu *tmp_menu;
1649         tmp_menu = new KCalcConstMenu(constants_);
1650         connect(tmp_menu, &KCalcConstMenu::triggeredConstant, this, &KCalculator::slotChooseScientificConst0);
1651         constants_->pushButton0->setMenu(tmp_menu);
1652 
1653         tmp_menu = new KCalcConstMenu(constants_);
1654         connect(tmp_menu, &KCalcConstMenu::triggeredConstant, this, &KCalculator::slotChooseScientificConst1);
1655         constants_->pushButton1->setMenu(tmp_menu);
1656 
1657         tmp_menu = new KCalcConstMenu(constants_);
1658         connect(tmp_menu, &KCalcConstMenu::triggeredConstant, this, &KCalculator::slotChooseScientificConst2);
1659         constants_->pushButton2->setMenu(tmp_menu);
1660 
1661         tmp_menu = new KCalcConstMenu(constants_);
1662         connect(tmp_menu, &KCalcConstMenu::triggeredConstant, this, &KCalculator::slotChooseScientificConst3);
1663         constants_->pushButton3->setMenu(tmp_menu);
1664 
1665         tmp_menu = new KCalcConstMenu(constants_);
1666         connect(tmp_menu, &KCalcConstMenu::triggeredConstant, this, &KCalculator::slotChooseScientificConst4);
1667         constants_->pushButton4->setMenu(tmp_menu);
1668 
1669         tmp_menu = new KCalcConstMenu(constants_);
1670         connect(tmp_menu, &KCalcConstMenu::triggeredConstant, this, &KCalculator::slotChooseScientificConst5);
1671         constants_->pushButton5->setMenu(tmp_menu);
1672     }
1673 
1674     dialog->addPage(constants_, i18n("Constants"), QStringLiteral("preferences-kcalc-constants"), i18n("Define Constants"));
1675 
1676     // When the user clicks OK or Apply we want to update our settings.
1677     connect(dialog, &KConfigDialog::settingsChanged, this, &KCalculator::updateSettings);
1678 
1679     // Display the dialog.
1680     dialog->show();
1681 }
1682 
1683 // these 6 slots are just a quick hack, instead of setting the
1684 // TextEdit fields in the configuration dialog, we are setting the
1685 // Settingvalues themselves!!
1686 
1687 //------------------------------------------------------------------------------
1688 // Name: slotChooseScientificConst0
1689 // Desc: updates constants value
1690 //------------------------------------------------------------------------------
1691 void KCalculator::slotChooseScientificConst0(const science_constant &chosen_const)
1692 {
1693     constants_->kcfg_valueConstant0->setText(chosen_const.value);
1694     constants_->kcfg_nameConstant0->setText(chosen_const.label);
1695 }
1696 
1697 //------------------------------------------------------------------------------
1698 // Name: slotChooseScientificConst1
1699 // Desc: updates constants value
1700 //------------------------------------------------------------------------------
1701 void KCalculator::slotChooseScientificConst1(const science_constant &chosen_const)
1702 {
1703     constants_->kcfg_valueConstant1->setText(chosen_const.value);
1704     constants_->kcfg_nameConstant1->setText(chosen_const.label);
1705 }
1706 
1707 //------------------------------------------------------------------------------
1708 // Name: slotChooseScientificConst2
1709 // Desc: updates constants value
1710 //------------------------------------------------------------------------------
1711 void KCalculator::slotChooseScientificConst2(const science_constant &chosen_const)
1712 {
1713     constants_->kcfg_valueConstant2->setText(chosen_const.value);
1714     constants_->kcfg_nameConstant2->setText(chosen_const.label);
1715 }
1716 
1717 //------------------------------------------------------------------------------
1718 // Name: slotChooseScientificConst3
1719 // Desc: updates constants value
1720 //------------------------------------------------------------------------------
1721 void KCalculator::slotChooseScientificConst3(const science_constant &chosen_const)
1722 {
1723     constants_->kcfg_valueConstant3->setText(chosen_const.value);
1724     constants_->kcfg_nameConstant3->setText(chosen_const.label);
1725 }
1726 
1727 //------------------------------------------------------------------------------
1728 // Name: slotChooseScientificConst4
1729 // Desc: updates constants value
1730 //------------------------------------------------------------------------------
1731 void KCalculator::slotChooseScientificConst4(const science_constant &chosen_const)
1732 {
1733     constants_->kcfg_valueConstant4->setText(chosen_const.value);
1734     constants_->kcfg_nameConstant4->setText(chosen_const.label);
1735 }
1736 
1737 //------------------------------------------------------------------------------
1738 // Name: slotChooseScientificConst5
1739 // Desc: updates constants value
1740 //------------------------------------------------------------------------------
1741 void KCalculator::slotChooseScientificConst5(const science_constant &chosen_const)
1742 {
1743     constants_->kcfg_valueConstant5->setText(chosen_const.value);
1744     constants_->kcfg_nameConstant5->setText(chosen_const.label);
1745 }
1746 
1747 //------------------------------------------------------------------------------
1748 // Name: slotSetSimpleMode
1749 // Desc: sets the calculator to have a simple layout
1750 //------------------------------------------------------------------------------
1751 void KCalculator::slotSetSimpleMode()
1752 {
1753     bool wasMinimumSize = isMinimumSize();
1754 
1755     action_constants_show_->setChecked(false);
1756     action_constants_show_->setEnabled(false);
1757     action_bitset_show_->setEnabled(false);
1758     action_history_show_->setChecked(KCalcSettings::showHistory());
1759     showMemButtons(false);
1760     showScienceButtons(false);
1761     showStatButtons(false);
1762     showLogicButtons(false);
1763 
1764     if (shift_mode_) {
1765         Q_EMIT(slotShifttoggled(false));
1766     }
1767     // hide some individual buttons, which are not in one of the above groups
1768     pbShift->hide();
1769     pbMod->hide();
1770     pbReci->hide();
1771     pbFactorial->hide();
1772     pbSquare->hide();
1773     pbPower->hide();
1774     pbCube->hide();
1775     pbEE->hide();
1776 
1777     // delete the constant menu since it doesn't fit
1778     delete constants_menu_;
1779     constants_menu_ = nullptr;
1780 
1781     KCalcSettings::setCalculatorMode(KCalcSettings::EnumCalculatorMode::simple);
1782     // must be done after setting the calculator mode because the
1783     // slotBitsetshow slot should save the state only in numeral mode
1784     action_bitset_show_->setChecked(false);
1785     
1786     // disable leftPad from affecting the layout
1787     setLeftPadLayoutActive(false);
1788 
1789     // update font size
1790     QApplication::processEvents();
1791     setFonts();
1792     updateGeometry();
1793 
1794     if (!is_still_in_launch_) {
1795         forceResizeEvent();
1796         QApplication::processEvents();
1797         if (wasMinimumSize) {
1798             resize(minimumSize());
1799         }
1800     }
1801 }
1802 
1803 //------------------------------------------------------------------------------
1804 // Name: slotSetScienceMode
1805 // Desc: sets the calculator to science mode
1806 //------------------------------------------------------------------------------
1807 void KCalculator::slotSetScienceMode()
1808 {
1809     bool wasMinimumSize = isMinimumSize();
1810 
1811     action_constants_show_->setEnabled(true);
1812     action_constants_show_->setChecked(KCalcSettings::showConstants());
1813     action_bitset_show_->setEnabled(false);
1814     action_history_show_->setChecked(KCalcSettings::showHistory());
1815 
1816     // show some individual buttons
1817     pbShift->show();
1818     pbMod->show();
1819     pbReci->show();
1820     pbFactorial->show();
1821     pbSquare->show();
1822     pbPower->show();
1823     pbCube->show();
1824     pbEE->show();
1825 
1826     // show or hide some groups of buttons
1827     showStatButtons(false);
1828     showLogicButtons(false);
1829     showMemButtons(true);
1830     showScienceButtons(true);
1831 
1832     if (!constants_menu_) {
1833         constants_menu_ = createConstantsMenu();
1834         menuBar()->insertMenu((menuBar()->actions)()[2], constants_menu_);
1835     }
1836 
1837     KCalcSettings::setCalculatorMode(KCalcSettings::EnumCalculatorMode::science);
1838     // must be done after setting the calculator mode because the
1839     // slotBitsetshow slot should save the state only in numeral mode
1840     action_bitset_show_->setChecked(false);
1841     
1842     // enable leftPad to affect the layout
1843     setLeftPadLayoutActive(true);
1844 
1845     // update font size
1846     QApplication::processEvents();
1847     setFonts();
1848     updateGeometry();
1849 
1850     if (!is_still_in_launch_) {
1851         forceResizeEvent();
1852         QApplication::processEvents();
1853         if (wasMinimumSize) {
1854             resize(minimumSize());
1855         }
1856     }
1857 }
1858 
1859 //------------------------------------------------------------------------------
1860 // Name: slotSetStatisticMode
1861 // Desc: sets the calculator to stats mode
1862 //------------------------------------------------------------------------------
1863 void KCalculator::slotSetStatisticMode()
1864 {
1865     bool wasMinimumSize = isMinimumSize();
1866 
1867     action_constants_show_->setEnabled(true);
1868     action_constants_show_->setChecked(KCalcSettings::showConstants());
1869     action_bitset_show_->setEnabled(false);
1870     action_history_show_->setChecked(KCalcSettings::showHistory());
1871 
1872     // show some individual buttons
1873     pbShift->show();
1874     pbMod->show();
1875     pbReci->show();
1876     pbFactorial->show();
1877     pbSquare->show();
1878     pbPower->show();
1879     pbCube->show();
1880     pbEE->show();
1881 
1882     // show or hide some groups of buttons
1883     showLogicButtons(false);
1884     showMemButtons(true);
1885     showScienceButtons(true);
1886     showStatButtons(true);
1887 
1888     if (!constants_menu_) {
1889         constants_menu_ = createConstantsMenu();
1890         menuBar()->insertMenu((menuBar()->actions)()[2], constants_menu_);
1891     }
1892 
1893     KCalcSettings::setCalculatorMode(KCalcSettings::EnumCalculatorMode::statistics);
1894     // must be done after setting the calculator mode because the
1895     // slotBitsetshow slot should save the state only in numeral mode
1896     action_bitset_show_->setChecked(false);
1897     
1898     // enable leftPad to affect the layout
1899     setLeftPadLayoutActive(true);
1900 
1901     // update font size
1902     QApplication::processEvents();
1903     setFonts();
1904     updateGeometry();
1905 
1906     if (!is_still_in_launch_) {
1907         forceResizeEvent();
1908         QApplication::processEvents();
1909         if (wasMinimumSize) {
1910             resize(minimumSize());
1911         }
1912     }
1913 }
1914 
1915 //------------------------------------------------------------------------------
1916 // Name: slotSetNumeralMode
1917 // Desc: sets the calculator to numerical ("programmers") mode
1918 //------------------------------------------------------------------------------
1919 void KCalculator::slotSetNumeralMode()
1920 {
1921     bool wasMinimumSize = isMinimumSize();
1922 
1923     action_constants_show_->setChecked(false);
1924     action_constants_show_->setEnabled(false);
1925     action_bitset_show_->setEnabled(true);
1926     action_bitset_show_->setChecked(KCalcSettings::showBitset());
1927     action_history_show_->setChecked(KCalcSettings::showHistory());
1928 
1929     // show some individual buttons
1930     pbShift->show();
1931     pbMod->show();
1932     pbReci->show();
1933     pbFactorial->show();
1934     pbSquare->show();
1935     pbPower->show();
1936     pbCube->show();
1937     pbEE->show();
1938 
1939     // show or hide some groups of buttons
1940     showScienceButtons(false);
1941     showStatButtons(false);
1942     showMemButtons(true);
1943     showLogicButtons(true);
1944 
1945     if (!constants_menu_) {
1946         constants_menu_ = createConstantsMenu();
1947         menuBar()->insertMenu((menuBar()->actions)()[2], constants_menu_);
1948     }
1949 
1950     KCalcSettings::setCalculatorMode(KCalcSettings::EnumCalculatorMode::numeral);
1951     
1952     // enable leftPad to affect the layout
1953     setLeftPadLayoutActive(true);
1954 
1955     // update font size
1956     QApplication::processEvents();
1957     setFonts();
1958     updateGeometry();
1959 
1960     if (!is_still_in_launch_) {
1961         forceResizeEvent();
1962         QApplication::processEvents();
1963         if (wasMinimumSize) {
1964             resize(minimumSize());
1965         }
1966     }
1967 }
1968 
1969 //------------------------------------------------------------------------------
1970 // Name: slotBaseModeAmountChanged
1971 // Desc: updates numerical base conversions
1972 //------------------------------------------------------------------------------
1973 void KCalculator::slotBaseModeAmountChanged(const KNumber &number)
1974 {
1975     quint64 n = number.toUint64();
1976 
1977     decDisplay->setText(QString::number(n, 10));
1978     binDisplay->setText(QString::number(n, 2));
1979     octDisplay->setText(QString::number(n, 8));
1980     hexDisplay->setText(QString::number(n, 16).toUpper());
1981 }
1982 
1983 //------------------------------------------------------------------------------
1984 // Name: showMemButtons
1985 // Desc: hides or shows the memory buttons
1986 //------------------------------------------------------------------------------
1987 void KCalculator::showMemButtons(bool toggled)
1988 {
1989     if (toggled) {
1990         for (QAbstractButton *btn : std::as_const(mem_button_list_)) {
1991             btn->show();
1992         }
1993     } else {
1994         for (QAbstractButton *btn : std::as_const(mem_button_list_)) {
1995             btn->hide();
1996         }
1997 
1998         // these are in the mem_button_list_ but should not be hidden
1999         pbClear->show();
2000         pbAllClear->show();
2001     }
2002 }
2003 
2004 //------------------------------------------------------------------------------
2005 // Name: showStatButtons
2006 // Desc: hides or shows the stat buttons
2007 //------------------------------------------------------------------------------
2008 void KCalculator::showStatButtons(bool toggled)
2009 {
2010     if (toggled) {
2011         for (QAbstractButton *btn : std::as_const(stat_buttons_)) {
2012             btn->show();
2013         }
2014     } else {
2015         for (QAbstractButton *btn : std::as_const(stat_buttons_)) {
2016             btn->hide();
2017         }
2018     }
2019 }
2020 
2021 //------------------------------------------------------------------------------
2022 // Name: showScienceButtons
2023 // Desc: hides or shows the science buttons
2024 //------------------------------------------------------------------------------
2025 void KCalculator::showScienceButtons(bool toggled)
2026 {
2027     if (toggled) {
2028         for (QAbstractButton *btn : std::as_const(scientific_buttons_)) {
2029             btn->show();
2030         }
2031         const auto buttons = angle_choose_group_->buttons();
2032         for (QAbstractButton *btn : buttons) {
2033             btn->show();
2034         }
2035 
2036         setAngle();
2037         statusBar()->setAngleModeIndicatorVisible(true);
2038     } else {
2039         angle_units_label->setText(QStringLiteral(""));
2040         for (QAbstractButton *btn : std::as_const(scientific_buttons_)) {
2041             btn->hide();
2042         }
2043 
2044         const auto buttons = angle_choose_group_->buttons();
2045         for (QAbstractButton *btn : buttons) {
2046             btn->hide();
2047         }
2048 
2049         statusBar()->setAngleModeIndicatorVisible(false);
2050     }
2051 }
2052 
2053 //------------------------------------------------------------------------------
2054 // Name: showLogicButtons
2055 // Desc: hides or shows the logic buttons
2056 //------------------------------------------------------------------------------
2057 void KCalculator::showLogicButtons(bool toggled)
2058 {
2059     if (toggled) {
2060         mBitset->setEnabled(true);
2061         connect(mBitset, &KCalcBitset::valueChanged, this, &KCalculator::slotBitsetChanged);
2062         connect(calc_display, &KCalcDisplay::changedAmount, this, &KCalculator::slotUpdateBitset);
2063 
2064         for (QAbstractButton *btn : std::as_const(logic_buttons_)) {
2065             btn->show();
2066         }
2067 
2068         setBase();
2069         statusBar()->setBaseIndicatorVisible(true);
2070 
2071         const auto buttons = base_choose_group_->buttons();
2072         for (QAbstractButton *btn : buttons) {
2073             btn->show();
2074         }
2075 
2076         for (QLabel *lbl : base_conversion_labels_) {
2077             lbl->show();
2078         }
2079         connect(calc_display, &KCalcDisplay::changedAmount, this, &KCalculator::slotBaseModeAmountChanged);
2080 
2081         for (int i = 10; i < 16; ++i) {
2082             (num_button_group_->button(i))->show();
2083         }
2084     } else {
2085         mBitset->setEnabled(false);
2086         disconnect(mBitset, &KCalcBitset::valueChanged, this, &KCalculator::slotBitsetChanged);
2087         disconnect(calc_display, &KCalcDisplay::changedAmount, this, &KCalculator::slotUpdateBitset);
2088 
2089         for (QAbstractButton *btn : std::as_const(logic_buttons_)) {
2090             btn->hide();
2091         }
2092 
2093         // Hide Hex-Buttons, but first switch back to decimal
2094         decRadio->animateClick();
2095 
2096         const auto buttons = base_choose_group_->buttons();
2097         for (QAbstractButton *btn : buttons) {
2098             btn->hide();
2099         }
2100 
2101         for (QLabel *lbl : base_conversion_labels_) {
2102             lbl->hide();
2103         }
2104         connect(calc_display, &KCalcDisplay::changedAmount, this, &KCalculator::slotBaseModeAmountChanged);
2105 
2106         statusBar()->setBaseIndicatorVisible(false);
2107         base_label->setText(QStringLiteral("Dec"));
2108         for (int i = 10; i < 16; ++i) {
2109             (num_button_group_->button(i))->hide();
2110         }
2111     }
2112 }
2113 
2114 //------------------------------------------------------------------------------
2115 // Name: slotHistoryshow
2116 // Desc: hides or shows the history
2117 //------------------------------------------------------------------------------
2118 void KCalculator::slotHistoryshow(bool toggled) {
2119     bool wasMinimumSize = isMinimumSize();
2120 
2121     calc_history->setVisible(toggled);
2122     KCalcSettings::setShowHistory(toggled);
2123     updateGeometry();
2124 
2125     if (!is_still_in_launch_) {
2126         forceResizeEvent();
2127         QApplication::processEvents();
2128         if (wasMinimumSize) {
2129             resize(minimumSize());
2130         }
2131     }
2132 }
2133 
2134 //------------------------------------------------------------------------------
2135 // Name: slotConstantsShow
2136 // Desc: hides or shows the constants buttons
2137 //------------------------------------------------------------------------------
2138 void KCalculator::slotConstantsShow(bool toggled)
2139 {
2140     bool wasMinimumSize = isMinimumSize();
2141 
2142     if (toggled) {
2143         for (QAbstractButton *btn : std::as_const(const_buttons_)) {
2144             btn->show();
2145         }
2146     } else {
2147         for (QAbstractButton *btn : std::as_const(const_buttons_)) {
2148             btn->hide();
2149         }
2150     }
2151 
2152     KCalcSettings::setShowConstants(toggled);
2153     updateGeometry();
2154 
2155     if (!is_still_in_launch_) {
2156         forceResizeEvent();
2157         QApplication::processEvents();
2158         if (wasMinimumSize) {
2159             // In this specific case, we need to invalidate the layout before resize
2160             layout()->invalidate();
2161             QApplication::processEvents();
2162             resize(minimumSize());
2163         }
2164     }
2165 }
2166 
2167 //------------------------------------------------------------------------------
2168 // Name: slotBitsetshow
2169 // Desc: hides or shows the bitset buttons
2170 //------------------------------------------------------------------------------
2171 void KCalculator::slotBitsetshow(bool toggled)
2172 {
2173     bool wasMinimumSize = isMinimumSize();
2174 
2175     mBitset->setVisible(toggled);
2176     setBitsetLayoutActive(toggled);
2177     if (KCalcSettings::calculatorMode() == KCalcSettings::EnumCalculatorMode::numeral) {
2178         KCalcSettings::setShowBitset(toggled);
2179     }
2180     updateGeometry();
2181 
2182     if (!is_still_in_launch_) {
2183         forceResizeEvent();
2184         QApplication::processEvents();
2185         if (wasMinimumSize) {
2186             resize(minimumSize());
2187         }
2188     }
2189 }
2190 
2191 //------------------------------------------------------------------------------
2192 // Name: slotBitsetshow
2193 // Desc: This function is for setting the constant names configured in the
2194 //       kcalc settings menu. If the user doesn't enter a name for the
2195 //       constant C1 to C6 is used.
2196 //------------------------------------------------------------------------------
2197 void KCalculator::changeButtonNames()
2198 {
2199     for (QAbstractButton *btn : std::as_const(const_buttons_)) {
2200         if (auto const constbtn = qobject_cast<KCalcConstButton *>(btn)) {
2201             constbtn->setLabelAndTooltip();
2202         }
2203     }
2204 }
2205 
2206 //------------------------------------------------------------------------------
2207 // Name: slotBitsetChanged
2208 // Desc: updates the bitset display
2209 // NOTE: sets display to *unsigned* value
2210 //------------------------------------------------------------------------------
2211 void KCalculator::slotBitsetChanged(quint64 value)
2212 {
2213     calc_display->setAmount(KNumber(value));
2214     updateDisplay({});
2215 }
2216 
2217 //------------------------------------------------------------------------------
2218 // Name: slotUpdateBitset
2219 // Desc: updates the bitset itself
2220 //------------------------------------------------------------------------------
2221 void KCalculator::slotUpdateBitset(const KNumber &nr)
2222 {
2223     mBitset->setValue(nr.toUint64());
2224 }
2225 
2226 //------------------------------------------------------------------------------
2227 // Name: updateSettings
2228 // Desc: updates the persistent settings
2229 //------------------------------------------------------------------------------
2230 void KCalculator::updateSettings()
2231 {
2232     changeButtonNames();
2233     setColors();
2234     setBaseFont(KCalcSettings::buttonFont());
2235     setFonts();
2236     setPrecision();
2237 
2238     // Show the result in the app's caption in taskbar (wishlist - bug #52858)
2239     disconnect(calc_display, SIGNAL(changedText(QString)), this, nullptr);
2240 
2241     if (KCalcSettings::captionResult()) {
2242         connect(calc_display, &KCalcDisplay::changedText, this, &KCalculator::setWindowTitle);
2243     } else {
2244         setCaption(QString());
2245     }
2246 
2247     calc_display->changeSettings();
2248     calc_history->changeSettings();
2249     updateGeometry();
2250 }
2251 
2252 //------------------------------------------------------------------------------
2253 // Name: updateDisplay
2254 // Desc: updates the display
2255 //------------------------------------------------------------------------------
2256 
2257 void KCalculator::updateDisplay(UpdateFlags flags)
2258 {
2259     if (flags & UPDATE_FROM_CORE) {
2260         calc_display->updateFromCore(core, (flags & UPDATE_STORE_RESULT) != 0);
2261     } else if (flags & UPDATE_MALFORMED_EXPRESSION) {
2262         calc_display->setText(i18n("Input error"));
2263     } else if (flags & UPDATE_CLEAR) {
2264         calc_display->setText(QLatin1String(""));
2265     } else {
2266         calc_display->update();
2267     }
2268 
2269     pbShift->setChecked(false);
2270 }
2271 
2272 //------------------------------------------------------------------------------
2273 // Name: insertToInputDisplay
2274 // Desc: inserts into the input display
2275 //------------------------------------------------------------------------------
2276 
2277 void inline KCalculator::insertToInputDisplay(KCalcToken::TokenCode token)
2278 {
2279     input_display->insertToken(parser.TokenToString(token));
2280 }
2281 
2282 //------------------------------------------------------------------------------
2283 // Name: insertToInputDisplay
2284 // Desc: inserts into the input display
2285 //------------------------------------------------------------------------------
2286 
2287 void inline KCalculator::insertToInputDisplay(const QString &token)
2288 {
2289     input_display->insertToken(token);
2290 }
2291 
2292 //------------------------------------------------------------------------------
2293 // Name: commit_Input_
2294 // Desc: takes string from display and queries parsing, if success, queries calculation
2295 //------------------------------------------------------------------------------
2296 int KCalculator::commit_Input_()
2297 {
2298     int parsing_result, calculation_result;
2299     parsing_result = parser.stringToTokenQueue(input_display->text(), base_mode_, token_Queue_, input_error_index_);
2300 
2301     if (parsing_result != 0) {
2302         parsing_failure_ = true;
2303         return -1;
2304     } else {
2305         parsing_failure_ = false;
2306         calculation_result = core.calculate(token_Queue_, calculation_error_token_index_);
2307         if (calculation_result != 0) {
2308             input_error_index_ = token_Queue_.at(calculation_error_token_index_).getStringIndex();
2309             calculation_failure_ = true;
2310             return -1;
2311         } else {
2312             calculation_failure_ = false;
2313             input_display->end(false);
2314             if (!input_display->text().endsWith(QLatin1String("="))) {
2315                 this->insertToInputDisplay(KCalcToken::TokenCode::EQUAL);
2316             }
2317             input_display->slotSetOverwrite();
2318         }
2319     }
2320     return 0;
2321 }
2322 
2323 //------------------------------------------------------------------------------
2324 // Name: commit_Result_
2325 // Desc: updates result display with last core output, and history if requested
2326 //------------------------------------------------------------------------------
2327 void KCalculator::commit_Result_(bool toHistory /*=true*/)
2328 {
2329     updateResultDisplay();
2330     if (toHistory) {
2331         calc_history->addToHistory(this->input_display->text().toHtmlEscaped(), false);
2332         calc_history->addResultToHistory(calc_display->getAmount().toQString(KCalcSettings::precision()));
2333     }
2334 }
2335 
2336 //------------------------------------------------------------------------------
2337 // Name: handle_Parsing_Error_
2338 // Desc: moves cursor to found error position, when input is empty does nothing
2339 //------------------------------------------------------------------------------
2340 void inline KCalculator::handle_Parsing_Error_()
2341 {
2342     switch (this->parser.getParsingResult()) {
2343     case KCalcParser::INVALID_TOKEN:
2344         input_display->setCursorPosition(input_error_index_);
2345         input_display->setFocus();
2346         updateDisplay(UPDATE_MALFORMED_EXPRESSION);
2347         break;
2348     case KCalcParser::EMPTY:
2349     default:
2350         break;
2351     }
2352 }
2353 
2354 //------------------------------------------------------------------------------
2355 // Name: handle_Calculation_Error_
2356 // Desc: moves cursor to found error position during calculaton
2357 //------------------------------------------------------------------------------
2358 void inline KCalculator::handle_Calculation_Error_()
2359 {
2360     input_display->setCursorPosition(input_error_index_);
2361     input_display->setFocus();
2362     updateDisplay(UPDATE_MALFORMED_EXPRESSION);
2363 }
2364 
2365 //------------------------------------------------------------------------------
2366 // Name: load_Constants_
2367 // Desc: loads science constants into menu and parser.
2368 //------------------------------------------------------------------------------
2369 int KCalculator::load_Constants_(const QString &filePath)
2370 {
2371     QDomDocument doc(QStringLiteral("list_of_constants"));
2372     QFile file(filePath);
2373 
2374     if (!file.open(QIODevice::ReadOnly)) {
2375         qDebug() << "Did not find file \"scienceconstants.xml\". No constants will be available.";
2376         return -1;
2377     }
2378     if (!doc.setContent(&file)) {
2379         file.close();
2380         qDebug() << "The file \"scienceconstants.xml\" does not seem to be a valid description file. No constants will be available.";
2381         return -1;
2382     }
2383     file.close();
2384 
2385     parser.loadConstants(doc);
2386     KCalcConstMenu::init_consts(doc);
2387 
2388     return 0;
2389 }
2390 
2391 //------------------------------------------------------------------------------
2392 // Name: setColors
2393 // Desc: set the various colours
2394 //------------------------------------------------------------------------------
2395 void KCalculator::setColors()
2396 {
2397     calc_display->changeSettings();
2398     calc_history->changeSettings();
2399 
2400     const QColor numFontColor(KCalcSettings::numberFontsColor());
2401     for (int i = 0; i < 10; ++i) {
2402         qobject_cast<KCalcButton *>((num_button_group_->button(i)))->setTextColor(numFontColor);
2403     }
2404 
2405     const QColor funcFontColor(KCalcSettings::functionFontsColor());
2406     for (QAbstractButton *btn : std::as_const(function_button_list_)) {
2407         qobject_cast<KCalcButton *>(btn)->setTextColor(funcFontColor);
2408     }
2409 
2410     const QColor statFontColor(KCalcSettings::statFontsColor());
2411     for (QAbstractButton *btn : std::as_const(stat_buttons_)) {
2412         qobject_cast<KCalcButton *>(btn)->setTextColor(statFontColor);
2413     }
2414 
2415     const QColor hexFontColor(KCalcSettings::hexFontsColor());
2416     for (int i = 10; i < 16; ++i) {
2417         qobject_cast<KCalcButton *>((num_button_group_->button(i)))->setTextColor(hexFontColor);
2418     }
2419 
2420     const QColor memFontColor(KCalcSettings::memoryFontsColor());
2421     for (QAbstractButton *btn : std::as_const(mem_button_list_)) {
2422         qobject_cast<KCalcButton *>(btn)->setTextColor(memFontColor);
2423     }
2424 
2425     const QColor opFontColor(KCalcSettings::operationFontsColor());
2426     for (QAbstractButton *btn : std::as_const(operation_button_list_)) {
2427         qobject_cast<KCalcButton *>(btn)->setTextColor(opFontColor);
2428     }
2429 
2430     const QColor coFontColor(KCalcSettings::constantsFontsColor());
2431     for (QAbstractButton *btn : std::as_const(const_buttons_)) {
2432         qobject_cast<KCalcButton *>(btn)->setTextColor(coFontColor);
2433     }
2434 
2435     KColorScheme schemeButtons(QPalette::Active, KColorScheme::Button);
2436     const QColor defaultColor = schemeButtons.background().color();
2437 
2438     // Do not apply style sheets when using default background colors, see bug #237513
2439     if (KCalcSettings::numberButtonsColor() == defaultColor && KCalcSettings::functionButtonsColor() == defaultColor
2440         && KCalcSettings::statButtonsColor() == defaultColor && KCalcSettings::hexButtonsColor() == defaultColor
2441         && KCalcSettings::memoryButtonsColor() == defaultColor && KCalcSettings::operationButtonsColor() == defaultColor
2442         && KCalcSettings::constantsButtonsColor() == defaultColor) {
2443         return;
2444     }
2445 
2446     const QString sheet = QStringLiteral("QPushButton { background-color: %1 }");
2447 
2448     const QColor numPal(KCalcSettings::numberButtonsColor());
2449     for (int i = 0; i < 10; ++i) {
2450         (num_button_group_->button(i))->setStyleSheet(sheet.arg(numPal.name()));
2451     }
2452 
2453     const QColor funcPal(KCalcSettings::functionButtonsColor());
2454     for (QAbstractButton *btn : std::as_const(function_button_list_)) {
2455         btn->setStyleSheet(sheet.arg(funcPal.name()));
2456     }
2457 
2458     const QColor statPal(KCalcSettings::statButtonsColor());
2459     for (QAbstractButton *btn : std::as_const(stat_buttons_)) {
2460         btn->setStyleSheet(sheet.arg(statPal.name()));
2461     }
2462 
2463     const QColor hexPal(KCalcSettings::hexButtonsColor());
2464     for (int i = 10; i < 16; ++i) {
2465         (num_button_group_->button(i))->setStyleSheet(sheet.arg(hexPal.name()));
2466     }
2467 
2468     const QColor memPal(KCalcSettings::memoryButtonsColor());
2469     for (QAbstractButton *btn : std::as_const(mem_button_list_)) {
2470         btn->setStyleSheet(sheet.arg(memPal.name()));
2471     }
2472 
2473     const QColor opPal(KCalcSettings::operationButtonsColor());
2474     for (QAbstractButton *btn : std::as_const(operation_button_list_)) {
2475         btn->setStyleSheet(sheet.arg(opPal.name()));
2476     }
2477 
2478     const QColor coPal(KCalcSettings::constantsButtonsColor());
2479     for (QAbstractButton *btn : std::as_const(const_buttons_)) {
2480         btn->setStyleSheet(sheet.arg(coPal.name()));
2481     }
2482 }
2483 
2484 //------------------------------------------------------------------------------
2485 // Name: setFonts
2486 // Desc: set the various fonts
2487 //------------------------------------------------------------------------------
2488 void KCalculator::setFonts()
2489 {
2490     // Get the font selected in the settings
2491     QFont buttonFont = baseFont();
2492 
2493     // Step 1: Gather the minimum button width and height of all buttons
2494 
2495     int minButtonWidth = INT_MAX;
2496     int minButtonHeight = INT_MAX;
2497 
2498     const auto leftPadLst = leftPad->children();
2499     for (QObject *obj : leftPadLst) {
2500         if (auto const button = qobject_cast<KCalcButton *>(obj)) {
2501             if (button->isVisible()) {
2502                 if (button->width() < minButtonWidth)
2503                     minButtonWidth = button->width();
2504                 if (button->height() < minButtonHeight)
2505                     minButtonHeight = button->height();
2506             }
2507         }
2508     }
2509 
2510     const auto numericPadLst = numericPad->children();
2511     for (QObject *obj : numericPadLst) {
2512         if (auto const button = qobject_cast<KCalcButton *>(obj)) {
2513             if (button->isVisible()) {
2514                 if (button->width() < minButtonWidth)
2515                     minButtonWidth = button->width();
2516                 if (button->height() < minButtonHeight)
2517                     minButtonHeight = button->height();
2518             }
2519         }
2520     }
2521 
2522     const auto rightPadLst = rightPad->children();
2523     for (QObject *obj : rightPadLst) {
2524         if (auto const button = qobject_cast<KCalcButton *>(obj)) {
2525             if (button->isVisible() && button != pbShift) {
2526                 if (button->width() < minButtonWidth)
2527                     minButtonWidth = button->width();
2528                 if (button->height() < minButtonHeight)
2529                     minButtonHeight = button->height();
2530             }
2531         }
2532     }
2533 
2534     // Step 2: If step 1 worked, calculate new font size
2535 
2536     if (!(minButtonWidth == INT_MAX || minButtonHeight == INT_MAX)) {
2537 
2538         // Calculate new font size. Use the font size from the settings as minimum font size.
2539         // Please note these constants are arbitrarily chosen for lack of a better solution.
2540         // If issues with scaling arise (due to abnormally wide/tall fonts), increase them to compensate.
2541         buttonFont.setPointSizeF(qMax(KCalcSettings::buttonFont().pointSizeF(), qMin(minButtonWidth / 4.8, minButtonHeight / 3.6)));
2542         
2543     }
2544 
2545     // Step 3: Apply the new font (and size) to all buttons.
2546 
2547     for (QObject *obj : leftPadLst) {
2548         if (auto const button = qobject_cast<KCalcButton *>(obj)) {
2549             button->setFont(buttonFont);
2550         }
2551     }
2552 
2553     for (QObject *obj : numericPadLst) {
2554         if (auto const button = qobject_cast<KCalcButton *>(obj)) {
2555             button->setFont(buttonFont);
2556         }
2557     }
2558 
2559     for (QObject *obj : rightPadLst) {
2560         if (auto const button = qobject_cast<KCalcButton *>(obj)) {
2561             button->setFont(buttonFont);
2562         }
2563     }
2564 }
2565 
2566 //------------------------------------------------------------------------------
2567 // Name: setBaseFont
2568 // Desc: set the base font
2569 //------------------------------------------------------------------------------
2570 void KCalculator::setBaseFont(const QFont &font)
2571 {
2572     // Overwrite current baseFont
2573     baseFont_ = font;
2574 }
2575 
2576 //------------------------------------------------------------------------------
2577 // Name: baseFont
2578 // Desc: get the base font
2579 //------------------------------------------------------------------------------
2580 const QFont& KCalculator::baseFont() const
2581 {
2582     return baseFont_;
2583 }
2584 
2585 //------------------------------------------------------------------------------
2586 // Name: isMinimumSize
2587 // Desc: Is KCalc currently at minimum size?
2588 //------------------------------------------------------------------------------
2589 bool KCalculator::isMinimumSize()
2590 {
2591     QSize contentSize = KCalculator::contentsRect().size();
2592     QMargins contentMargins = KCalculator::contentsMargins();
2593     QSize actualSize(contentSize.width() + contentMargins.left() + contentMargins.right(),
2594                      contentSize.height() + contentMargins.top() + contentMargins.bottom());
2595     QSize minSize = KCalculator::minimumSize();
2596     return actualSize == minSize;
2597 }
2598 
2599 //------------------------------------------------------------------------------
2600 // Name: forceResizeEvent
2601 // Desc: Force a resize event with no size changes
2602 //------------------------------------------------------------------------------
2603 void KCalculator::forceResizeEvent()
2604 {
2605     QApplication::postEvent(this, new QResizeEvent(size(), size()));
2606 }
2607 
2608 //------------------------------------------------------------------------------
2609 // Name: setLeftPadLayoutActive
2610 // Desc: Enable/disable whether leftPad affects the layout
2611 //------------------------------------------------------------------------------
2612 void KCalculator::setLeftPadLayoutActive(bool active)
2613 {
2614     leftPad->setVisible(active);
2615 }
2616 
2617 //------------------------------------------------------------------------------
2618 // Name: setBitsetLayoutActive
2619 // Desc: Enable/disable whether mBitset affects the layout
2620 //------------------------------------------------------------------------------
2621 void KCalculator::setBitsetLayoutActive(bool active)
2622 {
2623     firstVerticalLayout->setStretch(1, (int)active); // 0 or 1
2624 }
2625 
2626 //------------------------------------------------------------------------------
2627 // Name: event
2628 // Desc: catch application's palette and font change events
2629 //------------------------------------------------------------------------------
2630 bool KCalculator::event(QEvent *e)
2631 {
2632     switch (e->type()) {
2633     case QEvent::ApplicationFontChange:
2634         setBaseFont(KCalcSettings::buttonFont());
2635         setFonts();
2636         updateGeometry();
2637         break;
2638     case QEvent::ApplicationPaletteChange:
2639         setColors();
2640         break;
2641     default:
2642         break;
2643     }
2644     return KXmlGuiWindow::event(e);
2645 }
2646 
2647 //------------------------------------------------------------------------------
2648 // Name: setPrecision
2649 // Desc: set the precision of the display
2650 //------------------------------------------------------------------------------
2651 void KCalculator::setPrecision()
2652 {
2653     KNumber::setDefaultFloatPrecision(KCalcSettings::precision());
2654     updateDisplay({});
2655 }
2656 
2657 //------------------------------------------------------------------------------
2658 // Name: setAngle
2659 // Desc: sets the angle mode
2660 //------------------------------------------------------------------------------
2661 void KCalculator::setAngle()
2662 {
2663     if (QAbstractButton *const btn = angle_choose_group_->button(KCalcSettings::angleMode())) {
2664         btn->click();
2665         Q_EMIT(slotAngleSelected(btn, true));
2666     }
2667 }
2668 
2669 //------------------------------------------------------------------------------
2670 // Name: setBase
2671 // Desc: sets the numeric base
2672 //------------------------------------------------------------------------------
2673 void KCalculator::setBase()
2674 {
2675     if (QAbstractButton *const btn = base_choose_group_->button(KCalcSettings::baseMode())) {
2676         btn->animateClick();
2677     }
2678 }
2679 
2680 //------------------------------------------------------------------------------
2681 // Name: eventFilter
2682 // Desc: general event filter used to track events like drag/drop
2683 //------------------------------------------------------------------------------
2684 bool KCalculator::eventFilter(QObject *o, QEvent *e)
2685 {
2686     switch (e->type()) {
2687     case QEvent::DragEnter: {
2688         auto const ev = reinterpret_cast<QDragEnterEvent *>(e);
2689         ev->setAccepted(KColorMimeData::canDecode(ev->mimeData()));
2690         return true;
2691     }
2692     case QEvent::DragLeave: {
2693         return true;
2694     }
2695     case QEvent::Drop: {
2696         auto const calcButton = qobject_cast<KCalcButton *>(o);
2697         if (!calcButton) {
2698             return false;
2699         }
2700 
2701         auto const ev = reinterpret_cast<QDropEvent *>(e);
2702         QColor c = KColorMimeData::fromMimeData(ev->mimeData());
2703 
2704         if (c.isValid()) {
2705             QString cn = c.name();
2706             QString sheet = QStringLiteral("background-color: %1");
2707 
2708             QList<QAbstractButton *> *list;
2709             const int num_but = num_button_group_->buttons().indexOf(calcButton);
2710             if (num_but != -1) {
2711                 // Was it hex-button or normal digit??
2712                 if (num_but < 10) {
2713                     for (int i = 0; i < 10; ++i) {
2714                         (num_button_group_->buttons().at(i))->setStyleSheet(sheet.arg(cn));
2715                     }
2716                 } else {
2717                     for (int i = 10; i < 16; ++i) {
2718                         (num_button_group_->buttons().at(i))->setStyleSheet(sheet.arg(cn));
2719                     }
2720                 }
2721                 return true;
2722             } else if (function_button_list_.contains(calcButton)) {
2723                 list = &function_button_list_;
2724             } else if (stat_button_list_.contains(calcButton)) {
2725                 list = &stat_button_list_;
2726             } else if (mem_button_list_.contains(calcButton)) {
2727                 list = &mem_button_list_;
2728             } else if (operation_button_list_.contains(calcButton)) {
2729                 list = &operation_button_list_;
2730             } else {
2731                 return false;
2732             }
2733 
2734             for (int i = 0; i < list->size(); ++i) {
2735                 list->at(i)->setStyleSheet(sheet.arg(cn));
2736             }
2737         }
2738         return true;
2739     }
2740     // FALL THROUGH
2741     default:
2742         return KXmlGuiWindow::eventFilter(o, e);
2743     }
2744 }
2745 
2746 //------------------------------------------------------------------------------
2747 // Name: slotPaste
2748 // Desc: paste a number from the clipboard
2749 //------------------------------------------------------------------------------
2750 void KCalculator::slotPaste()
2751 {
2752     input_display->paste();
2753 }
2754 
2755 //------------------------------------------------------------------------------
2756 // Name: resizeEvent
2757 // Desc: resize window and make sure it's large enough for its content
2758 //------------------------------------------------------------------------------
2759 void KCalculator::resizeEvent(QResizeEvent* event)
2760 {
2761     // Call the overridden resize event
2762     KXmlGuiWindow::resizeEvent(event);
2763 
2764     updateGeometry();
2765 
2766     // If the content size is now larger than the window size, resize window to fit
2767     QSize actualSize = KCalculator::size();
2768     QSize minSize = KCalculator::minimumSize();
2769     if (actualSize.width() < minSize.width() || actualSize.height() < minSize.height()) {
2770         KCalculator::resize(minSize); // force window as small as possible for current layout
2771     }
2772 
2773     // Adjust button fonts
2774     setFonts();
2775 
2776     // Force mBitset to call its resizeEvent
2777     mBitset->resize(0, 0);
2778 }
2779 
2780 
2781 ////////////////////////////////////////////////////////////////
2782 // Include the meta-object code for classes in this file
2783 //
2784 
2785 //------------------------------------------------------------------------------
2786 // Name: main
2787 // Desc: entry point of the application
2788 //------------------------------------------------------------------------------
2789 int main(int argc, char *argv[])
2790 {
2791     QApplication app(argc, argv);
2792 
2793     KLocalizedString::setApplicationDomain(QByteArrayLiteral("kcalc"));
2794     KCrash::initialize();
2795     KAboutData aboutData(QStringLiteral("kcalc"),
2796                          i18n("KCalc"),
2797                          QStringLiteral(KCALC_VERSION_STRING),
2798                          i18n("KDE Calculator"),
2799                          KAboutLicense::GPL,
2800                          i18n("Copyright © 2008-2013, Evan Teran\n"
2801                               "Copyright © 2000-2008, The KDE Team\n"
2802                               "Copyright © 2003-2005, Klaus Niederkr"
2803                               "\xc3\xbc"
2804                               "ger\n"
2805                               "Copyright © 1996-2000, Bernd Johannes Wuebben"),
2806                          QString(),
2807                          QStringLiteral("https://apps.kde.org/kcalc/"));
2808 
2809     // Klaus Niederkrueger
2810     aboutData.addAuthor(i18n("Klaus Niederkr"
2811                              "\xc3\xbc"
2812                              "ger"),
2813                         QString(),
2814                         QStringLiteral("kniederk@math.uni-koeln.de"));
2815     aboutData.addAuthor(i18n("Bernd Johannes Wuebben"), QString(), QStringLiteral("wuebben@kde.org"));
2816     aboutData.addAuthor(i18n("Evan Teran"), i18n("Maintainer"), QStringLiteral("eteran@alum.rit.edu"));
2817     aboutData.addAuthor(i18n("Espen Sand"), QString(), QStringLiteral("espen@kde.org"));
2818     aboutData.addAuthor(i18n("Chris Howells"), QString(), QStringLiteral("howells@kde.org"));
2819     aboutData.addAuthor(i18n("Aaron J. Seigo"), QString(), QStringLiteral("aseigo@olympusproject.org"));
2820     aboutData.addAuthor(i18n("Charles Samuels"), QString(), QStringLiteral("charles@altair.dhs.org"));
2821     // Rene Merou
2822     aboutData.addAuthor(i18n("Ren"
2823                              "\xc3\xa9"
2824                              " M"
2825                              "\xc3\xa9"
2826                              "rou"),
2827                         QString(),
2828                         QStringLiteral("ochominutosdearco@yahoo.es"));
2829     aboutData.addAuthor(i18n("Michel Marti"), QString(), QStringLiteral("mma@objectxp.com"));
2830     aboutData.addAuthor(i18n("David Johnson"), QString(), QStringLiteral("david@usermode.org"));
2831     aboutData.addAuthor(i18n("Niklas Freund"), QString(), QStringLiteral("nalquas.dev@gmail.com"));
2832 
2833     KAboutData::setApplicationData(aboutData);
2834     app.setWindowIcon(QIcon::fromTheme(QStringLiteral("accessories-calculator"), app.windowIcon()));
2835 
2836     QCommandLineParser parser;
2837     aboutData.setupCommandLine(&parser);
2838     parser.process(app);
2839     aboutData.processCommandLine(&parser);
2840 
2841     // Force system locale to "C" internally. Fix for bug #159168, showing multiple commas
2842     // in floating point operations because of different thousands separator and comma separator.
2843     setlocale(LC_NUMERIC, "C");
2844 
2845     KNumber::setGroupSeparator(QLocale().groupSeparator());
2846     KNumber::setDecimalSeparator(QString(QLocale().decimalPoint()));
2847 
2848     auto calc = new KCalculator(nullptr);
2849 
2850     calc->show();
2851     return app.exec();
2852 }
2853 
2854 #include "moc_kcalc.cpp"