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

JsonEditorDialog.cpp 8.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232
  1. /*****************************************************************************
  2. * gta5view Grand Theft Auto V Profile Viewer
  3. * Copyright (C) 2017-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 "JsonEditorDialog.h"
  19. #include "ui_JsonEditorDialog.h"
  20. #include "SnapmaticEditor.h"
  21. #include "AppEnv.h"
  22. #include "config.h"
  23. #include <QStringBuilder>
  24. #include <QJsonDocument>
  25. #include <QJsonObject>
  26. #include <QMessageBox>
  27. #if QT_VERSION >= 0x050200
  28. #include <QFontDatabase>
  29. #include <QDebug>
  30. #endif
  31. #ifdef GTA5SYNC_TELEMETRY
  32. #include "TelemetryClass.h"
  33. #endif
  34. JsonEditorDialog::JsonEditorDialog(SnapmaticPicture *picture, QWidget *parent) :
  35. QDialog(parent), smpic(picture),
  36. ui(new Ui::JsonEditorDialog)
  37. {
  38. // Set Window Flags
  39. setWindowFlags(windowFlags()^Qt::WindowContextHelpButtonHint^Qt::WindowMinMaxButtonsHint);
  40. ui->setupUi(this);
  41. ui->cmdClose->setDefault(true);
  42. ui->cmdClose->setFocus();
  43. // Set Icon for Close Button
  44. if (QIcon::hasThemeIcon("dialog-close"))
  45. {
  46. ui->cmdClose->setIcon(QIcon::fromTheme("dialog-close"));
  47. }
  48. else if (QIcon::hasThemeIcon("gtk-close"))
  49. {
  50. ui->cmdClose->setIcon(QIcon::fromTheme("gtk-close"));
  51. }
  52. // Set Icon for Save Button
  53. if (QIcon::hasThemeIcon("document-save"))
  54. {
  55. ui->cmdSave->setIcon(QIcon::fromTheme("document-save"));
  56. }
  57. else if (QIcon::hasThemeIcon("gtk-save"))
  58. {
  59. ui->cmdSave->setIcon(QIcon::fromTheme("gtk-save"));
  60. }
  61. jsonCode = picture->getJsonStr();
  62. #if QT_VERSION >= 0x050200
  63. ui->txtJSON->setFont(QFontDatabase::systemFont(QFontDatabase::FixedFont));
  64. #endif
  65. QFontMetrics fontMetrics(ui->txtJSON->font());
  66. ui->txtJSON->setTabStopWidth(fontMetrics.width(" "));
  67. QJsonDocument jsonDocument = QJsonDocument::fromJson(jsonCode.toUtf8());
  68. ui->txtJSON->setStyleSheet("QPlainTextEdit{background-color: rgb(46, 47, 48); color: rgb(238, 231, 172);}");
  69. ui->txtJSON->setPlainText(QString::fromUtf8(jsonDocument.toJson(QJsonDocument::Indented)).trimmed());
  70. jsonHl = new JSHighlighter(ui->txtJSON->document());
  71. // DPI calculation
  72. qreal screenRatio = AppEnv::screenRatio();
  73. #ifndef Q_OS_MAC
  74. ui->hlButtons->setSpacing(6 * screenRatio);
  75. ui->hlButtons->setContentsMargins(9 * screenRatio, 0, 9 * screenRatio, 0);
  76. ui->vlInterface->setContentsMargins(0, 0, 0, 9 * screenRatio);
  77. #else
  78. ui->hlButtons->setSpacing(6 * screenRatio);
  79. ui->hlButtons->setContentsMargins(9 * screenRatio, 0, 9 * screenRatio, 0);
  80. ui->vlInterface->setContentsMargins(0, 0, 0, 9 * screenRatio);
  81. #endif
  82. if (screenRatio > 1)
  83. {
  84. ui->lineJSON->setMinimumHeight(qRound(1 * screenRatio));
  85. ui->lineJSON->setMaximumHeight(qRound(1 * screenRatio));
  86. }
  87. resize(450 * screenRatio, 550 * screenRatio);
  88. }
  89. JsonEditorDialog::~JsonEditorDialog()
  90. {
  91. delete jsonHl;
  92. delete ui;
  93. }
  94. void JsonEditorDialog::closeEvent(QCloseEvent *ev)
  95. {
  96. QString jsonPatched = QString(ui->txtJSON->toPlainText()).replace("\t", " ");
  97. QJsonDocument jsonNew = QJsonDocument::fromJson(jsonPatched.toUtf8());
  98. QJsonDocument jsonOriginal = QJsonDocument::fromJson(jsonCode.toUtf8());
  99. QString originalCode = QString::fromUtf8(jsonOriginal.toJson(QJsonDocument::Compact));
  100. QString newCode = QString::fromUtf8(jsonNew.toJson(QJsonDocument::Compact));
  101. if (newCode != originalCode)
  102. {
  103. QMessageBox::StandardButton button = QMessageBox::warning(this, SnapmaticEditor::tr("Snapmatic Properties"), SnapmaticEditor::tr("<h4>Unsaved changes detected</h4>You want to save the JSON content before you quit?"), QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel, QMessageBox::Cancel);
  104. if (button == QMessageBox::Yes)
  105. {
  106. if (saveJsonContent())
  107. {
  108. ev->accept();
  109. }
  110. else
  111. {
  112. ev->ignore();
  113. }
  114. return;
  115. }
  116. else if (button == QMessageBox::No)
  117. {
  118. ev->accept();
  119. return;
  120. }
  121. else
  122. {
  123. ev->ignore();
  124. return;
  125. }
  126. }
  127. }
  128. bool JsonEditorDialog::saveJsonContent()
  129. {
  130. QString jsonPatched = QString(ui->txtJSON->toPlainText()).replace("\t", " ");
  131. QJsonDocument jsonNew = QJsonDocument::fromJson(jsonPatched.toUtf8());
  132. if (!jsonNew.isEmpty())
  133. {
  134. QJsonDocument jsonOriginal = QJsonDocument::fromJson(jsonCode.toUtf8());
  135. QString originalCode = QString::fromUtf8(jsonOriginal.toJson(QJsonDocument::Compact));
  136. QString newCode = QString::fromUtf8(jsonNew.toJson(QJsonDocument::Compact));
  137. if (newCode != originalCode)
  138. {
  139. QString currentFilePath = smpic->getPictureFilePath();
  140. QString originalFilePath = smpic->getOriginalPictureFilePath();
  141. QString backupFileName = originalFilePath % ".bak";
  142. if (!QFile::exists(backupFileName))
  143. {
  144. QFile::copy(currentFilePath, backupFileName);
  145. }
  146. smpic->setJsonStr(newCode, true);
  147. if (!smpic->isJsonOk())
  148. {
  149. QString lastStep = smpic->getLastStep(false);
  150. QString readableError;
  151. if (lastStep.contains("JSONINCOMPLETE") && lastStep.contains("JSONERROR"))
  152. {
  153. readableError = SnapmaticPicture::tr("JSON is incomplete and malformed");
  154. }
  155. else if (lastStep.contains("JSONINCOMPLETE"))
  156. {
  157. readableError = SnapmaticPicture::tr("JSON is incomplete");
  158. }
  159. else if (lastStep.contains("JSONERROR"))
  160. {
  161. readableError = SnapmaticPicture::tr("JSON is malformed");
  162. }
  163. else
  164. {
  165. readableError = tr("JSON Error");
  166. }
  167. QMessageBox::warning(this, SnapmaticEditor::tr("Snapmatic Properties"), SnapmaticEditor::tr("Patching of Snapmatic Properties failed because of %1").arg(readableError));
  168. smpic->setJsonStr(originalCode, true);
  169. return false;
  170. }
  171. if (!smpic->exportPicture(currentFilePath))
  172. {
  173. QMessageBox::warning(this, SnapmaticEditor::tr("Snapmatic Properties"), SnapmaticEditor::tr("Patching of Snapmatic Properties failed because of I/O Error"));
  174. smpic->setJsonStr(originalCode, true);
  175. return false;
  176. }
  177. jsonCode = newCode;
  178. smpic->updateStrings();
  179. smpic->emitUpdate();
  180. #ifdef GTA5SYNC_TELEMETRY
  181. QSettings telemetrySettings(GTA5SYNC_APPVENDOR, GTA5SYNC_APPSTR);
  182. telemetrySettings.beginGroup("Telemetry");
  183. bool pushUsageData = telemetrySettings.value("PushUsageData", false).toBool();
  184. telemetrySettings.endGroup();
  185. if (pushUsageData && Telemetry->canPush())
  186. {
  187. QJsonDocument jsonDocument;
  188. QJsonObject jsonObject;
  189. jsonObject["Type"] = "JSONEdited";
  190. jsonObject["EditedSize"] = QString::number(smpic->getContentMaxLength());
  191. jsonObject["EditedTime"] = QString::number(QDateTime::currentDateTimeUtc().toTime_t());
  192. jsonDocument.setObject(jsonObject);
  193. Telemetry->push(TelemetryCategory::PersonalData, jsonDocument);
  194. }
  195. #endif
  196. return true;
  197. }
  198. return true;
  199. }
  200. else
  201. {
  202. QMessageBox::warning(this, SnapmaticEditor::tr("Snapmatic Properties"), SnapmaticEditor::tr("Patching of Snapmatic Properties failed because of JSON Error"));
  203. return false;
  204. }
  205. }
  206. void JsonEditorDialog::on_cmdClose_clicked()
  207. {
  208. close();
  209. }
  210. void JsonEditorDialog::on_cmdSave_clicked()
  211. {
  212. if (saveJsonContent())
  213. {
  214. close();
  215. }
  216. }