~oif-team/ubuntu/natty/qt4-x11/xi2.1

« back to all changes in this revision

Viewing changes to examples/widgets/calculator/calculator.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Adam Conrad
  • Date: 2005-08-24 04:09:09 UTC
  • Revision ID: james.westby@ubuntu.com-20050824040909-xmxe9jfr4a0w5671
Tags: upstream-4.0.0
Import upstream version 4.0.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/****************************************************************************
 
2
**
 
3
** Copyright (C) 2005-2005 Trolltech AS. All rights reserved.
 
4
**
 
5
** This file is part of the example classes of the Qt Toolkit.
 
6
**
 
7
** This file may be distributed under the terms of the Q Public License
 
8
** as defined by Trolltech AS of Norway and appearing in the file
 
9
** LICENSE.QPL included in the packaging of this file.
 
10
**
 
11
** This file may be distributed and/or modified under the terms of the
 
12
** GNU General Public License version 2 as published by the Free Software
 
13
** Foundation and appearing in the file LICENSE.GPL included in the
 
14
** packaging of this file.
 
15
**
 
16
** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
 
17
**   information about Qt Commercial License Agreements.
 
18
** See http://www.trolltech.com/qpl/ for QPL licensing information.
 
19
** See http://www.trolltech.com/gpl/ for GPL licensing information.
 
20
**
 
21
** Contact info@trolltech.com if any conditions of this licensing are
 
22
** not clear to you.
 
23
**
 
24
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
 
25
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 
26
**
 
27
****************************************************************************/
 
28
 
 
29
#include <QtGui>
 
30
 
 
31
#include <math.h>
 
32
 
 
33
#include "button.h"
 
34
#include "calculator.h"
 
35
 
 
36
Calculator::Calculator(QWidget *parent)
 
37
    : QDialog(parent)
 
