/**************************************************************************** **** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).** All rights reserved.** Contact: Nokia Corporation (qt-info@)**** This file is part of the examples of the Qt Toolkit.**** $QT_BEGIN_LICENSE:LGPL$** Commercial Usage** Licensees holding valid Qt Commercial licenses may use this file in** accordance with the Qt Commercial License Agreement provided with the** Software or, alternatively, in accordance with the terms contained in** a written agreement between you and Nokia.**** GNU Lesser General Public License Usage** Alternatively, this file may be used under the terms of the GNU Lesser** General Public License version 2.1 as published by the Free Software** Foundation and appearing in the file LICENSE.LGPL included in the** packaging of this file. Please review the following information to** ensure the GNU Lesser General Public License version 2.1 requirements** will be met: /licenses/old-licenses/lgpl-2.1.html.**** In addition, as a special exception, Nokia gives you certain additional** rights. These rights are described in the Nokia Qt LGPL Exception** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.**** GNU General Public License Usage** Alternatively, this file may be used under the terms of the GNU** General Public License version 3.0 as published by the Free Software** Foundation and appearing in the file LICENSE.GPL included in the** packaging of this file. Please review the following information to** ensure the GNU General Public License version 3.0 requirements will be** met: /copyleft/gpl.html.**** If you have questions regarding the use of this file, please contact** Nokia at qt-info@.** $QT_END_LICENSE$******************************************************************************/ #include <QtGui>#include <math.h>#include "button.h"#include "calculator.h"//! [0]Calculator::Calculator(QWidget *parent): QDialog(parent){sumInMemory = 0.0;sumSoFar = 0.0;factorSoFar = 0.0;waitingForOperand = true;waitingForE = false;//! [0]//! [1]display = new QLineEdit("0");//! [1] //! [2]display->setReadOnly(true);display->setAlignment(Qt::AlignRight);display->setMaxLength(15);QFont font = display->font();font.setPointSize(font.pointSize() + 8);display->setFont(font);//! [2]//! [4]for (int i = 0; i < NumDigitButtons; ++i) {digitButtons[i] = createButton(QString::number(i), SLOT(digitClicked()));}Button *pointButton = createButton(tr("."), SLOT(pointClicked()));Button *changeSignButton = createButton(tr("\261"), SLOT(changeSignClicked()));Button *backspaceButton = createButton(tr("Backspace"), SLOT(backspaceClicked()));Button *clearButton = createButton(tr("Clear"), SLOT(clear()));Button *clearAllButton = createButton(tr("Clear All"), SLOT(clearAll()));Button *clearMemoryButton = createButton(tr("MC"), SLOT(clearMemory()));Button *readMemoryButton = createButton(tr("MR"), SLOT(readMemory()));Button *setMemoryButton = createButton(tr("MS"), SLOT(setMemory()));Button *addToMemoryButton = createButton(tr("M+"), SLOT(addToMemory()));Button *divisionButton = createButton(tr("\367"), SLOT(multiplicativeOperatorClicked()));Button *timesButton = createButton(tr("\327"), SLOT(multiplicativeOperatorClicked()));Button *minusButton = createButton(tr("-"), SLOT(additiveOperatorClicked()));Button *plusButton = createButton(tr("+"), SLOT(additiveOperatorClicked()));Button *squareRootButton = createButton(tr("Sqrt"), SLOT(unaryOperatorClicked()));Button *powerButton = createButton(tr("x\262"), SLOT(unaryOperatorClicked()));Button *reciprocalButton = createButton(tr("1/x"), SLOT(unaryOperatorClicked()));Button *sinhButton = createButton(tr("sinh"), SLOT(unaryOperatorClicked()));Button *coshButton = createButton(tr("cosh"), SLOT(unaryOperatorClicked()));Button *tanhButton = createButton(tr("tanh"), SLOT(unaryOperatorClicked()));Button *sinButton = createButton(tr("sin"), SLOT(unaryOperatorClicked()));Button *cosButton = createButton(tr("cos"), SLOT(unaryOperatorClicked()));Button *tanButton = createButton(tr("tan"), SLOT(unaryOperatorClicked()));Button *mi2Button = createButton(tr("x^2"), SLOT(unaryOperatorClicked()));Button *miyButton = createButton(tr("x^y"), SLOT(multiplicativeOperatorClicked()));Button *mi3Button = createButton(tr("x^3"), SLOT(unaryOperatorClicked()));Button *factorButton = createButton(tr("n!"), SLOT(unaryOperatorClicked()));Button *genyButton = createButton(tr("x^1/y"), SLOT(multiplicativeOperatorClicked()));Button *gen3Button = createButton(tr("x^1/3"), SLOT(unaryOperatorClicked()));Button *expButton = createButton(tr("Exp"), SLOT(expOperatorClicked()));Button *modButton = createButton(tr("Mod"), SLOT(multiplicativeOperatorClicked()));Button *logButton = createButton(tr("log"), SLOT(unaryOperatorClicked()));Button *mi10Button = createButton(tr("10^x"), SLOT(unaryOperatorClicked()));Button *equalButton = createButton(tr("="), SLOT(equalClicked()));//! [4]//! [5]QGridLayout *mainLayout = new QGridLayout;//! [5] //! [6]mainLayout->setSizeConstraint(QLayout::SetFixedSize);mainLayout->addWidget(display, 0, 0, 1, 10);mainLayout->addWidget(backspaceButton, 1, 0, 1, 4);mainLayout->addWidget(clearButton, 1, 4, 1, 3);mainLayout->addWidget(clearAllButton, 1, 7, 1, 3);mainLayout->addWidget(clearMemoryButton, 2, 0);mainLayout->addWidget(readMemoryButton, 3, 0);mainLayout->addWidget(setMemoryButton, 4, 0);mainLayout->addWidget(addToMemoryButton, 5, 0);for (int i = 1; i < NumDigitButtons; ++i) {int row = ((9 - i) / 3) + 2;int column = ((i - 1) % 3) + 1;mainLayout->addWidget(digitButtons[i], row, column);}mainLayout->addWidget(digitButtons[0], 5, 1);mainLayout->addWidget(pointButton, 5, 2);mainLayout->addWidget(changeSignButton, 5, 3);mainLayout->addWidget(divisionButton, 2, 4);mainLayout->addWidget(timesButton, 3, 4);mainLayout->addWidget(minusButton, 4, 4);mainLayout->addWidget(plusButton, 5, 4);mainLayout->addWidget(squareRootButton, 2, 5);mainLayout->addWidget(powerButton, 3, 5);mainLayout->addWidget(reciprocalButton, 4, 5);mainLayout->addWidget(equalButton, 5, 5);mainLayout->addWidget(sinhButton, 2, 6);mainLayout->addWidget(coshButton, 3, 6);mainLayout->addWidget(tanhButton, 4, 6);mainLayout->addWidget(expButton, 5, 6);mainLayout->addWidget(sinButton, 2, 7);mainLayout->addWidget(cosButton, 3, 7);mainLayout->addWidget(tanButton, 4, 7);mainLayout->addWidget(modButton, 5, 7);mainLayout->addWidget(mi2Button, 2, 8);mainLayout->addWidget(miyButton, 3, 8);mainLayout->addWidget(mi3Button, 4, 8);mainLayout->addWidget(logButton, 5, 8);mainLayout->addWidget(factorButton, 2, 9);mainLayout->addWidget(genyButton, 3, 9);mainLayout->addWidget(gen3Button, 4, 9);mainLayout->addWidget(mi10Button, 5, 9);setLayout(mainLayout);setWindowTitle(tr("Calculator"));}//! [6]//! [7]void Calculator::digitClicked(){Button *clickedButton = qobject_cast<Button *>(sender());int digitValue = clickedButton->text().toInt();if (display->text() == "0" && digitValue == 0.0)return;if (waitingForOperand) {display->clear();waitingForOperand = false;}display->setText(display->text() + QString::number(digitValue)); }//! [7]int factor(int n){int result = 1;while(n!=1){result=result*n;n--;}return result;}//! [8]void Calculator::unaryOperatorClicked()//! [8] //! [9]{Button *clickedButton = qobject_cast<Button *>(sender());QString clickedOperator = clickedButton->text();double operand = display->text().toDouble();double result = 0.0;if (clickedOperator == tr("Sqrt")) {if (operand < 0.0) {abortOperation();return;}result = sqrt(operand);} else if (clickedOperator == tr("x\262")) {result = pow(operand, 2.0);} else if (clickedOperator == tr("1/x")) {if (operand == 0.0) {abortOperation();return;}result = 1.0 / operand;} else if (clickedOperator == tr("sin")) {result = sin(operand);} else if (clickedOperator == tr("cos")) {result = cos(operand);} else if (clickedOperator == tr("tan")) {result = tan(operand);} else if (clickedOperator == tr("sinh")) { result = sinh(operand);} else if (clickedOperator == tr("cosh")) { result = cosh(operand);} else if (clickedOperator == tr("tanh")) { result = tanh(operand);} else if (clickedOperator == tr("x^2")) { result = operand * operand;} else if (clickedOperator == tr("x^3")) { result = operand * operand * operand;} else if (clickedOperator == tr("n!")) {if (operand < 0.0){abortOperation();return;}result = factor(operand);} else if (clickedOperator == tr("log")) {if(operand <= 0.0) {abortOperation();return;}result = log(operand)/log(10);} else if (clickedOperator == tr("10^x")) { result = pow(10, operand);} else if (clickedOperator == tr("x^1/3")) { result = pow(operand, 1.0/3.0);}display->setText(QString::number(result));waitingForOperand = true;waitingForE = false;}//! [9]//! [10]void Calculator::additiveOperatorClicked()//! [10] //! [11]{Button *clickedButton = qobject_cast<Button *>(sender());QString clickedOperator = clickedButton->text();double operand = display->text().toDouble();//! [11] //! [12]if (!pendingMultiplicativeOperator.isEmpty()) {//! [12] //! [13]if (!calculate(operand, pendingMultiplicativeOperator)) { abortOperation();return;}display->setText(QString::number(factorSoFar));operand = factorSoFar;factorSoFar = 0.0;pendingMultiplicativeOperator.clear();}//! [13] //! [14]if (!pendingAdditiveOperator.isEmpty()) {//! [14] //! [15]if (!calculate(operand, pendingAdditiveOperator)) {abortOperation();return;}display->setText(QString::number(sumSoFar));} else {sumSoFar = operand;}//! [15] //! [16]pendingAdditiveOperator = clickedOperator;//! [16] //! [17]waitingForOperand = true;waitingForE = false;}//! [17]//! [18]void Calculator::multiplicativeOperatorClicked(){Button *clickedButton = qobject_cast<Button *>(sender());QString clickedOperator = clickedButton->text();double operand = display->text().toDouble();if (!pendingMultiplicativeOperator.isEmpty()) {if (!calculate(operand, pendingMultiplicativeOperator)) { abortOperation();return;}display->setText(QString::number(factorSoFar));} else {factorSoFar = operand;}pendingMultiplicativeOperator = clickedOperator;waitingForOperand = true;waitingForE = false;}//! [18]void Calculator::expOperatorClicked(){Button *clickedButton = qobject_cast<Button *>(sender());QString clickedOperator = clickedButton->text();double operand = display->text().toDouble();if(!waitingForE){beforeE = operand;display->setText(QString::number(beforeE)+tr("e+0"));waitingForE = true;}}//! [20]void Calculator::equalClicked(){double operand = display->text().toDouble();if (!pendingMultiplicativeOperator.isEmpty()) {if (!calculate(operand, pendingMultiplicativeOperator)) { abortOperation();return;}operand = factorSoFar;factorSoFar = 0.0;pendingMultiplicativeOperator.clear();}if (!pendingAdditiveOperator.isEmpty()) {if (!calculate(operand, pendingAdditiveOperator)) { abortOperation();return;}pendingAdditiveOperator.clear();} else {sumSoFar = operand;}display->setText(QString::number(sumSoFar));sumSoFar = 0.0;waitingForOperand = true;}//! [20]//! [22]void Calculator::pointClicked(){if (waitingForOperand)display->setText("0");if (!display->text().contains("."))display->setText(display->text() + tr("."));waitingForOperand = false;}//! [22]//! [24]void Calculator::changeSignClicked(){QString text = display->text();double value = text.toDouble();if (value > 0.0) {text.prepend(tr("-"));} else if (value < 0.0) {text.remove(0, 1);}display->setText(text);}//! [24]//! [26]void Calculator::backspaceClicked(){if (waitingForOperand)return;QString text = display->text();text.chop(1);if (text.isEmpty()) {text = "0";waitingForOperand = true;}display->setText(text);}//! [26]//! [28]void Calculator::clear(){if (waitingForOperand)return;display->setText("0");waitingForOperand = true;}//! [28]//! [30]void Calculator::clearAll(){sumSoFar = 0.0;factorSoFar = 0.0;pendingAdditiveOperator.clear();pendingMultiplicativeOperator.clear();display->setText("0");waitingForOperand = true;}//! [30]//! [32]void Calculator::clearMemory(){sumInMemory = 0.0;}void Calculator::readMemory(){display->setText(QString::number(sumInMemory));waitingForOperand = true;}void Calculator::setMemory(){equalClicked();sumInMemory = display->text().toDouble();}void Calculator::addToMemory(){equalClicked();sumInMemory += display->text().toDouble();}//! [32]//! [34]Button *Calculator::createButton(const QString &text, const char *member){Button *button = new Button(text);connect(button, SIGNAL(clicked()), this, member);return button;}//! [34]//! [36]void Calculator::abortOperation(){clearAll();display->setText(tr("####"));}//! [36]//! [38]bool Calculator::calculate(double rightOperand, const QString &pendingOperator) {if (pendingOperator == tr("+")) {sumSoFar += rightOperand;} else if (pendingOperator == tr("-")) {sumSoFar -= rightOperand;} else if (pendingOperator == tr("\327")) {factorSoFar *= rightOperand;} else if (pendingOperator == tr("\367")) {if (rightOperand == 0.0)return false;factorSoFar /= rightOperand;} else if (pendingOperator == tr("x^y")) {factorSoFar = pow(factorSoFar, rightOperand);} else if (pendingOperator == tr("x^1/y")) {if (rightOperand == 0.0)return false;factorSoFar = pow(factorSoFar, 1.0/rightOperand);} else if (pendingOperator == tr("Mod")) {if (rightOperand == 0.0)return false;factorSoFar = (int)factorSoFar % (int)rightOperand;}return true;}//! [38]。