IVS-calculator
Loading...
Searching...
No Matches
Gui Class Reference

Main window class for the calculator GUI. More...

#include <gui.h>

Inheritance diagram for Gui:
Collaboration diagram for Gui:

Public Member Functions

 Gui (QWidget *parent=nullptr)
 Constructs the GUI and initializes components.
 
 ~Gui ()
 Destructor. Frees allocated resources.
 

Private Slots

void on_btn_0_clicked ()
 Digit button handlers.
 
void on_btn_1_clicked ()
 
void on_btn_2_clicked ()
 
void on_btn_3_clicked ()
 
void on_btn_4_clicked ()
 
void on_btn_5_clicked ()
 
void on_btn_6_clicked ()
 
void on_btn_7_clicked ()
 
void on_btn_8_clicked ()
 
void on_btn_9_clicked ()
 
void on_btn_plus_clicked ()
 Operation button handlers.
 
void on_btn_minus_clicked ()
 
void on_btn_mul_clicked ()
 
void on_btn_div_clicked ()
 
void on_btn_mod_clicked ()
 
void on_btn_pow_clicked ()
 
void on_btn_root_clicked ()
 Appends square root operator.
 
void on_btn_fac_clicked ()
 Appends factorial operator.
 
void on_btn_clear_clicked ()
 Control buttons.
 
void on_btn_equal_clicked ()
 Evaluates the current expression.
 
void on_btn_dot_clicked ()
 Appends a decimal point to the current expression.
 

Private Member Functions

void updateDisplay ()
 Updates the calculator display.
 
void showError (mathlib::MathError err)
 Displays an error message based on mathlib error code.
 
void keyPressEvent (QKeyEvent *event) override
 Keyboard input handler.
 
bool endsWithOperator () const
 Helpers for input validation.
 
bool hasOperator () const
 Checks if the expression already contains a binary operator.
 
int findOperatorPos (QChar op) const
 Finds the position of the binary operator in the expression.
 
void appendDigit (const QString &digit)
 Appends a digit to the expression.
 
void appendOperator (const QString &op)
 Appends a binary operator to the expression.
 

Private Attributes

Ui::Gui * ui
 
QString currentExpression
 
bool justEvaluated
 

Detailed Description

Main window class for the calculator GUI.

Handles user input, updates the display, and evaluates expressions using functions from mathlib.

Definition at line 25 of file gui.h.

Constructor & Destructor Documentation

◆ Gui()

Gui::Gui ( QWidget * parent = nullptr)
explicit

Constructs the GUI and initializes components.

Parameters
parentPointer to parent widget.

Definition at line 18 of file gui.cpp.

19 : QMainWindow(parent),
20 ui(new Ui::Gui),
21 justEvaluated(false)
22{
23 ui->setupUi(this);
24 currentExpression.clear();
25}
Ui::Gui * ui
Definition gui.h:62
QString currentExpression
Definition gui.h:63
bool justEvaluated
Definition gui.h:64

◆ ~Gui()

Gui::~Gui ( )

Destructor. Frees allocated resources.

Definition at line 30 of file gui.cpp.

31{
32 delete ui;
33}

Member Function Documentation

◆ appendDigit()

void Gui::appendDigit ( const QString & digit)
private

Appends a digit to the expression.

If the calculator just finished an evaluation, the digit starts a new expression instead of appending to the old result.

Definition at line 108 of file gui.cpp.

109{
110 if (justEvaluated) {
111 currentExpression.clear();
112 justEvaluated = false;
113 }
114 currentExpression += digit;
116}
void updateDisplay()
Updates the calculator display.
Definition gui.cpp:64

◆ appendOperator()

void Gui::appendOperator ( const QString & op)
private

Appends a binary operator to the expression.

Prevents duplicate operators and enforces single-operation limit. If the user just evaluated, the result is kept and the operator is chained onto it.

Definition at line 125 of file gui.cpp.

126{
127 // After evaluation, chain onto the result
128 if (justEvaluated) {
129 justEvaluated = false;
130 }
131
132 // Don't allow an operator on an empty expression
133 // (except minus, which creates a negative number)
134 if (currentExpression.isEmpty()) {
135 if (op == "-") {
136 currentExpression += op;
138 }
139 return;
140 }
141
142 // If expression already ends with an operator, replace it
143 if (endsWithOperator()) {
144 currentExpression.chop(1);
145 currentExpression += op;
147 return;
148 }
149
150 // Only allow one binary operator per expression
151 if (hasOperator()) {
152 return;
153 }
154
155 currentExpression += op;
157}
bool hasOperator() const
Checks if the expression already contains a binary operator.
Definition gui.cpp:88
bool endsWithOperator() const
Helpers for input validation.
Definition gui.cpp:73

◆ endsWithOperator()

