Skip to content

Commit 0a52213

Browse files
committed
Cleanup, bugfixes, minor improvements
1 parent 9079924 commit 0a52213

File tree

5 files changed

+101
-90
lines changed

5 files changed

+101
-90
lines changed

main.cpp

Lines changed: 86 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWi
3030
ui->setupUi(this);
3131

3232
option_copy = this->findChild<QCheckBox *>("option_copy");
33-
option_names = this->findChild<QCheckBox *>("option_names");
3433
option_rename = this->findChild<QCheckBox *>("option_rename");
3534

3635
combobox_game = this->findChild<QComboBox *>("combobox_game");
@@ -121,9 +120,12 @@ QList<QList<QVariant>> MainWindow::get_duplicates_from_hash(const QString hash)
121120
QSqlQuery query(database);
122121

123122
query.exec(query_standalone.arg(hash));
124-
if (query.next()) { // found standalone match
125-
if(query.value(2) == selected_game) {
126-
matches.append({hash_from_int(query.value(0)), query.value(1), 3, "" });
123+
if (query.isSelect()) { // found standalone match
124+
while(query.next()) {
125+
if(query.value(2) == selected_game) {
126+
matches.append({hash_from_int(query.value(0)), query.value(1), 3, "" });
127+
query.last();
128+
}
127129
}
128130
} else {
129131
qWarning("Texture not found in vanilla database, skipping...");
@@ -146,66 +148,78 @@ QList<QList<QVariant>> MainWindow::get_duplicates_from_hash(const QString hash)
146148
return matches;
147149
}
148150

149-
void MainWindow::generate_file_paths() {
150-
// if we're in string mode, generate "fake" QFileInfos to fill file_paths
151-
file_paths.clear();
152-
for(QString s : ui->text_edit_left->toPlainText().split("\n", QString::SkipEmptyParts)) {
153-
file_paths.append(QFileInfo(s));
151+
void MainWindow::go_initialize() {
152+
// options
153+
file_mode = ui->text_edit_left->isReadOnly();
154+
copy_mode = ui->option_copy->isChecked();
155+
rename_mode = ui->option_rename->isChecked();
156+
157+
// if we're in string mode, generate "fake" QFileInfos to fill file_paths, otherwise do nothing
158+
if(!file_mode) {
159+
file_paths.clear();
160+
for(QString s : ui->text_edit_left->toPlainText().split("\n", QString::SkipEmptyParts)) {
161+
file_paths.append(QFileInfo(s));
162+
}
154163
}
155164
}
156165

157-
QList<QString> MainWindow::get_hashes_from_name(const QString name) {
166+
/*
167+
* go_rename_mode: attempt to find the hashes and names of the files in text_edit_left
168+
* Rename selected files, if any, and display result
169+
*/
170+
void MainWindow::go_rename_mode() {
171+
QString result;
172+
QTextStream ts(&result, QIODevice::WriteOnly);
173+
QString selected_game(QString::number(combobox_game->currentIndex() + 1));
158174
QSqlQuery query(database);
159-
QList<QString> matches;
160-
161-
query.exec(query_name.arg(name)); // get all hashes that match the name
162-
while (query.next()) { // for each match, get all reusable textures
163-
matches.append(query.value(0).toString());
164-
}
165-
return matches;
166-
}
167175

168-
void MainWindow::rename() {
176+
qDebug("Starting search...");
169177
for (const QFileInfo &entry : file_paths) { // iterate over the selected files
178+
QString old_path = entry.filePath();
179+
QString new_path;
180+
170181
QRegularExpressionMatch match = regex_hash.match(entry.fileName());
171182

172-
// check presence of hash in filename
173-
QList<QString> hashes;
174-
if (match.hasMatch()) {
183+
if (match.hasMatch()) { // check presence of hash in filename
175184
qDebug("Found matching hash for %s", match.captured(0).toStdString().c_str());
176185

177-
QString groupid;
178-
QList<QList<QVariant>> matches; // { crc, name, grade, notes }
179-
QString selected_game(QString::number(ui->combobox_game->currentIndex() + 1));
180-
QSqlQuery query(database);
181-
182-
query.exec(query_standalone.arg(match.captured(0)));
183-
if (query.next()) { // found standalone match
184-
if(query.value(2) == selected_game) {
185-
QString crc = hash_from_int(query.value(0));
186-
QString name = query.value(1).toString();
187-
QFile::rename(entry.filePath(), QDir(path_dest).filePath(QString("%1_%2.%3")).arg(name, crc, entry.suffix()));
186+
query.exec(query_name_from_hash_game.arg(match.captured(0), selected_game));
187+
if (query.next()) { // the matching hash corresponds to a texture
188+
qDebug("Matching hash corresponds to a texture");
189+
QString game = query.value(2).toString();
190+
QString crc = hash_from_int(query.value(0));
191+
QString name = query.value(1).toString();
192+
193+
new_path = QDir(path_dest).filePath(QString("%1_%2.%3")).arg(name, crc, entry.suffix());
194+
ts << (QString("%1 -> %2<br>")).arg(crc, name);
195+
196+
if(file_mode) {
197+
QFile::rename(old_path, new_path);
188198
}
189199
}
190-
}
200+
} else { // no hash in filename, but we'll attempt to find it from the texture name
201+
query.exec(query_hash_from_name.arg(entry.baseName())); // get all hashes that match the name
202+
203+
if(query.next()) {
204+
qDebug("Found matching hash for %s", entry.baseName().toStdString().c_str());
205+
206+
ts << entry.baseName() << " <font color=\"orange\">(from name)</font><br>";
207+
do { // for each match, get all reusable textures
208+
QString game = query.value(2).toString();
209+
QString crc = hash_from_int(query.value(0));
210+
QString name = query.value(1).toString();
211+
212+
ts << (QString("(ME%1) %2 %3<br>")).arg(game, crc, name);
213+
} while (query.next());
214+
ts << "<br>";
215+
}
216+
}
191217
}
192-
}
193218

194-
void MainWindow::on_button_go_clicked() {
195-
bool file_mode = ui->text_edit_left->isReadOnly();
196-
bool copy_mode = ui->option_copy->isChecked();
197-
bool names_mode = ui->option_names->isChecked();
198-
bool rename_mode = ui->option_rename->isChecked();
199-
200-
if(file_mode && rename_mode) {
201-
rename();
202-
return;
203-
}
204-
205-
// CHECKS
206-
if(!file_mode) generate_file_paths();
207-
if(file_paths.isEmpty()) return;
219+
ui->text_edit_right->setText(result);
220+
}
208221

222+
void MainWindow::go_normal_mode() {
209223
QString result;
210224
QTextStream ts(&result, QIODevice::WriteOnly);
211225
QString game(QString::number(combobox_game->currentIndex() + 1));
@@ -216,7 +230,6 @@ void MainWindow::on_button_go_clicked() {
216230
}
217231

218232
qDebug("Checking duplicates...");
219-
bool from_name;
220233
for (const QFileInfo &entry : file_paths) { // iterate over the selected files
221234
QRegularExpressionMatch match = regex_hash.match(entry.fileName());
222235

@@ -225,24 +238,14 @@ void MainWindow::on_button_go_clicked() {
225238
if (match.hasMatch()) {
226239
hashes.append(match.captured(0));
227240
qDebug("Found matching hash for %s", match.captured(0).toStdString().c_str());
228-
from_name = false;
229-
} else if(names_mode) {
230-
QList<QString> h = get_hashes_from_name(entry.baseName());
231-
if(!h.isEmpty()) {
232-
for(QString hash : h) {
233-
hashes.append(hash_from_int(hash));
234-
}
235-
qDebug("Found %d matching hashes for name %s", hashes.size(), entry.fileName().toStdString().c_str());
236-
from_name = true;
237-
}
238241
}
239242

240243
QList<QList<QVariant>> search_results;
241244
for(QString hash : hashes) {
242245
search_results = get_duplicates_from_hash(hash);
243246

244247
if(!search_results.isEmpty()) {
245-
ts << hash << (from_name ? " <font color=\"orange\">(from name)</font><br>" : "<br>");
248+
ts << hash << "<br>";
246249
for (QList<QVariant> search : search_results) {
247250
QString crc = search[0].toString();
248251
QString name = search[1].toString();
@@ -272,6 +275,20 @@ void MainWindow::on_button_go_clicked() {
272275
}
273276
}
274277

278+
void MainWindow::on_button_go_clicked() {
279+
// INITIALIZATION
280+
go_initialize();
281+
282+
// if there is nothing to do, return immediately
283+
if(file_paths.isEmpty()) return;
284+
285+
if(rename_mode) {
286+
go_rename_mode();
287+
} else {
288+
go_normal_mode();
289+
}
290+
}
291+
275292
void MainWindow::on_button_clear_clicked() {
276293
qDebug("Clearing data");
277294
ui->text_edit_right->clear();
@@ -291,12 +308,14 @@ void MainWindow::run_copy_thread(MainWindow *w) {
291308
file = w->copy_queue.dequeue();
292309

293310

294-
if(QFile(file.second).exists() && QFile(file.second).size() < QFile(file.first).size()) {
295-
qDebug("Destination already exists, but this file is larger.");
296-
qDebug("Copying %s to %s", file.first.toStdString().c_str(), file.second.toStdString().c_str());
297-
QFile::remove(file.second);
298-
QFile::copy(file.first, file.second);
299-
} else if(!QFile(file.second).exists()) {
311+
if(QFile(file.second).exists()) {
312+
qDebug("Destination already exists, renaming");
313+
int i = 1;
314+
while(QFile(file.second + "_" + i).exists()) { i++; }
315+
316+
qDebug("Copying %s to %s", file.first.toStdString().c_str(), (file.second + "_" + i).toStdString().c_str());
317+
QFile::copy(file.first, file.second + "_" + i);
318+
} else {
300319
qDebug("Copying %s to %s", file.first.toStdString().c_str(), file.second.toStdString().c_str());
301320
QFile::copy(file.first, file.second);
302321
}

main.h

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ Q_OBJECT
3939
void sqlite_check_query(QSqlQuery &query);
4040

4141
QList<QString> get_hashes_from_name(const QString name);
42-
void generate_file_paths();
42+
void go_initialize();
4343
static void run_copy_thread(MainWindow *w);
4444
static void run_init_thread(MainWindow *w);
4545

@@ -52,7 +52,6 @@ Q_OBJECT
5252
const QPushButton *button_go;
5353
const QPushButton *button_clear;
5454
const QCheckBox *option_copy;
55-
const QCheckBox *option_names;
5655
const QCheckBox *option_rename;
5756
const QComboBox *combobox_game;
5857
QTextEdit *text_edit_right;
@@ -73,9 +72,14 @@ Q_OBJECT
7372
std::thread thread_copy;
7473
QQueue<QPair<QString, QString>> copy_queue;
7574

75+
bool file_mode;
76+
bool copy_mode;
77+
bool rename_mode;
78+
7679
~MainWindow() override;
7780
Ui::MainWindow *ui;
78-
void rename();
81+
void go_rename_mode();
82+
void go_normal_mode();
7983
};
8084

8185
#endif

sqlite.hpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ const QString query_create_database_duplicates(
2525
"groupid INTEGER,"
2626
"game INTEGER,"
2727
"crc INTEGER,"
28-
"name TEXT,"
28+
"name TEXT collate nocase,"
2929
"size_x INTEGER,"
3030
"size_y INTEGER,"
3131
"grade INTEGER,"
@@ -43,18 +43,19 @@ const QString query_create_database_vanilla(
4343
"create table vanilla ("
4444
"game INTEGER,"
4545
"crc INTEGER,"
46-
"name TEXT,"
46+
"name TEXT collate nocase,"
4747
"PRIMARY KEY(game, crc));");
4848

4949
const QString query_index_database_vanilla(
5050
"create index index_crc_vanilla on vanilla (crc);");
5151

5252
const QString query_vacuum("vacuum");
5353

54-
const QString query_standalone ("select crc, name, game from vanilla where crc=%1 limit 1");
54+
const QString query_name_from_hash_game ("select crc, name from vanilla where crc=%1 and game=%2 limit 1");
55+
const QString query_standalone ("select crc, name, game from vanilla where crc=%1");
5556
const QString query_groupid ("select groupid from duplicates where crc=%1 limit 1");
5657
const QString query_duplicates ("select crc, name, grade, notes from duplicates where groupid=%1 and game=%2 and not crc=%3");
57-
const QString query_name ("select crc from vanilla where name='%1'");
58+
const QString query_hash_from_name ("select crc, name, game from vanilla where name='%1'");
5859

5960
/*
6061
* SQLite3 specific utility functions

texturemapper.ui

Lines changed: 2 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@
4646
<number>8</number>
4747
</property>
4848
<item row="3" column="0">
49-
<layout class="QHBoxLayout" name="hl1" stretch="0,0,0,0,0">
49+
<layout class="QHBoxLayout" name="hl1" stretch="0,0,0,0">
5050
<property name="spacing">
5151
<number>8</number>
5252
</property>
@@ -66,23 +66,10 @@
6666
</property>
6767
</spacer>
6868
</item>
69-
<item>
70-
<widget class="QCheckBox" name="option_names">
71-
<property name="toolTip">
72-
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Attempt to detect the hash based only on the name of textures. Don't use this option if you don't know what you're doing.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
73-
</property>
74-
<property name="text">
75-
<string>Names</string>
76-
</property>
77-
</widget>
78-
</item>
7969
<item>
8070
<widget class="QCheckBox" name="option_rename">
81-
<property name="enabled">
82-
<bool>false</bool>
83-
</property>
8471
<property name="toolTip">
85-
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Renames the selected files to name_hash, where name is the name of the texture and hash its hash.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
72+
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;If the file name contains a hash, rename the file to name_hash. Otherwise, try to deduce the hash from the filename and display it in the right panel (no renaming : a name can correspond to multiple hashes).&lt;/p&gt;&lt;p&gt;If there are no files selected, the results will simply be displayed since there is nothing to rename.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
8673
</property>
8774
<property name="text">
8875
<string>Rename</string>

version.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
{
22
"database-version": 10,
3-
"main-version": 6
3+
"main-version": 7
44
}

0 commit comments

Comments
 (0)