Open Source Snapmatic picture and Savegame viewer/editor for GTA V https://gta5view.syping.de/

main.cpp 12KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332
  1. /*****************************************************************************
  2. * gta5view Grand Theft Auto V Profile Viewer
  3. * Copyright (C) 2016-2018 Syping
  4. *
  5. * This program is free software: you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation, either version 3 of the License, or
  8. * (at your option) any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License
  16. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. *****************************************************************************/
  18. #include "TranslationClass.h"
  19. #include "SnapmaticPicture.h"
  20. #include "ProfileDatabase.h"
  21. #include "DatabaseThread.h"
  22. #include "SavegameDialog.h"
  23. #include "OptionsDialog.h"
  24. #include "PictureDialog.h"
  25. #include "UserInterface.h"
  26. #include "CrewDatabase.h"
  27. #include "SavegameData.h"
  28. #include "UiModWidget.h"
  29. #include "UiModLabel.h"
  30. #include "IconLoader.h"
  31. #include "AppEnv.h"
  32. #include "config.h"
  33. #include <QDesktopWidget>
  34. #include <QStringBuilder>
  35. #include <QSignalMapper>
  36. #include <QStyleFactory>
  37. #include <QApplication>
  38. #include <QPushButton>
  39. #include <QSpacerItem>
  40. #include <QVBoxLayout>
  41. #include <QHBoxLayout>
  42. #include <QMessageBox>
  43. #include <QStringList>
  44. #include <QTranslator>
  45. #include <QResource>
  46. #include <QCheckBox>
  47. #include <QFileInfo>
  48. #include <QSysInfo>
  49. #include <QLayout>
  50. #include <QObject>
  51. #include <QString>
  52. #include <QDebug>
  53. #include <QFont>
  54. #include <QFile>
  55. #ifdef GTA5SYNC_WIN
  56. #include "windows.h"
  57. #include <iostream>
  58. #endif
  59. #ifdef GTA5SYNC_TELEMETRY
  60. #include "TelemetryClass.h"
  61. #endif
  62. #ifdef GTA5SYNC_DONATION
  63. #include "DonationDialog.h"
  64. #endif
  65. int main(int argc, char *argv[])
  66. {
  67. QApplication a(argc, argv);
  68. a.setApplicationName(GTA5SYNC_APPSTR);
  69. a.setApplicationVersion(GTA5SYNC_APPVER);
  70. a.setQuitOnLastWindowClosed(false);
  71. QResource::registerResource(":/global/global.rcc");
  72. QSettings settings(GTA5SYNC_APPVENDOR, GTA5SYNC_APPSTR);
  73. settings.beginGroup("Startup");
  74. #ifdef GTA5SYNC_TELEMETRY
  75. // Increase Start count at every startup
  76. uint startCount = settings.value("StartCount", 0).toUInt();
  77. startCount++;
  78. settings.setValue("StartCount", startCount);
  79. settings.sync();
  80. #endif
  81. bool isFirstStart = settings.value("IsFirstStart", true).toBool();
  82. bool customStyle = settings.value("CustomStyle", false).toBool();
  83. QString appStyle = settings.value("AppStyle", "Default").toString();
  84. if (customStyle)
  85. {
  86. if (QStyleFactory::keys().contains(appStyle, Qt::CaseInsensitive))
  87. {
  88. a.setStyle(QStyleFactory::create(appStyle));
  89. }
  90. }
  91. #ifdef GTA5SYNC_WIN
  92. #if QT_VERSION >= 0x050400
  93. bool alwaysUseMessageFont = settings.value("AlwaysUseMessageFont", false).toBool();
  94. if (QSysInfo::windowsVersion() >= 0x0080 || alwaysUseMessageFont)
  95. {
  96. // Get Windows Font
  97. NONCLIENTMETRICS ncm;
  98. ncm.cbSize = sizeof(ncm);
  99. SystemParametersInfo(SPI_GETNONCLIENTMETRICS, ncm.cbSize, &ncm, 0);
  100. LOGFONTW uiFont = ncm.lfMessageFont;
  101. QString uiFontStr(QString::fromStdWString(std::wstring(uiFont.lfFaceName)));
  102. #ifdef GTA5SYNC_DEBUG
  103. qDebug() << QApplication::tr("Font") << QApplication::tr("Selected Font: %1").arg(uiFontStr);
  104. #endif
  105. // Set Application Font
  106. QFont appFont(uiFontStr, 9);
  107. a.setFont(appFont);
  108. }
  109. #endif
  110. #endif
  111. QStringList applicationArgs = a.arguments();
  112. QString selectedAction;
  113. QString arg1;
  114. applicationArgs.removeAt(0);
  115. Translator->initUserLanguage();
  116. Translator->loadTranslation(&a);
  117. #ifdef GTA5SYNC_TELEMETRY
  118. Telemetry->init();
  119. Telemetry->work();
  120. #endif
  121. if (!applicationArgs.contains("--skip-firststart"))
  122. {
  123. if (isFirstStart)
  124. {
  125. QMessageBox::StandardButton button = QMessageBox::information(a.desktop(), QString("%1 %2").arg(GTA5SYNC_APPSTR, GTA5SYNC_APPVER), QApplication::tr("<h4>Welcome to %1!</h4>You want to configure %1 before you start using it?").arg(GTA5SYNC_APPSTR), QMessageBox::Yes | QMessageBox::No, QMessageBox::No);
  126. if (button == QMessageBox::Yes)
  127. {
  128. ProfileDatabase profileDB;
  129. OptionsDialog optionsDialog(&profileDB);
  130. optionsDialog.setWindowIcon(IconLoader::loadingAppIcon());
  131. optionsDialog.show();
  132. optionsDialog.exec();
  133. }
  134. settings.setValue("IsFirstStart", false);
  135. }
  136. }
  137. #ifdef GTA5SYNC_TELEMETRY
  138. bool telemetryWindowLaunched = settings.value("PersonalUsageDataWindowLaunched", false).toBool();
  139. bool pushUsageData = settings.value("PushUsageData", false).toBool();
  140. if (!telemetryWindowLaunched && !pushUsageData)
  141. {
  142. QDialog *telemetryDialog = new QDialog();
  143. telemetryDialog->setObjectName(QStringLiteral("TelemetryDialog"));
  144. telemetryDialog->setWindowTitle(QString("%1 %2").arg(GTA5SYNC_APPSTR, GTA5SYNC_APPVER));
  145. telemetryDialog->setWindowFlags(telemetryDialog->windowFlags()^Qt::WindowContextHelpButtonHint^Qt::WindowCloseButtonHint);
  146. telemetryDialog->setWindowIcon(IconLoader::loadingAppIcon());
  147. QVBoxLayout *telemetryLayout = new QVBoxLayout(telemetryDialog);
  148. telemetryLayout->setObjectName(QStringLiteral("TelemetryLayout"));
  149. telemetryDialog->setLayout(telemetryLayout);
  150. UiModLabel *telemetryLabel = new UiModLabel(telemetryDialog);
  151. telemetryLabel->setObjectName(QStringLiteral("TelemetryLabel"));
  152. telemetryLabel->setText(QString("<h4>%2</h4>%1").arg(
  153. QApplication::translate("TelemetryDialog", "You want help %1 to improve in the future by including personal usage data in your submission?").arg(GTA5SYNC_APPSTR),
  154. QApplication::translate("TelemetryDialog", "%1 User Statistics").arg(GTA5SYNC_APPSTR)));
  155. telemetryLayout->addWidget(telemetryLabel);
  156. QCheckBox *telemetryCheckBox = new QCheckBox(telemetryDialog);
  157. telemetryCheckBox->setObjectName(QStringLiteral("TelemetryCheckBox"));
  158. telemetryCheckBox->setText(QApplication::translate("TelemetryDialog", "Yes, I want include personal usage data."));
  159. telemetryLayout->addWidget(telemetryCheckBox);
  160. QHBoxLayout *telemetryButtonLayout = new QHBoxLayout();
  161. telemetryButtonLayout->setObjectName(QStringLiteral("TelemetryButtonLayout"));
  162. telemetryLayout->addLayout(telemetryButtonLayout);
  163. QSpacerItem *telemetryButtonSpacer = new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum);
  164. telemetryButtonLayout->addSpacerItem(telemetryButtonSpacer);
  165. QPushButton *telemetryButton = new QPushButton(telemetryDialog);
  166. telemetryButton->setObjectName(QStringLiteral("TelemetryButton"));
  167. telemetryButton->setText(QApplication::translate("TelemetryDialog", "&OK"));
  168. telemetryButtonLayout->addWidget(telemetryButton);
  169. QObject::connect(telemetryButton, SIGNAL(clicked(bool)), telemetryDialog, SLOT(close()));
  170. telemetryDialog->setFixedSize(telemetryDialog->sizeHint());
  171. telemetryDialog->exec();
  172. QObject::disconnect(telemetryButton, SIGNAL(clicked(bool)), telemetryDialog, SLOT(close()));
  173. if (telemetryCheckBox->isChecked())
  174. {
  175. QSettings telemetrySettings(GTA5SYNC_APPVENDOR, GTA5SYNC_APPSTR);
  176. telemetrySettings.beginGroup("Telemetry");
  177. telemetrySettings.setValue("PushUsageData", true);
  178. telemetrySettings.setValue("PushAppConf", true);
  179. telemetrySettings.endGroup();
  180. telemetrySettings.sync();
  181. Telemetry->init();
  182. Telemetry->work();
  183. }
  184. settings.setValue("PersonalUsageDataWindowLaunched", true);
  185. delete telemetryDialog;
  186. }
  187. #endif
  188. settings.endGroup();
  189. for (QString currentArg : applicationArgs)
  190. {
  191. QString reworkedArg;
  192. if (currentArg.left(9) == "-showpic=" && selectedAction == "")
  193. {
  194. reworkedArg = currentArg.remove(0,9);
  195. arg1 = reworkedArg;
  196. selectedAction = "showpic";
  197. }
  198. else if (currentArg.left(9) == "-showsgd=" && selectedAction == "")
  199. {
  200. reworkedArg = currentArg.remove(0,9);
  201. arg1 = reworkedArg;
  202. selectedAction = "showsgd";
  203. }
  204. else if (selectedAction == "")
  205. {
  206. QFile argumentFile(currentArg);
  207. QFileInfo argumentFileInfo(argumentFile);
  208. if (argumentFile.exists())
  209. {
  210. QString argumentFileName = argumentFileInfo.fileName();
  211. QString argumentFileType = argumentFileName.left(4);
  212. QString argumentFileExt = argumentFileName.right(4);
  213. if (argumentFileType == "PGTA" || argumentFileExt == ".g5e")
  214. {
  215. arg1 = currentArg;
  216. selectedAction = "showpic";
  217. }
  218. else if (argumentFileType == "SGTA")
  219. {
  220. arg1 = currentArg;
  221. selectedAction = "showsgd";
  222. }
  223. else if (argumentFileType == "MISR")
  224. {
  225. arg1 = currentArg;
  226. selectedAction = "showsgd";
  227. }
  228. }
  229. }
  230. }
  231. if (selectedAction == "showpic")
  232. {
  233. CrewDatabase crewDB;
  234. ProfileDatabase profileDB;
  235. DatabaseThread threadDB(&crewDB);
  236. PictureDialog picDialog(true, &profileDB, &crewDB);
  237. SnapmaticPicture picture;
  238. bool readOk = picture.readingPictureFromFile(arg1);
  239. picDialog.setWindowIcon(IconLoader::loadingAppIcon());
  240. picDialog.setSnapmaticPicture(&picture, readOk);
  241. #ifndef Q_OS_LINUX
  242. picDialog.setWindowFlags(picDialog.windowFlags()^Qt::Dialog^Qt::Window);
  243. #endif
  244. int crewID = picture.getSnapmaticProperties().crewID;
  245. if (crewID != 0) { crewDB.addCrew(crewID); }
  246. if (!readOk) { return 1; }
  247. QObject::connect(&threadDB, SIGNAL(crewNameFound(int, QString)), &crewDB, SLOT(setCrewName(int, QString)));
  248. QObject::connect(&threadDB, SIGNAL(crewNameUpdated()), &picDialog, SLOT(crewNameUpdated()));
  249. QObject::connect(&threadDB, SIGNAL(playerNameFound(int, QString)), &profileDB, SLOT(setPlayerName(int, QString)));
  250. QObject::connect(&threadDB, SIGNAL(playerNameUpdated()), &picDialog, SLOT(playerNameUpdated()));
  251. QObject::connect(&threadDB, SIGNAL(finished()), &a, SLOT(quit()));
  252. QObject::connect(&picDialog, SIGNAL(endDatabaseThread()), &threadDB, SLOT(terminateThread()));
  253. threadDB.start();
  254. picDialog.show();
  255. return a.exec();
  256. }
  257. else if (selectedAction == "showsgd")
  258. {
  259. SavegameDialog savegameDialog;
  260. SavegameData savegame;
  261. bool readOk = savegame.readingSavegameFromFile(arg1);
  262. savegameDialog.setWindowIcon(IconLoader::loadingAppIcon());
  263. savegameDialog.setSavegameData(&savegame, arg1, readOk);
  264. savegameDialog.setWindowFlags(savegameDialog.windowFlags()^Qt::Dialog^Qt::Window);
  265. if (!readOk) { return 1; }
  266. a.setQuitOnLastWindowClosed(true);
  267. savegameDialog.show();
  268. return a.exec();
  269. }
  270. CrewDatabase crewDB;
  271. ProfileDatabase profileDB;
  272. DatabaseThread threadDB(&crewDB);
  273. QObject::connect(&threadDB, SIGNAL(crewNameFound(int,QString)), &crewDB, SLOT(setCrewName(int, QString)));
  274. QObject::connect(&threadDB, SIGNAL(playerNameFound(int, QString)), &profileDB, SLOT(setPlayerName(int, QString)));
  275. QObject::connect(&threadDB, SIGNAL(finished()), &a, SLOT(quit()));
  276. threadDB.start();
  277. UserInterface uiWindow(&profileDB, &crewDB, &threadDB);
  278. uiWindow.setWindowIcon(IconLoader::loadingAppIcon());
  279. uiWindow.setupDirEnv();
  280. #ifdef Q_OS_ANDROID
  281. uiWindow.showMaximized();
  282. #else
  283. uiWindow.show();
  284. #endif
  285. #ifdef GTA5SYNC_DONATION
  286. settings.beginGroup("Startup");
  287. bool showDonation = settings.value("ShowDonation", true).toBool();
  288. settings.endGroup();
  289. if (showDonation)
  290. {
  291. DonationDialog *donorDialog = new DonationDialog();
  292. donorDialog->show();
  293. QObject::connect(donorDialog, SIGNAL(finished(int)), donorDialog, SLOT(deleteLater()));
  294. }
  295. #endif
  296. return a.exec();
  297. }