campaigneditor.cpp 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255
  1. /*
  2. * campaigneditor.cpp, part of VCMI engine
  3. *
  4. * Authors: listed in file AUTHORS in main folder
  5. *
  6. * License: GNU General Public License v2.0 or later
  7. * Full text of license available in license.txt file, in main folder
  8. *
  9. */
  10. #include "StdInc.h"
  11. #include "campaigneditor.h"
  12. #include "ui_campaigneditor.h"
  13. #include "campaignproperties.h"
  14. #include "scenarioproperties.h"
  15. #include "../BitmapHandler.h"
  16. #include "../helper.h"
  17. #include "../../lib/VCMIDirs.h"
  18. #include "../../lib/json/JsonNode.h"
  19. #include "../../lib/campaign/CampaignState.h"
  20. #include "../../lib/mapping/CMap.h"
  21. CampaignEditor::CampaignEditor():
  22. ui(new Ui::CampaignEditor),
  23. selectedScenario(CampaignScenarioID::NONE)
  24. {
  25. ui->setupUi(this);
  26. setWindowIcon(QIcon{":/icons/menu-game.png"});
  27. ui->actionOpen->setIcon(QIcon{":/icons/document-open.png"});
  28. ui->actionSave->setIcon(QIcon{":/icons/document-save.png"});
  29. ui->actionNew->setIcon(QIcon{":/icons/document-new.png"});
  30. ui->actionScenarioProperties->setIcon(QIcon{":/icons/menu-settings.png"});
  31. ui->actionCampaignProperties->setIcon(QIcon{":/icons/menu-mods.png"});
  32. ui->actionShowFullBackground->setIcon(QIcon{":/icons/tool-area.png"});
  33. ui->actionShowFullBackground->setCheckable(true);
  34. connect(ui->actionShowFullBackground, &QAction::triggered, [this](){ redraw(); });
  35. campaignScene.reset(new CampaignScene());
  36. ui->campaignView->setScene(campaignScene.get());
  37. redraw();
  38. setTitle();
  39. setWindowModality(Qt::ApplicationModal);
  40. show();
  41. }
  42. CampaignEditor::~CampaignEditor()
  43. {
  44. delete ui;
  45. }
  46. void CampaignEditor::redraw()
  47. {
  48. ui->actionSave->setEnabled(campaignState != nullptr);
  49. ui->actionSave_as->setEnabled(campaignState != nullptr);
  50. ui->actionScenarioProperties->setEnabled(campaignState != nullptr && campaignState->scenarios.count(selectedScenario));
  51. ui->actionCampaignProperties->setEnabled(campaignState != nullptr);
  52. if(!campaignState)
  53. return;
  54. campaignScene->clear();
  55. auto background = BitmapHandler::loadBitmap(campaignState->getRegions().getBackgroundName().getName());
  56. if(!ui->actionShowFullBackground->isChecked())
  57. background = background.copy(0, 0, 456, 600);
  58. campaignScene->addItem(new QGraphicsPixmapItem(QPixmap::fromImage(background)));
  59. for (auto & s : campaignState->scenarios)
  60. {
  61. auto scenario = s.first;
  62. auto color = campaignState->scenarios.at(scenario).regionColor;
  63. auto image = BitmapHandler::loadBitmap(campaignState->getRegions().getAvailableName(scenario, color).getName());
  64. if(selectedScenario == scenario)
  65. image = BitmapHandler::loadBitmap(campaignState->getRegions().getSelectedName(scenario, color).getName());
  66. else if(campaignState->scenarios.at(scenario).mapName == "")
  67. image = BitmapHandler::loadBitmap(campaignState->getRegions().getConqueredName(scenario, color).getName());
  68. auto pixmap = new ClickablePixmapItem(QPixmap::fromImage(image), [this, scenario]()
  69. {
  70. bool redrawRequired = selectedScenario != scenario;
  71. selectedScenario = scenario;
  72. if(redrawRequired)
  73. redraw();
  74. }, [this, scenario]()
  75. {
  76. if(ScenarioProperties::showScenarioProperties(campaignState, scenario))
  77. changed();
  78. redraw();
  79. }, [this, scenario](QGraphicsSceneContextMenuEvent * event)
  80. {
  81. QMenu contextMenu(this);
  82. QAction *actionScenarioProperties = contextMenu.addAction(tr("Scenario editor"));
  83. actionScenarioProperties->setIcon(ui->actionScenarioProperties->icon());
  84. connect(actionScenarioProperties, &QAction::triggered, this, [this, scenario]() {
  85. if(ScenarioProperties::showScenarioProperties(campaignState, scenario))
  86. changed();
  87. redraw();
  88. });
  89. contextMenu.exec(event->screenPos());
  90. });
  91. auto pos = campaignState->getRegions().getPosition(scenario);
  92. pixmap->setPos(pos.x, pos.y);
  93. pixmap->setToolTip(QString::fromStdString(campaignState->scenarios.at(scenario).mapName));
  94. campaignScene->addItem(pixmap);
  95. }
  96. campaignScene->setSceneRect(background.rect());
  97. ui->campaignView->show();
  98. }
  99. bool CampaignEditor::getAnswerAboutUnsavedChanges()
  100. {
  101. if(unsaved)
  102. {
  103. auto sure = QMessageBox::question(this, tr("Confirmation"), tr("Unsaved changes will be lost, are you sure?"));
  104. if(sure == QMessageBox::No)
  105. {
  106. return false;
  107. }
  108. }
  109. return true;
  110. }
  111. void CampaignEditor::setTitle()
  112. {
  113. QFileInfo fileInfo(filename);
  114. QString title = QString("%1%2 - %3 (%4)").arg(fileInfo.fileName(), unsaved ? "*" : "", tr("VCMI Campaign Editor"), GameConstants::VCMI_VERSION.c_str());
  115. setWindowTitle(title);
  116. }
  117. void CampaignEditor::changed()
  118. {
  119. unsaved = true;
  120. setTitle();
  121. }
  122. void CampaignEditor::saveCampaign()
  123. {
  124. if(campaignState->mapPieces.size() != campaignState->campaignRegions.regions.size())
  125. logGlobal->trace("Not all regions have a map");
  126. Helper::saveCampaign(campaignState, filename);
  127. unsaved = false;
  128. }
  129. void CampaignEditor::showCampaignEditor()
  130. {
  131. auto * dialog = new CampaignEditor();
  132. dialog->setAttribute(Qt::WA_DeleteOnClose);
  133. }
  134. void CampaignEditor::on_actionOpen_triggered()
  135. {
  136. if(!getAnswerAboutUnsavedChanges())
  137. return;
  138. auto filenameSelect = QFileDialog::getOpenFileName(this, tr("Open map"),
  139. QString::fromStdString(VCMIDirs::get().userDataPath().make_preferred().string()),
  140. tr("All supported campaigns (*.vcmp *.h3c);;VCMI campaigns(*.vcmp);;HoMM3 campaigns(*.h3c)"));
  141. if(filenameSelect.isEmpty())
  142. return;
  143. campaignState = Helper::openCampaignInternal(filenameSelect);
  144. selectedScenario = *campaignState->allScenarios().begin();
  145. redraw();
  146. }
  147. void CampaignEditor::on_actionSave_as_triggered()
  148. {
  149. if(!campaignState)
  150. return;
  151. auto filenameSelect = QFileDialog::getSaveFileName(this, tr("Save campaign"), "", tr("VCMI campaigns (*.vcmp)"));
  152. if(filenameSelect.isNull())
  153. return;
  154. QFileInfo fileInfo(filenameSelect);
  155. if(fileInfo.suffix().toLower() != "vcmp")
  156. filenameSelect += ".vcmp";
  157. filename = filenameSelect;
  158. saveCampaign();
  159. setTitle();
  160. }
  161. void CampaignEditor::on_actionNew_triggered()
  162. {
  163. if(!getAnswerAboutUnsavedChanges())
  164. return;
  165. campaignState = std::make_unique<CampaignState>();
  166. campaignState->campaignRegions = CampaignRegions::getLegacy(0);
  167. for (int i = 0; i < campaignState->campaignRegions.regions.size(); i++)
  168. {
  169. CampaignScenario s;
  170. s.travelOptions.startOptions = CampaignStartOptions::START_BONUS;
  171. campaignState->scenarios.emplace(CampaignScenarioID(i), s);
  172. }
  173. campaignState->modName = "mapEditor";
  174. campaignState->creationDateTime = std::time(nullptr);
  175. changed();
  176. redraw();
  177. }
  178. void CampaignEditor::on_actionSave_triggered()
  179. {
  180. if(!campaignState)
  181. return;
  182. if(filename.isNull())
  183. on_actionSave_as_triggered();
  184. else
  185. saveCampaign();
  186. setTitle();
  187. }
  188. void CampaignEditor::on_actionCampaignProperties_triggered()
  189. {
  190. if(!campaignState)
  191. return;
  192. if(CampaignProperties::showCampaignProperties(campaignState))
  193. changed();
  194. redraw();
  195. }
  196. void CampaignEditor::on_actionScenarioProperties_triggered()
  197. {
  198. if(!campaignState || selectedScenario == CampaignScenarioID::NONE)
  199. return;
  200. if(ScenarioProperties::showScenarioProperties(campaignState, selectedScenario))
  201. changed();
  202. redraw();
  203. }
  204. void CampaignEditor::closeEvent(QCloseEvent *event)
  205. {
  206. if(getAnswerAboutUnsavedChanges())
  207. QWidget::closeEvent(event);
  208. else
  209. event->ignore();
  210. }