File indexing completed on 2024-03-24 05:52:56
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>√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("Γ"), 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("√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("σ") + 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"