2da8ebec81600716e437fbdbe18ba201de500008
[ussd-widget] / ussd4all / src / qussd.cpp
1 #include <QtGui>
2 #include <iostream>
3 #include <string.h>
4
5 #define PROCESSING "Processing..."
6
7 class QUssd : public QMainWindow {
8         Q_OBJECT
9
10         public:
11                 QUssd(QString message, bool lock = false) {
12                         number = "";
13
14                         QActionGroup *filterGroup = new QActionGroup(this);
15                         filterGroup->setExclusive(true);
16
17                         actPortrait = new QAction(tr("Portrait"), filterGroup);
18                         actPortrait->setCheckable(true);
19
20                         actLandscape = new QAction(tr("Landscape"), filterGroup);
21                         actLandscape->setCheckable(true);
22
23                         actAuto = new QAction(tr("Auto"), filterGroup);
24                         actAuto->setCheckable(true);
25                         actAuto->setChecked(true);
26                 
27                         menuBar()->addActions(filterGroup->actions());
28
29                         connect(actPortrait, SIGNAL(changed()), this, SLOT(setOrientation()));
30                         connect(actLandscape, SIGNAL(changed()), this, SLOT(setOrientation()));
31                         connect(actAuto, SIGNAL(changed()), this, SLOT(setOrientation()));
32
33                         replyLabel = new QTextEdit(message);
34                         replyLabel->setMinimumWidth(400);
35                         replyLabel->setMinimumHeight(200);
36                         replyLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Maximum);
37                         replyLabel->setFrameStyle(QFrame::NoFrame);
38                         QPalette pal = palette();
39                         pal.setColor(QPalette::Base, Qt::transparent);
40                         pal.setColor(QPalette::Text, pal.color(QPalette::ButtonText));
41                         replyLabel->setPalette(pal);
42 //                      replyLabel->setTextBackgroundColor(Qt::black);
43 //                      replyLabel->setTextColor(Qt::white);
44                         replyLabel->setTextInteractionFlags(Qt::TextSelectableByMouse | Qt::TextSelectableByKeyboard);
45                         
46                         numberLabel = new QLabel("");
47                         numberLabel->setMinimumWidth(400);
48                         numberLabel->setMaximumHeight(100);
49                         numberLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
50
51                         indicationLayout = new QVBoxLayout;
52                         indicationLayout->addWidget(numberLabel);
53
54                         indicationLayout->addWidget(replyLabel);
55
56                         padDel = new QPushButton("C");
57                         connect(padDel, SIGNAL(clicked()), this, SLOT(del()));
58                         padDel->setMaximumWidth(150);
59                         padDel->setMaximumHeight(72);
60                         padDel->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Expanding);
61                         padSend = new QPushButton("SEND");
62                         connect(padSend, SIGNAL(clicked()), this, SLOT(send()));
63                         padSend->setMaximumWidth(300);
64                         padSend->setMaximumHeight(72);
65                         padSend->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Expanding);
66
67                         btnLayout = new QHBoxLayout;
68                         btnLayout->addWidget(padSend);
69                         btnLayout->addWidget(padDel);
70
71                         numberPad = new QGridLayout();
72                         numberPad->setSpacing(2);
73
74                         padBtn1 = new QPushButton("1");
75                         connect(padBtn1, SIGNAL(clicked()), this, SLOT(add1()));
76                         padBtn1->setMaximumWidth(150);
77                         padBtn1->setMaximumHeight(72);
78                         padBtn1->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Expanding);
79                         numberPad->addWidget(padBtn1, 0, 0);
80                         padBtn2 = new QPushButton("2");
81                         connect(padBtn2, SIGNAL(clicked()), this, SLOT(add2()));
82                         padBtn2->setMaximumWidth(150);
83                         padBtn2->setMaximumHeight(72);
84                         padBtn2->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Expanding);
85                         numberPad->addWidget(padBtn2, 0, 1);
86                         padBtn3 = new QPushButton("3");
87                         connect(padBtn3, SIGNAL(clicked()), this, SLOT(add3()));
88                         padBtn3->setMaximumWidth(150);
89                         padBtn3->setMaximumHeight(72);
90                         padBtn3->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Expanding);
91                         numberPad->addWidget(padBtn3, 0, 2);
92                         padBtn4 = new QPushButton("4");
93                         connect(padBtn4, SIGNAL(clicked()), this, SLOT(add4()));
94                         padBtn4->setMaximumWidth(150);
95                         padBtn4->setMaximumHeight(72);
96                         padBtn4->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Expanding);
97                         numberPad->addWidget(padBtn4, 1, 0);
98                         padBtn5 = new QPushButton("5");
99                         connect(padBtn5, SIGNAL(clicked()), this, SLOT(add5()));
100                         padBtn5->setMaximumWidth(150);
101                         padBtn5->setMaximumHeight(72);
102                         padBtn5->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Expanding);
103                         numberPad->addWidget(padBtn5, 1, 1);
104                         padBtn6 = new QPushButton("6");
105                         connect(padBtn6, SIGNAL(clicked()), this, SLOT(add6()));
106                         padBtn6->setMaximumWidth(150);
107                         padBtn6->setMaximumHeight(72);
108                         padBtn6->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Expanding);
109                         numberPad->addWidget(padBtn6, 1, 2);
110                         padBtn7 = new QPushButton("7");
111                         connect(padBtn7, SIGNAL(clicked()), this, SLOT(add7()));
112                         padBtn7->setMaximumWidth(150);
113                         padBtn7->setMaximumHeight(72);
114                         padBtn7->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Expanding);
115                         numberPad->addWidget(padBtn7, 2, 0);
116                         padBtn8 = new QPushButton("8");
117                         connect(padBtn8, SIGNAL(clicked()), this, SLOT(add8()));
118                         padBtn8->setMaximumWidth(150);
119                         padBtn8->setMaximumHeight(72);
120                         padBtn8->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Expanding);
121                         numberPad->addWidget(padBtn8, 2, 1);
122                         padBtn9 = new QPushButton("9");
123                         connect(padBtn9, SIGNAL(clicked()), this, SLOT(add9()));
124                         padBtn9->setMaximumWidth(150);
125                         padBtn9->setMaximumHeight(72);
126                         padBtn9->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Expanding);
127                         numberPad->addWidget(padBtn9, 2, 2);
128                         padBtnStar = new QPushButton("*+");
129                         connect(padBtnStar, SIGNAL(clicked()), this, SLOT(addStar()));
130                         padBtnStar->setMaximumWidth(150);
131                         padBtnStar->setMaximumHeight(72);
132                         padBtnStar->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Expanding);
133                         numberPad->addWidget(padBtnStar, 3, 0);
134                         padBtn0 = new QPushButton("0");
135                         connect(padBtn0, SIGNAL(clicked()), this, SLOT(add0()));
136                         padBtn0->setMaximumWidth(150);
137                         padBtn0->setMaximumHeight(72);
138                         padBtn0->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Expanding);
139                         numberPad->addWidget(padBtn0, 3, 1);
140                         padBtnGrid = new QPushButton("#");
141                         connect(padBtnGrid, SIGNAL(clicked()), this, SLOT(addGrid()));
142                         padBtnGrid->setMaximumWidth(150);
143                         padBtnGrid->setMaximumHeight(72);
144                         padBtnGrid->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Expanding);
145                         numberPad->addWidget(padBtnGrid, 3, 2);
146
147                         centralWidget = new QWidget;
148                         setCentralWidget(centralWidget);
149                         mainLayout = new QGridLayout(centralWidget);
150
151                         connect(QApplication::desktop(), SIGNAL(resized(int)), this, SLOT(orientationChanged()));
152                         setOrientation();
153                         orientationChanged();
154
155                         startUSSD (lock);
156                 }
157
158                 ~QUssd () {
159                         USSDquery->write("exit\n");
160                         USSDquery->closeWriteChannel();
161                         USSDquery->waitForFinished();
162
163                         delete USSDquery;
164                 }
165
166         public slots:
167                 void restartUSSD( int, QProcess::ExitStatus) {
168                         replyLabel->setText(QString("Error: ")+QString::fromUtf8(reply));
169                         reply = "";
170                         number = "";
171                         setNumber();
172
173                         delete USSDquery;
174                         startUSSD ();
175                 }
176
177
178                 void send() {   
179                         USSDquery->write(number.toUtf8().data());
180                         USSDquery->write("\n");
181                         number = tr(PROCESSING);
182                         setNumber();
183                 }
184
185                 void readData() {
186                         QByteArray line;
187                         for (line = USSDquery->readLine(); !line.isEmpty(); line = USSDquery->readLine()) {
188                                 reply += line;
189                                 if (reply.endsWith("\n==MESSAGE END ==\n")) {
190                                         reply.chop(strlen("\n==MESSAGE END ==\n"));
191                                         if (!reply.isEmpty())
192                                                 replyLabel->setText(QString::fromUtf8(reply));
193                                         reply = "";
194                                         number = "";
195                                         setNumber();
196                                         break;
197                                 }
198                         }
199                 }
200
201                 void setOrientation() {
202                         if (actLandscape->isChecked())
203                                 setAttribute(Qt::WA_Maemo5LandscapeOrientation, true);
204                         else if (actPortrait->isChecked())
205                                 setAttribute(Qt::WA_Maemo5PortraitOrientation, true);
206                         else
207                                 setAttribute(Qt::WA_Maemo5AutoOrientation, true);
208                 }
209
210                 void orientationChanged() {
211                         QRect screenGeometry = QApplication::desktop()->screenGeometry();
212                         mainLayout->removeItem(indicationLayout);
213                         mainLayout->removeItem(numberPad);
214                         mainLayout->removeItem(btnLayout);
215                         
216                         if (screenGeometry.width() > screenGeometry.height()) {
217                                 mainLayout->addLayout(indicationLayout, 0, 0);
218                                 mainLayout->addLayout(btnLayout, 1, 0);
219                                 mainLayout->addLayout(numberPad, 0, 1, -1, 1);
220                         } else {
221                                 mainLayout->addLayout(indicationLayout, 0, 0);
222                                 mainLayout->addLayout(numberPad, 1, 0);
223                                 mainLayout->addLayout(btnLayout, 2, 0);
224                         }
225                 }
226         
227                 void add1 () {
228                         if (number != tr(PROCESSING)) {
229                                 number += "1";
230                                 setNumber();
231                         }
232                 }
233
234                 void add2 () {
235                         if (number != tr(PROCESSING)) {
236                                 number += "2";
237                                 setNumber();
238                         }
239                 }
240
241                 void add3 () {
242                         if (number != tr(PROCESSING)) {
243                                 number += "3";
244                                 setNumber();
245                         }
246                 }
247
248                 void add4 () {
249                         if (number != tr(PROCESSING)) {
250                                 number += "4";
251                                 setNumber();
252                         }
253                 }
254
255                 void add5 () {
256                         if (number != tr(PROCESSING)) {
257                                 number += "5";
258                                 setNumber();
259                         }
260                 }
261
262                 void add6 () {
263                         if (number != tr(PROCESSING)) {
264                                 number += "6";
265                                 setNumber();
266                         }
267                 }
268         
269                 void add7 () {
270                         if (number != tr(PROCESSING)) {
271                                 number += "7";
272                                 setNumber();
273                         }
274                 }
275
276                 void add8 () {
277                         if (number != tr(PROCESSING)) {
278                                 number += "8";
279                                 setNumber();
280                         }
281                 }
282
283                 void add9 () {
284                         if (number != tr(PROCESSING)) {
285                                 number += "9";
286                                 setNumber();
287                         }
288                 }
289
290                 void add0 () {
291                         if (number != tr(PROCESSING)) {
292                                 number += "0";
293                                 setNumber();
294                         }
295                 }
296
297                 void addGrid () {
298                         if (number != tr(PROCESSING)) {
299                                 number += "#";
300                                 setNumber();
301                         }
302                 }
303
304                 void addStar () {
305                         if (number != tr(PROCESSING)) {
306                                 // Do not change star if it was created more than 3 seconds before.
307                                 if (number[number.length()-1] == '*' && lastStar.elapsed() < 3*1000) {
308                                         number[number.length()-1] = '+';
309                                 } else {
310                                         number += "*";
311                                         lastStar = QTime();
312                                         lastStar.start();
313                                 }
314                                 setNumber();
315                         }
316                 }
317
318                 void del () {
319                         if (number != tr(PROCESSING)) {
320                                 number.chop(1);
321                                 setNumber();
322                         }
323                 }
324
325         private:
326                 void startUSSD (bool lock = false) {
327                         QString program = "ussdquery.py";
328                         QStringList arguments;
329                         arguments << "interactive" << "-d" << "\n==MESSAGE END ==\n";
330                         if (lock)
331                                 arguments << "-m";
332
333                         USSDquery = new QProcess();
334                         USSDquery->setProcessChannelMode(QProcess::MergedChannels);
335                         connect(USSDquery, SIGNAL(readyReadStandardOutput()), this, SLOT(readData()));
336                         connect(USSDquery, SIGNAL(readyReadStandardError()), this, SLOT(readData()));
337                         connect(USSDquery, SIGNAL(finished( int, QProcess::ExitStatus )), this, SLOT(restartUSSD( int, QProcess::ExitStatus )));
338
339                         USSDquery->start(program, arguments);
340                 }
341
342                 void setNumber () {
343                         numberLabel->setText(QString("<p style=\"font-size: 30pt;\" align=\"center\">")+number+"</p>");
344                 }
345
346                 QTextEdit *replyLabel;
347                 QLabel *numberLabel;
348                 QAction *actPortrait;
349                 QAction *actLandscape;
350                 QAction *actAuto;
351
352                 QVBoxLayout *indicationLayout;
353                 QHBoxLayout *btnLayout;
354                 QGridLayout *numberPad;
355                 QGridLayout *mainLayout;
356                 QWidget* centralWidget;
357
358                 QPushButton *padBtn1;
359                 QPushButton *padBtn2;
360                 QPushButton *padBtn3;
361                 QPushButton *padBtn4;
362                 QPushButton *padBtn5;
363                 QPushButton *padBtn6;
364                 QPushButton *padBtn7;
365                 QPushButton *padBtn8;
366                 QPushButton *padBtn9;
367                 QPushButton *padBtn0;
368                 QPushButton *padBtnStar;
369                 QPushButton *padBtnGrid;
370
371                 QPushButton *padDel;
372                 QPushButton *padSend;
373
374                 QProcess *USSDquery;
375
376                 QString number;
377                 QByteArray reply;
378
379                 QTime lastStar;
380 };
381
382 int main(int argc, char *argv[]) {
383         QApplication app(argc, argv);
384
385         bool lock = false;
386         QString message;
387         if (argc >= 2)
388                 message = message.fromUtf8(argv[1]);
389         if (argc >=3 && !strcmp(argv[2], "lock"))
390                 lock = true;
391
392         QUssd w(message, lock);
393         w.show();
394         
395         return app.exec();
396 }
397
398 #include "qussd.moc"