bool Gui::endsWithOperator ( ) const
private

Helpers for input validation.

Checks if the last character in the expression is an operator.

Returns
true if expression ends with an operator.

Definition at line 73 of file gui.cpp.

74{
75 if (currentExpression.isEmpty()) return false;
76 QChar last = currentExpression.back();
77 return last == '+' || last == '-' || last == '*' ||
78 last == '/' || last == '%' || last == '^';
79}

◆ findOperatorPos()

int Gui::findOperatorPos ( QChar op) const
private

Finds the position of the binary operator in the expression.

Skips a leading minus sign so that negative first operands are handled correctly (e.g. "-5+3" splits into -5 and 3).

Parameters
opThe operator character to find.
Returns
The index of the operator, or -1 if not found.

Definition at line 278 of file gui.cpp.

279{
280 // Start at 1 to skip a possible leading negative sign
281 for (int i = 1; i < currentExpression.size(); ++i) {
282 if (currentExpression[i] == op)
283 return i;
284 }
285 return -1;
286}

◆ hasOperator()

bool Gui::hasOperator ( ) const
private

Checks if the expression already contains a binary operator.

Skips a leading minus sign (negative number) and looks for any binary operator in the remaining characters.

Returns
true if a binary operator is present.

Definition at line 88 of file gui.cpp.

89{
90 // Start scanning from index 1 to allow a leading negative sign
91 for (int i = 1; i < currentExpression.size(); ++i) {
92 QChar c = currentExpression[i];
93 if (c == '+' || c == '*' || c == '/' || c == '%' || c == '^')
94 return true;
95 // A '-' that isn't at position 0 counts as an operator
96 if (c == '-')
97 return true;
98 }
99 return false;
100}

◆ keyPressEvent()

void Gui::keyPressEvent ( QKeyEvent * event)
overrideprivate

Keyboard input handler.

Handles keyboard input for the calculator.

Maps keyboard keys to their corresponding button actions.

Parameters
eventThe key press event.

Definition at line 384 of file gui.cpp.

385{
386 int key = event->key();
387
388 // Digit keys 0-9
389 if (key >= Qt::Key_0 && key <= Qt::Key_9) {
390 appendDigit(QString::number(key - Qt::Key_0));
391 return;
392 }
393
394 switch (key) {
395 // Basic operators
396 case Qt::Key_Plus:
397 appendOperator("+");
398 break;
399 case Qt::Key_Minus:
400 appendOperator("-");
401 break;
402 case Qt::Key_Asterisk:
403 appendOperator("*");
404 break;
405 case Qt::Key_Slash:
406 appendOperator("/");
407 break;
408 case Qt::Key_Percent:
409 appendOperator("%");
410 break;
411 case Qt::Key_AsciiCircum:
412 appendOperator("^");
413 break;
414 case Qt::Key_Exclam:
416 break;
417
418 // Decimal point
419 case Qt::Key_Period:
420 case Qt::Key_Comma:
422 break;
423
424 // Evaluate
425 case Qt::Key_Return:
426 case Qt::Key_Enter:
427 case Qt::Key_Equal:
429 break;
430
431 // Backspace — delete last character
432 case Qt::Key_Backspace:
433 if (justEvaluated) {
434 currentExpression.clear();
435 justEvaluated = false;
436 } else if (!currentExpression.isEmpty()) {
437 currentExpression.chop(1);
438 }
440 break;
441
442 // Clear
443 case Qt::Key_Escape:
444 case Qt::Key_Delete:
445 case Qt::Key_C:
447 break;
448
449 default:
450 QMainWindow::keyPressEvent(event);
451 break;
452 }
453}
void on_btn_clear_clicked()
Control buttons.
Definition gui.cpp:263
void appendOperator(const QString &op)
Appends a binary operator to the expression.
Definition gui.cpp:125
void appendDigit(const QString &digit)
Appends a digit to the expression.
Definition gui.cpp:108
void on_btn_dot_clicked()
Appends a decimal point to the current expression.
Definition gui.cpp:187
void on_btn_equal_clicked()
Evaluates the current expression.
Definition gui.cpp:294
void on_btn_fac_clicked()
Appends factorial operator.
Definition gui.cpp:238

◆ on_btn_0_clicked

void Gui::on_btn_0_clicked ( )
privateslot

Digit button handlers.

Definition at line 161 of file gui.cpp.

161{ appendDigit("0"); }

◆ on_btn_1_clicked

void Gui::on_btn_1_clicked ( )
privateslot

Definition at line 162 of file gui.cpp.

162{ appendDigit("1"); }

◆ on_btn_2_clicked

void Gui::on_btn_2_clicked ( )
privateslot

Definition at line 163 of file gui.cpp.

163{ appendDigit("2"); }

◆ on_btn_3_clicked

