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