1 | /* |
2 | SPDX-FileCopyrightText: 2001-2013 Evan Teran <evan.teran@gmail.com> |
3 | SPDX-FileCopyrightText: 2006 Michel Marti <mma@objectxp.com> |
4 | SPDX-FileCopyrightText: 1996-2000 Bernd Johannes Wuebben <wuebben@kde.org> |
5 | |
6 | SPDX-License-Identifier: GPL-2.0-or-later |
7 | */ |
8 | |
9 | #include "kcalc.h" |
10 | #include "kcalc_version.h" |
11 | |
12 | #include <clocale> |
13 | |
14 | #include <QActionGroup> |
15 | #include <QApplication> |
16 | #include <QButtonGroup> |
17 | #include <QCommandLineParser> |
18 | #include <QCursor> |
19 | #include <QKeyEvent> |
20 | #include <QMenuBar> |
21 | #include <QShortcut> |
22 | #include <QStyle> |
23 | |
24 | #include <KAboutData> |
25 | #include <KAcceleratorManager> |
26 | #include <KActionCollection> |
27 | #include <KColorMimeData> |
28 | #include <KConfigDialog> |
29 | #include <KCrash> |
30 | #include <KStandardAction> |
31 | #include <KToggleAction> |
32 | #include <KToolBar> |
33 | #include <KXMLGUIFactory> |
34 | |
35 | #include "kcalc_bitset.h" |
36 | #include "kcalc_const_menu.h" |
37 | #include "kcalc_settings.h" |
38 | #include "kcalc_statusbar.h" |
39 | #include "kcalcdisplay.h" |
40 | #include "kcalchistory.h" |
41 | |
42 | namespace |
43 | { |
44 | const int maxprecision = 1000; |
45 | } |
46 | |
47 | //------------------------------------------------------------------------------ |
48 | // Name: KCalculator |
49 | // Desc: constructor |
50 | //------------------------------------------------------------------------------ |
51 | KCalculator::KCalculator(QWidget *parent) |
52 | : KXmlGuiWindow(parent) |
53 | , memory_num_(0.0) |
54 | , core() |
55 | { |
56 | // central widget to contain all the elements |
57 | auto const central = new QWidget(this); |
58 | central->setLayoutDirection(Qt::LeftToRight); |
59 | setCentralWidget(central); |
60 | KAcceleratorManager::setNoAccel(central); |
61 | |
62 | setAutoSaveSettings(group: QStringLiteral("KCalcMainWindow" )); |
63 | |
64 | // load science constants_ from xml-file |
65 | KCalcConstMenu::init_consts(); |
66 | |
67 | // setup interface (order is critical) |
68 | setupUi(central); |
69 | setupMainActions(); |
70 | setStatusBar(new KCalcStatusBar(this)); |
71 | createGUI(); |
72 | setupKeys(); |
73 | |
74 | toolBar()->hide(); // hide by default |
75 | |
76 | // create button groups |
77 | base_choose_group_ = new QButtonGroup(this); |
78 | base_choose_group_->setExclusive(true); |
79 | base_choose_group_->addButton(hexRadio, HexMode); |
80 | base_choose_group_->addButton(decRadio, DecMode); |
81 | base_choose_group_->addButton(octRadio, OctMode); |
82 | base_choose_group_->addButton(binRadio, BinMode); |
83 | connect(base_choose_group_, &QButtonGroup::buttonClicked, this, &KCalculator::slotBaseSelected); |
84 | |
85 | base_conversion_labels_ = {binDisplay, hexDisplay, decDisplay, octDisplay}; |
86 | |
87 | angle_choose_group_ = new QButtonGroup(this); |
88 | angle_choose_group_-> |
89 | setExclusive(true); |
90 | angle_choose_group_->addButton(degRadio, DegMode); |
91 | angle_choose_group_->addButton(radRadio, RadMode); |
92 | angle_choose_group_->addButton(gradRadio, GradMode); |
93 | connect(angle_choose_group_, &QButtonGroup::buttonClicked, this, &KCalculator::slotAngleSelected); |
94 | |
95 | // additional menu setup |
96 | constants_menu_ = createConstantsMenu(); |
97 | menuBar()->insertMenu((menuBar()->actions)()[2], constants_menu_); |
98 | |
99 | // misc setup |
100 | setColors(); |
101 | setBaseFont(KCalcSettings::buttonFont()); |
102 | setFonts(); |
103 | |
104 | // Show the result in the app's caption in taskbar (wishlist - bug #52858) |
105 | if (KCalcSettings::captionResult()) { |
106 | connect(calc_display, &KCalcDisplay::changedText, this, &KCalculator::setWindowTitle); |
107 | } |
108 | |
109 | calc_display->changeSettings(); |
110 | calc_history->changeSettings(); |
111 | update_history_window_ = true; |
112 | setPrecision(); |
113 | |
114 | updateGeometry(); |
115 | |
116 | updateDisplay(UPDATE_FROM_CORE); |
117 | // clear history, otherwise we have a leading "0" in it |
118 | calc_history->clearHistory(); |
119 | |
120 | // misc settings |
121 | KCalcSettings::EnumCalculatorMode::type calculatorMode = KCalcSettings::calculatorMode(); |
122 | |
123 | switch (calculatorMode) { |
124 | case KCalcSettings::EnumCalculatorMode::science: |
125 | action_mode_science_->setChecked(true); |
126 | break; |
127 | case KCalcSettings::EnumCalculatorMode::statistics: |
128 | action_mode_statistic_->setChecked(true); |
129 | break; |
130 | case KCalcSettings::EnumCalculatorMode::numeral: |
131 | action_mode_numeral_->setChecked(true); |
132 | break; |
133 | case KCalcSettings::EnumCalculatorMode::simple: |
134 | default: |
135 | action_mode_simple_->setChecked(true); |
136 | } |
137 | is_still_in_launch_ = false; |
138 | |
139 | setAngle(); |
140 | setBase(); |
141 | |
142 | calc_display->setFocus(); |
143 | } |
144 | |
145 | //------------------------------------------------------------------------------ |
146 | // Name: ~KCalculator |
147 | // Desc: deconstructor |
148 | //------------------------------------------------------------------------------ |
149 | KCalculator::~KCalculator() |
150 | { |
151 | KCalcSettings::self()->save(); |
152 | } |
153 | |
154 | //------------------------------------------------------------------------------ |
155 | // Name: setupMainActions |
156 | // Desc: connects all of the basic actions |
157 | //------------------------------------------------------------------------------ |
158 | void KCalculator::setupMainActions() |
159 | { |
160 | // file menu |
161 | KStandardAction::quit(this, SLOT(close()), actionCollection()); |
162 | |
163 | // edit menu |
164 | KStandardAction::undo(calc_display, SLOT(slotHistoryBack()), actionCollection()); |
165 | KStandardAction::redo(calc_display, SLOT(slotHistoryForward()), actionCollection()); |
166 | KStandardAction::cut(calc_display, SLOT(slotCut()), actionCollection()); |
167 | KStandardAction::copy(calc_display, SLOT(slotCopy()), actionCollection()); |
168 | KStandardAction::paste(this, SLOT(slotPaste()), actionCollection()); |
169 | |
170 | // mode menu |
171 | auto modeGroup = new QActionGroup(this); |
172 | |
173 | action_mode_simple_ = actionCollection()->add<KToggleAction>(QStringLiteral("mode_simple" )); |
174 | action_mode_simple_->setActionGroup(modeGroup); |
175 | action_mode_simple_->setText(i18n("Simple Mode" )); |
176 | connect(action_mode_simple_, &KToggleAction::toggled, this, &KCalculator::slotSetSimpleMode); |
177 | |
178 | action_mode_science_ = actionCollection()->add<KToggleAction>(QStringLiteral("mode_science" )); |
179 | action_mode_science_->setActionGroup(modeGroup); |
180 | action_mode_science_->setText(i18n("Science Mode" )); |
181 | connect(action_mode_science_, &KToggleAction::toggled, this, &KCalculator::slotSetScienceMode); |
182 | |
183 | action_mode_statistic_ = actionCollection()->add<KToggleAction>(QStringLiteral("mode_statistics" )); |
184 | action_mode_statistic_->setActionGroup(modeGroup); |
185 | action_mode_statistic_->setText(i18n("Statistic Mode" )); |
186 | connect(action_mode_statistic_, &KToggleAction::toggled, this, &KCalculator::slotSetStatisticMode); |
187 | |
188 | action_mode_numeral_ = actionCollection()->add<KToggleAction>(QStringLiteral("mode_numeral" )); |
189 | action_mode_numeral_->setActionGroup(modeGroup); |
190 | action_mode_numeral_->setText(i18n("Numeral System Mode" )); |
191 | connect(action_mode_numeral_, &KToggleAction::toggled, this, &KCalculator::slotSetNumeralMode); |
192 | |
193 | // settings menu |
194 | action_history_show_ = actionCollection()->add<KToggleAction>(QStringLiteral("show_history" )); |
195 | action_history_show_->setText(i18n("Show &History" )); |
196 | action_history_show_->setChecked(true); |
197 | actionCollection()->setDefaultShortcut(action_history_show_, Qt::CTRL | Qt::Key_H); |
198 | connect(action_history_show_, &KToggleAction::toggled, this, &KCalculator::slotHistoryshow); |
199 | |
200 | action_constants_show_ = actionCollection()->add<KToggleAction>(QStringLiteral("show_constants" )); |
201 | action_constants_show_->setText(i18n("Constants &Buttons" )); |
202 | action_constants_show_->setChecked(true); |
203 | connect(action_constants_show_, &KToggleAction::toggled, this, &KCalculator::slotConstantsShow); |
204 | |
205 | action_bitset_show_ = actionCollection()->add<KToggleAction>(QStringLiteral("show_bitset" )); |
206 | action_bitset_show_->setText(i18n("Show B&it Edit" )); |
207 | action_bitset_show_->setChecked(true); |
208 | connect(action_bitset_show_, &KToggleAction::toggled, this, &KCalculator::slotBitsetshow); |
209 | |
210 | KStandardAction::preferences(this, &KCalculator::showSettings, actionCollection()); |
211 | |
212 | KStandardAction::keyBindings(guiFactory(), &KXMLGUIFactory::showConfigureShortcutsDialog, actionCollection()); |
213 | } |
214 | |
215 | //------------------------------------------------------------------------------ |
216 | // Name: createConstantsMenu |
217 | // Desc: creates and returns a pointer to the constant menu |
218 | //------------------------------------------------------------------------------ |
219 | KCalcConstMenu *KCalculator::() |
220 | { |
221 | auto const = new KCalcConstMenu(i18n("&Constants" ), this); |
222 | connect(menu, &KCalcConstMenu::triggeredConstant, this, &KCalculator::slotConstantToDisplay); |
223 | return menu; |
224 | } |
225 | |
226 | //------------------------------------------------------------------------------ |
227 | // Name: statusBar |
228 | // Desc: returns a pointer to the status bar |
229 | //------------------------------------------------------------------------------ |
230 | KCalcStatusBar *KCalculator::statusBar() |
231 | { |
232 | return static_cast<KCalcStatusBar *>(KXmlGuiWindow::statusBar()); |
233 | } |
234 | |
235 | //------------------------------------------------------------------------------ |
236 | // Name: setupNumberKeys |
237 | // Desc: sets up number keys and related shortcuts |
238 | //------------------------------------------------------------------------------ |
239 | void KCalculator::setupNumberKeys() |
240 | { |
241 | num_button_group_ = new QButtonGroup(this); |
242 | connect(num_button_group_, &QButtonGroup::buttonClicked, this, &KCalculator::slotNumberclicked); |
243 | |
244 | num_button_group_->addButton(pb0, 0); |
245 | num_button_group_->addButton(pb1, 1); |
246 | num_button_group_->addButton(pb2, 2); |
247 | num_button_group_->addButton(pb3, 3); |
248 | num_button_group_->addButton(pb4, 4); |
249 | num_button_group_->addButton(pb5, 5); |
250 | num_button_group_->addButton(pb6, 6); |
251 | num_button_group_->addButton(pb7, 7); |
252 | num_button_group_->addButton(pb8, 8); |
253 | num_button_group_->addButton(pb9, 9); |
254 | num_button_group_->addButton(pbA, 0xA); |
255 | num_button_group_->addButton(pbB, 0xB); |
256 | num_button_group_->addButton(pbC, 0xC); |
257 | num_button_group_->addButton(pbD, 0xD); |
258 | num_button_group_->addButton(pbE, 0xE); |
259 | num_button_group_->addButton(pbF, 0xF); |
260 | connect(this, &KCalculator::switchShowAccels, pb0, &KCalcButton::slotSetAccelDisplayMode); |
261 | connect(this, &KCalculator::switchShowAccels, pb1, &KCalcButton::slotSetAccelDisplayMode); |
262 | connect(this, &KCalculator::switchShowAccels, pb2, &KCalcButton::slotSetAccelDisplayMode); |
263 | connect(this, &KCalculator::switchShowAccels, pb3, &KCalcButton::slotSetAccelDisplayMode); |
264 | connect(this, &KCalculator::switchShowAccels, pb4, &KCalcButton::slotSetAccelDisplayMode); |
265 | connect(this, &KCalculator::switchShowAccels, pb5, &KCalcButton::slotSetAccelDisplayMode); |
266 | connect(this, &KCalculator::switchShowAccels, pb6, &KCalcButton::slotSetAccelDisplayMode); |
267 | connect(this, &KCalculator::switchShowAccels, pb7, &KCalcButton::slotSetAccelDisplayMode); |
268 | connect(this, &KCalculator::switchShowAccels, pb8, &KCalcButton::slotSetAccelDisplayMode); |
269 | connect(this, &KCalculator::switchShowAccels, pb9, &KCalcButton::slotSetAccelDisplayMode); |
270 | connect(this, &KCalculator::switchShowAccels, pbA, &KCalcButton::slotSetAccelDisplayMode); |
271 | connect(this, &KCalculator::switchShowAccels, pbB, &KCalcButton::slotSetAccelDisplayMode); |
272 | connect(this, &KCalculator::switchShowAccels, pbC, &KCalcButton::slotSetAccelDisplayMode); |
273 | connect(this, &KCalculator::switchShowAccels, pbD, &KCalcButton::slotSetAccelDisplayMode); |
274 | connect(this, &KCalculator::switchShowAccels, pbE, &KCalcButton::slotSetAccelDisplayMode); |
275 | connect(this, &KCalculator::switchShowAccels, pbF, &KCalcButton::slotSetAccelDisplayMode); |
276 | } |
277 | |
278 | //------------------------------------------------------------------------------ |
279 | // Name: setupRightKeypad |
280 | // Desc: sets up right keypad keys and related shortcuts |
281 | //------------------------------------------------------------------------------ |
282 | void KCalculator::setupRightKeypad() |
283 | { |
284 | connect(pbShift, &KCalcButton::toggled, this, &KCalculator::slotShifttoggled); |
285 | connect(this, &KCalculator::switchShowAccels, pbShift, &KCalcButton::slotSetAccelDisplayMode); |
286 | |
287 | pbBackspace->setShortcut(QKeySequence(Qt::Key_Backspace)); |
288 | new QShortcut(Qt::Key_PageUp, pbBackspace, SLOT(animateClick())); |
289 | connect(pbBackspace, &KCalcButton::clicked, this, &KCalculator::slotBackspaceclicked); |
290 | connect(this, &KCalculator::switchShowAccels, pbBackspace, &KCalcButton::slotSetAccelDisplayMode); |
291 | |
292 | pbClear->setShortcut(QKeySequence(Qt::Key_Escape)); |
293 | new QShortcut(Qt::Key_PageUp, pbClear, SLOT(animateClick())); |
294 | connect(pbClear, &KCalcButton::clicked, this, &KCalculator::slotClearclicked); |
295 | connect(this, &KCalculator::switchShowAccels, pbClear, &KCalcButton::slotSetAccelDisplayMode); |
296 | |
297 | pbAllClear->setShortcut(QKeySequence(Qt::Key_Delete)); |
298 | new QShortcut(Qt::Key_PageDown, pbAllClear, SLOT(animateClick())); |
299 | connect(pbAllClear, &KCalcButton::clicked, this, &KCalculator::slotAllClearclicked); |
300 | connect(this, &KCalculator::switchShowAccels, pbAllClear, &KCalcButton::slotSetAccelDisplayMode); |
301 | // also clear the content of the history when clicked |
302 | connect(pbAllClear, &KCalcButton::clicked, calc_history, &KCalcHistory::clearHistory); |
303 | |
304 | pbParenOpen->setShortcut(QKeySequence(Qt::Key_ParenLeft)); |
305 | connect(pbParenOpen, &KCalcButton::clicked, this, &KCalculator::slotParenOpenclicked); |
306 | connect(this, &KCalculator::switchShowAccels, pbParenOpen, &KCalcButton::slotSetAccelDisplayMode); |
307 | |
308 | pbParenClose->setShortcut(QKeySequence(Qt::Key_ParenRight)); |
309 | connect(pbParenClose, &KCalcButton::clicked, this, &KCalculator::slotParenCloseclicked); |
310 | connect(this, &KCalculator::switchShowAccels, pbParenClose, &KCalcButton::slotSetAccelDisplayMode); |
311 | |
312 | pbMemRecall->setDisabled(true); // nothing in memory at start |
313 | connect(pbMemRecall, &KCalcButton::clicked, this, &KCalculator::slotMemRecallclicked); |
314 | connect(this, &KCalculator::switchShowAccels, pbMemRecall, &KCalcButton::slotSetAccelDisplayMode); |
315 | |
316 | connect(pbMemClear, &KCalcButton::clicked, this, &KCalculator::slotMemClearclicked); |
317 | connect(this, &KCalculator::switchShowAccels, pbMemClear, &KCalcButton::slotSetAccelDisplayMode); |
318 | |
319 | pbMemPlusMinus->addMode(ModeNormal, i18nc("Add display to memory" , "M+" ), i18n("Add display to memory" )); |
320 | pbMemPlusMinus->addMode(ModeShift, i18nc("Subtract from memory" , "M\xe2\x88\x92" ), i18n("Subtract from memory" )); |
321 | connect(pbMemPlusMinus, &KCalcButton::clicked, this, &KCalculator::slotMemPlusMinusclicked); |
322 | connect(this, &KCalculator::switchShowAccels, pbMemPlusMinus, &KCalcButton::slotSetAccelDisplayMode); |
323 | connect(this, &KCalculator::switchMode, pbMemPlusMinus, &KCalcButton::slotSetMode); |
324 | |
325 | connect(pbMemStore, &KCalcButton::clicked, this, &KCalculator::slotMemStoreclicked); |
326 | connect(this, &KCalculator::switchShowAccels, pbMemStore, &KCalcButton::slotSetAccelDisplayMode); |
327 | |
328 | pbPercent->setShortcut(QKeySequence(Qt::Key_Percent)); |
329 | connect(pbPercent, &KCalcButton::clicked, this, &KCalculator::slotPercentclicked); |
330 | connect(this, &KCalculator::switchShowAccels, pbPercent, &KCalcButton::slotSetAccelDisplayMode); |
331 | |
332 | pbPlusMinus->setShortcut(QKeySequence(Qt::Key_Backslash)); |
333 | connect(pbPlusMinus, &KCalcButton::clicked, this, &KCalculator::slotPlusMinusclicked); |
334 | connect(this, &KCalculator::switchShowAccels, pbPlusMinus, &KCalcButton::slotSetAccelDisplayMode); |
335 | } |
336 | |
337 | //------------------------------------------------------------------------------ |
338 | // Name: setupNumericKeypad |
339 | // Desc: sets up numeric keys and related shortcuts |
340 | //------------------------------------------------------------------------------ |
341 | void KCalculator::setupNumericKeypad() |
342 | { |
343 | pbCube->addMode(ModeNormal, i18nc("Third power" , "x<sup>3</sup>" ), i18n("Third power" )); |
344 | pbCube->addMode(ModeShift, QStringLiteral("<sup>3</sup>√x" ), i18n("Cube root" )); |
345 | connect(pbCube, &KCalcButton::clicked, this, &KCalculator::slotCubeclicked); |
346 | connect(this, &KCalculator::switchShowAccels, pbCube, &KCalcButton::slotSetAccelDisplayMode); |
347 | connect(this, &KCalculator::switchMode, pbCube, &KCalcButton::slotSetMode); |
348 | |
349 | pbDivision->setShortcut(QKeySequence(Qt::Key_Slash)); |
350 | new QShortcut(Qt::Key_division, pbDivision, SLOT(animateClick())); |
351 | connect(pbDivision, &KCalcButton::clicked, this, &KCalculator::slotDivisionclicked); |
352 | connect(this, &KCalculator::switchShowAccels, pbDivision, &KCalcButton::slotSetAccelDisplayMode); |
353 | |
354 | pbMultiplication->setShortcut(QKeySequence(Qt::Key_Asterisk)); |
355 | new QShortcut(Qt::Key_X, pbMultiplication, SLOT(animateClick())); |
356 | new QShortcut(Qt::Key_multiply, pbMultiplication, SLOT(animateClick())); |
357 | connect(pbMultiplication, &KCalcButton::clicked, this, &KCalculator::slotMultiplicationclicked); |
358 | connect(this, &KCalculator::switchShowAccels, pbMultiplication, &KCalcButton::slotSetAccelDisplayMode); |
359 | |
360 | pbMinus->setShortcut(QKeySequence(Qt::Key_Minus)); |
361 | connect(pbMinus, &KCalcButton::clicked, this, &KCalculator::slotMinusclicked); |
362 | connect(this, &KCalculator::switchShowAccels, pbMinus, &KCalcButton::slotSetAccelDisplayMode); |
363 | |
364 | pbPlus->setShortcut(QKeySequence(Qt::Key_Plus)); |
365 | connect(pbPlus, &KCalcButton::clicked, this, &KCalculator::slotPlusclicked); |
366 | connect(this, &KCalculator::switchShowAccels, pbPlus, &KCalcButton::slotSetAccelDisplayMode); |
367 | |
368 | // set decimal separator from locale |
369 | pbPeriod->setText(QString(QLocale().decimalPoint())); |
370 | pbPeriod->setShortcut(QString(QLocale().decimalPoint())); |
371 | |
372 | // add shortcut for the other decimal separator (point or comma) |
373 | if (QLocale().decimalPoint() == QLatin1Char('.')) { |
374 | new QShortcut(Qt::Key_Comma, pbPeriod, SLOT(animateClick())); |
375 | } else if (QLocale().decimalPoint() == QLatin1Char(',')) { |
376 | new QShortcut(Qt::Key_Period, pbPeriod, SLOT(animateClick())); |
377 | } |
378 | |
379 | connect(pbPeriod, &KCalcButton::clicked, this, &KCalculator::slotPeriodclicked); |
380 | connect(this, &KCalculator::switchShowAccels, pbPeriod, &KCalcButton::slotSetAccelDisplayMode); |
381 | |
382 | pbEqual->setShortcut(QKeySequence(Qt::Key_Enter)); |
383 | new QShortcut(Qt::Key_Equal, pbEqual, SLOT(animateClick())); |
384 | new QShortcut(Qt::Key_Return, pbEqual, SLOT(animateClick())); |
385 | connect(pbEqual, &KCalcButton::clicked, this, &KCalculator::slotEqualclicked); |
386 | connect(this, &KCalculator::switchShowAccels, pbEqual, &KCalcButton::slotSetAccelDisplayMode); |
387 | } |
388 | |
389 | //------------------------------------------------------------------------------ |
390 | // Name: setupLogicKeys |
391 | // Desc: sets up logic keys and related shortcuts |
392 | //------------------------------------------------------------------------------ |
393 | void KCalculator::setupLogicKeys() |
394 | { |
395 | logic_buttons_.append(pbAND); |
396 | logic_buttons_.append(pbOR); |
397 | logic_buttons_.append(pbXOR); |
398 | logic_buttons_.append(pbLsh); |
399 | logic_buttons_.append(pbRsh); |
400 | logic_buttons_.append(pbCmp); |
401 | |
402 | pbAND->setShortcut(QKeySequence(Qt::Key_Ampersand)); |
403 | connect(this, &KCalculator::switchShowAccels, pbAND, &KCalcButton::slotSetAccelDisplayMode); |
404 | connect(pbAND, &KCalcButton::clicked, this, &KCalculator::slotANDclicked); |
405 | |
406 | pbOR->setShortcut(QKeySequence(Qt::Key_Bar)); |
407 | connect(this, &KCalculator::switchShowAccels, pbOR, &KCalcButton::slotSetAccelDisplayMode); |
408 | connect(pbOR, &KCalcButton::clicked, this, &KCalculator::slotORclicked); |
409 | |
410 | connect(this, &KCalculator::switchShowAccels, pbXOR, &KCalcButton::slotSetAccelDisplayMode); |
411 | connect(pbXOR, &KCalcButton::clicked, this, &KCalculator::slotXORclicked); |
412 | |
413 | pbLsh->setShortcut(QKeySequence(Qt::Key_Less)); |
414 | connect(this, &KCalculator::switchShowAccels, pbLsh, &KCalcButton::slotSetAccelDisplayMode); |
415 | connect(pbLsh, &KCalcButton::clicked, this, &KCalculator::slotLeftShiftclicked); |
416 | |
417 | pbRsh->setShortcut(QKeySequence(Qt::Key_Greater)); |
418 | connect(this, &KCalculator::switchShowAccels, pbRsh, &KCalcButton::slotSetAccelDisplayMode); |
419 | connect(pbRsh, &KCalcButton::clicked, this, &KCalculator::slotRightShiftclicked); |
420 | |
421 | pbCmp->setShortcut(QKeySequence(Qt::Key_AsciiTilde)); |
422 | connect(this, &KCalculator::switchShowAccels, pbCmp, &KCalcButton::slotSetAccelDisplayMode); |
423 | connect(pbCmp, &KCalcButton::clicked, this, &KCalculator::slotNegateclicked); |
424 | } |
425 | |
426 | //------------------------------------------------------------------------------ |
427 | // Name: setupLogicKeys |
428 | // Desc: sets up scientific keys and related shortcuts |
429 | //------------------------------------------------------------------------------ |
430 | void KCalculator::setupScientificKeys() |
431 | { |
432 | scientific_buttons_.append(pbHyp); |
433 | scientific_buttons_.append(pbSin); |
434 | scientific_buttons_.append(pbCos); |
435 | scientific_buttons_.append(pbTan); |
436 | scientific_buttons_.append(pbLog); |
437 | scientific_buttons_.append(pbLn); |
438 | |
439 | connect(this, &KCalculator::switchShowAccels, pbHyp, &KCalcButton::slotSetAccelDisplayMode); |
440 | connect(pbHyp, &KCalcButton::toggled, this, &KCalculator::slotHyptoggled); |
441 | |
442 | pbSin->addMode(ModeNormal, i18nc("Sine" , "sin" ), i18n("Sine" )); |
443 | pbSin->addMode(ModeShift, i18nc("Arc sine" , "asin" ), i18n("Arc sine" )); |
444 | pbSin->addMode(ModeHyperbolic, i18nc("Hyperbolic sine" , "sinh" ), i18n("Hyperbolic sine" )); |
445 | pbSin->addMode(ButtonModeFlags(ModeShift | ModeHyperbolic), i18nc("Inverse hyperbolic sine" , "asinh" ), i18n("Inverse hyperbolic sine" )); |
446 | connect(this, &KCalculator::switchShowAccels, pbSin, &KCalcButton::slotSetAccelDisplayMode); |
447 | connect(this, &KCalculator::switchMode, pbSin, &KCalcButton::slotSetMode); |
448 | connect(pbSin, &KCalcButton::clicked, this, &KCalculator::slotSinclicked); |
449 | |
450 | pbCos->addMode(ModeNormal, i18nc("Cosine" , "cos" ), i18n("Cosine" )); |
451 | pbCos->addMode(ModeShift, i18nc("Arc cosine" , "acos" ), i18n("Arc cosine" )); |
452 | pbCos->addMode(ModeHyperbolic, i18nc("Hyperbolic cosine" , "cosh" ), i18n("Hyperbolic cosine" )); |
453 | pbCos->addMode(ButtonModeFlags(ModeShift | ModeHyperbolic), i18nc("Inverse hyperbolic cosine" , "acosh" ), i18n("Inverse hyperbolic cosine" )); |
454 | connect(this, &KCalculator::switchShowAccels, pbCos, &KCalcButton::slotSetAccelDisplayMode); |
455 | connect(this, &KCalculator::switchMode, pbCos, &KCalcButton::slotSetMode); |
456 | connect(pbCos, &KCalcButton::clicked, this, &KCalculator::slotCosclicked); |
457 | |
458 | pbTan->addMode(ModeNormal, i18nc("Tangent" , "tan" ), i18n("Tangent" )); |
459 | pbTan->addMode(ModeShift, i18nc("Arc tangent" , "atan" ), i18n("Arc tangent" )); |
460 | pbTan->addMode(ModeHyperbolic, i18nc("Hyperbolic tangent" , "tanh" ), i18n("Hyperbolic tangent" )); |
461 | pbTan->addMode(ButtonModeFlags(ModeShift | ModeHyperbolic), i18nc("Inverse hyperbolic tangent" , "atanh" ), i18n("Inverse hyperbolic tangent" )); |
462 | connect(this, &KCalculator::switchShowAccels, pbTan, &KCalcButton::slotSetAccelDisplayMode); |
463 | connect(this, &KCalculator::switchMode, pbTan, &KCalcButton::slotSetMode); |
464 | connect(pbTan, &KCalcButton::clicked, this, &KCalculator::slotTanclicked); |
465 | |
466 | pbLog->addMode(ModeNormal, i18nc("Logarithm to base 10" , "log" ), i18n("Logarithm to base 10" )); |
467 | pbLog->addMode(ModeShift, i18nc("10 to the power of x" , "10<sup>x</sup>" ), i18n("10 to the power of x" )); |
468 | connect(this, &KCalculator::switchShowAccels, pbLog, &KCalcButton::slotSetAccelDisplayMode); |
469 | connect(this, &KCalculator::switchMode, pbLog, &KCalcButton::slotSetMode); |
470 | connect(pbLog, &KCalcButton::clicked, this, &KCalculator::slotLogclicked); |
471 | pbLn->addMode(ModeNormal, i18nc("Natural log" , "ln" ), i18n("Natural log" )); |
472 | pbLn->addMode(ModeShift, i18nc("Exponential function" , "e<sup>x</sup>" ), i18n("Exponential function" )); |
473 | connect(this, &KCalculator::switchShowAccels, pbLn, &KCalcButton::slotSetAccelDisplayMode); |
474 | connect(this, &KCalculator::switchMode, pbLn, &KCalcButton::slotSetMode); |
475 | connect(pbLn, &KCalcButton::clicked, this, &KCalculator::slotLnclicked); |
476 | } |
477 | |
478 | //------------------------------------------------------------------------------ |
479 | // Name: setupStatisticKeys |
480 | // Desc: sets up statistical keys and related shortcuts |
481 | //------------------------------------------------------------------------------ |
482 | void KCalculator::setupStatisticKeys() |
483 | { |
484 | stat_buttons_.append(pbNData); |
485 | stat_buttons_.append(pbMean); |
486 | stat_buttons_.append(pbSd); |
487 | stat_buttons_.append(pbMed); |
488 | stat_buttons_.append(pbDat); |
489 | stat_buttons_.append(pbCSt); |
490 | |
491 | pbNData->addMode(ModeNormal, i18nc("Number of data entered" , "N" ), i18n("Number of data entered" )); |
492 | pbNData->addMode(ModeShift, QString::fromUtf8("\xce\xa3" ) + QLatin1Char('x'), i18n("Sum of all data items" )); |
493 | connect(this, &KCalculator::switchShowAccels, pbNData, &KCalcButton::slotSetAccelDisplayMode); |
494 | connect(this, &KCalculator::switchMode, pbNData, &KCalcButton::slotSetMode); |
495 | connect(pbNData, &KCalcButton::clicked, this, &KCalculator::slotStatNumclicked); |
496 | |
497 | pbMean->addMode(ModeNormal, i18nc("Mean" , "Mea" ), i18n("Mean" )); |
498 | pbMean->addMode(ModeShift, QString::fromUtf8("\xce\xa3" ) + QLatin1String("x<sup>2</sup>" ), i18n("Sum of all data items squared" )); |
499 | connect(this, &KCalculator::switchShowAccels, pbMean, &KCalcButton::slotSetAccelDisplayMode); |
500 | connect(this, &KCalculator::switchMode, pbMean, &KCalcButton::slotSetMode); |
501 | connect(pbMean, &KCalcButton::clicked, this, &KCalculator::slotStatMeanclicked); |
502 | |
503 | pbSd->addMode(ModeNormal, QString::fromUtf8("\xcf\x83" ) + QLatin1String("<sub>N</sub>" ), i18n("Standard deviation" )); |
504 | pbSd->addMode(ModeShift, QString::fromUtf8("\xcf\x83" ) + QLatin1String("<sub>N-1</sub>" ), i18n("Sample standard deviation" )); |
505 | connect(this, &KCalculator::switchShowAccels, pbSd, &KCalcButton::slotSetAccelDisplayMode); |
506 | connect(this, &KCalculator::switchMode, pbSd, &KCalcButton::slotSetMode); |
507 | connect(pbSd, &KCalcButton::clicked, this, &KCalculator::slotStatStdDevclicked); |
508 | |
509 | connect(this, &KCalculator::switchShowAccels, pbMed, &KCalcButton::slotSetAccelDisplayMode); |
510 | connect(pbMed, &KCalcButton::clicked, this, &KCalculator::slotStatMedianclicked); |
511 | |
512 | pbDat->addMode(ModeNormal, i18nc("Enter data" , "Dat" ), i18n("Enter data" )); |
513 | pbDat->addMode(ModeShift, i18nc("Delete last data item" , "CDat" ), i18n("Delete last data item" )); |
514 | connect(this, &KCalculator::switchShowAccels, pbDat, &KCalcButton::slotSetAccelDisplayMode); |
515 | connect(this, &KCalculator::switchMode, pbDat, &KCalcButton::slotSetMode); |
516 | connect(pbDat, &KCalcButton::clicked, this, &KCalculator::slotStatDataInputclicked); |
517 | |
518 | connect(this, &KCalculator::switchShowAccels, pbCSt, &KCalcButton::slotSetAccelDisplayMode); |
519 | connect(pbCSt, &KCalcButton::clicked, this, &KCalculator::slotStatClearDataclicked); |
520 | } |
521 | |
522 | //------------------------------------------------------------------------------ |
523 | // Name: setupConstantsKeys |
524 | // Desc: sets up constants keys and related shortcuts |
525 | //------------------------------------------------------------------------------ |
526 | void KCalculator::setupConstantsKeys() |
527 | { |
528 | const_buttons_.append(pbC1); |
529 | const_buttons_.append(pbC2); |
530 | const_buttons_.append(pbC3); |
531 | const_buttons_.append(pbC4); |
532 | const_buttons_.append(pbC5); |
533 | const_buttons_.append(pbC6); |
534 | |
535 | pbC1->setButtonNumber(0); |
536 | connect(this, &KCalculator::switchShowAccels, pbC1, &KCalcConstButton::slotSetAccelDisplayMode); |
537 | connect(this, &KCalculator::switchMode, pbC1, &KCalcConstButton::slotSetMode); |
538 | connect(pbC1, &KCalcConstButton::constButtonClicked, this, &KCalculator::slotConstclicked); |
539 | |
540 | pbC2->setButtonNumber(1); |
541 | connect(this, &KCalculator::switchShowAccels, pbC2, &KCalcConstButton::slotSetAccelDisplayMode); |
542 | connect(this, &KCalculator::switchMode, pbC2, &KCalcConstButton::slotSetMode); |
543 | connect(pbC2, &KCalcConstButton::constButtonClicked, this, &KCalculator::slotConstclicked); |
544 | |
545 | pbC3->setButtonNumber(2); |
546 | connect(this, &KCalculator::switchShowAccels, pbC3, &KCalcConstButton::slotSetAccelDisplayMode); |
547 | connect(this, &KCalculator::switchMode, pbC3, &KCalcConstButton::slotSetMode); |
548 | connect(pbC3, &KCalcConstButton::constButtonClicked, this, &KCalculator::slotConstclicked); |
549 | |
550 | pbC4->setButtonNumber(3); |
551 | connect(this, &KCalculator::switchShowAccels, pbC4, &KCalcConstButton::slotSetAccelDisplayMode); |
552 | connect(this, &KCalculator::switchMode, pbC4, &KCalcConstButton::slotSetMode); |
553 | connect(pbC4, &KCalcConstButton::constButtonClicked, this, &KCalculator::slotConstclicked); |
554 | |
555 | pbC5->setButtonNumber(4); |
556 | connect(this, &KCalculator::switchShowAccels, pbC5, &KCalcConstButton::slotSetAccelDisplayMode); |
557 | connect(this, &KCalculator::switchMode, pbC5, &KCalcConstButton::slotSetMode); |
558 | connect(pbC5, &KCalcConstButton::constButtonClicked, this, &KCalculator::slotConstclicked); |
559 | |
560 | pbC6->setButtonNumber(5); |
561 | connect(this, &KCalculator::switchShowAccels, pbC6, &KCalcConstButton::slotSetAccelDisplayMode); |
562 | connect(this, &KCalculator::switchMode, pbC6, &KCalcConstButton::slotSetMode); |
563 | connect(pbC6, &KCalcConstButton::constButtonClicked, this, &KCalculator::slotConstclicked); |
564 | |
565 | changeButtonNames(); |
566 | } |
567 | |
568 | //------------------------------------------------------------------------------ |
569 | // Name: setupMiscKeys |
570 | // Desc: sets up misc keys and related shortcuts |
571 | //------------------------------------------------------------------------------ |
572 | void KCalculator::setupMiscKeys() |
573 | { |
574 | pbMod->addMode(ModeNormal, i18nc("Modulo" , "mod" ), i18n("Modulo" )); |
575 | pbMod->addMode(ModeShift, i18nc("Integer division" , "IntDiv" ), i18n("Integer division" )); |
576 | connect(this, &KCalculator::switchMode, pbMod, &KCalcButton::slotSetMode); |
577 | connect(this, &KCalculator::switchShowAccels, pbMod, &KCalcButton::slotSetAccelDisplayMode); |
578 | pbMod->setShortcut(QKeySequence(Qt::Key_Colon)); |
579 | connect(pbMod, &KCalcButton::clicked, this, &KCalculator::slotModclicked); |
580 | |
581 | pbReci->addMode(ModeNormal, i18nc("Reciprocal" , "1/x" ), i18n("Reciprocal" )); |
582 | pbReci->addMode(ModeShift, i18nc("n Choose m" , "nCm" ), i18n("n Choose m" )); |
583 | connect(this, &KCalculator::switchMode, pbReci, &KCalcButton::slotSetMode); |
584 | connect(this, &KCalculator::switchShowAccels, pbReci, &KCalcButton::slotSetAccelDisplayMode); |
585 | connect(pbReci, &KCalcButton::clicked, this, &KCalculator::slotReciclicked); |
586 | |
587 | pbFactorial->addMode(ModeNormal, i18nc("Factorial" , "x!" ), i18n("Factorial" )); |
588 | pbFactorial->addMode(ModeShift, QStringLiteral("Γ" ), i18n("Gamma" )); |
589 | pbFactorial->setShortcut(QKeySequence(Qt::Key_Exclam)); |
590 | connect(this, &KCalculator::switchShowAccels, pbFactorial, &KCalcButton::slotSetAccelDisplayMode); |
591 | connect(this, &KCalculator::switchMode, pbFactorial, &KCalcButton::slotSetMode); |
592 | connect(pbFactorial, &KCalcButton::clicked, this, &KCalculator::slotFactorialclicked); |
593 | |
594 | pbSquare->addMode(ModeNormal, i18nc("Square" , "x<sup>2</sup>" ), i18n("Square" )); |
595 | pbSquare->addMode(ModeShift, QStringLiteral("√x" ), i18n("Square root" )); |
596 | pbSquare->setShortcut(QKeySequence(Qt::Key_BracketLeft)); |
597 | new QShortcut(Qt::Key_twosuperior, pbSquare, SLOT(animateClick())); |
598 | connect(this, &KCalculator::switchShowAccels, pbSquare, &KCalcButton::slotSetAccelDisplayMode); |
599 | connect(this, &KCalculator::switchMode, pbSquare, &KCalcButton::slotSetMode); |
600 | connect(pbSquare, &KCalcButton::clicked, this, &KCalculator::slotSquareclicked); |
601 | |
602 | pbPower->addMode(ModeNormal, i18nc("x to the power of y" , "x<sup>y</sup>" ), i18n("x to the power of y" )); |
603 | pbPower->addMode(ModeShift, i18nc("x to the power of 1/y" , "x<sup>1/y</sup>" ), i18n("x to the power of 1/y" )); |
604 | connect(this, &KCalculator::switchShowAccels, pbPower, &KCalcButton::slotSetAccelDisplayMode); |
605 | connect(this, &KCalculator::switchMode, pbPower, &KCalcButton::slotSetMode); |
606 | pbPower->setShortcut(QKeySequence(Qt::Key_AsciiCircum)); |
607 | connect(pbPower, &KCalcButton::clicked, this, &KCalculator::slotPowerclicked); |
608 | |
609 | pbEE->addMode(ModeNormal, |
610 | QStringLiteral("x<small>" |
611 | "\xb7" |
612 | "10</small><sup>y</sup>" ), |
613 | i18n("Exponent" )); |
614 | connect(this, &KCalculator::switchShowAccels, pbEE, &KCalcButton::slotSetAccelDisplayMode); |
615 | connect(pbEE, &KCalcButton::clicked, this, &KCalculator::slotEEclicked); |
616 | } |
617 | |
618 | //------------------------------------------------------------------------------ |
619 | // Name: createConstantsMenu |
620 | // Desc: additional setup for button keys |
621 | // NOTE: all alphanumeric shorts set in ui file |
622 | //------------------------------------------------------------------------------ |
623 | void KCalculator::setupKeys() |
624 | { |
625 | setupNumberKeys(); |
626 | setupRightKeypad(); |
627 | setupNumericKeypad(); |
628 | setupLogicKeys(); |
629 | setupScientificKeys(); |
630 | setupStatisticKeys(); |
631 | setupConstantsKeys(); |
632 | setupMiscKeys(); |
633 | |
634 | // other button lists |
635 | |
636 | function_button_list_.append(pbHyp); |
637 | function_button_list_.append(pbShift); |
638 | function_button_list_.append(pbEE); |
639 | function_button_list_.append(pbSin); |
640 | function_button_list_.append(pbPlusMinus); |
641 | function_button_list_.append(pbCos); |
642 | function_button_list_.append(pbReci); |
643 | function_button_list_.append(pbTan); |
644 | function_button_list_.append(pbFactorial); |
645 | function_button_list_.append(pbLog); |
646 | function_button_list_.append(pbSquare); |
647 | function_button_list_.append(pbLn); |
648 | function_button_list_.append(pbPower); |
649 | function_button_list_.append(pbCube); |
650 | |
651 | mem_button_list_.append(pbMemRecall); |
652 | mem_button_list_.append(pbMemPlusMinus); |
653 | mem_button_list_.append(pbMemStore); |
654 | mem_button_list_.append(pbMemClear); |
655 | mem_button_list_.append(pbClear); |
656 | mem_button_list_.append(pbAllClear); |
657 | mem_button_list_.append(pbBackspace); |
658 | |
659 | operation_button_list_.append(pbMultiplication); |
660 | operation_button_list_.append(pbParenOpen); |
661 | operation_button_list_.append(pbParenClose); |
662 | operation_button_list_.append(pbAND); |
663 | operation_button_list_.append(pbDivision); |
664 | operation_button_list_.append(pbOR); |
665 | operation_button_list_.append(pbXOR); |
666 | operation_button_list_.append(pbPlus); |
667 | operation_button_list_.append(pbMinus); |
668 | operation_button_list_.append(pbLsh); |
669 | operation_button_list_.append(pbRsh); |
670 | operation_button_list_.append(pbPeriod); |
671 | operation_button_list_.append(pbEqual); |
672 | operation_button_list_.append(pbPercent); |
673 | operation_button_list_.append(pbCmp); |
674 | operation_button_list_.append(pbMod); |
675 | } |
676 | |
677 | //------------------------------------------------------------------------------ |
678 | // Name: updateGeometry |
679 | // Desc: makes all the buttons have reasonable sizes |
680 | //------------------------------------------------------------------------------ |
681 | void KCalculator::updateGeometry() |
682 | { |
683 | // Create font metrics using base font (at base size) |
684 | const QFontMetrics fm(baseFont()); |
685 | |
686 | // Calculate some useful values |
687 | const QSize em = fm.size(0, QStringLiteral("M" )); |
688 | int margin = QApplication::style()->pixelMetric(QStyle::PM_ButtonMargin, nullptr, nullptr); |
689 | margin = qMax(qMin(margin / 2, 3), 3); |
690 | |
691 | // left pad |
692 | const auto leftPadList = leftPad->children(); |
693 | for (QObject *obj : leftPadList) { |
694 | if (auto const button = qobject_cast<KCalcButton *>(obj)) { |
695 | button->setMinimumWidth(em.width() * 4 + margin * 2); |
696 | button->setMinimumHeight(em.height() * 1.25 + margin * 2); |
697 | button->installEventFilter(this); |
698 | } |
699 | } |
700 | |
701 | // right pad |
702 | const auto rightPadList = rightPad->children(); |
703 | for (QObject *obj : rightPadList) { |
704 | if (auto const button = qobject_cast<KCalcButton *>(obj)) { |
705 | button->setMinimumWidth(em.width() * 3 + margin * 2); |
706 | button->setMinimumHeight(em.height() * 1.25 + margin * 2); |
707 | button->installEventFilter(this); |
708 | } |
709 | } |
710 | |
711 | // numeric pad |
712 | const auto numericPadList = numericPad->children(); |
713 | for (QObject *obj : numericPadList) { |
714 | if (auto const button = qobject_cast<KCalcButton *>(obj)) { |
715 | button->setMinimumWidth(em.width() * 3 + margin * 2); |
716 | button->setMinimumHeight(em.height() * 1.25 + margin * 2); |
717 | button->installEventFilter(this); |
718 | } |
719 | } |
720 | } |
721 | |
722 | //------------------------------------------------------------------------------ |
723 | // Name: slotConstantToDisplay |
724 | // Desc: inserts a constant |
725 | //------------------------------------------------------------------------------ |
726 | void KCalculator::slotConstantToDisplay(const science_constant &const_chosen) |
727 | { |
728 | QString val = const_chosen.value; |
729 | val.replace(QLatin1Char('.'), KNumber::decimalSeparator()); |
730 | calc_display->setAmount(KNumber(val)); |
731 | updateDisplay({}); |
732 | core.setOnlyUpdateOperation(false); |
733 | } |
734 | |
735 | //------------------------------------------------------------------------------ |
736 | // Name: slotBaseSelected |
737 | // Desc: changes the selected numeric base |
738 | //------------------------------------------------------------------------------ |
739 | void KCalculator::slotBaseSelected(QAbstractButton *button) |
740 | { |
741 | if (button) { |
742 | const int base = base_choose_group_->id(button); |
743 | int current_base; |
744 | |
745 | // set display & statusbar (if item exist in statusbar) |
746 | statusBar()->setBase(base); |
747 | switch (base) { |
748 | case BinMode: |
749 | current_base = calc_display->setBase(NumBase(2)); |
750 | calc_display->setStatusText(BaseField, QStringLiteral("Bin" )); |
751 | break; |
752 | case OctMode: |
753 | current_base = calc_display->setBase(NumBase(8)); |
754 | calc_display->setStatusText(BaseField, QStringLiteral("Oct" )); |
755 | break; |
756 | case DecMode: |
757 | current_base = calc_display->setBase(NumBase(10)); |
758 | calc_display->setStatusText(BaseField, QStringLiteral("Dec" )); |
759 | break; |
760 | case HexMode: |
761 | current_base = calc_display->setBase(NumBase(16)); |
762 | calc_display->setStatusText(BaseField, QStringLiteral("Hex" )); |
763 | break; |
764 | default: |
765 | calc_display->setStatusText(BaseField, QStringLiteral("Error" )); |
766 | return; |
767 | } |
768 | |
769 | // Enable the buttons available in this base |
770 | for (int i = 0; i < current_base; ++i) { |
771 | (num_button_group_->buttons().at(i))->setEnabled(true); |
772 | } |
773 | |
774 | // Disable the buttons not available in this base |
775 | for (int i = current_base; i < 16; ++i) { |
776 | (num_button_group_->buttons().at(i))->setEnabled(false); |
777 | } |
778 | |
779 | // Only enable the decimal point in decimal |
780 | pbPeriod->setEnabled(current_base == NB_DECIMAL); |
781 | |
782 | // Only enable the x*10^y button in decimal |
783 | pbEE->setEnabled(current_base == NB_DECIMAL); |
784 | |
785 | // Disable buttons that make only sense with floating point numbers |
786 | if (current_base != NB_DECIMAL) { |
787 | for (QAbstractButton *btn : std::as_const(scientific_buttons_)) { |
788 | btn->setEnabled(false); |
789 | } |
790 | } else { |
791 | for (QAbstractButton *btn : std::as_const(scientific_buttons_)) { |
792 | btn->setEnabled(true); |
793 | } |
794 | } |
795 | |
796 | KCalcSettings::setBaseMode(base); |
797 | } |
798 | } |
799 | |
800 | //------------------------------------------------------------------------------ |
801 | // Name: keyPressEvent |
802 | // Desc: handles keypress events |
803 | //------------------------------------------------------------------------------ |
804 | void KCalculator::keyPressEvent(QKeyEvent *e) |
805 | { |
806 | // Fix for bug #314586 |
807 | // Basically, on some keyboards such as French, even though the decimal separator |
808 | // is "," the numeric keypad has a "." key. So we fake it so people can more seamlessly |
809 | // enter numbers using the keypad |
810 | if (KNumber::decimalSeparator() != QLatin1String("." )) { |
811 | if (e->key() == Qt::Key_Period && e->modifiers() & Qt::KeypadModifier) { |
812 | pbPeriod->animateClick(); |
813 | } |
814 | } |
815 | |
816 | if (((e->modifiers() & Qt::NoModifier) == 0) || (e->modifiers() & Qt::ShiftModifier)) { |
817 | switch (e->key()) { |
818 | case Qt::Key_Backspace: |
819 | calc_display->deleteLastDigit(); |
820 | break; |
821 | } |
822 | } |
823 | |
824 | if (e->key() == Qt::Key_Control) { |
825 | Q_EMIT switchShowAccels(true); |
826 | } |
827 | |
828 | // Workaround for bug #283521 |
829 | // Unfortunately adding multiple shortcuts (A, Shift+A) to pushbuttons |
830 | // does not work properly, so we handle the A-F keypresses with shift in Hex mode here |
831 | if (hexRadio->isChecked() && e->modifiers() & Qt::ShiftModifier) { |
832 | switch (e->key()) { |
833 | case Qt::Key_A: |
834 | pbA->animateClick(); |
835 | break; |
836 | case Qt::Key_B: |
837 | pbB->animateClick(); |
838 | break; |
839 | case Qt::Key_C: |
840 | pbC->animateClick(); |
841 | break; |
842 | case Qt::Key_D: |
843 | pbD->animateClick(); |
844 | break; |
845 | case Qt::Key_E: |
846 | pbE->animateClick(); |
847 | break; |
848 | case Qt::Key_F: |
849 | pbF->animateClick(); |
850 | break; |
851 | default: |
852 | break; |
853 | } |
854 | } |
855 | } |
856 | |
857 | //------------------------------------------------------------------------------ |
858 | // Name: keyReleaseEvent |
859 | // Desc: handles keyrelease events |
860 | //------------------------------------------------------------------------------ |
861 | void KCalculator::keyReleaseEvent(QKeyEvent *e) |
862 | { |
863 | if (e->key() == Qt::Key_Control) { |
864 | Q_EMIT switchShowAccels(false); |
865 | } |
866 | } |
867 | |
868 | //------------------------------------------------------------------------------ |
869 | // Name: slotAngleSelected |
870 | // Desc: changes the selected angle system |
871 | //------------------------------------------------------------------------------ |
872 | void KCalculator::slotAngleSelected(QAbstractButton *button) |
873 | { |
874 | if (button) { |
875 | const int mode = angle_choose_group_->id(button); |
876 | angle_mode_ = mode; |
877 | |
878 | statusBar()->setAngleMode(KCalcStatusBar::AngleMode(mode)); |
879 | switch (mode) { |
880 | case DegMode: |
881 | calc_display->setStatusText(AngleField, QStringLiteral("Deg" )); |
882 | break; |
883 | case RadMode: |
884 | calc_display->setStatusText(AngleField, QStringLiteral("Rad" )); |
885 | break; |
886 | case GradMode: |
887 | calc_display->setStatusText(AngleField, QStringLiteral("Gra" )); |
888 | break; |
889 | default: // we shouldn't ever end up here |
890 | angle_mode_ = RadMode; |
891 | } |
892 | |
893 | KCalcSettings::setAngleMode(angle_mode_); |
894 | } |
895 | } |
896 | |
897 | //------------------------------------------------------------------------------ |
898 | // Name: slotEEclicked |
899 | // Desc: starts the entering of numbers using scientific notation |
900 | //------------------------------------------------------------------------------ |
901 | void KCalculator::slotEEclicked() |
902 | { |
903 | calc_display->newCharacter(QLatin1Char('e')); |
904 | } |
905 | |
906 | //------------------------------------------------------------------------------ |
907 | // Name: slotShifttoggled |
908 | // Desc: updates the shift state for alternate button functionality |
909 | //------------------------------------------------------------------------------ |
910 | void KCalculator::slotShifttoggled(bool flag) |
911 | { |
912 | shift_mode_ = flag; |
913 | |
914 | Q_EMIT switchMode(ModeShift, flag); |
915 | |
916 | statusBar()->setShiftIndicator(shift_mode_); |
917 | if (shift_mode_) { |
918 | calc_display->setStatusText(ShiftField, i18n("Shift" )); |
919 | } else { |
920 | calc_display->setStatusText(ShiftField, QString()); |
921 | } |
922 | } |
923 | |
924 | //------------------------------------------------------------------------------ |
925 | // Name: slotHyptoggled |
926 | // Desc: updates the Hyp state for alternate trig button functionality |
927 | //------------------------------------------------------------------------------ |
928 | void KCalculator::slotHyptoggled(bool flag) |
929 | { |
930 | // toggle between hyperbolic and standard trig functions |
931 | hyp_mode_ = flag; |
932 | |
933 | Q_EMIT switchMode(ModeHyperbolic, flag); |
934 | } |
935 | |
936 | //------------------------------------------------------------------------------ |
937 | // Name: slotMemRecallclicked |
938 | // Desc: recalls a value from memory |
939 | //------------------------------------------------------------------------------ |
940 | void KCalculator::slotMemRecallclicked() |
941 | { |
942 | // temp. work-around |
943 | calc_display->sendEvent(event: KCalcDisplay::EventReset); |
944 | |
945 | // temp. work-around |
946 | calc_display->sendEvent(event: KCalcDisplay::EventReset); |
947 | |
948 | calc_history->addToHistory(QStringLiteral("MR" ), false); |
949 | |
950 | calc_display->setAmount(memory_num_); |
951 | updateDisplay({}); |
952 | core.setOnlyUpdateOperation(false); |
953 | calc_history->addResultToHistory(memory_num_.toQString()); |
954 | } |
955 | |
956 | //------------------------------------------------------------------------------ |
957 | // Name: slotMemStoreclicked |
958 | // Desc: stores a value into memory |
959 | //------------------------------------------------------------------------------ |
960 | void KCalculator::slotMemStoreclicked() |
961 | { |
962 | calc_history->addToHistory(QStringLiteral("M" ), false); |
963 | update_history_window_ = false; |
964 | EnterEqual(allow_repeat: CalcEngine::REPEAT_PREVENT); |
965 | |
966 | memory_num_ = calc_display->getAmount(); |
967 | calc_display->setStatusText(MemField, QStringLiteral("M" )); |
968 | statusBar()->setMemoryIndicator(true); |
969 | pbMemRecall->setEnabled(true); |
970 | } |
971 | |
972 | //------------------------------------------------------------------------------ |
973 | // Name: slotNumberclicked |
974 | // Desc: user has entered a digit |
975 | //------------------------------------------------------------------------------ |
976 | void KCalculator::slotNumberclicked(QAbstractButton *button) |
977 | { |
978 | if (button) { |
979 | const int number_clicked = num_button_group_->id(button); |
980 | calc_display->enterDigit(data: number_clicked); |
981 | core.setOnlyUpdateOperation(false); |
982 | } |
983 | } |
984 | |
985 | //------------------------------------------------------------------------------ |
986 | // Name: slotSinclicked |
987 | // Desc: executes the sine function |
988 | //------------------------------------------------------------------------------ |
989 | void KCalculator::slotSinclicked() |
990 | { |
991 | if (hyp_mode_) { |
992 | // sinh or arcsinh |
993 | if (!shift_mode_) { |
994 | calc_history->addFuncToHistory(QStringLiteral("sinh" )); |
995 | core.SinHyp(calc_display->getAmount()); |
996 | } else { |
997 | calc_history->addFuncToHistory(QStringLiteral("arcsinh" )); |
998 | core.AreaSinHyp(calc_display->getAmount()); |
999 | } |
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(event: 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(event: 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(event: 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(event: 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(event: 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(i: button, v: 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(name: 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 *; |
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(toggled: false); |
1883 | showScienceButtons(toggled: false); |
1884 | showStatButtons(toggled: false); |
1885 | showLogicButtons(toggled: 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(toggled: false); |
1948 | showLogicButtons(toggled: false); |
1949 | showMemButtons(toggled: true); |
1950 | showScienceButtons(toggled: 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(toggled: false); |
2004 | showMemButtons(toggled: true); |
2005 | showScienceButtons(toggled: true); |
2006 | showStatButtons(toggled: 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(toggled: false); |
2061 | showStatButtons(toggled: false); |
2062 | showMemButtons(toggled: true); |
2063 | showLogicButtons(toggled: 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(mimeData: 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: &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, locale: "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" |
2866 | |