void Gui::on_btn_3_clicked ( )
privateslot

Definition at line 164 of file gui.cpp.

164{ appendDigit("3"); }

◆ on_btn_4_clicked

void Gui::on_btn_4_clicked ( )
privateslot

Definition at line 165 of file gui.cpp.

165{ appendDigit("4"); }

◆ on_btn_5_clicked

void Gui::on_btn_5_clicked ( )
privateslot

Definition at line 166 of file gui.cpp.

166{ appendDigit("5"); }

◆ on_btn_6_clicked

void Gui::on_btn_6_clicked ( )
privateslot

Definition at line 167 of file gui.cpp.

167{ appendDigit("6"); }

◆ on_btn_7_clicked

void Gui::on_btn_7_clicked ( )
privateslot

Definition at line 168 of file gui.cpp.

168{ appendDigit("7"); }

◆ on_btn_8_clicked

void Gui::on_btn_8_clicked ( )
privateslot

Definition at line 169 of file gui.cpp.

169{ appendDigit("8"); }

◆ on_btn_9_clicked

void Gui::on_btn_9_clicked ( )
privateslot

Definition at line 170 of file gui.cpp.

170{ appendDigit("9"); }

◆ on_btn_clear_clicked

void Gui::on_btn_clear_clicked ( )
privateslot

Control buttons.

Clears the current expression and resets display.

Definition at line 263 of file gui.cpp.

264{
265 currentExpression.clear();
266 justEvaluated = false;
268}

◆ on_btn_div_clicked

void Gui::on_btn_div_clicked ( )
privateslot

Definition at line 177 of file gui.cpp.

177{ appendOperator("/"); }

◆ on_btn_dot_clicked

void Gui::on_btn_dot_clicked ( )
privateslot

Appends a decimal point to the current expression.

Only allows one decimal point per number segment. If the calculator just evaluated, clears the expression first.

Definition at line 187 of file gui.cpp.

188{
189 if (justEvaluated) {
190 currentExpression.clear();
191 justEvaluated = false;
192 }
193
194 // Find the current number segment (after the last operator)
195 int lastOp = -1;
196 for (int i = currentExpression.size() - 1; i >= 0; --i) {
197 QChar c = currentExpression[i];
198 if (c == '+' || c == '-' || c == '*' ||
199 c == '/' || c == '%' || c == '^') {
200 lastOp = i;
201 break;
202 }
203 }
204 QString segment = currentExpression.mid(lastOp + 1);
205
206 // Only add a dot if this number segment doesn't already have one
207 if (!segment.contains('.')) {
208 currentExpression += ".";
210 }
211}

◆ on_btn_equal_clicked

void Gui::on_btn_equal_clicked ( )
privateslot

Evaluates the current expression.

Supports basic binary operations and simple unary operations. Displays error messages if invalid operations occur.

Definition at line 294 of file gui.cpp.

295{
296 if (currentExpression.isEmpty())
297 return;
298
299
300 if (justEvaluated)
301 return;
302
303
304 if (endsWithOperator())
305 return;
306
308 double result = 0.0;
309 bool evaluated = false;
310
311
312
313
314 if (currentExpression.endsWith("!")) {
315 int val = currentExpression.chopped(1).toInt();
316 result = mathlib::factorial(val, err);
317 evaluated = true;
318 }
319
320 else if (currentExpression.startsWith("√")) {
321 double val = currentExpression.mid(1).toDouble();
322 result = mathlib::root(val, 2, err);
323 evaluated = true;
324 }
325
326
327
328 if (!evaluated) {
329 int pos = -1;
330 QChar op = '\0';
331
332
333 const QString ops = "+*/%^";
334 for (QChar c : ops) {
335 pos = findOperatorPos(c);
336 if (pos != -1) { op = c; break; }
337 }
338
339 if (pos == -1) {
340 pos = findOperatorPos('-');
341 if (pos != -1) op = '-';
342 }
343
344 if (pos != -1) {
345 double left = currentExpression.left(pos).toDouble();
346 double right = currentExpression.mid(pos + 1).toDouble();
347
348 if (op == '+') result = mathlib::add(left, right);
349 else if (op == '-') result = mathlib::subtract(left, right);
350 else if (op == '*') result = mathlib::multiply(left, right);
351 else if (op == '/') result = mathlib::divide(left, right, err);
352 else if (op == '%') result = mathlib::modulo(left, right, err);
353 else if (op == '^') result = mathlib::power(left, static_cast<int>(right));
354
355 evaluated = true;
356 }
357 }
358
359 // Plain number — just keep it
360 if (!evaluated) {
361 result = currentExpression.toDouble();
362 }
363
364 if (err != mathlib::OK) {
365 showError(err);
366 currentExpression.clear();
367 justEvaluated = false;
369 return;
370 }
371
372 currentExpression = QString::number(result);
373 justEvaluated = true;
375}
int findOperatorPos(QChar op) const
Finds the position of the binary operator in the expression.
Definition gui.cpp:278
void showError(mathlib::MathError err)
Displays an error message based on mathlib error code.
Definition gui.cpp:39
double root(double base, int n, MathError &err)
Implementation of function root.
Definition mathlib.cpp:85
double add(double a, double b)
Implementation of function add.
Definition mathlib.cpp:9
double multiply(double a, double b)
Implementation of function multiply.
Definition mathlib.cpp:25
double modulo(double a, double b, MathError &err)
Implementation of function modulo.
Definition mathlib.cpp:111
MathError
Definition mathlib.h:11
double divide(double a, double b, MathError &err)
Implementation of function divide.
Definition mathlib.cpp:33
double subtract(double a, double b)
Implementation of function subtract.
Definition mathlib.cpp:17
double factorial(int a, MathError &err)
Implementation of function factorial.
Definition mathlib.cpp:47
double power(double base, int exp)
Implementation of function power.
Definition mathlib.cpp:67

