From 0f51c738001623dbff262aecd03c22dcc0013844 Mon Sep 17 00:00:00 2001 From: Quildra Date: Mon, 14 Oct 2024 22:00:58 +0100 Subject: [PATCH] - Start of the split --- .gitignore | 2 +- DBEditor/DBEditor.py | 220 ++++++++++++++++++++++++- DBEditor/database_operations.py | 114 +++++++++++++ DBEditor/db_editor.py | 19 +++ DBEditor/encounter_operations.py | 12 ++ DBEditor/evolution_operations.py | 12 ++ DBEditor/main.py | 9 + DBEditor/patch_operations.py | 12 ++ DBEditor/pokemon_details_operations.py | 8 + DBEditor/pokemon_list_operations.py | 13 ++ DBEditor/ui_components.py | 8 + 11 files changed, 420 insertions(+), 9 deletions(-) create mode 100644 DBEditor/database_operations.py create mode 100644 DBEditor/db_editor.py create mode 100644 DBEditor/encounter_operations.py create mode 100644 DBEditor/evolution_operations.py create mode 100644 DBEditor/main.py create mode 100644 DBEditor/patch_operations.py create mode 100644 DBEditor/pokemon_details_operations.py create mode 100644 DBEditor/pokemon_list_operations.py create mode 100644 DBEditor/ui_components.py diff --git a/.gitignore b/.gitignore index 29c772d..ff0067e 100644 --- a/.gitignore +++ b/.gitignore @@ -3,4 +3,4 @@ pokemon_database.db Utilities/venv/ venv/ DBVisualiser/node_modules/ -Utilities/__pycache__/ \ No newline at end of file +__pycache__/ \ No newline at end of file diff --git a/DBEditor/DBEditor.py b/DBEditor/DBEditor.py index 9773e2a..9bcda8c 100644 --- a/DBEditor/DBEditor.py +++ b/DBEditor/DBEditor.py @@ -74,11 +74,117 @@ class DBEditor(QMainWindow): #self.load_pokemon_list() # Make sure this is called after init_ui def init_database(self): - # Copy the original database to the in-memory database + # Create or open the file-based database disk_conn = sqlite3.connect('pokemon_forms.db') + disk_cursor = disk_conn.cursor() + + # Create tables in the file-based database + self.create_pokemon_forms_table(disk_cursor) + self.create_pokemon_storage_table(disk_cursor) + self.create_evolution_chains_table(disk_cursor) + self.create_exclusive_encounter_groups_table(disk_cursor) + self.create_encounters_table(disk_cursor) + + # Commit changes to the file-based database + disk_conn.commit() + + # Copy the file-based database to the in-memory database disk_conn.backup(self.conn) + + # Close the file-based database connection disk_conn.close() + # Create tables in the in-memory database (in case they weren't copied) + self.create_pokemon_forms_table(self.cursor) + self.create_pokemon_storage_table(self.cursor) + self.create_evolution_chains_table(self.cursor) + self.create_exclusive_encounter_groups_table(self.cursor) + self.create_encounters_table(self.cursor) + + # Commit changes to the in-memory database + self.conn.commit() + + def create_pokemon_forms_table(self, cursor): + cursor.execute(''' + CREATE TABLE IF NOT EXISTS pokemon_forms ( + PFIC TEXT PRIMARY KEY, + name TEXT NOT NULL, + form_name TEXT, + national_dex INTEGER NOT NULL, + generation INTEGER NOT NULL + ) + ''') + + def create_pokemon_storage_table(self, cursor): + cursor.execute(''' + CREATE TABLE IF NOT EXISTS pokemon_storage ( + PFIC TEXT PRIMARY KEY, + storable_in_home BOOLEAN NOT NULL, + FOREIGN KEY (PFIC) REFERENCES pokemon_forms (PFIC) + ) + ''') + + def create_evolution_chains_table(self, cursor): + cursor.execute(''' + CREATE TABLE IF NOT EXISTS evolution_chains ( + from_pfic TEXT, + to_pfic TEXT, + method TEXT, + PRIMARY KEY (from_pfic, to_pfic), + FOREIGN KEY (from_pfic) REFERENCES pokemon_forms (PFIC), + FOREIGN KEY (to_pfic) REFERENCES pokemon_forms (PFIC) + ) + ''') + + def create_exclusive_encounter_groups_table(self, cursor): + cursor.execute(''' + CREATE TABLE IF NOT EXISTS exclusive_encounter_groups ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + group_name TEXT NOT NULL, + description TEXT + ) + ''') + + def create_encounters_table(self, cursor): + # First, check if the table exists + cursor.execute("SELECT name FROM sqlite_master WHERE type='table' AND name='encounters'") + table_exists = cursor.fetchone() is not None + + if not table_exists: + # If the table doesn't exist, create it with all columns + cursor.execute(''' + CREATE TABLE encounters ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + pfic TEXT, + game TEXT, + location TEXT, + day TEXT, + time TEXT, + dual_slot TEXT, + static_encounter BOOLEAN, + static_encounter_count INTEGER, + extra_text TEXT, + stars TEXT, + fishing BOOLEAN, + rods TEXT, + exclusive_group_id INTEGER, + FOREIGN KEY (pfic) REFERENCES pokemon_forms (PFIC), + FOREIGN KEY (exclusive_group_id) REFERENCES exclusive_encounter_groups (id) + ) + ''') + else: + # If the table exists, check if the exclusive_group_id column exists + cursor.execute("PRAGMA table_info(encounters)") + columns = [column[1] for column in cursor.fetchall()] + + if 'exclusive_group_id' not in columns: + # If the column doesn't exist, add it + cursor.execute(''' + ALTER TABLE encounters + ADD COLUMN exclusive_group_id INTEGER + REFERENCES exclusive_encounter_groups (id) + ''') + def load_and_apply_patches(self): try: with open('patches.json', 'r') as f: @@ -598,16 +704,24 @@ class DBEditor(QMainWindow): layout.addRow("Fishing:", fishing_check) layout.addRow("Rods:", rods_edit) + exclusive_group_combo = QComboBox() + exclusive_group_combo.addItem("None", None) + self.cursor.execute('SELECT id, group_name FROM exclusive_encounter_groups') + for group_id, group_name in self.cursor.fetchall(): + exclusive_group_combo.addItem(group_name, group_id) + + layout.addRow("Exclusive Group:", exclusive_group_combo) + # Fetch current values self.cursor.execute(''' - SELECT day, time, dual_slot, static_encounter_count, static_encounter, extra_text, stars, fishing, rods + SELECT day, time, dual_slot, static_encounter_count, static_encounter, extra_text, stars, fishing, rods, exclusive_group_id FROM encounters WHERE pfic = ? AND game = ? AND location = ? ''', (self.current_pfic, game, location)) current_values = self.cursor.fetchone() if current_values: - day, time, dual_slot, static_encounter_count, static_encounter, extra_text, stars, fishing, rods = current_values + day, time, dual_slot, static_encounter_count, static_encounter, extra_text, stars, fishing, rods, exclusive_group_id = current_values day_edit.setText(day or "") time_edit.setText(time or "") dual_slot_edit.setText(dual_slot or "") @@ -617,6 +731,9 @@ class DBEditor(QMainWindow): stars_edit.setText(stars or "") fishing_check.setChecked(bool(fishing)) rods_edit.setText(rods or "") + index = exclusive_group_combo.findData(exclusive_group_id) + if index >= 0: + exclusive_group_combo.setCurrentIndex(index) buttons = QDialogButtonBox( QDialogButtonBox.StandardButton.Ok | QDialogButtonBox.StandardButton.Cancel, @@ -637,17 +754,18 @@ class DBEditor(QMainWindow): new_stars = stars_edit.text() or None new_fishing = fishing_check.isChecked() new_rods = rods_edit.text() or None + new_exclusive_group_id = exclusive_group_combo.currentData() # Update the database self.cursor.execute(''' UPDATE encounters SET game = ?, location = ?, day = ?, time = ?, dual_slot = ?, static_encounter = ?, static_encounter_count = ?, extra_text = ?, - stars = ?, fishing = ?, rods = ? + stars = ?, fishing = ?, rods = ?, exclusive_group_id = ? WHERE pfic = ? AND game = ? AND location = ? ''', (new_game, new_location, new_day, new_time, new_dual_slot, new_static_encounter, new_static_encounter_count, new_extra_text, - new_stars, new_fishing, new_rods, + new_stars, new_fishing, new_rods, new_exclusive_group_id, self.current_pfic, game, location)) self.conn.commit() @@ -687,6 +805,14 @@ class DBEditor(QMainWindow): layout.addRow("Fishing:", fishing_check) layout.addRow("Rods:", rods_edit) + exclusive_group_combo = QComboBox() + exclusive_group_combo.addItem("None", None) + self.cursor.execute('SELECT id, group_name FROM exclusive_encounter_groups') + for group_id, group_name in self.cursor.fetchall(): + exclusive_group_combo.addItem(group_name, group_id) + + layout.addRow("Exclusive Group:", exclusive_group_combo) + buttons = QDialogButtonBox( QDialogButtonBox.StandardButton.Ok | QDialogButtonBox.StandardButton.Cancel, Qt.Orientation.Horizontal, dialog) @@ -706,13 +832,14 @@ class DBEditor(QMainWindow): stars = stars_edit.text() or None fishing = fishing_check.isChecked() rods = rods_edit.text() or None + exclusive_group_id = exclusive_group_combo.currentData() # Insert new encounter into the database self.cursor.execute(''' INSERT INTO encounters - (pfic, game, location, day, time, dual_slot, static_encounter, static_encounter_count, extra_text, stars, fishing, rods) - VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) - ''', (self.current_pfic, game, location, day, time, dual_slot, static_encounter, static_encounter_count, extra_text, stars, fishing, rods)) + (pfic, game, location, day, time, dual_slot, static_encounter, static_encounter_count, extra_text, stars, fishing, rods, exclusive_group_id) + VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) + ''', (self.current_pfic, game, location, day, time, dual_slot, static_encounter, static_encounter_count, extra_text, stars, fishing, rods, exclusive_group_id)) self.conn.commit() # Update the cache @@ -769,6 +896,83 @@ class DBEditor(QMainWindow): def check_pokemon_has_encounters(self, pfic): return self.encounter_cache.get(pfic, False) + def manage_exclusive_groups(self): + dialog = QDialog(self) + dialog.setWindowTitle("Manage Exclusive Encounter Groups") + layout = QVBoxLayout(dialog) + + group_list = QListWidget() + self.cursor.execute('SELECT id, group_name, description FROM exclusive_encounter_groups') + for group_id, group_name, description in self.cursor.fetchall(): + item = QListWidgetItem(f"{group_name} - {description}") + item.setData(Qt.ItemDataRole.UserRole, group_id) + group_list.addItem(item) + + layout.addWidget(group_list) + + add_button = QPushButton("Add Group") + edit_button = QPushButton("Edit Group") + delete_button = QPushButton("Delete Group") + + button_layout = QHBoxLayout() + button_layout.addWidget(add_button) + button_layout.addWidget(edit_button) + button_layout.addWidget(delete_button) + layout.addLayout(button_layout) + + add_button.clicked.connect(lambda: self.add_edit_exclusive_group(dialog, group_list)) + edit_button.clicked.connect(lambda: self.add_edit_exclusive_group(dialog, group_list, group_list.currentItem())) + delete_button.clicked.connect(lambda: self.delete_exclusive_group(dialog, group_list, group_list.currentItem())) + + dialog.exec() + + def add_edit_exclusive_group(self, parent_dialog, group_list, item=None): + dialog = QDialog(parent_dialog) + dialog.setWindowTitle("Add/Edit Exclusive Group") + layout = QFormLayout(dialog) + + name_edit = QLineEdit() + description_edit = QLineEdit() + + layout.addRow("Group Name:", name_edit) + layout.addRow("Description:", description_edit) + + if item: + group_id = item.data(Qt.ItemDataRole.UserRole) + self.cursor.execute('SELECT group_name, description FROM exclusive_encounter_groups WHERE id = ?', (group_id,)) + group_name, description = self.cursor.fetchone() + name_edit.setText(group_name) + description_edit.setText(description) + + buttons = QDialogButtonBox(QDialogButtonBox.StandardButton.Ok | QDialogButtonBox.StandardButton.Cancel) + buttons.accepted.connect(dialog.accept) + buttons.rejected.connect(dialog.reject) + layout.addRow(buttons) + + if dialog.exec() == QDialog.DialogCode.Accepted: + name = name_edit.text() + description = description_edit.text() + if item: + self.cursor.execute('UPDATE exclusive_encounter_groups SET group_name = ?, description = ? WHERE id = ?', (name, description, group_id)) + item.setText(f"{name} - {description}") + else: + self.cursor.execute('INSERT INTO exclusive_encounter_groups (group_name, description) VALUES (?, ?)', (name, description)) + group_id = self.cursor.lastrowid + new_item = QListWidgetItem(f"{name} - {description}") + new_item.setData(Qt.ItemDataRole.UserRole, group_id) + group_list.addItem(new_item) + self.conn.commit() + + def delete_exclusive_group(self, parent_dialog, group_list, item): + if item: + group_id = item.data(Qt.ItemDataRole.UserRole) + reply = QMessageBox.question(parent_dialog, 'Delete Group', 'Are you sure you want to delete this group?', QMessageBox.StandardButton.Yes | QMessageBox.StandardButton.No, QMessageBox.StandardButton.No) + if reply == QMessageBox.StandardButton.Yes: + self.cursor.execute('DELETE FROM exclusive_encounter_groups WHERE id = ?', (group_id,)) + self.cursor.execute('UPDATE encounters SET exclusive_group_id = NULL WHERE exclusive_group_id = ?', (group_id,)) + self.conn.commit() + group_list.takeItem(group_list.row(item)) + if __name__ == '__main__': app = QApplication(sys.argv) editor = DBEditor() diff --git a/DBEditor/database_operations.py b/DBEditor/database_operations.py new file mode 100644 index 0000000..547c6e1 --- /dev/null +++ b/DBEditor/database_operations.py @@ -0,0 +1,114 @@ +import sqlite3 + +class DatabaseOperations: + def init_database(self): + # Create or open the file-based database + disk_conn = sqlite3.connect('pokemon_forms.db') + disk_cursor = disk_conn.cursor() + + # Create tables in the file-based database + self.create_pokemon_forms_table(disk_cursor) + self.create_pokemon_storage_table(disk_cursor) + self.create_evolution_chains_table(disk_cursor) + self.create_exclusive_encounter_groups_table(disk_cursor) + self.create_encounters_table(disk_cursor) + + # Commit changes to the file-based database + disk_conn.commit() + + # Copy the file-based database to the in-memory database + disk_conn.backup(self.conn) + + # Close the file-based database connection + disk_conn.close() + + # Create tables in the in-memory database (in case they weren't copied) + self.create_pokemon_forms_table(self.cursor) + self.create_pokemon_storage_table(self.cursor) + self.create_evolution_chains_table(self.cursor) + self.create_exclusive_encounter_groups_table(self.cursor) + self.create_encounters_table(self.cursor) + + # Commit changes to the in-memory database + self.conn.commit() + + def create_pokemon_forms_table(self, cursor): + cursor.execute(''' + CREATE TABLE IF NOT EXISTS pokemon_forms ( + PFIC TEXT PRIMARY KEY, + name TEXT NOT NULL, + form_name TEXT, + national_dex INTEGER NOT NULL, + generation INTEGER NOT NULL + ) + ''') + + def create_pokemon_storage_table(self, cursor): + cursor.execute(''' + CREATE TABLE IF NOT EXISTS pokemon_storage ( + PFIC TEXT PRIMARY KEY, + storable_in_home BOOLEAN NOT NULL, + FOREIGN KEY (PFIC) REFERENCES pokemon_forms (PFIC) + ) + ''') + + def create_evolution_chains_table(self, cursor): + cursor.execute(''' + CREATE TABLE IF NOT EXISTS evolution_chains ( + from_pfic TEXT, + to_pfic TEXT, + method TEXT, + PRIMARY KEY (from_pfic, to_pfic), + FOREIGN KEY (from_pfic) REFERENCES pokemon_forms (PFIC), + FOREIGN KEY (to_pfic) REFERENCES pokemon_forms (PFIC) + ) + ''') + + def create_exclusive_encounter_groups_table(self, cursor): + cursor.execute(''' + CREATE TABLE IF NOT EXISTS exclusive_encounter_groups ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + group_name TEXT NOT NULL, + description TEXT + ) + ''') + + def create_encounters_table(self, cursor): + # First, check if the table exists + cursor.execute("SELECT name FROM sqlite_master WHERE type='table' AND name='encounters'") + table_exists = cursor.fetchone() is not None + + if not table_exists: + # If the table doesn't exist, create it with all columns + cursor.execute(''' + CREATE TABLE encounters ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + pfic TEXT, + game TEXT, + location TEXT, + day TEXT, + time TEXT, + dual_slot TEXT, + static_encounter BOOLEAN, + static_encounter_count INTEGER, + extra_text TEXT, + stars TEXT, + fishing BOOLEAN, + rods TEXT, + exclusive_group_id INTEGER, + FOREIGN KEY (pfic) REFERENCES pokemon_forms (PFIC), + FOREIGN KEY (exclusive_group_id) REFERENCES exclusive_encounter_groups (id) + ) + ''') + else: + # If the table exists, check if the exclusive_group_id column exists + cursor.execute("PRAGMA table_info(encounters)") + columns = [column[1] for column in cursor.fetchall()] + + if 'exclusive_group_id' not in columns: + # If the column doesn't exist, add it + cursor.execute(''' + ALTER TABLE encounters + ADD COLUMN exclusive_group_id INTEGER + REFERENCES exclusive_encounter_groups (id) + ''') \ No newline at end of file diff --git a/DBEditor/db_editor.py b/DBEditor/db_editor.py new file mode 100644 index 0000000..9f98040 --- /dev/null +++ b/DBEditor/db_editor.py @@ -0,0 +1,19 @@ +from PyQt6.QtWidgets import QMainWindow +from database_operations import DatabaseOperations +from ui_components import UIComponents +from pokemon_list_operations import PokemonListOperations +from pokemon_details_operations import PokemonDetailsOperations +from evolution_operations import EvolutionOperations +from encounter_operations import EncounterOperations +from patch_operations import PatchOperations + +class DBEditor(QMainWindow, DatabaseOperations, UIComponents, PokemonListOperations, + PokemonDetailsOperations, EvolutionOperations, EncounterOperations, PatchOperations): + def __init__(self): + super().__init__() + self.setWindowTitle("Pokémon Database Editor") + self.setGeometry(100, 100, 1000, 600) + + self.init_database() + self.init_ui() + self.load_pokemon_list() \ No newline at end of file diff --git a/DBEditor/encounter_operations.py b/DBEditor/encounter_operations.py new file mode 100644 index 0000000..4dccba6 --- /dev/null +++ b/DBEditor/encounter_operations.py @@ -0,0 +1,12 @@ +from PyQt6.QtWidgets import QTreeWidgetItem + +class EncounterOperations: + def load_encounter_locations(self, pfic): + print("") + # Encounter locations loading code + + def add_new_encounter(self): + print("") + # New encounter addition code + + # Other encounter-related methods \ No newline at end of file diff --git a/DBEditor/evolution_operations.py b/DBEditor/evolution_operations.py new file mode 100644 index 0000000..5ad824d --- /dev/null +++ b/DBEditor/evolution_operations.py @@ -0,0 +1,12 @@ +from PyQt6.QtWidgets import QTreeWidgetItem + +class EvolutionOperations: + def load_evolution_chain(self, pfic): + print("") + # Evolution chain loading code + + def edit_evolution(self, item, column): + print("") + # Evolution editing code + + # Other evolution-related methods \ No newline at end of file diff --git a/DBEditor/main.py b/DBEditor/main.py new file mode 100644 index 0000000..9cad14d --- /dev/null +++ b/DBEditor/main.py @@ -0,0 +1,9 @@ +import sys +from PyQt6.QtWidgets import QApplication +from db_editor import DBEditor + +if __name__ == '__main__': + app = QApplication(sys.argv) + editor = DBEditor() + editor.show() + sys.exit(app.exec()) \ No newline at end of file diff --git a/DBEditor/patch_operations.py b/DBEditor/patch_operations.py new file mode 100644 index 0000000..9d26a40 --- /dev/null +++ b/DBEditor/patch_operations.py @@ -0,0 +1,12 @@ +import json + +class PatchOperations: + def load_and_apply_patches(self): + print("") + # Patch loading and applying code + + def save_patches(self): + print("") + # Patch saving code + + # Other patch-related methods \ No newline at end of file diff --git a/DBEditor/pokemon_details_operations.py b/DBEditor/pokemon_details_operations.py new file mode 100644 index 0000000..17e93d4 --- /dev/null +++ b/DBEditor/pokemon_details_operations.py @@ -0,0 +1,8 @@ +from PyQt6.QtGui import QPixmap + +class PokemonDetailsOperations: + def load_pokemon_details(self, current, previous): + print("") + # Pokémon details loading code + + # Other Pokémon details-related methods \ No newline at end of file diff --git a/DBEditor/pokemon_list_operations.py b/DBEditor/pokemon_list_operations.py new file mode 100644 index 0000000..8d51a5f --- /dev/null +++ b/DBEditor/pokemon_list_operations.py @@ -0,0 +1,13 @@ +from PyQt6.QtWidgets import QListWidgetItem +from PyQt6.QtCore import Qt + +class PokemonListOperations: + def load_pokemon_list(self): + print("") + # Pokémon list loading code + + def filter_pokemon_list(self): + print("") + # Filtering code + + # Other Pokémon list-related methods \ No newline at end of file diff --git a/DBEditor/ui_components.py b/DBEditor/ui_components.py new file mode 100644 index 0000000..f71ac49 --- /dev/null +++ b/DBEditor/ui_components.py @@ -0,0 +1,8 @@ +from PyQt6.QtWidgets import QWidget, QVBoxLayout, QHBoxLayout, QSplitter + +class UIComponents: + def init_ui(self): + print("") + # UI setup code + + # Methods for creating and setting up UI components \ No newline at end of file