Crossfire Server, Trunk
AssetOriginAndCreationDialog.cpp
Go to the documentation of this file.
1 /*
2  * Crossfire -- cooperative multi-player graphical RPG and adventure game
3  *
4  * Copyright (c) 2022 the Crossfire Development Team
5  *
6  * Crossfire is free software and comes with ABSOLUTELY NO WARRANTY. You are
7  * welcome to redistribute it under certain conditions. For details, please
8  * see COPYING and LICENSE.
9  *
10  * The authors can be reached via e-mail at <crossfire@metalforge.org>.
11  */
12 
14 #include "global.h"
15 
16 const char * const addTitles[] = {
17  QT_TRANSLATE_NOOP("AssetOriginAndCreationDialog", "Quest creation"),
18  QT_TRANSLATE_NOOP("AssetOriginAndCreationDialog", "Treasure creation"),
19 };
20 const char * const originTitles[] = {
21  QT_TRANSLATE_NOOP("AssetOriginAndCreationDialog", "Quest file definition"),
22  QT_TRANSLATE_NOOP("AssetOriginAndCreationDialog", "Treasure list file definition"),
23 };
24 const char * const names[] = {
25  QT_TRANSLATE_NOOP("AssetOriginAndCreationDialog", "quest"),
26  QT_TRANSLATE_NOOP("AssetOriginAndCreationDialog", "treasure"),
27 };
28 const char * const extensions[] = {
29  ".quests",
30  ".trs",
31 };
32 const bool isArch[] = {
33  false,
34  true,
35 };
36 
38  const std::vector<std::string> &origins, const std::vector<std::string> &assets) : myType(type), myAssets(assets) {
39  setModal(true);
40  setWindowTitle(tr(mode == CreateAsset ? addTitles[type] : originTitles[type]));
41  QGridLayout *layout = new QGridLayout(this);
42 
43  myRootDirectory = QString("%1/%2/").arg(settings.datadir, isArch[type] ? "arch" : settings.mapdir);
44 
45  layout->addWidget(new QLabel(tr("Code:")), 1, 0);
46  layout->addWidget(myCode = new QLineEdit(this), 1, 1, 1, 2);
47  if (mode == DefineOrigin) {
48  myCode->setReadOnly(true);
49  myCode->setText(code);
50  }
51 
52  QRadioButton *existing = new QRadioButton(tr("Add to an existing %1 file:").arg(names[type]), this);
53  layout->addWidget(existing, 2, 0);
54  myExistingFile = new QComboBox(this);
55  for (const auto &origin : origins) {
56  myExistingFile->addItem(QString::fromStdString(origin));
57  }
58  layout->addWidget(myExistingFile, 2, 1, 1, 2);
59 
60  QRadioButton *nqf = new QRadioButton(tr("Create a new %1 file:").arg(names[type]), this);
61  layout->addWidget(nqf, 3, 0);
62  myNewFile = new QLineEdit(this);
63  layout->addWidget(myNewFile, 3, 1);
64  auto browse = new QPushButton(tr("Browse..."), this);
65  layout->addWidget(browse, 3, 2);
66  connect(browse, &QAbstractButton::clicked, [this] () {
67  QFileDialog dlg;
68  if (myNewFile->text().isEmpty()) {
69  dlg.setDirectory(myRootDirectory);
70  } else {
71  dlg.selectFile(myNewFile->text());
72  }
73  dlg.setNameFilter(tr("%1 file (*%2);;All files (*.*)").arg(names[myType], extensions[myType]));
74  dlg.setAcceptMode(QFileDialog::AcceptSave);
75  dlg.setFileMode(QFileDialog::AnyFile);
76  if (dlg.exec() == QDialog::Accepted) {
77  myNewFile->setText(dlg.selectedFiles()[0]);
78  }
79  });
80 
81  connect(existing, &QAbstractButton::clicked, [this, browse] {
82  myExistingFile->setEnabled(true);
83  myNewFile->setEnabled(false);
84  browse->setEnabled(false);
85  });
86  connect(nqf, &QAbstractButton::clicked, [this, browse] {
87  myExistingFile->setEnabled(false);
88  myNewFile->setEnabled(true);
89  browse->setEnabled(true);
90  if (myNewFile->text().isEmpty()) {
91  browse->click();
92  }
93  });
94  existing->click();
95 
96  auto buttons = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
97  connect(buttons, &QDialogButtonBox::rejected, this, &QDialog::reject);
98  connect(buttons, &QDialogButtonBox::accepted, [this] () { validate(); });
99  layout->addWidget(buttons, 4, 0, 1, 3);
100 }
101 
103  if (!myCode->isReadOnly()) {
104  if (myCode->text().isEmpty()) {
105  QMessageBox::critical(this, tr("Empty required field"), tr("Please enter a code."));
106  myCode->setFocus();
107  return;
108  }
109  if (std::find(myAssets.cbegin(), myAssets.cend(), myCode->text().toStdString()) != myAssets.cend()) {
110  QMessageBox::critical(this, tr("Code already exists"), tr("The code you entered matches an existing code."));
111  myCode->setFocus();
112  return;
113  }
114  }
115  if (myNewFile->isEnabled()) {
116  if (myNewFile->text().isEmpty()) {
117  QMessageBox::critical(this, tr("Empty file"), tr("Please enter a file to define the %1 into.").arg(names[myType]));
118  myNewFile->setFocus();
119  return;
120  }
121  if (!myNewFile->text().startsWith(myRootDirectory)) {
122  if (QMessageBox::question(this, tr("File warning"), tr("The file seems to be outside the root directory for this kind of assets (%1).\nThis means the asset will not be visible to the game.\nAre you sure you want to use this file?").arg(myRootDirectory)) != QMessageBox::Yes) {
123  myNewFile->setFocus();
124  return;
125  }
126  }
127  if (!myNewFile->text().endsWith(extensions[myType])) {
128  if (QMessageBox::question(this, tr("File warning"), tr("The file does not end with '%1'.\nThis means the asset will not be visible to the game.\nAre you sure you want to use this file?").arg(extensions[myType])) != QMessageBox::Yes) {
129  myNewFile->setFocus();
130  return;
131  }
132  }
133  }
134  accept();
135 }
extensions
const char *const extensions[]
Definition: AssetOriginAndCreationDialog.cpp:28
Settings::mapdir
const char * mapdir
Definition: global.h:251
global.h
settings
struct Settings settings
Definition: init.cpp:139
layout
Definition: main.cpp:84
isArch
const bool isArch[]
Definition: AssetOriginAndCreationDialog.cpp:32
AssetOriginAndCreationDialog::myAssets
std::vector< std::string > myAssets
Definition: AssetOriginAndCreationDialog.h:46
Settings::datadir
const char * datadir
Definition: global.h:248
AssetOriginAndCreationDialog::AssetOriginAndCreationDialog
AssetOriginAndCreationDialog(Type type, Mode mode, const QString &code, const std::vector< std::string > &origins, const std::vector< std::string > &assets)
Definition: AssetOriginAndCreationDialog.cpp:37
AssetOriginAndCreationDialog::DefineOrigin
@ DefineOrigin
Definition: AssetOriginAndCreationDialog.h:25
AssetOriginAndCreationDialog::CreateAsset
@ CreateAsset
Definition: AssetOriginAndCreationDialog.h:25
AssetOriginAndCreationDialog::myNewFile
QLineEdit * myNewFile
Definition: AssetOriginAndCreationDialog.h:45
addTitles
const char *const addTitles[]
Definition: AssetOriginAndCreationDialog.cpp:16
AssetOriginAndCreationDialog::Mode
Mode
Definition: AssetOriginAndCreationDialog.h:25
AssetOriginAndCreationDialog.h
AssetOriginAndCreationDialog::myCode
QLineEdit * myCode
Definition: AssetOriginAndCreationDialog.h:43
AssetOriginAndCreationDialog::validate
void validate()
Definition: AssetOriginAndCreationDialog.cpp:102
AssetOriginAndCreationDialog::myRootDirectory
QString myRootDirectory
Definition: AssetOriginAndCreationDialog.h:42
AssetOriginAndCreationDialog::Type
Type
Definition: AssetOriginAndCreationDialog.h:24
originTitles
const char *const originTitles[]
Definition: AssetOriginAndCreationDialog.cpp:20
names
const char *const names[]
Definition: AssetOriginAndCreationDialog.cpp:24
connect
Definition: connect.py:1
AssetOriginAndCreationDialog::myType
Type myType
Definition: AssetOriginAndCreationDialog.h:41
altar_valkyrie.accept
def accept(description)
Definition: altar_valkyrie.py:22
AssetOriginAndCreationDialog::code
QString code() const
Definition: AssetOriginAndCreationDialog.h:37
is_valid_types_gen.type
list type
Definition: is_valid_types_gen.py:25
AssetOriginAndCreationDialog::myExistingFile
QComboBox * myExistingFile
Definition: AssetOriginAndCreationDialog.h:44