◆ on_btn_fac_clicked

void Gui::on_btn_fac_clicked ( )
privateslot

Appends factorial operator.

Only allowed at the end of a number (unary postfix operator). Prevents factorial on an empty expression or after an operator.

Definition at line 238 of file gui.cpp.

239{
240 if (justEvaluated) {
241 justEvaluated = false;
242 }
243
244 if (currentExpression.isEmpty() || endsWithOperator())
245 return;
246
247 // Don't allow factorial if there's already an operator (keeps single-op rule)
248 // but do allow it as the sole operation on a plain number
249 if (hasOperator())
250 return;
251
252 // Don't allow double factorial
253 if (currentExpression.endsWith("!"))
254 return;
255
256 currentExpression += "!";
258}

◆ on_btn_minus_clicked

void Gui::on_btn_minus_clicked ( )
privateslot

Definition at line 175 of file gui.cpp.

175{ appendOperator("-"); }

◆ on_btn_mod_clicked

void Gui::on_btn_mod_clicked ( )
privateslot

Definition at line 178 of file gui.cpp.

178{ appendOperator("%"); }

◆ on_btn_mul_clicked

void Gui::on_btn_mul_clicked ( )
privateslot

Definition at line 176 of file gui.cpp.

176{ appendOperator("*"); }

◆ on_btn_plus_clicked

void Gui::on_btn_plus_clicked ( )
privateslot

Operation button handlers.

Definition at line 174 of file gui.cpp.

174{ appendOperator("+"); }

◆ on_btn_pow_clicked

void Gui::on_btn_pow_clicked ( )
privateslot

Definition at line 179 of file gui.cpp.

179{ appendOperator("^"); }

◆ on_btn_root_clicked

void Gui::on_btn_root_clicked ( )
privateslot

Appends square root operator.

Only allowed at the start of an expression (unary prefix operator).

Definition at line 218 of file gui.cpp.

219{
220 if (justEvaluated) {
221 currentExpression.clear();
222 justEvaluated = false;
223 }
224
225 // √ is a prefix unary op — only valid at the beginning
226 if (currentExpression.isEmpty()) {
227 currentExpression = "√";
229 }
230}

◆ showError()

void Gui::showError ( mathlib::MathError err)
private

Displays an error message based on mathlib error code.

Parameters
errError type returned from mathlib.

Definition at line 39 of file gui.cpp.

40{
41 switch (err) {
43 QMessageBox::warning(this, "Error", "Division by zero!");
44 break;
46 QMessageBox::warning(this, "Error", "Factorial of negative number!");
47 break;
49 QMessageBox::warning(this, "Error", "Invalid root operation!");
50 break;
52 QMessageBox::warning(this, "Error", "Invalid argument!");
53 break;
54 default:
55 break;
56 }
57}
@ INVALID_ROOT
Definition mathlib.h:15
@ NEGATIVE_FACTORIAL
Definition mathlib.h:14
@ DIVISION_BY_ZERO
Definition mathlib.h:13
@ INVALID_ARGUMENT
Definition mathlib.h:16

◆ updateDisplay()

void Gui::updateDisplay ( )
private

Updates the calculator display.

If the expression is empty, displays 0.

Definition at line 64 of file gui.cpp.

65{
66 ui->display->setText(currentExpression.isEmpty() ? "0" : currentExpression);
67}

Member Data Documentation

◆ currentExpression

QString Gui::currentExpression
private

Definition at line 63 of file gui.h.

◆ justEvaluated

bool Gui::justEvaluated
private

Definition at line 64 of file gui.h.

◆ ui

Ui::Gui* Gui::ui
private

Definition at line 62 of file gui.h.


The documentation for this class was generated from the following files: