#include <ctype.h>
#include <QPainter>
#include <QFile>
#include <QTimer>
#include <QKeyEvent>
#include <calculator.h>
struct {
char symbol;
int x, y;
const char *file;
} buttonList[] = {
{ '=', 217, 158, "equal" },
{ '+', 188, 140, "plus" },
{ '-', 252, 140, "minus" },
{ '*', 192, 135, "double" },
{ '/', 192, 193, "division" },
{ '(', 107, 157, "star" },
{ ')', 297, 157, "sharp" }
};
const int buttonListSize = sizeof(buttonList)/sizeof(buttonList[0]);
class Button : public QLabel
{
public:
Button(QWidget *parent, int idx) : QLabel(parent), index(idx) {
setDown(false);
move(buttonList[index].x, buttonList[index].y);
}
void setDown(bool down) {
setPixmap(QPixmap(QString("images/btn_") + buttonList[index].file + ((down) ? "_r.png" : ".png")));
raise();
}
int index;
};
Calculator::Calculator(QWidget *parent) : QWidget(parent)
{
QLabel *lab = new QLabel(this);
lab->setText("Calculator written in C++");
QLabel *bg = new QLabel(this);
bg->setPixmap(QPixmap("images/calculator_bg.png"));
bg->move(95, 35);
QPalette p;
p.setColor(QPalette::WindowText,Qt::white);
input = new QLabel(this);
input->setFont(QFont("Arial",14));
input->setText("");
input->setGeometry(120, 58, 230, 20);
input->setPalette(p);
output = new QLabel(this);
output->setFont(QFont("Arial",14));
output->setText("= 0");
output->setGeometry(120, 89, 230, 20);
output->setPalette(p);
for (int i = 0; i < buttonListSize; i++)
button[i] = new Button(this, i);
}
Calculator::~Calculator()
{
}
int Calculator::indexForKey(int key)
{
int i = -1;
switch (key) {
case Qt::Key_Enter: i = 0; break; // OK
case Qt::Key_Left: i = 1; break; // Left
case Qt::Key_Right: i = 2; break; // Right
case Qt::Key_Up: i = 3; break; // Up
case Qt::Key_Down: i = 4; break; // Down
case Qt::Key_Asterisk: i = 5; break; // '*'
case Qt::Key_NumberSign: i = 6; break; // '#'
}
return i;
}
static QString calculateExpression(QString input)
{
input.remove(QChar('\''));
input.replace(QString("+"), QString(" + "));
input.replace(QString("-"), QString(" - "));
input.replace(QString("/"), QString(" / "));
input.replace(QString("*"), QString(" \\* "));
input.replace(QString("("), QString(" \\( "));
input.replace(QString(")"), QString(" \\) "));
input = "expr " + input + " > /tmp/result.txt 2> /tmp/result.txt";
::system(input.toLatin1().data());
QFile f("/tmp/result.txt");
f.open(QFile::ReadOnly);
QString result = "= " + f.readAll();
result.replace(QString("= expr: syntax error"),QString("Wrong Input"));
result.replace(QString("= expr: too few arguments"),QString("No Input"));
result.replace(QString("= expr: division by zero"),QString("Can not divide by zero"));
return result;
}
static void showPopupDialog(QString message)
{
QLabel *popupImg = new QLabel(0);
QFontMetrics fm(popupImg->font());
QImage img(480, 272, QImage::Format_RGB32);
QPainter p(&img);
p.drawPixmap(0, 0, QPixmap("images/depth_bg.jpg"));
p.drawPixmap(0, 244, QPixmap("images/softykey.png"));
p.drawImage((480-329)/2, (272-176)/2-12, QImage("images/big_popup_01.png"));
p.drawText((480-fm.width(message))/2, 140, message);
p.drawText(10, 10, "Popup Example in C++");
p.end();
popupImg->setPixmap(QPixmap::fromImage(img));
popupImg->setGeometry(0,0,480,272);
popupImg->show();
QTimer::singleShot(2000, popupImg, SLOT(deleteLater()));
}
void Calculator::keyPressEvent(QKeyEvent *ke)
{
int i = indexForKey(ke->key());
if (i != -1) {
if (i == 0) {
QString result = calculateExpression(input->text());
if ( result.left(1) != "=" ) {
showPopupDialog(result);
output->setText("= 0");
} else {
output->setText(result);
}
//output->setText(calculateExpression(input->text()));
} else {
QString existing = input->text();
QChar last = existing.right(1).at(0);
if ( last == '*' || last == '/' || last == '+' || last == '-')
existing = existing.left(existing.length() - 1);
input->setText(existing + QChar(buttonList[i].symbol));
}
button[i]->setDown(true);
return;
}
switch ( ke->key() ) {
case Qt::Key_0: input->setText(input->text() + "0"); return;
case Qt::Key_1: input->setText(input->text() + "1"); return;
case Qt::Key_2: input->setText(input->text() + "2"); return;
case Qt::Key_3: input->setText(input->text() + "3"); return;
case Qt::Key_4: input->setText(input->text() + "4"); return;
case Qt::Key_5: input->setText(input->text() + "5"); return;
case Qt::Key_6: input->setText(input->text() + "6"); return;
case Qt::Key_7: input->setText(input->text() + "7"); return;
case Qt::Key_8: input->setText(input->text() + "8"); return;
case Qt::Key_9: input->setText(input->text() + "9"); return;
}
// Handle any other keys
if ( ke->key() == Qt::Key_Context1 ) { // OK
QString result = calculateExpression(input->text());
if ( result.left(1) != "=" ) {
showPopupDialog(result);
output->setText("= 0");
} else {
output->setText(result);
}
} else if ( ke->key() == Qt::Key_Context2 ) { // AC
input->setText("");
output->setText("= 0");
} else if ( ke->key() == Qt::Key_Context3 ) { // Backspace
input->setText(input->text().left(input->text().length() - 1));
}
}
void Calculator::keyReleaseEvent(QKeyEvent *ke)
{
int i = indexForKey(ke->key());
if (i != -1)
button[i]->setDown(false);
}