Skip to content

Commit a5a98e9

Browse files
committed
init
cannot afford to continue working without source control at this point :^) mostly boilerplate, reading a card works although there are parts missing to be represented in the UI (mostly bitfields)
0 parents  commit a5a98e9

15 files changed

+1239
-0
lines changed

.editorconfig

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
root = true
2+
3+
[*]
4+
end_of_line = lf
5+
charset = utf-8
6+
trim_trailing_whitespace = true
7+
insert_final_newline = true
8+
indent_style = tab
9+
indent_size = 4

.gitignore

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
resources/
2+
build*
3+
res/es.qm

es.ts

+67
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<!DOCTYPE TS>
3+
<TS version="1.0" language="es" sourcelanguage="en">
4+
<context>
5+
<name>MainWindow</name>
6+
<message>
7+
<location filename="src/gui/main_window.ui"/>
8+
<source>cdb-editor</source>
9+
<translation type="unfinished"></translation>
10+
</message>
11+
<message>
12+
<location filename="src/gui/main_window.ui"/>
13+
<source>Database</source>
14+
<translation type="unfinished"></translation>
15+
</message>
16+
<message>
17+
<location filename="src/gui/main_window.ui"/>
18+
<source>Help</source>
19+
<translation type="unfinished"></translation>
20+
</message>
21+
<message>
22+
<location filename="src/gui/main_window.ui"/>
23+
<source>Options</source>
24+
<translation type="unfinished"></translation>
25+
</message>
26+
<message>
27+
<location filename="src/gui/main_window.ui"/>
28+
<source>Language</source>
29+
<translation type="unfinished"></translation>
30+
</message>
31+
<message>
32+
<location filename="src/gui/main_window.ui"/>
33+
<source>New Database...</source>
34+
<translation type="unfinished"></translation>
35+
</message>
36+
<message>
37+
<location filename="src/gui/main_window.ui"/>
38+
<source>Open Database...</source>
39+
<translation type="unfinished"></translation>
40+
</message>
41+
<message>
42+
<location filename="src/gui/main_window.ui"/>
43+
<source>Homepage</source>
44+
<translation type="unfinished"></translation>
45+
</message>
46+
<message>
47+
<location filename="src/gui/main_window.ui"/>
48+
<source>About</source>
49+
<translation type="unfinished"></translation>
50+
</message>
51+
<message>
52+
<location filename="src/gui/main_window.ui"/>
53+
<source>Close Database</source>
54+
<translation type="unfinished"></translation>
55+
</message>
56+
<message>
57+
<location filename="src/gui/main_window.ui"/>
58+
<source>Español (Spanish)</source>
59+
<translation type="unfinished"></translation>
60+
</message>
61+
<message>
62+
<location filename="src/gui/main_window.ui"/>
63+
<source>Inglés (English)</source>
64+
<translation type="unfinished"></translation>
65+
</message>
66+
</context>
67+
</TS>

meson.build

+42
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
project('cdb-editor', 'cpp', default_options : ['cpp_std=c++17'])
2+
3+
qt_mod = import('qt5')
4+
qt_dep = dependency('qt5', modules : ['Core', 'Gui', 'Widgets', 'Sql'])
5+
6+
src_files = files([
7+
'src/main.cpp',
8+
'src/gui/main_window.cpp'
9+
])
10+
11+
moc_header_files = files([
12+
'src/gui/main_window.hpp'
13+
])
14+
15+
ui_files = files([
16+
'src/gui/main_window.ui'
17+
])
18+
19+
processed_src_files = qt_mod.preprocess(
20+
moc_headers : moc_header_files,
21+
ui_files : ui_files,
22+
qresources : 'res/res.qrc'
23+
)
24+
25+
is_windows = host_machine.system() == 'windows'
26+
27+
rc_file = []
28+
if is_windows
29+
win = import('windows')
30+
rc_file = win.compile_resources(
31+
'res/res.rc',
32+
depend_files : 'res/icon.ico',
33+
)
34+
endif
35+
36+
executable(
37+
'cdb-editor',
38+
[src_files, processed_src_files, rc_file],
39+
dependencies : qt_dep,
40+
gui_app : true,
41+
link_args : is_windows ? ['-static', '-static-libgcc', '-static-libstdc++'] : []
42+
)

regenerate_ts.sh

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
lupdate @ts_list.txt -no-ui-lines -source-language en -target-language es -ts es.ts
2+
lrelease es.ts -qm res/es.qm
3+
touch res/res.qrc

res/icon.ico

17.3 KB
Binary file not shown.

res/res.qrc

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<!DOCTYPE RCC>
2+
<RCC version="1.0">
3+
<qresource>
4+
<file>es.qm</file>
5+
<file>icon.ico</file>
6+
</qresource>
7+
</RCC>

res/res.rc

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
1 ICON "icon.ico"

