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