38
{
 
39
    sumInMemory = 0.0;
 
40
    sumSoFar = 0.0;
 
41
    factorSoFar = 0.0;
 
42
    waitingForOperand = true;
 
43
 
 
44
    display = new QLineEdit("0");
 
45
    display->setReadOnly(true);
 
46
    display->setAlignment(Qt::AlignRight);
 
47
    display->setMaxLength(15);
 
48
    display->installEventFilter(this);
 
49
 
 
50
    QFont font = display->font();
 
51
    font.setPointSize(font.pointSize() + 8);
 
52
    display->setFont(font);
 
53
 
 
54
    QColor digitColor(150, 205, 205);
 
55
    QColor backspaceColor(225, 185, 135);
 
56
    QColor memoryColor(100, 155, 155);
 
57
    QColor operatorColor(155, 175, 195);
 
58
 
 
59
    for (int i = 0; i < NumDigitButtons; ++i) {
 
60
        digitButtons[i] = createButton(QString::number(i), digitColor,
 
61
                                       SLOT(digitClicked()));
 
62
    }
 
63
 
 
64
    pointButton = createButton(tr("."), digitColor, SLOT(pointClicked()));
 
65
    changeSignButton = createButton(tr("�"), digitColor, SLOT(changeSignClicked()));
 
66
 
 
67
    backspaceButton = createButton(tr("Backspace"), backspaceColor,
 
68
                                   SLOT(backspaceClicked()));
 
69
    clearButton = createButton(tr("Clear"), backspaceColor, SLOT(clear()));
 
70
    clearAllButton = createButton(tr("Clear All"), backspaceColor.light(120),
 
71
                                  SLOT(clearAll()));
 
72
 
 
73
    clearMemoryButton = createButton(tr("MC"), memoryColor,
 
74
                                     SLOT(clearMemory()));
 
75
    readMemoryButton = createButton(tr("MR"), memoryColor, SLOT(readMemory()));
 
76
    setMemoryButton = createButton(tr("MS"), memoryColor, SLOT(setMemory()));
 
77
    addToMemoryButton = createButton(tr("M+"), memoryColor,
 
78
                                     SLOT(addToMemory()));
 
79
 
 
80
    divisionButton = createButton(tr("�"), operatorColor,
 
81
                                  SLOT(multiplicativeOperatorClicked()));
 
82
    timesButton = createButton(tr("�"), operatorColor,
 
83
                               SLOT(multiplicativeOperatorClicked()));
 
84
    minusButton = createButton(tr("-"), operatorColor,
 
85
                               SLOT(additiveOperatorClicked()));
 
86
    plusButton = createButton(tr("+"), operatorColor,
 
87
                              SLOT(additiveOperatorClicked()));
 
88
 
 
89
    squareRootButton = createButton(tr("Sqrt"), operatorColor,
 
90
                                    SLOT(unaryOperatorClicked()));
 
91
    powerButton = createButton(tr("x�"), operatorColor,
 
92
                               SLOT(unaryOperatorClicked()));
 
93
    reciprocalButton = createButton(tr("1/x"), operatorColor,
 
94
                                    SLOT(unaryOperatorClicked()));
 
95
    equalButton = createButton(tr("="), operatorColor.light(120),
 
96
                               SLOT(equalClicked()));
 
97
 
 
98
    QGridLayout *mainLayout = new QGridLayout;
 
99
    mainLayout->setSizeConstraint(QLayout::SetFixedSize);
 
100
 
 
101
    mainLayout->addWidget(display, 0, 0, 1, 6);
 
102
    mainLayout->addWidget(backspaceButton, 1, 0, 1, 2);
 
103
    mainLayout->addWidget(clearButton, 1, 2, 1, 2);
 
104
    mainLayout->addWidget(clearAllButton, 1, 4, 1, 2);
 
105
 
 
106
    mainLayout->addWidget(clearMemoryButton, 2, 0);
 
107
    mainLayout->addWidget(readMemoryButton, 3, 0);
 
108
    mainLayout->addWidget(setMemoryButton, 4, 0);
 
109
    mainLayout->addWidget(addToMemoryButton, 5, 0);
 
110
 
 
111
    for (int i = 1; i < NumDigitButtons; ++i) {
 
112
        int row = ((9 - i) / 3) + 2;
 
113
        int column = ((i - 1) % 3) + 1;
 
114
        mainLayout->addWidget(digitButtons[i], row, column);
 
115
    }
 
116
 
 
117
    mainLayout->addWidget(digitButtons[0], 5, 1);
 
118
    mainLayout->addWidget(pointButton, 5, 2);
 
119
    mainLayout->addWidget(changeSignButton, 5, 3);
 
120
 
 
121
    mainLayout->addWidget(divisionButton, 2, 4);
 
122
    mainLayout->addWidget(timesButton, 3, 4);
 
123
    mainLayout->addWidget(minusButton, 4, 4);
 
124
    mainLayout->addWidget(plusButton, 5, 4);
 
125
 
 
126
    mainLayout->addWidget(squareRootButton, 2, 5);
 
127
    mainLayout->addWidget(powerButton, 3, 5);
 
128
    mainLayout->addWidget(reciprocalButton, 4, 5);
 
129
    mainLayout->addWidget(equalButton, 5, 5);
 
130
    setLayout(mainLayout);
 
131
 
 
132
    setWindowTitle(tr("Calculator"));
 
133
}
 
134
 
 
135
bool Calculator::eventFilter(QObject *target, QEvent *event)
 
136
{
 
137
    if (target == display) {
 
138
        if (event->type() == QEvent::MouseButtonPress
 
139
                || event->type() == QEvent::MouseButtonDblClick
 
140
                || event->type() == QEvent::MouseButtonRelease
 
141
                || event->type() == QEvent::ContextMenu) {
 
142
            QMouseEvent *mouseEvent = static_cast<QMouseEvent *>(event);
 
143
            if (mouseEvent->buttons() & Qt::LeftButton) {
 
144
                QPalette newPalette = palette();
 
145
                newPalette.setColor(QPalette::Base,
 
146
                                    display->palette().color(QPalette::Text));
 
147
                newPalette.setColor(QPalette::Text,
 
148
                                    display->palette().color(QPalette::Base));
 
149
                display->setPalette(newPalette);
 
150
            } else {
 
151
                display->setPalette(palette());
 
152
            }
 
153
            return true;
 
154
        }
 
155
    }
 
156
    return QDialog::eventFilter(target, event);
 
157
}
 