src/card_database.hpp

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
#ifndef CARD_DATABASE_HPP
2+
#define CARD_DATABASE_HPP
3+
#include <memory>
4+
5+
class CardDatabase final
6+
{
7+
Q_OBJECT
8+
public:
9+
MainWindow(QWidget *parent = nullptr);
10+
~MainWindow();
11+
12+
void changeEvent(QEvent *event) override;
13+
private slots:
14+
void toSpanish();
15+
void toEnglish();
16+
private:
17+
std::unique_ptr<QTranslator> spanishTranslator;
18+
std::unique_ptr<Ui::MainWindow> ui;
19+
};
20+
21+
#endif // CARD_DATABASE_HPP

src/gui/default_layout.png

47.1 KB
Loading

src/gui/main_window.cpp

+206
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,206 @@
1+
#include "main_window.hpp"
2+
3+
#include <QDateTime>
4+
// #include <QDesktopServices> // openUrl
5+
#include <QFileDialog>
6+
#include <QMessageBox>
7+
#include <QSqlDatabase>
8+
#include <QSqlError>
9+
#include <QSqlQuery>
10+
#include <QTranslator>
11+
12+
#include "ui_main_window.h"
13+
14+
namespace
15+
{
16+
17+
QString const SQL_DB_DRIVER("QSQLITE");
18+
19+
QString const SQL_QUERY_DATA(R"(
20+
SELECT id,alias,setcode,type,atk,def,level,race,attribute,ot,category
21+
FROM datas WHERE datas.id = ?;
22+
)");
23+
24+
QString const SQL_QUERY_TEXT(R"(
25+
SELECT name,desc,str1,str2,str3,str4,str5,str6,str7,str8,str9,str10,str11,str12,str13,str14,str15,str16
26+
FROM texts WHERE texts.id = ?;
27+
)");
28+
29+
}
30+
31+
// public
32+
33+
MainWindow::MainWindow(QWidget* parent) :
34+
QMainWindow(parent),
35+
spanishTranslator(std::make_unique<QTranslator>()),
36+
ui(std::make_unique<Ui::MainWindow>())
37+
{
38+
spanishTranslator->load(":/es");
39+
QApplication::instance()->installTranslator(spanishTranslator.get());
40+
ui->setupUi(this);
41+
// TODO: Create custom Validator that works with unsigned integers...
42+
// ui->passLineEdit->setValidator(new QIntValidator(0, 4294967295, this));
43+
// ui->aliasLineEdit->setValidator(new QIntValidator(0, 4294967295, this));
44+
// connect(ui->actionNewDatabase, &QAction::triggered, this, &MainWindow::newDatabase);
45+
connect(ui->actionOpenDatabase, &QAction::triggered, this, &MainWindow::openDatabase);
46+
connect(ui->actionCloseDatabase, &QAction::triggered, this, &MainWindow::closeDatabase);
47+
connect(ui->actionSpanish, &QAction::triggered, this, &MainWindow::toSpanish);
48+
connect(ui->actionEnglish, &QAction::triggered, this, &MainWindow::toEnglish);
49+
}
50+
51+
MainWindow::~MainWindow()
52+
{
53+
QApplication::instance()->removeTranslator(spanishTranslator.get());
54+
}
55+
56+
void MainWindow::changeEvent(QEvent *event)
57+
{
58+
if (event->type() == QEvent::LanguageChange)
59+
ui->retranslateUi(this);
60+
else
61+
QWidget::changeEvent(event);
62+
}
63+
64+
// private slots
65+
66+
void MainWindow::openDatabase()
67+
{
68+
auto does_db_have_correct_format = [&](QSqlDatabase& db)
69+
{
70+
return true; // TODO
71+
};
72+
if(!checkAndAskToCloseDb())
73+
return;
74+
QString const file = QFileDialog::getOpenFileName
75+
(
76+
this,
77+
tr("Select Database"),
78+
".",
79+
tr("YGOPro Database (*.cdb *.db *.sqlite)")
80+
);
81+
if(file.isEmpty())
82+
return;
83+
auto db = QSqlDatabase::addDatabase(SQL_DB_DRIVER);
84+
db.setDatabaseName(file);
85+
if(!db.open())
86+
{
87+
QMessageBox::critical(this, tr("Error Opening Database"), db.lastError().text());
88+
closeDatabase();
89+
return;
90+
}
91+
if(!does_db_have_correct_format(db))
92+
{
93+
QMessageBox::critical(this, tr("Error Opening Database"), tr("Selected file is not a proper YGOPRO database."));
94+
closeDatabase();
95+
return;
96+
}
97+
updateUiWithCode(5043010); // TODO: Maybe load the first card on the db?
98+
}
99+
100+
void MainWindow::closeDatabase()
101+
{
102+
auto db = QSqlDatabase::database();
103+
if(db.isValid())
104+
{
105+
db.close();
106+
QSqlDatabase::removeDatabase(db.connectionName());
107+
}
108+
updateUiWithCode(0U);
109+
}
110+
111+
void MainWindow::toSpanish()
112+
{
113+
ui->actionSpanish->setEnabled(false);
114+
ui->actionEnglish->setEnabled(true);
115+
ui->actionEnglish->setChecked(false);
116+
QApplication::instance()->installTranslator(spanishTranslator.get());
117+
}
118+
119+
void MainWindow::toEnglish()
120+
{
121+
ui->actionEnglish->setEnabled(false);
122+
ui->actionSpanish->setEnabled(true);
123+
ui->actionSpanish->setChecked(false);
124+
QApplication::instance()->removeTranslator(spanishTranslator.get());
125+
}
126+
127+
// private
128+
129+
bool MainWindow::checkAndAskToCloseDb()
130+
{
131+
if(!QSqlDatabase::database().isValid())
132+
return true;
133+
if(QMessageBox::question(this, tr("Close Opened Database?"), tr("Do you wish to close the currently opened database?")) == QMessageBox::Yes)
134+
{
135+
closeDatabase();
136+
return true;
137+
}
138+
return false;
139+
}
140+
141+
void MainWindow::updateUiWithCode(quint32 code)
142+
{
143+
// Clean the UI first
144+
if(code == 0U) // If code is 0 then we don't fill in the info
145+
return;
146+
// Query the data
147+
auto db = QSqlDatabase::database();
148+
Q_ASSERT(db.isValid());
149+
QSqlQuery q1(db);
150+
q1.prepare(SQL_QUERY_DATA);
151+
q1.bindValue(0, code);
152+
bool const q1result = q1.exec() && q1.first();
153+
Q_ASSERT(q1result);
154+
QSqlQuery q2(db);
155+
q2.prepare(SQL_QUERY_TEXT);
156+
q2.bindValue(0, code);
157+
bool const q2result = q2.exec() && q2.first();
158+
Q_ASSERT(q2result);
159+
// Proceed to populate the fields with the new data
160+
ui->passLineEdit->setText(q1.value(0).toString());
161+
ui->aliasLineEdit->setText(q1.value(1).toString());
162+
// TODO: 2 - setcodes / archetypes
163+
constexpr quint32 TYPE_LINK = 0x4000000;
164+
quint32 const type = q1.value(3).toUInt();
165+
// TODO: 3 - type - checkboxes
166+
constexpr qint32 QMARK_ATK_DEF = -2;
167+
qint32 const atk = q1.value(4).toInt();
168+
ui->atkQmCheckBox->setChecked(atk == QMARK_ATK_DEF);
169+
ui->atkSpinBox->setEnabled(atk != QMARK_ATK_DEF);
170+
ui->atkSpinBox->setValue(std::max(atk, 0));
171+
if(qint32 const def = q1.value(5).toInt(); (type & TYPE_LINK) == 0U)
172+
{
173+
ui->defQmCheckBox->setChecked(def == QMARK_ATK_DEF);
174+
ui->defSpinBox->setEnabled(def != QMARK_ATK_DEF);
175+
ui->defSpinBox->setValue(std::max(def, 0));
176+
}
177+
else
178+
{
179+
ui->markerBottomLeftButton->setChecked((def & 0x1) != 0U);
180+
ui->markerBottomButton->setChecked((def & 0x2) != 0U);
181+
ui->markerBottomRightButton->setChecked((def & 0x4) != 0U);
182+
ui->markerLeftButton->setChecked((def & 0x8) != 0U);
183+
ui->markerRightButton->setChecked((def & 0x20) != 0U);
184+
ui->markerTopLeftButton->setChecked((def & 0x40) != 0U);
185+
ui->markerTopButton->setChecked((def & 0x80) != 0U);
186+
ui->markerTopRightButton->setChecked((def & 0x100) != 0U);
187+
}
188+
quint32 const dbLevel = q1.value(6).toUInt();
189+
ui->levelSpinBox->setValue(dbLevel & 0x800000FF);
190+
ui->lScaleSpinBox->setValue((dbLevel >> 24U) & 0xFF);
191+
ui->rScaleSpinBox->setValue((dbLevel >> 16U) & 0xFF);
192+
// TODO: 7 - race - checkboxes
193+
// TODO: 8 - attribute - checkboxes
194+
// TODO: 9 - ot/scope - checkboxes
195+
// TODO: 10 - category - checkboxes
196+
197+
ui->nameLineEdit->setText(q2.value(0).toString());
198+
ui->descPlainTextEdit->setPlainText(q2.value(1).toString());
199+
int const count = ui->stringsTableWidget->rowCount();
200+
for(int i = 0; i < count; ++i)
201+
{
202+
auto& item = *ui->stringsTableWidget->item(i, 0);
203+
item.setText(q2.value(2 + i).toString());
204+
}
205+
}
206+

0 commit comments

Comments
 (0)