Add bugtracker to control file
[magread] / magread.cpp
1 /*
2     This file is part of MagRead.
3
4     MagRead is free software: you can redistribute it and/or modify
5     it under the terms of the GNU General Public License as published by
6     the Free Software Foundation, either version 3 of the License, or
7     (at your option) any later version.
8
9     MagRead is distributed in the hope that it will be useful,
10     but WITHOUT ANY WARRANTY; without even the implied warranty of
11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12     GNU General Public License for more details.
13
14     You should have received a copy of the GNU General Public License
15     along with MagRead.  If not, see <http://www.gnu.org/licenses/>.
16     
17     Written by Jeffrey Malone <ieatlint@tehinterweb.com>
18     http://blog.tehinterweb.com
19 */
20 #include "magread.h"
21
22 #include <QDebug>
23
24 MagRead::MagRead(QWidget *parent) : QMainWindow(parent) {
25         mainPage();
26
27         captureAudio = false;
28         partialRead = false;
29
30         qRegisterMetaType<MagCard>( "MagCard" );
31
32         connect( &audioInput, SIGNAL( cardRead( const MagCard& ) ), this, SLOT( cardRead( const MagCard& ) ) );
33         connect( &audioInput, SIGNAL( error( const QString& ) ), this, SLOT( audioInputError( const QString& ) ) );
34 }
35
36 void MagRead::maemoNotice( QString msg, int msec ) {
37         QMaemo5InformationBox infoBox;
38
39         infoBox.information( 0, msg, msec );
40         infoBox.show();
41 }
42
43 void MagRead::cardRead( const MagCard _card ) {
44         card = _card;
45         cardDetect.setCard( &card );
46
47         if( card.type & MagCard::CARD_CC && card.accountValid ) {
48                 creditPage();
49         } else if( card.type == MagCard::CARD_AAMVA ) {
50                 aamvaPage();
51         } else if( card.swipeValid ) {
52                 miscPage();
53         } else if( partialRead ) {
54                 maemoNotice( "Show data from a partial read; may be incomplete/invalid!", 1000 );
55                 miscPage( true );
56         } else {
57                 maemoNotice( "Swipe Failed! Please Retry", 1000 );
58         }
59 }
60
61 void MagRead::audioInputError( const QString msg ) {
62         maemoNotice( msg, 5000 );
63         captureAudio = false;
64 }
65
66 /* Main Page */
67 void MagRead::mainPage() {
68         QWidget *widget = new QWidget;
69         QVBoxLayout *layout = new QVBoxLayout( widget );
70
71         widget->setLayout( layout );
72
73         QLabel *label;
74         label = new QLabel( "<span style=\"font-size:48pt;\">MagRead</span>" );
75         layout->addWidget( label, 1, Qt::AlignHCenter );
76
77         QCheckBox *cbox = new QCheckBox( "Show Partial Data" );
78         layout->addWidget( cbox );
79         connect( cbox, SIGNAL( toggled( bool ) ), this, SLOT( togglePartialRead( bool ) ) );
80
81         QPushButton *button = new QPushButton( "Start" );
82         layout->addWidget( button );
83         connect( button, SIGNAL( clicked() ), this, SLOT( toggleRead() ) );
84
85         onMainPage = true;
86
87         setCentralWidget( widget );
88 }
89
90 void MagRead::toggleRead() {
91         QPushButton *button = qobject_cast<QPushButton *>( QObject::sender() );
92
93         if( captureAudio ) {
94                 audioInput.stop();
95                 if( onMainPage )
96                         button->setText( "Start" );
97                 else
98                         button->setText( "Back to Main Page" );
99                 captureAudio = false;
100         } else if( onMainPage ) {
101                 audioInput.start();
102                 button->setText( "Stop" );
103                 captureAudio = true;
104         } else {
105                 mainPage();
106         }
107
108 }
109
110 void MagRead::togglePartialRead( bool _partialRead ) {
111         partialRead = _partialRead;
112 }
113
114 /* Credit Page */
115 void MagRead::creditPage() {
116         maemoNotice( "Successfully Read Credit Card", 1000 );
117         QWidget *widget = new QWidget;
118         QGridLayout *layout = new QGridLayout( widget );
119
120         onMainPage = false;
121
122         widget->setLayout( layout );
123
124         QLabel *label;
125
126         QString accountNumber = card.accountNumber;
127         if( card.type == MagCard::CARD_AMEX ) {
128                 accountNumber.insert( 10, '\t' );
129                 accountNumber.insert( 4, '\t' );
130         } else {
131                 accountNumber.insert( 12, '\t' );
132                 accountNumber.insert( 8, '\t' );
133                 accountNumber.insert( 4, '\t' );
134         }
135
136         accountNumber.prepend( "<span style=\"font-size:48pt;\"><br>\n" );
137         accountNumber.append( "</span>" );
138         
139         if( !card.accountHolder.isEmpty() ) {
140                 accountNumber.append( "\n<span style=\"font-size:36pt;\"><div align=center>" );
141                 accountNumber.append( card.accountHolder );
142                 accountNumber.append( "</div></span>" );
143         }
144
145         label = new QLabel( accountNumber );
146         layout->addWidget( label, 0, 0, 1, 2, Qt::AlignHCenter );
147
148         label = new QLabel( "<span style=\"font-size:24pt;\">Expiration Date</span>" );
149         layout->addWidget( label, 1, 0, 1, 1, Qt::AlignHCenter | Qt::AlignBottom );
150
151         label = new QLabel( "<span style=\"font-size:24pt;\">Issuer</span>" );
152         layout->addWidget( label, 1, 1, 1, 1, Qt::AlignHCenter | Qt::AlignBottom );
153
154         QString expDate = card.expirationDate.toString( "MM/yy" );
155         if( card.expirationDate < QDate::currentDate() ) {
156                 expDate.prepend( "<font color=\"red\">" );
157                 expDate.append( "</font>" );
158         }
159
160         label = new QLabel( QString( "<span style=\"font-size:32pt;\">%1</span>" ).arg( expDate ) );
161         layout->addWidget( label, 2, 0, 1, 1, Qt::AlignHCenter | Qt::AlignTop );
162
163         label = new QLabel( QString( "<span style=\"font-size:32pt;\">%1</span>" ).arg( card.accountIssuer ) );
164         layout->addWidget( label, 2, 1, 1, 1, Qt::AlignHCenter | Qt::AlignTop );
165
166         QPushButton *button = new QPushButton( "Stop" );
167         layout->addWidget( button, 3, 0, 1, 2 );
168         connect( button, SIGNAL( clicked() ), this, SLOT( toggleRead() ) );
169
170         setCentralWidget( widget );
171 }
172
173 void MagRead::aamvaPage() {
174         maemoNotice( "Successfully Read AAMVA Card", 1000 );
175         QWidget *widget = new QWidget;
176         QGridLayout *layout = new QGridLayout( widget );
177
178         onMainPage = false;
179
180         widget->setLayout( layout );
181
182         QLabel *label;
183
184         label = new QLabel( "<span style=\"font-size:36pt;\">" + card.aamvaIssuerName + "</span>" );
185         layout->addWidget( label, 0, 0, 1, 2, Qt::AlignHCenter );
186
187         label = new QLabel( "<span style=\"font-size:32pt;\">" + card.accountNumber + "</span>" );
188         layout->addWidget( label, 1, 0, 1 ,2, Qt::AlignHCenter | Qt::AlignTop );
189         layout->setRowStretch( 1, 1 );
190
191         /* Calculate the age */
192         QDate curDate = QDate::currentDate();
193
194         /* FIXME a leap year can offset this by a day ... */
195         int age = QDate::currentDate().year() - card.aamvaBirthday.year();
196         if( card.aamvaBirthday.dayOfYear() > QDate::currentDate().dayOfYear() ) {
197                 age--;
198         }
199
200         QString ageStr = QString ( "<span style=\"font-size:32pt;\">Age %1 </span>" ).arg( age );
201         if( age < 18 ) {
202                 ageStr.prepend( "<font color=\"red\">" );
203                 ageStr.append( "</font>" );
204         } else if( age < 21 ) {
205                 ageStr.prepend( "<font color=\"yellow\">" );
206                 ageStr.append( "</font>" );
207         }
208
209         label = new QLabel( ageStr );
210         layout->addWidget( label, 2, 0, 1, 2, Qt::AlignHCenter );
211
212         label = new QLabel( "<span style=\"font-size:24pt;\">Expiration Date</font>" );
213         layout->addWidget( label, 3, 0, 1, 1, Qt::AlignHCenter );
214
215         label = new QLabel( "<span style=\"font-size:24pt;\">Date of Birth</span>" );
216         layout->addWidget( label, 3, 1, 1, 1, Qt::AlignHCenter );
217
218         QString expDate = card.expirationDate.toString( "MM/dd/yy" );
219         expDate.prepend( "<span style=\"font-size:24pt;\">" );
220         if( card.expirationDate < QDate::currentDate() ) {
221                 expDate.prepend( "<font color=\"red\"><div align=\"center\">" );
222                 expDate.append( "<br>\nEXPIRED</font></div>" );
223         }
224         expDate.append( "</span>" );
225         label = new QLabel( expDate );
226         layout->addWidget( label, 4, 0, 1, 1, Qt::AlignHCenter );
227
228
229         label = new QLabel(  "<span style=\"font-size:24pt;\">" + card.aamvaBirthday.toString( "MM/dd/yy" ) + "</span>" );
230         layout->addWidget( label, 4, 1, 1, 1, Qt::AlignHCenter );
231
232         QPushButton *button = new QPushButton( "Stop" );
233         layout->addWidget( button, 5, 0, 1, 2 );
234         connect( button, SIGNAL( clicked() ), this, SLOT( toggleRead() ) );
235
236         setCentralWidget( widget );
237 }
238
239 /* Misc Page */
240 void MagRead::miscPage( bool partial ) {
241         if( !partial )
242                 maemoNotice( "Successfully Read an Unknown Card", 1000 );
243         
244         QWidget *widget = new QWidget;
245         QGridLayout *layout = new QGridLayout( widget );
246
247         onMainPage = false;
248
249         widget->setLayout( layout );
250
251         QScrollArea *scroll = new QScrollArea;
252
253         QString tmpStr = card.charStream;
254         if( tmpStr.contains( '%' ) ) {
255                 tmpStr.replace( '^', "<br>\n[Field Separator]<br>\n" );
256         } else {
257                 tmpStr.replace( '=', "<br>\n[Field Separator]<br>\n" );
258         }
259         tmpStr.replace( '|', "<font color=\"red\">|</font>" );
260
261         tmpStr.prepend( "<span style=\"font-size:36pt;\"><div align=\"center\">" );
262         tmpStr.append( "</div></span>" );
263
264         QLabel *label = new QLabel( tmpStr );
265         scroll->setWidget( label );
266         scroll->setWidgetResizable( true );
267         layout->addWidget( scroll, 0, 0, 1, 2, Qt::AlignHCenter );
268
269         label->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Expanding );
270
271         QPushButton *button = new QPushButton( "Stop" );
272         layout->addWidget( button, 1, 0, 1, 2 );
273         connect( button, SIGNAL( clicked() ), this, SLOT( toggleRead() ) );
274
275         setCentralWidget( widget );
276 }
277