158
 
 
159
void Calculator::digitClicked()
 
160
{
 
161
    Button *clickedButton = qobject_cast<Button *>(sender());
 
162
    int digitValue = clickedButton->text().toInt();
 
163
    if (display->text() == "0" && digitValue == 0.0)
 
164
        return;
 
165
 
 
166
    if (waitingForOperand) {
 
167
        display->clear();
 
168
        waitingForOperand = false;
 
169
    }
 
170
    display->setText(display->text() + QString::number(digitValue));
 
171
}
 
172
 
 
173
void Calculator::unaryOperatorClicked()
 
174
{
 
175
    Button *clickedButton = qobject_cast<Button *>(sender());
 
176
    QString clickedOperator = clickedButton->text();
 
177
    double operand = display->text().toDouble();
 
178
    double result;
 
179
 
 
180
    if (clickedOperator == tr("Sqrt")) {
 
181
        if (operand < 0.0) {
 
182
            abortOperation();
 
183
            return;
 
184
        }
 
185
        result = sqrt(operand);
 
186
    } else if (clickedOperator == tr("x�")) {
 
187
        result = pow(operand, 2.0);
 
188
    } else if (clickedOperator == tr("1/x")) {
 
189
        if (operand == 0.0) {
 
190
            abortOperation();
 
191
            return;
 
192
        }
 
193
        result = 1.0 / operand;
 
194
    }
 
195
    display->setText(QString::number(result));
 
196
    waitingForOperand = true;
 
197
}
 
198
 
 
199
void Calculator::additiveOperatorClicked()
 
200
{
 
201
    Button *clickedButton = qobject_cast<Button *>(sender());
 
202
    QString clickedOperator = clickedButton->text();
 
203
    double operand = display->text().toDouble();
 
204
 
 
205
    if (!pendingMultiplicativeOperator.isEmpty()) {
 
206
        if (!calculate(operand, pendingMultiplicativeOperator)) {
 
207
            abortOperation();
 
208
            return;
 
209
        }
 
210
        display->setText(QString::number(factorSoFar));
 
211
        operand = factorSoFar;
 
212
        factorSoFar = 0.0;
 
213
        pendingMultiplicativeOperator.clear();
 
214
    }
 
215
 
 
216
    if (!pendingAdditiveOperator.isEmpty()) {
 
217
        if (!calculate(operand, pendingAdditiveOperator)) {
 
218
            abortOperation();
 
219
            return;
 
220
        }
 
221
        display->setText(QString::number(sumSoFar));
 
222
    } else {
 
223
        sumSoFar = operand;
 
224
    }
 
225
 
 
226
    pendingAdditiveOperator = clickedOperator;
 
227
    waitingForOperand = true;
 
228
}
 
229
 
 
230
void Calculator::multiplicativeOperatorClicked()
 
231
{
 
232
    Button *clickedButton = qobject_cast<Button *>(sender());
 
233
    QString clickedOperator = clickedButton->text();
 
234
    double operand = display->text().toDouble();
 
235
 
 
236
    if (!pendingMultiplicativeOperator.isEmpty()) {
 
237
        if (!calculate(operand, pendingMultiplicativeOperator)) {
 
238
            abortOperation();
 
239
            return;
 
240
        }
 
241
        display->setText(QString::number(factorSoFar));
 
242
    } else {
 
243
        factorSoFar = operand;
 
244
    }
 
245
 
 
246
    pendingMultiplicativeOperator = clickedOperator;
 
247
    waitingForOperand = true;
 
248
}
 
249
 
 
250
void Calculator::equalClicked()
 
