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

ImageEditorDialog.cpp 7.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205
  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 "ImageEditorDialog.h"
  19. #include "ui_ImageEditorDialog.h"
  20. #include "ProfileInterface.h"
  21. #include "SidebarGenerator.h"
  22. #include "StandardPaths.h"
  23. #include "ImportDialog.h"
  24. #include "AppEnv.h"
  25. #include "config.h"
  26. #include <QStringBuilder>
  27. #include <QImageReader>
  28. #include <QFileDialog>
  29. #include <QMessageBox>
  30. ImageEditorDialog::ImageEditorDialog(SnapmaticPicture *picture, QString profileName, QWidget *parent) :
  31. QDialog(parent), smpic(picture), profileName(profileName),
  32. ui(new Ui::ImageEditorDialog)
  33. {
  34. // Set Window Flags
  35. setWindowFlags(windowFlags()^Qt::WindowContextHelpButtonHint);
  36. ui->setupUi(this);
  37. ui->cmdClose->setDefault(true);
  38. ui->cmdClose->setFocus();
  39. // Set Icon for Close Button
  40. if (QIcon::hasThemeIcon("dialog-close"))
  41. {
  42. ui->cmdClose->setIcon(QIcon::fromTheme("dialog-close"));
  43. }
  44. else if (QIcon::hasThemeIcon("gtk-close"))
  45. {
  46. ui->cmdClose->setIcon(QIcon::fromTheme("gtk-close"));
  47. }
  48. // Set Icon for Import Button
  49. if (QIcon::hasThemeIcon("document-import"))
  50. {
  51. ui->cmdReplace->setIcon(QIcon::fromTheme("document-import"));
  52. }
  53. // Set Icon for Overwrite Button
  54. if (QIcon::hasThemeIcon("document-save"))
  55. {
  56. ui->cmdSave->setIcon(QIcon::fromTheme("document-save"));
  57. }
  58. else if (QIcon::hasThemeIcon("gtk-save"))
  59. {
  60. ui->cmdSave->setIcon(QIcon::fromTheme("gtk-save"));
  61. }
  62. // DPI calculation
  63. qreal screenRatio = AppEnv::screenRatio();
  64. snapmaticResolutionLW = 516 * screenRatio; // 430
  65. snapmaticResolutionLH = 288 * screenRatio; // 240
  66. ui->labPicture->setMinimumSize(snapmaticResolutionLW, snapmaticResolutionLH);
  67. imageIsChanged = false;
  68. pictureCache = picture->getImage();
  69. ui->labPicture->setPixmap(QPixmap::fromImage(pictureCache).scaled(snapmaticResolutionLW, snapmaticResolutionLH, Qt::IgnoreAspectRatio, Qt::SmoothTransformation));
  70. setMaximumSize(sizeHint());
  71. setMinimumSize(sizeHint());
  72. setFixedSize(sizeHint());
  73. }
  74. ImageEditorDialog::~ImageEditorDialog()
  75. {
  76. delete ui;
  77. }
  78. void ImageEditorDialog::on_cmdClose_clicked()
  79. {
  80. close();
  81. }
  82. void ImageEditorDialog::on_cmdReplace_clicked()
  83. {
  84. QSettings settings(GTA5SYNC_APPVENDOR, GTA5SYNC_APPSTR);
  85. settings.beginGroup("FileDialogs");
  86. bool dontUseNativeDialog = settings.value("DontUseNativeDialog", false).toBool();
  87. settings.beginGroup("ImportReplace");
  88. fileDialogPreOpen: //Work?
  89. QFileDialog fileDialog(this);
  90. fileDialog.setFileMode(QFileDialog::ExistingFile);
  91. fileDialog.setViewMode(QFileDialog::Detail);
  92. fileDialog.setAcceptMode(QFileDialog::AcceptOpen);
  93. fileDialog.setOption(QFileDialog::DontUseNativeDialog, dontUseNativeDialog);
  94. fileDialog.setWindowFlags(fileDialog.windowFlags()^Qt::WindowContextHelpButtonHint);
  95. fileDialog.setWindowTitle(ProfileInterface::tr("Import..."));
  96. fileDialog.setLabelText(QFileDialog::Accept, ProfileInterface::tr("Import"));
  97. // Getting readable Image formats
  98. QString imageFormatsStr = " ";
  99. for (QByteArray imageFormat : QImageReader::supportedImageFormats())
  100. {
  101. imageFormatsStr += QString("*.") % QString::fromUtf8(imageFormat).toLower() % " ";
  102. }
  103. QStringList filters;
  104. filters << ProfileInterface::tr("All image files (%1)").arg(imageFormatsStr.trimmed());
  105. filters << ProfileInterface::tr("All files (**)");
  106. fileDialog.setNameFilters(filters);
  107. QList<QUrl> sidebarUrls = SidebarGenerator::generateSidebarUrls(fileDialog.sidebarUrls());
  108. fileDialog.setSidebarUrls(sidebarUrls);
  109. fileDialog.setDirectory(settings.value(profileName % "+Directory", StandardPaths::documentsLocation()).toString());
  110. fileDialog.restoreGeometry(settings.value(profileName % "+Geometry", "").toByteArray());
  111. if (fileDialog.exec())
  112. {
  113. QStringList selectedFiles = fileDialog.selectedFiles();
  114. if (selectedFiles.length() == 1)
  115. {
  116. QString selectedFile = selectedFiles.at(0);
  117. QString selectedFileName = QFileInfo(selectedFile).fileName();
  118. QFile snapmaticFile(selectedFile);
  119. if (!snapmaticFile.open(QFile::ReadOnly))
  120. {
  121. QMessageBox::warning(this, ProfileInterface::tr("Import"), ProfileInterface::tr("Can't import %1 because file can't be open").arg("\""+selectedFileName+"\""));
  122. goto fileDialogPreOpen;
  123. }
  124. QImage *importImage = new QImage();
  125. QImageReader snapmaticImageReader;
  126. snapmaticImageReader.setDecideFormatFromContent(true);
  127. snapmaticImageReader.setDevice(&snapmaticFile);
  128. if (!snapmaticImageReader.read(importImage))
  129. {
  130. QMessageBox::warning(this, ProfileInterface::tr("Import"), ProfileInterface::tr("Can't import %1 because file can't be parsed properly").arg("\""+selectedFileName+"\""));
  131. delete importImage;
  132. goto fileDialogPreOpen;
  133. }
  134. ImportDialog *importDialog = new ImportDialog(profileName, this);
  135. importDialog->setImage(importImage);
  136. importDialog->setModal(true);
  137. importDialog->show();
  138. importDialog->exec();
  139. if (importDialog->isImportAgreed())
  140. {
  141. pictureCache = importDialog->image();
  142. ui->labPicture->setPixmap(QPixmap::fromImage(pictureCache).scaled(snapmaticResolutionLW, snapmaticResolutionLH, Qt::KeepAspectRatio, Qt::SmoothTransformation));
  143. imageIsChanged = true;
  144. }
  145. delete importDialog;
  146. }
  147. }
  148. settings.setValue(profileName % "+Geometry", fileDialog.saveGeometry());
  149. settings.setValue(profileName % "+Directory", fileDialog.directory().absolutePath());
  150. settings.endGroup();
  151. settings.endGroup();
  152. }
  153. void ImageEditorDialog::on_cmdSave_clicked()
  154. {
  155. if (imageIsChanged)
  156. {
  157. const QByteArray previousPicture = smpic->getPictureStream();
  158. bool success = smpic->setImage(pictureCache);
  159. if (success)
  160. {
  161. QString currentFilePath = smpic->getPictureFilePath();
  162. QString originalFilePath = smpic->getOriginalPictureFilePath();
  163. QString backupFileName = originalFilePath % ".bak";
  164. if (!QFile::exists(backupFileName))
  165. {
  166. QFile::copy(currentFilePath, backupFileName);
  167. }
  168. if (!smpic->exportPicture(currentFilePath))
  169. {
  170. smpic->setPictureStream(previousPicture);
  171. QMessageBox::warning(this, tr("Snapmatic Image Editor"), tr("Patching of Snapmatic Image failed because of I/O Error"));
  172. return;
  173. }
  174. smpic->emitCustomSignal("PictureUpdated");
  175. }
  176. else
  177. {
  178. QMessageBox::warning(this, tr("Snapmatic Image Editor"), tr("Patching of Snapmatic Image failed because of Image Error"));
  179. return;
  180. }
  181. }
  182. close();
  183. }