1
/***************************************************************************
2
* Copyright (C) 2009-2012 by Savoir-Faire Linux *
3
* Author : Jérémy Quentin <jeremy.quentin@savoirfairelinux.com> *
4
* Emmanuel Lepage Vallee <emmanuel.lepage@savoirfairelinux.com>*
6
* This program is free software; you can redistribute it and/or modify *
7
* it under the terms of the GNU General Public License as published by *
8
* the Free Software Foundation; either version 3 of the License, or *
9
* (at your option) any later version. *
11
* This program is distributed in the hope that it will be useful, *
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
14
* GNU General Public License for more details. *
16
* You should have received a copy of the GNU General Public License *
17
* along with this program; if not, write to the *
18
* Free Software Foundation, Inc., *
19
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
20
***************************************************************************/
22
#include "AccountWizard.h"
23
#include <QVBoxLayout>
24
#include <QFormLayout>
25
#include "lib/sflphone_const.h"
26
#include "lib/configurationmanager_interface_singleton.h"
28
#include <QRadioButton>
40
#define FIELD_SFL_ACCOUNT "SFL"
41
#define FIELD_OTHER_ACCOUNT "OTHER"
42
#define FIELD_SIP_ACCOUNT "SIP"
43
#define FIELD_IAX_ACCOUNT "IAX"
44
#define FIELD_EMAIL_ADDRESS "EMAIL_ADDRESS"
46
#define FIELD_SIP_ALIAS "SIP_ALIAS"
47
#define FIELD_SIP_SERVER "SIP_SERVER"
48
#define FIELD_SIP_USER "SIP_USER"
49
#define FIELD_SIP_PASSWORD "SIP_PASSWORD"
50
#define FIELD_SIP_VOICEMAIL "SIP_VOICEMAIL"
51
#define FIELD_SIP_ENABLE_STUN "SIP_ENABLE_STUN"
52
#define FIELD_SIP_STUN_SERVER "SIP_STUN_SERVER"
54
#define FIELD_ZRTP_ENABLED "ZRTP_ENABLED"
56
#define FIELD_IAX_ALIAS "IAX_ALIAS"
57
#define FIELD_IAX_SERVER "IAX_SERVER"
58
#define FIELD_IAX_USER "IAX_USER"
59
#define FIELD_IAX_PASSWORD "IAX_PASSWORD"
60
#define FIELD_IAX_VOICEMAIL "IAX_VOICEMAIL"
63
#define SFL_ACCOUNT_HOST "sip.sflphone.org"
65
/***************************************************************************
66
* Global functions for creating an account on sflphone.org *
68
***************************************************************************/
77
///Validate if the connection can be done with the PBX
78
int sendRequest(QString host, int port, QString req, QString & ret)
81
struct sockaddr_in servSockAddr;
82
struct hostent *servHostEnt;
89
bzero(&servSockAddr, sizeof(servSockAddr));
90
servHostEnt = gethostbyname(host.toLatin1());
91
if (servHostEnt == NULL) {
92
ret = "gethostbyname";
95
bcopy((char *)servHostEnt->h_addr, (char *)&servSockAddr.sin_addr, servHostEnt->h_length);
96
servSockAddr.sin_port = htons(port);
97
servSockAddr.sin_family = AF_INET;
99
if ((s = socket(AF_INET,SOCK_STREAM,0)) < 0) {
104
if(connect(s, (const struct sockaddr *) &servSockAddr, (socklen_t) sizeof(servSockAddr)) < 0 ) {
112
const char * req2 = req.toLatin1();
113
const char * host2 = host.toLatin1();
114
fprintf(f, "%s HTTP/1.1\r\n", req2);
115
fprintf(f, "Host: %s\r\n", host2);
116
fputs("User-Agent: SFLphone\r\n", f);
119
while (strncmp(fgets(buf, sizeof(buf), f), "\r\n", 2)) {
120
const char *len_h = "content-length";
121
const char *status_h = "HTTP/1.1";
122
if (strncasecmp(buf, len_h, strlen(len_h)) == 0)
123
length = atoi(buf + strlen(len_h) + 1);
124
if (strncasecmp(buf, status_h, strlen(status_h)) == 0)
125
status = atoi(buf + strlen(status_h) + 1);
127
for (i = 0; i < length; i++)
131
ret = "http error: " + status;
132
// sprintf(ret, "http error: %ld", status);
143
rest_account get_rest_account(QString host, QString email)
145
QString req = "GET /rest/accountcreator?email=" + email;
148
kDebug() << "HOST: " << host;
149
int res = sendRequest(host, 80, req, ret);
151
QStringList list = ret.split("\n");
153
ra.passwd = list[1];\
163
/***************************************************************************
164
* Class AccountWizard *
165
* Widget of the wizard for creating an account. *
166
**************************************************************************/
169
AccountWizard::AccountWizard(QWidget * parent)
172
setPage(Page_Intro , new WizardIntroPage );
173
setPage(Page_AutoMan , new WizardAccountAutoManualPage );
174
setPage(Page_Type , new WizardAccountTypePage );
175
setPage(Page_Email , new WizardAccountEmailAddressPage );
176
setPage(Page_SIPForm , new WizardAccountSIPFormPage );
177
setPage(Page_IAXForm , new WizardAccountIAXFormPage );
178
setPage(Page_Stun , new WizardAccountStunPage );
179
setPage(Page_Conclusion , new WizardAccountConclusionPage );
181
setStartId(Page_Intro);
182
setWindowTitle(i18n("Account creation wizard"));
183
setWindowIcon(QIcon(ICON_SFLPHONE));
184
setMinimumHeight ( 350 );
185
setMinimumWidth ( 500 );
186
setPixmap(QWizard::WatermarkPixmap, QPixmap(ICON_SFLPHONE));
190
AccountWizard::~AccountWizard()
194
///The accept button have been pressed
195
void AccountWizard::accept()
197
ConfigurationManagerInterface & configurationManager = ConfigurationManagerInterfaceSingleton::getInstance();
200
MapStringString accountDetails;
202
QString& alias = accountDetails[ QString(ACCOUNT_ALIAS) ];
203
QString& enabled = accountDetails[ QString(ACCOUNT_ENABLED) ];
204
QString& mailbox = accountDetails[ QString(ACCOUNT_MAILBOX) ];
205
QString& protocol = accountDetails[ QString(ACCOUNT_TYPE) ];
206
QString& server = accountDetails[ QString(ACCOUNT_HOSTNAME) ];
207
QString& user = accountDetails[ QString(ACCOUNT_USERNAME) ];
208
QString& password = accountDetails[ QString(ACCOUNT_PASSWORD) ];
210
// sip only parameters
211
QString& stun_enabled = accountDetails[ QString(ACCOUNT_SIP_STUN_ENABLED) ];
212
QString& stun_server = accountDetails[ QString(ACCOUNT_SIP_STUN_SERVER) ];
214
// zrtp only parameters
215
QString& srtp_enabled = accountDetails[ QString(ACCOUNT_SRTP_ENABLED) ];
216
QString& key_exchange = accountDetails[ QString(ACCOUNT_KEY_EXCHANGE) ];
217
QString& zrtp_display_sas = accountDetails[ QString(ACCOUNT_ZRTP_DISPLAY_SAS) ];
218
QString& zrtp_not_supp_warning = accountDetails[ QString(ACCOUNT_ZRTP_NOT_SUPP_WARNING) ];
219
QString& zrtp_hello_hash = accountDetails[ QString(ACCOUNT_ZRTP_HELLO_HASH) ];
220
QString& display_sas_once = accountDetails[ QString(ACCOUNT_DISPLAY_SAS_ONCE) ];
222
// interface paramters
223
QString& locale_interface = accountDetails[ QString(LOCAL_INTERFACE) ];
224
QString& published_address = accountDetails[ QString(PUBLISHED_ADDRESS) ];
226
bool is_using_sflphone_org = field(FIELD_SFL_ACCOUNT).toBool();
227
bool is_using_sip = false;
228
bool is_create_account = false;
231
if(is_using_sflphone_org) {
232
QString emailAddress = field(FIELD_EMAIL_ADDRESS).toString();
233
char charEmailAddress[1024];
234
strncpy(charEmailAddress, emailAddress.toLatin1(), sizeof(charEmailAddress) - 1);
235
rest_account acc = get_rest_account(SFL_ACCOUNT_HOST, charEmailAddress);
238
ret += i18n("This assistant is now finished.") + "\n";
239
field( FIELD_SIP_ALIAS ) = QString(acc.user) + "@" + SFL_ACCOUNT_HOST;
240
field( FIELD_SIP_VOICEMAIL ) = QString();
241
field( FIELD_SIP_SERVER ) = QString(SFL_ACCOUNT_HOST);
242
field( FIELD_SIP_PASSWORD ) = QString(acc.passwd);
243
field( FIELD_SIP_USER ) = QString(acc.user);
245
protocol = QString( ACCOUNT_TYPE_SIP );
246
server = QString( SFL_ACCOUNT_HOST );
247
password = QString( acc.passwd );
248
user = QString( acc.user );
249
enabled = QString( ACCOUNT_ENABLED_TRUE );
251
is_create_account = true;
255
ret += i18n("Creation of account has failed for the reason") + " :\n";
259
else if(field(FIELD_SIP_ACCOUNT).toBool()) { //sip
260
ret += i18n("This assistant is now finished.") + "\n";
262
alias = field ( FIELD_SIP_ALIAS ).toString();
263
enabled = QString ( ACCOUNT_ENABLED_TRUE );
264
mailbox = field ( FIELD_SIP_VOICEMAIL ).toString();
265
protocol = QString ( ACCOUNT_TYPE_SIP );
266
server = field ( FIELD_SIP_SERVER ).toString();
267
password = field ( FIELD_SIP_PASSWORD ).toString();
268
user = field ( FIELD_SIP_USER ).toString();
270
is_create_account = true;
275
ret += i18n("This assistant is now finished.") + "\n";
277
alias = field ( FIELD_IAX_ALIAS ).toString();
278
enabled = QString ( ACCOUNT_ENABLED_TRUE );
279
mailbox = field ( FIELD_IAX_VOICEMAIL ).toString();
280
protocol = QString ( ACCOUNT_TYPE_IAX );
281
server = field ( FIELD_IAX_SERVER ).toString();
282
password = field ( FIELD_IAX_PASSWORD ).toString();
283
user = field ( FIELD_IAX_USER ).toString();
285
is_create_account = true;
286
is_using_sip = false;
290
// common sip paramaters
292
if(field(FIELD_SIP_ENABLE_STUN).toBool()) {
293
stun_enabled = QString(ACCOUNT_ENABLED_TRUE);
294
stun_server = field(FIELD_SIP_STUN_SERVER).toString();
297
stun_enabled = QString(ACCOUNT_ENABLED_FALSE);
298
stun_server = QString();
301
if(field(FIELD_ZRTP_ENABLED).toBool()) {
302
srtp_enabled = QString( ACCOUNT_ENABLED_TRUE );
303
key_exchange = QString( ZRTP );
304
zrtp_display_sas = QString( ACCOUNT_ENABLED_TRUE );
305
zrtp_not_supp_warning = QString( ACCOUNT_ENABLED_TRUE );
306
zrtp_hello_hash = QString( ACCOUNT_ENABLED_TRUE );
307
display_sas_once = QString( ACCOUNT_ENABLED_FALSE );
310
QStringList ifaceList = configurationManager.getAllIpInterface();
312
locale_interface = ifaceList.at(0);
313
published_address = ifaceList.at(0);
315
ret += i18n( "Alias" ) + " : " + alias + "\n";
316
ret += i18n( "Server" ) + " : " + server + "\n";
317
ret += i18n( "Username" ) + " : " + user + "\n";
318
ret += i18n( "Password" ) + " : " + password + "\n";
319
ret += i18n( "Protocol" ) + " : " + protocol + "\n";
320
ret += i18n( "Voicemail number" ) + " : " + mailbox + "\n";
323
if(is_create_account) {
324
QString accountId = configurationManager.addAccount(accountDetails);
334
/***************************************************************************
335
* Class WizardIntroPage *
336
* Widget of the introduction page of the wizard *
337
**************************************************************************/
340
WizardIntroPage::WizardIntroPage(QWidget *parent)
341
: QWizardPage(parent)
343
setTitle(i18n("Account creation wizard"));
344
setSubTitle(i18n("Welcome to the Account creation wizard of SFLphone!"));
346
introLabel = new QLabel(i18n("This installation wizard will help you configure an account."));
347
introLabel->setWordWrap(true);
349
QVBoxLayout *layout = new QVBoxLayout;
350
layout->addWidget(introLabel);
355
WizardIntroPage::~WizardIntroPage()
360
int WizardIntroPage::nextId() const
362
return AccountWizard::Page_AutoMan;
365
/***************************************************************************
366
* Class WizardAccountAutoManualPage *
367
* Page in which user choses to create an account on *
368
* sflphone.org or register a new one. *
369
**************************************************************************/
371
WizardAccountAutoManualPage::WizardAccountAutoManualPage(QWidget *parent)
372
: QWizardPage(parent)
374
setTitle(i18n("Account"));
375
setSubTitle(i18n("Please select one of the following options"));
377
radioButton_SFL = new QRadioButton(i18n("Create a free SIP/IAX2 account on sflphone.org"));
378
radioButton_manual = new QRadioButton(i18n("Register an existing SIP or IAX2 account"));
379
radioButton_SFL->setChecked(true);
381
registerField( FIELD_SFL_ACCOUNT , radioButton_SFL );
382
registerField( FIELD_OTHER_ACCOUNT , radioButton_manual );
384
QVBoxLayout *layout = new QVBoxLayout;
385
layout->addWidget( radioButton_SFL );
386
layout->addWidget( radioButton_manual );
390
///Second page destructor
391
WizardAccountAutoManualPage::~WizardAccountAutoManualPage()
393
delete radioButton_SFL;
394
delete radioButton_manual;
398
int WizardAccountAutoManualPage::nextId() const
400
if(radioButton_SFL->isChecked())
401
return AccountWizard::Page_Email;
403
return AccountWizard::Page_Type;
406
/***************************************************************************
407
* Class WizardAccountTypePage *
408
* Page in which user choses between SIP and IAX account. *
409
***************************************************************************/
411
WizardAccountTypePage::WizardAccountTypePage(QWidget *parent)
412
: QWizardPage(parent)
414
setTitle ( i18n("VoIP Protocols" ));
415
setSubTitle ( i18n("Select an account type" ));
417
radioButton_SIP = new QRadioButton(i18n("SIP (Session Initiation Protocol)" ));
418
radioButton_IAX = new QRadioButton(i18n("IAX2 (InterAsterix Exchange)" ));
419
radioButton_SIP->setChecked(true);
421
registerField( FIELD_SIP_ACCOUNT, radioButton_SIP );
422
registerField( FIELD_IAX_ACCOUNT, radioButton_IAX );
424
QVBoxLayout *layout = new QVBoxLayout;
425
layout->addWidget(radioButton_SIP);
426
layout->addWidget(radioButton_IAX);
430
///Third page destructor
431
WizardAccountTypePage::~WizardAccountTypePage()
433
delete radioButton_SIP;
434
delete radioButton_IAX;
438
int WizardAccountTypePage::nextId() const
440
if(radioButton_SIP->isChecked())
441
return AccountWizard::Page_SIPForm;
443
return AccountWizard::Page_IAXForm;
446
/***************************************************************************
447
* Class WizardAccountEmailAddressPage *
448
* Page in which user choses between SIP and IAX account. *
449
**************************************************************************/
451
///Set your email address
452
WizardAccountEmailAddressPage::WizardAccountEmailAddressPage(QWidget *parent)
453
: QWizardPage(parent)
455
setTitle(i18n("Optional email address"));
456
setSubTitle(i18n("This email address will be used to send your voicemail messages."));
458
label_emailAddress = new QLabel(i18n("Email address"));
459
lineEdit_emailAddress = new QLineEdit();
460
label_enableZrtp = new QLabel(i18n("Secure with ZRTP"));
461
checkBox_enableZrtp = new QCheckBox();
463
registerField( FIELD_EMAIL_ADDRESS , lineEdit_emailAddress );
464
registerField( FIELD_ZRTP_ENABLED , checkBox_enableZrtp );
466
QFormLayout *layout = new QFormLayout;
468
layout->setWidget(0 , QFormLayout::LabelRole , label_emailAddress );
469
layout->setWidget(0 , QFormLayout::FieldRole , lineEdit_emailAddress );
470
layout->setWidget(1 , QFormLayout::LabelRole , label_enableZrtp );
471
layout->setWidget(1 , QFormLayout::FieldRole , checkBox_enableZrtp );
476
///Email page destructor
477
WizardAccountEmailAddressPage::~WizardAccountEmailAddressPage()
479
delete label_emailAddress;
480
delete lineEdit_emailAddress;
481
delete label_enableZrtp;
482
delete checkBox_enableZrtp;
486
int WizardAccountEmailAddressPage::nextId() const
488
return AccountWizard::Page_Stun;
491
/***************************************************************************
492
* Class WizardAccountFormPage *
493
* Page of account settings. *
494
**************************************************************************/
496
WizardAccountSIPFormPage::WizardAccountSIPFormPage(QWidget *parent)
497
: QWizardPage(parent)
499
setTitle(i18n("SIP account settings"));
500
setSubTitle(i18n("Please fill the following information"));
502
label_alias = new QLabel( i18n( "Alias" ) + " *" );
503
label_server = new QLabel( i18n( "Server" ) + " *" );
504
label_user = new QLabel( i18n( "Username" ) + " *" );
505
label_password = new QLabel( i18n( "Password" ) + " *" );
506
label_voicemail = new QLabel( i18n( "Voicemail number" ) );
507
label_enableZrtp = new QLabel( i18n( "Secure with ZRTP" ) );
509
lineEdit_alias = new QLineEdit;
510
lineEdit_server = new QLineEdit;
511
lineEdit_user = new QLineEdit;
512
lineEdit_password = new QLineEdit;
513
lineEdit_voicemail = new QLineEdit;
514
checkBox_enableZrtp = new QCheckBox;
516
lineEdit_password->setEchoMode(QLineEdit::Password);
518
registerField(QString( FIELD_SIP_ALIAS) + "*" , lineEdit_alias );
519
registerField(QString( FIELD_SIP_SERVER) + "*" , lineEdit_server );
520
registerField(QString( FIELD_SIP_USER) + "*" , lineEdit_user );
521
registerField(QString( FIELD_SIP_PASSWORD) + "*" , lineEdit_password );
522
registerField(QString( FIELD_SIP_VOICEMAIL) , lineEdit_voicemail );
523
registerField(QString( FIELD_ZRTP_ENABLED) , checkBox_enableZrtp );
525
QFormLayout *layout = new QFormLayout;
528
layout->setWidget( 0, QFormLayout::LabelRole , label_alias );
529
layout->setWidget( 0, QFormLayout::FieldRole , lineEdit_alias );
530
layout->setWidget( 1, QFormLayout::LabelRole , label_server );
531
layout->setWidget( 1, QFormLayout::FieldRole , lineEdit_server );
532
layout->setWidget( 2, QFormLayout::LabelRole , label_user );
533
layout->setWidget( 2, QFormLayout::FieldRole , lineEdit_user );
534
layout->setWidget( 3, QFormLayout::LabelRole , label_password );
535
layout->setWidget( 3, QFormLayout::FieldRole , lineEdit_password );
536
layout->setWidget( 4, QFormLayout::LabelRole , label_voicemail );
537
layout->setWidget( 4, QFormLayout::FieldRole , lineEdit_voicemail );
538
layout->setWidget( 5, QFormLayout::LabelRole , label_enableZrtp );
539
layout->setWidget( 5, QFormLayout::FieldRole , checkBox_enableZrtp );
545
WizardAccountSIPFormPage::~WizardAccountSIPFormPage()
550
delete label_password;
551
delete label_voicemail;
552
delete label_enableZrtp;
553
delete lineEdit_alias;
554
delete lineEdit_server;
555
delete lineEdit_user;
556
delete lineEdit_password;
557
delete lineEdit_voicemail;
558
delete checkBox_enableZrtp;
561
int WizardAccountSIPFormPage::nextId() const
563
return AccountWizard::Page_Stun;
566
/***************************************************************************
567
* Class WizardAccountFormPage *
568
* Page of account settings. *
569
***************************************************************************/
571
WizardAccountIAXFormPage::WizardAccountIAXFormPage(QWidget *parent)
572
: QWizardPage(parent)
574
setTitle(i18n("IAX2 account settings"));
575
setSubTitle(i18n("Please fill the following information"));
577
label_alias = new QLabel(i18n("Alias") + " *" );
578
label_server = new QLabel(i18n("Server") + " *" );
579
label_user = new QLabel(i18n("Username") + " *" );
580
label_password = new QLabel(i18n("Password") + " *" );
581
label_voicemail = new QLabel(i18n("Voicemail number" ));
583
lineEdit_alias = new QLineEdit;
584
lineEdit_server = new QLineEdit;
585
lineEdit_user = new QLineEdit;
586
lineEdit_password = new QLineEdit;
587
lineEdit_voicemail = new QLineEdit;
589
lineEdit_password->setEchoMode(QLineEdit::Password);
591
registerField( QString( FIELD_IAX_ALIAS ) + "*", lineEdit_alias );
592
registerField( QString( FIELD_IAX_SERVER ) + "*", lineEdit_server );
593
registerField( QString( FIELD_IAX_USER ) + "*", lineEdit_user );
594
registerField( QString( FIELD_IAX_PASSWORD ) + "*", lineEdit_password );
595
registerField( QString( FIELD_IAX_VOICEMAIL ) , lineEdit_voicemail );
597
QFormLayout *layout = new QFormLayout;
599
layout->setWidget( 0 , QFormLayout::LabelRole , label_alias );
600
layout->setWidget( 0 , QFormLayout::FieldRole , lineEdit_alias );
601
layout->setWidget( 1 , QFormLayout::LabelRole , label_server );
602
layout->setWidget( 1 , QFormLayout::FieldRole , lineEdit_server );
603
layout->setWidget( 2 , QFormLayout::LabelRole , label_user );
604
layout->setWidget( 2 , QFormLayout::FieldRole , lineEdit_user );
605
layout->setWidget( 3 , QFormLayout::LabelRole , label_password );
606
layout->setWidget( 3 , QFormLayout::FieldRole , lineEdit_password );
607
layout->setWidget( 4 , QFormLayout::LabelRole , label_voicemail );
608
layout->setWidget( 4 , QFormLayout::FieldRole , lineEdit_voicemail );
614
WizardAccountIAXFormPage::~WizardAccountIAXFormPage()
619
delete label_password;
620
delete label_voicemail;
621
delete lineEdit_alias;
622
delete lineEdit_server;
623
delete lineEdit_user;
624
delete lineEdit_password;
625
delete lineEdit_voicemail;
628
int WizardAccountIAXFormPage::nextId() const
630
return AccountWizard::Page_Conclusion;
633
/***************************************************************************
634
* Class WizardAccountStunPage *
635
* Page of Stun settings. *
636
***************************************************************************/
638
WizardAccountStunPage::WizardAccountStunPage(QWidget *parent)
639
: QWizardPage(parent)
641
setTitle(i18n("Network Address Translation (NAT)"));
642
setSubTitle(i18n("You should probably enable this if you are behind a firewall."));
644
checkBox_enableStun = new QCheckBox(i18n("Enable STUN"));
645
label_StunServer = new QLabel(i18n("Stun Server"));
646
lineEdit_StunServer = new QLineEdit();
647
lineEdit_StunServer->setDisabled(true);
649
registerField(FIELD_SIP_ENABLE_STUN, checkBox_enableStun);
650
registerField(FIELD_SIP_STUN_SERVER, lineEdit_StunServer);
652
QFormLayout *layout = new QFormLayout;
653
layout->addWidget( checkBox_enableStun );
654
layout->addWidget( label_StunServer );
655
layout->addWidget( lineEdit_StunServer );
658
connect(checkBox_enableStun, SIGNAL(toggled(bool)), lineEdit_StunServer, SLOT(setEnabled(bool)));
662
WizardAccountStunPage::~WizardAccountStunPage()
664
delete checkBox_enableStun;
665
delete label_StunServer;
666
delete lineEdit_StunServer;
669
int WizardAccountStunPage::nextId() const
671
return AccountWizard::Page_Conclusion;
674
/***************************************************************************
675
* Class WizardAccountConclusionPage *
677
***************************************************************************/
679
WizardAccountConclusionPage::WizardAccountConclusionPage(QWidget *parent)
680
: QWizardPage(parent)
682
setTitle(i18n("This assistant is now finished."));
683
setSubTitle(i18n("After checking the settings you chose, click \"Finish\" to create the account."));
685
QVBoxLayout *layout = new QVBoxLayout;
689
WizardAccountConclusionPage::~WizardAccountConclusionPage()
693
int WizardAccountConclusionPage::nextId() const