examples/widgets/calculator/calculator.cpp
changeset 0 1918ee327afb
child 4 3b1da2848fc7
equal deleted inserted replaced
-1:000000000000 0:1918ee327afb
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     4 ** All rights reserved.
       
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
       
     6 **
       
     7 ** This file is part of the examples of the Qt Toolkit.
       
     8 **
       
     9 ** $QT_BEGIN_LICENSE:LGPL$
       
    10 ** No Commercial Usage
       
    11 ** This file contains pre-release code and may not be distributed.
       
    12 ** You may use this file in accordance with the terms and conditions
       
    13 ** contained in the Technology Preview License Agreement accompanying
       
    14 ** this package.
       
    15 **
       
    16 ** GNU Lesser General Public License Usage
       
    17 ** Alternatively, this file may be used under the terms of the GNU Lesser
       
    18 ** General Public License version 2.1 as published by the Free Software
       
    19 ** Foundation and appearing in the file LICENSE.LGPL included in the
       
    20 ** packaging of this file.  Please review the following information to
       
    21 ** ensure the GNU Lesser General Public License version 2.1 requirements
       
    22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
       
    23 **
       
    24 ** In addition, as a special exception, Nokia gives you certain additional
       
    25 ** rights.  These rights are described in the Nokia Qt LGPL Exception
       
    26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
       
    27 **
       
    28 ** If you have questions regarding the use of this file, please contact
       
    29 ** Nokia at qt-info@nokia.com.
       
    30 **
       
    31 **
       
    32 **
       
    33 **
       
    34 **
       
    35 **
       
    36 **
       
    37 **
       
    38 ** $QT_END_LICENSE$
       
    39 **
       
    40 ****************************************************************************/
       
    41 
       
    42 #include <QtGui>
       
    43 
       
    44 #include <math.h>
       
    45 
       
    46 #include "button.h"
       
    47 #include "calculator.h"
       
    48 
       
    49 //! [0]
       
    50 Calculator::Calculator(QWidget *parent)
       
    51     : QDialog(parent)
       
    52 {
       
    53     sumInMemory = 0.0;
       
    54     sumSoFar = 0.0;
       
    55     factorSoFar = 0.0;
       
    56     waitingForOperand = true;
       
    57 //! [0]
       
    58 
       
    59 //! [1]
       
    60     display = new QLineEdit("0");
       
    61 //! [1] //! [2]
       
    62     display->setReadOnly(true);
       
    63     display->setAlignment(Qt::AlignRight);
       
    64     display->setMaxLength(15);
       
    65 
       
    66     QFont font = display->font();
       
    67     font.setPointSize(font.pointSize() + 8);
       
    68     display->setFont(font);
       
    69 //! [2]
       
    70 
       
    71 //! [4]
       
    72     for (int i = 0; i < NumDigitButtons; ++i) {
       
    73 	digitButtons[i] = createButton(QString::number(i), SLOT(digitClicked()));
       
    74     }
       
    75 
       
    76     Button *pointButton = createButton(tr("."), SLOT(pointClicked()));
       
    77     Button *changeSignButton = createButton(tr("\261"), SLOT(changeSignClicked()));
       
    78 
       
    79     Button *backspaceButton = createButton(tr("Backspace"), SLOT(backspaceClicked()));
       
    80     Button *clearButton = createButton(tr("Clear"), SLOT(clear()));
       
    81     Button *clearAllButton = createButton(tr("Clear All"), SLOT(clearAll()));
       
    82 
       
    83     Button *clearMemoryButton = createButton(tr("MC"), SLOT(clearMemory()));
       
    84     Button *readMemoryButton = createButton(tr("MR"), SLOT(readMemory()));
       
    85     Button *setMemoryButton = createButton(tr("MS"), SLOT(setMemory()));
       
    86     Button *addToMemoryButton = createButton(tr("M+"), SLOT(addToMemory()));
       
    87 
       
    88     Button *divisionButton = createButton(tr("\367"), SLOT(multiplicativeOperatorClicked()));
       
    89     Button *timesButton = createButton(tr("\327"), SLOT(multiplicativeOperatorClicked()));
       
    90     Button *minusButton = createButton(tr("-"), SLOT(additiveOperatorClicked()));
       
    91     Button *plusButton = createButton(tr("+"), SLOT(additiveOperatorClicked()));
       
    92 
       
    93     Button *squareRootButton = createButton(tr("Sqrt"), SLOT(unaryOperatorClicked()));
       
    94     Button *powerButton = createButton(tr("x\262"), SLOT(unaryOperatorClicked()));
       
    95     Button *reciprocalButton = createButton(tr("1/x"), SLOT(unaryOperatorClicked()));
       
    96     Button *equalButton = createButton(tr("="), SLOT(equalClicked()));
       
    97 //! [4]
       
    98 
       
    99 //! [5]
       
   100     QGridLayout *mainLayout = new QGridLayout;
       
   101 //! [5] //! [6]
       
   102     mainLayout->setSizeConstraint(QLayout::SetFixedSize);
       
   103 
       
   104     mainLayout->addWidget(display, 0, 0, 1, 6);
       
   105     mainLayout->addWidget(backspaceButton, 1, 0, 1, 2);
       
   106     mainLayout->addWidget(clearButton, 1, 2, 1, 2);
       
   107     mainLayout->addWidget(clearAllButton, 1, 4, 1, 2);
       
   108 
       
   109     mainLayout->addWidget(clearMemoryButton, 2, 0);
       
   110     mainLayout->addWidget(readMemoryButton, 3, 0);
       
   111     mainLayout->addWidget(setMemoryButton, 4, 0);
       
   112     mainLayout->addWidget(addToMemoryButton, 5, 0);
       
   113 
       
   114     for (int i = 1; i < NumDigitButtons; ++i) {
       
   115         int row = ((9 - i) / 3) + 2;
       
   116         int column = ((i - 1) % 3) + 1;
       
   117         mainLayout->addWidget(digitButtons[i], row, column);
       
   118     }
       
   119 
       
   120     mainLayout->addWidget(digitButtons[0], 5, 1);
       
   121     mainLayout->addWidget(pointButton, 5, 2);
       
   122     mainLayout->addWidget(changeSignButton, 5, 3);
       
   123 
       
   124     mainLayout->addWidget(divisionButton, 2, 4);
       
   125     mainLayout->addWidget(timesButton, 3, 4);
       
   126     mainLayout->addWidget(minusButton, 4, 4);
       
   127     mainLayout->addWidget(plusButton, 5, 4);
       
   128 
       
   129     mainLayout->addWidget(squareRootButton, 2, 5);
       
   130     mainLayout->addWidget(powerButton, 3, 5);
       
   131     mainLayout->addWidget(reciprocalButton, 4, 5);
       
   132     mainLayout->addWidget(equalButton, 5, 5);
       
   133     setLayout(mainLayout);
       
   134 
       
   135     setWindowTitle(tr("Calculator"));
       
   136 }
       
   137 //! [6]
       
   138 
       
   139 //! [7]
       
   140 void Calculator::digitClicked()
       
   141 {
       
   142     Button *clickedButton = qobject_cast<Button *>(sender());
       
   143     int digitValue = clickedButton->text().toInt();
       
   144     if (display->text() == "0" && digitValue == 0.0)
       
   145         return;
       
   146 
       
   147     if (waitingForOperand) {
       
   148         display->clear();
       
   149 	waitingForOperand = false;
       
   150     }
       
   151     display->setText(display->text() + QString::number(digitValue));
       
   152 }
       
   153 //! [7]
       
   154 
       
   155 //! [8]
       
   156 void Calculator::unaryOperatorClicked()
       
   157 //! [8] //! [9]
       
   158 {
       
   159     Button *clickedButton = qobject_cast<Button *>(sender());
       
   160     QString clickedOperator = clickedButton->text();
       
   161     double operand = display->text().toDouble();
       
   162     double result = 0.0;
       
   163 
       
   164     if (clickedOperator == tr("Sqrt")) {
       
   165         if (operand < 0.0) {
       
   166             abortOperation();
       
   167             return;
       
   168         }
       
   169         result = sqrt(operand);
       
   170     } else if (clickedOperator == tr("x\262")) {
       
   171         result = pow(operand, 2.0);
       
   172     } else if (clickedOperator == tr("1/x")) {
       
   173         if (operand == 0.0) {
       
   174 	    abortOperation();
       
   175 	    return;
       
   176         }
       
   177         result = 1.0 / operand;
       
   178     }
       
   179     display->setText(QString::number(result));
       
   180     waitingForOperand = true;
       
   181 }
       
   182 //! [9]
       
   183 
       
   184 //! [10]
       
   185 void Calculator::additiveOperatorClicked()
       
   186 //! [10] //! [11]
       
   187 {
       
   188     Button *clickedButton = qobject_cast<Button *>(sender());
       
   189     QString clickedOperator = clickedButton->text();
       
   190     double operand = display->text().toDouble();
       
   191 
       
   192 //! [11] //! [12]
       
   193     if (!pendingMultiplicativeOperator.isEmpty()) {
       
   194 //! [12] //! [13]
       
   195         if (!calculate(operand, pendingMultiplicativeOperator)) {
       
   196             abortOperation();
       
   197 	    return;
       
   198         }
       
   199         display->setText(QString::number(factorSoFar));
       
   200         operand = factorSoFar;
       
   201         factorSoFar = 0.0;
       
   202         pendingMultiplicativeOperator.clear();
       
   203     }
       
   204 
       
   205 //! [13] //! [14]
       
   206     if (!pendingAdditiveOperator.isEmpty()) {
       
   207 //! [14] //! [15]
       
   208         if (!calculate(operand, pendingAdditiveOperator)) {
       
   209             abortOperation();
       
   210 	    return;
       
   211         }
       
   212         display->setText(QString::number(sumSoFar));
       
   213     } else {
       
   214         sumSoFar = operand;
       
   215     }
       
   216 
       
   217 //! [15] //! [16]
       
   218     pendingAdditiveOperator = clickedOperator;
       
   219 //! [16] //! [17]
       
   220     waitingForOperand = true;
       
   221 }
       
   222 //! [17]
       
   223 
       
   224 //! [18]
       
   225 void Calculator::multiplicativeOperatorClicked()
       
   226 {
       
   227     Button *clickedButton = qobject_cast<Button *>(sender());
       
   228     QString clickedOperator = clickedButton->text();
       
   229     double operand = display->text().toDouble();
       
   230 
       
   231     if (!pendingMultiplicativeOperator.isEmpty()) {
       
   232         if (!calculate(operand, pendingMultiplicativeOperator)) {
       
   233             abortOperation();
       
   234 	    return;
       
   235         }
       
   236         display->setText(QString::number(factorSoFar));
       
   237     } else {
       
   238         factorSoFar = operand;
       
   239     }
       
   240 
       
   241     pendingMultiplicativeOperator = clickedOperator;
       
   242     waitingForOperand = true;
       
   243 }
       
   244 //! [18]
       
   245 
       
   246 //! [20]
       
   247 void Calculator::equalClicked()
       
   248 {
       
   249     double operand = display->text().toDouble();
       
   250 
       
   251     if (!pendingMultiplicativeOperator.isEmpty()) {
       
   252         if (!calculate(operand, pendingMultiplicativeOperator)) {
       
   253             abortOperation();
       
   254 	    return;
       
   255         }
       
   256         operand = factorSoFar;
       
   257         factorSoFar = 0.0;
       
   258         pendingMultiplicativeOperator.clear();
       
   259     }
       
   260     if (!pendingAdditiveOperator.isEmpty()) {
       
   261         if (!calculate(operand, pendingAdditiveOperator)) {
       
   262             abortOperation();
       
   263 	    return;
       
   264         }
       
   265         pendingAdditiveOperator.clear();
       
   266     } else {
       
   267         sumSoFar = operand;
       
   268     }
       
   269 
       
   270     display->setText(QString::number(sumSoFar));
       
   271     sumSoFar = 0.0;
       
   272     waitingForOperand = true;
       
   273 }
       
   274 //! [20]
       
   275 
       
   276 //! [22]
       
   277 void Calculator::pointClicked()
       
   278 {
       
   279     if (waitingForOperand)
       
   280         display->setText("0");
       
   281     if (!display->text().contains("."))
       
   282         display->setText(display->text() + tr("."));
       
   283     waitingForOperand = false;
       
   284 }
       
   285 //! [22]
       
   286 
       
   287 //! [24]
       
   288 void Calculator::changeSignClicked()
       
   289 {
       
   290     QString text = display->text();
       
   291     double value = text.toDouble();
       
   292 
       
   293     if (value > 0.0) {
       
   294         text.prepend(tr("-"));
       
   295     } else if (value < 0.0) {
       
   296         text.remove(0, 1);
       
   297     }
       
   298     display->setText(text);
       
   299 }
       
   300 //! [24]
       
   301 
       
   302 //! [26]
       
   303 void Calculator::backspaceClicked()
       
   304 {
       
   305     if (waitingForOperand)
       
   306         return;
       
   307 
       
   308     QString text = display->text();
       
   309     text.chop(1);
       
   310     if (text.isEmpty()) {
       
   311         text = "0";
       
   312         waitingForOperand = true;
       
   313     }
       
   314     display->setText(text);
       
   315 }
       
   316 //! [26]
       
   317 
       
   318 //! [28]
       
   319 void Calculator::clear()
       
   320 {
       
   321     if (waitingForOperand)
       
   322         return;
       
   323 
       
   324     display->setText("0");
       
   325     waitingForOperand = true;
       
   326 }
       
   327 //! [28]
       
   328 
       
   329 //! [30]
       
   330 void Calculator::clearAll()
       
   331 {
       
   332     sumSoFar = 0.0;
       
   333     factorSoFar = 0.0;
       
   334     pendingAdditiveOperator.clear();
       
   335     pendingMultiplicativeOperator.clear();
       
   336     display->setText("0");
       
   337     waitingForOperand = true;
       
   338 }
       
   339 //! [30]
       
   340 
       
   341 //! [32]
       
   342 void Calculator::clearMemory()
       
   343 {
       
   344     sumInMemory = 0.0;
       
   345 }
       
   346 
       
   347 void Calculator::readMemory()
       
   348 {
       
   349     display->setText(QString::number(sumInMemory));
       
   350     waitingForOperand = true;
       
   351 }
       
   352 
       
   353 void Calculator::setMemory()
       
   354 {
       
   355     equalClicked();
       
   356     sumInMemory = display->text().toDouble();
       
   357 }
       
   358 
       
   359 void Calculator::addToMemory()
       
   360 {
       
   361     equalClicked();
       
   362     sumInMemory += display->text().toDouble();
       
   363 }
       
   364 //! [32]
       
   365 //! [34]
       
   366 Button *Calculator::createButton(const QString &text, const char *member)
       
   367 {
       
   368     Button *button = new Button(text);
       
   369     connect(button, SIGNAL(clicked()), this, member);
       
   370     return button;
       
   371 }
       
   372 //! [34]
       
   373 
       
   374 //! [36]
       
   375 void Calculator::abortOperation()
       
   376 {
       
   377     clearAll();
       
   378     display->setText(tr("####"));
       
   379 }
       
   380 //! [36]
       
   381 
       
   382 //! [38]
       
   383 bool Calculator::calculate(double rightOperand, const QString &pendingOperator)
       
   384 {
       
   385     if (pendingOperator == tr("+")) {
       
   386         sumSoFar += rightOperand;
       
   387     } else if (pendingOperator == tr("-")) {
       
   388         sumSoFar -= rightOperand;
       
   389     } else if (pendingOperator == tr("\327")) {
       
   390         factorSoFar *= rightOperand;
       
   391     } else if (pendingOperator == tr("\367")) {
       
   392 	if (rightOperand == 0.0)
       
   393 	    return false;
       
   394 	factorSoFar /= rightOperand;
       
   395     }
       
   396     return true;
       
   397 }
       
   398 //! [38]