PageRenderTime 68ms CodeModel.GetById 26ms RepoModel.GetById 0ms app.codeStats 0ms

/launchBoxSim/launchboxsim.cpp

https://bitbucket.org/sumant_rapsodo/sourcetree
C++ | 2714 lines | 2408 code | 229 blank | 77 comment | 567 complexity | d041307d184aaffb1d6835c1eb2b6c14 MD5 | raw file
  1. /*******************************************************************************
  2. * @attention
  3. *
  4. * AUTHOR: Michael, Kelvin
  5. *
  6. * DATE: 8 March 2016
  7. *
  8. * VERSION: 1.44
  9. *
  10. * COPYRIGHT RAPSODO PTE. LTD. MARCH, 2016
  11. * ALL RIGHTS RESERVED
  12. *
  13. * THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED INCLUDING BUT NOT LIMITED TO WARRANTIES OF MERCHANTIBILITY,
  14. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  15. * LIABILITY,. WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  16. * IN SOFTWARE.
  17. * `
  18. * YOU SHOULD HAVE A LICENSE AGREEMENT WITH RAPSODO TO USE THIS SOURCE CODE.
  19. * CONFIDENTIAL AND RELEASED UNDER NDA.
  20. ********************************************************************************************************/
  21. #include "launchboxsim.h"
  22. #include <QScrollBar>
  23. #include <QMovie>
  24. #include "rmdInterface.h"
  25. #include "helper.h"
  26. #define MAIN_APPLICATION_VERSION_MAJOR 1
  27. #define MAIN_APPLICATION_VERSION_MINOR 3
  28. #define MAIN_APPLICATION_VERSION_TAIL 2
  29. #define FW_VERSION_MAJOR 1
  30. #define FW_VERSION_MINOR 3
  31. #define FW_VERSION_TAIL 1
  32. #define HW_VERSION_MAJOR 1
  33. #define HW_VERSION_MINOR 2
  34. #define HW_VERSION_TAIL 0
  35. static unsigned char encrytionKeys[ENCRYPTION_KEY_SIZE]=
  36. {
  37. //G5M5E97O41KNjLpT6kc5vCTLmM0dnLea ProTee to Rapsodo Key
  38. 0x47, 0x35, 0x4d, 0x35, 0x45, 0x39, 0x37, 0x4f, 0x34, 0x31, 0x4b,
  39. 0x4e, 0x6a, 0x4c, 0x70, 0x54, 0x36, 0x6b, 0x63, 0x35, 0x76, 0x43,
  40. 0x54, 0x4c, 0x6d, 0x4d, 0x30, 0x64, 0x6e, 0x4c, 0x65, 0x61
  41. };
  42. static unsigned char encrytionIVLE[ENCRYPTION_KEY_SIZE]=
  43. {
  44. //139tes147rboPO0teze4Xh0W8W7Fb1a1 ProTee to Rapsodo Key
  45. 0x31, 0x33, 0x39, 0x74, 0x65, 0x73, 0x31, 0x34, 0x37, 0x72, 0x62,
  46. 0x6f, 0x50, 0x4f, 0x30, 0x74, 0x65, 0x7a, 0x65, 0x34, 0x58, 0x68,
  47. 0x30, 0x57, 0x38, 0x57, 0x37, 0x46, 0x62, 0x31, 0x61, 0x31
  48. };
  49. extern QString gamePathString;
  50. extern QString ourPathString;
  51. extern QString zipFilePrepend;
  52. extern ball_params ballResult;
  53. extern club_params clubResult;
  54. launchBoxSim::launchBoxSim(QWidget *parent)
  55. : QMainWindow(parent)
  56. {
  57. ui.setupUi(this);
  58. setWindowFlags(Qt::Window);
  59. statusBar()->hide();
  60. windowsTitleString = "R-Motion " + QString::number(MAIN_APPLICATION_VERSION_MAJOR) + "." + QString::number(MAIN_APPLICATION_VERSION_MINOR) +
  61. "." + QString::number(MAIN_APPLICATION_VERSION_TAIL);
  62. setWindowTitle(windowsTitleString);
  63. qDebug() << "Current Version:" << windowsTitleString;
  64. savedData = new QSettings("Rapsodo", "Rmotion");
  65. qDebug() << savedData->fileName();
  66. userLoginStatus = savedData->value("ui/userLoginStatus", QVariant(0)).toInt();
  67. userLicenseStatus = savedData->value("ui/userLicenseStatus", QVariant(0)).toInt();
  68. userEmail = savedData->value("ui/userEmail", QVariant(tr(""))).toString();
  69. dongleIdText = savedData->value("ui/dongleIdText", QVariant(tr(""))).toString();
  70. machineIdText = savedData->value("ui/machineIdText", QVariant(tr(""))).toString();
  71. userLicenseText = savedData->value("ui/userLicenseText", QVariant(tr(""))).toString();
  72. userFullLicenseText = savedData->value("ui/userFullLicenseText", QVariant(tr(""))).toString();
  73. licenseCurState = LICENSE_SM_NONE_VALID;
  74. licenseNewState = LICENSE_SM_MIN;
  75. triedFreeLicense = 0;
  76. triedFullLicense = 0;
  77. settingsEnableShotLog = "OFF";
  78. settingsEnableDebugMode = "OFF";
  79. settingsSendDebugData = "OFF";
  80. settingsSendFalseTrigger = "OFF";
  81. settingsDisableAutoStandby = "OFF";
  82. // read user settings from userSettings.txt file
  83. QFile userSettingsFile(ourPathString + "userSettings.txt");
  84. if ((userSettingsFile.exists()) && (userSettingsFile.open(QFile::ReadOnly | QFile::Text))) // check if the file existed and we can read
  85. {
  86. QTextStream tmpIn(&userSettingsFile);
  87. QString userSettingsText = "";
  88. while ((userSettingsText = tmpIn.readLine()) != "")
  89. {
  90. QList<QString> userSettingsToken = userSettingsText.split('=');
  91. if (userSettingsToken.count() == 2)
  92. {
  93. if ((userSettingsToken[0].contains("USER_ENABLE_SHOT_LOG")) && (userSettingsToken[1].contains("ON")))
  94. settingsEnableShotLog = "ON";
  95. if ((userSettingsToken[0].contains("USER_DISABLE_AUTO_STANDBY")) && (userSettingsToken[1].contains("ON")))
  96. settingsDisableAutoStandby = "ON";
  97. if ((userSettingsToken[0].contains("USER_SEND_DEBUG_DATA")) && (userSettingsToken[1].contains("ON")))
  98. settingsSendDebugData = "ON";
  99. if ((userSettingsToken[0].contains("USER_SEND_FALSE_TRIGGER")) && (userSettingsToken[1].contains("ON")))
  100. settingsSendFalseTrigger = "ON";
  101. if ((userSettingsToken[0].contains("USER_ENABLE_DEBUG_MODE")) && (userSettingsToken[1].contains("ON")))
  102. settingsEnableDebugMode = "ON";
  103. }
  104. }
  105. userSettingsFile.close();
  106. }
  107. qDebug() << "From file: disableAutoStandby" << settingsDisableAutoStandby;
  108. qDebug() << "From file: enableShotLog" << settingsEnableShotLog;
  109. qDebug() << "From file: enableDebugMode" << settingsEnableDebugMode;
  110. qDebug() << "From file: sendDebugData" << settingsSendDebugData;
  111. qDebug() << "From file: sendFalseTrigger" << settingsSendFalseTrigger;
  112. settingsDiagnosticMode = savedData->value("ui/settingsDiagnosticMode", QVariant("DISABLED")).toString();
  113. if (settingsDiagnosticMode == "DISABLED")
  114. {
  115. ui.diagnosticDisabledRadio->setChecked(true);
  116. qDebug() << "Diagnostic mode is disabled";
  117. }
  118. else if (settingsDiagnosticMode == "ENABLED")
  119. {
  120. ui.diagnosticEnabledRadio->setChecked(true);
  121. qDebug() << "Diagnostic mode is enabled";
  122. }
  123. networkManager = new QNetworkAccessManager(this);
  124. connect(networkManager, SIGNAL(finished(QNetworkReply*)), this, SLOT(replyFinished(QNetworkReply*)), Qt::QueuedConnection);
  125. newAppMajor = MAIN_APPLICATION_VERSION_MAJOR;
  126. newAppMinor = MAIN_APPLICATION_VERSION_MINOR;
  127. newAppTail = MAIN_APPLICATION_VERSION_TAIL;
  128. scanningInProgress = 0;
  129. curClubType = "";
  130. curPlayerHand = "RH";
  131. curPlayerName = "DEFAULT_ADULT";
  132. settingsBallType = savedData->value("ui/settingsBallType", QVariant(tr("HARDBALL"))).toString();
  133. settingsKidMode = savedData->value("ui/settingsKidMode", QVariant(tr("DISABLE"))).toString();
  134. if (settingsBallType == "HARDBALL")
  135. ui.hardBallRadio->setChecked(true);
  136. else if (settingsBallType == "ALMOSTBALL")
  137. ui.almostBallRadio->setChecked(true);
  138. if (settingsKidMode == "ENABLE")
  139. ui.kidModeEnableRadio->setChecked(true);
  140. else if (settingsKidMode == "DISABLE")
  141. ui.kidModeDisableRadio->setChecked(true);
  142. ui.kidModeDisableRadio->setVisible(false);
  143. ui.kidModeEnableRadio->setVisible(false);
  144. deviceList = QList<QByteArray>();
  145. ui.deviceListSelectBox->hide();
  146. monitorGetLicenseRequire = new QTimer(this);
  147. //to fix font size to pixel instead of point
  148. QFont font1 = ui.dongleIdLabel->font();
  149. font1.setPixelSize(13);
  150. font1.setFamily("Arial");
  151. font1.setItalic(1);
  152. font1.setBold(1);
  153. ui.dongleIdLabel->setFont(font1);
  154. QFont font2 = ui.otherInfoLabel->font();
  155. font2.setPixelSize(13);
  156. font2.setFamily("Arial");
  157. font2.setItalic(1);
  158. font2.setBold(1);
  159. ui.otherInfoLabel->setFont(font2);
  160. otherInfoString = "";
  161. QFont font3 = ui.hardwareVersionLabel->font();
  162. font3.setPixelSize(13);
  163. font3.setFamily("Arial");
  164. font3.setItalic(1);
  165. font3.setBold(1);
  166. ui.hardwareVersionLabel->setFont(font3);
  167. QFont font10 = ui.firmwareVersionLabel->font();
  168. font10.setPixelSize(13);
  169. font10.setFamily("Arial");
  170. font10.setItalic(1);
  171. font10.setBold(1);
  172. ui.firmwareVersionLabel->setFont(font10);
  173. QFont font4 = ui.deviceIdLabel->font();
  174. font4.setPixelSize(13);
  175. font4.setFamily("Arial");
  176. font4.setItalic(1);
  177. font4.setBold(1);
  178. ui.deviceIdLabel->setFont(font4);
  179. QFont font5 = ui.applicationVersionLabel->font();
  180. font4.setPixelSize(13);
  181. font4.setFamily("Arial");
  182. font4.setItalic(1);
  183. font4.setBold(1);
  184. ui.applicationVersionLabel->setFont(font4);
  185. ui.applicationVersionLabel->setText(QString::number(MAIN_APPLICATION_VERSION_MAJOR) + "." + QString::number(MAIN_APPLICATION_VERSION_MINOR) +
  186. "." + QString::number(MAIN_APPLICATION_VERSION_TAIL));
  187. QFont font8 = ui.licensekeyText->font();
  188. font8.setPixelSize(11);
  189. font8.setFamily("Arial");
  190. ui.licensekeyText->setFont(font8);
  191. //init side panel window
  192. ui.dashboardPushButton->setFlat(true);
  193. ui.upgradePushbutton->setFlat(true);
  194. ui.helpPushbutton->setFlat(true);
  195. ui.aboutPushButton->setFlat(true);
  196. ui.clubsPushButton->setFlat(true);
  197. ui.settingsPushButton->setFlat(true);
  198. if (userLoginStatus > 0)
  199. {
  200. QPixmap tempPm(":/launchBoxSim/images/logoutButton.png");
  201. ui.loginButtonLabel->setPixmap(tempPm);
  202. ui.loginButtonLabel->show();
  203. ui.loginPushbutton->raise();
  204. }
  205. else
  206. {
  207. QPixmap tempPm(":/launchBoxSim/images/loginButton.png");
  208. ui.loginButtonLabel->setPixmap(tempPm);
  209. ui.loginButtonLabel->show();
  210. ui.loginPushbutton->raise();
  211. }
  212. ui.playGameButton->setDisabled(1);
  213. xmlObject = new xmlParser();
  214. if (gamePathString == QString(""))
  215. {
  216. game = new gameInterface(xmlObject->proteeDirectory, 0);
  217. }
  218. else
  219. {
  220. //system("runas /user:Administrator@domain \"taskkill /F /T /IM server.exe\"");
  221. //system("taskkill /F /T /IM server.exe /IM golf.exe > /dev/null 2>&1 &");
  222. QProcess::execute("taskkill /F /T /IM server.exe /IM golf.exe");
  223. game = new gameInterface(gamePathString, 0);
  224. }
  225. connect(this, SIGNAL(startPlayingGame()), game, SLOT(launchSimGame()), Qt::QueuedConnection);
  226. connect(this, SIGNAL(ui2GameAskForMachineID()), game, SLOT(askForMachineID()), Qt::QueuedConnection);
  227. connect(this, SIGNAL(ui2GameAskForPlayerInfo()), game, SLOT(askForPlayerInfo()), Qt::QueuedConnection);
  228. connect(this, SIGNAL(ui2GameRemoveLicense()), game, SLOT(removeLicense()), Qt::QueuedConnection);
  229. connect(this, SIGNAL(ui2GameConnectLicense(QString)), game, SLOT(connectLicense(QString)), Qt::QueuedConnection);
  230. connect(this, SIGNAL(ballFly2UI(QJsonObject)), game, SLOT(transmitData(QJsonObject)), Qt::QueuedConnection);
  231. connect(game, SIGNAL(gameServerScanStarted()), this, SLOT(scanForGameStatus()), Qt::QueuedConnection);
  232. connect(game, SIGNAL(gameStarted()), this, SLOT(game2UIReady()), Qt::QueuedConnection);
  233. connect(game, SIGNAL(gameFinished()), this, SLOT(game2UIFinished()), Qt::QueuedConnection);
  234. connect(game, SIGNAL(gameIncomingPlayerStatus(QJsonObject)), this, SLOT(game2UIPlayerInfo(QJsonObject)), Qt::QueuedConnection);
  235. connect(game, SIGNAL(gameMIDReady(QString)), this, SLOT(game2UIMachineIDReady(QString)), Qt::QueuedConnection);
  236. connect(game, SIGNAL(gameLicenseAccepted()), this, SLOT(game2UILicenseAccepted()), Qt::QueuedConnection);
  237. connect(game, SIGNAL(gameLicenseNotAccepted(QString)), this, SLOT(game2UILicenseNotAccepted(QString)), Qt::QueuedConnection);
  238. connect(game, SIGNAL(gameGameNotFound()), this, SLOT(game2UINotFound()), Qt::QueuedConnection);
  239. connect(game, SIGNAL(gameServerConnected()), this, SLOT(game2UIServerConnected()), Qt::QueuedConnection);
  240. box = new boxInterface(0);
  241. connect(box, SIGNAL(bleAppReady()), this, SLOT(uiBleAppReady()), Qt::QueuedConnection);
  242. connect(box, SIGNAL(dongleInserted()), this, SLOT(uiDongleInserted()), Qt::QueuedConnection);
  243. connect(box, SIGNAL(dongleRemoved()), this, SLOT(uiDongleRemoved()), Qt::QueuedConnection);
  244. connect(box, SIGNAL(rmotionConnected()), this, SLOT(uiRmotionConnected()), Qt::QueuedConnection);
  245. connect(box, SIGNAL(rmotionDisconnected()), this, SLOT(uiRmotionDisconnected()), Qt::QueuedConnection);
  246. connect(box, SIGNAL(rmotionInfoAvailable()), this, SLOT(uiRmotionInfoUpdate()), Qt::QueuedConnection);
  247. connect(box, SIGNAL(rmotionFwUpgradeSuccess()), this, SLOT(uiRmotionFwUpgradeSuccess()), Qt::QueuedConnection);//fw upgrade success
  248. connect(box, SIGNAL(rmotionFwUpgradeFailure()), this, SLOT(uiRmotionFwUpgradeFailure()), Qt::QueuedConnection);//fw upgrade fail
  249. connect(box, SIGNAL(rmotionFwUpgradeProgress(int)), this, SLOT(uiRmotionFwUpgradeProgress(int)), Qt::QueuedConnection);
  250. connect(box, SIGNAL(deviceListDevice(unsigned char *)), this, SLOT(uiDeviceListDevice(unsigned char *)), Qt::DirectConnection);
  251. connect(box, SIGNAL(deviceListEnd()), this, SLOT(uiDeviceListEnd()), Qt::QueuedConnection);
  252. connect(box, SIGNAL(unableToConnect()), this, SLOT(connectToDeviceTimeout()), Qt::QueuedConnection);
  253. connect(box, SIGNAL(shotDataAvailable()), this, SLOT(wrapLaunchData()), Qt::QueuedConnection);
  254. connect(this, SIGNAL(uiStartFWUpgrade()), box, SLOT(startFWUpgrade()), Qt::QueuedConnection);
  255. connect(this, SIGNAL(uiRestartDevice()), box, SLOT(restartDevice()), Qt::QueuedConnection);
  256. connect(this, SIGNAL(uiDisarmDevice()), box, SLOT(disarmDevice()), Qt::QueuedConnection);
  257. connect(this, SIGNAL(uiConnectDevice(unsigned char *)), box, SLOT(connectDevice(unsigned char *)), Qt::DirectConnection);
  258. connect(this, SIGNAL(uiStartScanning()), box, SLOT(startScanning()), Qt::QueuedConnection);
  259. connect(this, SIGNAL(uiChangePlayingMode(QString, QString, float, QString, QString, float, float, int)),
  260. box, SLOT(changePlayingMode(QString, QString, float, QString, QString, float, float, int)), Qt::QueuedConnection);
  261. connect(this, SIGNAL(uiChangeUserSettings(QString, QString, QString, QString, QString)),
  262. box, SLOT(changeUserSettings(QString, QString, QString, QString, QString)), Qt::QueuedConnection);
  263. if (game->gameStatus == GAMEDISCONNECTED)
  264. {
  265. scanForGameStatus();
  266. }
  267. if (userLicenseStatus == 0)
  268. {
  269. //ask for machine id
  270. emit ui2GameAskForMachineID();
  271. }
  272. curHelpSlide = 1;
  273. int notShowHelpStartUp = savedData->value("ui/notShowHelpStartUp", QVariant(0)).toInt();
  274. if (notShowHelpStartUp == 0)
  275. ui.notShowCheckBox->setCheckState(Qt::Unchecked);
  276. else
  277. ui.notShowCheckBox->setCheckState(Qt::Checked);
  278. if (notShowHelpStartUp == 0)
  279. {
  280. clickedOkHelp();
  281. ui.dashboardPushButton->setDisabled(1);
  282. ui.clubsPushButton->setDisabled(1);
  283. ui.settingsPushButton->setDisabled(1);
  284. ui.upgradePushbutton->setDisabled(1);
  285. ui.aboutPushButton->setDisabled(1);
  286. ui.helpPushbutton->setDisabled(1);
  287. }
  288. else if (userLoginStatus == 0)
  289. {
  290. clickedOkLogin();
  291. }
  292. else if (userLicenseStatus == 0)
  293. {
  294. goToLicenseRequest();
  295. }
  296. else
  297. {
  298. clickedOkDashBoard();
  299. }
  300. //to elevate and show window after splash screen
  301. QTimer::singleShot(2000, this, SLOT(elevateWindow()));
  302. // init player club info list
  303. initPlayerClubInfoList();
  304. for (QMap<QString, PlayerClubs>::const_iterator i = playerClubInfoList.constBegin(); i != playerClubInfoList.constEnd(); i++)
  305. {
  306. QString tmpStr = createPlayerClubInfoLine(i.key());
  307. qDebug() << tmpStr;
  308. }
  309. if (needToSavePlayerClubInfoList == true)
  310. savePlayerClubInfoList();
  311. // display DEFAULT club info
  312. ui.playerListSelectBox->addItem("DEFAULT_ADULT");
  313. ui.playerListSelectBox->addItem("DEFAULT_KID");
  314. for (QMap<QString, PlayerClubs>::const_iterator i = playerClubInfoList.constBegin(); i != playerClubInfoList.constEnd(); i++)
  315. if ((i.key() != "DEFAULT_ADULT") && (i.key() != "DEFAULT_KID"))
  316. ui.playerListSelectBox->addItem(i.key());
  317. selectedPlayerName = "DEFAULT_ADULT";
  318. selectedBaseInfo = "DEFAULT_ADULT";
  319. ui.playerListSelectBox->setCurrentIndex(0);
  320. displayPlayerClubInfo("DEFAULT_ADULT");
  321. ui.saveClubInfoButton->setDisabled(1);
  322. ui.playerListSelectBox->addItem("How To Add New Player And Manage Clubs ...");
  323. // check for new app available
  324. checkAppUpdate();
  325. // shot database
  326. shotDatabase = new ShotDatabase(0);
  327. shotSyncFunc(); // sync when app start
  328. // sync every 5 minutes
  329. QTimer *shotSyncTimer = new QTimer(this);
  330. connect(shotSyncTimer, SIGNAL(timeout()), this, SLOT(shotSyncFunc()));
  331. shotSyncTimer->start(300000); // every 5 minutes
  332. }
  333. launchBoxSim::~launchBoxSim()
  334. {
  335. delete game;
  336. delete box;
  337. delete savedData;
  338. }
  339. void launchBoxSim::uiLicenseUpdateIcon()
  340. {
  341. if (userLicenseStatus > 0)
  342. {
  343. QPixmap tmpPm(":/launchBoxSim/images/statusOK.png");
  344. ui.licenseStatusLabel->setPixmap(tmpPm);
  345. ui.licenseStatusLabel->show();
  346. }
  347. else
  348. {
  349. QPixmap tmpPm(":/launchBoxSim/images/statusNOK.png");
  350. ui.licenseStatusLabel->setPixmap(tmpPm);
  351. ui.licenseStatusLabel->show();
  352. }
  353. }
  354. //load login
  355. void launchBoxSim::clickedOkLogin()
  356. {
  357. // if user is already logged in, this means user wants to logout
  358. if (userLoginStatus > 0)
  359. {
  360. userLoginStatus = 0;
  361. savedData->setValue("ui/userLoginStatus", QVariant(userLoginStatus));
  362. QPixmap tempPm(":/launchBoxSim/images/loginButton.png");
  363. ui.loginButtonLabel->setPixmap(tempPm);
  364. ui.loginButtonLabel->show();
  365. ui.loginPushbutton->raise();
  366. }
  367. // if the timer to monitor license request requirement is running, stop it
  368. if ((monitorGetLicenseRequire != NULL) && (monitorGetLicenseRequire->isActive()))
  369. monitorGetLicenseRequire->stop();
  370. ui.stackedWidget->setCurrentIndex(3);
  371. QPixmap pixmap(":/launchBoxSim/images/loginSkeleton.png");
  372. this->setFixedSize(pixmap.width(), pixmap.height());
  373. QPalette palette;
  374. palette.setBrush(QPalette::Background, pixmap);
  375. this->setPalette(palette);
  376. ui.signinButton->setDisabled(1);
  377. ui.emailText->clear();
  378. ui.passwordText->clear();
  379. ui.loginErrorLabel->clear();
  380. ui.dashboardPushButton->setDisabled(1);
  381. ui.clubsPushButton->setDisabled(1);
  382. ui.settingsPushButton->setDisabled(1);
  383. ui.upgradePushbutton->setDisabled(1);
  384. ui.helpPushbutton->setDisabled(1);
  385. ui.aboutPushButton->setDisabled(1);
  386. }
  387. //load dash board
  388. void launchBoxSim::clickedOkDashBoard()
  389. {
  390. uiLicenseUpdateIcon();
  391. ui.stackedWidget->setCurrentIndex(0);
  392. QPixmap pixmap(":/launchBoxSim/images/dashboardSkeleton.png");
  393. this->setFixedSize(pixmap.width(), pixmap.height());
  394. QPalette palette;
  395. palette.setBrush(QPalette::Background, pixmap);
  396. this->setPalette(palette);
  397. ui.dashboardPushButton->setDisabled(0);
  398. ui.clubsPushButton->setDisabled(0);
  399. ui.settingsPushButton->setDisabled(0);
  400. ui.upgradePushbutton->setDisabled(0);
  401. ui.helpPushbutton->setDisabled(0);
  402. ui.aboutPushButton->setDisabled(0);
  403. ui.batteryStatusLabel->show();
  404. }
  405. void launchBoxSim::clickedOkUpgrade()
  406. {
  407. ui.stackedWidget->setCurrentIndex(1);
  408. QPixmap pixmap(":/launchBoxSim/images/upgradeSkeleton.png");
  409. this->setFixedSize(pixmap.width(), pixmap.height());
  410. QPalette palette;
  411. palette.setBrush(QPalette::Background, pixmap);
  412. this->setPalette(palette);
  413. ui.activateLicense->setDisabled(1);
  414. if (userLicenseStatus == 2)
  415. {
  416. ui.buyNow->setDisabled(1);
  417. ui.notInterested->setDisabled(1);
  418. ui.licensekeyText->setText(userFullLicenseText);
  419. ui.licensekeyText->setReadOnly(true);
  420. ui.activateLicense->setDisabled(1);
  421. QMessageBox msgBox;
  422. msgBox.setWindowTitle("R-Motion");
  423. msgBox.setText("Full TGC license is already activated.");
  424. msgBox.exec();
  425. }
  426. }
  427. //load help
  428. void launchBoxSim::clickedOkHelp()
  429. {
  430. curHelpSlide = 1;
  431. ui.stackedWidget->setCurrentIndex(2);
  432. QPixmap pixmap(":/launchBoxSim/images/helpSkeleton1.png");
  433. this->setFixedSize(pixmap.width(), pixmap.height());
  434. QPalette palette;
  435. palette.setBrush(QPalette::Background, pixmap);
  436. this->setPalette(palette);
  437. ui.prevSlideButton->setDisabled(1);
  438. ui.nextSlideButton->setStyleSheet("QPushButton{border-image: url(:/launchBoxSim/images/nextButton.png); outline: none; }");
  439. }
  440. //load about
  441. void launchBoxSim::clickedOkAbout()
  442. {
  443. ui.stackedWidget->setCurrentIndex(7);
  444. QPixmap pixmap(":/launchBoxSim/images/aboutSkeleton.png");
  445. this->setFixedSize(pixmap.width(), pixmap.height());
  446. QPalette palette;
  447. palette.setBrush(QPalette::Background, pixmap);
  448. this->setPalette(palette);
  449. }
  450. void launchBoxSim::clickedOkSettings()
  451. {
  452. ui.stackedWidget->setCurrentIndex(9);
  453. QPixmap pixmap(":/launchBoxSim/images/settingsSkeleton.png");
  454. this->setFixedSize(pixmap.width(), pixmap.height());
  455. QPalette palette;
  456. palette.setBrush(QPalette::Background, pixmap);
  457. this->setPalette(palette);
  458. }
  459. void launchBoxSim::clickedOkClubs()
  460. {
  461. ui.stackedWidget->setCurrentIndex(8);
  462. QPixmap pixmap(":/launchBoxSim/images/clubsSkeleton.png");
  463. this->setFixedSize(pixmap.width(), pixmap.height());
  464. QPalette palette;
  465. palette.setBrush(QPalette::Background, pixmap);
  466. this->setPalette(palette);
  467. ui.clubLengthExplanation->setVisible(false);
  468. needToSavePlayerClubInfoList = false;
  469. displayPlayerClubInfo(selectedPlayerName);
  470. ui.saveClubInfoButton->setDisabled(1);
  471. }
  472. //start TGC game
  473. void launchBoxSim::clickedPlayGame()
  474. {
  475. emit startPlayingGame();
  476. }
  477. void launchBoxSim::clickedActivateButton()
  478. {
  479. userFullLicenseText = ui.licensekeyText->toPlainText();
  480. licenseNewState = LICENSE_SM_ACTIVATE_FULL;
  481. emit ui2GameConnectLicense(userFullLicenseText);
  482. }
  483. void launchBoxSim::uiBleAppReady()
  484. {
  485. qDebug() << "BLE APP ready, send user settings now";
  486. if (settingsDiagnosticMode == "DISABLED")
  487. emit uiChangeUserSettings(settingsDisableAutoStandby, "OFF", "OFF", "OFF", "OFF");
  488. else if (settingsDiagnosticMode == "ENABLED")
  489. emit uiChangeUserSettings(settingsDisableAutoStandby, settingsEnableShotLog, settingsEnableDebugMode,
  490. settingsSendDebugData, settingsSendFalseTrigger);
  491. }
  492. void launchBoxSim::uiDongleInserted()
  493. {
  494. qDebug() << "Dongle is inserted";
  495. QPixmap dongleStatusOkPm(":/launchBoxSim/images/statusOK.png");
  496. ui.dongleStatusLabel->setPixmap(dongleStatusOkPm);
  497. ui.dongleStatusLabel->show();
  498. uiDongleIdUpdate();
  499. if ((userLoginStatus > 0) && (userLicenseStatus > 0))
  500. {
  501. scanForRmotion();
  502. scanForGameStatus();
  503. }
  504. }
  505. void launchBoxSim::uiDongleRemoved()
  506. {
  507. qDebug() << "Dongle is removed";
  508. QPixmap dongleStatusNokPm(":/launchBoxSim/images/statusNOK.png");
  509. ui.dongleStatusLabel->setPixmap(dongleStatusNokPm);
  510. ui.dongleStatusLabel->show();
  511. uiDongleIdUpdate();
  512. // when the dongle is removed, BLE is also disconnected
  513. box->bleConnectionStatus = 0;
  514. ui.batteryStatusLabel->hide();
  515. QPixmap deviceStatusNokPm(":/launchBoxSim/images/statusNOK.png");
  516. ui.deviceStatusLabel->setPixmap(deviceStatusNokPm);
  517. ui.deviceStatusLabel->show();
  518. // when the dongle is removed, Game Status is also disconnected
  519. QPixmap gameStatusNokPm(":/launchBoxSim/images/statusNOK.png");
  520. ui.gameServerStatusLabel->setPixmap(gameStatusNokPm);
  521. ui.gameServerStatusLabel->show();
  522. uiRmotionIdUpdate();
  523. ui.hardwareVersionLabel->setText("No data. Connect R-Motion first.");
  524. ui.firmwareVersionLabel->setText("No data. Connect R-Motion first.");
  525. otherInfoString = "No data. Connect R-Motion first.";
  526. QString displayStr(otherInfoString);
  527. if (curClubType != "")
  528. displayStr += " Club " + curClubType;
  529. else
  530. displayStr += " Club N/A";
  531. ui.otherInfoLabel->setText(displayStr);
  532. scanningInProgress = 0;
  533. }
  534. void launchBoxSim::uiDongleIdUpdate()
  535. {
  536. if (box->dongleStatus == 0)
  537. {
  538. ui.dongleIdLabel->setText("No data. Insert dongle first.");
  539. }
  540. else
  541. {
  542. qDebug() << "DongleID is received";
  543. QString tempString;
  544. tempString.sprintf("%02X %02X %02X %02X %02X %02X", box->dongleId[5], box->dongleId[4], box->dongleId[3], box->dongleId[2], box->dongleId[1], box->dongleId[0]);
  545. if (dongleIdText != tempString)
  546. {
  547. dongleIdText = tempString;
  548. savedData->setValue("ui/dongleIdText", QVariant(dongleIdText));
  549. }
  550. ui.dongleIdLabel->setText(tempString);
  551. }
  552. }
  553. void launchBoxSim::uiRmotionConnected()
  554. {
  555. qDebug() << "Rmotion is connected";
  556. QPixmap deviceStatusOkPm(":/launchBoxSim/images/statusOK.png");
  557. ui.deviceStatusLabel->setPixmap(deviceStatusOkPm);
  558. ui.deviceStatusLabel->show();
  559. uiRmotionIdUpdate();
  560. // resend the clubType to the device if it was disconnected before
  561. if ((curPlayerName != "") && (curClubType != ""))
  562. {
  563. ClubInfo clubInfo = getPlayerClubInfo(curPlayerName, curClubType);
  564. emit uiChangePlayingMode(curPlayerHand, curClubType, 1.0f, settingsBallType, settingsKidMode,
  565. clubInfo.clubLength, clubInfo.clubLoft, clubInfo.isHybrid);
  566. }
  567. else if (game->gameStatus == GAMECONNECTED)
  568. {
  569. emit ui2GameAskForPlayerInfo();
  570. }
  571. scanningInProgress = 0;
  572. }
  573. void launchBoxSim::uiRmotionDisconnected()
  574. {
  575. qDebug() << "Rmotion is disconnected";
  576. QPixmap deviceStatusNokPm(":/launchBoxSim/images/statusNOK.png");
  577. ui.deviceStatusLabel->setPixmap(deviceStatusNokPm);
  578. ui.deviceStatusLabel->show();
  579. QPixmap gameStatusNokPm(":/launchBoxSim/images/statusNOK.png");
  580. ui.gameServerStatusLabel->setPixmap(gameStatusNokPm);
  581. ui.gameServerStatusLabel->show();
  582. uiRmotionIdUpdate();
  583. ui.hardwareVersionLabel->setText("No data. Connect R-Motion first.");
  584. ui.firmwareVersionLabel->setText("No data. Connect R-Motion first.");
  585. otherInfoString = "No data. Connect R-Motion first.";
  586. QString displayStr(otherInfoString);
  587. if (curClubType != "")
  588. displayStr += " Club " + curClubType;
  589. else
  590. displayStr += " Club N/A";
  591. ui.otherInfoLabel->setText(displayStr);
  592. ui.batteryStatusLabel->hide();
  593. scanForRmotion();
  594. scanForGameStatus();
  595. }
  596. void launchBoxSim::uiRmotionIdUpdate()
  597. {
  598. if (box->bleConnectionStatus == 0)
  599. {
  600. ui.deviceIdLabel->setText("No data. Connect R-Motion first.");
  601. }
  602. else
  603. {
  604. QString tempString;
  605. tempString.sprintf("%02X %02X %02X %02X %02X %02X", box->deviceId[0], box->deviceId[1], box->deviceId[2], box->deviceId[3], box->deviceId[4], box->deviceId[5]);
  606. ui.deviceIdLabel->setText(tempString);
  607. qDebug() << "RmotionID is received " << tempString;
  608. }
  609. }
  610. void launchBoxSim::uiRmotionInfoUpdate()
  611. {
  612. QString hwVerString;
  613. hwVerString.sprintf("%d.%d.%d", HW_VERSION_MAJOR, HW_VERSION_MINOR, HW_VERSION_TAIL);
  614. ui.hardwareVersionLabel->setText(hwVerString);
  615. QString fwVerString;
  616. fwVerString.sprintf("%d.%d.%d", box->fwVerMajor, box->fwVerMinor, box->fwVerTail);
  617. ui.firmwareVersionLabel->setText(fwVerString);
  618. otherInfoString.sprintf("State %d Accx %d Accy %d Accz %d Battery %.1lf Voltage %.2lf",
  619. box->deviceStateMachine, box->accxValue, box->accyValue, box->acczValue, box->curBatteryLevel, box->curVoltageLevel);
  620. QString displayStr(otherInfoString);
  621. if (curClubType != "")
  622. displayStr += " Club " + curClubType;
  623. else
  624. displayStr += " Club N/A";
  625. ui.otherInfoLabel->setText(displayStr);
  626. qDebug() << "DeviceInfo is received " << hwVerString << " " << fwVerString << " " << otherInfoString;
  627. if (box->curBatteryLevel >= 75)
  628. {
  629. QPixmap tmpPm(":/launchBoxSim/images/battery_4.png");
  630. ui.batteryStatusLabel->setPixmap(tmpPm.scaled(ui.batteryStatusLabel->width(), ui.batteryStatusLabel->height(), Qt::KeepAspectRatio));
  631. ui.batteryStatusLabel->show();
  632. }
  633. else if (box->curBatteryLevel >= 50)
  634. {
  635. QPixmap tmpPm(":/launchBoxSim/images/battery_3.png");
  636. ui.batteryStatusLabel->setPixmap(tmpPm.scaled(ui.batteryStatusLabel->width(), ui.batteryStatusLabel->height(), Qt::KeepAspectRatio));
  637. ui.batteryStatusLabel->show();
  638. }
  639. else if (box->curBatteryLevel >= 25)
  640. {
  641. QPixmap tmpPm(":/launchBoxSim/images/battery_2.png");
  642. ui.batteryStatusLabel->setPixmap(tmpPm.scaled(ui.batteryStatusLabel->width(), ui.batteryStatusLabel->height(), Qt::KeepAspectRatio));
  643. ui.batteryStatusLabel->show();
  644. }
  645. else
  646. {
  647. QPixmap tmpPm(":/launchBoxSim/images/battery_1.png");
  648. ui.batteryStatusLabel->setPixmap(tmpPm.scaled(ui.batteryStatusLabel->width(), ui.batteryStatusLabel->height(), Qt::KeepAspectRatio));
  649. ui.batteryStatusLabel->show();
  650. }
  651. qDebug() << "Current battery level: " << box->curBatteryLevel << " Current voltage level: " << box->curVoltageLevel << " Is device charging? " << box->isDeviceCharging;
  652. if (ui.stackedWidget->currentIndex() == 0)
  653. {
  654. if (((box->fwVerMajor < FW_VERSION_MAJOR) || ((box->fwVerMajor == FW_VERSION_MAJOR) && (box->fwVerMinor < FW_VERSION_MINOR)) ||
  655. ((box->fwVerMajor == FW_VERSION_MAJOR) && (box->fwVerMinor == FW_VERSION_MINOR) && (box->fwVerTail < FW_VERSION_TAIL)))
  656. &&
  657. (box->fwVerMajor >= 1)) // only update official FW (version 1.0.0 onward)
  658. {
  659. goToFwWaitCharging();
  660. // wait until Rmotion device is charging or voltage level is high enough
  661. QTimer::singleShot(1000, this, SLOT(waitRmotionCharging()));
  662. }
  663. }
  664. }
  665. void launchBoxSim::uiRmotionFwUpgradeSuccess()
  666. {
  667. qDebug() << "Firmware Upgrade Completed";
  668. ui.fwUpgradeLabel->setText("Firmware Upgrade Completed");
  669. ui.fwUpgradeLabel->show();
  670. QTimer::singleShot(2000, this, SLOT(clickedOkDashBoard()));
  671. }
  672. void launchBoxSim::uiRmotionFwUpgradeFailure()
  673. {
  674. qDebug() << "Fimrware Upgrade Failed";
  675. ui.fwUpgradeLabel->setText("Firmware Upgrade Failed");
  676. ui.fwUpgradeLabel->show();
  677. QTimer::singleShot(2000, this, SLOT(clickedOkDashBoard()));
  678. }
  679. void launchBoxSim::uiRmotionFwUpgradeProgress(int percentage)
  680. {
  681. qDebug() << "Firmware Upgrade percentage: " << percentage;
  682. ui.fwUpgradeLabel->setText("Firmware Upgrading " + QString::number(percentage) + "%");
  683. ui.fwUpgradeLabel->show();
  684. }
  685. void launchBoxSim::game2UINotFound()
  686. {
  687. ui.otherInfoLabel->setText("Game not found");
  688. QPalette palette = ui.otherInfoLabel->palette();
  689. palette.setColor(QPalette::WindowText, QColor("Red"));
  690. ui.otherInfoLabel->setPalette(palette);
  691. }
  692. void launchBoxSim::game2UIReady()
  693. {
  694. ui.playGameButton->setDisabled(1);
  695. }
  696. void launchBoxSim::game2UIFinished()
  697. {
  698. if (game->gameStatus == GAMEDISCONNECTED)
  699. {
  700. if ((box->dongleStatus == 1) && (box->bleConnectionStatus == 1))
  701. {
  702. QPixmap gameStatusOkPm(":/launchBoxSim/images/statusOK.png");
  703. ui.gameServerStatusLabel->setPixmap(gameStatusOkPm);
  704. ui.gameServerStatusLabel->show();
  705. ui.playGameButton->setDisabled(0);
  706. qDebug() << "play button is enabled";
  707. }
  708. else
  709. {
  710. ui.playGameButton->setDisabled(1);
  711. qDebug() << "play button is disabled";
  712. }
  713. }
  714. // disarm R-Motion device if connected
  715. if (box->bleConnectionStatus == 1)
  716. emit uiDisarmDevice();
  717. }
  718. void launchBoxSim::game2UIPlayerInfo(QJsonObject object)
  719. {
  720. try {
  721. //read jSon
  722. QString playerName = object["playerName"].toString();
  723. QString courseName = object["courseName"].toString();
  724. QString tourName = object["tourName"].toString();
  725. QString playerClub = object["playerClub"].toString();
  726. QString playerHand = object["playerHand"].toString();
  727. QString playerDistanceToFlag = object["playerDistanceToFlag"].toString();
  728. QString playerSurface = object["playerSurface"].toString();
  729. qDebug() << "Parsing Json " << playerName << " " << playerClub << " " << playerHand << " " << playerDistanceToFlag;
  730. curPlayerName = playerName;
  731. curPlayerHand = playerHand;
  732. curClubType = playerClub;
  733. if (!playerClubInfoList.contains(curPlayerName))
  734. {
  735. addNewPlayerToClubInfoList(curPlayerName);
  736. needToSavePlayerClubInfoList = true;
  737. }
  738. ClubInfo clubInfo = getPlayerClubInfo(curPlayerName, curClubType);
  739. if (box->bleConnectionStatus == 1)
  740. {
  741. qDebug() << "ARM command: " << curPlayerHand << " " << curClubType << " " << settingsBallType << " "
  742. << QString::number(clubInfo.clubLength) << " " << QString::number(clubInfo.clubLoft);
  743. emit uiChangePlayingMode(curPlayerHand, curClubType, playerDistanceToFlag.toFloat(), settingsBallType, settingsKidMode,
  744. clubInfo.clubLength, clubInfo.clubLoft, clubInfo.isHybrid);
  745. }
  746. else
  747. {
  748. qDebug() << "Received player info from game but device is disconnected";
  749. }
  750. if (needToSavePlayerClubInfoList == true)
  751. savePlayerClubInfoList();
  752. // display new selected club type on other information label
  753. QString displayStr(otherInfoString);
  754. if (curClubType != "")
  755. displayStr += " Club " + curClubType;
  756. else
  757. displayStr += " Club N/A";
  758. ui.otherInfoLabel->setText(displayStr);
  759. }
  760. catch(QException qe){
  761. qDebug() << "Parsing JSON exception";
  762. }
  763. }
  764. void launchBoxSim::game2UIMachineIDReady(QString MID)
  765. {
  766. machineIdText = MID;
  767. savedData->setValue("ui/machineIdText", QVariant(machineIdText));
  768. qDebug() << machineIdText;
  769. }
  770. void launchBoxSim::game2UILicenseAccepted()
  771. {
  772. // full license is activating
  773. if (licenseNewState == LICENSE_SM_ACTIVATE_FULL)
  774. {
  775. qDebug() << "Full license activated OK";
  776. licenseNewState = LICENSE_SM_MIN;
  777. licenseCurState = LICENSE_SM_FULL_VALID;
  778. userLicenseStatus = 2;
  779. savedData->setValue("ui/userLicenseStatus", QVariant(userLicenseStatus));
  780. savedData->setValue("ui/userFullLicenseText", QVariant(userFullLicenseText));
  781. ui.buyNow->setDisabled(1);
  782. ui.notInterested->setDisabled(1);
  783. ui.licensekeyText->setText(userFullLicenseText);
  784. ui.licensekeyText->setReadOnly(true);
  785. ui.activateLicense->setDisabled(1);
  786. QMessageBox msgBox;
  787. msgBox.setWindowTitle("R-Motion");
  788. msgBox.setText("Full License Activation Successful.");
  789. msgBox.exec();
  790. return;
  791. }
  792. // free license is activating
  793. else if (licenseNewState == LICENSE_SM_ACTIVATE_FREE)
  794. {
  795. qDebug() << "Free license activated OK";
  796. freeLicenseRequesting = 0;
  797. licenseNewState = LICENSE_SM_MIN;
  798. licenseCurState = LICENSE_SM_FREE_VALID;
  799. userLicenseStatus = 1;
  800. savedData->setValue("ui/userLicenseStatus", QVariant(userLicenseStatus));
  801. savedData->setValue("ui/userLicenseText", QVariant(userLicenseText));
  802. QPixmap tmpPm(":/launchBoxSim/images/getLicenseLabelOk.png");
  803. ui.getLicenseLabel->setPixmap(tmpPm);
  804. ui.getLicenseLabel->show();
  805. ui.getLicenseButton->raise();
  806. ui.dashboardPushButton->setDisabled(0);
  807. ui.clubsPushButton->setDisabled(0);
  808. ui.settingsPushButton->setDisabled(0);
  809. ui.upgradePushbutton->setDisabled(0);
  810. ui.aboutPushButton->setDisabled(0);
  811. ui.helpPushbutton->setDisabled(0);
  812. return;
  813. }
  814. // free license is being verified
  815. else if (licenseNewState == LICENSE_SM_VERIFY_FREE)
  816. {
  817. qDebug() << "Free license verified OK";
  818. licenseNewState = LICENSE_SM_MIN;
  819. licenseCurState = LICENSE_SM_FREE_VALID;
  820. triedFreeLicense = 0;
  821. return;
  822. }
  823. // full license is being verified
  824. else if (licenseNewState == LICENSE_SM_VERIFY_FULL)
  825. {
  826. qDebug() << "Full license verified OK";
  827. licenseNewState = LICENSE_SM_MIN;
  828. licenseCurState = LICENSE_SM_FULL_VALID;
  829. triedFullLicense = 0;
  830. return;
  831. }
  832. }
  833. void launchBoxSim::game2UILicenseNotAccepted(QString tgcErrorMsg)
  834. {
  835. if (licenseNewState == LICENSE_SM_ACTIVATE_FULL) // full license entered is invalid
  836. {
  837. qDebug() << "Full license activated NOK";
  838. licenseNewState = LICENSE_SM_MIN;
  839. userFullLicenseText = QString("");
  840. QMessageBox msgBox;
  841. msgBox.setWindowTitle("R-Motion");
  842. msgBox.setText("The TGC License entered is rejected with error: " + tgcErrorMsg);
  843. msgBox.setInformativeText("Please contact Protee Support. Meanwhile, you can continue using the free license.");
  844. msgBox.exec();
  845. return;
  846. }
  847. else if (licenseNewState == LICENSE_SM_ACTIVATE_FREE) // free license request failed
  848. {
  849. qDebug() << "Free license activated NOK";
  850. licenseNewState = LICENSE_SM_MIN;
  851. userLicenseText = QString("");
  852. QMessageBox msgBox;
  853. msgBox.setWindowTitle("R-Motion");
  854. msgBox.setText("New Free License is rejected with error: " + tgcErrorMsg);
  855. msgBox.setInformativeText("Please try again or contact R-Motion support.");
  856. int tempRet = msgBox.exec();
  857. freeLicenseRequesting = 0;
  858. goToLicenseRequest();
  859. return;
  860. }
  861. else if (licenseNewState == LICENSE_SM_VERIFY_FREE) // free license verified NOK
  862. {
  863. qDebug() << "Free license verified NOK";
  864. licenseNewState = LICENSE_SM_MIN;
  865. if (triedFreeLicense < 2)
  866. {
  867. triedFreeLicense++;
  868. licenseNewState = LICENSE_SM_VERIFY_FREE;
  869. emit ui2GameConnectLicense(userLicenseText);
  870. }
  871. else
  872. {
  873. triedFreeLicense = 0;
  874. userLicenseStatus = 0;
  875. savedData->setValue("ui/userLicenseStatus", QVariant(userLicenseStatus));
  876. QMessageBox msgBox;
  877. msgBox.setWindowTitle("R-Motion");
  878. msgBox.setText("Existing TGC Free License is rejected with error: " + tgcErrorMsg);
  879. msgBox.setInformativeText("Click Cancel to go to License Upgrade to activate your existing full license.\n\n"
  880. "Or click OK to request new free license before playing.");
  881. msgBox.setStandardButtons(QMessageBox::Cancel | QMessageBox::Ok);
  882. int tempRet = msgBox.exec();
  883. if (tempRet == QMessageBox::Ok)
  884. {
  885. freeLicenseRequesting = 0;
  886. goToLicenseRequest();
  887. }
  888. else if (tempRet == QMessageBox::Cancel)
  889. {
  890. clickedOkUpgrade();
  891. }
  892. }
  893. return;
  894. }
  895. else if (licenseNewState == LICENSE_SM_VERIFY_FULL) // full license verified NOK
  896. {
  897. qDebug() << "Full license verified NOK";
  898. licenseNewState = LICENSE_SM_MIN;
  899. if (triedFullLicense < 2)
  900. {
  901. triedFullLicense++;
  902. licenseNewState = LICENSE_SM_VERIFY_FULL;
  903. emit ui2GameConnectLicense(userFullLicenseText);
  904. }
  905. else
  906. {
  907. triedFullLicense = 0;
  908. QMessageBox msgBox;
  909. msgBox.setWindowTitle("R-Motion");
  910. msgBox.setText("Existing TGC Full License is rejected with error: " + tgcErrorMsg);
  911. msgBox.setInformativeText("Please contact Protee Support. Meanwhile, you can continue using the free license.");
  912. msgBox.exec();
  913. userLicenseStatus = 1;
  914. savedData->setValue("ui/userLicenseStatus", QVariant(userLicenseStatus));
  915. licenseNewState = LICENSE_SM_VERIFY_FREE;
  916. emit ui2GameConnectLicense(userLicenseText); // check the free license
  917. }
  918. return;
  919. }
  920. }
  921. void launchBoxSim::elevateWindow()
  922. {
  923. this->activateWindow();
  924. }
  925. void launchBoxSim::clickSigninButton()
  926. {
  927. QString userEmail = ui.emailText->text();
  928. QString userPassword = ui.passwordText->text();
  929. QString urlString = "http://rmotion.rapsodo.com/api/auth/login?username=" + userEmail + "&password=" + userPassword;
  930. QNetworkRequest loginRequest;
  931. loginRequest.setUrl(QUrl(urlString));
  932. loginRequest.setAttribute(QNetworkRequest::User, QVariant("loginRequest"));
  933. networkManager->get(loginRequest);
  934. }
  935. void launchBoxSim::clickBuyNowButton()
  936. {
  937. QString urlString = "http://rmotion.rapsodo.com/api/fullName?username=" + userEmail;
  938. QNetworkRequest getNameInfoRequest;
  939. getNameInfoRequest.setUrl(QUrl(urlString));
  940. getNameInfoRequest.setAttribute(QNetworkRequest::User, QVariant("getNameInfoRequest"));
  941. networkManager->get(getNameInfoRequest);
  942. }
  943. void launchBoxSim::clickNotInterestedButton()
  944. {
  945. ui.licensekeyText->clear();
  946. clickedOkDashBoard();
  947. }
  948. void launchBoxSim::replyFinished(QNetworkReply *networkReply)
  949. {
  950. QString requestAttribute = networkReply->request().attribute(QNetworkRequest::User).toString();
  951. if (requestAttribute.contains("loginRequest")) // login response
  952. {
  953. if (networkReply->error())
  954. {
  955. qDebug() << "Login Error: " << networkReply->errorString();
  956. QMessageBox msgBox;
  957. msgBox.setWindowTitle("R-Motion");
  958. msgBox.setText("Unable to connect to R-Motion server.");
  959. msgBox.setInformativeText("Please try again or contact R-Motion support.");
  960. msgBox.exec();
  961. }
  962. else
  963. {
  964. QByteArray responseData = networkReply->readAll();
  965. qDebug() << networkReply->header(QNetworkRequest::ContentTypeHeader).toString();
  966. qDebug() << networkReply->header(QNetworkRequest::LastModifiedHeader).toDateTime().toString();
  967. qDebug() << networkReply->header(QNetworkRequest::ContentLengthHeader).toULongLong();
  968. qDebug() << responseData;
  969. QList<QByteArray> responses = responseData.split('\n');
  970. if (responses[0].contains("ok"))
  971. {
  972. // update LOGIN button to LOGOUT
  973. QPixmap tempPm(":/launchBoxSim/images/logoutButton.png");
  974. ui.loginButtonLabel->setPixmap(tempPm);
  975. ui.loginButtonLabel->show();
  976. ui.loginPushbutton->raise();
  977. // update login status
  978. userLoginStatus = 1;
  979. savedData->setValue("ui/userLoginStatus", QVariant(userLoginStatus));
  980. userEmail = ui.emailText->text();
  981. savedData->setValue("ui/userEmail", QVariant(userEmail));
  982. // depends on the license status, we should go to the dashboard or the license request page
  983. if (userLicenseStatus == 0)
  984. goToLicenseRequest();
  985. else
  986. {
  987. clickedOkDashBoard();
  988. scanForRmotion();
  989. }
  990. }
  991. else if (responses[0].contains("wrong"))
  992. {
  993. ui.loginErrorLabel->setText("Invalid username/password");
  994. }
  995. }
  996. }
  997. else if (requestAttribute.contains("freeLicenseRequest")) // free license response
  998. {
  999. if (networkReply->error())
  1000. {
  1001. qDebug() << "Free License Request Error: " << networkReply->errorString();
  1002. QMessageBox msgBox;
  1003. msgBox.setWindowTitle("R-Motion");
  1004. msgBox.setText("Unable to connect to R-Motion server.");
  1005. msgBox.setInformativeText("Please try again or contact R-Motion support.");
  1006. msgBox.exec();
  1007. freeLicenseRequesting = 0;
  1008. goToLicenseRequest();
  1009. }
  1010. else
  1011. {
  1012. QByteArray responseData = networkReply->readAll();
  1013. qDebug() << responseData;
  1014. if (responseData.contains("ERROR "))
  1015. {
  1016. QMessageBox msgBox;
  1017. msgBox.setWindowTitle("R-Motion");
  1018. msgBox.setText("Free license request failed with " + responseData);
  1019. msgBox.setInformativeText("Please try again or contact R-Motion support.");
  1020. msgBox.exec();
  1021. freeLicenseRequesting = 0;
  1022. goToLicenseRequest();
  1023. }
  1024. else
  1025. {
  1026. userLicenseText = responseData;
  1027. licenseNewState = LICENSE_SM_ACTIVATE_FREE;
  1028. emit ui2GameConnectLicense(userLicenseText);
  1029. }
  1030. }
  1031. }
  1032. else if (requestAttribute.contains("checkAppUpdate")) // check app update response
  1033. {
  1034. if (!networkReply->error())
  1035. {
  1036. QByteArray responseData = networkReply->readAll();
  1037. qDebug() << responseData;
  1038. responseData.replace("\r\n", "\n");
  1039. QList<QByteArray> responses = responseData.split('\n');
  1040. if (responses.count() != 2)
  1041. return;
  1042. QList<QByteArray> version = responses[0].split('.');
  1043. if (version.count() != 3)
  1044. return;
  1045. newAppMajor = version[0].toInt();
  1046. newAppMinor = version[1].toInt();
  1047. newAppTail = version[2].toInt();
  1048. if ((newAppMajor > MAIN_APPLICATION_VERSION_MAJOR) || ((newAppMajor == MAIN_APPLICATION_VERSION_MAJOR) && (newAppMinor > MAIN_APPLICATION_VERSION_MINOR)) ||
  1049. ((newAppMajor == MAIN_APPLICATION_VERSION_MAJOR) && (newAppMinor == MAIN_APPLICATION_VERSION_MINOR) && (newAppTail > MAIN_APPLICATION_VERSION_TAIL)))
  1050. {
  1051. appHashValue = responses[1];
  1052. bool shouldDownloadNewInstaller = false;
  1053. // check if we have already downloaded the new installer and some permission sanity check
  1054. QString ourDownloadPath = ourPathString + "tmpdwnld\\";
  1055. QString newAppFilename = ourDownloadPath + "R-Motion_v" + QString::number(newAppMajor) + "." +
  1056. QString::number(newAppMinor) + "." + QString::number(newAppTail) + ".exe";
  1057. QFile installerFile(newAppFilename);
  1058. if (installerFile.exists())
  1059. {
  1060. if (installerFile.open(QFile::ReadWrite | QFile::Truncate))
  1061. {
  1062. // verify the integrity of the existed installer
  1063. QByteArray existedInstallerData = installerFile.readAll();
  1064. installerFile.close();
  1065. QCryptographicHash hash(QCryptographicHash::Sha256);
  1066. hash.addData(existedInstallerData);
  1067. QByteArray hashResult = hash.result().toHex();
  1068. qDebug() << "SHA256 hash of existed installer:" << hashResult;
  1069. if (hashResult == appHashValue)
  1070. {
  1071. qDebug() << "Existed installer SHA matched expected SHA, no need to download";
  1072. shouldDownloadNewInstaller = false;
  1073. // inform user about the new application version
  1074. QMessageBox tmpBox;
  1075. tmpBox.setWindowTitle("R-Motion");
  1076. tmpBox.setText("New R-Motion application version v" + QString::number(newAppMajor) + "." + QString::number(newAppMinor) + "." + QString::number(newAppTail) +
  1077. " is available.\nPlease remember to close the application before running the installer.");
  1078. tmpBox.setInformativeText("Do you want to go to the installer now?");
  1079. tmpBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
  1080. int ret = tmpBox.exec();
  1081. if (ret == QMessageBox::Yes)
  1082. {
  1083. ourDownloadPath.replace("\\", "/");
  1084. QString urlToTmpDownload = "file:///" + ourDownloadPath;
  1085. qDebug() << "Opening the file url: " << urlToTmpDownload;
  1086. QDesktopServices::openUrl(QUrl(urlToTmpDownload, QUrl::TolerantMode));
  1087. }
  1088. }
  1089. else
  1090. {
  1091. qDebug() << "Existed installer SHA not matched expected SHA, remove and download";
  1092. installerFile.remove();
  1093. shouldDownloadNewInstaller = true;
  1094. }
  1095. }
  1096. else
  1097. {
  1098. qDebug() << "Some permission issue with the existed installer file";
  1099. qDebug() << "We assume there is some permission issue with the folder, so we will not do anything";
  1100. shouldDownloadNewInstaller = false;
  1101. }
  1102. }
  1103. else
  1104. shouldDownloadNewInstaller = true;
  1105. // download new version of app from server
  1106. if (shouldDownloadNewInstaller == true)
  1107. {
  1108. qDebug() << "Download new app version from server";
  1109. QString downloadString = "http://rmotion.rapsodo.com/download/R-Motion.exe";
  1110. QNetworkRequest downloadNewAppRequest;
  1111. downloadNewAppRequest.setUrl(QUrl(downloadString));
  1112. downloadNewAppRequest.setAttribute(QNetworkRequest::User, QVariant("downloadNewApp"));
  1113. QNetworkReply *tmpReply = networkManager->get(downloadNewAppRequest);
  1114. connect(tmpReply, SIGNAL(downloadProgress(qint64, qint64)), this, SLOT(updateAppDownloadProgress(qint64, qint64)), Qt::QueuedConnection);
  1115. }
  1116. }
  1117. }
  1118. }
  1119. else if (requestAttribute.contains("downloadNewApp")) // download new app
  1120. {
  1121. if (networkReply->error())
  1122. {
  1123. qDebug() << "Error downloading new version of application" << networkReply->errorString();
  1124. }
  1125. else
  1126. {
  1127. QByteArray downloadData = networkReply->readAll();
  1128. // compare checksum
  1129. QCryptographicHash hash(QCryptographicHash::Sha256);
  1130. hash.addData(downloadData);
  1131. QByteArray hashResult = hash.result().toHex();
  1132. qDebug() << "SHA256 hash of downloaded data:" << hashResult;
  1133. if (hashResult == appHashValue)
  1134. {
  1135. qDebug() << "SHA256 hash of downloaded data matched expected SHA";
  1136. // write file to disk
  1137. QString ourDownloadPath = ourPathString + "tmpdwnld\\";
  1138. QString newAppFilename = ourDownloadPath + "R-Motion_v" + QString::number(newAppMajor) + "." +
  1139. QString::number(newAppMinor) + "." + QString::number(newAppTail) + ".exe";
  1140. QFile installerFile(newAppFilename);
  1141. if (installerFile.open(QFile::ReadWrite | QFile::Truncate))
  1142. {
  1143. installerFile.write(downloadData);
  1144. installerFile.flush();
  1145. installerFile.close();
  1146. qDebug() << "New app installer" << newAppFilename << "is saved on disk";
  1147. // inform user about the new application version
  1148. QMessageBox tmpBox;
  1149. tmpBox.setWindowTitle("R-Motion");
  1150. tmpBox.setText("New R-Motion application version v" + QString::number(newAppMajor) + "." + QString::number(newAppMinor) + "." + QString::number(newAppTail) +
  1151. " is available.\nPlease remember to close the application before running the installer.");
  1152. tmpBox.setInformativeText("Do you want to go to the installer now?");
  1153. tmpBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
  1154. int ret = tmpBox.exec();
  1155. if (ret == QMessageBox::Yes)
  1156. {
  1157. ourDownloadPath.replace("\\", "/");
  1158. QString urlToTmpDownload = "file:///" + ourDownloadPath;
  1159. qDebug() << "Opening the file url: " << urlToTmpDownload;
  1160. QDesktopServices::openUrl(QUrl(urlToTmpDownload, QUrl::TolerantMode));
  1161. }
  1162. }
  1163. else
  1164. {
  1165. qDebug() << "Do not have permission to write to the file:" << newAppFilename;
  1166. }
  1167. }
  1168. else
  1169. {
  1170. qDebug() << "Corrupted app downloaded from server";
  1171. }
  1172. }
  1173. }
  1174. else if (requestAttribute.contains("getNameInfoRequest"))
  1175. {
  1176. if (networkReply->error())
  1177. {
  1178. QString extLink = "http://rmotiongolf.com/VB2/payment/tgc-license.php?tgc_email=" + userEmail + "&tgc_machineid=" +
  1179. machineIdText + "&tgc_exist_license=" + userLicenseText;
  1180. QDesktopServices::openUrl(QUrl(extLink));
  1181. }
  1182. else
  1183. {
  1184. QString tmpReply = networkReply->readAll();
  1185. QList<QString> tmpNames = tmpReply.split(" ");
  1186. if (tmpNames.count() == 2)
  1187. {
  1188. QString firstName = tmpNames[0];
  1189. QString lastName = tmpNames[1];
  1190. QString extLink = "http://rmotiongolf.com/VB2/payment/tgc-license.php?tgc_firstname=" + firstName + "&tgc_lastname=" + lastName
  1191. + "&tgc_email=" + userEmail + "&tgc_machineid=" + machineIdText + "&tgc_exist_license=" + userLicenseText;
  1192. QDesktopServices::openUrl(QUrl(extLink));
  1193. }
  1194. else
  1195. {
  1196. QString extLink = "http://rmotiongolf.com/VB2/payment/tgc-license.php?tgc_email=" + userEmail + "&tgc_machineid=" +
  1197. machineIdText + "&tgc_exist_license=" + userLicenseText;
  1198. QDesktopServices::openUrl(QUrl(extLink));
  1199. }
  1200. }
  1201. }
  1202. else if (requestAttribute.contains("dataSyncRequest"))
  1203. {
  1204. if (networkReply->error())
  1205. qDebug() << "Error during sync request";
  1206. else
  1207. {
  1208. QByteArray respByteArray = networkReply->readAll();
  1209. qDebug() << respByteArray;
  1210. QJsonDocument respJsonDoc = QJsonDocument::fromJson(respByteArray);
  1211. QJsonObject respJsonObj = respJsonDoc.object();
  1212. if (respJsonObj["success"].toBool() == true)
  1213. {
  1214. qDebug() << "Sync completed for email" << syncingPlayer.loginName << ". Delete data now";
  1215. int deleteRet = shotDatabase->deleteAllPlayerShots(syncingPlayer);
  1216. if (deleteRet == 0)
  1217. shotSyncFunc();
  1218. }
  1219. else
  1220. qDebug() << "Sync failed for email" << syncingPlayer.loginName << ":" << respJsonObj["message"].toString();
  1221. }
  1222. }
  1223. networkReply->deleteLater();
  1224. }
  1225. void launchBoxSim::goToFwWaitCharging()
  1226. {
  1227. ui.stackedWidget->setCurrentIndex(6);
  1228. ui.fwUpgradeLabel->hide();
  1229. QPixmap pixmap(":/launchBoxSim/images/fwWaitCharging.png");
  1230. this->setFixedSize(pixmap.width(), pixmap.height());
  1231. QPalette palette;
  1232. palette.setBrush(QPalette::Background, pixmap);
  1233. this->setPalette(palette);
  1234. ui.dashboardPushButton->setDisabled(1);
  1235. ui.clubsPushButton->setDisabled(1);
  1236. ui.settingsPushButton->setDisabled(1);
  1237. ui.upgradePushbutton->setDisabled(1);
  1238. ui.helpPushbutton->setDisabled(1);
  1239. ui.aboutPushButton->setDisabled(1);
  1240. }
  1241. void launchBoxSim::goToFwUpgrading()
  1242. {
  1243. ui.stackedWidget->setCurrentIndex(6);
  1244. QPixmap pixmap(":/launchBoxSim/images/fwUpgrading.png");
  1245. this->setFixedSize(pixmap.width(), pixmap.height());
  1246. QPalette palette;
  1247. palette.setBrush(QPalette::Background, pixmap);
  1248. this->setPalette(palette);
  1249. ui.dashboardPushButton->setDisabled(1);
  1250. ui.clubsPushButton->setDisabled(1);
  1251. ui.settingsPushButton->setDisabled(1);
  1252. ui.upgradePushbutton->setDisabled(1);
  1253. ui.helpPushbutton->setDisabled(1);
  1254. ui.aboutPushButton->setDisabled(1);
  1255. }
  1256. void launchBoxSim::goToLicenseRequest()
  1257. {
  1258. ui.stackedWidget->setCurrentIndex(4);
  1259. QPixmap pixmap(":/launchBoxSim/images/licenseRequestSkeleton.png");
  1260. this->setFixedSize(pixmap.width(), pixmap.height());
  1261. QPalette palette;
  1262. palette.setBrush(QPalette::Background, pixmap);
  1263. this->setPalette(palette);
  1264. ui.dashboardPushButton->setDisabled(1);
  1265. ui.clubsPushButton->setDisabled(1);
  1266. ui.settingsPushButton->setDisabled(1);
  1267. ui.upgradePushbutton->setDisabled(1);
  1268. ui.helpPushbutton->setDisabled(1);
  1269. ui.aboutPushButton->setDisabled(1);
  1270. if (box->dongleStatus == 1)
  1271. {
  1272. QPixmap tmpPm(":/launchBoxSim/images/statusOK.png");
  1273. ui.licenseDongleLabel->setPixmap(tmpPm);
  1274. ui.licenseDongleLabel->show();
  1275. }
  1276. else
  1277. {
  1278. QPixmap tmpPm(":/launchBoxSim/images/statusNOK.png");
  1279. ui.licenseDongleLabel->setPixmap(tmpPm);
  1280. ui.licenseDongleLabel->show();
  1281. }
  1282. if (box->dongleStatus == 1)
  1283. {
  1284. QPixmap tmpPm(":/launchBoxSim/images/getLicenseLabelActive.png");
  1285. ui.getLicenseLabel->setPixmap(tmpPm);
  1286. ui.getLicenseLabel->show();
  1287. ui.getLicenseButton->raise();
  1288. }
  1289. else
  1290. {
  1291. QPixmap tmpPm(":/launchBoxSim/images/getLicenseLabelInActive.png");
  1292. ui.getLicenseLabel->setPixmap(tmpPm);
  1293. ui.getLicenseLabel->show();
  1294. }
  1295. monitorGetLicenseRequire = new QTimer(this);
  1296. monitorGetLicenseRequire->setInterval(1000);
  1297. monitorGetLicenseRequire->setSingleShot(true);
  1298. connect(monitorGetLicenseRequire, SIGNAL(timeout()), this, SLOT(goToLicenseRequest()), Qt::QueuedConnection);
  1299. monitorGetLicenseRequire->start();
  1300. }
  1301. void launchBoxSim::clickGetLicense()
  1302. {
  1303. if ((monitorGetLicenseRequire != NULL) && (monitorGetLicenseRequire->isActive()))
  1304. monitorGetLicenseRequire->stop();
  1305. if (freeLicenseRequesting == 1)
  1306. return;
  1307. if (userLicenseStatus == 0)
  1308. {
  1309. freeLicenseRequesting = 1; // prevent multiple continuous free license request
  1310. QPixmap tmpPm(":/launchBoxSim/images/getLicenseLabelWaiting.png");
  1311. ui.getLicenseLabel->setPixmap(tmpPm);
  1312. ui.getLicenseLabel->show();
  1313. QString tmpDongleId;
  1314. tmpDongleId.sprintf("%02X%02X%02X%02X%02X%02X", box->dongleId[5], box->dongleId[4], box->dongleId[3], box->dongleId[2], box->dongleId[1], box->dongleId[0]);
  1315. QString licenseServerString;
  1316. QNetworkRequest freeLicenseRequest;
  1317. licenseServerString = "http://rmotion.rapsodo.com/api/licence?username=" + userEmail + "&dongleID=" + tmpDongleId + "&machineID=" + machineIdText;
  1318. qDebug() << licenseServerString;
  1319. freeLicenseRequest.setUrl(QUrl(licenseServerString));
  1320. freeLicenseRequest.setAttribute(QNetworkRequest::User, QVariant("freeLicenseRequest"));
  1321. networkManager->get(freeLicenseRequest);
  1322. }
  1323. else
  1324. {
  1325. clickedOkDashBoard();
  1326. scanForRmotion();
  1327. }
  1328. }
  1329. void launchBoxSim::emailPasswordChanged()
  1330. {
  1331. ui.loginErrorLabel->clear();
  1332. if ((ui.emailText->text().isEmpty()) || (ui.passwordText->text().isEmpty()))
  1333. ui.signinButton->setDisabled(1);
  1334. else
  1335. ui.signinButton->setDisabled(0);
  1336. }
  1337. void launchBoxSim::licenseTextChanged()
  1338. {
  1339. if ((ui.licensekeyText->toPlainText().isEmpty()) || (userLicenseStatus == 2))
  1340. ui.activateLicense->setDisabled(1);
  1341. else
  1342. ui.activateLicense->setDisabled(0);
  1343. }
  1344. void launchBoxSim::clickForgotPassword()
  1345. {
  1346. if (ui.emailText->text().isEmpty())
  1347. {
  1348. QMessageBox noEmailPopup;
  1349. noEmailPopup.setText("Please fill in your email ID before clicking Forgot Password button.");
  1350. noEmailPopup.setStandardButtons(QMessageBox::Ok);
  1351. noEmailPopup.setDefaultButton(QMessageBox::Ok);
  1352. noEmailPopup.exec();
  1353. }
  1354. else
  1355. {
  1356. QString forgotPasswordString = "http://rmotion.rapsodo.com/api/auth/forgetpassword?username=" + ui.emailText->text();
  1357. QNetworkRequest forgotPasswordRequest;
  1358. qDebug() << forgotPasswordString;
  1359. forgotPasswordRequest.setUrl(QUrl(forgotPasswordString));
  1360. forgotPasswordRequest.setAttribute(QNetworkRequest::User, QVariant("forgotPasswordRequest"));
  1361. networkManager->get(forgotPasswordRequest);
  1362. QMessageBox forgotPasswordPopup;
  1363. forgotPasswordPopup.setText("An email with your password information will be sent to you soon. Please check your mailbox.");
  1364. forgotPasswordPopup.setStandardButtons(QMessageBox::Ok);
  1365. forgotPasswordPopup.setDefaultButton(QMessageBox::Ok);
  1366. forgotPasswordPopup.exec();
  1367. }
  1368. }
  1369. void launchBoxSim::updateAppDownloadProgress(qint64 bytesReceived, qint64 bytesTotal)
  1370. {
  1371. qDebug() << "Downloading new application version:" << bytesReceived << "bytes over total" << bytesTotal << "bytes";
  1372. }
  1373. void launchBoxSim::checkAppUpdate()
  1374. {
  1375. QString checkAppUpdateString = "http://rmotion.rapsodo.com/build/version.txt";
  1376. QNetworkRequest checkAppUpdateReq;
  1377. checkAppUpdateReq.setUrl(QUrl(checkAppUpdateString));
  1378. checkAppUpdateReq.setAttribute(QNetworkRequest::User, QVariant("checkAppUpdate"));
  1379. networkManager->get(checkAppUpdateReq);
  1380. }
  1381. void launchBoxSim::waitRmotionCharging()
  1382. {
  1383. if ((box->isDeviceCharging == 1) || (box->curVoltageLevel >= 3.8))
  1384. {
  1385. goToFwUpgrading();
  1386. emit uiStartFWUpgrade();
  1387. }
  1388. else
  1389. QTimer::singleShot(1000, this, SLOT(waitRmotionCharging()));
  1390. }
  1391. void launchBoxSim::clickRestartDevice()
  1392. {
  1393. // anything to do before restart device?
  1394. emit uiRestartDevice();
  1395. }
  1396. void launchBoxSim::uiDeviceListDevice(unsigned char *deviceId)
  1397. {
  1398. QString tempString;
  1399. tempString.sprintf("%02X %02X %02X %02X %02X %02X", deviceId[0], deviceId[1], deviceId[2], deviceId[3], deviceId[4], deviceId[5]);
  1400. qDebug() << "bleapp found R-Motion device ID" << tempString;
  1401. QByteArray newDevice;
  1402. newDevice.resize(6);
  1403. newDevice[0] = deviceId[0];
  1404. newDevice[1] = deviceId[1];
  1405. newDevice[2] = deviceId[2];
  1406. newDevice[3] = deviceId[3];
  1407. newDevice[4] = deviceId[4];
  1408. newDevice[5] = deviceId[5];
  1409. for (int i = 0; i < deviceList.count(); i++)
  1410. if (deviceList[i] == newDevice)
  1411. return;
  1412. deviceList.append(newDevice);
  1413. }
  1414. void launchBoxSim::uiDeviceListEnd()
  1415. {
  1416. ui.deviceListSelectBox->clear();
  1417. ui.deviceListSelectBox->hide();
  1418. int deviceListCount = deviceList.count();
  1419. if (deviceListCount == 0)
  1420. {
  1421. deviceList.clear();
  1422. ui.deviceStatusLabel->setText("No Device Found");
  1423. ui.deviceStatusLabel->show();
  1424. scanningInProgress = 0;
  1425. QTimer::singleShot(2000, this, SLOT(scanForRmotion()));
  1426. }
  1427. else if (deviceListCount == 1) // auto connect if there is only 1 device available after 5 seconds of scanning
  1428. {
  1429. unsigned char selectedDevice[6];
  1430. selectedDevice[0] = deviceList[0][0];
  1431. selectedDevice[1] = deviceList[0][1];
  1432. selectedDevice[2] = deviceList[0][2];
  1433. selectedDevice[3] = deviceList[0][3];
  1434. selectedDevice[4] = deviceList[0][4];
  1435. selectedDevice[5] = deviceList[0][5];
  1436. emit uiConnectDevice(selectedDevice);
  1437. deviceList.clear();
  1438. }
  1439. else
  1440. {
  1441. ui.deviceStatusLabel->setText("Multiple Devices Found");
  1442. ui.deviceStatusLabel->show();
  1443. ui.deviceListSelectBox->show();
  1444. ui.deviceListSelectBox->insertItem(0, "Select Your Device");
  1445. ui.deviceListSelectBox->setCurrentIndex(0);
  1446. for (int i = 0; i < deviceListCount; i++)
  1447. {
  1448. QString tmpString = QString(deviceList[i].toHex());
  1449. tmpString.insert(10, " ");
  1450. tmpString.insert(8, " ");
  1451. tmpString.insert(6, " ");
  1452. tmpString.insert(4, " ");
  1453. tmpString.insert(2, " ");
  1454. tmpString.prepend("R-Motion ");
  1455. tmpString.truncate(14);
  1456. ui.deviceListSelectBox->insertItem(i+1, tmpString);
  1457. }
  1458. connect(ui.deviceListSelectBox, SIGNAL(activated(int)), this, SLOT(handleDeviceSelected(int)), Qt::QueuedConnection);
  1459. }
  1460. }
  1461. void launchBoxSim::handleDeviceSelected(int index)
  1462. {
  1463. if ((index >= 1) && (index <= deviceList.count()))
  1464. {
  1465. int row = index - 1;
  1466. unsigned char selectedDevice[6];
  1467. selectedDevice[0] = deviceList[row][0];
  1468. selectedDevice[1] = deviceList[row][1];
  1469. selectedDevice[2] = deviceList[row][2];
  1470. selectedDevice[3] = deviceList[row][3];
  1471. selectedDevice[4] = deviceList[row][4];
  1472. selectedDevice[5] = deviceList[row][5];
  1473. emit uiConnectDevice(selectedDevice);
  1474. ui.deviceListSelectBox->clear();
  1475. ui.deviceListSelectBox->hide();
  1476. deviceList.clear();
  1477. }
  1478. }
  1479. void launchBoxSim::connectToDeviceTimeout()
  1480. {
  1481. ui.deviceStatusLabel->setText("Unable To Connect");
  1482. ui.deviceStatusLabel->show();
  1483. scanningInProgress = 0;
  1484. QTimer::singleShot(2000, this, SLOT(scanForRmotion()));
  1485. }
  1486. void launchBoxSim::closeEvent(QCloseEvent *event)
  1487. {
  1488. delete box;
  1489. delete game;
  1490. delete savedData;
  1491. zipFilePrepend = userEmail;
  1492. qApp->quit();
  1493. }
  1494. void launchBoxSim::wrapLaunchData()
  1495. {
  1496. QJsonObject jsonObj;
  1497. QJsonObject jsonObjData;
  1498. #ifdef ENCRYPT
  1499. int aesStatus;
  1500. QJsonObject jsonObjEnc;
  1501. #endif
  1502. // dampen the result and limit launch direction with in [-7 7]
  1503. float launch_dir = ballResult.launch_direction; // degree
  1504. float face_ang = clubResult.face_angle;
  1505. float club_pat = clubResult.club_path;
  1506. float face_relative_to_path = clubResult.face_to_path_at_hit;
  1507. if ((curClubType == "DR") || (curClubType == "W3") || (curClubType == "W5"))
  1508. {
  1509. launch_dir = launch_dir / 1.5;
  1510. face_ang = face_ang / 1.5;
  1511. club_pat = club_pat / 1.5;
  1512. face_relative_to_path = face_relative_to_path / 1.5;
  1513. }
  1514. else
  1515. {
  1516. launch_dir = launch_dir / 1.2;
  1517. face_ang = face_ang / 1.2;
  1518. club_pat = club_pat / 1.2;
  1519. face_relative_to_path = face_relative_to_path / 1.2;
  1520. }
  1521. if (launch_dir < -10.0)
  1522. launch_dir = -10.0;
  1523. else if (launch_dir > 10.0)
  1524. launch_dir = 10.0;
  1525. // reverse club path and face angle if the player is left-handed
  1526. if (curPlayerHand == "LH")
  1527. {
  1528. face_ang = face_ang * (-1.0);
  1529. club_pat = club_pat * (-1.0);
  1530. }
  1531. QString protocol = "PTLAUNCH";
  1532. jsonObj["protocol"] = protocol;
  1533. jsonObjData["ballSpeedMPH"] = QString::number(ballResult.ball_speed/0.44704,'f',1);
  1534. jsonObjData["ballDirection"] = QString::number(launch_dir,'f',1);
  1535. jsonObjData["ballAngle"] = QString::number(ballResult.launch_angle,'f',1);
  1536. jsonObjData["spinAxis"] = QString::number(ballResult.spin_axis,'f',1);
  1537. jsonObjData["backSpin"] = QString::number(ballResult.spin_rate * 60,'f',0);
  1538. if (curClubType == "PT") // in PUTTER mode just send 1000rpm back spin to the game
  1539. jsonObjData["backSpin"] = QString::number(1000,'f',0);
  1540. jsonObjData["clubSpeedMPH"] = QString::number(clubResult.club_speed * 2.23694, 'f', 1);
  1541. jsonObjData["clubFace"] = QString::number(face_ang, 'f', 1);
  1542. jsonObjData["swingPath"] = QString::number(club_pat, 'f', 1);
  1543. jsonObjData["swingTempo"] = QString::number(clubResult.tempo, 'f', 1);
  1544. jsonObjData["faceRelative"] = QString::number(face_relative_to_path, 'f', 1);
  1545. #ifdef ENCRYPT
  1546. jsonObj["DATA"] = jsonObjData;
  1547. // convert to string
  1548. QJsonDocument doc(jsonObj);
  1549. QByteArray encryptedBytes = doc.toJson(QJsonDocument::Compact);
  1550. QString qstr = "";
  1551. qstr.append(encryptedBytes);
  1552. qDebug() << qstr;
  1553. //int byteCount = encryptedBytes.size();
  1554. int byteCount = encryptedBytes.size() + 1; // Thomas: add in the null-terminated character
  1555. int effectiveByteCount;
  1556. char residue;
  1557. char *data = encryptedBytes.data();
  1558. unsigned char buffer[MAX_LAUNCH_DATA_SIZE];// = (unsigned char *)new(sizeof(char), MAX_LAUNCH_DATA_SIZE);
  1559. QByteArray encOutput;
  1560. float factor = (float)byteCount/(float)ENCRYPTION_BLOCK_SIZE;
  1561. if(byteCount<=128)
  1562. {
  1563. factor = 5;//force to 160 at least
  1564. effectiveByteCount = (int)(factor)*ENCRYPTION_BLOCK_SIZE;
  1565. residue = effectiveByteCount - byteCount;
  1566. }
  1567. else
  1568. {
  1569. if(byteCount%ENCRYPTION_BLOCK_SIZE==0)
  1570. {
  1571. effectiveByteCount = byteCount;
  1572. residue = 0;
  1573. }
  1574. else
  1575. {
  1576. effectiveByteCount = (int)(factor+1)*ENCRYPTION_BLOCK_SIZE;
  1577. residue = effectiveByteCount - byteCount;
  1578. }
  1579. }
  1580. memset(buffer,residue,sizeof(char)*MAX_LAUNCH_DATA_SIZE);
  1581. memcpy(buffer,data,sizeof(char)*byteCount);
  1582. MCRYPT cModule;
  1583. cModule = mcrypt_module_open(MCRYPT_RIJNDAEL_256, NULL, MCRYPT_CBC, NULL );
  1584. mcrypt_generic_init(cModule, &encrytionKeys[0], ENCRYPTION_BLOCK_SIZE, &encrytionIVLE[0]);
  1585. mcrypt_generic(cModule, buffer, effectiveByteCount);
  1586. // encode base 64
  1587. encOutput.prepend((char *)buffer,effectiveByteCount);
  1588. QString encB64(encOutput.toBase64());
  1589. QString protocolEnc = "PTLAUNCHENC";
  1590. jsonObjEnc["protocol"] = protocolEnc;
  1591. jsonObjEnc["WO"] = "2";
  1592. jsonObjEnc["ENCDATA"] = encB64;
  1593. emit ballFly2UI(jsonObjEnc);
  1594. shotDatabaseEntry entry;
  1595. entry.timeHappened = QDateTime::currentDateTime().toMSecsSinceEpoch();
  1596. entry.loginName = userEmail;
  1597. entry.playerName = curPlayerName;
  1598. entry.clubType = curClubType;
  1599. entry.ballSpeedMPH = ballResult.ball_speed / 0.44704;
  1600. entry.ballDirection = launch_dir;
  1601. entry.ballAngle = ballResult.launch_angle;
  1602. entry.spinAxis = ballResult.spin_axis;
  1603. entry.backSpin = ballResult.spin_rate * 60;
  1604. entry.clubSpeedMPH = clubResult.club_speed * 2.23694;
  1605. entry.clubFace = face_ang;
  1606. entry.swingPath = club_pat;
  1607. entry.swingTempo = clubResult.tempo;
  1608. entry.faceRelative = face_relative_to_path;
  1609. shotDatabase->insertShotDatabaseEntry(entry);
  1610. #else
  1611. jsonObj["DATA"] = jsonObjData;
  1612. emit ballFly2UI(jsonObj);
  1613. #endif
  1614. }
  1615. void launchBoxSim::clickGoToHomepage()
  1616. {
  1617. QString extLink = "http://rmotiongolf.com";
  1618. QDesktopServices::openUrl(QUrl(extLink));
  1619. }
  1620. void launchBoxSim::game2UIServerConnected()
  1621. {
  1622. if (userLicenseStatus == 2)
  1623. {
  1624. licenseNewState = LICENSE_SM_VERIFY_FULL;
  1625. emit ui2GameConnectLicense(userFullLicenseText);
  1626. }
  1627. else if (userLicenseStatus == 1)
  1628. {
  1629. licenseNewState = LICENSE_SM_VERIFY_FREE;
  1630. emit ui2GameConnectLicense(userLicenseText);
  1631. }
  1632. }
  1633. void launchBoxSim::ballTypeGroupChanged(int radio)
  1634. {
  1635. if (ui.hardBallRadio->isChecked())
  1636. settingsBallType = "HARDBALL";
  1637. else if (ui.almostBallRadio->isChecked())
  1638. settingsBallType = "ALMOSTBALL";
  1639. savedData->setValue("ui/settingsBallType", QVariant(settingsBallType));
  1640. // resend ARM command if the ball type is changed in the middle of playing
  1641. if ((curPlayerName != "") && (curClubType != "") && (box->bleConnectionStatus == 1))
  1642. {
  1643. ClubInfo clubInfo = getPlayerClubInfo(curPlayerName, curClubType);
  1644. emit uiChangePlayingMode(curPlayerHand, curClubType, 1.0f, settingsBallType, settingsKidMode,
  1645. clubInfo.clubLength, clubInfo.clubLoft, clubInfo.isHybrid);
  1646. }
  1647. }
  1648. void launchBoxSim::kidModeGroupChanged(int radio)
  1649. {
  1650. if (ui.kidModeEnableRadio->isChecked())
  1651. settingsKidMode = "ENABLE";
  1652. else if (ui.kidModeDisableRadio->isChecked())
  1653. settingsKidMode = "DISABLE";
  1654. savedData->setValue("ui/settingsKidMode", QVariant(settingsKidMode));
  1655. // resend ARM command if kid mode is changed in the middle of playing
  1656. if ((curPlayerName != "") && (curClubType != "") && (box->bleConnectionStatus == 1))
  1657. {
  1658. ClubInfo clubInfo = getPlayerClubInfo(curPlayerName, curClubType);
  1659. emit uiChangePlayingMode(curPlayerHand, curClubType, 1.0f, settingsBallType, settingsKidMode,
  1660. clubInfo.clubLength, clubInfo.clubLoft, clubInfo.isHybrid);
  1661. }
  1662. }
  1663. void launchBoxSim::diagnosticModeGroupChanged(int)
  1664. {
  1665. if (ui.diagnosticDisabledRadio->isChecked())
  1666. {
  1667. settingsDiagnosticMode = "DISABLED";
  1668. savedData->setValue("ui/settingsDiagnosticMode", QVariant("DISABLED"));
  1669. qDebug() << "User disabled diagnostic mode";
  1670. emit uiChangeUserSettings(settingsDisableAutoStandby, "OFF", "OFF", "OFF", "OFF");
  1671. }
  1672. else if (ui.diagnosticEnabledRadio->isChecked())
  1673. {
  1674. settingsDiagnosticMode = "ENABLED";
  1675. savedData->setValue("ui/settingsDiagnosticMode", QVariant("ENABLED"));
  1676. qDebug() << "User enabled diagnostic mode";
  1677. emit uiChangeUserSettings(settingsDisableAutoStandby, settingsEnableShotLog, settingsEnableDebugMode,
  1678. settingsSendDebugData, settingsSendFalseTrigger);
  1679. }
  1680. // resend ARM command if the diagnostic mode is changed in the middle of playing
  1681. if ((curPlayerName != "") && (curClubType != "") && (box->bleConnectionStatus == 1))
  1682. {
  1683. ClubInfo clubInfo = getPlayerClubInfo(curPlayerName, curClubType);
  1684. emit uiChangePlayingMode(curPlayerHand, curClubType, 1.0f, settingsBallType, settingsKidMode,
  1685. clubInfo.clubLength, clubInfo.clubLoft, clubInfo.isHybrid);
  1686. }
  1687. }
  1688. QString launchBoxSim::createPlayerClubInfoLine(QString playerName)
  1689. {
  1690. QString tmpStr;
  1691. tmpStr = "playerName=" + playerName + ";";
  1692. PlayerClubs tmpClubs = playerClubInfoList[playerName];
  1693. tmpStr += "base_info=" + tmpClubs.baseInfo + ";";
  1694. for (QMap<QString, ClubInfo>::const_iterator i = tmpClubs.clubInfo.constBegin(); i != tmpClubs.clubInfo.constEnd(); i++)
  1695. {
  1696. QString clubStr = QString("%1=%2,%3,%4,%5;")
  1697. .arg(i.key())
  1698. .arg(i.value().clubType)
  1699. .arg(QString::number(i.value().clubLength))
  1700. .arg(QString::number(i.value().clubLoft))
  1701. .arg(QString::number(i.value().isHybrid));
  1702. //tmpStr += i.key() + "=" + i.value().clubType + "," + QString::number(i.value().clubLength) + "," + QString::number(i.value().clubLoft) + ";";
  1703. tmpStr += clubStr;
  1704. }
  1705. return tmpStr;
  1706. }
  1707. void launchBoxSim::savePlayerClubInfoList()
  1708. {
  1709. QString playerClubFilename = ourPathString + "playerClubs.txt";
  1710. QFile playerClubFile(playerClubFilename);
  1711. if (playerClubFile.open(QIODevice::WriteOnly))
  1712. {
  1713. QTextStream out(&playerClubFile);
  1714. for (QMap<QString, PlayerClubs>::const_iterator i = playerClubInfoList.constBegin(); i != playerClubInfoList.constEnd(); i++)
  1715. {
  1716. QString tmpStr = createPlayerClubInfoLine(i.key());
  1717. out << tmpStr << endl;
  1718. }
  1719. }
  1720. playerClubFile.flush();
  1721. playerClubFile.close();
  1722. needToSavePlayerClubInfoList = false;
  1723. }
  1724. void launchBoxSim::initPlayerClubInfoList()
  1725. {
  1726. QString playerClubFilename = ourPathString + "playerClubs.txt";
  1727. QFile playerClubFile(playerClubFilename);
  1728. // if the file is not found, initialize default and default_kid clubs with static information
  1729. if ((!playerClubFile.exists()) || (!playerClubFile.open(QIODevice::ReadOnly)))
  1730. {
  1731. initDefaultPlayerClubInfoList();
  1732. initDefaultKidPlayerClubInfoList();
  1733. needToSavePlayerClubInfoList = true;
  1734. return;
  1735. }
  1736. // parse the file to create playerClubInfoList
  1737. QTextStream in(&playerClubFile);
  1738. while (!in.atEnd())
  1739. {
  1740. QString tmpLine = in.readLine();
  1741. QList<QString> entries = tmpLine.split(';');
  1742. if (entries.size() < 3) // there must be playerName, base_info and at least one custom club entry
  1743. continue;
  1744. QList<QString> nameEntry = entries[0].split('='); // playerName=DEFAULT;
  1745. if (nameEntry.size() != 2)
  1746. continue;
  1747. QString tmpName = nameEntry[1];
  1748. QList<QString> baseEntry = entries[1].split('='); // base_info=DEFAULT;
  1749. if (baseEntry.size() != 2)
  1750. continue;
  1751. PlayerClubs tmpClubs;
  1752. tmpClubs.playerName = tmpName;
  1753. tmpClubs.baseInfo = baseEntry[1];
  1754. for (int i = 2; i < entries.size(); i++)
  1755. {
  1756. QList<QString> tmpInfo = entries[i].split('='); // I3=IRON_3,length,loft;
  1757. if (tmpInfo.size() != 2)
  1758. continue;
  1759. QList<QString> tmpProp = tmpInfo[1].split(',');
  1760. if ((tmpProp.size() != 3) && (tmpProp.size() != 4))
  1761. continue;
  1762. tmpClubs.clubInfo[tmpInfo[0]].clubType = tmpProp[0];
  1763. tmpClubs.clubInfo[tmpInfo[0]].clubLength = tmpProp[1].toFloat();
  1764. tmpClubs.clubInfo[tmpInfo[0]].clubLoft = tmpProp[2].toFloat();
  1765. if (tmpProp.size() == 3)
  1766. tmpClubs.clubInfo[tmpInfo[0]].isHybrid = 0;
  1767. else
  1768. tmpClubs.clubInfo[tmpInfo[0]].isHybrid = tmpProp[3].toInt();
  1769. }
  1770. playerClubInfoList[tmpName] = tmpClubs;
  1771. }
  1772. needToSavePlayerClubInfoList = false;
  1773. playerClubFile.close();
  1774. }
  1775. void launchBoxSim::initDefaultPlayerClubInfoList()
  1776. {
  1777. PlayerClubs defaultPlayerClubs;
  1778. defaultPlayerClubs.playerName = "DEFAULT_ADULT";
  1779. defaultPlayerClubs.baseInfo = "DEFAULT_ADULT";
  1780. defaultPlayerClubs.clubInfo["I3"] = { "IRON_3", 27.6, 23, 0 };
  1781. defaultPlayerClubs.clubInfo["I4"] = { "IRON_4", 27.1, 25, 0 };
  1782. defaultPlayerClubs.clubInfo["I5"] = { "IRON_5", 26.6, 27, 0 };
  1783. defaultPlayerClubs.clubInfo["I6"] = { "IRON_6", 26.1, 31, 0 };
  1784. defaultPlayerClubs.clubInfo["I7"] = { "IRON_7", 25.6, 35, 0 };
  1785. defaultPlayerClubs.clubInfo["I8"] = { "IRON_8", 25.1, 39, 0 };
  1786. defaultPlayerClubs.clubInfo["I9"] = { "IRON_9", 24.6, 43, 0 };
  1787. defaultPlayerClubs.clubInfo["PW"] = { "PITCH_WEDGE", 24.6, 47, 0 };
  1788. defaultPlayerClubs.clubInfo["SW"] = { "SAND_WEDGE", 24.6, 55, 0 };
  1789. defaultPlayerClubs.clubInfo["LW"] = { "LOFT_WEDGE", 24.6, 60, 0 };
  1790. defaultPlayerClubs.clubInfo["W3"] = { "WOOD_3", 30.5, 17, 0 };
  1791. defaultPlayerClubs.clubInfo["W5"] = { "WOOD_5", 29.5, 23, 0 };
  1792. defaultPlayerClubs.clubInfo["DR"] = { "DRIVER", 31.9, 12, 0 };
  1793. defaultPlayerClubs.clubInfo["PT"] = { "PUTTER", 23.8, 0.1, 0 };
  1794. playerClubInfoList["DEFAULT_ADULT"] = defaultPlayerClubs;
  1795. }
  1796. void launchBoxSim::initDefaultKidPlayerClubInfoList()
  1797. {
  1798. PlayerClubs defaultKidPlayerClubs;
  1799. defaultKidPlayerClubs.playerName = "DEFAULT_KID";
  1800. defaultKidPlayerClubs.baseInfo = "DEFAULT_KID";
  1801. defaultKidPlayerClubs.clubInfo["I3"] = { "IRON_3", 25.0, 23, 0 };
  1802. defaultKidPlayerClubs.clubInfo["I4"] = { "IRON_4", 24.0, 25, 0 };
  1803. defaultKidPlayerClubs.clubInfo["I5"] = { "IRON_5", 23.0, 27, 0 };
  1804. defaultKidPlayerClubs.clubInfo["I6"] = { "IRON_6", 22.0, 31, 0 };
  1805. defaultKidPlayerClubs.clubInfo["I7"] = { "IRON_7", 21.1, 35, 0 };
  1806. defaultKidPlayerClubs.clubInfo["I8"] = { "IRON_8", 19.1, 39, 0 };
  1807. defaultKidPlayerClubs.clubInfo["I9"] = { "IRON_9", 18.1, 43, 0 };
  1808. defaultKidPlayerClubs.clubInfo["PW"] = { "PITCH_WEDGE", 18.1, 47, 0 };
  1809. defaultKidPlayerClubs.clubInfo["SW"] = { "SAND_WEDGE", 18.1, 55, 0 };
  1810. defaultKidPlayerClubs.clubInfo["LW"] = { "LOFT_WEDGE", 18.1, 60, 0 };
  1811. defaultKidPlayerClubs.clubInfo["W3"] = { "WOOD_3", 25.6, 17, 0 };
  1812. defaultKidPlayerClubs.clubInfo["W5"] = { "WOOD_5", 24.6, 23, 0 };
  1813. defaultKidPlayerClubs.clubInfo["DR"] = { "DRIVER", 26.6, 11, 0 };
  1814. defaultKidPlayerClubs.clubInfo["PT"] = { "PUTTER", 18.1, 0.1, 0 };
  1815. playerClubInfoList["DEFAULT_KID"] = defaultKidPlayerClubs;
  1816. }
  1817. ClubInfo launchBoxSim::getPlayerClubInfo(QString playerName, QString clubType)
  1818. {
  1819. if (!playerClubInfoList.contains(playerName)) // this should not happen, but check anyway
  1820. {
  1821. return playerClubInfoList["DEFAULT_ADULT"].clubInfo[clubType];
  1822. }
  1823. else
  1824. {
  1825. QMap<QString, ClubInfo> tmpMap = playerClubInfoList[playerName].clubInfo;
  1826. QString tmpBase = playerClubInfoList[playerName].baseInfo;
  1827. if (tmpMap.contains(clubType)) // this clubType was customized for this player
  1828. return tmpMap[clubType];
  1829. else // this player uses the default info for this clubType
  1830. return playerClubInfoList[tmpBase].clubInfo[clubType];
  1831. }
  1832. }
  1833. ClubInfo launchBoxSim::getPlayerClubInfoNewBase(QString playerName, QString clubType, QString newBase)
  1834. {
  1835. if (!playerClubInfoList.contains(playerName)) // this should not happen, but check anyway
  1836. {
  1837. return playerClubInfoList[newBase].clubInfo[clubType];
  1838. }
  1839. else
  1840. {
  1841. QMap<QString, ClubInfo> tmpMap = playerClubInfoList[playerName].clubInfo;
  1842. if (tmpMap.contains(clubType)) // this clubType was customized for this player
  1843. return tmpMap[clubType];
  1844. else
  1845. return playerClubInfoList[newBase].clubInfo[clubType];
  1846. }
  1847. }
  1848. void launchBoxSim::addNewPlayerToClubInfoList(QString playerName)
  1849. {
  1850. PlayerClubs tmpClubs;
  1851. tmpClubs.playerName = playerName;
  1852. tmpClubs.baseInfo = "DEFAULT_ADULT";
  1853. QMap<QString, ClubInfo> tmpInfo;
  1854. tmpClubs.clubInfo = tmpInfo;
  1855. playerClubInfoList[playerName] = tmpClubs;
  1856. ui.playerListSelectBox->addItem(playerName);
  1857. }
  1858. void launchBoxSim::displayPlayerClubInfo(QString playerName)
  1859. {
  1860. ClubInfo tmpInfo;
  1861. tmpInfo = getPlayerClubInfo(playerName, "I3");
  1862. ui.iron3LengthText->setText(QString::number(tmpInfo.clubLength));
  1863. ui.iron3LoftText->setText(QString::number(tmpInfo.clubLoft));
  1864. ui.hybrid3CheckBox->setChecked(tmpInfo.isHybrid);
  1865. tmpInfo = getPlayerClubInfo(playerName, "I4");
  1866. ui.iron4LengthText->setText(QString::number(tmpInfo.clubLength));
  1867. ui.iron4LoftText->setText(QString::number(tmpInfo.clubLoft));
  1868. ui.hybrid4CheckBox->setChecked(tmpInfo.isHybrid);
  1869. tmpInfo = getPlayerClubInfo(playerName, "I5");
  1870. ui.iron5LengthText->setText(QString::number(tmpInfo.clubLength));
  1871. ui.iron5LoftText->setText(QString::number(tmpInfo.clubLoft));
  1872. tmpInfo = getPlayerClubInfo(playerName, "I6");
  1873. ui.iron6LengthText->setText(QString::number(tmpInfo.clubLength));
  1874. ui.iron6LoftText->setText(QString::number(tmpInfo.clubLoft));
  1875. tmpInfo = getPlayerClubInfo(playerName, "I7");
  1876. ui.iron7LengthText->setText(QString::number(tmpInfo.clubLength));
  1877. ui.iron7LoftText->setText(QString::number(tmpInfo.clubLoft));
  1878. tmpInfo = getPlayerClubInfo(playerName, "I8");
  1879. ui.iron8LengthText->setText(QString::number(tmpInfo.clubLength));
  1880. ui.iron8LoftText->setText(QString::number(tmpInfo.clubLoft));
  1881. tmpInfo = getPlayerClubInfo(playerName, "I9");
  1882. ui.iron9LengthText->setText(QString::number(tmpInfo.clubLength));
  1883. ui.iron9LoftText->setText(QString::number(tmpInfo.clubLoft));
  1884. tmpInfo = getPlayerClubInfo(playerName, "PW");
  1885. ui.pWedgeLengthText->setText(QString::number(tmpInfo.clubLength));
  1886. ui.pWedgeLoftText->setText(QString::number(tmpInfo.clubLoft));
  1887. tmpInfo = getPlayerClubInfo(playerName, "SW");
  1888. ui.sWedgeLengthText->setText(QString::number(tmpInfo.clubLength));
  1889. ui.sWedgeLoftText->setText(QString::number(tmpInfo.clubLoft));
  1890. tmpInfo = getPlayerClubInfo(playerName, "LW");
  1891. ui.lWedgeLengthText->setText(QString::number(tmpInfo.clubLength));
  1892. ui.lWedgeLoftText->setText(QString::number(tmpInfo.clubLoft));
  1893. tmpInfo = getPlayerClubInfo(playerName, "W3");
  1894. ui.wood3LengthText->setText(QString::number(tmpInfo.clubLength));
  1895. ui.wood3LoftText->setText(QString::number(tmpInfo.clubLoft));
  1896. tmpInfo = getPlayerClubInfo(playerName, "W5");
  1897. ui.wood5LengthText->setText(QString::number(tmpInfo.clubLength));
  1898. ui.wood5LoftText->setText(QString::number(tmpInfo.clubLoft));
  1899. tmpInfo = getPlayerClubInfo(playerName, "DR");
  1900. ui.driverLengthText->setText(QString::number(tmpInfo.clubLength));
  1901. ui.driverLoftText->setText(QString::number(tmpInfo.clubLoft));
  1902. tmpInfo = getPlayerClubInfo(playerName, "PT");
  1903. ui.putterLengthText->setText(QString::number(tmpInfo.clubLength));
  1904. ui.putterLoftText->setText(QString::number(tmpInfo.clubLoft));
  1905. selectedBaseInfo = playerClubInfoList[playerName].baseInfo;
  1906. if (playerClubInfoList[playerName].baseInfo == "DEFAULT_ADULT")
  1907. {
  1908. ui.useAdultButton->setDisabled(1);
  1909. ui.useKidButton->setDisabled(0);
  1910. }
  1911. else
  1912. {
  1913. ui.useAdultButton->setDisabled(0);
  1914. ui.useKidButton->setDisabled(1);
  1915. }
  1916. if ((playerName == "DEFAULT_ADULT") || (playerName == "DEFAULT_KID"))
  1917. {
  1918. ui.useAdultButton->setVisible(false);
  1919. ui.useKidButton->setVisible(false);
  1920. }
  1921. else
  1922. {
  1923. ui.useAdultButton->setVisible(true);
  1924. ui.useKidButton->setVisible(true);
  1925. }
  1926. }
  1927. void launchBoxSim::displayPlayerClubInfoNewBase(QString playerName, QString newBase)
  1928. {
  1929. ClubInfo tmpInfo;
  1930. tmpInfo = getPlayerClubInfoNewBase(playerName, "I3", newBase);
  1931. ui.iron3LengthText->setText(QString::number(tmpInfo.clubLength));
  1932. ui.iron3LoftText->setText(QString::number(tmpInfo.clubLoft));
  1933. ui.hybrid3CheckBox->setChecked(tmpInfo.isHybrid);
  1934. tmpInfo = getPlayerClubInfoNewBase(playerName, "I4", newBase);
  1935. ui.iron4LengthText->setText(QString::number(tmpInfo.clubLength));
  1936. ui.iron4LoftText->setText(QString::number(tmpInfo.clubLoft));
  1937. ui.hybrid4CheckBox->setChecked(tmpInfo.isHybrid);
  1938. tmpInfo = getPlayerClubInfoNewBase(playerName, "I5", newBase);
  1939. ui.iron5LengthText->setText(QString::number(tmpInfo.clubLength));
  1940. ui.iron5LoftText->setText(QString::number(tmpInfo.clubLoft));
  1941. tmpInfo = getPlayerClubInfoNewBase(playerName, "I6", newBase);
  1942. ui.iron6LengthText->setText(QString::number(tmpInfo.clubLength));
  1943. ui.iron6LoftText->setText(QString::number(tmpInfo.clubLoft));
  1944. tmpInfo = getPlayerClubInfoNewBase(playerName, "I7", newBase);
  1945. ui.iron7LengthText->setText(QString::number(tmpInfo.clubLength));
  1946. ui.iron7LoftText->setText(QString::number(tmpInfo.clubLoft));
  1947. tmpInfo = getPlayerClubInfoNewBase(playerName, "I8", newBase);
  1948. ui.iron8LengthText->setText(QString::number(tmpInfo.clubLength));
  1949. ui.iron8LoftText->setText(QString::number(tmpInfo.clubLoft));
  1950. tmpInfo = getPlayerClubInfoNewBase(playerName, "I9", newBase);
  1951. ui.iron9LengthText->setText(QString::number(tmpInfo.clubLength));
  1952. ui.iron9LoftText->setText(QString::number(tmpInfo.clubLoft));
  1953. tmpInfo = getPlayerClubInfoNewBase(playerName, "PW", newBase);
  1954. ui.pWedgeLengthText->setText(QString::number(tmpInfo.clubLength));
  1955. ui.pWedgeLoftText->setText(QString::number(tmpInfo.clubLoft));
  1956. tmpInfo = getPlayerClubInfoNewBase(playerName, "SW", newBase);
  1957. ui.sWedgeLengthText->setText(QString::number(tmpInfo.clubLength));
  1958. ui.sWedgeLoftText->setText(QString::number(tmpInfo.clubLoft));
  1959. tmpInfo = getPlayerClubInfoNewBase(playerName, "LW", newBase);
  1960. ui.lWedgeLengthText->setText(QString::number(tmpInfo.clubLength));
  1961. ui.lWedgeLoftText->setText(QString::number(tmpInfo.clubLoft));
  1962. tmpInfo = getPlayerClubInfoNewBase(playerName, "W3", newBase);
  1963. ui.wood3LengthText->setText(QString::number(tmpInfo.clubLength));
  1964. ui.wood3LoftText->setText(QString::number(tmpInfo.clubLoft));
  1965. tmpInfo = getPlayerClubInfoNewBase(playerName, "W5", newBase);
  1966. ui.wood5LengthText->setText(QString::number(tmpInfo.clubLength));
  1967. ui.wood5LoftText->setText(QString::number(tmpInfo.clubLoft));
  1968. tmpInfo = getPlayerClubInfoNewBase(playerName, "DR", newBase);
  1969. ui.driverLengthText->setText(QString::number(tmpInfo.clubLength));
  1970. ui.driverLoftText->setText(QString::number(tmpInfo.clubLoft));
  1971. tmpInfo = getPlayerClubInfoNewBase(playerName, "PT", newBase);
  1972. ui.putterLengthText->setText(QString::number(tmpInfo.clubLength));
  1973. ui.putterLoftText->setText(QString::number(tmpInfo.clubLoft));
  1974. }
  1975. void launchBoxSim::playerListSelectPlayer(QString playerName)
  1976. {
  1977. if (playerName == "How To Add New Player And Manage Clubs ...")
  1978. {
  1979. QMessageBox mb;
  1980. mb.setWindowTitle("R-Motion");
  1981. QString tmpStr = "R-Motion application retrieves player names from The Golf Club game, therefore you can only add players here via the game interface.\n\n"
  1982. "Please add a player in the game and hit a ball, once the shot is registered, you can see the player name and start customizing clubs here. The application remembers the player name, therefore next time if you use the same player name, no action is necessary, your previously customized clubs will be used.\n\n"
  1983. "You can click Adult/Kid to set the initial club parameters and start customizing. Please note that the length is calculated from the head of the club to sensor. If you click Information, you can see how the measurement is done.\n\n";
  1984. mb.setText(tmpStr);
  1985. mb.exec();
  1986. ui.playerListSelectBox->setCurrentIndex(ui.playerListSelectBox->findText(selectedPlayerName));
  1987. return;
  1988. }
  1989. if (playerName == selectedPlayerName)
  1990. return;
  1991. if (needToSavePlayerClubInfoList == true)
  1992. {
  1993. needToSavePlayerClubInfoList = false;
  1994. selectedPlayerName = playerName;
  1995. displayPlayerClubInfo(selectedPlayerName);
  1996. ui.saveClubInfoButton->setDisabled(1);
  1997. }
  1998. else
  1999. {
  2000. selectedPlayerName = playerName;
  2001. displayPlayerClubInfo(selectedPlayerName);
  2002. }
  2003. }
  2004. void launchBoxSim::clubInfoTextEdited(QString tmpText)
  2005. {
  2006. needToSavePlayerClubInfoList = true;
  2007. ui.saveClubInfoButton->setDisabled(0);
  2008. }
  2009. void launchBoxSim::clickSaveClubInfo()
  2010. {
  2011. bool userInputValidate = validateUserInputLengthLoft();
  2012. if (userInputValidate == false)
  2013. {
  2014. QMessageBox mb;
  2015. mb.setWindowTitle("R-Motion");
  2016. mb.setText("Invalid club data detected in the table. Please double check your input.");
  2017. mb.setInformativeText("Clubs length and loft must be number.\n"
  2018. "Clubs length must be between 10 and 40 inches.\n"
  2019. "Clubs loft must be within 5 degrees deviated from the default value.\n");
  2020. mb.exec();
  2021. return;
  2022. }
  2023. // update player club info list on memory
  2024. playerClubInfoList[selectedPlayerName].playerName = selectedPlayerName;
  2025. playerClubInfoList[selectedPlayerName].baseInfo = selectedBaseInfo;
  2026. if ((playerClubInfoList[selectedBaseInfo].clubInfo["I3"].clubLength != ui.iron3LengthText->text().toFloat()) ||
  2027. (playerClubInfoList[selectedBaseInfo].clubInfo["I3"].clubLoft != ui.iron3LoftText->text().toFloat()) ||
  2028. (playerClubInfoList[selectedBaseInfo].clubInfo["I3"].isHybrid != ui.hybrid3CheckBox->isChecked()))
  2029. playerClubInfoList[selectedPlayerName].clubInfo["I3"] = { "IRON_3", ui.iron3LengthText->text().toFloat(), ui.iron3LoftText->text().toFloat(), ui.hybrid3CheckBox->isChecked() };
  2030. else
  2031. if ((selectedPlayerName != "DEFAULT_ADULT") && (selectedPlayerName != "DEFAULT_KID"))
  2032. playerClubInfoList[selectedPlayerName].clubInfo.remove("I3");
  2033. if ((playerClubInfoList[selectedBaseInfo].clubInfo["I4"].clubLength != ui.iron4LengthText->text().toFloat()) ||
  2034. (playerClubInfoList[selectedBaseInfo].clubInfo["I4"].clubLoft != ui.iron4LoftText->text().toFloat()) ||
  2035. (playerClubInfoList[selectedBaseInfo].clubInfo["I4"].isHybrid != ui.hybrid4CheckBox->isChecked()))
  2036. playerClubInfoList[selectedPlayerName].clubInfo["I4"] = { "IRON_4", ui.iron4LengthText->text().toFloat(), ui.iron4LoftText->text().toFloat(), ui.hybrid4CheckBox->isChecked() };
  2037. else
  2038. if ((selectedPlayerName != "DEFAULT_ADULT") && (selectedPlayerName != "DEFAULT_KID"))
  2039. playerClubInfoList[selectedPlayerName].clubInfo.remove("I4");
  2040. if ((playerClubInfoList[selectedBaseInfo].clubInfo["I5"].clubLength != ui.iron5LengthText->text().toFloat()) ||
  2041. (playerClubInfoList[selectedBaseInfo].clubInfo["I5"].clubLoft != ui.iron5LoftText->text().toFloat()))
  2042. playerClubInfoList[selectedPlayerName].clubInfo["I5"] = { "IRON_5", ui.iron5LengthText->text().toFloat(), ui.iron5LoftText->text().toFloat(), 0 };
  2043. else
  2044. if ((selectedPlayerName != "DEFAULT_ADULT") && (selectedPlayerName != "DEFAULT_KID"))
  2045. playerClubInfoList[selectedPlayerName].clubInfo.remove("I5");
  2046. if ((playerClubInfoList[selectedBaseInfo].clubInfo["I6"].clubLength != ui.iron6LengthText->text().toFloat()) ||
  2047. (playerClubInfoList[selectedBaseInfo].clubInfo["I6"].clubLoft != ui.iron6LoftText->text().toFloat()))
  2048. playerClubInfoList[selectedPlayerName].clubInfo["I6"] = { "IRON_6", ui.iron6LengthText->text().toFloat(), ui.iron6LoftText->text().toFloat(), 0 };
  2049. else
  2050. if ((selectedPlayerName != "DEFAULT_ADULT") && (selectedPlayerName != "DEFAULT_KID"))
  2051. playerClubInfoList[selectedPlayerName].clubInfo.remove("I6");
  2052. if ((playerClubInfoList[selectedBaseInfo].clubInfo["I7"].clubLength != ui.iron7LengthText->text().toFloat()) ||
  2053. (playerClubInfoList[selectedBaseInfo].clubInfo["I7"].clubLoft != ui.iron7LoftText->text().toFloat()))
  2054. playerClubInfoList[selectedPlayerName].clubInfo["I7"] = { "IRON_7", ui.iron7LengthText->text().toFloat(), ui.iron7LoftText->text().toFloat(), 0 };
  2055. else
  2056. if ((selectedPlayerName != "DEFAULT_ADULT") && (selectedPlayerName != "DEFAULT_KID"))
  2057. playerClubInfoList[selectedPlayerName].clubInfo.remove("I7");
  2058. if ((playerClubInfoList[selectedBaseInfo].clubInfo["I8"].clubLength != ui.iron8LengthText->text().toFloat()) ||
  2059. (playerClubInfoList[selectedBaseInfo].clubInfo["I8"].clubLoft != ui.iron8LoftText->text().toFloat()))
  2060. playerClubInfoList[selectedPlayerName].clubInfo["I8"] = { "IRON_8", ui.iron8LengthText->text().toFloat(), ui.iron8LoftText->text().toFloat(), 0 };
  2061. else
  2062. if ((selectedPlayerName != "DEFAULT_ADULT") && (selectedPlayerName != "DEFAULT_KID"))
  2063. playerClubInfoList[selectedPlayerName].clubInfo.remove("I8");
  2064. if ((playerClubInfoList[selectedBaseInfo].clubInfo["I9"].clubLength != ui.iron9LengthText->text().toFloat()) ||
  2065. (playerClubInfoList[selectedBaseInfo].clubInfo["I9"].clubLoft != ui.iron9LoftText->text().toFloat()))
  2066. playerClubInfoList[selectedPlayerName].clubInfo["I9"] = { "IRON_9", ui.iron9LengthText->text().toFloat(), ui.iron9LoftText->text().toFloat(), 0 };
  2067. else
  2068. if ((selectedPlayerName != "DEFAULT_ADULT") && (selectedPlayerName != "DEFAULT_KID"))
  2069. playerClubInfoList[selectedPlayerName].clubInfo.remove("I9");
  2070. if ((playerClubInfoList[selectedBaseInfo].clubInfo["PW"].clubLength != ui.pWedgeLengthText->text().toFloat()) ||
  2071. (playerClubInfoList[selectedBaseInfo].clubInfo["PW"].clubLoft != ui.pWedgeLoftText->text().toFloat()))
  2072. playerClubInfoList[selectedPlayerName].clubInfo["PW"] = { "PITCH_WEDGE", ui.pWedgeLengthText->text().toFloat(), ui.pWedgeLoftText->text().toFloat(), 0 };
  2073. else
  2074. if ((selectedPlayerName != "DEFAULT_ADULT") && (selectedPlayerName != "DEFAULT_KID"))
  2075. playerClubInfoList[selectedPlayerName].clubInfo.remove("PW");
  2076. if ((playerClubInfoList[selectedBaseInfo].clubInfo["SW"].clubLength != ui.sWedgeLengthText->text().toFloat()) ||
  2077. (playerClubInfoList[selectedBaseInfo].clubInfo["SW"].clubLoft != ui.sWedgeLoftText->text().toFloat()))
  2078. playerClubInfoList[selectedPlayerName].clubInfo["SW"] = { "SAND_WEDGE", ui.sWedgeLengthText->text().toFloat(), ui.sWedgeLoftText->text().toFloat(), 0 };
  2079. else
  2080. if ((selectedPlayerName != "DEFAULT_ADULT") && (selectedPlayerName != "DEFAULT_KID"))
  2081. playerClubInfoList[selectedPlayerName].clubInfo.remove("SW");
  2082. if ((playerClubInfoList[selectedBaseInfo].clubInfo["LW"].clubLength != ui.lWedgeLengthText->text().toFloat()) ||
  2083. (playerClubInfoList[selectedBaseInfo].clubInfo["LW"].clubLoft != ui.lWedgeLoftText->text().toFloat()))
  2084. playerClubInfoList[selectedPlayerName].clubInfo["LW"] = { "LOFT_WEDGE", ui.lWedgeLengthText->text().toFloat(), ui.lWedgeLoftText->text().toFloat(), 0 };
  2085. else
  2086. if ((selectedPlayerName != "DEFAULT_ADULT") && (selectedPlayerName != "DEFAULT_KID"))
  2087. playerClubInfoList[selectedPlayerName].clubInfo.remove("LW");
  2088. if ((playerClubInfoList[selectedBaseInfo].clubInfo["W3"].clubLength != ui.wood3LengthText->text().toFloat()) ||
  2089. (playerClubInfoList[selectedBaseInfo].clubInfo["W3"].clubLoft != ui.wood3LoftText->text().toFloat()))
  2090. playerClubInfoList[selectedPlayerName].clubInfo["W3"] = { "WOOD_3", ui.wood3LengthText->text().toFloat(), ui.wood3LoftText->text().toFloat(), 0 };
  2091. else
  2092. if ((selectedPlayerName != "DEFAULT_ADULT") && (selectedPlayerName != "DEFAULT_KID"))
  2093. playerClubInfoList[selectedPlayerName].clubInfo.remove("W3");
  2094. if ((playerClubInfoList[selectedBaseInfo].clubInfo["W5"].clubLength != ui.wood5LengthText->text().toFloat()) ||
  2095. (playerClubInfoList[selectedBaseInfo].clubInfo["W5"].clubLoft != ui.wood5LoftText->text().toFloat()))
  2096. playerClubInfoList[selectedPlayerName].clubInfo["W5"] = { "WOOD_5", ui.wood5LengthText->text().toFloat(), ui.wood5LoftText->text().toFloat(), 0 };
  2097. else
  2098. if ((selectedPlayerName != "DEFAULT_ADULT") && (selectedPlayerName != "DEFAULT_KID"))
  2099. playerClubInfoList[selectedPlayerName].clubInfo.remove("W5");
  2100. if ((playerClubInfoList[selectedBaseInfo].clubInfo["DR"].clubLength != ui.driverLengthText->text().toFloat()) ||
  2101. (playerClubInfoList[selectedBaseInfo].clubInfo["DR"].clubLoft != ui.driverLoftText->text().toFloat()))
  2102. playerClubInfoList[selectedPlayerName].clubInfo["DR"] = { "DRIVER", ui.driverLengthText->text().toFloat(), ui.driverLoftText->text().toFloat(), 0 };
  2103. else
  2104. if ((selectedPlayerName != "DEFAULT_ADULT") && (selectedPlayerName != "DEFAULT_KID"))
  2105. playerClubInfoList[selectedPlayerName].clubInfo.remove("DR");
  2106. if ((playerClubInfoList[selectedBaseInfo].clubInfo["PT"].clubLength != ui.putterLengthText->text().toFloat()) ||
  2107. (playerClubInfoList[selectedBaseInfo].clubInfo["PT"].clubLoft != ui.putterLoftText->text().toFloat()))
  2108. playerClubInfoList[selectedPlayerName].clubInfo["PT"] = { "PUTTER", ui.putterLengthText->text().toFloat(), ui.putterLoftText->text().toFloat(), 0 };
  2109. else
  2110. if ((selectedPlayerName != "DEFAULT_ADULT") && (selectedPlayerName != "DEFAULT_KID"))
  2111. playerClubInfoList[selectedPlayerName].clubInfo.remove("PT");
  2112. // save the data into file
  2113. savePlayerClubInfoList();
  2114. ui.saveClubInfoButton->setDisabled(1);
  2115. // resend ARM command if club info is changed in the middle of playing
  2116. if ((curPlayerName != "") && (curClubType != "") && (box->bleConnectionStatus == 1))
  2117. {
  2118. ClubInfo clubInfo = getPlayerClubInfo(curPlayerName, curClubType);
  2119. emit uiChangePlayingMode(curPlayerHand, curClubType, 1.0f, settingsBallType, settingsKidMode,
  2120. clubInfo.clubLength, clubInfo.clubLoft, clubInfo.isHybrid);
  2121. }
  2122. QMessageBox tmpBox;
  2123. tmpBox.setWindowTitle("R-Motion");
  2124. tmpBox.setText("Changes in club information for player " + selectedPlayerName + " is saved.");
  2125. tmpBox.exec();
  2126. }
  2127. void launchBoxSim::changeToUseAdult()
  2128. {
  2129. if ((selectedPlayerName != "DEFAULT_ADULT") && (selectedPlayerName != "DEFAULT_KID"))
  2130. {
  2131. selectedBaseInfo = "DEFAULT_ADULT";
  2132. ui.useAdultButton->setDisabled(1);
  2133. ui.useKidButton->setDisabled(0);
  2134. displayPlayerClubInfoNewBase(selectedPlayerName, selectedBaseInfo);
  2135. needToSavePlayerClubInfoList = true;
  2136. ui.saveClubInfoButton->setDisabled(0);
  2137. }
  2138. else
  2139. {
  2140. QMessageBox msgBox;
  2141. msgBox.setWindowTitle("R-Motion");
  2142. msgBox.setText("You cannot change the base profile of default players.");
  2143. msgBox.exec();
  2144. }
  2145. }
  2146. void launchBoxSim::changeToUseKid()
  2147. {
  2148. if ((selectedPlayerName != "DEFAULT_ADULT") && (selectedPlayerName != "DEFAULT_KID"))
  2149. {
  2150. selectedBaseInfo = "DEFAULT_KID";
  2151. ui.useAdultButton->setDisabled(0);
  2152. ui.useKidButton->setDisabled(1);
  2153. displayPlayerClubInfoNewBase(selectedPlayerName, selectedBaseInfo);
  2154. needToSavePlayerClubInfoList = true;
  2155. ui.saveClubInfoButton->setDisabled(0);
  2156. }
  2157. else
  2158. {
  2159. QMessageBox msgBox;
  2160. msgBox.setWindowTitle("R-Motion");
  2161. msgBox.setText("You cannot change the base profile of default players.");
  2162. msgBox.exec();
  2163. }
  2164. }
  2165. void launchBoxSim::clickDefaultClubButton()
  2166. {
  2167. if (selectedPlayerName == "DEFAULT_ADULT")
  2168. {
  2169. // fill all the text field with built-in club information
  2170. ui.iron3LengthText->setText(QString::number(27.6));
  2171. ui.iron3LoftText->setText(QString::number(23));
  2172. ui.hybrid3CheckBox->setChecked(false);
  2173. ui.iron4LengthText->setText(QString::number(27.1));
  2174. ui.iron4LoftText->setText(QString::number(25));
  2175. ui.hybrid4CheckBox->setChecked(false);
  2176. ui.iron5LengthText->setText(QString::number(26.6));
  2177. ui.iron5LoftText->setText(QString::number(27));
  2178. ui.iron6LengthText->setText(QString::number(26.1));
  2179. ui.iron6LoftText->setText(QString::number(31));
  2180. ui.iron7LengthText->setText(QString::number(25.6));
  2181. ui.iron7LoftText->setText(QString::number(35));
  2182. ui.iron8LengthText->setText(QString::number(25.1));
  2183. ui.iron8LoftText->setText(QString::number(39));
  2184. ui.iron9LengthText->setText(QString::number(24.6));
  2185. ui.iron9LoftText->setText(QString::number(43));
  2186. ui.pWedgeLengthText->setText(QString::number(24.6));
  2187. ui.pWedgeLoftText->setText(QString::number(47));
  2188. ui.sWedgeLengthText->setText(QString::number(24.6));
  2189. ui.sWedgeLoftText->setText(QString::number(55));
  2190. ui.lWedgeLengthText->setText(QString::number(24.6));
  2191. ui.lWedgeLoftText->setText(QString::number(60));
  2192. ui.wood3LengthText->setText(QString::number(30.5));
  2193. ui.wood3LoftText->setText(QString::number(17));
  2194. ui.wood5LengthText->setText(QString::number(29.5));
  2195. ui.wood5LoftText->setText(QString::number(23));
  2196. ui.driverLengthText->setText(QString::number(31.9));
  2197. ui.driverLoftText->setText(QString::number(12));
  2198. ui.putterLengthText->setText(QString::number(23.8));
  2199. ui.putterLoftText->setText(QString::number(0.1));
  2200. }
  2201. else if (selectedPlayerName == "DEFAULT_KID")
  2202. {
  2203. // fill all the text field with built-in club information
  2204. ui.iron3LengthText->setText(QString::number(25.0));
  2205. ui.iron3LoftText->setText(QString::number(23));
  2206. ui.hybrid3CheckBox->setChecked(false);
  2207. ui.iron4LengthText->setText(QString::number(24.0));
  2208. ui.iron4LoftText->setText(QString::number(25));
  2209. ui.hybrid4CheckBox->setChecked(false);
  2210. ui.iron5LengthText->setText(QString::number(23.0));
  2211. ui.iron5LoftText->setText(QString::number(27));
  2212. ui.iron6LengthText->setText(QString::number(22.0));
  2213. ui.iron6LoftText->setText(QString::number(31));
  2214. ui.iron7LengthText->setText(QString::number(21.1));
  2215. ui.iron7LoftText->setText(QString::number(35));
  2216. ui.iron8LengthText->setText(QString::number(19.1));
  2217. ui.iron8LoftText->setText(QString::number(39));
  2218. ui.iron9LengthText->setText(QString::number(18.1));
  2219. ui.iron9LoftText->setText(QString::number(43));
  2220. ui.pWedgeLengthText->setText(QString::number(18.1));
  2221. ui.pWedgeLoftText->setText(QString::number(47));
  2222. ui.sWedgeLengthText->setText(QString::number(18.1));
  2223. ui.sWedgeLoftText->setText(QString::number(55));
  2224. ui.lWedgeLengthText->setText(QString::number(18.1));
  2225. ui.lWedgeLoftText->setText(QString::number(60));
  2226. ui.wood3LengthText->setText(QString::number(25.6));
  2227. ui.wood3LoftText->setText(QString::number(17));
  2228. ui.wood5LengthText->setText(QString::number(24.6));
  2229. ui.wood5LoftText->setText(QString::number(23));
  2230. ui.driverLengthText->setText(QString::number(26.6));
  2231. ui.driverLoftText->setText(QString::number(11));
  2232. ui.putterLengthText->setText(QString::number(18.1));
  2233. ui.putterLoftText->setText(QString::number(0.1));
  2234. }
  2235. else
  2236. {
  2237. // simply fill all the text field with default club information from the selected base
  2238. displayPlayerClubInfoNewBase(selectedBaseInfo, selectedBaseInfo);
  2239. }
  2240. ui.saveClubInfoButton->setDisabled(0);
  2241. }
  2242. void launchBoxSim::toggleClubLengthExplanation()
  2243. {
  2244. if (ui.clubLengthExplanation->isVisible())
  2245. ui.clubLengthExplanation->setVisible(false);
  2246. else
  2247. ui.clubLengthExplanation->setVisible(true);
  2248. }
  2249. bool launchBoxSim::validateUserInputLengthLoft()
  2250. {
  2251. bool convertRes;
  2252. float userLength;
  2253. float userLoft, defaultLoft;
  2254. userLength = ui.iron3LengthText->text().toFloat(&convertRes);
  2255. if ((convertRes == false) || (userLength < 10) || (userLength > 40))
  2256. return false;
  2257. userLength = ui.iron4LengthText->text().toFloat(&convertRes);
  2258. if ((convertRes == false) || (userLength < 10) || (userLength > 40))
  2259. return false;
  2260. userLength = ui.iron5LengthText->text().toFloat(&convertRes);
  2261. if ((convertRes == false) || (userLength < 10) || (userLength > 40))
  2262. return false;
  2263. userLength = ui.iron6LengthText->text().toFloat(&convertRes);
  2264. if ((convertRes == false) || (userLength < 10) || (userLength > 40))
  2265. return false;
  2266. userLength = ui.iron7LengthText->text().toFloat(&convertRes);
  2267. if ((convertRes == false) || (userLength < 10) || (userLength > 40))
  2268. return false;
  2269. userLength = ui.iron8LengthText->text().toFloat(&convertRes);
  2270. if ((convertRes == false) || (userLength < 10) || (userLength > 40))
  2271. return false;
  2272. userLength = ui.iron9LengthText->text().toFloat(&convertRes);
  2273. if ((convertRes == false) || (userLength < 10) || (userLength > 40))
  2274. return false;
  2275. userLength = ui.pWedgeLengthText->text().toFloat(&convertRes);
  2276. if ((convertRes == false) || (userLength < 10) || (userLength > 40))
  2277. return false;
  2278. userLength = ui.sWedgeLengthText->text().toFloat(&convertRes);
  2279. if ((convertRes == false) || (userLength < 10) || (userLength > 40))
  2280. return false;
  2281. userLength = ui.lWedgeLengthText->text().toFloat(&convertRes);
  2282. if ((convertRes == false) || (userLength < 10) || (userLength > 40))
  2283. return false;
  2284. userLength = ui.wood3LengthText->text().toFloat(&convertRes);
  2285. if ((convertRes == false) || (userLength < 10) || (userLength > 40))
  2286. return false;
  2287. userLength = ui.wood5LengthText->text().toFloat(&convertRes);
  2288. if ((convertRes == false) || (userLength < 10) || (userLength > 40))
  2289. return false;
  2290. userLength = ui.driverLengthText->text().toFloat(&convertRes);
  2291. if ((convertRes == false) || (userLength < 10) || (userLength > 40))
  2292. return false;
  2293. userLength = ui.putterLengthText->text().toFloat(&convertRes);
  2294. if ((convertRes == false) || (userLength < 10) || (userLength > 40))
  2295. return false;
  2296. userLoft = ui.iron3LoftText->text().toFloat(&convertRes);
  2297. if (convertRes == false)
  2298. return false;
  2299. defaultLoft = getPlayerClubInfo(selectedPlayerName, "I3").clubLoft;
  2300. if ((userLoft < (defaultLoft - 5)) || (userLoft > (defaultLoft + 5)))
  2301. return false;
  2302. userLoft = ui.iron4LoftText->text().toFloat(&convertRes);
  2303. if (convertRes == false)
  2304. return false;
  2305. defaultLoft = getPlayerClubInfo(selectedPlayerName, "I4").clubLoft;
  2306. if ((userLoft < (defaultLoft - 5)) || (userLoft >(defaultLoft + 5)))
  2307. return false;
  2308. userLoft = ui.iron5LoftText->text().toFloat(&convertRes);
  2309. if (convertRes == false)
  2310. return false;
  2311. defaultLoft = getPlayerClubInfo(selectedPlayerName, "I5").clubLoft;
  2312. if ((userLoft < (defaultLoft - 5)) || (userLoft >(defaultLoft + 5)))
  2313. return false;
  2314. userLoft = ui.iron6LoftText->text().toFloat(&convertRes);
  2315. if (convertRes == false)
  2316. return false;
  2317. defaultLoft = getPlayerClubInfo(selectedPlayerName, "I6").clubLoft;
  2318. if ((userLoft < (defaultLoft - 5)) || (userLoft >(defaultLoft + 5)))
  2319. return false;
  2320. userLoft = ui.iron7LoftText->text().toFloat(&convertRes);
  2321. if (convertRes == false)
  2322. return false;
  2323. defaultLoft = getPlayerClubInfo(selectedPlayerName, "I7").clubLoft;
  2324. if ((userLoft < (defaultLoft - 5)) || (userLoft >(defaultLoft + 5)))
  2325. return false;
  2326. userLoft = ui.iron8LoftText->text().toFloat(&convertRes);
  2327. if (convertRes == false)
  2328. return false;
  2329. defaultLoft = getPlayerClubInfo(selectedPlayerName, "I8").clubLoft;
  2330. if ((userLoft < (defaultLoft - 5)) || (userLoft >(defaultLoft + 5)))
  2331. return false;
  2332. userLoft = ui.iron9LoftText->text().toFloat(&convertRes);
  2333. if (convertRes == false)
  2334. return false;
  2335. defaultLoft = getPlayerClubInfo(selectedPlayerName, "I9").clubLoft;
  2336. if ((userLoft < (defaultLoft - 5)) || (userLoft >(defaultLoft + 5)))
  2337. return false;
  2338. userLoft = ui.pWedgeLoftText->text().toFloat(&convertRes);
  2339. if (convertRes == false)
  2340. return false;
  2341. defaultLoft = getPlayerClubInfo(selectedPlayerName, "PW").clubLoft;
  2342. if ((userLoft < (defaultLoft - 5)) || (userLoft >(defaultLoft + 5)))
  2343. return false;
  2344. userLoft = ui.sWedgeLoftText->text().toFloat(&convertRes);
  2345. if (convertRes == false)
  2346. return false;
  2347. defaultLoft = getPlayerClubInfo(selectedPlayerName, "SW").clubLoft;
  2348. if ((userLoft < (defaultLoft - 5)) || (userLoft >(defaultLoft + 5)))
  2349. return false;
  2350. userLoft = ui.lWedgeLoftText->text().toFloat(&convertRes);
  2351. if (convertRes == false)
  2352. return false;
  2353. defaultLoft = getPlayerClubInfo(selectedPlayerName, "LW").clubLoft;
  2354. if ((userLoft < (defaultLoft - 5)) || (userLoft >(defaultLoft + 5)))
  2355. return false;
  2356. userLoft = ui.wood3LoftText->text().toFloat(&convertRes);
  2357. if (convertRes == false)
  2358. return false;
  2359. defaultLoft = getPlayerClubInfo(selectedPlayerName, "W3").clubLoft;
  2360. if ((userLoft < (defaultLoft - 5)) || (userLoft >(defaultLoft + 5)))
  2361. return false;
  2362. userLoft = ui.wood5LoftText->text().toFloat(&convertRes);
  2363. if (convertRes == false)
  2364. return false;
  2365. defaultLoft = getPlayerClubInfo(selectedPlayerName, "W5").clubLoft;
  2366. if ((userLoft < (defaultLoft - 5)) || (userLoft >(defaultLoft + 5)))
  2367. return false;
  2368. userLoft = ui.driverLoftText->text().toFloat(&convertRes);
  2369. if (convertRes == false)
  2370. return false;
  2371. defaultLoft = getPlayerClubInfo(selectedPlayerName, "DR").clubLoft;
  2372. if ((userLoft < (defaultLoft - 5)) || (userLoft >(defaultLoft + 5)))
  2373. return false;
  2374. userLoft = ui.putterLoftText->text().toFloat(&convertRes);
  2375. if (convertRes == false)
  2376. return false;
  2377. defaultLoft = getPlayerClubInfo(selectedPlayerName, "PT").clubLoft;
  2378. if ((userLoft < (defaultLoft - 5)) || (userLoft >(defaultLoft + 5)))
  2379. return false;
  2380. return true;
  2381. }
  2382. void launchBoxSim::clickHybridClubNoticeButton()
  2383. {
  2384. QMessageBox tmpBox;
  2385. tmpBox.setWindowTitle("R-Motion");
  2386. tmpBox.setText("Please click on the button besides the club to switch between Iron (I) and Hybrid (H) club.");
  2387. tmpBox.exec();
  2388. }
  2389. void launchBoxSim::hybridCheckBoxChanged()
  2390. {
  2391. needToSavePlayerClubInfoList = true;
  2392. ui.saveClubInfoButton->setDisabled(0);
  2393. }
  2394. void launchBoxSim::scanForRmotion()
  2395. {
  2396. if ((box->dongleStatus == 1) && (box->bleConnectionStatus == 0) && (scanningInProgress == 0))
  2397. {
  2398. scanningInProgress = 1;
  2399. QMovie *swirlingMovie = new QMovie(":/launchBoxSim/images/swirling.gif");
  2400. swirlingMovie->setScaledSize(QSize(26, 27));
  2401. swirlingMovie->setSpeed(80);
  2402. ui.deviceStatusLabel->setMovie(swirlingMovie);
  2403. swirlingMovie->start();
  2404. ui.deviceStatusLabel->show();
  2405. deviceList.clear();
  2406. ui.deviceListSelectBox->clear();
  2407. ui.deviceListSelectBox->hide();
  2408. emit uiStartScanning();
  2409. }
  2410. }
  2411. void launchBoxSim::scanForGameStatus()
  2412. {
  2413. QMovie *swirlingMovie = new QMovie(":/launchBoxSim/images/swirling.gif");
  2414. swirlingMovie->setScaledSize(QSize(26, 27));
  2415. swirlingMovie->setSpeed(80);
  2416. ui.gameServerStatusLabel->setMovie(swirlingMovie);
  2417. swirlingMovie->start();
  2418. ui.gameServerStatusLabel->show();
  2419. }
  2420. void launchBoxSim::notShowCheckBoxChanged(int state)
  2421. {
  2422. if (state == Qt::Checked)
  2423. savedData->setValue("ui/notShowHelpStartUp", QVariant(1));
  2424. else
  2425. savedData->setValue("ui/notShowHelpStartUp", QVariant(0));
  2426. }
  2427. void launchBoxSim::nextSlideClicked()
  2428. {
  2429. if (curHelpSlide < 5)
  2430. {
  2431. curHelpSlide++;
  2432. ui.stackedWidget->setCurrentIndex(2);
  2433. QString imagePath = ":/launchBoxSim/images/helpSkeleton" + QString::number(curHelpSlide) + ".png";
  2434. QPixmap pixmap(imagePath);
  2435. this->setFixedSize(pixmap.width(), pixmap.height());
  2436. QPalette palette;
  2437. palette.setBrush(QPalette::Background, pixmap);
  2438. this->setPalette(palette);
  2439. ui.prevSlideButton->setDisabled(0);
  2440. if (curHelpSlide == 5)
  2441. ui.nextSlideButton->setStyleSheet("QPushButton{border-image: url(:/launchBoxSim/images/nextButtonDone.png); outline: none; }");
  2442. }
  2443. else
  2444. {
  2445. if (userLoginStatus == 0)
  2446. clickedOkLogin();
  2447. else if (userLicenseStatus == 0)
  2448. goToLicenseRequest();
  2449. else
  2450. clickedOkDashBoard();
  2451. }
  2452. }
  2453. void launchBoxSim::prevSlideClicked()
  2454. {
  2455. curHelpSlide--;
  2456. ui.stackedWidget->setCurrentIndex(2);
  2457. QString imagePath = ":/launchBoxSim/images/helpSkeleton" + QString::number(curHelpSlide) + ".png";
  2458. QPixmap pixmap(imagePath);
  2459. this->setFixedSize(pixmap.width(), pixmap.height());
  2460. QPalette palette;
  2461. palette.setBrush(QPalette::Background, pixmap);
  2462. this->setPalette(palette);
  2463. ui.nextSlideButton->setStyleSheet("QPushButton{border-image: url(:/launchBoxSim/images/nextButton.png); outline: none; }");
  2464. if (curHelpSlide == 1)
  2465. ui.prevSlideButton->setDisabled(1);
  2466. }
  2467. void launchBoxSim::shotSyncFunc()
  2468. {
  2469. QList<playerDatabaseEntry> listOfPlayers;
  2470. int numOfPlayers = shotDatabase->retrieveAllPlayers(listOfPlayers);
  2471. if ((numOfPlayers <= 0) || (listOfPlayers.isEmpty()))
  2472. return;
  2473. syncingPlayer = listOfPlayers.first();
  2474. QByteArray dataToSync;
  2475. int numOfShots = shotDatabase->retrieveAllPlayerShots(syncingPlayer, dataToSync);
  2476. if (numOfShots <= 0) // should not happen
  2477. return;
  2478. QUrl dataSyncUrl("http://rmotion.rapsodo.com/api/push/new");
  2479. QNetworkRequest dataSyncRequest;
  2480. dataSyncRequest.setUrl(dataSyncUrl);
  2481. dataSyncRequest.setAttribute(QNetworkRequest::User, QVariant("dataSyncRequest"));
  2482. dataSyncRequest.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
  2483. qDebug() << "Syncing shot data for email" << syncingPlayer.loginName;
  2484. networkManager->post(dataSyncRequest, dataToSync);
  2485. }