251
{
 
252
    double operand = display->text().toDouble();
 
253
 
 
254
    if (!pendingMultiplicativeOperator.isEmpty()) {
 
255
        if (!calculate(operand, pendingMultiplicativeOperator)) {
 
256
            abortOperation();
 
257
            return;
 
258
        }
 
259
        operand = factorSoFar;
 
260
        factorSoFar = 0.0;
 
261
        pendingMultiplicativeOperator.clear();
 
262
    }
 
263
    if (!pendingAdditiveOperator.isEmpty()) {
 
264
        if (!calculate(operand, pendingAdditiveOperator)) {
 
265
            abortOperation();
 
266
            return;
 
267
        }
 
268
        pendingAdditiveOperator.clear();
 
269
    } else {
 
270
        sumSoFar = operand;
 
271
    }
 
272
 
 
273
    display->setText(QString::number(sumSoFar));
 
274
    sumSoFar = 0.0;
 
275
    waitingForOperand = true;
 
276
}
 
277
 
 
278
void Calculator::pointClicked()
 
279
{
 
280
    if (waitingForOperand)
 
281
        display->setText("0");
 
282
    if (!display->text().contains("."))
 
283
        display->setText(display->text() + tr("."));
 
284
    waitingForOperand = false;
 
285
}
 
286
 
 
287
void Calculator::changeSignClicked()
 
288
{
 
289
    QString text = display->text();
 
290
    double value = text.toDouble();
 
291
 
 
292
    if (value > 0.0) {
 
293
        text.prepend(tr("-"));
 
294
    } else if (value < 0.0) {
 
295
        text.remove(0, 1);
 
296
    }
 
297
    display->setText(text);
 
298
}
 
299
 
 
300
void Calculator::backspaceClicked()
 
301
{
 
302
    if (waitingForOperand)
 
303
        return;
 
304
 
 
305
    QString text = display->text();
 
306
    text.chop(1);
 
307
    if (text.isEmpty()) {
 
308
        text = "0";
 
309
        waitingForOperand = true;
 
310
    }
 
311
    display->setText(text);
 
312
}
 
313
 
 
314
void Calculator::clear()
 
315
{
 
316
    if (waitingForOperand)
 
317
        return;
 
318
 
 
319
    display->setText("0");
 
320
    waitingForOperand = true;
 
321
}
 
322
 
 
323
void Calculator::clearAll()
 
324
{
 
325
    sumSoFar = 0.0;
 
326
    factorSoFar = 0.0;
 
327
    pendingAdditiveOperator.clear();
 
328
    pendingMultiplicativeOperator.clear();
 
329
    display->setText("0");
 
330
    waitingForOperand = true;
 
331
}
 
332
 
 
333
void Calculator::clearMemory()
 
334
{
 
335
    sumInMemory = 0.0;
 
336
}
 
337
 
 
338
void Calculator::readMemory()
 
339
{
 
340
    display->setText(QString::number(sumInMemory));
 
341
    waitingForOperand = true;
 
342
}
 
343
 
 
344
void Calculator::setMemory()
 
345
{
 
346
    equalClicked();
 
347
    sumInMemory = display->text().toDouble();
 
348
}
 
349
 
 
350
void Calculator::addToMemory()
 
351
{
 
352
    equalClicked();
 
353
    sumInMemory += display->text().toDouble();
 
354
}
 
355
 
 
356
Button *Calculator::createButton(const QString &text, const QColor &color,
 
357
                                 const char *member)
 
358
{
 
359
    Button *button = new Button(text, color);
 
360
    connect(button, SIGNAL(clicked()), this, member);
 
361
    return button;
 
362
}
 
363
 
 
364
void Calculator::abortOperation()
 
365
{
 
366
    clearAll();
 
367
    display->setText(tr("####"));
 
368
}
 
369
 
 
370
bool Calculator::calculate(double rightOperand, const QString &pendingOperator)
 
371
{
 
372
    if (pendingOperator == tr("+")) {
 
373
        sumSoFar += rightOperand;
 
374
    } else if (pendingOperator == tr("-")) {
 
375
        sumSoFar -= rightOperand;
 
376
    } else if (pendingOperator == tr("�")) {
 
377
        factorSoFar *= rightOperand;
 
378
    } else if (pendingOperator == tr("�")) {
 
379
        if (rightOperand == 0.0)
 
380
            return false;
 
381
        factorSoFar /= rightOperand;
 
382
    }
 
383
    return true;
 
384
}