VirtualBox

source: vbox/trunk/src/VBox/Frontends/VirtualBox/ui/VBoxRegistrationDlg.ui.h@ 5592

Last change on this file since 5592 was 5592, checked in by vboxsync, 17 years ago

Registration dialog: use the Runtime function rather than the Qt function (important for our .debs/.rpms)

  • Property svn:eol-style set to native
  • Property svn:keywords set to Date Revision Author Id
File size: 17.3 KB
Line 
1/**
2 *
3 * VBox frontends: Qt GUI ("VirtualBox"):
4 * VBoxRegistrationDlg UI include (Qt Designer)
5 */
6
7/*
8 * Copyright (C) 2007 innotek GmbH
9 *
10 * This file is part of VirtualBox Open Source Edition (OSE), as
11 * available from http://www.virtualbox.org. This file is free software;
12 * you can redistribute it and/or modify it under the terms of the GNU
13 * General Public License as published by the Free Software Foundation,
14 * in version 2 as it comes in the "COPYING" file of the VirtualBox OSE
15 * distribution. VirtualBox OSE is distributed in the hope that it will
16 * be useful, but WITHOUT ANY WARRANTY of any kind.
17 */
18
19/****************************************************************************
20** ui.h extension file, included from the uic-generated form implementation.
21**
22** If you want to add, delete, or rename functions or slots, use
23** Qt Designer to update this file, preserving your code.
24**
25** You should not define a constructor or destructor in this file.
26** Instead, write your code in functions called init() and destroy().
27** These will automatically be called by the form's constructor and
28** destructor.
29*****************************************************************************/
30
31#include <iprt/param.h>
32#include <iprt/path.h>
33
34/**
35 * This class is used to encode/decode the registration data.
36 */
37class VBoxRegistrationData
38{
39public:
40
41 VBoxRegistrationData (const QString &aData)
42 : mIsValid (false), mIsRegistered (false)
43 , mData (aData)
44 , mTriesLeft (3 /* the initial tries value! */)
45 {
46 decode (aData);
47 }
48
49 VBoxRegistrationData (const QString &aName, const QString &aEmail,
50 const QString &aPrivate)
51 : mIsValid (true), mIsRegistered (true)
52 , mName (aName), mEmail (aEmail), mPrivate (aPrivate)
53 , mTriesLeft (0)
54 {
55 encode (aName, aEmail, aPrivate);
56 }
57
58 bool isValid() const { return mIsValid; }
59 bool isRegistered() const { return mIsRegistered; }
60
61 const QString &data() const { return mData; }
62 const QString &name() const { return mName; }
63 const QString &email() const { return mEmail; }
64 const QString &isPrivate() const { return mPrivate; }
65
66 uint triesLeft() const { return mTriesLeft; }
67
68private:
69
70 void decode (const QString &aData)
71 {
72 mIsValid = mIsRegistered = false;
73
74 if (aData.isEmpty())
75 return;
76
77 if (aData.startsWith ("triesLeft="))
78 {
79 bool ok = false;
80 uint triesLeft = aData.section ('=', 1, 1).toUInt (&ok);
81 if (!ok)
82 return;
83 mTriesLeft = triesLeft;
84 mIsValid = true;
85 return;
86 }
87
88 /* Decoding CRC32 */
89 QString data = aData;
90 QString crcData = data.right (2 * sizeof (ulong));
91 ulong crcNeed = 0;
92 for (ulong i = 0; i < crcData.length(); i += 2)
93 {
94 crcNeed <<= 8;
95 uchar curByte = (uchar) crcData.mid (i, 2).toUShort (0, 16);
96 crcNeed += curByte;
97 }
98 data.truncate (data.length() - 2 * sizeof (ulong));
99
100 /* Decoding data */
101 QString result;
102 for (ulong i = 0; i < data.length(); i += 4)
103 result += QChar (data.mid (i, 4).toUShort (0, 16));
104 ulong crcNow = crc32 ((uchar*)result.ascii(), result.length());
105
106 /* Check the CRC32 */
107 if (crcNeed != crcNow)
108 return;
109
110 /* Initialize values */
111 QStringList dataList = QStringList::split ("|", result);
112 mName = dataList [0];
113 mEmail = dataList [1];
114 mPrivate = dataList [2];
115
116 mIsValid = true;
117 mIsRegistered = true;
118 }
119
120 void encode (const QString &aName, const QString &aEmail,
121 const QString &aPrivate)
122 {
123 /* Encoding data */
124 QString data = QString ("%1|%2|%3")
125 .arg (aName).arg (aEmail).arg (aPrivate);
126 mData = QString::null;
127 for (ulong i = 0; i < data.length(); ++ i)
128 {
129 QString curPair = QString::number (data.at (i).unicode(), 16);
130 while (curPair.length() < 4)
131 curPair.prepend ('0');
132 mData += curPair;
133 }
134
135 /* Enconding CRC32 */
136 ulong crcNow = crc32 ((uchar*)data.ascii(), data.length());
137 QString crcData;
138 for (ulong i = 0; i < sizeof (ulong); ++ i)
139 {
140 ushort curByte = crcNow & 0xFF;
141 QString curPair = QString::number (curByte, 16);
142 if (curPair.length() == 1)
143 curPair.prepend ("0");
144 crcData = curPair + crcData;
145 crcNow >>= 8;
146 }
147
148 mData += crcData;
149 }
150
151 ulong crc32 (unsigned char *aBufer, int aSize)
152 {
153 /* Filling CRC32 table */
154 ulong crc32;
155 ulong crc_table [256];
156 ulong temp;
157 for (int i = 0; i < 256; ++ i)
158 {
159 temp = i;
160 for (int j = 8; j > 0; -- j)
161 {
162 if (temp & 1)
163 temp = (temp >> 1) ^ 0xedb88320;
164 else
165 temp >>= 1;
166 };
167 crc_table [i] = temp;
168 }
169
170 /* CRC32 calculation */
171 crc32 = 0xffffffff;
172 for (int i = 0; i < aSize; ++ i)
173 {
174 crc32 = crc_table [(crc32 ^ (*aBufer ++)) & 0xff] ^ (crc32 >> 8);
175 }
176 crc32 = crc32 ^ 0xffffffff;
177 return crc32;
178 };
179
180 bool mIsValid : 1;
181 bool mIsRegistered : 1;
182
183 QString mData;
184 QString mName;
185 QString mEmail;
186 QString mPrivate;
187
188 uint mTriesLeft;
189};
190
191/* static */
192bool VBoxRegistrationDlg::hasToBeShown()
193{
194 VBoxRegistrationData regData (vboxGlobal().virtualBox().
195 GetExtraData (VBoxDefs::GUI_RegistrationData));
196
197 return !regData.isValid() ||
198 (!regData.isRegistered() && regData.triesLeft() > 0);
199}
200
201/* Default constructor initialization. */
202void VBoxRegistrationDlg::init()
203{
204 /* Hide unnecessary buttons */
205 helpButton()->setShown (false);
206 cancelButton()->setShown (false);
207 backButton()->setShown (false);
208
209 /* Confirm button initially disabled */
210 finishButton()->setEnabled (false);
211 finishButton()->setAutoDefault (true);
212 finishButton()->setDefault (true);
213
214 /* Setup the label colors for nice scaling */
215 VBoxGlobal::adoptLabelPixmap (pictureLabel);
216
217 /* Adjust text label size */
218 mTextLabel->setMinimumWidth (widthSpacer->minimumSize().width());
219
220 /* Setup validations and maximum text-edit text length */
221 QRegExp nameExp ("[\\S\\s]+");
222 /* E-mail address is validated according to RFC2821, RFC2822,
223 * see http://en.wikipedia.org/wiki/E-mail_address. */
224 QRegExp emailExp ("(([a-zA-Z0-9_\\-\\.!#$%\\*/?|^{}`~&'\\+=]*"
225 "[a-zA-Z0-9_\\-!#$%\\*/?|^{}`~&'\\+=])|"
226 "(\"([\\x0001-\\x0008,\\x000B,\\x000C,\\x000E-\\x0019,\\x007F,"
227 "\\x0021,\\x0023-\\x005B,\\x005D-\\x007E,"
228 "\\x0009,\\x0020]|"
229 "(\\\\[\\x0001-\\x0009,\\x000B,\\x000C,"
230 "\\x000E-\\x007F]))*\"))"
231 "@"
232 "[a-zA-Z0-9\\-]+(\\.[a-zA-Z0-9\\-]+)*");
233 mNameEdit->setValidator (new QRegExpValidator (nameExp, this));
234 mEmailEdit->setValidator (new QRegExpValidator (emailExp, this));
235 mNameEdit->setMaxLength (50);
236 mEmailEdit->setMaxLength (50);
237
238 /* Create connection-timeout timer */
239 mTimeout = new QTimer (this);
240
241 /* Load language constraints */
242 languageChangeImp();
243
244 /* Set required boolean flags */
245 mSuicide = false;
246 mHandshake = true;
247
248 /* Network framework */
249 mNetfw = 0;
250
251 /* Setup connections */
252 disconnect (finishButton(), SIGNAL (clicked()), 0, 0);
253 connect (finishButton(), SIGNAL (clicked()), SLOT (registration()));
254 connect (mTimeout, SIGNAL (timeout()), this, SLOT (processTimeout()));
255 connect (mNameEdit, SIGNAL (textChanged (const QString&)), this, SLOT (validate()));
256 connect (mEmailEdit, SIGNAL (textChanged (const QString&)), this, SLOT (validate()));
257 connect (mTextLabel, SIGNAL (clickedOnLink (const QString &)),
258 &vboxGlobal(), SLOT (openURL (const QString &)));
259
260 /* Resize the dialog initially to minimum size */
261 resize (minimumSize());
262}
263
264/* Default destructor cleanup. */
265void VBoxRegistrationDlg::destroy()
266{
267 delete mNetfw;
268 *mSelf = 0;
269}
270
271/* Setup necessary dialog parameters. */
272void VBoxRegistrationDlg::setup (VBoxRegistrationDlg **aSelf)
273{
274 mSelf = aSelf;
275 *mSelf = this;
276 mUrl = "http://www.innotek.de/register762.php";
277
278 VBoxRegistrationData regData (vboxGlobal().virtualBox().
279 GetExtraData (VBoxDefs::GUI_RegistrationData));
280
281 mNameEdit->setText (regData.name());
282 mEmailEdit->setText (regData.email());
283 mUseCheckBox->setChecked (regData.isPrivate() == "yes");
284}
285
286/* String constants initializer. */
287void VBoxRegistrationDlg::languageChangeImp()
288{
289 finishButton()->setText (tr ("&Confirm"));
290}
291
292void VBoxRegistrationDlg::postRequest (const QString &aHost,
293 const QString &aUrl)
294{
295 delete mNetfw;
296 mNetfw = new VBoxNetworkFramework();
297 connect (mNetfw, SIGNAL (netBegin (int)),
298 SLOT (onNetBegin (int)));
299 connect (mNetfw, SIGNAL (netData (const QByteArray&)),
300 SLOT (onNetData (const QByteArray&)));
301 connect (mNetfw, SIGNAL (netEnd (const QByteArray&)),
302 SLOT (onNetEnd (const QByteArray&)));
303 connect (mNetfw, SIGNAL (netError (const QString&)),
304 SLOT (onNetError (const QString&)));
305
306 mNetfw->postRequest (aHost, aUrl);
307}
308
309
310/* Post the handshake request into the innotek register site. */
311void VBoxRegistrationDlg::registration()
312{
313 /* Disable control elements */
314 mNameEdit->setEnabled (false);
315 mEmailEdit->setEnabled (false);
316 mUseCheckBox->setEnabled (false);
317 finishButton()->setEnabled (false);
318
319 /* Handshake arguments initializing */
320 QString version = vboxGlobal().virtualBox().GetVersion();
321 QUrl::encode (version);
322
323 /* Handshake */
324 QString argument = QString ("?version=%1").arg (version);
325 mTimeout->start (20000, true);
326 postRequest (mUrl.host(), mUrl.path() + argument);
327}
328
329/* This slot is used to control the connection timeout. */
330void VBoxRegistrationDlg::processTimeout()
331{
332 abortRegisterRequest (tr ("Connection timed out."));
333}
334
335/* Handles the network request begining. */
336void VBoxRegistrationDlg::onNetBegin (int aStatus)
337{
338 if (aStatus == 404)
339 abortRegisterRequest (tr ("Could not locate the registration form on "
340 "the server (response: %1).").arg (aStatus));
341 else
342 mTimeout->start (20000, true);
343}
344
345/* Handles the network request data incoming. */
346void VBoxRegistrationDlg::onNetData (const QByteArray&)
347{
348 if (!mSuicide)
349 mTimeout->start (20000, true);
350}
351
352/* Handles the network request end. */
353void VBoxRegistrationDlg::onNetEnd (const QByteArray &aTotalData)
354{
355 if (mSuicide)
356 return;
357
358 mTimeout->stop();
359 if (mHandshake)
360 {
361 /* Registration arguments initializing */
362 QString version = vboxGlobal().virtualBox().GetVersion();
363 QString key (aTotalData);
364 QString platform = getPlatform();
365 QString name = mNameEdit->text();
366 QString email = mEmailEdit->text();
367 QString prvt = mUseCheckBox->isChecked() ? "1" : "0";
368 QUrl::encode (version);
369 QUrl::encode (platform);
370 QUrl::encode (name);
371 QUrl::encode (email);
372
373 /* Registration */
374 QString argument;
375 argument += QString ("?version=%1").arg (version);
376 argument += QString ("&key=%1").arg (key);
377 argument += QString ("&platform=%1").arg (platform);
378 argument += QString ("&name=%1").arg (name);
379 argument += QString ("&email=%1").arg (email);
380 argument += QString ("&private=%1").arg (prvt);
381
382 mHandshake = false;
383 mTimeout->start (20000, true);
384 postRequest (mUrl.host(), mUrl.path() + argument);
385 }
386 else
387 {
388 /* Show registration result */
389 QString result (aTotalData);
390 vboxProblem().showRegisterResult (this, result);
391
392 /* Close the dialog */
393 result == "OK" ? accept() : reject();
394 }
395}
396
397void VBoxRegistrationDlg::onNetError (const QString &aError)
398{
399 abortRegisterRequest (aError);
400}
401
402/* SLOT: QDialog accept slot reimplementation. */
403void VBoxRegistrationDlg::accept()
404{
405 vboxGlobal().virtualBox().SetExtraData (VBoxDefs::GUI_RegistrationDlgWinID,
406 QString::null);
407
408 VBoxRegistrationData regData (mNameEdit->text(), mEmailEdit->text(),
409 mUseCheckBox->isChecked() ? "yes" : "no");
410 vboxGlobal().virtualBox().SetExtraData (VBoxDefs::GUI_RegistrationData,
411 regData.data());
412
413 QDialog::accept();
414}
415
416/* SLOT: QDialog reject slot reimplementation. */
417void VBoxRegistrationDlg::reject()
418{
419 vboxGlobal().virtualBox().SetExtraData (VBoxDefs::GUI_RegistrationDlgWinID,
420 QString::null);
421
422 /* Decrement the triesLeft. */
423 VBoxRegistrationData regData (vboxGlobal().virtualBox().
424 GetExtraData (VBoxDefs::GUI_RegistrationData));
425 if (!regData.isValid() || !regData.isRegistered())
426 {
427 uint triesLeft = regData.triesLeft();
428 if (triesLeft)
429 {
430 -- triesLeft;
431 vboxGlobal().virtualBox().SetExtraData (VBoxDefs::GUI_RegistrationData,
432 QString ("triesLeft=%1")
433 .arg (triesLeft));
434 }
435 }
436
437 QDialog::reject();
438}
439
440void VBoxRegistrationDlg::validate()
441{
442 int pos = 0;
443 QString name = mNameEdit->text();
444 QString email = mEmailEdit->text();
445 finishButton()->setEnabled (
446 mNameEdit->validator()->validate (name, pos) == QValidator::Acceptable &&
447 mEmailEdit->validator()->validate (email, pos) == QValidator::Acceptable);
448}
449
450QString VBoxRegistrationDlg::getPlatform()
451{
452 QString platform;
453
454#if defined (Q_OS_WIN)
455 platform = "win";
456#elif defined (Q_OS_LINUX)
457 platform = "linux";
458#elif defined (Q_OS_MACX)
459 platform = "macosx";
460#elif defined (Q_OS_OS2)
461 platform = "os2";
462#elif defined (Q_OS_FREEBSD)
463 platform = "freebsd";
464#elif defined (Q_OS_SOLARIS)
465 platform = "solaris";
466#else
467 platform = "unknown";
468#endif
469
470 /* the format is <system>.<bitness> */
471 platform += QString (".%1").arg (ARCH_BITS);
472
473 /* add more system information */
474#if defined (Q_OS_WIN)
475 OSVERSIONINFO versionInfo;
476 ZeroMemory (&versionInfo, sizeof (OSVERSIONINFO));
477 versionInfo.dwOSVersionInfoSize = sizeof (OSVERSIONINFO);
478 GetVersionEx (&versionInfo);
479 int major = versionInfo.dwMajorVersion;
480 int minor = versionInfo.dwMinorVersion;
481 int build = versionInfo.dwBuildNumber;
482 QString sp = QString::fromUcs2 ((ushort*)versionInfo.szCSDVersion);
483
484 QString distrib;
485 if (major == 6)
486 distrib = QString ("Windows Vista %1");
487 else if (major == 5)
488 {
489 if (minor == 2)
490 distrib = QString ("Windows Server 2003 %1");
491 else if (minor == 1)
492 distrib = QString ("Windows XP %1");
493 else if (minor == 0)
494 distrib = QString ("Windows 2000 %1");
495 else
496 distrib = QString ("Unknown %1");
497 }
498 else if (major == 4)
499 {
500 if (minor == 90)
501 distrib = QString ("Windows Me %1");
502 else if (minor == 10)
503 distrib = QString ("Windows 98 %1");
504 else if (minor == 0)
505 distrib = QString ("Windows 95 %1");
506 else
507 distrib = QString ("Unknown %1");
508 }
509 else
510 distrib = QString ("Unknown %1");
511 distrib = distrib.arg (sp);
512 QString version = QString ("%1.%2").arg (major).arg (minor);
513 QString kernel = QString ("%1").arg (build);
514 platform += QString (" [Distribution: %1 | Version: %2 | Build: %3]")
515 .arg (distrib).arg (version).arg (kernel);
516#elif defined (Q_OS_OS2)
517 // TODO: add sys info for os2 if any...
518#elif defined (Q_OS_LINUX) || defined (Q_OS_MACX) || defined (Q_OS_FREEBSD) || defined (Q_OS_SOLARIS)
519 char szAppPrivPath [RTPATH_MAX];
520 int rc;
521
522 rc = RTPathAppPrivateNoArch (szAppPrivPath, sizeof (szAppPrivPath));
523 Assert (RT_SUCCESS (rc));
524 QProcess infoScript (QString ("./VBoxSysInfo.sh"), this, "infoScript");
525 infoScript.setWorkingDirectory (QString (szAppPrivPath));
526 if (infoScript.start())
527 {
528 while (infoScript.isRunning()) {}
529 if (infoScript.normalExit())
530 platform += QString (" [%1]").arg (infoScript.readStdout());
531 }
532#endif
533
534 return platform;
535}
536
537/* This wrapper displays an error message box (unless aReason is
538 * QString::null) with the cause of the request-send procedure
539 * termination. After the message box is dismissed, the downloader signals
540 * to close itself on the next event loop iteration. */
541void VBoxRegistrationDlg::abortRegisterRequest (const QString &aReason)
542{
543 /* Protect against double kill request. */
544 if (mSuicide)
545 return;
546 mSuicide = true;
547
548 if (!aReason.isNull())
549 vboxProblem().cannotConnectRegister (this, mUrl.toString(), aReason);
550
551 /* Allows all the queued signals to be processed before quit. */
552 QTimer::singleShot (0, this, SLOT (reject()));
553}
554
555void VBoxRegistrationDlg::showEvent (QShowEvent *aEvent)
556{
557 validate();
558 QWizard::showEvent (aEvent);
559}
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette